| //===----------------------------------------------------------------------===// |
| // |
| // 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 |
| // |
| //===----------------------------------------------------------------------===// |
| |
| // <regex> |
| |
| // template <class BidirectionalIterator> 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 <class BiIter> |
| // bool |
| // operator==(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator!=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator<(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator<=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator>=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter, class ST, class SA> |
| // bool |
| // operator==(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, |
| // const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter, class ST, class SA> |
| // bool |
| // operator!=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, |
| // const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter, class ST, class SA> |
| // bool |
| // operator<(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, |
| // const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter, class ST, class SA> |
| // bool |
| // operator>(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, |
| // const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter, class ST, class SA> |
| // bool operator>=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, |
| // const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter, class ST, class SA> |
| // bool |
| // operator<=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, |
| // const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter, class ST, class SA> |
| // bool |
| // operator==(const sub_match<BiIter>& lhs, |
| // const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
| // |
| // template <class BiIter, class ST, class SA> |
| // bool |
| // operator!=(const sub_match<BiIter>& lhs, |
| // const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
| // |
| // template <class BiIter, class ST, class SA> |
| // bool |
| // operator<(const sub_match<BiIter>& lhs, |
| // const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
| // |
| // template <class BiIter, class ST, class SA> |
| // bool operator>(const sub_match<BiIter>& lhs, |
| // const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
| // |
| // template <class BiIter, class ST, class SA> |
| // bool |
| // operator>=(const sub_match<BiIter>& lhs, |
| // const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
| // |
| // template <class BiIter, class ST, class SA> |
| // bool |
| // operator<=(const sub_match<BiIter>& lhs, |
| // const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator==(typename iterator_traits<BiIter>::value_type const* lhs, |
| // const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator!=(typename iterator_traits<BiIter>::value_type const* lhs, |
| // const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator<(typename iterator_traits<BiIter>::value_type const* lhs, |
| // const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator>(typename iterator_traits<BiIter>::value_type const* lhs, |
| // const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator>=(typename iterator_traits<BiIter>::value_type const* lhs, |
| // const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator<=(typename iterator_traits<BiIter>::value_type const* lhs, |
| // const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator==(const sub_match<BiIter>& lhs, |
| // typename iterator_traits<BiIter>::value_type const* rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator!=(const sub_match<BiIter>& lhs, |
| // typename iterator_traits<BiIter>::value_type const* rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator<(const sub_match<BiIter>& lhs, |
| // typename iterator_traits<BiIter>::value_type const* rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator>(const sub_match<BiIter>& lhs, |
| // typename iterator_traits<BiIter>::value_type const* rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator>=(const sub_match<BiIter>& lhs, |
| // typename iterator_traits<BiIter>::value_type const* rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator<=(const sub_match<BiIter>& lhs, |
| // typename iterator_traits<BiIter>::value_type const* rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator==(typename iterator_traits<BiIter>::value_type const& lhs, |
| // const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator!=(typename iterator_traits<BiIter>::value_type const& lhs, |
| // const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator<(typename iterator_traits<BiIter>::value_type const& lhs, |
| // const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator>(typename iterator_traits<BiIter>::value_type const& lhs, |
| // const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator>=(typename iterator_traits<BiIter>::value_type const& lhs, |
| // const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator<=(typename iterator_traits<BiIter>::value_type const& lhs, |
| // const sub_match<BiIter>& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator==(const sub_match<BiIter>& lhs, |
| // typename iterator_traits<BiIter>::value_type const& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator!=(const sub_match<BiIter>& lhs, |
| // typename iterator_traits<BiIter>::value_type const& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator<(const sub_match<BiIter>& lhs, |
| // typename iterator_traits<BiIter>::value_type const& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator>(const sub_match<BiIter>& lhs, |
| // typename iterator_traits<BiIter>::value_type const& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator>=(const sub_match<BiIter>& lhs, |
| // typename iterator_traits<BiIter>::value_type const& rhs); |
| // |
| // template <class BiIter> |
| // bool |
| // operator<=(const sub_match<BiIter>& lhs, |
| // typename iterator_traits<BiIter>::value_type const& rhs); |
| |
| // Added in C++20 |
| // template <class BiIter> |
| // auto |
| // operator<=>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
| // template <class BiIter, class ST, class SA> |
| // auto |
| // operator<=>(const sub_match<BiIter>& lhs, |
| // const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
| // |
| // template <class BiIter> |
| // auto |
| // operator<=>(const sub_match<BiIter>& lhs, |
| // typename iterator_traits<BiIter>::value_type const* rhs); |
| // |
| // template <class BiIter> |
| // auto |
| // operator<=>(const sub_match<BiIter>& lhs, |
| // typename iterator_traits<BiIter>::value_type const& rhs); |
| |
| #include <regex> |
| #include <array> |
| #include <cassert> |
| |
| #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 <class CharT> |
| void |
| test(const std::basic_string<CharT>& x, const std::basic_string<CharT>& y, bool doCStrTests = true) |
| { |
| typedef std::basic_string<CharT> string; |
| typedef std::sub_match<typename string::const_iterator> sub_match; |
| #if TEST_STD_VER > 17 |
| AssertOrderReturn<std::strong_ordering, sub_match>(); |
| AssertOrderReturn<std::strong_ordering, sub_match, string>(); |
| #else |
| AssertComparisonsReturnBool<sub_match>(); |
| AssertComparisonsReturnBool<sub_match, string>(); |
| #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 <class CharT, class Ordering> |
| struct char_traits : public constexpr_char_traits<CharT> { |
| using comparison_category = Ordering; |
| }; |
| |
| template <class T, class Ordering = std::strong_ordering> |
| constexpr void test() { |
| AssertOrderAreNoexcept<T>(); |
| AssertOrderReturn<Ordering, T>(); |
| |
| 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<typename T::const_iterator> 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 <class CharT> |
| constexpr void test_all_orderings() { |
| test<std::basic_string<CharT>>(); // Strong ordering in its char_traits |
| test<std::basic_string<CharT, constexpr_char_traits<CharT>>, |
| std::weak_ordering>(); // No ordering in its char_traits |
| test<std::basic_string<CharT, char_traits<CharT, std::weak_ordering>>, std::weak_ordering>(); |
| test<std::basic_string<CharT, char_traits<CharT, std::partial_ordering>>, 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<char>(); |
| #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<wchar_t>(); |
| #endif |
| #endif // TEST_HAS_NO_WIDE_CHARACTERS |
| |
| return 0; |
| } |