Closes #58 ("Comparing strings does not compile in gcc 7+ in C++17 mode")

This commit is contained in:
Ion Gaztañaga
2017-10-19 21:53:37 +02:00
parent 407aabd77b
commit 2a7b5a70a5
4 changed files with 137 additions and 14 deletions

View File

@@ -1220,6 +1220,7 @@ use [*Boost.Container]? There are several reasons for that:
* Fixed bugs: * 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/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] [endsect]

View File

@@ -2953,6 +2953,20 @@ typedef basic_string
,new_allocator<wchar_t> > ,new_allocator<wchar_t> >
wstring; wstring;
#else
template<class S>
struct is_string
{
static const bool value = false;
};
template<class C, class T, class A>
struct is_string< basic_string<C, T, A> >
{
static const bool value = true;
};
#endif #endif
// ------------------------------------------------------------ // ------------------------------------------------------------
@@ -3060,16 +3074,22 @@ operator==(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
} }
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView> template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool inline
operator==( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y) BOOST_CONTAINER_DOC1ST( bool,
typename container_detail::disable_if
<is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
operator==( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
{ {
return x.size() == y.size() && return x.size() == y.size() &&
Traits::compare(x.data(), y.data(), x.size()) == 0; Traits::compare(x.data(), y.data(), x.size()) == 0;
} }
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView> template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool inline
operator==( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y) BOOST_CONTAINER_DOC1ST( bool,
typename container_detail::disable_if
<is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
operator==( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
{ {
return x.size() == y.size() && return x.size() == y.size() &&
Traits::compare(x.data(), y.data(), x.size()) == 0; Traits::compare(x.data(), y.data(), x.size()) == 0;
@@ -3092,12 +3112,18 @@ operator!=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView> template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool inline
BOOST_CONTAINER_DOC1ST( bool,
typename container_detail::disable_if
<is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
operator!=( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y) operator!=( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
{ return !(x == y); } { return !(x == y); }
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView> template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool inline
BOOST_CONTAINER_DOC1ST( bool,
typename container_detail::disable_if
<is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
operator!=( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y) operator!=( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
{ return !(x == y); } { return !(x == y); }
@@ -3124,12 +3150,18 @@ operator<(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
} }
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView> template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool inline
BOOST_CONTAINER_DOC1ST( bool,
typename container_detail::disable_if
<is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
operator<( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y) operator<( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
{ return y.compare(x) > 0; } { return y.compare(x) > 0; }
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView> template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool inline
BOOST_CONTAINER_DOC1ST( bool,
typename container_detail::disable_if
<is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
operator<( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y) operator<( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
{ return x.compare(y) < 0; } { return x.compare(y) < 0; }
@@ -3153,12 +3185,18 @@ operator>(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
} }
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView> template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool inline
BOOST_CONTAINER_DOC1ST( bool,
typename container_detail::disable_if
<is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
operator>( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y) operator>( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
{ return y < x; } { return y < x; }
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView> template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool inline
BOOST_CONTAINER_DOC1ST( bool,
typename container_detail::disable_if
<is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
operator>( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y) operator>( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
{ return y < x; } { return y < x; }
@@ -3181,12 +3219,18 @@ operator<=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView> template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool inline
BOOST_CONTAINER_DOC1ST( bool,
typename container_detail::disable_if
<is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
operator<=( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y) operator<=( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
{ return !(y < x); } { return !(y < x); }
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView> template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool inline
BOOST_CONTAINER_DOC1ST( bool,
typename container_detail::disable_if
<is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
operator<=( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y) operator<=( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
{ return !(y < x); } { return !(y < x); }
@@ -3207,12 +3251,18 @@ operator>=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
{ return !(x < s); } { return !(x < s); }
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView> template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool inline
BOOST_CONTAINER_DOC1ST( bool,
typename container_detail::disable_if
<is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
operator>=( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y) operator>=( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
{ return !(x < y); } { return !(x < y); }
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView> template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool inline
BOOST_CONTAINER_DOC1ST( bool,
typename container_detail::disable_if
<is_string< BasicStringView<CharT BOOST_MOVE_I Traits> > BOOST_MOVE_I bool >::type)
operator>=( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y) operator>=( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
{ return !(x < y); } { return !(x < y); }

58
test/comparison_test.hpp Normal file
View File

@@ -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 <deque>
#include <boost/core/lightweight_test.hpp>
namespace boost {
namespace container {
namespace test {
template<class Cont>
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

View File

@@ -24,8 +24,10 @@
#include "expand_bwd_test_template.hpp" #include "expand_bwd_test_template.hpp"
#include "propagate_allocator_test.hpp" #include "propagate_allocator_test.hpp"
#include "default_init_test.hpp" #include "default_init_test.hpp"
#include "comparison_test.hpp"
#include "../../intrusive/test/iterator_test.hpp" #include "../../intrusive/test/iterator_test.hpp"
#include <boost/utility/string_view.hpp> #include <boost/utility/string_view.hpp>
#include <boost/core/lightweight_test.hpp>
using namespace boost::container; using namespace boost::container;
@@ -507,8 +509,10 @@ struct alloc_propagate_base<boost_container_string>
}; };
}; };
}}} //namespace boost::container::test }}} //namespace boost::container::test
int main() int main()
{ {
if(string_test<char>()){ if(string_test<char>()){
@@ -558,6 +562,16 @@ int main()
boost::intrusive::test::test_iterator_random< cont_int >(a); boost::intrusive::test::test_iterator_random< cont_int >(a);
} }
////////////////////////////////////
// Comparison testing
////////////////////////////////////
{
if(!boost::container::test::test_container_comparisons<string>())
return 1;
if(!boost::container::test::test_container_comparisons<wstring>())
return 1;
}
return boost::report_errors(); return boost::report_errors();
} }