[libcxx-commits] [libcxx] [libc++] Support sorting consteval-only ranges (PR #134623)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Apr 19 09:35:16 PDT 2025
================
@@ -912,30 +900,63 @@ using __sort_is_specialized_in_library _LIBCPP_NODEBUG = __is_any_of<
long double>;
template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, __less<>&) {
- __less<_Type> __comp;
- std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp);
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __sort_dispatch(_Type* __first, _Type* __last, __less<>&) {
+#if _LIBCPP_STD_VER >= 20
+ if (std::is_constant_evaluated()) {
+ auto __depth_limit = static_cast<ptrdiff_t>(2 * std::__bit_log2(static_cast<size_t>(__last - __first)));
+ std::__introsort<_ClassicAlgPolicy, ranges::less, _Type*, __use_branchless_sort<ranges::less, _Type*>>(
+ __first, __last, ranges::less{}, __depth_limit);
+ } else
+#endif
----------------
philnik777 wrote:
> > How does it not make a difference when they can't be instantiated because they're not defined?
>
> No, the error is not about undefined functions. It is about functions templates that are defined but not constexpr (i.e. `__introsort` etc. in the status quo).
>
> > I don't understand. How does it make a difference whether some functions that aren't constexpr are instantiated or not?
>
> The expression `__last - __first` inside `__introsort` can't be a constant expression because `__first` and `__last` are function parameters. When the `operator-` for the iterator is a `consteval` function and `__introsort` is not `constexpr`, `__last - __first` would be required to be a constant expression, which makes instantiation of `__introsort` ill-formed.
>
> Marking `__introsort` `constexpr` makes the `__introsort` specialization gets immediate-escalated and becomes an immediate function, and thus its instantiation can be well-formed.
That is quite unfortunate. IMO it shouldn't make a difference whether we define a function or not. Anyways, can't we just replace the `if (__libcpp_is_constant_evaluated())` with `if consteval`? That would make the diff significantly smaller.
https://github.com/llvm/llvm-project/pull/134623
More information about the libcxx-commits
mailing list