Commit 875d6cb3 by Jonathan Wakely

libstdc++: Add comparison operators for string and regex types

Some more C++20 changes from P1614R2, "The Mothership has Landed".

This adds three-way comparison support to std::char_traits,
std::basic_string, std::basic_string_view, and std::sub_match.

	* include/bits/basic_string.h (basic_string): Define operator<=> and
	remove redundant comparison operators for C++20.
	* include/bits/char_traits.h (__gnu_cxx::char_traits, char_traits):
	Add comparison_category members.
	(__detail::__char_traits_cmp_cat): New helper to get comparison
	category from char traits class.
	* include/bits/regex.h (regex_traits::_RegexMask::operator!=): Do not
	define for C++20.
	(sub_match): Define operator<=> and remove redundant comparison
	operators for C++20.
	(match_results): Remove redundant operator!= for C++20.
	* include/std/string_view (basic_string_view): Define operator<=> and
	remove redundant comparison operators for C++20.
	* testsuite/21_strings/basic_string/operators/char/cmp_c++20.cc: New
	test.
	* testsuite/21_strings/basic_string/operators/wchar_t/cmp_c++20.cc:
	New test.
	* testsuite/21_strings/basic_string_view/operations/copy/char/
	constexpr.cc: Initialize variable.
	* testsuite/21_strings/basic_string_view/operations/copy/wchar_t/
	constexpr.cc: Likewise.
	* testsuite/21_strings/basic_string_view/operators/char/2.cc: Add
	dg-do directive and remove comments showing incorrect signatures.
	* testsuite/21_strings/basic_string_view/operators/wchar_t/2.cc:
	Likewise.
	* testsuite/21_strings/basic_string_view/operators/char/cmp_c++20.cc:
	New test.
	* testsuite/21_strings/basic_string_view/operators/wchar_t/cmp_c++20.cc:
	New test.
	* testsuite/28_regex/sub_match/compare_c++20.cc: New test.
