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.
+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>
* testsuite/20_util/unsynchronized_pool_resource/allocate.cc: Remove
&& !std::char_traits<_CharT>::compare(__lhs.data(), __rhs.data(),
__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.
* @param __lhs String.
const _CharT* __rhs)
{ 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 !=
/**
* @brief Test difference of two strings.
operator>=(const _CharT* __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
{ return __rhs.compare(__lhs) <= 0; }
+#endif // three-way comparison
/**
* @brief Swap contents of two strings.
#include <bits/stl_algobase.h> // std::copy, std::fill_n
#include <bits/postypes.h> // For streampos
#include <cwchar> // For WEOF, wmemmove, wmemset, etc.
+#if __cplusplus > 201703L
+# include <compare>
+#endif
#ifndef _GLIBCXX_ALWAYS_INLINE
# define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
typedef typename _Char_types<_CharT>::pos_type pos_type;
typedef typename _Char_types<_CharT>::off_type off_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
assign(char_type& __c1, const char_type& __c2)
typedef streampos pos_type;
typedef streamoff off_type;
typedef mbstate_t state_type;
+#if __cpp_lib_three_way_comparison
+ using comparison_category = strong_ordering;
+#endif
static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
typedef streamoff off_type;
typedef wstreampos pos_type;
typedef mbstate_t state_type;
+#if __cpp_lib_three_way_comparison
+ using comparison_category = strong_ordering;
+#endif
static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
typedef u8streampos pos_type;
typedef streamoff off_type;
typedef mbstate_t state_type;
+#if __cpp_lib_three_way_comparison
+ using comparison_category = strong_ordering;
+#endif
static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
typedef streamoff off_type;
typedef u16streampos pos_type;
typedef mbstate_t state_type;
+#if __cpp_lib_three_way_comparison
+ using comparison_category = strong_ordering;
+#endif
static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) noexcept
typedef streamoff off_type;
typedef u32streampos pos_type;
typedef mbstate_t state_type;
+#if __cpp_lib_three_way_comparison
+ using comparison_category = strong_ordering;
+#endif
static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) noexcept
{ 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
} // namespace
&& _M_base == __other._M_base;
}
+#if __cpp_impl_three_way_comparison < 201907L
constexpr bool
operator!=(_RegexMask __other) const
{ return !((*this) == __other); }
-
+#endif
};
+
public:
typedef _RegexMask char_class_type;
operator==(const sub_match<_BiIter>& __lhs, const sub_match<_BiIter>& __rhs)
{ 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.
* @param __lhs First regular expression submatch.
inline bool
operator>(const sub_match<_BiIter>& __lhs, const sub_match<_BiIter>& __rhs)
{ return __lhs.compare(__rhs) > 0; }
+#endif // three-way comparison
/// @cond undocumented
_Ch_traits, _Ch_alloc>;
/// @endcond
+#if ! __cpp_lib_three_way_comparison
/**
* @brief Tests the equivalence of a string and a regular expression
* submatch.
operator<=(const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __lhs,
const sub_match<_Bi_iter>& __rhs)
{ return !(__rhs < __lhs); }
+#endif // three-way comparison
/**
* @brief Tests the equivalence of a regular expression submatch and a
const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __rhs)
{ 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
* string.
operator<=(typename iterator_traits<_Bi_iter>::value_type const* __lhs,
const sub_match<_Bi_iter>& __rhs)
{ return !(__rhs < __lhs); }
+#endif // three-way comparison
/**
* @brief Tests the equivalence of a regular expression submatch and a C
typename iterator_traits<_Bi_iter>::value_type const* __rhs)
{ 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
* string.
operator<=(typename iterator_traits<_Bi_iter>::value_type const& __lhs,
const sub_match<_Bi_iter>& __rhs)
{ return !(__rhs < __lhs); }
+#endif // three-way comparison
/**
* @brief Tests the equivalence of a regular expression submatch and a
typename iterator_traits<_Bi_iter>::value_type const& __rhs)
{ 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
* character.
operator<=(const sub_match<_Bi_iter>& __lhs,
typename iterator_traits<_Bi_iter>::value_type const& __rhs)
{ return !(__rhs < __lhs); }
+#endif // three-way comparison
/**
* @brief Inserts a matched string into an output stream.
&& __m1.suffix() == __m2.suffix();
}
+#if ! __cpp_lib_three_way_comparison
/**
* @brief Compares two match_results for inequality.
* @returns true if the two objects do not refer to the same match,
operator!=(const match_results<_Bi_iter, _Alloc>& __m1,
const match_results<_Bi_iter, _Alloc>& __m2) noexcept
{ return !(__m1 == __m2); }
+#endif
// [7.10.6] match_results swap
/**
noexcept
{ 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>
constexpr bool
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
{ return __x.compare(__y) >= 0; }
+#endif // three-way comparison
// [string.view.io], Inserters and extractors
template<typename _CharT, typename _Traits>
--- /dev/null
+// 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();
+}
--- /dev/null
+// 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();
+}
test01()
{
std::string_view s = "Everything changes and nothing stands still.";
- char buf[7];
+ char buf[7]{};
auto n = s.copy(buf, 7, 11);
return std::string_view(buf, n) == "changes";
}
test01()
{
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);
return std::wstring_view(buf, n) == L"changes";
}
// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++17 } }
// Copyright (C) 2013-2020 Free Software Foundation, Inc.
//
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// basic_string non-member functions
-
-// 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);
-*/
+// C++17 24.4.3 Non-member comparison functions [string.view.comparison]
#include <string_view>
#include <testsuite_hooks.h>
--- /dev/null
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+// 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/>.
+
+// C++20 21.4.4 Non-member comparison functions [string.view.comparisons]
+
+// operator==
+/*
+template<class charT, class traits>
+ constexpr bool
+ operator==(basic_string_view<charT, traits> lhs,
+ basic_string_view<charT, traits> rhs) noexcept;
+
+template<class charT, class traits>
+ constexpr bool
+ operator==(basic_string_view<charT, traits> lhs,
+ type_identity_t<basic_string_view<charT, traits>> rhs) noexcept;
+*/
+
+// operator<=>
+/*
+template<class charT, class traits>
+ constexpr [see below]
+ operator<=>(basic_string_view<charT, traits> lhs,
+ basic_string_view<charT, traits> rhs) noexcept;
+
+template<class charT, class traits>
+ constexpr [see below]
+ operator<=>(basic_string_view<charT, traits> lhs,
+ type_identity_t<basic_string_view<charT, traits>> rhs) noexcept;
+*/
+
+#include <string_view>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ std::string_view str_0("costa rica");
+ std::string_view str_1("costa marbella");
+ std::string_view str_2("cost");
+ std::string_view str_3("costa ricans");
+ std::string_view 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) );
+}
+
+constexpr bool
+test02()
+{
+ std::string_view str_0("costa rica");
+ std::string_view str_1("costa marbella");
+ std::string_view str_2("cost");
+ std::string_view str_3("costa ricans");
+ std::string_view str_4;
+
+#undef VERIFY
+#define VERIFY(x) if (!(x)) return false
+
+ 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) );
+
+ return true;
+}
+
+int
+main()
+{
+ test01();
+ static_assert( test02() );
+}
// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++17 } }
// Copyright (C) 2013-2020 Free Software Foundation, Inc.
//
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// basic_string_view non-member functions
-
-// 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);
-*/
+// C++17 24.4.3 Non-member comparison functions [string.view.comparison]
#include <string_view>
#include <testsuite_hooks.h>
--- /dev/null
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+// 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/>.
+
+// C++20 21.4.4 Non-member comparison functions [string.view.comparisons]
+
+// operator==
+/*
+template<class charT, class traits>
+ constexpr bool
+ operator==(basic_string_view<charT, traits> lhs,
+ basic_string_view<charT, traits> rhs) noexcept;
+
+template<class charT, class traits>
+ constexpr bool
+ operator==(basic_string_view<charT, traits> lhs,
+ type_identity_t<basic_string_view<charT, traits>> rhs) noexcept;
+*/
+
+// operator<=>
+/*
+template<class charT, class traits>
+ constexpr [see below]
+ operator<=>(basic_string_view<charT, traits> lhs,
+ basic_string_view<charT, traits> rhs) noexcept;
+
+template<class charT, class traits>
+ constexpr [see below]
+ operator<=>(basic_string_view<charT, traits> lhs,
+ type_identity_t<basic_string_view<charT, traits>> rhs) noexcept;
+*/
+
+#include <string_view>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ std::wstring_view str_0(L"costa rica");
+ std::wstring_view str_1(L"costa marbella");
+ std::wstring_view str_2(L"cost");
+ std::wstring_view str_3(L"costa ricans");
+ std::wstring_view str_4;
+
+ str_4 = str_0;
+ //comparisons between string_view 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_view object and string_view 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) );
+}
+
+constexpr bool
+test02()
+{
+ std::wstring_view str_0(L"costa rica");
+ std::wstring_view str_1(L"costa marbella");
+ std::wstring_view str_2(L"cost");
+ std::wstring_view str_3(L"costa ricans");
+ std::wstring_view str_4;
+
+#undef VERIFY
+#define VERIFY(x) if (!(x)) return false
+
+ str_4 = str_0;
+ //comparisons between string_view 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_view object and string_view 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) );
+
+ return true;
+}
+
+int
+main()
+{
+ test01();
+ static_assert( test02() );
+}
--- /dev/null
+// 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();
+}