Skip to content

Commit 6e402f5

Browse files
authored
[libc++] Support constexpr for std::stable_sort in radix sort branch (#125284)
`std::stable_sort` is `constexpr` since PR #110320 But `radix_sort` branch is still non-`constexpr`. This PR fixes it. #119394 #105360
1 parent c4f5463 commit 6e402f5

File tree

3 files changed

+22
-12
lines changed

3 files changed

+22
-12
lines changed

libcxx/include/__algorithm/radix_sort.h

+13-12
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <__bit/countl.h>
3434
#include <__config>
3535
#include <__functional/identity.h>
36+
#include <__iterator/access.h>
3637
#include <__iterator/distance.h>
3738
#include <__iterator/iterator_traits.h>
3839
#include <__iterator/move_iterator.h>
@@ -67,7 +68,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
6768
#if _LIBCPP_STD_VER >= 14
6869

6970
template <class _InputIterator, class _OutputIterator>
70-
_LIBCPP_HIDE_FROM_ABI pair<_OutputIterator, __iter_value_type<_InputIterator>>
71+
_LIBCPP_HIDE_FROM_ABI constexpr pair<_OutputIterator, __iter_value_type<_InputIterator>>
7172
__partial_sum_max(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
7273
if (__first == __last)
7374
return {__result, 0};
@@ -109,15 +110,15 @@ struct __counting_sort_traits {
109110
};
110111

111112
template <class _Radix, class _Integer>
112-
_LIBCPP_HIDE_FROM_ABI auto __nth_radix(size_t __radix_number, _Radix __radix, _Integer __n) {
113+
_LIBCPP_HIDE_FROM_ABI constexpr auto __nth_radix(size_t __radix_number, _Radix __radix, _Integer __n) {
113114
static_assert(is_unsigned<_Integer>::value);
114115
using __traits = __counting_sort_traits<_Integer, _Radix>;
115116

116117
return __radix(static_cast<_Integer>(__n >> __traits::__radix_size * __radix_number));
117118
}
118119

119120
template <class _ForwardIterator, class _Map, class _RandomAccessIterator>
120-
_LIBCPP_HIDE_FROM_ABI void
121+
_LIBCPP_HIDE_FROM_ABI constexpr void
121122
__collect(_ForwardIterator __first, _ForwardIterator __last, _Map __map, _RandomAccessIterator __counters) {
122123
using __value_type = __iter_value_type<_ForwardIterator>;
123124
using __traits = __counting_sort_traits<__value_type, _Map>;
@@ -129,7 +130,7 @@ __collect(_ForwardIterator __first, _ForwardIterator __last, _Map __map, _Random
129130
}
130131

131132
template <class _ForwardIterator, class _RandomAccessIterator1, class _Map, class _RandomAccessIterator2>
132-
_LIBCPP_HIDE_FROM_ABI void
133+
_LIBCPP_HIDE_FROM_ABI constexpr void
133134
__dispose(_ForwardIterator __first,
134135
_ForwardIterator __last,
135136
_RandomAccessIterator1 __result,
@@ -147,7 +148,7 @@ template <class _ForwardIterator,
147148
class _RandomAccessIterator1,
148149
class _RandomAccessIterator2,
149150
size_t... _Radices>
150-
_LIBCPP_HIDE_FROM_ABI bool __collect_impl(
151+
_LIBCPP_HIDE_FROM_ABI constexpr bool __collect_impl(
151152
_ForwardIterator __first,
152153
_ForwardIterator __last,
153154
_Map __map,
@@ -177,7 +178,7 @@ _LIBCPP_HIDE_FROM_ABI bool __collect_impl(
177178
}
178179

179180
template <class _ForwardIterator, class _Map, class _Radix, class _RandomAccessIterator1, class _RandomAccessIterator2>
180-
_LIBCPP_HIDE_FROM_ABI bool
181+
_LIBCPP_HIDE_FROM_ABI constexpr bool
181182
__collect(_ForwardIterator __first,
182183
_ForwardIterator __last,
183184
_Map __map,
@@ -191,7 +192,7 @@ __collect(_ForwardIterator __first,
191192
}
192193

193194
template <class _BidirectionalIterator, class _RandomAccessIterator1, class _Map, class _RandomAccessIterator2>
194-
_LIBCPP_HIDE_FROM_ABI void __dispose_backward(
195+
_LIBCPP_HIDE_FROM_ABI constexpr void __dispose_backward(
195196
_BidirectionalIterator __first,
196197
_BidirectionalIterator __last,
197198
_RandomAccessIterator1 __result,
@@ -206,7 +207,7 @@ _LIBCPP_HIDE_FROM_ABI void __dispose_backward(
206207
}
207208

208209
template <class _ForwardIterator, class _RandomAccessIterator, class _Map>
209-
_LIBCPP_HIDE_FROM_ABI _RandomAccessIterator
210+
_LIBCPP_HIDE_FROM_ABI constexpr _RandomAccessIterator
210211
__counting_sort_impl(_ForwardIterator __first, _ForwardIterator __last, _RandomAccessIterator __result, _Map __map) {
211212
using __value_type = __iter_value_type<_ForwardIterator>;
212213
using __traits = __counting_sort_traits<__value_type, _Map>;
@@ -225,7 +226,7 @@ template <class _RandomAccessIterator1,
225226
class _Radix,
226227
enable_if_t< __radix_sort_traits<__iter_value_type<_RandomAccessIterator1>, _Map, _Radix>::__radix_count == 1,
227228
int> = 0>
228-
_LIBCPP_HIDE_FROM_ABI void __radix_sort_impl(
229+
_LIBCPP_HIDE_FROM_ABI constexpr void __radix_sort_impl(
229230
_RandomAccessIterator1 __first,
230231
_RandomAccessIterator1 __last,
231232
_RandomAccessIterator2 __buffer,
@@ -245,7 +246,7 @@ template <
245246
class _Radix,
246247
enable_if_t< __radix_sort_traits<__iter_value_type<_RandomAccessIterator1>, _Map, _Radix>::__radix_count % 2 == 0,
247248
int> = 0 >
248-
_LIBCPP_HIDE_FROM_ABI void __radix_sort_impl(
249+
_LIBCPP_HIDE_FROM_ABI constexpr void __radix_sort_impl(
249250
_RandomAccessIterator1 __first,
250251
_RandomAccessIterator1 __last,
251252
_RandomAccessIterator2 __buffer_begin,
@@ -307,7 +308,7 @@ struct __low_byte_fn {
307308
};
308309

309310
template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Map, class _Radix>
310-
_LIBCPP_HIDE_FROM_ABI void
311+
_LIBCPP_HIDE_FROM_ABI constexpr void
311312
__radix_sort(_RandomAccessIterator1 __first,
312313
_RandomAccessIterator1 __last,
313314
_RandomAccessIterator2 __buffer,
@@ -318,7 +319,7 @@ __radix_sort(_RandomAccessIterator1 __first,
318319
}
319320

320321
template <class _RandomAccessIterator1, class _RandomAccessIterator2>
321-
_LIBCPP_HIDE_FROM_ABI void
322+
_LIBCPP_HIDE_FROM_ABI constexpr void
322323
__radix_sort(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __buffer) {
323324
std::__radix_sort(__first, __last, __buffer, __identity{}, __low_byte_fn{});
324325
}

libcxx/include/__algorithm/stable_sort.h

+7
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <__memory/unique_temporary_buffer.h>
2626
#include <__type_traits/desugars_to.h>
2727
#include <__type_traits/enable_if.h>
28+
#include <__type_traits/is_constant_evaluated.h>
2829
#include <__type_traits/is_integral.h>
2930
#include <__type_traits/is_same.h>
3031
#include <__type_traits/is_trivially_assignable.h>
@@ -253,6 +254,12 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void __stable_sort(
253254
if constexpr (__allowed_radix_sort) {
254255
if (__len <= __buff_size && __len >= static_cast<difference_type>(__radix_sort_min_bound<value_type>()) &&
255256
__len <= static_cast<difference_type>(__radix_sort_max_bound<value_type>())) {
257+
if (__libcpp_is_constant_evaluated()) {
258+
for (auto* __p = __buff; __p < __buff + __buff_size; ++__p) {
259+
std::__construct_at(__p);
260+
}
261+
}
262+
256263
std::__radix_sort(__first, __last, __buff);
257264
return;
258265
}

libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ int main(int, char**) {
199199
#if TEST_STD_VER >= 26
200200
static_assert(test<int>());
201201
static_assert(test<float>());
202+
// test constexprness of radix sort branch
203+
static_assert(test<char>());
202204
#endif
203205
return 0;
204206
}

0 commit comments

Comments
 (0)