362 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// <regex>10 11// template <class BidirectionalIterator> class sub_match;12 13// Note in C++20 several of these operators have been removed and implicitly14// generated by the compiler using operator== and operator<=>.15 16// template <class BiIter>17// bool18// operator==(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);19//20// template <class BiIter>21// bool22// operator!=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);23//24// template <class BiIter>25// bool26// operator<(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);27//28// template <class BiIter>29// bool30// operator<=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);31//32// template <class BiIter>33// bool34// operator>=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);35//36// template <class BiIter>37// bool38// operator>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);39//40// template <class BiIter, class ST, class SA>41// bool42// operator==(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,43// const sub_match<BiIter>& rhs);44//45// template <class BiIter, class ST, class SA>46// bool47// operator!=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,48// const sub_match<BiIter>& rhs);49//50// template <class BiIter, class ST, class SA>51// bool52// operator<(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,53// const sub_match<BiIter>& rhs);54//55// template <class BiIter, class ST, class SA>56// bool57// operator>(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,58// const sub_match<BiIter>& rhs);59//60// template <class BiIter, class ST, class SA>61// bool operator>=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,62// const sub_match<BiIter>& rhs);63//64// template <class BiIter, class ST, class SA>65// bool66// operator<=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,67// const sub_match<BiIter>& rhs);68//69// template <class BiIter, class ST, class SA>70// bool71// operator==(const sub_match<BiIter>& lhs,72// const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);73//74// template <class BiIter, class ST, class SA>75// bool76// operator!=(const sub_match<BiIter>& lhs,77// const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);78//79// template <class BiIter, class ST, class SA>80// bool81// operator<(const sub_match<BiIter>& lhs,82// const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);83//84// template <class BiIter, class ST, class SA>85// bool operator>(const sub_match<BiIter>& lhs,86// const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);87//88// template <class BiIter, class ST, class SA>89// bool90// operator>=(const sub_match<BiIter>& lhs,91// const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);92//93// template <class BiIter, class ST, class SA>94// bool95// operator<=(const sub_match<BiIter>& lhs,96// const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);97//98// template <class BiIter>99// bool100// operator==(typename iterator_traits<BiIter>::value_type const* lhs,101// const sub_match<BiIter>& rhs);102//103// template <class BiIter>104// bool105// operator!=(typename iterator_traits<BiIter>::value_type const* lhs,106// const sub_match<BiIter>& rhs);107//108// template <class BiIter>109// bool110// operator<(typename iterator_traits<BiIter>::value_type const* lhs,111// const sub_match<BiIter>& rhs);112//113// template <class BiIter>114// bool115// operator>(typename iterator_traits<BiIter>::value_type const* lhs,116// const sub_match<BiIter>& rhs);117//118// template <class BiIter>119// bool120// operator>=(typename iterator_traits<BiIter>::value_type const* lhs,121// const sub_match<BiIter>& rhs);122//123// template <class BiIter>124// bool125// operator<=(typename iterator_traits<BiIter>::value_type const* lhs,126// const sub_match<BiIter>& rhs);127//128// template <class BiIter>129// bool130// operator==(const sub_match<BiIter>& lhs,131// typename iterator_traits<BiIter>::value_type const* rhs);132//133// template <class BiIter>134// bool135// operator!=(const sub_match<BiIter>& lhs,136// typename iterator_traits<BiIter>::value_type const* rhs);137//138// template <class BiIter>139// bool140// operator<(const sub_match<BiIter>& lhs,141// typename iterator_traits<BiIter>::value_type const* rhs);142//143// template <class BiIter>144// bool145// operator>(const sub_match<BiIter>& lhs,146// typename iterator_traits<BiIter>::value_type const* rhs);147//148// template <class BiIter>149// bool150// operator>=(const sub_match<BiIter>& lhs,151// typename iterator_traits<BiIter>::value_type const* rhs);152//153// template <class BiIter>154// bool155// operator<=(const sub_match<BiIter>& lhs,156// typename iterator_traits<BiIter>::value_type const* rhs);157//158// template <class BiIter>159// bool160// operator==(typename iterator_traits<BiIter>::value_type const& lhs,161// const sub_match<BiIter>& rhs);162//163// template <class BiIter>164// bool165// operator!=(typename iterator_traits<BiIter>::value_type const& lhs,166// const sub_match<BiIter>& rhs);167//168// template <class BiIter>169// bool170// operator<(typename iterator_traits<BiIter>::value_type const& lhs,171// const sub_match<BiIter>& rhs);172//173// template <class BiIter>174// bool175// operator>(typename iterator_traits<BiIter>::value_type const& lhs,176// const sub_match<BiIter>& rhs);177//178// template <class BiIter>179// bool180// operator>=(typename iterator_traits<BiIter>::value_type const& lhs,181// const sub_match<BiIter>& rhs);182//183// template <class BiIter>184// bool185// operator<=(typename iterator_traits<BiIter>::value_type const& lhs,186// const sub_match<BiIter>& rhs);187//188// template <class BiIter>189// bool190// operator==(const sub_match<BiIter>& lhs,191// typename iterator_traits<BiIter>::value_type const& rhs);192//193// template <class BiIter>194// bool195// operator!=(const sub_match<BiIter>& lhs,196// typename iterator_traits<BiIter>::value_type const& rhs);197//198// template <class BiIter>199// bool200// operator<(const sub_match<BiIter>& lhs,201// typename iterator_traits<BiIter>::value_type const& rhs);202//203// template <class BiIter>204// bool205// operator>(const sub_match<BiIter>& lhs,206// typename iterator_traits<BiIter>::value_type const& rhs);207//208// template <class BiIter>209// bool210// operator>=(const sub_match<BiIter>& lhs,211// typename iterator_traits<BiIter>::value_type const& rhs);212//213// template <class BiIter>214// bool215// operator<=(const sub_match<BiIter>& lhs,216// typename iterator_traits<BiIter>::value_type const& rhs);217 218// Added in C++20219// template <class BiIter>220// auto221// operator<=>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);222// template <class BiIter, class ST, class SA>223// auto224// operator<=>(const sub_match<BiIter>& lhs,225// const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);226//227// template <class BiIter>228// auto229// operator<=>(const sub_match<BiIter>& lhs,230// typename iterator_traits<BiIter>::value_type const* rhs);231//232// template <class BiIter>233// auto234// operator<=>(const sub_match<BiIter>& lhs,235// typename iterator_traits<BiIter>::value_type const& rhs);236 237#include <regex>238#include <array>239#include <cassert>240 241#include "constexpr_char_traits.h"242#include "make_string.h"243#include "test_comparisons.h"244#include "test_macros.h"245 246 247#define SV(S) MAKE_STRING_VIEW(CharT, S)248 249template <class CharT>250void251test(const std::basic_string<CharT>& x, const std::basic_string<CharT>& y, bool doCStrTests = true)252{253 typedef std::basic_string<CharT> string;254 typedef std::sub_match<typename string::const_iterator> sub_match;255#if TEST_STD_VER > 17256 AssertOrderReturn<std::strong_ordering, sub_match>();257 AssertOrderReturn<std::strong_ordering, sub_match, string>();258#else259 AssertComparisonsReturnBool<sub_match>();260 AssertComparisonsReturnBool<sub_match, string>();261#endif262 sub_match sm1;263 sm1.first = x.begin();264 sm1.second = x.end();265 sm1.matched = true;266 sub_match sm2;267 sm2.first = y.begin();268 sm2.second = y.end();269 sm2.matched = true;270 271 assert(testComparisons(sm1, sm2, x == y, x < y));272 assert(testComparisons(x, sm2, x == y, x < y));273 assert(testComparisons(sm1, y, x == y, x < y));274#if TEST_STD_VER > 17275 assert(testOrder(sm1, sm2, x <=> y));276 assert(testOrder(x, sm2, x <=> y));277 assert(testOrder(sm1, y, x <=> y));278#endif279 280 if (doCStrTests) {281 assert(testComparisons(x.c_str(), sm2, x == y, x < y));282 assert(testComparisons(sm1, y.c_str(), x == y, x < y));283#if TEST_STD_VER > 17284 assert(testOrder(x.c_str(), sm2, x <=> y));285 assert(testOrder(sm1, y.c_str(), x <=> y));286#endif287 }288 289 assert(testComparisons(x[0], sm2, string(1, x[0]) == y, string(1, x[0]) < y));290 assert(testComparisons(sm1, y[0], x == string(1, y[0]), x < string(1, y[0])));291#if TEST_STD_VER > 17292 assert(testOrder(x[0], sm2, (string(1, x[0]) <=> y)));293 assert(testOrder(sm1, y[0], x <=> (string(1, y[0]))));294#endif295}296 297#if TEST_STD_VER > 17298template <class CharT, class Ordering>299struct char_traits : public constexpr_char_traits<CharT> {300 using comparison_category = Ordering;301};302 303template <class T, class Ordering = std::strong_ordering>304constexpr void test() {305 AssertOrderAreNoexcept<T>();306 AssertOrderReturn<Ordering, T>();307 308 using CharT = typename T::value_type;309 310 // sorted values311 std::array s = [] {312 std::array input{SV(""), SV("abc"), SV("abcdef")};313 return std::array{314 T{input[0].begin(), input[0].end()}, T{input[1].begin(), input[1].end()}, T{input[2].begin(), input[2].end()}};315 }();316 auto ctor = [](const T& string) {317 std::sub_match<typename T::const_iterator> sm;318 sm.first = string.begin();319 sm.second = string.end();320 sm.matched = true;321 return sm;322 };323 std::array sm{ctor(s[0]), ctor(s[1]), ctor(s[2])};324 325 for (std::size_t i = 0; i < s.size(); ++i) {326 for (std::size_t j = 0; j < s.size(); ++j) {327 assert(testOrder(s[i], sm[j], i == j ? Ordering::equivalent : i < j ? Ordering::less : Ordering::greater));328 }329 }330}331 332template <class CharT>333constexpr void test_all_orderings() {334 test<std::basic_string<CharT>>(); // Strong ordering in its char_traits335 test<std::basic_string<CharT, constexpr_char_traits<CharT>>,336 std::weak_ordering>(); // No ordering in its char_traits337 test<std::basic_string<CharT, char_traits<CharT, std::weak_ordering>>, std::weak_ordering>();338 test<std::basic_string<CharT, char_traits<CharT, std::partial_ordering>>, std::partial_ordering>();339}340#endif // TEST_STD_VER > 17341 342int main(int, char**)343{344 test(std::string("123"), std::string("123"));345 test(std::string("1234"), std::string("123"));346 test(std::string("123\000" "56", 6), std::string("123\000" "56", 6), false);347#if TEST_STD_VER > 17348 test_all_orderings<char>();349#endif350 351#ifndef TEST_HAS_NO_WIDE_CHARACTERS352 test(std::wstring(L"123"), std::wstring(L"123"));353 test(std::wstring(L"1234"), std::wstring(L"123"));354 test(std::wstring(L"123\000" L"56", 6), std::wstring(L"123\000" L"56", 6), false);355#if TEST_STD_VER > 17356 test_all_orderings<wchar_t>();357#endif358#endif // TEST_HAS_NO_WIDE_CHARACTERS359 360 return 0;361}362