[libcxx-commits] [libcxx] [libc++][pstl] Implementation of parallel std::reverse() based on parallel for_each (PR #213487)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Aug 3 06:02:30 PDT 2026
================
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___PSTL_CPU_ALGOS_REVERSE_H
+#define _LIBCPP___PSTL_CPU_ALGOS_REVERSE_H
+
+#include <__algorithm/reverse.h>
+#include <__algorithm/swap_ranges.h>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/reverse_iterator.h>
+#include <__optional/optional.h>
+#include <__pstl/backend_fwd.h>
+#include <__pstl/cpu_algos/cpu_traits.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__utility/empty.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __cpu_parallel_reverse {
+ template <class _Policy, class _ForwardIterator>
+ _LIBCPP_HIDE_FROM_ABI optional<__empty>
+ operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last) const noexcept {
+ if constexpr (__is_parallel_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
+ // Perform a chunked for_each on the first half of the range.
----------------
ldionne wrote:
Can you add a sentence about how odd-sized ranges are handled. IIUC, this is really clever. Since you start from the end to calculate the mirror range, in case of an odd sized input range the middle element ends up unswapped, and that's fine since it already sits in the right position. For an even-sized range, the first range and its mirror are immediately consecutive.
I originally thought you didn't handle odd-sized ranges and I had to walk through an odd-sized case step by step to understand, so I think a short sentence would be helpful.
https://github.com/llvm/llvm-project/pull/213487
More information about the libcxx-commits
mailing list