xref: /aosp_15_r20/external/cronet/third_party/libc++/src/include/__pstl/internal/execution_impl.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef _PSTL_EXECUTION_IMPL_H
11 #define _PSTL_EXECUTION_IMPL_H
12 
13 #include <__config>
14 #include <__iterator/iterator_traits.h>
15 #include <__type_traits/conditional.h>
16 #include <__type_traits/conjunction.h>
17 #include <__type_traits/decay.h>
18 #include <__type_traits/integral_constant.h>
19 #include <__type_traits/is_base_of.h>
20 
21 #include <__pstl/internal/execution_defs.h>
22 
23 #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
24 
25 namespace __pstl {
26 namespace __internal {
27 
28 template <typename _IteratorTag, typename... _IteratorTypes>
29 using __are_iterators_of = std::conjunction<
30     std::is_base_of<_IteratorTag, typename std::iterator_traits<std::decay_t<_IteratorTypes>>::iterator_category>...>;
31 
32 template <typename... _IteratorTypes>
33 using __are_random_access_iterators = __are_iterators_of<std::random_access_iterator_tag, _IteratorTypes...>;
34 
35 struct __serial_backend_tag {};
36 struct __tbb_backend_tag {};
37 struct __openmp_backend_tag {};
38 
39 #  if defined(_PSTL_PAR_BACKEND_TBB)
40 using __par_backend_tag = __tbb_backend_tag;
41 #  elif defined(_PSTL_PAR_BACKEND_OPENMP)
42 using __par_backend_tag = __openmp_backend_tag;
43 #  elif defined(_PSTL_PAR_BACKEND_SERIAL)
44 using __par_backend_tag = __serial_backend_tag;
45 #  else
46 #    error "A parallel backend must be specified";
47 #  endif
48 
49 template <class _IsVector>
50 struct __serial_tag {
51   using __is_vector = _IsVector;
52 };
53 
54 template <class _IsVector>
55 struct __parallel_tag {
56   using __is_vector = _IsVector;
57   // backend tag can be change depending on
58   // TBB availability in the environment
59   using __backend_tag = __par_backend_tag;
60 };
61 
62 template <class _IsVector, class... _IteratorTypes>
63 using __tag_type =
64     typename std::conditional<__internal::__are_random_access_iterators<_IteratorTypes...>::value,
65                               __parallel_tag<_IsVector>,
66                               __serial_tag<_IsVector>>::type;
67 
68 template <class... _IteratorTypes>
69 _LIBCPP_HIDE_FROM_ABI __serial_tag</*_IsVector = */ std::false_type>
__select_backend(__pstl::execution::sequenced_policy,_IteratorTypes &&...)70 __select_backend(__pstl::execution::sequenced_policy, _IteratorTypes&&...) {
71   return {};
72 }
73 
74 template <class... _IteratorTypes>
75 _LIBCPP_HIDE_FROM_ABI __serial_tag<__internal::__are_random_access_iterators<_IteratorTypes...>>
__select_backend(__pstl::execution::unsequenced_policy,_IteratorTypes &&...)76 __select_backend(__pstl::execution::unsequenced_policy, _IteratorTypes&&...) {
77   return {};
78 }
79 
80 template <class... _IteratorTypes>
81 _LIBCPP_HIDE_FROM_ABI __tag_type</*_IsVector = */ std::false_type, _IteratorTypes...>
__select_backend(__pstl::execution::parallel_policy,_IteratorTypes &&...)82 __select_backend(__pstl::execution::parallel_policy, _IteratorTypes&&...) {
83   return {};
84 }
85 
86 template <class... _IteratorTypes>
87 _LIBCPP_HIDE_FROM_ABI __tag_type<__internal::__are_random_access_iterators<_IteratorTypes...>, _IteratorTypes...>
__select_backend(__pstl::execution::parallel_unsequenced_policy,_IteratorTypes &&...)88 __select_backend(__pstl::execution::parallel_unsequenced_policy, _IteratorTypes&&...) {
89   return {};
90 }
91 
92 } // namespace __internal
93 } // namespace __pstl
94 
95 #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
96 
97 #endif /* _PSTL_EXECUTION_IMPL_H */
98