//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // template class sub_match; // Note in C++20 several of these operators have been removed and implicitly // generated by the compiler using operator== and operator<=>. // template // bool // operator==(const sub_match& lhs, const sub_match& rhs); // // template // bool // operator!=(const sub_match& lhs, const sub_match& rhs); // // template // bool // operator<(const sub_match& lhs, const sub_match& rhs); // // template // bool // operator<=(const sub_match& lhs, const sub_match& rhs); // // template // bool // operator>=(const sub_match& lhs, const sub_match& rhs); // // template // bool // operator>(const sub_match& lhs, const sub_match& rhs); // // template // bool // operator==(const basic_string::value_type, ST, SA>& lhs, // const sub_match& rhs); // // template // bool // operator!=(const basic_string::value_type, ST, SA>& lhs, // const sub_match& rhs); // // template // bool // operator<(const basic_string::value_type, ST, SA>& lhs, // const sub_match& rhs); // // template // bool // operator>(const basic_string::value_type, ST, SA>& lhs, // const sub_match& rhs); // // template // bool operator>=(const basic_string::value_type, ST, SA>& lhs, // const sub_match& rhs); // // template // bool // operator<=(const basic_string::value_type, ST, SA>& lhs, // const sub_match& rhs); // // template // bool // operator==(const sub_match& lhs, // const basic_string::value_type, ST, SA>& rhs); // // template // bool // operator!=(const sub_match& lhs, // const basic_string::value_type, ST, SA>& rhs); // // template // bool // operator<(const sub_match& lhs, // const basic_string::value_type, ST, SA>& rhs); // // template // bool operator>(const sub_match& lhs, // const basic_string::value_type, ST, SA>& rhs); // // template // bool // operator>=(const sub_match& lhs, // const basic_string::value_type, ST, SA>& rhs); // // template // bool // operator<=(const sub_match& lhs, // const basic_string::value_type, ST, SA>& rhs); // // template // bool // operator==(typename iterator_traits::value_type const* lhs, // const sub_match& rhs); // // template // bool // operator!=(typename iterator_traits::value_type const* lhs, // const sub_match& rhs); // // template // bool // operator<(typename iterator_traits::value_type const* lhs, // const sub_match& rhs); // // template // bool // operator>(typename iterator_traits::value_type const* lhs, // const sub_match& rhs); // // template // bool // operator>=(typename iterator_traits::value_type const* lhs, // const sub_match& rhs); // // template // bool // operator<=(typename iterator_traits::value_type const* lhs, // const sub_match& rhs); // // template // bool // operator==(const sub_match& lhs, // typename iterator_traits::value_type const* rhs); // // template // bool // operator!=(const sub_match& lhs, // typename iterator_traits::value_type const* rhs); // // template // bool // operator<(const sub_match& lhs, // typename iterator_traits::value_type const* rhs); // // template // bool // operator>(const sub_match& lhs, // typename iterator_traits::value_type const* rhs); // // template // bool // operator>=(const sub_match& lhs, // typename iterator_traits::value_type const* rhs); // // template // bool // operator<=(const sub_match& lhs, // typename iterator_traits::value_type const* rhs); // // template // bool // operator==(typename iterator_traits::value_type const& lhs, // const sub_match& rhs); // // template // bool // operator!=(typename iterator_traits::value_type const& lhs, // const sub_match& rhs); // // template // bool // operator<(typename iterator_traits::value_type const& lhs, // const sub_match& rhs); // // template // bool // operator>(typename iterator_traits::value_type const& lhs, // const sub_match& rhs); // // template // bool // operator>=(typename iterator_traits::value_type const& lhs, // const sub_match& rhs); // // template // bool // operator<=(typename iterator_traits::value_type const& lhs, // const sub_match& rhs); // // template // bool // operator==(const sub_match& lhs, // typename iterator_traits::value_type const& rhs); // // template // bool // operator!=(const sub_match& lhs, // typename iterator_traits::value_type const& rhs); // // template // bool // operator<(const sub_match& lhs, // typename iterator_traits::value_type const& rhs); // // template // bool // operator>(const sub_match& lhs, // typename iterator_traits::value_type const& rhs); // // template // bool // operator>=(const sub_match& lhs, // typename iterator_traits::value_type const& rhs); // // template // bool // operator<=(const sub_match& lhs, // typename iterator_traits::value_type const& rhs); // Added in C++20 // template // auto // operator<=>(const sub_match& lhs, const sub_match& rhs); // template // auto // operator<=>(const sub_match& lhs, // const basic_string::value_type, ST, SA>& rhs); // // template // auto // operator<=>(const sub_match& lhs, // typename iterator_traits::value_type const* rhs); // // template // auto // operator<=>(const sub_match& lhs, // typename iterator_traits::value_type const& rhs); #include #include #include #include "constexpr_char_traits.h" #include "make_string.h" #include "test_comparisons.h" #include "test_macros.h" #define SV(S) MAKE_STRING_VIEW(CharT, S) template void test(const std::basic_string& x, const std::basic_string& y, bool doCStrTests = true) { typedef std::basic_string string; typedef std::sub_match sub_match; #if TEST_STD_VER > 17 AssertOrderReturn(); AssertOrderReturn(); #else AssertComparisonsReturnBool(); AssertComparisonsReturnBool(); #endif sub_match sm1; sm1.first = x.begin(); sm1.second = x.end(); sm1.matched = true; sub_match sm2; sm2.first = y.begin(); sm2.second = y.end(); sm2.matched = true; assert(testComparisons(sm1, sm2, x == y, x < y)); assert(testComparisons(x, sm2, x == y, x < y)); assert(testComparisons(sm1, y, x == y, x < y)); #if TEST_STD_VER > 17 assert(testOrder(sm1, sm2, x <=> y)); assert(testOrder(x, sm2, x <=> y)); assert(testOrder(sm1, y, x <=> y)); #endif if (doCStrTests) { assert(testComparisons(x.c_str(), sm2, x == y, x < y)); assert(testComparisons(sm1, y.c_str(), x == y, x < y)); #if TEST_STD_VER > 17 assert(testOrder(x.c_str(), sm2, x <=> y)); assert(testOrder(sm1, y.c_str(), x <=> y)); #endif } assert(testComparisons(x[0], sm2, string(1, x[0]) == y, string(1, x[0]) < y)); assert(testComparisons(sm1, y[0], x == string(1, y[0]), x < string(1, y[0]))); #if TEST_STD_VER > 17 assert(testOrder(x[0], sm2, (string(1, x[0]) <=> y))); assert(testOrder(sm1, y[0], x <=> (string(1, y[0])))); #endif } #if TEST_STD_VER > 17 template struct char_traits : public constexpr_char_traits { using comparison_category = Ordering; }; template constexpr void test() { AssertOrderAreNoexcept(); AssertOrderReturn(); using CharT = typename T::value_type; // sorted values std::array s = [] { std::array input{SV(""), SV("abc"), SV("abcdef")}; return std::array{ T{input[0].begin(), input[0].end()}, T{input[1].begin(), input[1].end()}, T{input[2].begin(), input[2].end()}}; }(); auto ctor = [](const T& string) { std::sub_match sm; sm.first = string.begin(); sm.second = string.end(); sm.matched = true; return sm; }; std::array sm{ctor(s[0]), ctor(s[1]), ctor(s[2])}; for (std::size_t i = 0; i < s.size(); ++i) { for (std::size_t j = 0; j < s.size(); ++j) { assert(testOrder(s[i], sm[j], i == j ? Ordering::equivalent : i < j ? Ordering::less : Ordering::greater)); } } } template constexpr void test_all_orderings() { test>(); // Strong ordering in its char_traits test>, std::weak_ordering>(); // No ordering in its char_traits test>, std::weak_ordering>(); test>, std::partial_ordering>(); } #endif // TEST_STD_VER > 17 int main(int, char**) { test(std::string("123"), std::string("123")); test(std::string("1234"), std::string("123")); test(std::string("123\000" "56", 6), std::string("123\000" "56", 6), false); #if TEST_STD_VER > 17 test_all_orderings(); #endif #ifndef TEST_HAS_NO_WIDE_CHARACTERS test(std::wstring(L"123"), std::wstring(L"123")); test(std::wstring(L"1234"), std::wstring(L"123")); test(std::wstring(L"123\000" L"56", 6), std::wstring(L"123\000" L"56", 6), false); #if TEST_STD_VER > 17 test_all_orderings(); #endif #endif // TEST_HAS_NO_WIDE_CHARACTERS return 0; }