From 2a7b5a70a5cbd822759c1d8ab3b9ac6345372ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Thu, 19 Oct 2017 21:53:37 +0200 Subject: [PATCH] Closes #58 ("Comparing strings does not compile in gcc 7+ in C++17 mode") --- doc/container.qbk | 1 + include/boost/container/string.hpp | 78 ++++++++++++++++++++++++------ test/comparison_test.hpp | 58 ++++++++++++++++++++++ test/string_test.cpp | 14 ++++++ 4 files changed, 137 insertions(+), 14 deletions(-) create mode 100644 test/comparison_test.hpp diff --git a/doc/container.qbk b/doc/container.qbk index 8ceee1c..55f21ec 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -1220,6 +1220,7 @@ use [*Boost.Container]? There are several reasons for that: * Fixed bugs: * [@https://github.com/boostorg/container/pull/54 GitHub #54: ['"no sbrk() in VxWorks, configure dlmalloc to use only mmap"]]. + * [@https://github.com/boostorg/container/issues/58 GitHub #58: ['"Comparing strings does not compile in gcc 7+ in C++17 mode"]]. [endsect] diff --git a/include/boost/container/string.hpp b/include/boost/container/string.hpp index 2405678..51a8fe0 100644 --- a/include/boost/container/string.hpp +++ b/include/boost/container/string.hpp @@ -2953,6 +2953,20 @@ typedef basic_string ,new_allocator > wstring; +#else + +template +struct is_string +{ + static const bool value = false; +}; + +template +struct is_string< basic_string > +{ + static const bool value = true; +}; + #endif // ------------------------------------------------------------ @@ -3060,16 +3074,22 @@ operator==(const basic_string& x, const CharT* s) } template class BasicStringView> -inline bool -operator==( BasicStringView x, const basic_string& y) +inline + BOOST_CONTAINER_DOC1ST( bool, + typename container_detail::disable_if + > BOOST_MOVE_I bool >::type) + operator==( BasicStringView x, const basic_string& y) { return x.size() == y.size() && Traits::compare(x.data(), y.data(), x.size()) == 0; } template class BasicStringView> -inline bool -operator==( const basic_string& x, BasicStringView y) +inline + BOOST_CONTAINER_DOC1ST( bool, + typename container_detail::disable_if + > BOOST_MOVE_I bool >::type) + operator==( const basic_string& x, BasicStringView y) { return x.size() == y.size() && Traits::compare(x.data(), y.data(), x.size()) == 0; @@ -3092,12 +3112,18 @@ operator!=(const basic_string& x, const CharT* s) template class BasicStringView> -inline bool +inline + BOOST_CONTAINER_DOC1ST( bool, + typename container_detail::disable_if + > BOOST_MOVE_I bool >::type) operator!=( BasicStringView x, const basic_string& y) { return !(x == y); } template class BasicStringView> -inline bool +inline + BOOST_CONTAINER_DOC1ST( bool, + typename container_detail::disable_if + > BOOST_MOVE_I bool >::type) operator!=( const basic_string& x, BasicStringView y) { return !(x == y); } @@ -3124,12 +3150,18 @@ operator<(const basic_string& x, const CharT* s) } template class BasicStringView> -inline bool +inline + BOOST_CONTAINER_DOC1ST( bool, + typename container_detail::disable_if + > BOOST_MOVE_I bool >::type) operator<( BasicStringView x, const basic_string& y) { return y.compare(x) > 0; } template class BasicStringView> -inline bool +inline + BOOST_CONTAINER_DOC1ST( bool, + typename container_detail::disable_if + > BOOST_MOVE_I bool >::type) operator<( const basic_string& x, BasicStringView y) { return x.compare(y) < 0; } @@ -3153,12 +3185,18 @@ operator>(const basic_string& x, const CharT* s) } template class BasicStringView> -inline bool +inline + BOOST_CONTAINER_DOC1ST( bool, + typename container_detail::disable_if + > BOOST_MOVE_I bool >::type) operator>( BasicStringView x, const basic_string& y) { return y < x; } template class BasicStringView> -inline bool +inline + BOOST_CONTAINER_DOC1ST( bool, + typename container_detail::disable_if + > BOOST_MOVE_I bool >::type) operator>( const basic_string& x, BasicStringView y) { return y < x; } @@ -3181,12 +3219,18 @@ operator<=(const basic_string& x, const CharT* s) template class BasicStringView> -inline bool +inline + BOOST_CONTAINER_DOC1ST( bool, + typename container_detail::disable_if + > BOOST_MOVE_I bool >::type) operator<=( BasicStringView x, const basic_string& y) { return !(y < x); } template class BasicStringView> -inline bool +inline + BOOST_CONTAINER_DOC1ST( bool, + typename container_detail::disable_if + > BOOST_MOVE_I bool >::type) operator<=( const basic_string& x, BasicStringView y) { return !(y < x); } @@ -3207,12 +3251,18 @@ operator>=(const basic_string& x, const CharT* s) { return !(x < s); } template class BasicStringView> -inline bool +inline + BOOST_CONTAINER_DOC1ST( bool, + typename container_detail::disable_if + > BOOST_MOVE_I bool >::type) operator>=( BasicStringView x, const basic_string& y) { return !(x < y); } template class BasicStringView> -inline bool +inline + BOOST_CONTAINER_DOC1ST( bool, + typename container_detail::disable_if + > BOOST_MOVE_I bool >::type) operator>=( const basic_string& x, BasicStringView y) { return !(x < y); } diff --git a/test/comparison_test.hpp b/test/comparison_test.hpp new file mode 100644 index 0000000..7f3f1b3 --- /dev/null +++ b/test/comparison_test.hpp @@ -0,0 +1,58 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2017-2017. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_TEST_COMPARISON_TEST_HPP +#define BOOST_CONTAINER_TEST_COMPARISON_TEST_HPP + +#include +#include + +namespace boost { +namespace container { +namespace test { + + +template +bool test_container_comparisons() +{ + typedef typename Cont::value_type value_type; + + Cont cont; + cont.push_back(value_type(1)); + cont.push_back(value_type(2)); + cont.push_back(value_type(3)); + + Cont cont_equal(cont); + + Cont cont_less; + cont_less.push_back(value_type(1)); + cont_less.push_back(value_type(2)); + cont_less.push_back(value_type(2)); + + BOOST_TEST(cont == cont_equal); + BOOST_TEST(!(cont != cont_equal)); + BOOST_TEST(cont != cont_less); + BOOST_TEST(cont_less < cont); + BOOST_TEST(cont_less <= cont); + BOOST_TEST(!(cont_less > cont)); + BOOST_TEST(!(cont_less >= cont)); + BOOST_TEST(!(cont < cont_less)); + BOOST_TEST(!(cont <= cont_less)); + BOOST_TEST(cont > cont_less); + BOOST_TEST(cont >= cont_less); + + return ::boost::report_errors() == 0; +} + +} //namespace test { +} //namespace container { +} //namespace boost { + +#endif //#ifndef BOOST_CONTAINER_TEST_COMPARISON_TEST_HPP diff --git a/test/string_test.cpp b/test/string_test.cpp index 631ad96..f54a350 100644 --- a/test/string_test.cpp +++ b/test/string_test.cpp @@ -24,8 +24,10 @@ #include "expand_bwd_test_template.hpp" #include "propagate_allocator_test.hpp" #include "default_init_test.hpp" +#include "comparison_test.hpp" #include "../../intrusive/test/iterator_test.hpp" #include +#include using namespace boost::container; @@ -507,8 +509,10 @@ struct alloc_propagate_base }; }; + }}} //namespace boost::container::test + int main() { if(string_test()){ @@ -558,6 +562,16 @@ int main() boost::intrusive::test::test_iterator_random< cont_int >(a); } + //////////////////////////////////// + // Comparison testing + //////////////////////////////////// + { + if(!boost::container::test::test_container_comparisons()) + return 1; + if(!boost::container::test::test_container_comparisons()) + return 1; + } + return boost::report_errors(); }