@@ -64,20 +64,28 @@ auto last_known_good_lex_compare_3way(pair<FwdIt, FwdIt> expected_mismatch, FwdI
6464#endif // _HAS_CXX20
6565
6666template <class T >
67- void test_case_mismatch_and_lex_compare_family (const vector<T>& a, const vector<T>& b) {
67+ auto test_case_mismatch_only (const vector<T>& a, const vector<T>& b) {
6868 auto expected_mismatch = last_known_good_mismatch (a.begin (), a.end (), b.begin (), b.end ());
6969 auto actual_mismatch = mismatch (a.begin (), a.end (), b.begin (), b.end ());
7070 assert (expected_mismatch == actual_mismatch);
7171
72- auto expected_lex = last_known_good_lex_compare (expected_mismatch, a.end (), b.end ());
73- auto actual_lex = lexicographical_compare (a.begin (), a.end (), b.begin (), b.end ());
74- assert (expected_lex == actual_lex);
75-
7672#if _HAS_CXX20
7773 auto ranges_actual_mismatch = ranges::mismatch (a, b);
7874 assert (get<0 >(expected_mismatch) == ranges_actual_mismatch.in1 );
7975 assert (get<1 >(expected_mismatch) == ranges_actual_mismatch.in2 );
76+ #endif // _HAS_CXX20
77+ return expected_mismatch;
78+ }
79+
80+ template <class T >
81+ void test_case_mismatch_and_lex_compare_family (const vector<T>& a, const vector<T>& b) {
82+ auto expected_mismatch = test_case_mismatch_only (a, b);
83+
84+ auto expected_lex = last_known_good_lex_compare (expected_mismatch, a.end (), b.end ());
85+ auto actual_lex = lexicographical_compare (a.begin (), a.end (), b.begin (), b.end ());
86+ assert (expected_lex == actual_lex);
8087
88+ #if _HAS_CXX20
8189 auto ranges_actual_lex = ranges::lexicographical_compare (a, b);
8290 assert (expected_lex == ranges_actual_lex);
8391
@@ -130,6 +138,65 @@ void test_mismatch_and_lex_compare_family(mt19937_64& gen) {
130138 }
131139}
132140
141+ #if _HAS_CXX20
142+ template <class T >
143+ struct triplet {
144+ T x;
145+ T y;
146+ T z;
147+
148+ bool operator ==(const triplet&) const = default ;
149+ };
150+
151+ template <class T >
152+ void test_mismatch_only_triplets (mt19937_64& gen) {
153+ constexpr size_t shrinkCount = 4 ;
154+ constexpr size_t mismatchCount = 10 ;
155+ using TD = conditional_t <sizeof (T) == 1 , int , T>;
156+ uniform_int_distribution<TD> dis (' a' , ' z' );
157+ vector<triplet<T>> input_a;
158+ vector<triplet<T>> input_b;
159+ input_a.reserve (dataCount);
160+ input_b.reserve (dataCount);
161+
162+ for (;;) {
163+ // equal
164+ test_case_mismatch_only (input_a, input_b);
165+
166+ // different sizes
167+ for (size_t i = 0 ; i != shrinkCount && !input_b.empty (); ++i) {
168+ input_b.pop_back ();
169+ test_case_mismatch_only (input_a, input_b);
170+ test_case_mismatch_only (input_b, input_a);
171+ }
172+
173+ // actual mismatch (or maybe not, depending on random)
174+ if (!input_b.empty ()) {
175+ uniform_int_distribution<size_t > mismatch_dis (0 , input_a.size () - 1 );
176+
177+ for (size_t attempts = 0 ; attempts < mismatchCount; ++attempts) {
178+ const size_t possible_mismatch_pos = mismatch_dis (gen);
179+ input_a[possible_mismatch_pos].x = static_cast <T>(dis (gen));
180+ input_a[possible_mismatch_pos].y = static_cast <T>(dis (gen));
181+ input_a[possible_mismatch_pos].z = static_cast <T>(dis (gen));
182+ test_case_mismatch_only (input_a, input_b);
183+ test_case_mismatch_only (input_b, input_a);
184+ }
185+ }
186+
187+ if (input_a.size () == dataCount) {
188+ break ;
189+ }
190+
191+ input_a.emplace_back ();
192+ input_a.back ().x = static_cast <T>(dis (gen));
193+ input_a.back ().y = static_cast <T>(dis (gen));
194+ input_a.back ().z = static_cast <T>(dis (gen));
195+ input_b = input_a;
196+ }
197+ }
198+ #endif // _HAS_CXX20
199+
133200template <class C1 , class C2 >
134201void test_mismatch_and_lex_compare_family_containers () {
135202 C1 a{' m' , ' e' , ' o' , ' w' , ' ' , ' C' , ' A' , ' T' , ' S' };
@@ -245,6 +312,18 @@ void test_vector_algorithms(mt19937_64& gen) {
245312 test_mismatch_and_lex_compare_family<long long >(gen);
246313 test_mismatch_and_lex_compare_family<unsigned long long >(gen);
247314
315+ #if _HAS_CXX20
316+ test_mismatch_only_triplets<char >(gen);
317+ test_mismatch_only_triplets<signed char >(gen);
318+ test_mismatch_only_triplets<unsigned char >(gen);
319+ test_mismatch_only_triplets<short >(gen);
320+ test_mismatch_only_triplets<unsigned short >(gen);
321+ test_mismatch_only_triplets<int >(gen);
322+ test_mismatch_only_triplets<unsigned int >(gen);
323+ test_mismatch_only_triplets<long long >(gen);
324+ test_mismatch_only_triplets<unsigned long long >(gen);
325+ #endif // _HAS_CXX20
326+
248327 test_mismatch_and_lex_compare_family_containers<vector<char >, vector<signed char >>();
249328 test_mismatch_and_lex_compare_family_containers<vector<char >, vector<unsigned char >>();
250329 test_mismatch_and_lex_compare_family_containers<vector<wchar_t >, vector<char >>();
0 commit comments