1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___ALGORITHM_PSTL_ROTATE_COPY_H
10#define _LIBCPP___ALGORITHM_PSTL_ROTATE_COPY_H
11
12#include <__algorithm/pstl_backend.h>
13#include <__algorithm/pstl_copy.h>
14#include <__algorithm/pstl_frontend_dispatch.h>
15#include <__type_traits/is_execution_policy.h>
16#include <optional>
17
18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19#  pragma GCC system_header
20#endif
21
22_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29template <class>
30void __pstl_rotate_copy();
31
32template <class _ExecutionPolicy,
33          class _ForwardIterator,
34          class _ForwardOutIterator,
35          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
36          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
37[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator>
38__rotate_copy(_ExecutionPolicy&& __policy,
39              _ForwardIterator&& __first,
40              _ForwardIterator&& __middle,
41              _ForwardIterator&& __last,
42              _ForwardOutIterator&& __result) noexcept {
43  return std::__pstl_frontend_dispatch(
44      _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_rotate_copy, _RawPolicy),
45      [&__policy](_ForwardIterator __g_first,
46                  _ForwardIterator __g_middle,
47                  _ForwardIterator __g_last,
48                  _ForwardOutIterator __g_result) -> optional<_ForwardOutIterator> {
49        auto __result_mid =
50            std::__copy(__policy, _ForwardIterator(__g_middle), std::move(__g_last), std::move(__g_result));
51        if (!__result_mid)
52          return nullopt;
53        return std::__copy(__policy, std::move(__g_first), std::move(__g_middle), *std::move(__result_mid));
54      },
55      std::move(__first),
56      std::move(__middle),
57      std::move(__last),
58      std::move(__result));
59}
60
61template <class _ExecutionPolicy,
62          class _ForwardIterator,
63          class _ForwardOutIterator,
64          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
65          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
66_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator rotate_copy(
67    _ExecutionPolicy&& __policy,
68    _ForwardIterator __first,
69    _ForwardIterator __middle,
70    _ForwardIterator __last,
71    _ForwardOutIterator __result) {
72  auto __res =
73      std::__rotate_copy(__policy, std::move(__first), std::move(__middle), std::move(__last), std::move(__result));
74  if (!__res)
75    std::__throw_bad_alloc();
76  return *__res;
77}
78
79_LIBCPP_END_NAMESPACE_STD
80
81#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
82
83_LIBCPP_POP_MACROS
84
85#endif // _LIBCPP___ALGORITHM_PSTL_ROTATE_COPY_H
86