Skip to content

[libc++] Support constexpr for std::stable_sort in radix sort branch #125284

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions libcxx/include/__algorithm/radix_sort.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -67,7 +68,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 14

template <class _InputIterator, class _OutputIterator>
_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};
Expand Down Expand Up @@ -109,15 +110,15 @@ struct __counting_sort_traits {
};

template <class _Radix, class _Integer>
_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>;

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

template <class _ForwardIterator, class _Map, class _RandomAccessIterator>
_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>;
Expand All @@ -129,7 +130,7 @@ __collect(_ForwardIterator __first, _ForwardIterator __last, _Map __map, _Random
}

template <class _ForwardIterator, class _RandomAccessIterator1, class _Map, class _RandomAccessIterator2>
_LIBCPP_HIDE_FROM_ABI void
_LIBCPP_HIDE_FROM_ABI constexpr void
__dispose(_ForwardIterator __first,
_ForwardIterator __last,
_RandomAccessIterator1 __result,
Expand All @@ -147,7 +148,7 @@ template <class _ForwardIterator,
class _RandomAccessIterator1,
class _RandomAccessIterator2,
size_t... _Radices>
_LIBCPP_HIDE_FROM_ABI bool __collect_impl(
_LIBCPP_HIDE_FROM_ABI constexpr bool __collect_impl(
_ForwardIterator __first,
_ForwardIterator __last,
_Map __map,
Expand Down Expand Up @@ -177,7 +178,7 @@ _LIBCPP_HIDE_FROM_ABI bool __collect_impl(
}

template <class _ForwardIterator, class _Map, class _Radix, class _RandomAccessIterator1, class _RandomAccessIterator2>
_LIBCPP_HIDE_FROM_ABI bool
_LIBCPP_HIDE_FROM_ABI constexpr bool
__collect(_ForwardIterator __first,
_ForwardIterator __last,
_Map __map,
Expand All @@ -191,7 +192,7 @@ __collect(_ForwardIterator __first,
}

template <class _BidirectionalIterator, class _RandomAccessIterator1, class _Map, class _RandomAccessIterator2>
_LIBCPP_HIDE_FROM_ABI void __dispose_backward(
_LIBCPP_HIDE_FROM_ABI constexpr void __dispose_backward(
_BidirectionalIterator __first,
_BidirectionalIterator __last,
_RandomAccessIterator1 __result,
Expand All @@ -206,7 +207,7 @@ _LIBCPP_HIDE_FROM_ABI void __dispose_backward(
}

template <class _ForwardIterator, class _RandomAccessIterator, class _Map>
_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>;
Expand All @@ -225,7 +226,7 @@ template <class _RandomAccessIterator1,
class _Radix,
enable_if_t< __radix_sort_traits<__iter_value_type<_RandomAccessIterator1>, _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,
Expand All @@ -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,
Expand Down Expand Up @@ -307,7 +308,7 @@ struct __low_byte_fn {
};

template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Map, class _Radix>
_LIBCPP_HIDE_FROM_ABI void
_LIBCPP_HIDE_FROM_ABI constexpr void
__radix_sort(_RandomAccessIterator1 __first,
_RandomAccessIterator1 __last,
_RandomAccessIterator2 __buffer,
Expand All @@ -318,7 +319,7 @@ __radix_sort(_RandomAccessIterator1 __first,
}

template <class _RandomAccessIterator1, class _RandomAccessIterator2>
_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{});
}
Expand Down
7 changes: 7 additions & 0 deletions libcxx/include/__algorithm/stable_sort.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -253,6 +254,12 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void __stable_sort(
if constexpr (__allowed_radix_sort) {
if (__len <= __buff_size && __len >= static_cast<difference_type>(__radix_sort_min_bound<value_type>()) &&
__len <= static_cast<difference_type>(__radix_sort_max_bound<value_type>())) {
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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ int main(int, char**) {
#if TEST_STD_VER >= 26
static_assert(test<int>());
static_assert(test<float>());
// test constexprness of radix sort branch
static_assert(test<char>());
#endif
return 0;
}