parent 8b50d7a4
2020-04-17 Jonathan Wakely <jwakely@redhat.com>
* include/bits/basic_string.h (basic_string): Define operator<=> and
remove redundant comparison operators for C++20.
* include/bits/char_traits.h (__gnu_cxx::char_traits, char_traits):
Add comparison_category members.
(__detail::__char_traits_cmp_cat): New helper to get comparison
category from char traits class.
* include/bits/regex.h (regex_traits::_RegexMask::operator!=): Do not
define for C++20.
(sub_match): Define operator<=> and remove redundant comparison
operators for C++20.
(match_results): Remove redundant operator!= for C++20.
* include/std/string_view (basic_string_view): Define operator<=> and
remove redundant comparison operators for C++20.
* testsuite/21_strings/basic_string/operators/char/cmp_c++20.cc: New
test.
* testsuite/21_strings/basic_string/operators/wchar_t/cmp_c++20.cc:
New test.
* testsuite/21_strings/basic_string_view/operations/copy/char/
constexpr.cc: Initialize variable.
* testsuite/21_strings/basic_string_view/operations/copy/wchar_t/
constexpr.cc: Likewise.
* testsuite/21_strings/basic_string_view/operators/char/2.cc: Add
dg-do directive and remove comments showing incorrect signatures.
* testsuite/21_strings/basic_string_view/operators/wchar_t/2.cc:
Likewise.
* testsuite/21_strings/basic_string_view/operators/char/cmp_c++20.cc:
New test.
* testsuite/21_strings/basic_string_view/operators/wchar_t/cmp_c++20.cc:
New test.
* testsuite/28_regex/sub_match/compare_c++20.cc: New test.
2020-04-16 Jonathan Wakely <jwakely@redhat.com> 2020-04-16 Jonathan Wakely <jwakely@redhat.com>
* testsuite/20_util/unsynchronized_pool_resource/allocate.cc: Remove * testsuite/20_util/unsynchronized_pool_resource/allocate.cc: Remove
......
...@@ -6165,18 +6165,6 @@ _GLIBCXX_END_NAMESPACE_CXX11 ...@@ -6165,18 +6165,6 @@ _GLIBCXX_END_NAMESPACE_CXX11
__lhs.size())); } __lhs.size())); }
/** /**
* @brief Test equivalence of C string and string.
* @param __lhs C string.
* @param __rhs String.
* @return True if @a __rhs.compare(@a __lhs) == 0. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator==(const _CharT* __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
{ return __rhs.compare(__lhs) == 0; }
/**
* @brief Test equivalence of string and C string. * @brief Test equivalence of string and C string.
* @param __lhs String. * @param __lhs String.
* @param __rhs C string. * @param __rhs C string.
...@@ -6188,6 +6176,47 @@ _GLIBCXX_END_NAMESPACE_CXX11 ...@@ -6188,6 +6176,47 @@ _GLIBCXX_END_NAMESPACE_CXX11
const _CharT* __rhs) const _CharT* __rhs)
{ return __lhs.compare(__rhs) == 0; } { return __lhs.compare(__rhs) == 0; }
#if __cpp_lib_three_way_comparison
/**
* @brief Three-way comparison of a string and a C string.
* @param __lhs A string.
* @param __rhs A null-terminated string.
* @return A value indicating whether `__lhs` is less than, equal to,
* greater than, or incomparable with `__rhs`.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
inline auto
operator<=>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs) noexcept
-> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
{ return __detail::__char_traits_cmp_cat<_Traits>(__lhs.compare(__rhs)); }
/**
* @brief Three-way comparison of a string and a C string.
* @param __lhs A string.
* @param __rhs A null-terminated string.
* @return A value indicating whether `__lhs` is less than, equal to,
* greater than, or incomparable with `__rhs`.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
inline auto
operator<=>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const _CharT* __rhs) noexcept
-> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
{ return __detail::__char_traits_cmp_cat<_Traits>(__lhs.compare(__rhs)); }
#else
/**
* @brief Test equivalence of C string and string.
* @param __lhs C string.
* @param __rhs String.
* @return True if @a __rhs.compare(@a __lhs) == 0. False otherwise.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator==(const _CharT* __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
{ return __rhs.compare(__lhs) == 0; }
// operator != // operator !=
/** /**
* @brief Test difference of two strings. * @brief Test difference of two strings.
...@@ -6377,6 +6406,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 ...@@ -6377,6 +6406,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
operator>=(const _CharT* __lhs, operator>=(const _CharT* __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs) const basic_string<_CharT, _Traits, _Alloc>& __rhs)
{ return __rhs.compare(__lhs) <= 0; } { return __rhs.compare(__lhs) <= 0; }
#endif // three-way comparison
/** /**
* @brief Swap contents of two strings. * @brief Swap contents of two strings.
......
...@@ -39,6 +39,9 @@ ...@@ -39,6 +39,9 @@
#include <bits/stl_algobase.h> // std::copy, std::fill_n #include <bits/stl_algobase.h> // std::copy, std::fill_n
#include <bits/postypes.h> // For streampos #include <bits/postypes.h> // For streampos
#include <cwchar> // For WEOF, wmemmove, wmemset, etc. #include <cwchar> // For WEOF, wmemmove, wmemset, etc.
#if __cplusplus > 201703L
# include <compare>
#endif
#ifndef _GLIBCXX_ALWAYS_INLINE #ifndef _GLIBCXX_ALWAYS_INLINE
# define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__)) # define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
...@@ -91,6 +94,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -91,6 +94,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef typename _Char_types<_CharT>::pos_type pos_type; typedef typename _Char_types<_CharT>::pos_type pos_type;
typedef typename _Char_types<_CharT>::off_type off_type; typedef typename _Char_types<_CharT>::off_type off_type;
typedef typename _Char_types<_CharT>::state_type state_type; typedef typename _Char_types<_CharT>::state_type state_type;
#if __cpp_lib_three_way_comparison
using comparison_category = std::strong_ordering;
#endif
static _GLIBCXX14_CONSTEXPR void static _GLIBCXX14_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) assign(char_type& __c1, const char_type& __c2)
...@@ -307,6 +313,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -307,6 +313,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef streampos pos_type; typedef streampos pos_type;
typedef streamoff off_type; typedef streamoff off_type;
typedef mbstate_t state_type; typedef mbstate_t state_type;
#if __cpp_lib_three_way_comparison
using comparison_category = strong_ordering;
#endif
static _GLIBCXX17_CONSTEXPR void static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
...@@ -432,6 +441,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -432,6 +441,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef streamoff off_type; typedef streamoff off_type;
typedef wstreampos pos_type; typedef wstreampos pos_type;
typedef mbstate_t state_type; typedef mbstate_t state_type;
#if __cpp_lib_three_way_comparison
using comparison_category = strong_ordering;
#endif
static _GLIBCXX17_CONSTEXPR void static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
...@@ -550,6 +562,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -550,6 +562,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef u8streampos pos_type; typedef u8streampos pos_type;
typedef streamoff off_type; typedef streamoff off_type;
typedef mbstate_t state_type; typedef mbstate_t state_type;
#if __cpp_lib_three_way_comparison
using comparison_category = strong_ordering;
#endif
static _GLIBCXX17_CONSTEXPR void static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
...@@ -687,6 +702,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -687,6 +702,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef streamoff off_type; typedef streamoff off_type;
typedef u16streampos pos_type; typedef u16streampos pos_type;
typedef mbstate_t state_type; typedef mbstate_t state_type;
#if __cpp_lib_three_way_comparison
using comparison_category = strong_ordering;
#endif
static _GLIBCXX17_CONSTEXPR void static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) noexcept assign(char_type& __c1, const char_type& __c2) noexcept
...@@ -798,6 +816,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -798,6 +816,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef streamoff off_type; typedef streamoff off_type;
typedef u32streampos pos_type; typedef u32streampos pos_type;
typedef mbstate_t state_type; typedef mbstate_t state_type;
#if __cpp_lib_three_way_comparison
using comparison_category = strong_ordering;
#endif
static _GLIBCXX17_CONSTEXPR void static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) noexcept assign(char_type& __c1, const char_type& __c2) noexcept
...@@ -895,6 +916,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -895,6 +916,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return eq_int_type(__c, eof()) ? 0 : __c; } { return eq_int_type(__c, eof()) ? 0 : __c; }
}; };
#if __cpp_lib_three_way_comparison
namespace __detail
{
template<typename _ChTraits>
constexpr auto
__char_traits_cmp_cat(int __cmp) noexcept
{
if constexpr (requires { typename _ChTraits::comparison_category; })
{
using _Cat = typename _ChTraits::comparison_category;
static_assert( !is_void_v<common_comparison_category_t<_Cat>> );
return static_cast<_Cat>(__cmp <=> 0);
}
else
return static_cast<weak_ordering>(__cmp <=> 0);
}
} // namespace __detail
#endif // C++20
_GLIBCXX_END_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION
} // namespace } // namespace
......
...@@ -142,11 +142,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -142,11 +142,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
&& _M_base == __other._M_base; && _M_base == __other._M_base;
} }
#if __cpp_impl_three_way_comparison < 201907L
constexpr bool constexpr bool
operator!=(_RegexMask __other) const operator!=(_RegexMask __other) const
{ return !((*this) == __other); } { return !((*this) == __other); }
#endif
}; };
public: public:
typedef _RegexMask char_class_type; typedef _RegexMask char_class_type;
...@@ -1033,6 +1035,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -1033,6 +1035,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
operator==(const sub_match<_BiIter>& __lhs, const sub_match<_BiIter>& __rhs) operator==(const sub_match<_BiIter>& __lhs, const sub_match<_BiIter>& __rhs)
{ return __lhs.compare(__rhs) == 0; } { return __lhs.compare(__rhs) == 0; }
#if __cpp_lib_three_way_comparison
/**
* @brief Three-way comparison of two regular expression submatches.
* @param __lhs First regular expression submatch.
* @param __rhs Second regular expression submatch.
* @returns A value indicating whether `__lhs` is less than, equal to,
* greater than, or incomparable with `__rhs`.
*/
template<typename _BiIter>
inline auto
operator<=>(const sub_match<_BiIter>& __lhs,
const sub_match<_BiIter>& __rhs)
noexcept(__detail::__is_contiguous_iter<_BiIter>::value)
{
using _Tr = char_traits<typename iterator_traits<_BiIter>::value_type>;
return __detail::__char_traits_cmp_cat<_Tr>(__lhs.compare(__rhs));
}
#else
/** /**
* @brief Tests the inequivalence of two regular expression submatches. * @brief Tests the inequivalence of two regular expression submatches.
* @param __lhs First regular expression submatch. * @param __lhs First regular expression submatch.
...@@ -1087,6 +1107,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -1087,6 +1107,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
inline bool inline bool
operator>(const sub_match<_BiIter>& __lhs, const sub_match<_BiIter>& __rhs) operator>(const sub_match<_BiIter>& __lhs, const sub_match<_BiIter>& __rhs)
{ return __lhs.compare(__rhs) > 0; } { return __lhs.compare(__rhs) > 0; }
#endif // three-way comparison
/// @cond undocumented /// @cond undocumented
...@@ -1097,6 +1118,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -1097,6 +1118,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
_Ch_traits, _Ch_alloc>; _Ch_traits, _Ch_alloc>;
/// @endcond /// @endcond
#if ! __cpp_lib_three_way_comparison
/** /**
* @brief Tests the equivalence of a string and a regular expression * @brief Tests the equivalence of a string and a regular expression
* submatch. * submatch.
...@@ -1170,6 +1192,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -1170,6 +1192,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
operator<=(const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __lhs, operator<=(const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __lhs,
const sub_match<_Bi_iter>& __rhs) const sub_match<_Bi_iter>& __rhs)
{ return !(__rhs < __lhs); } { return !(__rhs < __lhs); }
#endif // three-way comparison
/** /**
* @brief Tests the equivalence of a regular expression submatch and a * @brief Tests the equivalence of a regular expression submatch and a
...@@ -1184,6 +1207,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -1184,6 +1207,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __rhs) const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __rhs)
{ return __lhs._M_compare(__rhs.data(), __rhs.size()) == 0; } { return __lhs._M_compare(__rhs.data(), __rhs.size()) == 0; }
#if __cpp_lib_three_way_comparison
/**
* @brief Three-way comparison of a regular expression submatch and a string.
* @param __lhs A regular expression submatch.
* @param __rhs A string.
* @returns A value indicating whether `__lhs` is less than, equal to,
* greater than, or incomparable with `__rhs`.
*/
template<typename _Bi_iter, typename _Ch_traits, typename _Alloc>
inline auto
operator<=>(const sub_match<_Bi_iter>& __lhs,
const __sub_match_string<_Bi_iter, _Ch_traits, _Alloc>& __rhs)
noexcept(__detail::__is_contiguous_iter<_Bi_iter>::value)
{
return __detail::__char_traits_cmp_cat<_Ch_traits>(
__lhs._M_compare(__rhs.data(), __rhs.size()));
}
#else
/** /**
* @brief Tests the inequivalence of a regular expression submatch and a * @brief Tests the inequivalence of a regular expression submatch and a
* string. * string.
...@@ -1318,6 +1359,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -1318,6 +1359,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
operator<=(typename iterator_traits<_Bi_iter>::value_type const* __lhs, operator<=(typename iterator_traits<_Bi_iter>::value_type const* __lhs,
const sub_match<_Bi_iter>& __rhs) const sub_match<_Bi_iter>& __rhs)
{ return !(__rhs < __lhs); } { return !(__rhs < __lhs); }
#endif // three-way comparison
/** /**
* @brief Tests the equivalence of a regular expression submatch and a C * @brief Tests the equivalence of a regular expression submatch and a C
...@@ -1332,6 +1374,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -1332,6 +1374,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
typename iterator_traits<_Bi_iter>::value_type const* __rhs) typename iterator_traits<_Bi_iter>::value_type const* __rhs)
{ return __lhs.compare(__rhs) == 0; } { return __lhs.compare(__rhs) == 0; }
#if __cpp_lib_three_way_comparison
/**
* @brief Three-way comparison of a regular expression submatch and a C
* string.
* @param __lhs A regular expression submatch.
* @param __rhs A null-terminated string.
* @returns A value indicating whether `__lhs` is less than, equal to,
* greater than, or incomparable with `__rhs`.
*/
template<typename _Bi_iter>
inline auto
operator<=>(const sub_match<_Bi_iter>& __lhs,
typename iterator_traits<_Bi_iter>::value_type const* __rhs)
noexcept(__detail::__is_contiguous_iter<_Bi_iter>::value)
{
using _Tr = char_traits<typename iterator_traits<_Bi_iter>::value_type>;
return __detail::__char_traits_cmp_cat<_Tr>(__lhs.compare(__rhs));
}
#else
/** /**
* @brief Tests the inequivalence of a regular expression submatch and a * @brief Tests the inequivalence of a regular expression submatch and a
* string. * string.
...@@ -1470,6 +1531,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -1470,6 +1531,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
operator<=(typename iterator_traits<_Bi_iter>::value_type const& __lhs, operator<=(typename iterator_traits<_Bi_iter>::value_type const& __lhs,
const sub_match<_Bi_iter>& __rhs) const sub_match<_Bi_iter>& __rhs)
{ return !(__rhs < __lhs); } { return !(__rhs < __lhs); }
#endif // three-way comparison
/** /**
* @brief Tests the equivalence of a regular expression submatch and a * @brief Tests the equivalence of a regular expression submatch and a
...@@ -1484,6 +1546,27 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -1484,6 +1546,27 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
typename iterator_traits<_Bi_iter>::value_type const& __rhs) typename iterator_traits<_Bi_iter>::value_type const& __rhs)
{ return __lhs._M_compare(std::__addressof(__rhs), 1) == 0; } { return __lhs._M_compare(std::__addressof(__rhs), 1) == 0; }
#if __cpp_lib_three_way_comparison
/**
* @brief Three-way comparison of a regular expression submatch and a
* character.
* @param __lhs A regular expression submatch.
* @param __rhs A character.
* @returns A value indicating whether `__lhs` is less than, equal to,
* greater than, or incomparable with `__rhs`.
*/
template<typename _Bi_iter>
inline auto
operator<=>(const sub_match<_Bi_iter>& __lhs,
typename iterator_traits<_Bi_iter>::value_type const& __rhs)
noexcept(__detail::__is_contiguous_iter<_Bi_iter>::value)
{
using _Tr = char_traits<typename iterator_traits<_Bi_iter>::value_type>;
return __detail::__char_traits_cmp_cat<_Tr>(
__lhs._M_compare(std::__addressof(__rhs), 1));
}
#else
/** /**
* @brief Tests the inequivalence of a regular expression submatch and a * @brief Tests the inequivalence of a regular expression submatch and a
* character. * character.
...@@ -1548,6 +1631,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -1548,6 +1631,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
operator<=(const sub_match<_Bi_iter>& __lhs, operator<=(const sub_match<_Bi_iter>& __lhs,
typename iterator_traits<_Bi_iter>::value_type const& __rhs) typename iterator_traits<_Bi_iter>::value_type const& __rhs)
{ return !(__rhs < __lhs); } { return !(__rhs < __lhs); }
#endif // three-way comparison
/** /**
* @brief Inserts a matched string into an output stream. * @brief Inserts a matched string into an output stream.
...@@ -2031,6 +2115,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -2031,6 +2115,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
&& __m1.suffix() == __m2.suffix(); && __m1.suffix() == __m2.suffix();
} }
#if ! __cpp_lib_three_way_comparison
/** /**
* @brief Compares two match_results for inequality. * @brief Compares two match_results for inequality.
* @returns true if the two objects do not refer to the same match, * @returns true if the two objects do not refer to the same match,
...@@ -2041,6 +2126,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ...@@ -2041,6 +2126,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
operator!=(const match_results<_Bi_iter, _Alloc>& __m1, operator!=(const match_results<_Bi_iter, _Alloc>& __m1,
const match_results<_Bi_iter, _Alloc>& __m2) noexcept const match_results<_Bi_iter, _Alloc>& __m2) noexcept
{ return !(__m1 == __m2); } { return !(__m1 == __m2); }
#endif
// [7.10.6] match_results swap // [7.10.6] match_results swap
/** /**
......
...@@ -494,6 +494,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -494,6 +494,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
noexcept noexcept
{ return __x.size() == __y.size() && __x.compare(__y) == 0; } { return __x.size() == __y.size() && __x.compare(__y) == 0; }
#if __cpp_lib_three_way_comparison
template<typename _CharT, typename _Traits>
constexpr auto
operator<=>(basic_string_view<_CharT, _Traits> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
-> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
{ return __detail::__char_traits_cmp_cat<_Traits>(__x.compare(__y)); }
template<typename _CharT, typename _Traits>
constexpr auto
operator<=>(basic_string_view<_CharT, _Traits> __x,
__type_identity_t<basic_string_view<_CharT, _Traits>> __y)
noexcept
-> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
{ return __detail::__char_traits_cmp_cat<_Traits>(__x.compare(__y)); }
#else
template<typename _CharT, typename _Traits> template<typename _CharT, typename _Traits>
constexpr bool constexpr bool
operator==(__type_identity_t<basic_string_view<_CharT, _Traits>> __x, operator==(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
...@@ -594,6 +610,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -594,6 +610,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator>=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x, operator>=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.compare(__y) >= 0; } { return __x.compare(__y) >= 0; }
#endif // three-way comparison
// [string.view.io], Inserters and extractors // [string.view.io], Inserters and extractors
template<typename _CharT, typename _Traits> template<typename _CharT, typename _Traits>
......
// Copyright (C) 2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } }
// C++20 21.3.3.2 Non-member comparison functions [string.cmp]
// operator==
/*
template<class charT, class traits, class Allocator>
constexpr bool
operator==(const basic_string<charT, traits, Allocator>& lhs,
const basic_string<charT, traits, Allocator>& rhs);
template<class charT, class traits, class Allocator>
constexpr bool
operator==(const basic_string<charT, traits, Allocator>& lhs,
const charT* rhs);
*/
// operator<=>
/*
template<class charT, class traits, class Allocator>
constexpr [see below]
operator<=>(const basic_string<charT, traits, Allocator>& lhs,
const basic_string<charT, traits, Allocator>& rhs);
template<class charT, class traits, class Allocator>
constexpr [see below]
operator<=>(const basic_string<charT,traits,Allocator>& lhs,
const charT* rhs);
*/
#include <string>
#include <testsuite_hooks.h>
void
test01()
{
std::string str_0("costa rica");
std::string str_1("costa marbella");
std::string str_2("cost");
std::string str_3("costa ricans");
std::string str_4;
str_4 = str_0;
//comparisons between string objects
VERIFY( !(str_0 == str_1) );
VERIFY( !(str_0 == str_2) );
VERIFY( !(str_0 == str_3) );
VERIFY( !(str_1 == str_0) );
VERIFY( !(str_2 == str_0) );
VERIFY( !(str_3 == str_0) );
VERIFY( str_4 == str_0 );
VERIFY( str_0 == str_4 );
VERIFY( str_0 != str_1 );
VERIFY( str_0 != str_2 );
VERIFY( str_0 != str_3 );
VERIFY( str_1 != str_0 );
VERIFY( str_2 != str_0 );
VERIFY( str_3 != str_0 );
VERIFY( !(str_0 != str_4) );
VERIFY( !(str_4 != str_0) );
VERIFY( str_0 > str_1 ); //true cuz r>m
VERIFY( str_0 > str_2 );
VERIFY( !(str_0 > str_3) );
VERIFY( !(str_1 > str_0) ); //false cuz m<r
VERIFY( !(str_2 > str_0) );
VERIFY( str_3 > str_0 );
VERIFY( !(str_0 > str_4) );
VERIFY( !(str_4 > str_0) );
VERIFY( !(str_0 < str_1) ); //false cuz r>m
VERIFY( !(str_0 < str_2) );
VERIFY( str_0 < str_3 );
VERIFY( str_1 < str_0 ); //true cuz m<r
VERIFY( str_2 < str_0 );
VERIFY( !(str_3 < str_0) );
VERIFY( !(str_0 < str_4) );
VERIFY( !(str_4 < str_0) );
VERIFY( str_0 >= str_1 ); //true cuz r>m
VERIFY( str_0 >= str_2 );
VERIFY( !(str_0 >= str_3) );
VERIFY( !(str_1 >= str_0) );//false cuz m<r
VERIFY( !(str_2 >= str_0) );
VERIFY( str_3 >= str_0 );
VERIFY( str_0 >= str_4 );
VERIFY( str_4 >= str_0 );
VERIFY( !(str_0 <= str_1) );//false cuz r>m
VERIFY( !(str_0 <= str_2) );
VERIFY( str_0 <= str_3 );
VERIFY( str_1 <= str_0 );//true cuz m<r
VERIFY( str_2 <= str_0 );
VERIFY( !(str_3 <= str_0) );
VERIFY( str_0 <= str_4 );
VERIFY( str_4 <= str_0 );
VERIFY( std::is_gt(str_0 <=> str_1) );
VERIFY( std::is_gt(str_0 <=> str_2) );
VERIFY( std::is_lt(str_0 <=> str_3) );
VERIFY( std::is_eq(str_0 <=> str_4) );
VERIFY( std::is_lt(str_1 <=> str_0) );
VERIFY( std::is_lt(str_2 <=> str_0) );
VERIFY( std::is_gt(str_3 <=> str_0) );
VERIFY( std::is_eq(str_4 <=> str_0) );
//comparisons between string object and string literal
VERIFY( !(str_0 == "costa marbella") );
VERIFY( !(str_0 == "cost") );
VERIFY( !(str_0 == "costa ricans") );
VERIFY( !("costa marbella" == str_0) );
VERIFY( !("cost" == str_0) );
VERIFY( !("costa ricans" == str_0) );
VERIFY( "costa rica" == str_0 );
VERIFY( str_0 == "costa rica" );
VERIFY( str_0 != "costa marbella" );
VERIFY( str_0 != "cost" );
VERIFY( str_0 != "costa ricans" );
VERIFY( "costa marbella" != str_0 );
VERIFY( "cost" != str_0 );
VERIFY( "costa ricans" != str_0 );
VERIFY( !("costa rica" != str_0) );
VERIFY( !(str_0 != "costa rica") );
VERIFY( str_0 > "costa marbella" ); //true cuz r>m
VERIFY( str_0 > "cost" );
VERIFY( !(str_0 > "costa ricans") );
VERIFY( !("costa marbella" > str_0) );//false cuz m<r
VERIFY( !("cost" > str_0) );
VERIFY( "costa ricans" > str_0 );
VERIFY( !("costa rica" > str_0) );
VERIFY( !(str_0 > "costa rica") );
VERIFY( !(str_0 < "costa marbella") );//false cuz r>m
VERIFY( !(str_0 < "cost") );
VERIFY( str_0 < "costa ricans" );
VERIFY( "costa marbella" < str_0 );//true cuz m<r
VERIFY( "cost" < str_0 );
VERIFY( !("costa ricans" < str_0) );
VERIFY( !("costa rica" < str_0) );
VERIFY( !(str_0 < "costa rica") );
VERIFY( str_0 >= "costa marbella" );//true cuz r>m
VERIFY( str_0 >= "cost" );
VERIFY( !(str_0 >= "costa ricans") );
VERIFY( !("costa marbella" >= str_0) );//false cuz m<r
VERIFY( !("cost" >= str_0) );
VERIFY( "costa ricans" >= str_0 );
VERIFY( "costa rica" >= str_0 );
VERIFY( str_0 >= "costa rica" );
VERIFY( !(str_0 <= "costa marbella") );//false cuz r>m
VERIFY( !(str_0 <= "cost") );
VERIFY( str_0 <= "costa ricans" );
VERIFY( "costa marbella" <= str_0 );//true cuz m<r
VERIFY( "cost" <= str_0 );
VERIFY( !("costa ricans" <= str_0) );
VERIFY( "costa rica" <= str_0 );
VERIFY( str_0 <= "costa rica" );
VERIFY( std::is_gt(str_0 <=> "costa marbella") );
VERIFY( std::is_gt(str_0 <=> "cost") );
VERIFY( std::is_lt(str_0 <=> "costa ricans") );
VERIFY( std::is_eq(str_0 <=> "costa rica") );
VERIFY( std::is_lt("costa marbella" <=> str_0) );
VERIFY( std::is_lt("cost" <=> str_0) );
VERIFY( std::is_gt("costa ricans" <=> str_0) );
VERIFY( std::is_eq("costa rica" <=> str_0) );
}
int main()
{
test01();
}
// Copyright (C) 2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } }
// C++20 21.3.3.2 Non-member comparison functions [string.cmp]
// operator==
/*
template<class charT, class traits, class Allocator>
constexpr bool
operator==(const basic_string<charT, traits, Allocator>& lhs,
const basic_string<charT, traits, Allocator>& rhs);
template<class charT, class traits, class Allocator>
constexpr bool
operator==(const basic_string<charT, traits, Allocator>& lhs,
const charT* rhs);
*/
// operator<=>
/*
template<class charT, class traits, class Allocator>
constexpr [see below]
operator<=>(const basic_string<charT, traits, Allocator>& lhs,
const basic_string<charT, traits, Allocator>& rhs);
template<class charT, class traits, class Allocator>
constexpr [see below]
operator<=>(const basic_string<charT,traits,Allocator>& lhs,
const charT* rhs);
*/
#include <string>
#include <testsuite_hooks.h>
void
test01()
{
std::wstring str_0(L"costa rica");
std::wstring str_1(L"costa marbella");
std::wstring str_2(L"cost");
std::wstring str_3(L"costa ricans");
std::wstring str_4;
str_4 = str_0;
//comparisons between string objects
VERIFY( !(str_0 == str_1) );
VERIFY( !(str_0 == str_2) );
VERIFY( !(str_0 == str_3) );
VERIFY( !(str_1 == str_0) );
VERIFY( !(str_2 == str_0) );
VERIFY( !(str_3 == str_0) );
VERIFY( str_4 == str_0 );
VERIFY( str_0 == str_4 );
VERIFY( str_0 != str_1 );
VERIFY( str_0 != str_2 );
VERIFY( str_0 != str_3 );
VERIFY( str_1 != str_0 );
VERIFY( str_2 != str_0 );
VERIFY( str_3 != str_0 );
VERIFY( !(str_0 != str_4) );
VERIFY( !(str_4 != str_0) );
VERIFY( str_0 > str_1 ); //true cuz r>m
VERIFY( str_0 > str_2 );
VERIFY( !(str_0 > str_3) );
VERIFY( !(str_1 > str_0) ); //false cuz m<r
VERIFY( !(str_2 > str_0) );
VERIFY( str_3 > str_0 );
VERIFY( !(str_0 > str_4) );
VERIFY( !(str_4 > str_0) );
VERIFY( !(str_0 < str_1) ); //false cuz r>m
VERIFY( !(str_0 < str_2) );
VERIFY( str_0 < str_3 );
VERIFY( str_1 < str_0 ); //true cuz m<r
VERIFY( str_2 < str_0 );
VERIFY( !(str_3 < str_0) );
VERIFY( !(str_0 < str_4) );
VERIFY( !(str_4 < str_0) );
VERIFY( str_0 >= str_1 ); //true cuz r>m
VERIFY( str_0 >= str_2 );
VERIFY( !(str_0 >= str_3) );
VERIFY( !(str_1 >= str_0) );//false cuz m<r
VERIFY( !(str_2 >= str_0) );
VERIFY( str_3 >= str_0 );
VERIFY( str_0 >= str_4 );
VERIFY( str_4 >= str_0 );
VERIFY( !(str_0 <= str_1) );//false cuz r>m
VERIFY( !(str_0 <= str_2) );
VERIFY( str_0 <= str_3 );
VERIFY( str_1 <= str_0 );//true cuz m<r
VERIFY( str_2 <= str_0 );
VERIFY( !(str_3 <= str_0) );
VERIFY( str_0 <= str_4 );
VERIFY( str_4 <= str_0 );
VERIFY( std::is_gt(str_0 <=> str_1) );
VERIFY( std::is_gt(str_0 <=> str_2) );
VERIFY( std::is_lt(str_0 <=> str_3) );
VERIFY( std::is_eq(str_0 <=> str_4) );
VERIFY( std::is_lt(str_1 <=> str_0) );
VERIFY( std::is_lt(str_2 <=> str_0) );
VERIFY( std::is_gt(str_3 <=> str_0) );
VERIFY( std::is_eq(str_4 <=> str_0) );
//comparisons between string object and string literal
VERIFY( !(str_0 == L"costa marbella") );
VERIFY( !(str_0 == L"cost") );
VERIFY( !(str_0 == L"costa ricans") );
VERIFY( !(L"costa marbella" == str_0) );
VERIFY( !(L"cost" == str_0) );
VERIFY( !(L"costa ricans" == str_0) );
VERIFY( L"costa rica" == str_0 );
VERIFY( str_0 == L"costa rica" );
VERIFY( str_0 != L"costa marbella" );
VERIFY( str_0 != L"cost" );
VERIFY( str_0 != L"costa ricans" );
VERIFY( L"costa marbella" != str_0 );
VERIFY( L"cost" != str_0 );
VERIFY( L"costa ricans" != str_0 );
VERIFY( !(L"costa rica" != str_0) );
VERIFY( !(str_0 != L"costa rica") );
VERIFY( str_0 > L"costa marbella" ); //true cuz r>m
VERIFY( str_0 > L"cost" );
VERIFY( !(str_0 > L"costa ricans") );
VERIFY( !(L"costa marbella" > str_0) );//false cuz m<r
VERIFY( !(L"cost" > str_0) );
VERIFY( L"costa ricans" > str_0 );
VERIFY( !(L"costa rica" > str_0) );
VERIFY( !(str_0 > L"costa rica") );
VERIFY( !(str_0 < L"costa marbella") );//false cuz r>m
VERIFY( !(str_0 < L"cost") );
VERIFY( str_0 < L"costa ricans" );
VERIFY( L"costa marbella" < str_0 );//true cuz m<r
VERIFY( L"cost" < str_0 );
VERIFY( !(L"costa ricans" < str_0) );
VERIFY( !(L"costa rica" < str_0) );
VERIFY( !(str_0 < L"costa rica") );
VERIFY( str_0 >= L"costa marbella" );//true cuz r>m
VERIFY( str_0 >= L"cost" );
VERIFY( !(str_0 >= L"costa ricans") );
VERIFY( !(L"costa marbella" >= str_0) );//false cuz m<r
VERIFY( !(L"cost" >= str_0) );
VERIFY( L"costa ricans" >= str_0 );
VERIFY( L"costa rica" >= str_0 );
VERIFY( str_0 >= L"costa rica" );
VERIFY( !(str_0 <= L"costa marbella") );//false cuz r>m
VERIFY( !(str_0 <= L"cost") );
VERIFY( str_0 <= L"costa ricans" );
VERIFY( L"costa marbella" <= str_0 );//true cuz m<r
VERIFY( L"cost" <= str_0 );
VERIFY( !(L"costa ricans" <= str_0) );
VERIFY( L"costa rica" <= str_0 );
VERIFY( str_0 <= L"costa rica" );
VERIFY( std::is_gt(str_0 <=> L"costa marbella") );
VERIFY( std::is_gt(str_0 <=> L"cost") );
VERIFY( std::is_lt(str_0 <=> L"costa ricans") );
VERIFY( std::is_eq(str_0 <=> L"costa rica") );
VERIFY( std::is_lt(L"costa marbella" <=> str_0) );
VERIFY( std::is_lt(L"cost" <=> str_0) );
VERIFY( std::is_gt(L"costa ricans" <=> str_0) );
VERIFY( std::is_eq(L"costa rica" <=> str_0) );
}
int main()
{
test01();
}
...@@ -24,7 +24,7 @@ constexpr bool ...@@ -24,7 +24,7 @@ constexpr bool
test01() test01()
{ {
std::string_view s = "Everything changes and nothing stands still."; std::string_view s = "Everything changes and nothing stands still.";
char buf[7]; char buf[7]{};
auto n = s.copy(buf, 7, 11); auto n = s.copy(buf, 7, 11);
return std::string_view(buf, n) == "changes"; return std::string_view(buf, n) == "changes";
} }
......
...@@ -24,7 +24,7 @@ constexpr bool ...@@ -24,7 +24,7 @@ constexpr bool
test01() test01()
{ {
std::wstring_view s = L"Everything changes and nothing stands still."; std::wstring_view s = L"Everything changes and nothing stands still.";
wchar_t buf[7]; wchar_t buf[7]{};
auto n = s.copy(buf, 7, 11); auto n = s.copy(buf, 7, 11);
return std::wstring_view(buf, n) == L"changes"; return std::wstring_view(buf, n) == L"changes";
} }
......
// { dg-options "-std=gnu++17" } // { dg-options "-std=gnu++17" }
// { dg-do run { target c++17 } }
// Copyright (C) 2013-2020 Free Software Foundation, Inc. // Copyright (C) 2013-2020 Free Software Foundation, Inc.
// //
...@@ -17,97 +18,7 @@ ...@@ -17,97 +18,7 @@
// with this library; see the file COPYING3. If not see // with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>. // <http://www.gnu.org/licenses/>.
// basic_string non-member functions // C++17 24.4.3 Non-member comparison functions [string.view.comparison]
// operator==
/*
template<class charT, class traits, class Allocator>
bool operator==(const basic_string<charT,traits,Allocator>& lhs,
const basic_string<charT,traits,Allocator>& rhs);
template<class charT, class traits, class Allocator>
bool operator==(const charT* lhs,
const basic_string<charT,traits,Allocator>& rhs);
template<class charT, class traits, class Allocator>
bool operator==(const basic_string<charT,traits,Allocator>& lhs,
const charT* rhs);
*/
// operator!=
/*
template<class charT, class traits, class Allocator>
bool operator!=(const basic_string<charT,traits,Allocator>& lhs,
const basic_string<charT,traits,Allocator>& rhs);
template<class charT, class traits, class Allocator>
bool operator!=(const charT* lhs,
const basic_string<charT,traits,Allocator>& rhs);
template<class charT, class traits, class Allocator>
bool operator!=(const basic_string<charT,traits,Allocator>& lhs,
const charT* rhs);
*/
// operator<
/*
template<class charT, class traits, class Allocator>
bool operator< (const basic_string<charT,traits,Allocator>& lhs,
const basic_string<charT,traits,Allocator>& rhs);
template<class charT, class traits, class Allocator>
bool operator< (const basic_string<charT,traits,Allocator>& lhs,
const charT* rhs);
template<class charT, class traits, class Allocator>
bool operator< (const charT* lhs,
const basic_string<charT,traits,Allocator>& rhs);
*/
// operator>
/*
template<class charT, class traits, class Allocator>
bool operator> (const basic_string<charT,traits,Allocator>& lhs,
const basic_string<charT,traits,Allocator>& rhs);
template<class charT, class traits, class Allocator>
bool operator> (const basic_string<charT,traits,Allocator>& lhs,
const charT* rhs);
template<class charT, class traits, class Allocator>
bool operator> (const charT* lhs,
const basic_string<charT,traits,Allocator>& rhs);
*/
// operator<=
/*
template<class charT, class traits, class Allocator>
bool operator<=(const basic_string<charT,traits,Allocator>& lhs,
const basic_string<charT,traits,Allocator>& rhs);
template<class charT, class traits, class Allocator>
bool operator<=(const basic_string<charT,traits,Allocator>& lhs,
const charT* rhs);
template<class charT, class traits, class Allocator>
bool operator<=(const charT* lhs,
const basic_string<charT,traits,Allocator>& rhs);
*/
// operator>=
/*
template<class charT, class traits, class Allocator>
bool operator>=(const basic_string<charT,traits,Allocator>& lhs,
const basic_string<charT,traits,Allocator>& rhs);
template<class charT, class traits, class Allocator>
bool operator>=(const basic_string<charT,traits,Allocator>& lhs,
const charT* rhs);
template<class charT, class traits, class Allocator>
bool operator>=(const charT* lhs,
const basic_string<charT,traits,Allocator>& rhs);
*/
#include <string_view> #include <string_view>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
......
// { dg-options "-std=gnu++17" } // { dg-options "-std=gnu++17" }
// { dg-do run { target c++17 } }
// Copyright (C) 2013-2020 Free Software Foundation, Inc. // Copyright (C) 2013-2020 Free Software Foundation, Inc.
// //
...@@ -17,97 +18,7 @@ ...@@ -17,97 +18,7 @@
// with this library; see the file COPYING3. If not see // with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>. // <http://www.gnu.org/licenses/>.
// basic_string_view non-member functions // C++17 24.4.3 Non-member comparison functions [string.view.comparison]
// operator==
/*
template<class charT, class traits, class Allocator>
bool operator==(const basic_string_view<charT,traits,Allocator>& lhs,
const basic_string_view<charT,traits,Allocator>& rhs);
template<class charT, class traits, class Allocator>
bool operator==(const charT* lhs,
const basic_string_view<charT,traits,Allocator>& rhs);
template<class charT, class traits, class Allocator>
bool operator==(const basic_string_view<charT,traits,Allocator>& lhs,
const charT* rhs);
*/
// operator!=
/*
template<class charT, class traits, class Allocator>
bool operator!=(const basic_string_view<charT,traits,Allocator>& lhs,
const basic_string_view<charT,traits,Allocator>& rhs);
template<class charT, class traits, class Allocator>
bool operator!=(const charT* lhs,
const basic_string_view<charT,traits,Allocator>& rhs);
template<class charT, class traits, class Allocator>
bool operator!=(const basic_string_view<charT,traits,Allocator>& lhs,
const charT* rhs);
*/
// operator<
/*
template<class charT, class traits, class Allocator>
bool operator< (const basic_string_view<charT,traits,Allocator>& lhs,
const basic_string_view<charT,traits,Allocator>& rhs);
template<class charT, class traits, class Allocator>
bool operator< (const basic_string_view<charT,traits,Allocator>& lhs,
const charT* rhs);
template<class charT, class traits, class Allocator>
bool operator< (const charT* lhs,
const basic_string_view<charT,traits,Allocator>& rhs);
*/
// operator>
/*
template<class charT, class traits, class Allocator>
bool operator> (const basic_string_view<charT,traits,Allocator>& lhs,
const basic_string_view<charT,traits,Allocator>& rhs);
template<class charT, class traits, class Allocator>
bool operator> (const basic_string_view<charT,traits,Allocator>& lhs,
const charT* rhs);
template<class charT, class traits, class Allocator>
bool operator> (const charT* lhs,
const basic_string_view<charT,traits,Allocator>& rhs);
*/
// operator<=
/*
template<class charT, class traits, class Allocator>
bool operator<=(const basic_string_view<charT,traits,Allocator>& lhs,
const basic_string_view<charT,traits,Allocator>& rhs);
template<class charT, class traits, class Allocator>
bool operator<=(const basic_string_view<charT,traits,Allocator>& lhs,
const charT* rhs);
template<class charT, class traits, class Allocator>
bool operator<=(const charT* lhs,
const basic_string_view<charT,traits,Allocator>& rhs);
*/
// operator>=
/*
template<class charT, class traits, class Allocator>
bool operator>=(const basic_string_view<charT,traits,Allocator>& lhs,
const basic_string_view<charT,traits,Allocator>& rhs);
template<class charT, class traits, class Allocator>
bool operator>=(const basic_string_view<charT,traits,Allocator>& lhs,
const charT* rhs);
template<class charT, class traits, class Allocator>
bool operator>=(const charT* lhs,
const basic_string_view<charT,traits,Allocator>& rhs);
*/
#include <string_view> #include <string_view>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
......
// Copyright (C) 2018-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } }
#include <regex>
#include <testsuite_hooks.h>
#include <testsuite_iterators.h>
using __gnu_test::test_container;
using __gnu_test::bidirectional_iterator_wrapper;
template<typename C> struct traits : std::char_traits<C> { };
void
test01()
{
const std::basic_string<char, traits<char>> s0, s1 = "1";
const std::ssub_match sm, sm2;
VERIFY( sm.compare(sm) == 0 );
VERIFY( sm.compare(sm2) == 0 );
VERIFY( sm.compare(sm.str()) == 0 );
VERIFY( sm.compare(sm.str().c_str()) == 0 );
VERIFY( sm.compare(sm2.str()) == 0 );
VERIFY( sm.compare(sm2.str().c_str()) == 0 );
VERIFY( sm.compare(std::string(s1.c_str())) == -1 );
VERIFY( sm.compare(s1.c_str()) == -1 );
VERIFY( sm == sm2 );
VERIFY( !(sm != sm2) );
VERIFY( !(sm < sm2) );
VERIFY( !(sm > sm2) );
VERIFY( sm <= sm2 );
VERIFY( sm >= sm2 );
VERIFY( std::is_eq(sm <=> sm2) );
VERIFY( sm == s0 );
VERIFY( !(sm != s0) );
VERIFY( !(sm < s0) );
VERIFY( !(sm > s0) );
VERIFY( sm <= s0 );
VERIFY( sm >= s0 );
VERIFY( std::is_eq(sm <=> s0) );
VERIFY( s0 == sm );
VERIFY( !(s0 != sm) );
VERIFY( !(s0 < sm) );
VERIFY( !(s0 > sm) );
VERIFY( s0 <= sm );
VERIFY( s0 >= sm );
VERIFY( std::is_eq(s0 <=> sm) );
VERIFY( sm == s0.c_str() );
VERIFY( !(sm != s0.c_str()) );
VERIFY( !(sm < s0.c_str()) );
VERIFY( !(sm > s0.c_str()) );
VERIFY( sm <= s0.c_str() );
VERIFY( sm >= s0.c_str() );
VERIFY( std::is_eq(sm <=> s0.c_str()) );
VERIFY( s0.c_str() == sm );
VERIFY( !(s0.c_str() != sm) );
VERIFY( !(s0.c_str() < sm) );
VERIFY( !(s0.c_str() > sm) );
VERIFY( s0.c_str() <= sm );
VERIFY( s0.c_str() >= sm );
VERIFY( std::is_eq(s0.c_str() <=> sm) );
VERIFY( !(sm == s1) );
VERIFY( sm != s1 );
VERIFY( sm < s1 );
VERIFY( !(sm > s1) );
VERIFY( sm <= s1 );
VERIFY( !(sm >= s1) );
VERIFY( std::is_lt(sm <=> s1) );
VERIFY( !(sm == s1.c_str()) );
VERIFY( sm != s1.c_str() );
VERIFY( sm < s1.c_str() );
VERIFY( !(sm > s1.c_str()) );
VERIFY( sm <= s1.c_str() );
VERIFY( !(sm >= s1.c_str()) );
VERIFY( std::is_lt(sm <=> s1.c_str()) );
VERIFY( !(s1.c_str() == sm) );
VERIFY( s1.c_str() != sm );
VERIFY( !(s1.c_str() < sm) );
VERIFY( s1.c_str() > sm );
VERIFY( !(s1.c_str() <= sm) );
VERIFY( s1.c_str() >= sm );
VERIFY( std::is_gt(s1.c_str() <=> sm) );
VERIFY( !(sm == s1[0]) );
VERIFY( sm != s1[0] );
VERIFY( sm < s1[0] );
VERIFY( !(sm > s1[0]) );
VERIFY( sm <= s1[0] );
VERIFY( !(sm >= s1[0]) );
VERIFY( std::is_lt(sm <=> s1[0]) );
VERIFY( !(s1[0] == sm) );
VERIFY( s1[0] != sm );
VERIFY( !(s1[0] < sm) );
VERIFY( s1[0] > sm );
VERIFY( !(s1[0] <= sm) );
VERIFY( s1[0] >= sm );
VERIFY( std::is_gt(s1[0] <=> sm) );
}
void
test02()
{
const std::basic_string<char, traits<char>> s0, s1 = "1";
std::csub_match sm;
const std::csub_match sm2;
const char c[] = "1";
sm.matched = true;
sm.first = c;
sm.second = c+1;
VERIFY( sm.compare(sm) == 0 );
VERIFY( sm.compare(sm2) == 1 );
VERIFY( sm.compare(sm.str()) == 0 );
VERIFY( sm.compare(sm.str().c_str()) == 0 );
VERIFY( sm.compare(sm2.str()) == 1 );
VERIFY( sm.compare(sm2.str().c_str()) == 1 );
VERIFY( sm.compare(std::string(s1.c_str())) == 0 );
VERIFY( sm.compare(s1.c_str()) == 0 );
VERIFY( !(sm == sm2) );
VERIFY( sm != sm2 );
VERIFY( !(sm < sm2) );
VERIFY( sm > sm2 );
VERIFY( !(sm <= sm2) );
VERIFY( sm >= sm2 );
VERIFY( std::is_gt(sm <=> sm2) );
VERIFY( !(sm2 == sm) );
VERIFY( sm2 != sm );
VERIFY( sm2 < sm );
VERIFY( !(sm2 > sm) );
VERIFY( sm2 <= sm );
VERIFY( !(sm2 >= sm) );
VERIFY( std::is_lt(sm2 <=> sm) );
VERIFY( !(sm == s0) );
VERIFY( sm != s0 );
VERIFY( !(sm < s0) );
VERIFY( sm > s0 );
VERIFY( !(sm <= s0) );
VERIFY( sm >= s0 );
VERIFY( std::is_gt(sm <=> s0) );
VERIFY( !(sm == s0.c_str()) );
VERIFY( sm != s0.c_str() );
VERIFY( !(sm < s0.c_str()) );
VERIFY( sm > s0.c_str() );
VERIFY( !(sm <= s0.c_str()) );
VERIFY( sm >= s0.c_str() );
VERIFY( std::is_gt(sm <=> s0.c_str()) );
VERIFY( !(s0.c_str() == sm) );
VERIFY( s0.c_str() != sm );
VERIFY( s0.c_str() < sm );
VERIFY( !(s0.c_str() > sm) );
VERIFY( s0.c_str() <= sm );
VERIFY( !(s0.c_str() >= sm) );
VERIFY( std::is_lt(s0.c_str() <=> sm) );
VERIFY( s1 == sm );
VERIFY( !(s1 != sm) );
VERIFY( !(s1 < sm) );
VERIFY( !(s1 > sm) );
VERIFY( s1 <= sm );
VERIFY( s1 >= sm );
VERIFY( std::is_eq(s1 <=> sm) );
VERIFY( sm == s1.c_str() );
VERIFY( !(sm != s1.c_str()) );
VERIFY( !(sm < s1.c_str()) );
VERIFY( !(sm > s1.c_str()) );
VERIFY( sm <= s1.c_str() );
VERIFY( sm >= s1.c_str() );
VERIFY( std::is_eq(sm <=> s1.c_str()) );
VERIFY( s1.c_str() == sm );
VERIFY( !(s1.c_str() != sm) );
VERIFY( !(s1.c_str() < sm) );
VERIFY( !(s1.c_str() > sm) );
VERIFY( s1.c_str() <= sm );
VERIFY( s1.c_str() >= sm );
VERIFY( std::is_eq(s1.c_str() <=> sm) );
VERIFY( sm == s1[0] );
VERIFY( !(sm != s1[0]) );
VERIFY( !(sm < s1[0]) );
VERIFY( !(sm > s1[0]) );
VERIFY( sm <= s1[0] );
VERIFY( sm >= s1[0] );
VERIFY( std::is_eq(sm <=> s1[0]) );
VERIFY( s1[0] == sm );
VERIFY( !(s1[0] != sm) );
VERIFY( !(s1[0] < sm) );
VERIFY( !(s1[0] > sm) );
VERIFY( s1[0] <= sm );
VERIFY( s1[0] >= sm );
VERIFY( std::is_eq(s1[0] <=> sm) );
}
void
test03()
{
const std::basic_string<char, traits<char>> s0, s1 = "1";
const char c[] = "1";
test_container<const char, bidirectional_iterator_wrapper> tc(c, c+1);
std::sub_match<bidirectional_iterator_wrapper<const char>> sm;
const std::sub_match<bidirectional_iterator_wrapper<const char>> sm2;
sm.matched = true;
sm.first = tc.begin();
sm.second = tc.end();
VERIFY( sm.compare(sm) == 0 );
VERIFY( sm.compare(sm2) == 1 );
VERIFY( sm.compare(sm.str()) == 0 );
VERIFY( sm.compare(sm.str().c_str()) == 0 );
VERIFY( sm.compare(sm2.str()) == 1 );
VERIFY( sm.compare(sm2.str().c_str()) == 1 );
VERIFY( sm.compare(std::string(s1.c_str())) == 0 );
VERIFY( sm.compare(s1.c_str()) == 0 );
VERIFY( !(sm == sm2) );
VERIFY( sm != sm2 );
VERIFY( !(sm < sm2) );
VERIFY( sm > sm2 );
VERIFY( !(sm <= sm2) );
VERIFY( sm >= sm2 );
VERIFY( std::is_gt(sm <=> sm2) );
VERIFY( !(sm2 == sm) );
VERIFY( sm2 != sm );
VERIFY( sm2 < sm );
VERIFY( !(sm2 > sm) );
VERIFY( sm2 <= sm );
VERIFY( !(sm2 >= sm) );
VERIFY( std::is_lt(sm2 <=> sm) );
VERIFY( !(sm == s0) );
VERIFY( sm != s0 );
VERIFY( !(sm < s0) );
VERIFY( sm > s0 );
VERIFY( !(sm <= s0) );
VERIFY( sm >= s0 );
VERIFY( std::is_gt(sm <=> s0) );
VERIFY( !(sm == s0.c_str()) );
VERIFY( sm != s0.c_str() );
VERIFY( !(sm < s0.c_str()) );
VERIFY( sm > s0.c_str() );
VERIFY( !(sm <= s0.c_str()) );
VERIFY( sm >= s0.c_str() );
VERIFY( std::is_gt(sm <=> s0.c_str()) );
VERIFY( !(s0.c_str() == sm) );
VERIFY( s0.c_str() != sm );
VERIFY( s0.c_str() < sm );
VERIFY( !(s0.c_str() > sm) );
VERIFY( s0.c_str() <= sm );
VERIFY( !(s0.c_str() >= sm) );
VERIFY( std::is_lt(s0.c_str() <=> sm) );
VERIFY( s1 == sm );
VERIFY( !(s1 != sm) );
VERIFY( !(s1 < sm) );
VERIFY( !(s1 > sm) );
VERIFY( s1 <= sm );
VERIFY( s1 >= sm );
VERIFY( std::is_eq(s1 <=> sm) );
VERIFY( sm == s1.c_str() );
VERIFY( !(sm != s1.c_str()) );
VERIFY( !(sm < s1.c_str()) );
VERIFY( !(sm > s1.c_str()) );
VERIFY( sm <= s1.c_str() );
VERIFY( sm >= s1.c_str() );
VERIFY( std::is_eq(sm <=> s1.c_str()) );
VERIFY( s1.c_str() == sm );
VERIFY( !(s1.c_str() != sm) );
VERIFY( !(s1.c_str() < sm) );
VERIFY( !(s1.c_str() > sm) );
VERIFY( s1.c_str() <= sm );
VERIFY( s1.c_str() >= sm );
VERIFY( std::is_eq(s1.c_str() <=> sm) );
VERIFY( sm == s1[0] );
VERIFY( !(sm != s1[0]) );
VERIFY( !(sm < s1[0]) );
VERIFY( !(sm > s1[0]) );
VERIFY( sm <= s1[0] );
VERIFY( sm >= s1[0] );
VERIFY( std::is_eq(sm <=> s1[0]) );
VERIFY( s1[0] == sm );
VERIFY( !(s1[0] != sm) );
VERIFY( !(s1[0] < sm) );
VERIFY( !(s1[0] > sm) );
VERIFY( s1[0] <= sm );
VERIFY( s1[0] >= sm );
VERIFY( std::is_eq(s1[0] <=> sm) );
}
int main()
{
test01();
test02();
test03();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment