[libcxx-commits] [libcxx] Libcxx nth element small ranges (PR #215698)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Aug 12 06:04:29 PDT 2026
================
@@ -28,6 +28,43 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
+// Handles ranges of at most 5 elements by sorting them entirely, which trivially satisfies the
+// nth_element postconditions. Sorting networks are the most efficient way to handle such small
+// ranges, and this function boils down to one of them when the size of the range is known at
+// compile time. Returns false if the range was too large to be handled.
+template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
+__nth_element_small(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
+ using _Ops = _IterOps<_AlgPolicy>;
+ typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+ switch (__last - __first) {
+ case 0:
+ case 1:
+ return true;
+ case 2:
+ if (__comp(*--__last, *__first))
+ _Ops::iter_swap(__first, __last);
+ return true;
+ case 3:
+ std::__sort3<_AlgPolicy, _Compare>(__first, __first + difference_type(1), --__last, __comp);
+ return true;
+ case 4:
+ std::__sort4<_AlgPolicy, _Compare>(
+ __first, __first + difference_type(1), __first + difference_type(2), --__last, __comp);
+ return true;
+ case 5:
+ std::__sort5<_AlgPolicy, _Compare>(
----------------
ldionne wrote:
Is this really the fastest way to write a median-of-5 algorithm? Google tells me that The Art of Computer Programming contains an algorithm with exactly 6 comparisons. `__sort5` is a bit different: it needs to do more work, since it fully sorts the range.
Same comment likely applies to the 4 element case and maybe to the 3 element case.
If you think this is actually optimal, can you please explain?
https://github.com/llvm/llvm-project/pull/215698
More information about the libcxx-commits
mailing list