From 6e402f5121e87e82fa686046c867ef67d4b4b851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9=20=D0=98=D0=B7?= =?UTF-8?q?=D0=B2=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Thu, 6 Feb 2025 11:07:25 +0300 Subject: [PATCH] [libc++] Support `constexpr` for `std::stable_sort` in radix sort branch (#125284) `std::stable_sort` is `constexpr` since PR https://github.com/llvm/llvm-project/pull/110320 But `radix_sort` branch is still non-`constexpr`. This PR fixes it. #119394 #105360 --- libcxx/include/__algorithm/radix_sort.h | 25 ++++++++++--------- libcxx/include/__algorithm/stable_sort.h | 7 ++++++ .../alg.sort/stable.sort/stable_sort.pass.cpp | 2 ++ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/libcxx/include/__algorithm/radix_sort.h b/libcxx/include/__algorithm/radix_sort.h index de6927995e74..f6d9fb1ad7ca 100644 --- a/libcxx/include/__algorithm/radix_sort.h +++ b/libcxx/include/__algorithm/radix_sort.h @@ -33,6 +33,7 @@ #include <__bit/countl.h> #include <__config> #include <__functional/identity.h> +#include <__iterator/access.h> #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> #include <__iterator/move_iterator.h> @@ -67,7 +68,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 14 template -_LIBCPP_HIDE_FROM_ABI pair<_OutputIterator, __iter_value_type<_InputIterator>> +_LIBCPP_HIDE_FROM_ABI constexpr pair<_OutputIterator, __iter_value_type<_InputIterator>> __partial_sum_max(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { if (__first == __last) return {__result, 0}; @@ -109,7 +110,7 @@ struct __counting_sort_traits { }; template -_LIBCPP_HIDE_FROM_ABI auto __nth_radix(size_t __radix_number, _Radix __radix, _Integer __n) { +_LIBCPP_HIDE_FROM_ABI constexpr auto __nth_radix(size_t __radix_number, _Radix __radix, _Integer __n) { static_assert(is_unsigned<_Integer>::value); using __traits = __counting_sort_traits<_Integer, _Radix>; @@ -117,7 +118,7 @@ _LIBCPP_HIDE_FROM_ABI auto __nth_radix(size_t __radix_number, _Radix __radix, _I } template -_LIBCPP_HIDE_FROM_ABI void +_LIBCPP_HIDE_FROM_ABI constexpr void __collect(_ForwardIterator __first, _ForwardIterator __last, _Map __map, _RandomAccessIterator __counters) { using __value_type = __iter_value_type<_ForwardIterator>; using __traits = __counting_sort_traits<__value_type, _Map>; @@ -129,7 +130,7 @@ __collect(_ForwardIterator __first, _ForwardIterator __last, _Map __map, _Random } template -_LIBCPP_HIDE_FROM_ABI void +_LIBCPP_HIDE_FROM_ABI constexpr void __dispose(_ForwardIterator __first, _ForwardIterator __last, _RandomAccessIterator1 __result, @@ -147,7 +148,7 @@ template -_LIBCPP_HIDE_FROM_ABI bool __collect_impl( +_LIBCPP_HIDE_FROM_ABI constexpr bool __collect_impl( _ForwardIterator __first, _ForwardIterator __last, _Map __map, @@ -177,7 +178,7 @@ _LIBCPP_HIDE_FROM_ABI bool __collect_impl( } template -_LIBCPP_HIDE_FROM_ABI bool +_LIBCPP_HIDE_FROM_ABI constexpr bool __collect(_ForwardIterator __first, _ForwardIterator __last, _Map __map, @@ -191,7 +192,7 @@ __collect(_ForwardIterator __first, } template -_LIBCPP_HIDE_FROM_ABI void __dispose_backward( +_LIBCPP_HIDE_FROM_ABI constexpr void __dispose_backward( _BidirectionalIterator __first, _BidirectionalIterator __last, _RandomAccessIterator1 __result, @@ -206,7 +207,7 @@ _LIBCPP_HIDE_FROM_ABI void __dispose_backward( } template -_LIBCPP_HIDE_FROM_ABI _RandomAccessIterator +_LIBCPP_HIDE_FROM_ABI constexpr _RandomAccessIterator __counting_sort_impl(_ForwardIterator __first, _ForwardIterator __last, _RandomAccessIterator __result, _Map __map) { using __value_type = __iter_value_type<_ForwardIterator>; using __traits = __counting_sort_traits<__value_type, _Map>; @@ -225,7 +226,7 @@ template , _Map, _Radix>::__radix_count == 1, int> = 0> -_LIBCPP_HIDE_FROM_ABI void __radix_sort_impl( +_LIBCPP_HIDE_FROM_ABI constexpr void __radix_sort_impl( _RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __buffer, @@ -245,7 +246,7 @@ template < class _Radix, enable_if_t< __radix_sort_traits<__iter_value_type<_RandomAccessIterator1>, _Map, _Radix>::__radix_count % 2 == 0, int> = 0 > -_LIBCPP_HIDE_FROM_ABI void __radix_sort_impl( +_LIBCPP_HIDE_FROM_ABI constexpr void __radix_sort_impl( _RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __buffer_begin, @@ -307,7 +308,7 @@ struct __low_byte_fn { }; template -_LIBCPP_HIDE_FROM_ABI void +_LIBCPP_HIDE_FROM_ABI constexpr void __radix_sort(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __buffer, @@ -318,7 +319,7 @@ __radix_sort(_RandomAccessIterator1 __first, } template -_LIBCPP_HIDE_FROM_ABI void +_LIBCPP_HIDE_FROM_ABI constexpr void __radix_sort(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __buffer) { std::__radix_sort(__first, __last, __buffer, __identity{}, __low_byte_fn{}); } diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h index 3cfbcf08d2c5..49d3cca2526e 100644 --- a/libcxx/include/__algorithm/stable_sort.h +++ b/libcxx/include/__algorithm/stable_sort.h @@ -25,6 +25,7 @@ #include <__memory/unique_temporary_buffer.h> #include <__type_traits/desugars_to.h> #include <__type_traits/enable_if.h> +#include <__type_traits/is_constant_evaluated.h> #include <__type_traits/is_integral.h> #include <__type_traits/is_same.h> #include <__type_traits/is_trivially_assignable.h> @@ -253,6 +254,12 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void __stable_sort( if constexpr (__allowed_radix_sort) { if (__len <= __buff_size && __len >= static_cast(__radix_sort_min_bound()) && __len <= static_cast(__radix_sort_max_bound())) { + if (__libcpp_is_constant_evaluated()) { + for (auto* __p = __buff; __p < __buff + __buff_size; ++__p) { + std::__construct_at(__p); + } + } + std::__radix_sort(__first, __last, __buff); return; } diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp index b3b458808c44..4ee1d795a23b 100644 --- a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp +++ b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp @@ -199,6 +199,8 @@ int main(int, char**) { #if TEST_STD_VER >= 26 static_assert(test()); static_assert(test()); + // test constexprness of radix sort branch + static_assert(test()); #endif return 0; }