@@ -272,57 +272,100 @@ class Comparable {
272272 friend bool operator ==(const Comparable& lhs, long long rhs) { return comparable_data[lhs.index_ ] == rhs; }
273273};
274274
275- void test_deque () {
276- { // empty deque
277- std::deque<int > data;
278- assert (std::ranges::find (data, 4 ) == data.end ());
279- assert (std::ranges::find (data.begin (), data.end (), 4 ) == data.end ());
280- }
281-
282- { // single element - match
283- std::deque<int > data = {4 };
284- assert (std::ranges::find (data, 4 ) == data.begin ());
285- assert (std::ranges::find (data.begin (), data.end (), 4 ) == data.begin ());
286- }
287-
288- { // single element - no match
289- std::deque<int > data = {3 };
290- assert (std::ranges::find (data, 4 ) == data.end ());
291- assert (std::ranges::find (data.begin (), data.end (), 4 ) == data.end ());
292- }
293-
294- // many elements
295- for (auto size : {2 , 3 , 1023 , 1024 , 1025 , 2047 , 2048 , 2049 }) {
296- { // last element match
275+ void test_segmented_iterator_types () {
276+ // Test the optimized find algorithm for types that implement the segment iterator trait
277+ // deque
278+ {
279+ { // empty deque
297280 std::deque<int > data;
298- data.resize (size);
299- std::fill (data.begin (), data.end (), 3 );
300- data[size - 1 ] = 4 ;
301- assert (std::ranges::find (data, 4 ) == data.end () - 1 );
302- assert (std::ranges::find (data.begin (), data.end (), 4 ) == data.end () - 1 );
281+ assert (std::ranges::find (data, 4 ) == data.end ());
282+ assert (std::ranges::find (data.begin (), data.end (), 4 ) == data.end ());
303283 }
304284
305- { // second-last element match
306- std::deque<int > data;
307- data.resize (size);
308- std::fill (data.begin (), data.end (), 3 );
309- data[size - 2 ] = 4 ;
310- assert (std::ranges::find (data, 4 ) == data.end () - 2 );
311- assert (std::ranges::find (data.begin (), data.end (), 4 ) == data.end () - 2 );
285+ { // single element - match
286+ std::deque<int > data = {4 };
287+ assert (std::ranges::find (data, 4 ) == data.begin ());
288+ assert (std::ranges::find (data.begin (), data.end (), 4 ) == data.begin ());
312289 }
313290
314- { // no match
315- std::deque<int > data;
316- data.resize (size);
317- std::fill (data.begin (), data.end (), 3 );
291+ { // single element - no match
292+ std::deque<int > data = {3 };
318293 assert (std::ranges::find (data, 4 ) == data.end ());
319294 assert (std::ranges::find (data.begin (), data.end (), 4 ) == data.end ());
320295 }
296+
297+ // many elements
298+ for (auto size : {2 , 3 , 1023 , 1024 , 1025 , 2047 , 2048 , 2049 }) {
299+ { // last element match
300+ std::deque<int > data;
301+ data.resize (size);
302+ std::fill (data.begin (), data.end (), 3 );
303+ data[size - 1 ] = 4 ;
304+ assert (std::ranges::find (data, 4 ) == data.end () - 1 );
305+ assert (std::ranges::find (data.begin (), data.end (), 4 ) == data.end () - 1 );
306+ }
307+
308+ { // second-last element match
309+ std::deque<int > data;
310+ data.resize (size);
311+ std::fill (data.begin (), data.end (), 3 );
312+ data[size - 2 ] = 4 ;
313+ assert (std::ranges::find (data, 4 ) == data.end () - 2 );
314+ assert (std::ranges::find (data.begin (), data.end (), 4 ) == data.end () - 2 );
315+ }
316+
317+ { // no match
318+ std::deque<int > data;
319+ data.resize (size);
320+ std::fill (data.begin (), data.end (), 3 );
321+ assert (std::ranges::find (data, 4 ) == data.end ());
322+ assert (std::ranges::find (data.begin (), data.end (), 4 ) == data.end ());
323+ }
324+ }
325+ }
326+ // join_view ranges adaptor
327+ {
328+ { // single element - match
329+ int data[1 ][1 ] = {{4 }};
330+ auto joined = std::views::join (data);
331+ assert (std::ranges::find (joined, 4 ) == std::ranges::begin (joined));
332+ }
333+ { // single element - no match
334+ // (reproducer for https://llvm.org/PR158279, where the iterator would never reach the end sentinel)
335+ int data[1 ][1 ] = {{3 }};
336+ auto joined = std::views::join (data);
337+ assert (std::ranges::find (joined, 4 ) == std::ranges::end (joined));
338+ }
339+ { // several sub-arrays of size 1 - match
340+ int data[3 ][1 ] = {{0 }, {4 }, {0 }};
341+ auto joined = std::views::join (data);
342+ assert (std::ranges::find (joined, 4 ) == std::next (std::ranges::begin (joined)));
343+ }
344+ { // several sub-arrays of size 2 - match in second element of an array
345+ int data[3 ][2 ] = {{0 , 0 }, {0 , 4 }, {0 , 0 }};
346+ auto joined = std::views::join (data);
347+ assert (std::ranges::find (joined, 4 ) == std::ranges::next (std::ranges::begin (joined), 3 ));
348+ }
349+ { // vector of empty vectors
350+ std::vector<std::vector<int >> data = {{}, {}};
351+ auto joined = std::views::join (data);
352+ assert (std::ranges::find (joined, 4 ) == std::ranges::end (joined));
353+ }
354+ { // vector of variably sized vectors - match
355+ std::vector<std::vector<int >> data = {{}, {}, {3 , 4 }, {}, {}};
356+ auto joined = std::views::join (data);
357+ assert (std::ranges::find (joined, 4 ) == std::ranges::next (std::ranges::begin (joined)));
358+ }
359+ { // vector of variably sized vectors - no match
360+ std::vector<std::vector<int >> data = {{}, {}, {3 , 5 }, {}, {}};
361+ auto joined = std::views::join (data);
362+ assert (std::ranges::find (joined, 4 ) == std::ranges::end (joined));
363+ }
321364 }
322365}
323366
324367int main (int , char **) {
325- test_deque ();
368+ test_segmented_iterator_types ();
326369 test ();
327370 static_assert (test ());
328371
0 commit comments