1// -*- C++ -*- 2//===-- execution_impl.h --------------------------------------------------===// 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 "execution_defs.h" 17 18namespace __pstl 19{ 20namespace __internal 21{ 22 23using namespace __pstl::execution; 24 25/* predicate */ 26 27template <typename _Tp> 28std::false_type __lazy_and(_Tp, std::false_type) 29{ 30 return std::false_type{}; 31}; 32 33template <typename _Tp> 34inline _Tp 35__lazy_and(_Tp __a, std::true_type) 36{ 37 return __a; 38} 39 40template <typename _Tp> 41std::true_type __lazy_or(_Tp, std::true_type) 42{ 43 return std::true_type{}; 44}; 45 46template <typename _Tp> 47inline _Tp 48__lazy_or(_Tp __a, std::false_type) 49{ 50 return __a; 51} 52 53/* iterator */ 54template <typename _IteratorType, typename... _OtherIteratorTypes> 55struct __is_random_access_iterator 56{ 57 static constexpr bool value = __internal::__is_random_access_iterator<_IteratorType>::value && 58 __internal::__is_random_access_iterator<_OtherIteratorTypes...>::value; 59 typedef std::integral_constant<bool, value> type; 60}; 61 62template <typename _IteratorType> 63struct __is_random_access_iterator<_IteratorType> 64 : std::is_same<typename std::iterator_traits<_IteratorType>::iterator_category, std::random_access_iterator_tag> 65{ 66}; 67 68/* policy */ 69template <typename _Policy> 70struct __policy_traits 71{ 72}; 73 74template <> 75struct __policy_traits<sequenced_policy> 76{ 77 typedef std::false_type allow_parallel; 78 typedef std::false_type allow_unsequenced; 79 typedef std::false_type allow_vector; 80}; 81 82template <> 83struct __policy_traits<unsequenced_policy> 84{ 85 typedef std::false_type allow_parallel; 86 typedef std::true_type allow_unsequenced; 87 typedef std::true_type allow_vector; 88}; 89 90template <> 91struct __policy_traits<parallel_policy> 92{ 93 typedef std::true_type allow_parallel; 94 typedef std::false_type allow_unsequenced; 95 typedef std::false_type allow_vector; 96}; 97 98template <> 99struct __policy_traits<parallel_unsequenced_policy> 100{ 101 typedef std::true_type allow_parallel; 102 typedef std::true_type allow_unsequenced; 103 typedef std::true_type allow_vector; 104}; 105 106template <typename _ExecutionPolicy> 107using __collector_t = 108 typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__collector_type; 109 110template <typename _ExecutionPolicy> 111using __allow_vector = 112 typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_vector; 113 114template <typename _ExecutionPolicy> 115using __allow_unsequenced = 116 typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_unsequenced; 117 118template <typename _ExecutionPolicy> 119using __allow_parallel = 120 typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_parallel; 121 122template <typename _ExecutionPolicy, typename... _IteratorTypes> 123auto 124__is_vectorization_preferred(_ExecutionPolicy&& __exec) 125 -> decltype(__internal::__lazy_and(__exec.__allow_vector(), 126 typename __internal::__is_random_access_iterator<_IteratorTypes...>::type())) 127{ 128 return __internal::__lazy_and(__exec.__allow_vector(), 129 typename __internal::__is_random_access_iterator<_IteratorTypes...>::type()); 130} 131 132template <typename _ExecutionPolicy, typename... _IteratorTypes> 133auto 134__is_parallelization_preferred(_ExecutionPolicy&& __exec) 135 -> decltype(__internal::__lazy_and(__exec.__allow_parallel(), 136 typename __internal::__is_random_access_iterator<_IteratorTypes...>::type())) 137{ 138 return __internal::__lazy_and(__exec.__allow_parallel(), 139 typename __internal::__is_random_access_iterator<_IteratorTypes...>::type()); 140} 141 142template <typename policy, typename... _IteratorTypes> 143struct __prefer_unsequenced_tag 144{ 145 static constexpr bool value = __internal::__allow_unsequenced<policy>::value && 146 __internal::__is_random_access_iterator<_IteratorTypes...>::value; 147 typedef std::integral_constant<bool, value> type; 148}; 149 150template <typename policy, typename... _IteratorTypes> 151struct __prefer_parallel_tag 152{ 153 static constexpr bool value = __internal::__allow_parallel<policy>::value && 154 __internal::__is_random_access_iterator<_IteratorTypes...>::value; 155 typedef std::integral_constant<bool, value> type; 156}; 157 158} // namespace __internal 159} // namespace __pstl 160 161#endif /* _PSTL_EXECUTION_IMPL_H */ 162