[libcxx-commits] [libcxx] [libc++] Support `constexpr` for `std::stable_sort` in radix sort branch (PR #125284)

Дмитрий Изволов via libcxx-commits libcxx-commits at lists.llvm.org
Sat Feb 1 04:51:11 PST 2025


https://github.com/izvolov updated https://github.com/llvm/llvm-project/pull/125284

>From 96d373c9a4d88d5da1581f1d3a00e85dbdc76744 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?= <dmitriy at izvolov.ru>
Date: Fri, 31 Jan 2025 22:00:09 +0300
Subject: [PATCH 1/3] constexpr

---
 libcxx/include/__algorithm/radix_sort.h       | 24 +++++++++----------
 libcxx/include/__algorithm/stable_sort.h      |  6 +++++
 .../alg.sort/stable.sort/stable_sort.pass.cpp |  3 ++-
 3 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/libcxx/include/__algorithm/radix_sort.h b/libcxx/include/__algorithm/radix_sort.h
index de6927995e74c89..89df4e19fd00fb5 100644
--- a/libcxx/include/__algorithm/radix_sort.h
+++ b/libcxx/include/__algorithm/radix_sort.h
@@ -67,7 +67,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};
@@ -109,7 +109,7 @@ 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>;
 
@@ -117,7 +117,7 @@ _LIBCPP_HIDE_FROM_ABI auto __nth_radix(size_t __radix_number, _Radix __radix, _I
 }
 
 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>;
@@ -129,7 +129,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,
@@ -147,7 +147,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,
@@ -177,7 +177,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,
@@ -191,7 +191,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,
@@ -206,7 +206,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>;
@@ -225,7 +225,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,
@@ -245,7 +245,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 +307,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,
@@ -318,7 +318,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{});
 }
diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index 3cfbcf08d2c5c44..21bc3a947069c0d 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -253,6 +253,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>())) {
+      for (auto* p = __buff; p < __buff + __buff_size; ++p) {
+        std::__construct_at(p, 0);
+      }
+      __destruct_n __d(__buff_size);
+      unique_ptr<value_type, __destruct_n&> __h2(__buff, __d);
+
       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 b3b458808c44ad5..1e529529b78f96f 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
@@ -178,8 +178,9 @@ TEST_CONSTEXPR_CXX26 bool test() {
     test_larger_sorts<T>(1009);
     test_larger_sorts<T>(1024);
     test_larger_sorts<T>(1031);
-    test_larger_sorts<T>(2053);
   }
+  // test constexprness of radix sort branch
+  test_larger_sorts<T>(2053);
 
   // check that the algorithm works without memory
 #ifndef TEST_HAS_NO_EXCEPTIONS

>From 4d5783d1ead702b4b1383e8aa873456303beaf6f 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?= <dmitriy at izvolov.ru>
Date: Sat, 1 Feb 2025 09:09:19 +0300
Subject: [PATCH 2/3] fix-case

---
 libcxx/include/__algorithm/stable_sort.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h
index 21bc3a947069c0d..8659039dcf24b79 100644
--- a/libcxx/include/__algorithm/stable_sort.h
+++ b/libcxx/include/__algorithm/stable_sort.h
@@ -253,8 +253,8 @@ _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>())) {
-      for (auto* p = __buff; p < __buff + __buff_size; ++p) {
-        std::__construct_at(p, 0);
+      for (auto* __p = __buff; __p < __buff + __buff_size; ++__p) {
+        std::__construct_at(__p, 0);
       }
       __destruct_n __d(__buff_size);
       unique_ptr<value_type, __destruct_n&> __h2(__buff, __d);

>From 85e5de009cf69f4166cff46433b97ad4f530779a 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?= <dmitriy at izvolov.ru>
Date: Sat, 1 Feb 2025 15:50:03 +0300
Subject: [PATCH 3/3] smaller

---
 .../alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp     | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

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 1e529529b78f96f..8c82e7d8eea00ff 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
@@ -176,11 +176,11 @@ TEST_CONSTEXPR_CXX26 bool test() {
     test_larger_sorts<T>(997);
     test_larger_sorts<T>(1000);
     test_larger_sorts<T>(1009);
-    test_larger_sorts<T>(1024);
     test_larger_sorts<T>(1031);
+    test_larger_sorts<T>(2053);
   }
   // test constexprness of radix sort branch
-  test_larger_sorts<T>(2053);
+  test_larger_sorts<T>(1024);
 
   // check that the algorithm works without memory
 #ifndef TEST_HAS_NO_EXCEPTIONS



More information about the libcxx-commits mailing list