Skip to content

Commit 811b456

Browse files
committed
arithmetic-only
1 parent 2584e15 commit 811b456

File tree

3 files changed

+29
-16
lines changed

3 files changed

+29
-16
lines changed

libcxx/include/__algorithm/radix_sort.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -381,15 +381,9 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __to_ordered_integral(_Floating __f) {
381381
return static_cast<__integral_type>(__u & __sign_bit_mask ? ~__u : __u ^ __sign_bit_mask);
382382
}
383383

384+
// There may exist user-defined comparison for enum, so we cannot compare enums just like integers.
384385
template <class _Enum, enable_if_t< is_enum<_Enum>::value, int> = 0>
385-
_LIBCPP_HIDE_FROM_ABI constexpr auto __to_ordered_integral(_Enum __e) {
386-
return static_cast<std::underlying_type_t<_Enum>>(__e);
387-
}
388-
389-
template <class _Pointer>
390-
_LIBCPP_HIDE_FROM_ABI constexpr auto __to_ordered_integral(_Pointer* __ptr) {
391-
return std::__bit_cast<__unsigned_representation_for_t<_Pointer*>>(__ptr);
392-
}
386+
_LIBCPP_HIDE_FROM_ABI constexpr auto __to_ordered_integral(_Enum __e) = delete;
393387

394388
struct __low_byte_fn {
395389
template <class _Ip>

libcxx/include/__algorithm/stable_sort.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@
2626
#include <__type_traits/desugars_to.h>
2727
#include <__type_traits/enable_if.h>
2828
#include <__type_traits/invoke.h>
29+
#include <__type_traits/is_arithmetic.h>
2930
#include <__type_traits/is_constant_evaluated.h>
3031
#include <__type_traits/is_same.h>
31-
#include <__type_traits/is_scalar.h>
3232
#include <__type_traits/is_trivially_assignable.h>
3333
#include <__utility/move.h>
3434
#include <__utility/pair.h>
@@ -202,7 +202,7 @@ struct __stable_sort_switch {
202202
#if _LIBCPP_STD_VER >= 17
203203
template <class _Tp>
204204
_LIBCPP_HIDE_FROM_ABI constexpr unsigned __radix_sort_min_bound() {
205-
static_assert(is_scalar<_Tp>::value);
205+
static_assert(is_arithmetic<_Tp>::value);
206206
if constexpr (sizeof(_Tp) == 1) {
207207
return 1 << 8;
208208
}
@@ -212,7 +212,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr unsigned __radix_sort_min_bound() {
212212

213213
template <class _Tp>
214214
_LIBCPP_HIDE_FROM_ABI constexpr unsigned __radix_sort_max_bound() {
215-
static_assert(is_scalar<_Tp>::value);
215+
static_assert(is_arithmetic<_Tp>::value);
216216
if constexpr (sizeof(_Tp) >= 8) {
217217
return 1 << 15;
218218
}
@@ -248,11 +248,9 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 void __stable_sort(
248248

249249
#if _LIBCPP_STD_VER >= 17
250250
constexpr auto __default_comp = __desugars_to_v<__less_tag, _Compare, value_type, value_type >;
251-
constexpr auto __scalar_value =
252-
is_scalar_v<value_type > && is_same_v< value_type&, __iter_reference<_RandomAccessIterator>>;
253-
// There are non-comparable scalars (std::nullptr_t, pointers to members), so we need to exclude them.
254-
constexpr auto __comparable_value = is_invocable_r_v<bool, _Compare, value_type, value_type>;
255-
if constexpr (__default_comp && __scalar_value && __comparable_value) {
251+
constexpr auto __arithmetic_value =
252+
is_arithmetic_v<value_type > && is_same_v< value_type&, __iter_reference<_RandomAccessIterator>>;
253+
if constexpr (__default_comp && __arithmetic_value) {
256254
if (__len <= __buff_size && __len >= static_cast<difference_type>(std::__radix_sort_min_bound<value_type>()) &&
257255
__len <= static_cast<difference_type>(std::__radix_sort_max_bound<value_type>())) {
258256
if (__libcpp_is_constant_evaluated()) {

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,31 @@ bool test_floating() {
225225
return test<T>() && test_floating_special_values<T>();
226226
}
227227

228+
enum struct Enum : int { a, b, c, d, e, f, g, h };
229+
TEST_CONSTEXPR_CXX26 bool operator<(Enum x, Enum y) { return static_cast<int>(x) > static_cast<int>(y); }
230+
231+
TEST_CONSTEXPR_CXX26 bool test_enum() {
232+
auto v = std::vector<Enum>(128, Enum::a);
233+
v.resize(v.size() + 128, Enum::b);
234+
v.resize(v.size() + 128, Enum::c);
235+
v.resize(v.size() + 128, Enum::d);
236+
v.resize(v.size() + 128, Enum::e);
237+
v.resize(v.size() + 128, Enum::f);
238+
v.resize(v.size() + 128, Enum::g);
239+
v.resize(v.size() + 128, Enum::h);
240+
241+
// Order is reversed by definition
242+
std::stable_sort(v.begin(), v.end());
243+
assert(std::is_sorted(v.begin(), v.end()));
244+
245+
return true;
246+
}
247+
228248
int main(int, char**) {
229249
test<int>();
230250
test_floating<float>();
231251
test_floating<double>();
252+
test_enum();
232253
#if TEST_STD_VER >= 26
233254
static_assert(test<int>());
234255
static_assert(test<float>());

0 commit comments

Comments
 (0)