From a7b74c017d4522b1c6deaaf92a01833b24b713c0 Mon Sep 17 00:00:00 2001 From: marehr Date: Thu, 7 Dec 2017 15:09:54 +0100 Subject: [PATCH 1/3] [INTERNAL] travis: Use g++-7 direcly from packages --- .travis.yml | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/.travis.yml b/.travis.yml index 78a44a61bf..e208b5bdb7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,37 +5,42 @@ language: cpp git: submodules: true -env: - global: - - GCC_VERSION="20170319" - cache: + apt: true ccache: true - directories: - - $HOME/debs - -before_install: - - export GCC_PATH=/home/travis/gcc-7-$GCC_VERSION - - export PATH=$GCC_PATH/bin/:$PATH - - export LD_LIBRARY_PATH=$GCC_PATH/lib64/:$LD_LIBRARY_PATH - - echo $GCC_VERSION - - echo $GCC_PATH - - echo $PATH - - echo $LD_LIBRARY_PATH - - wget -nc -P $HOME/debs http://ftp.seqan.de/contribs/g++-7_"${GCC_VERSION}"_amd64.deb + +linux-gcc-7: &linux-gcc-7 + os: linux + compiler: 'g++-7' + addons: + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-7'] + before_install: + - export CC="gcc-7" CXX="g++-7" + +# https://docs.travis-ci.com/user/languages/c/#gcc-on-linux +matrix: + include: + - << : *linux-gcc-7 + env: + - BUILD=test + - BUILD_TYPE=Release + - << : *linux-gcc-7 + env: + - BUILD=test + - BUILD_TYPE=Debug install: - - dpkg -x $HOME/debs/g++-7_"${GCC_VERSION}"_amd64.deb $HOME - - mv $HOME/home/travis/* $HOME - ccache --version - - g++ -v + - $CXX -v - cmake --version before_script: - mkdir ../seqan3-build - cd ../seqan3-build - - cmake ../seqan3/test - - make googletest -j + - cmake ../seqan3/${BUILD} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} + - make googletest script: - make -k From 99b6357a39bc85252e4fd5f9bbe36b1b16925226 Mon Sep 17 00:00:00 2001 From: marehr Date: Thu, 7 Dec 2017 23:49:30 +0100 Subject: [PATCH 2/3] [FIX] Add container/concept.hpp test cases --- include/seqan3/range/container/concept.hpp | 23 ----- test/range/container/CMakeLists.txt | 1 + .../container/container_concept_test.cpp | 92 +++++++++++++++++++ 3 files changed, 93 insertions(+), 23 deletions(-) create mode 100644 test/range/container/container_concept_test.cpp diff --git a/include/seqan3/range/container/concept.hpp b/include/seqan3/range/container/concept.hpp index f11afec58e..ef2566b0ef 100644 --- a/include/seqan3/range/container/concept.hpp +++ b/include/seqan3/range/container/concept.hpp @@ -202,26 +202,3 @@ concept bool reservable_sequence_concept = requires (type val) //!\} } // namespace seqan3 - -#ifndef NDEBUG -/* Check the STL containers */ - -#include -#include -#include -#include -#include -#include - -static_assert(seqan3::container_concept>); -static_assert(seqan3::sequence_concept>); -static_assert(seqan3::random_access_sequence_concept>); -static_assert(seqan3::random_access_sequence_concept>); -static_assert(seqan3::random_access_sequence_concept); - -/* Check the SDSL containers */ -//TODO - -/* Check our containers */ -//TODO -#endif diff --git a/test/range/container/CMakeLists.txt b/test/range/container/CMakeLists.txt index 75a789569d..ba655277d7 100644 --- a/test/range/container/CMakeLists.txt +++ b/test/range/container/CMakeLists.txt @@ -1 +1,2 @@ +seqan3_test(container_concept_test.cpp) seqan3_test(container_of_container_test.cpp) diff --git a/test/range/container/container_concept_test.cpp b/test/range/container/container_concept_test.cpp new file mode 100644 index 0000000000..7469c693b0 --- /dev/null +++ b/test/range/container/container_concept_test.cpp @@ -0,0 +1,92 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// +// Copyright (c) 2006-2017, Knut Reinert, FU Berlin +// Copyright (c) 2016-2017, Knut Reinert & MPI Molekulare Genetik +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== + +#include + +#include +#include +#include +#include +#include +#include + +#include + +using namespace seqan3; + +TEST(container_concept, container_concept) +{ + EXPECT_TRUE((seqan3::container_concept>)); + EXPECT_TRUE((seqan3::container_concept>)); + EXPECT_FALSE((seqan3::container_concept>)); // `.size()` missing + EXPECT_TRUE((seqan3::container_concept>)); + EXPECT_TRUE((seqan3::container_concept>)); + EXPECT_TRUE((seqan3::container_concept)); +} + +TEST(container_concept, sequence_concept) +{ + EXPECT_FALSE((seqan3::sequence_concept>)); + EXPECT_TRUE((seqan3::sequence_concept>)); + EXPECT_FALSE((seqan3::sequence_concept>)); + EXPECT_TRUE((seqan3::sequence_concept>)); + EXPECT_TRUE((seqan3::sequence_concept>)); + EXPECT_TRUE((seqan3::sequence_concept)); +} + +TEST(container_concept, random_access_sequence_concept) +{ + EXPECT_FALSE((seqan3::random_access_sequence_concept>)); + EXPECT_FALSE((seqan3::random_access_sequence_concept>)); + EXPECT_FALSE((seqan3::random_access_sequence_concept>)); + EXPECT_TRUE((seqan3::random_access_sequence_concept>)); + EXPECT_TRUE((seqan3::random_access_sequence_concept>)); + EXPECT_TRUE((seqan3::random_access_sequence_concept)); +} + +TEST(container_concept, reservable_sequence_concept) +{ + EXPECT_FALSE((seqan3::reservable_sequence_concept>)); + EXPECT_FALSE((seqan3::reservable_sequence_concept>)); + EXPECT_FALSE((seqan3::reservable_sequence_concept>)); + EXPECT_TRUE((seqan3::reservable_sequence_concept>)); + EXPECT_FALSE((seqan3::reservable_sequence_concept>)); + EXPECT_TRUE((seqan3::reservable_sequence_concept)); +} + +/* Check the SDSL containers */ +//TODO + +/* Check our containers */ +//TODO From 5ba75261f785259adf8b49e0cf41ce818f481e8a Mon Sep 17 00:00:00 2001 From: marehr Date: Fri, 8 Dec 2017 00:10:10 +0100 Subject: [PATCH 3/3] [FIX] travis/ubuntu16.04: gcc-7.2 bug --- .../container/concatenated_sequences.hpp | 8 +- include/seqan3/range/container/concept.hpp | 106 ++++++++++- .../container/container_concept_test.cpp | 177 +++++++++++++++++- 3 files changed, 276 insertions(+), 15 deletions(-) diff --git a/include/seqan3/range/container/concatenated_sequences.hpp b/include/seqan3/range/container/concatenated_sequences.hpp index 4ad3f9be8b..cc65bdb8e5 100644 --- a/include/seqan3/range/container/concatenated_sequences.hpp +++ b/include/seqan3/range/container/concatenated_sequences.hpp @@ -138,6 +138,9 @@ template , + "KNOWN BUG: inner_type = std::basic_string<> is not working " + "for the ubuntu::ppa version of gcc7, because of a faulty STL version. "); protected: //!\privatesection //!\brief Where the concatenation is stored. @@ -1319,8 +1322,3 @@ class concatenated_sequences }; } // namespace seqan3 - -#ifndef NDEBUG -static_assert(seqan3::reservable_sequence_concept>); -static_assert(seqan3::forward_range_concept>); -#endif diff --git a/include/seqan3/range/container/concept.hpp b/include/seqan3/range/container/concept.hpp index ef2566b0ef..2fbaada647 100644 --- a/include/seqan3/range/container/concept.hpp +++ b/include/seqan3/range/container/concept.hpp @@ -42,6 +42,87 @@ #include +// remove if sequence_concept_modified_by_const_iterator_bug vanished from travis +#include + +// TODO: +// * merge sequence_concept_modified_by_const_iterator back into +// sequence_concept +// * remove is_basic_string +// * fix test cases +// * remove #include in this file +// once the ubuntu::ppa [1] of g++-7 has a newer update than +// 7.2.0-1ubuntu1~16.04 (2017-08-20) +// +// [1] https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test?field.series_filter=xenial +namespace seqan3::detail +{ +//!\privatesection + +//!\brief Returns whether `basic_string_t` is of type `std::basic_string`. +//!\attention Will be deleted once seqan3::detail::sequence_concept_modified_by_const_iterator_bug is fixed. +template +struct is_basic_string : std::false_type +{}; + +//!\brief Returns whether `basic_string_t` is of type `std::basic_string`. +//!\attention Will be deleted once seqan3::detail::sequence_concept_modified_by_const_iterator_bug is fixed. +template +struct is_basic_string> : std::true_type +{}; + +//!\brief Shorthand of seqan3::detail::is_basic_string +//!\attention Will be deleted once seqan3::detail::sequence_concept_modified_by_const_iterator_bug is fixed. +template +constexpr bool is_basic_string_v = is_basic_string::value; + +/*!\interface seqan3::detail::sequence_concept_modified_by_const_iterator <> + * \brief Checks whether insert and erase can be used with const_iterator + * + * \attention This will be merged back into sequence_concept once + * seqan3::detail::sequence_concept_modified_by_const_iterator_bug is fixed. + */ +//!\cond +template +concept bool sequence_concept_modified_by_const_iterator = requires (type val, type val2) +{ + { val.insert(val.cbegin(), val2.front()) } -> typename type::iterator; + { val.insert(val.cbegin(), typename type::value_type{}) } -> typename type::iterator; + { val.insert(val.cbegin(), typename type::size_type{}, typename type::value_type{})} -> typename type::iterator; + { val.insert(val.cbegin(), val2.begin(), val2.end()) } -> typename type::iterator; + requires is_basic_string_v || requires(type val) + { + // TODO this function is not defined on strings (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83328) + { val.insert(val.cbegin(), std::initializer_list{}) } -> typename type::iterator; + }; + { val.erase(val.cbegin()) } -> typename type::iterator; + { val.erase(val.cbegin(), val.cend()) } -> typename type::iterator; + + { val.insert(val.begin(), typename type::size_type{}, typename type::value_type{}) } -> typename type::iterator; + { val.insert(val.begin(), val2.begin(), val2.end()) } -> typename type::iterator; +}; +//!\endcond + +/*!\brief Workaround for a ubuntu/travis-ci exclusive bug with g++-7.2. + * + * seqan3::detail::sequence_concept_modified_by_const_iterator is + * known to work, but ubuntu::ppa (<18.04)/travis-ci has a version of g++-7.2 + * where a bug in the STL prevents this concept to be true. + * + * \attention This workaround can be removed if + * `/test/range/container/container_concept_test.cpp` is not failing on + * ubuntu::ppa (<18.04)/travis-ci anymore. \n + * Probably when the ppa version of gcc7 is newer than `7.2.0-1ubuntu1~16.04` (2017-08-20) + * \sa https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test?field.series_filter=xenial + */ +template +constexpr bool sequence_concept_modified_by_const_iterator_bug = + is_basic_string_v && !sequence_concept_modified_by_const_iterator; + +//!\publicsection + +} // seqan3::detail + namespace seqan3 { @@ -127,15 +208,22 @@ concept bool sequence_concept = requires (type val, type val2) // modify container //TODO: how do you model this? -// { val.emplace(typename type::const_iterator{}, ? } -> typename type::iterator; - { val.insert(val.cbegin(), val2.front()) } -> typename type::iterator; - { val.insert(val.cbegin(), typename type::value_type{}) } -> typename type::iterator; - { val.insert(val.cbegin(), typename type::size_type{}, typename type::value_type{})} -> typename type::iterator; - { val.insert(val.cbegin(), val2.begin(), val2.end()) } -> typename type::iterator; -//TODO this fails on std::string, although it should work -// { val.insert(val.cbegin(), std::initializer_list{}) } -> typename type::iterator; - { val.erase(val.cbegin()) } -> typename type::iterator; - { val.erase(val.cbegin(), val.cend()) } -> typename type::iterator; + // { val.emplace(typename type::const_iterator{}, ? } -> typename type::iterator; + + { val.insert(val.begin(), val2.front()) } -> typename type::iterator; + { val.insert(val.begin(), typename type::value_type{}) } -> typename type::iterator; + // because of a travis bug we can't assume typename type::iterator as return type + { val.insert(val.begin(), typename type::size_type{}, typename type::value_type{}) }; + { val.insert(val.begin(), val2.begin(), val2.end()) }; + //TODO should return type::iterator on strings (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83328) + { val.insert(val.begin(), std::initializer_list{}) }; + { val.erase(val.begin()) } -> typename type::iterator; + { val.erase(val.begin(), val.end()) } -> typename type::iterator; + + // workaround a travis bug where insert/erase can't take a const iterator, e.g. cbegin() + requires detail::sequence_concept_modified_by_const_iterator_bug || + detail::sequence_concept_modified_by_const_iterator; + { val.push_back(val.front()) } -> void; { val.push_back(typename type::value_type{}) } -> void; { val.pop_back() } -> void; diff --git a/test/range/container/container_concept_test.cpp b/test/range/container/container_concept_test.cpp index 7469c693b0..ae84b86024 100644 --- a/test/range/container/container_concept_test.cpp +++ b/test/range/container/container_concept_test.cpp @@ -41,10 +41,34 @@ #include #include -#include +#include +#include using namespace seqan3; +// if detail::sequence_concept_modified_by_const_iterator_bug<> is false +// test seqan3::concatenated_sequences, otherwise +// test seqan3::concatenated_sequences> +using concatenated_sequences_string_t = seqan3::concatenated_sequences< + std::conditional_t< + detail::sequence_concept_modified_by_const_iterator_bug<>, + std::vector, + std::string + >>; + +TEST(range_concept, forward_range_concept) +{ + EXPECT_TRUE((seqan3::forward_range_concept>)); + EXPECT_TRUE((seqan3::forward_range_concept>)); + EXPECT_TRUE((seqan3::forward_range_concept>)); // `.size()` missing + EXPECT_TRUE((seqan3::forward_range_concept>)); + EXPECT_TRUE((seqan3::forward_range_concept>)); + EXPECT_TRUE((seqan3::forward_range_concept)); + + EXPECT_TRUE((seqan3::forward_range_concept)); + EXPECT_TRUE((seqan3::forward_range_concept>>)); +} + TEST(container_concept, container_concept) { EXPECT_TRUE((seqan3::container_concept>)); @@ -53,6 +77,132 @@ TEST(container_concept, container_concept) EXPECT_TRUE((seqan3::container_concept>)); EXPECT_TRUE((seqan3::container_concept>)); EXPECT_TRUE((seqan3::container_concept)); + + EXPECT_TRUE((seqan3::container_concept)); + EXPECT_TRUE((seqan3::container_concept>>)); +} + +template +void container_concept_travis_bug_test() +{ + // non const version of container_concept_const_travis_bug_test + using namespace std::string_literals; + + // example code from http://en.cppreference.com/w/cpp/string/basic_string/insert + string_t s = "xmplr"; + string_t r = ""; + typename string_t::iterator it; + + // insert(size_type index, size_type count, char ch) + r = s.insert(0, 1, 'E'); + EXPECT_EQ("Exmplr", s); + + // insert(size_type index, const char* s) + r = s.insert(2, "e"); + EXPECT_EQ("Exemplr", s); + + // insert(size_type index, string const& str) + r = s.insert(6, "a"s); + EXPECT_EQ("Exemplar", s); + + // insert(size_type index, string const& str, + // size_type index_str, size_type count) + r = s.insert(8, " is an example string."s, 0, 14); + EXPECT_EQ("Exemplar is an example", s); + + // insert(const_iterator pos, char ch) + it = s.insert(s.begin() + s.find_first_of('n') + 1, ':'); + EXPECT_EQ("Exemplar is an: example", s); + + // insert(const_iterator pos, size_type count, char ch) + //TODO should return type::iterator on strings, remove if + // sequence_concept_modified_by_const_iterator_bug is no issue anymore + // it = + s.insert(s.begin() + s.find_first_of(':') + 1, 2, '='); + EXPECT_EQ("Exemplar is an:== example", s); + + // insert(const_iterator pos, InputIt first, InputIt last) + { + string_t seq = " string"; + //TODO should return type::iterator on strings, remove if + // sequence_concept_modified_by_const_iterator_bug is no issue anymore + // it = + s.insert(s.begin() + s.find_last_of('e') + 1, + std::begin(seq), std::end(seq)); + EXPECT_EQ("Exemplar is an:== example string", s); + } + + // insert(const_iterator pos, std::initializer_list) + //TODO should return type::iterator on strings (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83328) + // it = + s.insert(s.begin() + s.find_first_of('g') + 1, { '.' }); + EXPECT_EQ("Exemplar is an:== example string.", s); +} + +template +void container_concept_const_travis_bug_test() +{ + // travis failed on this statement + // concept bool sequence_concept = requires (type val, type val2) + // ^~~~~~~~~~~~~~~~ + // /include/seqan3/range/container/concept.hpp:113:14: note: with ‘std::basic_string val’ + // /include/seqan3/range/container/concept.hpp:113:14: note: with ‘std::basic_string val2’ + // [...] + // /include/seqan3/range/container/concept.hpp:113:14: note: the required expression ‘val.erase(val.cbegin(), val.cend())’ would be ill-formed + + using namespace std::string_literals; + + static_assert(detail::sequence_concept_modified_by_const_iterator); + static_assert(!detail::sequence_concept_modified_by_const_iterator_bug && std::is_same_v); + static_assert(seqan3::container_concept); + + // example code from http://en.cppreference.com/w/cpp/string/basic_string/insert + string_t s = "xmplr"; + + // insert(size_type index, size_type count, char ch) + s.insert(0, 1, 'E'); + EXPECT_EQ("Exmplr", s); + + // insert(size_type index, const char* s) + s.insert(2, "e"); + EXPECT_EQ("Exemplr", s); + + // insert(size_type index, string const& str) + s.insert(6, "a"s); + EXPECT_EQ("Exemplar", s); + + // insert(size_type index, string const& str, + // size_type index_str, size_type count) + s.insert(8, " is an example string."s, 0, 14); + EXPECT_EQ("Exemplar is an example", s); + + // insert(const_iterator pos, char ch) + s.insert(s.cbegin() + s.find_first_of('n') + 1, ':'); + EXPECT_EQ("Exemplar is an: example", s); + + // insert(const_iterator pos, size_type count, char ch) + s.insert(s.cbegin() + s.find_first_of(':') + 1, 2, '='); + EXPECT_EQ("Exemplar is an:== example", s); + + // insert(const_iterator pos, InputIt first, InputIt last) + { + string_t seq = " string"; + s.insert(s.cbegin() + s.find_last_of('e') + 1, + std::begin(seq), std::end(seq)); + EXPECT_EQ("Exemplar is an:== example string", s); + } + + // insert(const_iterator pos, std::initializer_list) + s.insert(s.cbegin() + s.find_first_of('g') + 1, { '.' }); + EXPECT_EQ("Exemplar is an:== example string.", s); +} + +TEST(container_concept, container_concept_travis_bug) +{ + container_concept_travis_bug_test(); + + if constexpr(!detail::sequence_concept_modified_by_const_iterator_bug<>) + container_concept_const_travis_bug_test(); } TEST(container_concept, sequence_concept) @@ -63,6 +213,25 @@ TEST(container_concept, sequence_concept) EXPECT_TRUE((seqan3::sequence_concept>)); EXPECT_TRUE((seqan3::sequence_concept>)); EXPECT_TRUE((seqan3::sequence_concept)); + + EXPECT_TRUE((seqan3::sequence_concept)); + EXPECT_TRUE((seqan3::sequence_concept>>)); +} + +TEST(container_concept, sequence_concept_modified_by_const_iterator) +{ + EXPECT_FALSE((seqan3::detail::sequence_concept_modified_by_const_iterator>)); + EXPECT_TRUE((seqan3::detail::sequence_concept_modified_by_const_iterator>)); + EXPECT_FALSE((seqan3::detail::sequence_concept_modified_by_const_iterator>)); + EXPECT_TRUE((seqan3::detail::sequence_concept_modified_by_const_iterator>)); + EXPECT_TRUE((seqan3::detail::sequence_concept_modified_by_const_iterator>)); + if constexpr(!detail::sequence_concept_modified_by_const_iterator_bug<>) + { + EXPECT_TRUE((seqan3::detail::sequence_concept_modified_by_const_iterator)); + } + + EXPECT_TRUE((seqan3::detail::sequence_concept_modified_by_const_iterator)); + EXPECT_TRUE((seqan3::detail::sequence_concept_modified_by_const_iterator>>)); } TEST(container_concept, random_access_sequence_concept) @@ -73,6 +242,9 @@ TEST(container_concept, random_access_sequence_concept) EXPECT_TRUE((seqan3::random_access_sequence_concept>)); EXPECT_TRUE((seqan3::random_access_sequence_concept>)); EXPECT_TRUE((seqan3::random_access_sequence_concept)); + + EXPECT_TRUE((seqan3::random_access_sequence_concept)); + EXPECT_TRUE((seqan3::random_access_sequence_concept>>)); } TEST(container_concept, reservable_sequence_concept) @@ -83,6 +255,9 @@ TEST(container_concept, reservable_sequence_concept) EXPECT_TRUE((seqan3::reservable_sequence_concept>)); EXPECT_FALSE((seqan3::reservable_sequence_concept>)); EXPECT_TRUE((seqan3::reservable_sequence_concept)); + + EXPECT_TRUE((seqan3::reservable_sequence_concept)); + EXPECT_TRUE((seqan3::reservable_sequence_concept>>)); } /* Check the SDSL containers */