xref: /llvm-project/pstl/include/pstl/internal/execution_impl.h (revision 843c12d6a0cdfd64c5a92e24eb58ba9ee17ca1ee)
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 <iterator>
14 #include <type_traits>
15 
16 #include "pstl_config.h"
17 #include "execution_defs.h"
18 
19 _PSTL_HIDE_FROM_ABI_PUSH
20 
21 namespace __pstl
22 {
23 namespace __internal
24 {
25 
26 template <typename _IteratorTag, typename... _IteratorTypes>
27 using __are_iterators_of = std::conjunction<
28     std::is_base_of<_IteratorTag, typename std::iterator_traits<std::decay_t<_IteratorTypes>>::iterator_category>...>;
29 
30 template <typename... _IteratorTypes>
31 using __are_random_access_iterators = __are_iterators_of<std::random_access_iterator_tag, _IteratorTypes...>;
32 
33 struct __serial_backend_tag
34 {
35 };
36 struct __tbb_backend_tag
37 {
38 };
39 struct __openmp_backend_tag
40 {
41 };
42 
43 #if defined(_PSTL_PAR_BACKEND_TBB)
44 using __par_backend_tag = __tbb_backend_tag;
45 #elif defined(_PSTL_PAR_BACKEND_OPENMP)
46 using __par_backend_tag = __openmp_backend_tag;
47 #elif defined(_PSTL_PAR_BACKEND_SERIAL)
48 using __par_backend_tag = __serial_backend_tag;
49 #else
50 #    error "A parallel backend must be specified";
51 #endif
52 
53 template <class _IsVector>
54 struct __serial_tag
55 {
56     using __is_vector = _IsVector;
57 };
58 
59 template <class _IsVector>
60 struct __parallel_tag
61 {
62     using __is_vector = _IsVector;
63     // backend tag can be change depending on
64     // TBB availability in the environment
65     using __backend_tag = __par_backend_tag;
66 };
67 
68 template <class _IsVector, class... _IteratorTypes>
69 using __tag_type = typename std::conditional<__internal::__are_random_access_iterators<_IteratorTypes...>::value,
70                                              __parallel_tag<_IsVector>, __serial_tag<_IsVector>>::type;
71 
72 template <class... _IteratorTypes>
73 __serial_tag</*_IsVector = */ std::false_type>
__select_backend(__pstl::execution::sequenced_policy,_IteratorTypes &&...)74 __select_backend(__pstl::execution::sequenced_policy, _IteratorTypes&&...)
75 {
76     return {};
77 }
78 
79 template <class... _IteratorTypes>
80 __serial_tag<__internal::__are_random_access_iterators<_IteratorTypes...>>
__select_backend(__pstl::execution::unsequenced_policy,_IteratorTypes &&...)81 __select_backend(__pstl::execution::unsequenced_policy, _IteratorTypes&&...)
82 {
83     return {};
84 }
85 
86 template <class... _IteratorTypes>
87 __tag_type</*_IsVector = */ std::false_type, _IteratorTypes...>
__select_backend(__pstl::execution::parallel_policy,_IteratorTypes &&...)88 __select_backend(__pstl::execution::parallel_policy, _IteratorTypes&&...)
89 {
90     return {};
91 }
92 
93 template <class... _IteratorTypes>
94 __tag_type<__internal::__are_random_access_iterators<_IteratorTypes...>, _IteratorTypes...>
__select_backend(__pstl::execution::parallel_unsequenced_policy,_IteratorTypes &&...)95 __select_backend(__pstl::execution::parallel_unsequenced_policy, _IteratorTypes&&...)
96 {
97     return {};
98 }
99 
100 } // namespace __internal
101 } // namespace __pstl
102 
103 _PSTL_HIDE_FROM_ABI_POP
104 
105 #endif /* _PSTL_EXECUTION_IMPL_H */
106