From 6ac8d03a3eb875ccabfacd03034abb060b982547 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Thu, 4 Apr 2024 07:00:47 +0300 Subject: [PATCH 01/12] Check if `find_last` can find anything --- stl/inc/algorithm | 5 +++++ .../tests/Dev11_0316853_find_memchr_optimization/test.cpp | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/stl/inc/algorithm b/stl/inc/algorithm index ff1f8b65e3..51ac1fd0f3 100644 --- a/stl/inc/algorithm +++ b/stl/inc/algorithm @@ -2973,6 +2973,11 @@ namespace ranges { && sized_sentinel_for<_Se, _It>) { if (!_STD is_constant_evaluated()) { const auto _Count = _Last - _First; + + if (!_STD _Could_compare_equal_to_value_type<_It>(_Value)) { + return {_First + _Count, _First + _Count}; + } + const auto _First_ptr = _STD _To_address(_First); const auto _Last_ptr = _First_ptr + _Count; diff --git a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp index 5ec9aaf944..bba969de91 100644 --- a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp +++ b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp @@ -180,6 +180,12 @@ int main() { assert(count(v.cbegin(), v.cend(), 33) == 1); assert(count(v.cbegin(), v.cend(), 44) == 2); assert(count(v.cbegin(), v.cend(), 255) == 0); + +#if _HAS_CXX23 + assert(ranges::find_last(v.cbegin(), v.cend(), 33).begin() - v.cbegin() == 1); + assert(ranges::find_last(v.cbegin(), v.cend(), -1).begin() - v.cbegin() == 2); + assert(ranges::find_last(v.cbegin(), v.cend(), 255).begin() - v.cbegin() == 6); +#endif // _HAS_CXX23 } From f550ee626795027361e5aeb892d19308a4dd7270 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Thu, 4 Apr 2024 07:16:34 +0300 Subject: [PATCH 02/12] format --- stl/inc/algorithm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/algorithm b/stl/inc/algorithm index 51ac1fd0f3..b151235ece 100644 --- a/stl/inc/algorithm +++ b/stl/inc/algorithm @@ -2972,10 +2972,10 @@ namespace ranges { if constexpr (is_same_v<_Pj, identity> && _Vector_alg_in_find_is_safe<_It, _Ty> && sized_sentinel_for<_Se, _It>) { if (!_STD is_constant_evaluated()) { - const auto _Count = _Last - _First; + const auto _Count = _Last - _First; if (!_STD _Could_compare_equal_to_value_type<_It>(_Value)) { - return {_First + _Count, _First + _Count}; + return {_First + _Count, _First + _Count}; } const auto _First_ptr = _STD _To_address(_First); From ee9f96f7d243aef840fab19272cadf57f11263a0 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Thu, 4 Apr 2024 07:59:30 +0300 Subject: [PATCH 03/12] more coverage --- .../test.cpp | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp index bba969de91..a3fbc675ba 100644 --- a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp +++ b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp @@ -55,14 +55,24 @@ void test_limit_check_elements_impl() { if constexpr (is_signed_v) { if constexpr (numeric_limits::min() < min_val) { assert(find(begin(sc), end(sc), ValueType{ValueType{min_val} - 1}) == end(sc)); +#if _HAS_CXX23 + assert(ranges::find_last(sc, ValueType{min_val} - 1).begin() == end(sc)); +#endif // _HAS_CXX23 } if constexpr (sizeof(ElementType) <= sizeof(ValueType)) { assert(find(begin(sc), end(sc), ValueType{min_val}) == begin(sc)); +#if _HAS_CXX23 + assert(ranges::find_last(sc, ValueType{min_val}).begin() == begin(sc)); +#endif // _HAS_CXX23 } assert(find(begin(sc), end(sc), ValueType{-1}) == begin(sc) + 4); assert(count(begin(sc), end(sc), ValueType{-1}) == 2); + +#if _HAS_CXX23 + assert(ranges::find_last(sc, ValueType{-1}).begin() == begin(sc) + 5); +#endif // _HAS_CXX23 } else { constexpr auto max_vt = numeric_limits::max(); if constexpr (ElementType{-1} == max_vt) { @@ -72,12 +82,22 @@ void test_limit_check_elements_impl() { assert(count(begin(sc), end(sc), max_vt) == 2); assert(count(begin(sc), end(sc), max_vt - 1) == 1); + +#if _HAS_CXX23 + assert(ranges::find_last(sc, max_vt).begin() == begin(sc) + 5); + assert(ranges::find_last(sc, max_vt - 1).begin() == begin(sc) + 3); +#endif // _HAS_CXX23 } else { assert(find(begin(sc), end(sc), max_vt) == end(sc)); assert(find(begin(sc), end(sc), max_vt - 1) == end(sc)); assert(count(begin(sc), end(sc), max_vt) == 0); assert(count(begin(sc), end(sc), max_vt - 1) == 0); + +#if _HAS_CXX23 + assert(ranges::find_last(sc, max_vt).begin() == end(sc)); + assert(ranges::find_last(sc, max_vt - 1).begin() == end(sc)); +#endif // _HAS_CXX23 } } @@ -86,9 +106,17 @@ void test_limit_check_elements_impl() { assert(find(begin(sc), end(sc), ValueType{0}) == begin(sc) + 6); assert(find(begin(sc), end(sc), ValueType{5}) == end(sc)); +#if _HAS_CXX23 + assert(ranges::find_last(sc, ValueType{0}).begin() == begin(sc) + 6); + assert(ranges::find_last(sc, ValueType{5}).begin() == end(sc)); +#endif // _HAS_CXX23 + if constexpr (sizeof(ElementType) <= sizeof(ValueType)) { assert(find(begin(sc), end(sc), ValueType{max_val}) == begin(sc) + 12); assert(count(begin(sc), end(sc), ValueType{max_val}) == 1); +#if _HAS_CXX23 + assert(ranges::find_last(sc, ValueType{max_val}).begin() == begin(sc) + 12); +#endif // _HAS_CXX23 if constexpr (sizeof(ElementType) < sizeof(ValueType)) { assert(find(begin(sc), end(sc), ValueType{ValueType{max_val} + 1}) == end(sc)); @@ -96,6 +124,11 @@ void test_limit_check_elements_impl() { assert(count(begin(sc), end(sc), ValueType{ValueType{max_val} + 1}) == 0); assert(count(begin(sc), end(sc), ValueType{umax_val}) == 0); + +#if _HAS_CXX23 + assert(ranges::find_last(sc, ValueType{ValueType{max_val} + 1}).begin() == end(sc)); + assert(ranges::find_last(sc, ValueType{umax_val}).begin() == end(sc)); +#endif // _HAS_CXX23 } } } else { @@ -107,6 +140,11 @@ void test_limit_check_elements_impl() { assert(find(begin(uc), end(uc), ValueType{0}) == begin(uc)); assert(find(begin(uc), end(uc), ValueType{2}) == begin(uc) + 3); assert(find(begin(uc), end(uc), ValueType{6}) == end(uc)); +#if _HAS_CXX23 + assert(ranges::find_last(uc, ValueType{0}).begin() == begin(uc)); + assert(ranges::find_last(uc, ValueType{2}).begin() == begin(uc) + 3); + assert(ranges::find_last(uc, ValueType{6}).begin() == end(uc)); +#endif // _HAS_CXX23 if constexpr (is_signed_v) { if constexpr (ValueType{-1} == max_val) { @@ -116,12 +154,20 @@ void test_limit_check_elements_impl() { assert(count(begin(uc), end(uc), ValueType{-1}) == 1); assert(count(begin(uc), end(uc), ValueType{-2}) == 1); +#if _HAS_CXX23 + assert(ranges::find_last(uc, ValueType{-1}).begin() == begin(uc) + 6); + assert(ranges::find_last(uc, ValueType{-2}).begin() == begin(uc) + 5); +#endif // _HAS_CXX23 } else { assert(find(begin(uc), end(uc), ValueType{-1}) == end(uc)); assert(find(begin(uc), end(uc), ValueType{-2}) == end(uc)); assert(count(begin(uc), end(uc), ValueType{-1}) == 0); assert(count(begin(uc), end(uc), ValueType{-2}) == 0); +#if _HAS_CXX23 + assert(ranges::find_last(uc, ValueType{-1}).begin() == end(uc)); + assert(ranges::find_last(uc, ValueType{-2}).begin() == end(uc)); +#endif // _HAS_CXX23 } } @@ -133,6 +179,9 @@ void test_limit_check_elements_impl() { assert(find(begin(uc), end(uc), ValueType{ValueType{max_val} + 1}) == end(uc)); if constexpr (sizeof(ElementType) < sizeof(ValueType)) { assert(find(begin(uc), end(uc), max_vt) == end(uc)); +#if _HAS_CXX23 + assert(ranges::find_last(uc, max_vt).begin() == end(uc)); +#endif // _HAS_CXX23 } } } @@ -205,6 +254,11 @@ int main() { assert(count(l.begin(), l.end(), 44) == 2); assert(count(l.begin(), l.end(), 17) == 0); + +#if _HAS_CXX23 + assert(ranges::find_last(l, 44).begin() == next(l.begin(), 4)); + assert(ranges::find_last(l, 16).begin() == l.end()); +#endif // _HAS_CXX23 } { // Optimization inapplicable due to bogus element type and bogus value type From 89a36283c430d1b19e4b4136c62bc7a8b13c0c75 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Thu, 4 Apr 2024 08:01:06 +0300 Subject: [PATCH 04/12] more coverage --- .../test.cpp | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp index a3fbc675ba..5d32867b99 100644 --- a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp +++ b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp @@ -275,6 +275,11 @@ int main() { assert(count(v.begin(), v.end(), "cute") == 2); assert(count(v.begin(), v.end(), "zombies") == 0); + +#if _HAS_CXX23 + assert(ranges::find_last(v, "fluffy").begin() == v.begin() + 2); + assert(ranges::find_last(v, "zombies").begin() == v.end()); +#endif // _HAS_CXX23 } { @@ -297,6 +302,11 @@ int main() { assert(count(v.begin(), v.end(), 0xAABBCCDDUL) == 1); assert(count(v.begin(), v.end(), 0x11UL) == 0); + +#if _HAS_CXX23 + assert(ranges::find_last(v, 0xAABBCCDDUL).begin() == v.begin() + 2); + assert(ranges::find_last(v, 0x11UL).begin() == v.end()); +#endif // _HAS_CXX23 } { // Optimization inapplicable due to bogus value type (although the element type is good) @@ -340,6 +350,11 @@ int main() { assert(count(vc.cbegin(), vc.cend(), 'o') == 2); assert(count(vc.cbegin(), vc.cend(), 'X') == 0); + +#if _HAS_CXX23 + assert(ranges::find_last(vc, 'o').begin() == vc.cbegin() + 4); + assert(ranges::find_last(vc, 'X').begin() == vc.cend()); +#endif // _HAS_CXX23 } { // Test optimized element types. @@ -367,6 +382,15 @@ int main() { assert(find(vsc.cbegin(), vsc.cend(), -128) == vsc.cbegin() + 3); assert(find(vsc.cbegin(), vsc.cend(), 127) == vsc.cbegin() + 4); assert(find(vsc.cbegin(), vsc.cend(), 255) == vsc.cend()); + +#if _HAS_CXX23 + assert(ranges::find_last(vsc, 17).begin() == vsc.begin()); + assert(ranges::find_last(vsc, 29).begin() == vsc.begin() + 1); + assert(ranges::find_last(vsc, -1).begin() == vsc.begin() + 2); + assert(ranges::find_last(vsc, -128).begin() == vsc.begin() + 3); + assert(ranges::find_last(vsc, 127).begin() == vsc.begin() + 4); + assert(ranges::find_last(vsc, 255).begin() == vsc.end()); +#endif // _HAS_CXX23 } { // Test optimized element types. @@ -388,6 +412,12 @@ int main() { assert(find(vuc.cbegin(), vuc.cend(), 47) == vuc.cbegin() + 2); assert(find(vuc.cbegin(), vuc.cend(), 255) == vuc.cbegin() + 4); assert(find(vuc.cbegin(), vuc.cend(), -1) == vuc.cend()); + +#if _HAS_CXX23 + assert(ranges::find_last(vuc, 47).begin() == vuc.begin() + 2); + assert(ranges::find_last(vuc, 255).begin() == vuc.begin() + 4); + assert(ranges::find_last(vuc, -1).begin() == vuc.end()); +#endif // _HAS_CXX23 } From b8ceeddbda2ad9c13f4566901988ed551df49a30 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 6 Apr 2024 12:14:12 -0700 Subject: [PATCH 05/12] Test with vectorization enabled/disabled. --- tests/std/tests/Dev11_0316853_find_memchr_optimization/env.lst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/std/tests/Dev11_0316853_find_memchr_optimization/env.lst b/tests/std/tests/Dev11_0316853_find_memchr_optimization/env.lst index 19f025bd0e..78fbe6b49a 100644 --- a/tests/std/tests/Dev11_0316853_find_memchr_optimization/env.lst +++ b/tests/std/tests/Dev11_0316853_find_memchr_optimization/env.lst @@ -2,3 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception RUNALL_INCLUDE ..\usual_matrix.lst +RUNALL_CROSSLIST +* PM_CL="" +* PM_CL="/D_USE_STD_VECTOR_ALGORITHMS=0" From 458644952cc6e8605e11d6f15910fb27f15361be Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 6 Apr 2024 12:06:46 -0700 Subject: [PATCH 06/12] Add extra `ValueType{...}` to match previous test. --- tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp index 5d32867b99..eab129b7ae 100644 --- a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp +++ b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp @@ -56,7 +56,7 @@ void test_limit_check_elements_impl() { if constexpr (numeric_limits::min() < min_val) { assert(find(begin(sc), end(sc), ValueType{ValueType{min_val} - 1}) == end(sc)); #if _HAS_CXX23 - assert(ranges::find_last(sc, ValueType{min_val} - 1).begin() == end(sc)); + assert(ranges::find_last(sc, ValueType{ValueType{min_val} - 1}).begin() == end(sc)); #endif // _HAS_CXX23 } From 69448d54890f5f4d6a70df5baf7d61367689071f Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 6 Apr 2024 12:08:07 -0700 Subject: [PATCH 07/12] `16` => `17` to match previous test. --- tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp index eab129b7ae..611b2d6461 100644 --- a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp +++ b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp @@ -257,7 +257,7 @@ int main() { #if _HAS_CXX23 assert(ranges::find_last(l, 44).begin() == next(l.begin(), 4)); - assert(ranges::find_last(l, 16).begin() == l.end()); + assert(ranges::find_last(l, 17).begin() == l.end()); #endif // _HAS_CXX23 } From 48180679bd7bde91ef29a8591a205c5705a4a466 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 6 Apr 2024 12:11:15 -0700 Subject: [PATCH 08/12] Consistently test the range overload. --- .../tests/Dev11_0316853_find_memchr_optimization/test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp index 611b2d6461..d52223f437 100644 --- a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp +++ b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp @@ -231,9 +231,9 @@ int main() { assert(count(v.cbegin(), v.cend(), 255) == 0); #if _HAS_CXX23 - assert(ranges::find_last(v.cbegin(), v.cend(), 33).begin() - v.cbegin() == 1); - assert(ranges::find_last(v.cbegin(), v.cend(), -1).begin() - v.cbegin() == 2); - assert(ranges::find_last(v.cbegin(), v.cend(), 255).begin() - v.cbegin() == 6); + assert(ranges::find_last(v, 33).begin() - v.begin() == 1); + assert(ranges::find_last(v, -1).begin() - v.begin() == 2); + assert(ranges::find_last(v, 255).begin() - v.begin() == 6); #endif // _HAS_CXX23 } From 59c3fcddec116680335311afd7bb537c3fbbfd9d Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 6 Apr 2024 12:35:44 -0700 Subject: [PATCH 09/12] Compare against `.begin()` and `.end()` for consistency. --- .../std/tests/Dev11_0316853_find_memchr_optimization/test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp index d52223f437..36be089a2a 100644 --- a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp +++ b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp @@ -352,8 +352,8 @@ int main() { assert(count(vc.cbegin(), vc.cend(), 'X') == 0); #if _HAS_CXX23 - assert(ranges::find_last(vc, 'o').begin() == vc.cbegin() + 4); - assert(ranges::find_last(vc, 'X').begin() == vc.cend()); + assert(ranges::find_last(vc, 'o').begin() == vc.begin() + 4); + assert(ranges::find_last(vc, 'X').begin() == vc.end()); #endif // _HAS_CXX23 } From fecfb2ce9e85743e2657b734c2babe70ab4e30a0 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 6 Apr 2024 12:42:17 -0700 Subject: [PATCH 10/12] Pre-existing: Add missing `count()` coverage, reorder to `find()` then `count()`. --- .../tests/Dev11_0316853_find_memchr_optimization/test.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp index 36be089a2a..dd46e9d3c7 100644 --- a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp +++ b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp @@ -101,11 +101,12 @@ void test_limit_check_elements_impl() { } } - assert(count(begin(sc), end(sc), ValueType{0}) == 1); - assert(find(begin(sc), end(sc), ValueType{0}) == begin(sc) + 6); assert(find(begin(sc), end(sc), ValueType{5}) == end(sc)); + assert(count(begin(sc), end(sc), ValueType{0}) == 1); + assert(count(begin(sc), end(sc), ValueType{5}) == 0); + #if _HAS_CXX23 assert(ranges::find_last(sc, ValueType{0}).begin() == begin(sc) + 6); assert(ranges::find_last(sc, ValueType{5}).begin() == end(sc)); From 998f9296e363ef525ba356f9204aa63f21e771ca Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 6 Apr 2024 12:49:27 -0700 Subject: [PATCH 11/12] Style: Adjust newlines. --- .../std/tests/Dev11_0316853_find_memchr_optimization/test.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp index dd46e9d3c7..46d17ebded 100644 --- a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp +++ b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp @@ -66,10 +66,9 @@ void test_limit_check_elements_impl() { assert(ranges::find_last(sc, ValueType{min_val}).begin() == begin(sc)); #endif // _HAS_CXX23 } - assert(find(begin(sc), end(sc), ValueType{-1}) == begin(sc) + 4); + assert(find(begin(sc), end(sc), ValueType{-1}) == begin(sc) + 4); assert(count(begin(sc), end(sc), ValueType{-1}) == 2); - #if _HAS_CXX23 assert(ranges::find_last(sc, ValueType{-1}).begin() == begin(sc) + 5); #endif // _HAS_CXX23 From 609ee424c5e84b14b012929e3200c9909f0c413f Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 6 Apr 2024 13:42:59 -0700 Subject: [PATCH 12/12] Add more test coverage. --- .../test.cpp | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp index 46d17ebded..4a7eb9526b 100644 --- a/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp +++ b/tests/std/tests/Dev11_0316853_find_memchr_optimization/test.cpp @@ -175,8 +175,19 @@ void test_limit_check_elements_impl() { assert(find(begin(uc), end(uc), ValueType{max_val - 3}) == end(uc)); assert(find(begin(uc), end(uc), ValueType{max_val - 2}) == begin(uc) + 4); assert(find(begin(uc), end(uc), ValueType{max_val}) == begin(uc) + 6); + +#if _HAS_CXX23 + assert(ranges::find_last(uc, ValueType{max_val - 3}).begin() == end(uc)); + assert(ranges::find_last(uc, ValueType{max_val - 2}).begin() == begin(uc) + 4); + assert(ranges::find_last(uc, ValueType{max_val}).begin() == begin(uc) + 6); +#endif // _HAS_CXX23 + if constexpr (max_val < max_vt) { assert(find(begin(uc), end(uc), ValueType{ValueType{max_val} + 1}) == end(uc)); +#if _HAS_CXX23 + assert(ranges::find_last(uc, ValueType{ValueType{max_val} + 1}).begin() == end(uc)); +#endif // _HAS_CXX23 + if constexpr (sizeof(ElementType) < sizeof(ValueType)) { assert(find(begin(uc), end(uc), max_vt) == end(uc)); #if _HAS_CXX23 @@ -443,6 +454,26 @@ int main() { assert(find(begin(arr), end(arr), false) == begin(arr) + 2); assert(find(begin(arr), end(arr), true) == end(arr)); + +#if _HAS_CXX23 + assert(ranges::find_last(arr, static_cast(30)).begin() == begin(arr) + 4); + assert(ranges::find_last(arr, static_cast(30)).begin() == begin(arr) + 4); + assert(ranges::find_last(arr, static_cast(30)).begin() == begin(arr) + 4); + assert(ranges::find_last(arr, static_cast(30)).begin() == begin(arr) + 4); + assert(ranges::find_last(arr, static_cast(30)).begin() == begin(arr) + 4); + + assert(ranges::find_last(arr, static_cast(30)).begin() == begin(arr) + 4); + assert(ranges::find_last(arr, static_cast(30)).begin() == begin(arr) + 4); + assert(ranges::find_last(arr, static_cast(30)).begin() == begin(arr) + 4); + assert(ranges::find_last(arr, static_cast(30)).begin() == begin(arr) + 4); + assert(ranges::find_last(arr, static_cast(30)).begin() == begin(arr) + 4); + + assert(ranges::find_last(arr, static_cast(30)).begin() == begin(arr) + 4); + assert(ranges::find_last(arr, static_cast(30)).begin() == begin(arr) + 4); + + assert(ranges::find_last(arr, false).begin() == begin(arr) + 2); + assert(ranges::find_last(arr, true).begin() == end(arr)); +#endif // _HAS_CXX23 } // Test limit checks. @@ -485,6 +516,26 @@ int main() { assert(find(begin(sc), end(sc), 0xFFFFFFFFFFFFFF7FULL) == end(sc)); assert(find(begin(sc), end(sc), 0xFFFFFFFFFFFFFF00ULL) == end(sc)); +#if _HAS_CXX23 + assert(ranges::find_last(sc, static_cast(0xFFFF)).begin() == end(sc)); + + assert(ranges::find_last(sc, 0xFFFFFFFFUL).begin() == begin(sc) + 4); + assert(ranges::find_last(sc, 0xFFFFFFFEUL).begin() == begin(sc) + 3); + assert(ranges::find_last(sc, 0xFFFFFFAAUL).begin() == end(sc)); + assert(ranges::find_last(sc, 0xFFFFFF81UL).begin() == begin(sc) + 1); + assert(ranges::find_last(sc, 0xFFFFFF80UL).begin() == begin(sc)); + assert(ranges::find_last(sc, 0xFFFFFF7FUL).begin() == end(sc)); + assert(ranges::find_last(sc, 0xFFFFFF00UL).begin() == end(sc)); + + assert(ranges::find_last(sc, 0xFFFFFFFFFFFFFFFFULL).begin() == begin(sc) + 4); + assert(ranges::find_last(sc, 0xFFFFFFFFFFFFFFFEULL).begin() == begin(sc) + 3); + assert(ranges::find_last(sc, 0xFFFFFFFFFFFFFFAAULL).begin() == end(sc)); + assert(ranges::find_last(sc, 0xFFFFFFFFFFFFFF81ULL).begin() == begin(sc) + 1); + assert(ranges::find_last(sc, 0xFFFFFFFFFFFFFF80ULL).begin() == begin(sc)); + assert(ranges::find_last(sc, 0xFFFFFFFFFFFFFF7FULL).begin() == end(sc)); + assert(ranges::find_last(sc, 0xFFFFFFFFFFFFFF00ULL).begin() == end(sc)); +#endif // _HAS_CXX23 + const short ss[] = {-32768, -32767, -32766, -2, -1, 0, 1, 2, 32765, 32766, 32767}; STATIC_ASSERT(static_cast(-1) != static_cast(0xFFFF)); @@ -511,6 +562,26 @@ int main() { assert(find(begin(ss), end(ss), 0xFFFFFFFFFFFF7FFFULL) == end(ss)); assert(find(begin(ss), end(ss), 0xFFFFFFFFFFFF0000ULL) == end(ss)); +#if _HAS_CXX23 + assert(ranges::find_last(ss, static_cast(0xFFFF)).begin() == end(ss)); + + assert(ranges::find_last(ss, 0xFFFFFFFFUL).begin() == begin(ss) + 4); + assert(ranges::find_last(ss, 0xFFFFFFFEUL).begin() == begin(ss) + 3); + assert(ranges::find_last(ss, 0xFFFFAAAAUL).begin() == end(ss)); + assert(ranges::find_last(ss, 0xFFFF8001UL).begin() == begin(ss) + 1); + assert(ranges::find_last(ss, 0xFFFF8000UL).begin() == begin(ss)); + assert(ranges::find_last(ss, 0xFFFF7FFFUL).begin() == end(ss)); + assert(ranges::find_last(ss, 0xFFFF0000UL).begin() == end(ss)); + + assert(ranges::find_last(ss, 0xFFFFFFFFFFFFFFFFULL).begin() == begin(ss) + 4); + assert(ranges::find_last(ss, 0xFFFFFFFFFFFFFFFEULL).begin() == begin(ss) + 3); + assert(ranges::find_last(ss, 0xFFFFFFFFFFFFAAAAULL).begin() == end(ss)); + assert(ranges::find_last(ss, 0xFFFFFFFFFFFF8001ULL).begin() == begin(ss) + 1); + assert(ranges::find_last(ss, 0xFFFFFFFFFFFF8000ULL).begin() == begin(ss)); + assert(ranges::find_last(ss, 0xFFFFFFFFFFFF7FFFULL).begin() == end(ss)); + assert(ranges::find_last(ss, 0xFFFFFFFFFFFF0000ULL).begin() == end(ss)); +#endif // _HAS_CXX23 + // No longer integral promotions, still repeat the applicable part once to be sure const long sl[] = {long_min, long_min + 1, long_min + 2, -2, -1, 0, 1, 2, long_max - 2, long_max - 1, long_max}; @@ -536,6 +607,24 @@ int main() { assert(find(begin(sl), end(sl), 0xFFFFFFFF80000000ULL) == begin(sl)); assert(find(begin(sl), end(sl), 0xFFFFFFFF7FFFFFFFULL) == end(sl)); assert(find(begin(sl), end(sl), 0xFFFFFFFF00000000ULL) == end(sl)); + +#if _HAS_CXX23 + assert(ranges::find_last(sl, static_cast(0xFFFF)).begin() == end(sl)); + + assert(ranges::find_last(sl, 0xFFFFFFFFUL).begin() == begin(sl) + 4); + assert(ranges::find_last(sl, 0xFFFFFFFEUL).begin() == begin(sl) + 3); + assert(ranges::find_last(sl, 0xAAAAAAAAUL).begin() == end(sl)); + assert(ranges::find_last(sl, 0x80000001UL).begin() == begin(sl) + 1); + assert(ranges::find_last(sl, 0x80000000UL).begin() == begin(sl)); + + assert(ranges::find_last(sl, 0xFFFFFFFFFFFFFFFFULL).begin() == begin(sl) + 4); + assert(ranges::find_last(sl, 0xFFFFFFFFFFFFFFFEULL).begin() == begin(sl) + 3); + assert(ranges::find_last(sl, 0xFFFFFFFFAAAAAAAAULL).begin() == end(sl)); + assert(ranges::find_last(sl, 0xFFFFFFFF80000001ULL).begin() == begin(sl) + 1); + assert(ranges::find_last(sl, 0xFFFFFFFF80000000ULL).begin() == begin(sl)); + assert(ranges::find_last(sl, 0xFFFFFFFF7FFFFFFFULL).begin() == end(sl)); + assert(ranges::find_last(sl, 0xFFFFFFFF00000000ULL).begin() == end(sl)); +#endif // _HAS_CXX23 } { // unsigned int == int, weird conversions yay! (GH-3244) @@ -546,6 +635,14 @@ int main() { assert(find(begin(ui), end(ui), 3) == end(ui)); assert(find(begin(ui), end(ui), -2) == begin(ui) + 4); assert(find(begin(ui), end(ui), -1) == begin(ui) + 5); + +#if _HAS_CXX23 + assert(ranges::find_last(ui, 0).begin() == begin(ui)); + assert(ranges::find_last(ui, 2).begin() == begin(ui) + 2); + assert(ranges::find_last(ui, 3).begin() == end(ui)); + assert(ranges::find_last(ui, -2).begin() == begin(ui) + 4); + assert(ranges::find_last(ui, -1).begin() == begin(ui) + 5); +#endif // _HAS_CXX23 } { // Test bools @@ -560,6 +657,12 @@ int main() { assert(count(begin(arr), end(arr), false) == 2); assert(count(begin(arr), end(arr), true) == 4); assert(count(begin(arr), end(arr), 2) == 0); + +#if _HAS_CXX23 + assert(ranges::find_last(arr, false).begin() == begin(arr) + 5); + assert(ranges::find_last(arr, true).begin() == begin(arr) + 4); + assert(ranges::find_last(arr, 2).begin() == end(arr)); +#endif // _HAS_CXX23 } { // Test pointers @@ -598,6 +701,22 @@ int main() { assert(count(begin(arr), end(arr), static_cast(nullptr)) == 1); assert(count(begin(arr), end(arr), nullptr) == 1); +#if _HAS_CXX23 + assert(ranges::find_last(arr, s).begin() == begin(arr) + 4); + assert(ranges::find_last(arr, const_cast(s)).begin() == begin(arr) + 4); + assert(ranges::find_last(arr, const_cast(s)).begin() == begin(arr) + 4); + + assert(ranges::find_last(arr, s + 1).begin() == begin(arr) + 2); + assert(ranges::find_last(arr, static_cast(s + 1)).begin() == begin(arr) + 2); + + assert(ranges::find_last(arr, s + 3).begin() == end(arr)); + assert(ranges::find_last(arr, static_cast(s + 3)).begin() == end(arr)); + + assert(ranges::find_last(arr, static_cast(nullptr)).begin() == begin(arr) + 6); + assert(ranges::find_last(arr, static_cast(nullptr)).begin() == begin(arr) + 6); + assert(ranges::find_last(arr, nullptr).begin() == begin(arr) + 6); +#endif // _HAS_CXX23 + // const void pointer range assert(find(begin(arr_void), end(arr_void), s) == begin(arr_void)); assert(find(begin(arr_void), end(arr_void), const_cast(s)) == begin(arr_void)); @@ -618,6 +737,22 @@ int main() { assert(count(begin(arr_void), end(arr_void), s + 3) == 0); assert(count(begin(arr_void), end(arr_void), static_cast(nullptr)) == 1); assert(count(begin(arr_void), end(arr_void), nullptr) == 1); + +#if _HAS_CXX23 + assert(ranges::find_last(arr_void, s).begin() == begin(arr_void) + 4); + assert(ranges::find_last(arr_void, const_cast(s)).begin() == begin(arr_void) + 4); + assert(ranges::find_last(arr_void, const_cast(s)).begin() == begin(arr_void) + 4); + + assert(ranges::find_last(arr_void, s + 1).begin() == begin(arr_void) + 2); + assert(ranges::find_last(arr_void, static_cast(s + 1)).begin() == begin(arr_void) + 2); + + assert(ranges::find_last(arr_void, s + 3).begin() == end(arr_void)); + assert(ranges::find_last(arr_void, static_cast(s + 3)).begin() == end(arr_void)); + + assert(ranges::find_last(arr_void, static_cast(nullptr)).begin() == begin(arr_void) + 6); + assert(ranges::find_last(arr_void, static_cast(nullptr)).begin() == begin(arr_void) + 6); + assert(ranges::find_last(arr_void, nullptr).begin() == begin(arr_void) + 6); +#endif // _HAS_CXX23 } { // random other checks for _Vector_alg_in_find_is_safe