Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:12:50

0001 /*
0002     Copyright (c) 2005-2020 Intel Corporation
0003 
0004     Licensed under the Apache License, Version 2.0 (the "License");
0005     you may not use this file except in compliance with the License.
0006     You may obtain a copy of the License at
0007 
0008         http://www.apache.org/licenses/LICENSE-2.0
0009 
0010     Unless required by applicable law or agreed to in writing, software
0011     distributed under the License is distributed on an "AS IS" BASIS,
0012     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013     See the License for the specific language governing permissions and
0014     limitations under the License.
0015 */
0016 
0017 #ifndef __TBB_template_helpers_H
0018 #define __TBB_template_helpers_H
0019 
0020 #include <utility>
0021 #include <cstddef>
0022 #include "../tbb_config.h"
0023 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT
0024 #include <type_traits>
0025 #endif
0026 #if __TBB_CPP11_PRESENT
0027 #include <iterator>
0028 #include <memory> // allocator_traits
0029 #endif
0030 
0031 namespace tbb { namespace internal {
0032 
0033 //! Enables one or the other code branches
0034 template<bool Condition, typename T = void> struct enable_if {};
0035 template<typename T> struct enable_if<true, T> { typedef T type; };
0036 
0037 //! Strips its template type argument from cv- and ref-qualifiers
0038 template<typename T> struct strip                     { typedef T type; };
0039 template<typename T> struct strip<const T>            { typedef T type; };
0040 template<typename T> struct strip<volatile T>         { typedef T type; };
0041 template<typename T> struct strip<const volatile T>   { typedef T type; };
0042 template<typename T> struct strip<T&>                 { typedef T type; };
0043 template<typename T> struct strip<const T&>           { typedef T type; };
0044 template<typename T> struct strip<volatile T&>        { typedef T type; };
0045 template<typename T> struct strip<const volatile T&>  { typedef T type; };
0046 //! Specialization for function pointers
0047 template<typename T> struct strip<T(&)()>             { typedef T(*type)(); };
0048 #if __TBB_CPP11_RVALUE_REF_PRESENT
0049 template<typename T> struct strip<T&&>                { typedef T type; };
0050 template<typename T> struct strip<const T&&>          { typedef T type; };
0051 template<typename T> struct strip<volatile T&&>       { typedef T type; };
0052 template<typename T> struct strip<const volatile T&&> { typedef T type; };
0053 #endif
0054 //! Specialization for arrays converts to a corresponding pointer
0055 template<typename T, std::size_t N> struct strip<T(&)[N]>                { typedef T* type; };
0056 template<typename T, std::size_t N> struct strip<const T(&)[N]>          { typedef const T* type; };
0057 template<typename T, std::size_t N> struct strip<volatile T(&)[N]>       { typedef volatile T* type; };
0058 template<typename T, std::size_t N> struct strip<const volatile T(&)[N]> { typedef const volatile T* type; };
0059 
0060 //! Detects whether two given types are the same
0061 template<class U, class V> struct is_same_type      { static const bool value = false; };
0062 template<class W>          struct is_same_type<W,W> { static const bool value = true; };
0063 
0064 template<typename T> struct is_ref { static const bool value = false; };
0065 template<typename U> struct is_ref<U&> { static const bool value = true; };
0066 
0067 //! Partial support for std::is_integral
0068 template<typename T> struct is_integral_impl             { static const bool value = false; };
0069 template<>           struct is_integral_impl<bool>       { static const bool value = true;  };
0070 template<>           struct is_integral_impl<char>       { static const bool value = true;  };
0071 #if __TBB_CPP11_PRESENT
0072 template<>           struct is_integral_impl<char16_t>   { static const bool value = true;  };
0073 template<>           struct is_integral_impl<char32_t>   { static const bool value = true;  };
0074 #endif
0075 template<>           struct is_integral_impl<wchar_t>    { static const bool value = true;  };
0076 template<>           struct is_integral_impl<short>      { static const bool value = true;  };
0077 template<>           struct is_integral_impl<int>        { static const bool value = true;  };
0078 template<>           struct is_integral_impl<long>       { static const bool value = true;  };
0079 template<>           struct is_integral_impl<long long>  { static const bool value = true;  };
0080 
0081 template<typename T>
0082 struct is_integral : is_integral_impl<typename strip<T>::type> {};
0083 
0084 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
0085 //! std::void_t internal implementation (to avoid GCC < 4.7 "template aliases" absence)
0086 template<typename...> struct void_t { typedef void type; };
0087 #endif
0088 
0089 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT
0090 
0091 // Generic SFINAE helper for expression checks, based on the idea demonstrated in ISO C++ paper n4502
0092 template<typename T, typename, template<typename> class... Checks>
0093 struct supports_impl { typedef std::false_type type; };
0094 template<typename T, template<typename> class... Checks>
0095 struct supports_impl<T, typename void_t<Checks<T>...>::type, Checks...> { typedef std::true_type type; };
0096 
0097 template<typename T, template<typename> class... Checks>
0098 using supports = typename supports_impl<T, void, Checks...>::type;
0099 
0100 #endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT */
0101 
0102 #if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
0103 
0104 //! Allows to store a function parameter pack as a variable and later pass it to another function
0105 template< typename... Types >
0106 struct stored_pack;
0107 
0108 template<>
0109 struct stored_pack<>
0110 {
0111     typedef stored_pack<> pack_type;
0112     stored_pack() {}
0113 
0114     // Friend front-end functions
0115     template< typename F, typename Pack > friend void call( F&& f, Pack&& p );
0116     template< typename Ret, typename F, typename Pack > friend Ret call_and_return( F&& f, Pack&& p );
0117 
0118 protected:
0119     // Ideally, ref-qualified non-static methods would be used,
0120     // but that would greatly reduce the set of compilers where it works.
0121     template< typename Ret, typename F, typename... Preceding >
0122     static Ret call( F&& f, const pack_type& /*pack*/, Preceding&&... params ) {
0123         return std::forward<F>(f)( std::forward<Preceding>(params)... );
0124     }
0125     template< typename Ret, typename F, typename... Preceding >
0126     static Ret call( F&& f, pack_type&& /*pack*/, Preceding&&... params ) {
0127         return std::forward<F>(f)( std::forward<Preceding>(params)... );
0128     }
0129 };
0130 
0131 template< typename T, typename... Types >
0132 struct stored_pack<T, Types...> : stored_pack<Types...>
0133 {
0134     typedef stored_pack<T, Types...> pack_type;
0135     typedef stored_pack<Types...> pack_remainder;
0136     // Since lifetime of original values is out of control, copies should be made.
0137     // Thus references should be stripped away from the deduced type.
0138     typename strip<T>::type leftmost_value;
0139 
0140     // Here rvalue references act in the same way as forwarding references,
0141     // as long as class template parameters were deduced via forwarding references.
0142     stored_pack( T&& t, Types&&... types )
0143     : pack_remainder(std::forward<Types>(types)...), leftmost_value(std::forward<T>(t)) {}
0144 
0145     // Friend front-end functions
0146     template< typename F, typename Pack > friend void call( F&& f, Pack&& p );
0147     template< typename Ret, typename F, typename Pack > friend Ret call_and_return( F&& f, Pack&& p );
0148 
0149 protected:
0150     template< typename Ret, typename F, typename... Preceding >
0151     static Ret call( F&& f, pack_type& pack, Preceding&&... params ) {
0152         return pack_remainder::template call<Ret>(
0153             std::forward<F>(f), static_cast<pack_remainder&>(pack),
0154             std::forward<Preceding>(params)... , pack.leftmost_value
0155         );
0156     }
0157     template< typename Ret, typename F, typename... Preceding >
0158     static Ret call( F&& f, const pack_type& pack, Preceding&&... params ) {
0159         return pack_remainder::template call<Ret>(
0160             std::forward<F>(f), static_cast<const pack_remainder&>(pack),
0161             std::forward<Preceding>(params)... , pack.leftmost_value
0162         );
0163     }
0164     template< typename Ret, typename F, typename... Preceding >
0165     static Ret call( F&& f, pack_type&& pack, Preceding&&... params ) {
0166         return pack_remainder::template call<Ret>(
0167             std::forward<F>(f), static_cast<pack_remainder&&>(pack),
0168             std::forward<Preceding>(params)... , std::move(pack.leftmost_value)
0169         );
0170     }
0171 };
0172 
0173 //! Calls the given function with arguments taken from a stored_pack
0174 template< typename F, typename Pack >
0175 void call( F&& f, Pack&& p ) {
0176     strip<Pack>::type::template call<void>( std::forward<F>(f), std::forward<Pack>(p) );
0177 }
0178 
0179 template< typename Ret, typename F, typename Pack >
0180 Ret call_and_return( F&& f, Pack&& p ) {
0181     return strip<Pack>::type::template call<Ret>( std::forward<F>(f), std::forward<Pack>(p) );
0182 }
0183 
0184 template< typename... Types >
0185 stored_pack<Types...> save_pack( Types&&... types ) {
0186     return stored_pack<Types...>( std::forward<Types>(types)... );
0187 }
0188 
0189 #endif /* __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */
0190 
0191 #if __TBB_CPP14_INTEGER_SEQUENCE_PRESENT
0192 
0193 using std::index_sequence;
0194 using std::make_index_sequence;
0195 
0196 #elif __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT
0197 
0198 template<std::size_t... S> class index_sequence {};
0199 
0200 template<std::size_t N, std::size_t... S>
0201 struct make_index_sequence_impl : make_index_sequence_impl < N - 1, N - 1, S... > {};
0202 
0203 template<std::size_t... S>
0204 struct make_index_sequence_impl <0, S...> {
0205     using type = index_sequence<S...>;
0206 };
0207 
0208 template<std::size_t N>
0209 using make_index_sequence = typename tbb::internal::make_index_sequence_impl<N>::type;
0210 
0211 #endif /* __TBB_CPP14_INTEGER_SEQUENCE_PRESENT */
0212 
0213 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
0214 template<typename... Args>
0215 struct conjunction;
0216 
0217 template<typename First, typename... Args>
0218 struct conjunction<First, Args...>
0219     : std::conditional<bool(First::value), conjunction<Args...>, First>::type {};
0220 
0221 template<typename T>
0222 struct conjunction<T> : T {};
0223 
0224 template<>
0225 struct conjunction<> : std::true_type {};
0226 
0227 #endif
0228 
0229 #if __TBB_CPP11_PRESENT
0230 
0231 template< typename Iter >
0232 using iterator_value_t = typename std::iterator_traits<Iter>::value_type;
0233 
0234 template< typename Iter >
0235 using iterator_key_t = typename std::remove_const<typename iterator_value_t<Iter>::first_type>::type;
0236 
0237 template< typename Iter >
0238 using iterator_mapped_t = typename iterator_value_t<Iter>::second_type;
0239 
0240 template< typename A > using value_type = typename A::value_type;
0241 template< typename A > using alloc_ptr_t = typename std::allocator_traits<A>::pointer;
0242 template< typename A > using has_allocate = decltype(std::declval<alloc_ptr_t<A>&>() = std::declval<A>().allocate(0));
0243 template< typename A > using has_deallocate = decltype(std::declval<A>().deallocate(std::declval<alloc_ptr_t<A>>(), 0));
0244 
0245 // value_type should be checked first because it can be used in other checks (via allocator_traits)
0246 template< typename T >
0247 using is_allocator = supports<T, value_type, has_allocate, has_deallocate>;
0248 
0249 #if __TBB_CPP14_VARIABLE_TEMPLATES_PRESENT
0250 
0251 template< typename T >
0252 static constexpr bool is_allocator_v = is_allocator<T>::value;
0253 
0254 #endif /*__TBB_CPP14_VARIABLE_TEMPLATES */
0255 
0256 template< std::size_t N, typename... Args >
0257 struct pack_element {
0258     using type = void;
0259 };
0260 
0261 template< std::size_t N, typename T, typename... Args >
0262 struct pack_element<N, T, Args...> {
0263     using type = typename pack_element<N - 1, Args...>::type;
0264 };
0265 
0266 template< typename T, typename... Args >
0267 struct pack_element<0, T, Args...> {
0268     using type = T;
0269 };
0270 
0271 template< std::size_t N, typename... Args >
0272 using pack_element_t = typename pack_element<N, Args...>::type;
0273 
0274 // Helper alias for heterogeneous lookup functions in containers
0275 // template parameter K and std::conditional are needed to provide immediate context
0276 // and postpone getting is_trasparent from the compare functor until method instantiation.
0277 template <typename Comp, typename K>
0278 using is_transparent = typename std::conditional<true, Comp, K>::type::is_transparent;
0279 
0280 #endif /* __TBB_CPP11_PRESENT */
0281 
0282 template <typename F>
0283 struct body_arg_detector;
0284 
0285 template <typename Callable, typename ReturnType, typename T>
0286 struct body_arg_detector<ReturnType(Callable::*)(T)> {
0287     typedef T arg_type;
0288 };
0289 
0290 template <typename Callable, typename ReturnType, typename T>
0291 struct body_arg_detector<ReturnType(Callable::*)(T) const> {
0292     typedef T arg_type;
0293 };
0294 
0295 #if __TBB_CPP11_PRESENT
0296 using std::conditional;
0297 #else
0298 template <bool C, typename T, typename U>
0299 struct conditional {
0300     typedef U type;
0301 };
0302 
0303 template <typename T, typename U>
0304 struct conditional<true, T, U> {
0305     typedef T type;
0306 };
0307 #endif
0308 
0309 } } // namespace internal, namespace tbb
0310 
0311 #endif /* __TBB_template_helpers_H */