Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-03 08:13:37

0001 //===----------------------------------------------------------------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef _LIBCPP___CXX03___PSTL_BACKENDS_DEFAULT_H
0010 #define _LIBCPP___CXX03___PSTL_BACKENDS_DEFAULT_H
0011 
0012 #include <__cxx03/__algorithm/copy_n.h>
0013 #include <__cxx03/__algorithm/equal.h>
0014 #include <__cxx03/__algorithm/fill_n.h>
0015 #include <__cxx03/__algorithm/for_each_n.h>
0016 #include <__cxx03/__config>
0017 #include <__cxx03/__functional/identity.h>
0018 #include <__cxx03/__functional/not_fn.h>
0019 #include <__cxx03/__functional/operations.h>
0020 #include <__cxx03/__iterator/concepts.h>
0021 #include <__cxx03/__iterator/iterator_traits.h>
0022 #include <__cxx03/__pstl/backend_fwd.h>
0023 #include <__cxx03/__pstl/dispatch.h>
0024 #include <__cxx03/__utility/empty.h>
0025 #include <__cxx03/__utility/forward.h>
0026 #include <__cxx03/__utility/move.h>
0027 #include <__cxx03/optional>
0028 
0029 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0030 #  pragma GCC system_header
0031 #endif
0032 
0033 _LIBCPP_PUSH_MACROS
0034 #include <__cxx03/__undef_macros>
0035 
0036 _LIBCPP_BEGIN_NAMESPACE_STD
0037 namespace __pstl {
0038 
0039 //
0040 // This file provides an incomplete PSTL backend that implements all of the PSTL algorithms
0041 // based on a smaller set of basis operations.
0042 //
0043 // It is intended as a building block for other PSTL backends that implement some operations more
0044 // efficiently but may not want to define the full set of PSTL algorithms.
0045 //
0046 // This backend implements all the PSTL algorithms based on the following basis operations:
0047 //
0048 // find_if family
0049 // --------------
0050 // - find
0051 // - find_if_not
0052 // - any_of
0053 // - all_of
0054 // - none_of
0055 // - is_partitioned
0056 //
0057 // for_each family
0058 // ---------------
0059 // - for_each_n
0060 // - fill
0061 // - fill_n
0062 // - replace
0063 // - replace_if
0064 // - generate
0065 // - generate_n
0066 //
0067 // merge family
0068 // ------------
0069 // No other algorithms based on merge
0070 //
0071 // stable_sort family
0072 // ------------------
0073 // - sort
0074 //
0075 // transform_reduce and transform_reduce_binary family
0076 // ---------------------------------------------------
0077 // - count_if
0078 // - count
0079 // - equal(3 legs)
0080 // - equal
0081 // - reduce
0082 //
0083 // transform and transform_binary family
0084 // -------------------------------------
0085 // - replace_copy_if
0086 // - replace_copy
0087 // - move
0088 // - copy
0089 // - copy_n
0090 // - rotate_copy
0091 //
0092 
0093 //////////////////////////////////////////////////////////////
0094 // find_if family
0095 //////////////////////////////////////////////////////////////
0096 template <class _ExecutionPolicy>
0097 struct __find<__default_backend_tag, _ExecutionPolicy> {
0098   template <class _Policy, class _ForwardIterator, class _Tp>
0099   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
0100   operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) const noexcept {
0101     using _FindIf = __dispatch<__find_if, __current_configuration, _ExecutionPolicy>;
0102     return _FindIf()(
0103         __policy, std::move(__first), std::move(__last), [&](__iter_reference<_ForwardIterator> __element) {
0104           return __element == __value;
0105         });
0106   }
0107 };
0108 
0109 template <class _ExecutionPolicy>
0110 struct __find_if_not<__default_backend_tag, _ExecutionPolicy> {
0111   template <class _Policy, class _ForwardIterator, class _Pred>
0112   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
0113   operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
0114     using _FindIf = __dispatch<__find_if, __current_configuration, _ExecutionPolicy>;
0115     return _FindIf()(__policy, __first, __last, std::not_fn(std::forward<_Pred>(__pred)));
0116   }
0117 };
0118 
0119 template <class _ExecutionPolicy>
0120 struct __any_of<__default_backend_tag, _ExecutionPolicy> {
0121   template <class _Policy, class _ForwardIterator, class _Pred>
0122   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
0123   operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
0124     using _FindIf = __dispatch<__find_if, __current_configuration, _ExecutionPolicy>;
0125     auto __res    = _FindIf()(__policy, __first, __last, std::forward<_Pred>(__pred));
0126     if (!__res)
0127       return nullopt;
0128     return *__res != __last;
0129   }
0130 };
0131 
0132 template <class _ExecutionPolicy>
0133 struct __all_of<__default_backend_tag, _ExecutionPolicy> {
0134   template <class _Policy, class _ForwardIterator, class _Pred>
0135   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
0136   operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
0137     using _AnyOf = __dispatch<__any_of, __current_configuration, _ExecutionPolicy>;
0138     auto __res   = _AnyOf()(__policy, __first, __last, [&](__iter_reference<_ForwardIterator> __value) {
0139       return !__pred(__value);
0140     });
0141     if (!__res)
0142       return nullopt;
0143     return !*__res;
0144   }
0145 };
0146 
0147 template <class _ExecutionPolicy>
0148 struct __none_of<__default_backend_tag, _ExecutionPolicy> {
0149   template <class _Policy, class _ForwardIterator, class _Pred>
0150   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
0151   operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
0152     using _AnyOf = __dispatch<__any_of, __current_configuration, _ExecutionPolicy>;
0153     auto __res   = _AnyOf()(__policy, __first, __last, std::forward<_Pred>(__pred));
0154     if (!__res)
0155       return nullopt;
0156     return !*__res;
0157   }
0158 };
0159 
0160 template <class _ExecutionPolicy>
0161 struct __is_partitioned<__default_backend_tag, _ExecutionPolicy> {
0162   template <class _Policy, class _ForwardIterator, class _Pred>
0163   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
0164   operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred) const noexcept {
0165     using _FindIfNot   = __dispatch<__find_if_not, __current_configuration, _ExecutionPolicy>;
0166     auto __maybe_first = _FindIfNot()(__policy, std::move(__first), std::move(__last), __pred);
0167     if (__maybe_first == nullopt)
0168       return nullopt;
0169 
0170     __first = *__maybe_first;
0171     if (__first == __last)
0172       return true;
0173     ++__first;
0174     using _NoneOf = __dispatch<__none_of, __current_configuration, _ExecutionPolicy>;
0175     return _NoneOf()(__policy, std::move(__first), std::move(__last), __pred);
0176   }
0177 };
0178 
0179 //////////////////////////////////////////////////////////////
0180 // for_each family
0181 //////////////////////////////////////////////////////////////
0182 template <class _ExecutionPolicy>
0183 struct __for_each_n<__default_backend_tag, _ExecutionPolicy> {
0184   template <class _Policy, class _ForwardIterator, class _Size, class _Function>
0185   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
0186   operator()(_Policy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) const noexcept {
0187     if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
0188       using _ForEach          = __dispatch<__for_each, __current_configuration, _ExecutionPolicy>;
0189       _ForwardIterator __last = __first + __size;
0190       return _ForEach()(__policy, std::move(__first), std::move(__last), std::move(__func));
0191     } else {
0192       // Otherwise, use the serial algorithm to avoid doing two passes over the input
0193       std::for_each_n(std::move(__first), __size, std::move(__func));
0194       return __empty{};
0195     }
0196   }
0197 };
0198 
0199 template <class _ExecutionPolicy>
0200 struct __fill<__default_backend_tag, _ExecutionPolicy> {
0201   template <class _Policy, class _ForwardIterator, class _Tp>
0202   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
0203   operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp const& __value) const noexcept {
0204     using _ForEach = __dispatch<__for_each, __current_configuration, _ExecutionPolicy>;
0205     using _Ref     = __iter_reference<_ForwardIterator>;
0206     return _ForEach()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) { __element = __value; });
0207   }
0208 };
0209 
0210 template <class _ExecutionPolicy>
0211 struct __fill_n<__default_backend_tag, _ExecutionPolicy> {
0212   template <class _Policy, class _ForwardIterator, class _Size, class _Tp>
0213   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
0214   operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n, _Tp const& __value) const noexcept {
0215     if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
0216       using _Fill             = __dispatch<__fill, __current_configuration, _ExecutionPolicy>;
0217       _ForwardIterator __last = __first + __n;
0218       return _Fill()(__policy, std::move(__first), std::move(__last), __value);
0219     } else {
0220       // Otherwise, use the serial algorithm to avoid doing two passes over the input
0221       std::fill_n(std::move(__first), __n, __value);
0222       return optional<__empty>{__empty{}};
0223     }
0224   }
0225 };
0226 
0227 template <class _ExecutionPolicy>
0228 struct __replace<__default_backend_tag, _ExecutionPolicy> {
0229   template <class _Policy, class _ForwardIterator, class _Tp>
0230   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
0231   operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp const& __old, _Tp const& __new)
0232       const noexcept {
0233     using _ReplaceIf = __dispatch<__replace_if, __current_configuration, _ExecutionPolicy>;
0234     using _Ref       = __iter_reference<_ForwardIterator>;
0235     return _ReplaceIf()(
0236         __policy, std::move(__first), std::move(__last), [&](_Ref __element) { return __element == __old; }, __new);
0237   }
0238 };
0239 
0240 template <class _ExecutionPolicy>
0241 struct __replace_if<__default_backend_tag, _ExecutionPolicy> {
0242   template <class _Policy, class _ForwardIterator, class _Pred, class _Tp>
0243   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> operator()(
0244       _Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred&& __pred, _Tp const& __new_value)
0245       const noexcept {
0246     using _ForEach = __dispatch<__for_each, __current_configuration, _ExecutionPolicy>;
0247     using _Ref     = __iter_reference<_ForwardIterator>;
0248     return _ForEach()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) {
0249       if (__pred(__element))
0250         __element = __new_value;
0251     });
0252   }
0253 };
0254 
0255 template <class _ExecutionPolicy>
0256 struct __generate<__default_backend_tag, _ExecutionPolicy> {
0257   template <class _Policy, class _ForwardIterator, class _Generator>
0258   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
0259   operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Generator&& __gen) const noexcept {
0260     using _ForEach = __dispatch<__for_each, __current_configuration, _ExecutionPolicy>;
0261     using _Ref     = __iter_reference<_ForwardIterator>;
0262     return _ForEach()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) { __element = __gen(); });
0263   }
0264 };
0265 
0266 template <class _ExecutionPolicy>
0267 struct __generate_n<__default_backend_tag, _ExecutionPolicy> {
0268   template <class _Policy, class _ForwardIterator, class _Size, class _Generator>
0269   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
0270   operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n, _Generator&& __gen) const noexcept {
0271     using _ForEachN = __dispatch<__for_each_n, __current_configuration, _ExecutionPolicy>;
0272     using _Ref      = __iter_reference<_ForwardIterator>;
0273     return _ForEachN()(__policy, std::move(__first), __n, [&](_Ref __element) { __element = __gen(); });
0274   }
0275 };
0276 
0277 //////////////////////////////////////////////////////////////
0278 // stable_sort family
0279 //////////////////////////////////////////////////////////////
0280 template <class _ExecutionPolicy>
0281 struct __sort<__default_backend_tag, _ExecutionPolicy> {
0282   template <class _Policy, class _RandomAccessIterator, class _Comp>
0283   _LIBCPP_HIDE_FROM_ABI optional<__empty> operator()(
0284       _Policy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp&& __comp) const noexcept {
0285     using _StableSort = __dispatch<__stable_sort, __current_configuration, _ExecutionPolicy>;
0286     return _StableSort()(__policy, std::move(__first), std::move(__last), std::forward<_Comp>(__comp));
0287   }
0288 };
0289 
0290 //////////////////////////////////////////////////////////////
0291 // transform_reduce family
0292 //////////////////////////////////////////////////////////////
0293 template <class _ExecutionPolicy>
0294 struct __count_if<__default_backend_tag, _ExecutionPolicy> {
0295   template <class _Policy, class _ForwardIterator, class _Predicate>
0296   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iter_diff_t<_ForwardIterator>> operator()(
0297       _Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate&& __pred) const noexcept {
0298     using _TransformReduce = __dispatch<__transform_reduce, __current_configuration, _ExecutionPolicy>;
0299     using _DiffT           = __iter_diff_t<_ForwardIterator>;
0300     using _Ref             = __iter_reference<_ForwardIterator>;
0301     return _TransformReduce()(
0302         __policy, std::move(__first), std::move(__last), _DiffT{}, std::plus{}, [&](_Ref __element) -> _DiffT {
0303           return __pred(__element) ? _DiffT(1) : _DiffT(0);
0304         });
0305   }
0306 };
0307 
0308 template <class _ExecutionPolicy>
0309 struct __count<__default_backend_tag, _ExecutionPolicy> {
0310   template <class _Policy, class _ForwardIterator, class _Tp>
0311   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iter_diff_t<_ForwardIterator>>
0312   operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp const& __value) const noexcept {
0313     using _CountIf = __dispatch<__count_if, __current_configuration, _ExecutionPolicy>;
0314     using _Ref     = __iter_reference<_ForwardIterator>;
0315     return _CountIf()(__policy, std::move(__first), std::move(__last), [&](_Ref __element) -> bool {
0316       return __element == __value;
0317     });
0318   }
0319 };
0320 
0321 template <class _ExecutionPolicy>
0322 struct __equal_3leg<__default_backend_tag, _ExecutionPolicy> {
0323   template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
0324   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
0325   operator()(_Policy&& __policy,
0326              _ForwardIterator1 __first1,
0327              _ForwardIterator1 __last1,
0328              _ForwardIterator2 __first2,
0329              _Predicate&& __pred) const noexcept {
0330     using _TransformReduce = __dispatch<__transform_reduce_binary, __current_configuration, _ExecutionPolicy>;
0331     return _TransformReduce()(
0332         __policy,
0333         std::move(__first1),
0334         std::move(__last1),
0335         std::move(__first2),
0336         true,
0337         std::logical_and{},
0338         std::forward<_Predicate>(__pred));
0339   }
0340 };
0341 
0342 template <class _ExecutionPolicy>
0343 struct __equal<__default_backend_tag, _ExecutionPolicy> {
0344   template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
0345   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
0346   operator()(_Policy&& __policy,
0347              _ForwardIterator1 __first1,
0348              _ForwardIterator1 __last1,
0349              _ForwardIterator2 __first2,
0350              _ForwardIterator2 __last2,
0351              _Predicate&& __pred) const noexcept {
0352     if constexpr (__has_random_access_iterator_category<_ForwardIterator1>::value &&
0353                   __has_random_access_iterator_category<_ForwardIterator2>::value) {
0354       if (__last1 - __first1 != __last2 - __first2)
0355         return false;
0356       // Fall back to the 3 legged algorithm
0357       using _Equal3Leg = __dispatch<__equal_3leg, __current_configuration, _ExecutionPolicy>;
0358       return _Equal3Leg()(
0359           __policy, std::move(__first1), std::move(__last1), std::move(__first2), std::forward<_Predicate>(__pred));
0360     } else {
0361       // If we don't have random access, fall back to the serial algorithm cause we can't do much
0362       return std::equal(
0363           std::move(__first1),
0364           std::move(__last1),
0365           std::move(__first2),
0366           std::move(__last2),
0367           std::forward<_Predicate>(__pred));
0368     }
0369   }
0370 };
0371 
0372 template <class _ExecutionPolicy>
0373 struct __reduce<__default_backend_tag, _ExecutionPolicy> {
0374   template <class _Policy, class _ForwardIterator, class _Tp, class _BinaryOperation>
0375   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_Tp>
0376   operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, _BinaryOperation&& __op)
0377       const noexcept {
0378     using _TransformReduce = __dispatch<__transform_reduce, __current_configuration, _ExecutionPolicy>;
0379     return _TransformReduce()(
0380         __policy,
0381         std::move(__first),
0382         std::move(__last),
0383         std::move(__init),
0384         std::forward<_BinaryOperation>(__op),
0385         __identity{});
0386   }
0387 };
0388 
0389 //////////////////////////////////////////////////////////////
0390 // transform family
0391 //////////////////////////////////////////////////////////////
0392 template <class _ExecutionPolicy>
0393 struct __replace_copy_if<__default_backend_tag, _ExecutionPolicy> {
0394   template <class _Policy, class _ForwardIterator, class _ForwardOutIterator, class _Pred, class _Tp>
0395   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
0396   operator()(_Policy&& __policy,
0397              _ForwardIterator __first,
0398              _ForwardIterator __last,
0399              _ForwardOutIterator __out_it,
0400              _Pred&& __pred,
0401              _Tp const& __new_value) const noexcept {
0402     using _Transform = __dispatch<__transform, __current_configuration, _ExecutionPolicy>;
0403     using _Ref       = __iter_reference<_ForwardIterator>;
0404     auto __res =
0405         _Transform()(__policy, std::move(__first), std::move(__last), std::move(__out_it), [&](_Ref __element) {
0406           return __pred(__element) ? __new_value : __element;
0407         });
0408     if (__res == nullopt)
0409       return nullopt;
0410     return __empty{};
0411   }
0412 };
0413 
0414 template <class _ExecutionPolicy>
0415 struct __replace_copy<__default_backend_tag, _ExecutionPolicy> {
0416   template <class _Policy, class _ForwardIterator, class _ForwardOutIterator, class _Tp>
0417   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty>
0418   operator()(_Policy&& __policy,
0419              _ForwardIterator __first,
0420              _ForwardIterator __last,
0421              _ForwardOutIterator __out_it,
0422              _Tp const& __old_value,
0423              _Tp const& __new_value) const noexcept {
0424     using _ReplaceCopyIf = __dispatch<__replace_copy_if, __current_configuration, _ExecutionPolicy>;
0425     using _Ref           = __iter_reference<_ForwardIterator>;
0426     return _ReplaceCopyIf()(
0427         __policy,
0428         std::move(__first),
0429         std::move(__last),
0430         std::move(__out_it),
0431         [&](_Ref __element) { return __element == __old_value; },
0432         __new_value);
0433   }
0434 };
0435 
0436 // TODO: Use the std::copy/move shenanigans to forward to std::memmove
0437 //       Investigate whether we want to still forward to std::transform(policy)
0438 //       in that case for the execution::par part, or whether we actually want
0439 //       to run everything serially in that case.
0440 template <class _ExecutionPolicy>
0441 struct __move<__default_backend_tag, _ExecutionPolicy> {
0442   template <class _Policy, class _ForwardIterator, class _ForwardOutIterator>
0443   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
0444   operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __out_it)
0445       const noexcept {
0446     using _Transform = __dispatch<__transform, __current_configuration, _ExecutionPolicy>;
0447     return _Transform()(__policy, std::move(__first), std::move(__last), std::move(__out_it), [&](auto&& __element) {
0448       return std::move(__element);
0449     });
0450   }
0451 };
0452 
0453 // TODO: Use the std::copy/move shenanigans to forward to std::memmove
0454 template <class _ExecutionPolicy>
0455 struct __copy<__default_backend_tag, _ExecutionPolicy> {
0456   template <class _Policy, class _ForwardIterator, class _ForwardOutIterator>
0457   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
0458   operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __out_it)
0459       const noexcept {
0460     using _Transform = __dispatch<__transform, __current_configuration, _ExecutionPolicy>;
0461     return _Transform()(__policy, std::move(__first), std::move(__last), std::move(__out_it), __identity());
0462   }
0463 };
0464 
0465 template <class _ExecutionPolicy>
0466 struct __copy_n<__default_backend_tag, _ExecutionPolicy> {
0467   template <class _Policy, class _ForwardIterator, class _Size, class _ForwardOutIterator>
0468   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
0469   operator()(_Policy&& __policy, _ForwardIterator __first, _Size __n, _ForwardOutIterator __out_it) const noexcept {
0470     if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
0471       using _Copy             = __dispatch<__copy, __current_configuration, _ExecutionPolicy>;
0472       _ForwardIterator __last = __first + __n;
0473       return _Copy()(__policy, std::move(__first), std::move(__last), std::move(__out_it));
0474     } else {
0475       // Otherwise, use the serial algorithm to avoid doing two passes over the input
0476       return std::copy_n(std::move(__first), __n, std::move(__out_it));
0477     }
0478   }
0479 };
0480 
0481 template <class _ExecutionPolicy>
0482 struct __rotate_copy<__default_backend_tag, _ExecutionPolicy> {
0483   template <class _Policy, class _ForwardIterator, class _ForwardOutIterator>
0484   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
0485   operator()(_Policy&& __policy,
0486              _ForwardIterator __first,
0487              _ForwardIterator __middle,
0488              _ForwardIterator __last,
0489              _ForwardOutIterator __out_it) const noexcept {
0490     using _Copy       = __dispatch<__copy, __current_configuration, _ExecutionPolicy>;
0491     auto __result_mid = _Copy()(__policy, __middle, std::move(__last), std::move(__out_it));
0492     if (__result_mid == nullopt)
0493       return nullopt;
0494     return _Copy()(__policy, std::move(__first), std::move(__middle), *std::move(__result_mid));
0495   }
0496 };
0497 
0498 } // namespace __pstl
0499 _LIBCPP_END_NAMESPACE_STD
0500 
0501 _LIBCPP_POP_MACROS
0502 
0503 #endif // _LIBCPP___CXX03___PSTL_BACKENDS_DEFAULT_H