/usr/include/oneapi/tbb/detail
NameSizeModeActions
_aggregator.h75620644editdlrm
_aligned_space.h13990644editdlrm
_allocator_traits.h38070644editdlrm
_assert.h23920644editdlrm
_concurrent_queue_base.h263600644editdlrm
_concurrent_skip_list.h466280644editdlrm
_concurrent_unordered_base.h646560644editdlrm
_config.h203820644editdlrm
_containers_helpers.h26270644editdlrm
_exception.h27150644editdlrm
_export.h11990644editdlrm
_flow_graph_body_impl.h127760644editdlrm
_flow_graph_cache_impl.h136150644editdlrm
_flow_graph_impl.h153600644editdlrm
_flow_graph_indexer_impl.h165290644editdlrm
_flow_graph_item_buffer_impl.h103590644editdlrm
_flow_graph_join_impl.h828860644editdlrm
_flow_graph_nodes_deduction.h95320644editdlrm
_flow_graph_node_impl.h275450644editdlrm
_flow_graph_node_set_impl.h101770644editdlrm
_flow_graph_tagged_buffer_impl.h103180644editdlrm
_flow_graph_trace_impl.h159740644editdlrm
_flow_graph_types_impl.h156230644editdlrm
_hash_compare.h44880644editdlrm
_intrusive_list_node.h14620644editdlrm
_machine.h130420644editdlrm
_mutex_common.h23470644editdlrm
_namespace_injection.h8150644editdlrm
_node_handle.h51730644editdlrm
_pipeline_filters.h159050644editdlrm
_pipeline_filters_deduction.h15290644editdlrm
_range_common.h46430644editdlrm
_rtm_mutex.h47850644editdlrm
_rtm_rw_mutex.h72100644editdlrm
_scoped_lock.h50090644editdlrm
_segment_table.h247500644editdlrm
_small_object_pool.h35740644editdlrm
_string_resource.h38720644editdlrm
_task.h71160644editdlrm
_task_handle.h36880644editdlrm
_template_helpers.h135170644editdlrm
_utils.h133180644editdlrm
_waitable_atomic.h35320644editdlrm
Edit: /usr/include/oneapi/tbb/detail/_template_helpers.h (13517B)
/* Copyright (c) 2005-2021 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef __TBB_detail__template_helpers_H #define __TBB_detail__template_helpers_H #include "_utils.h" #include "_config.h" #include #include #include #include #include #include namespace tbb { namespace detail { inline namespace d0 { // An internal implementation of void_t, which can be used in SFINAE contexts template struct void_impl { using type = void; }; // struct void_impl template using void_t = typename void_impl::type; // Generic SFINAE helper for expression checks, based on the idea demonstrated in ISO C++ paper n4502 template class... Checks> struct supports_impl { using type = std::false_type; }; template class... Checks> struct supports_impl...>, Checks...> { using type = std::true_type; }; template class... Checks> using supports = typename supports_impl::type; //! A template to select either 32-bit or 64-bit constant as compile time, depending on machine word size. template struct select_size_t_constant { // Explicit cast is needed to avoid compiler warnings about possible truncation. // The value of the right size, which is selected by ?:, is anyway not truncated or promoted. static const std::size_t value = (std::size_t)((sizeof(std::size_t)==sizeof(u)) ? u : ull); }; // TODO: do we really need it? //! Cast between unrelated pointer types. /** This method should be used sparingly as a last resort for dealing with situations that inherently break strict ISO C++ aliasing rules. */ // T is a pointer type because it will be explicitly provided by the programmer as a template argument; // U is a referent type to enable the compiler to check that "ptr" is a pointer, deducing U in the process. template inline T punned_cast( U* ptr ) { std::uintptr_t x = reinterpret_cast(ptr); return reinterpret_cast(x); } template struct padded_base : T { char pad[S - R]; }; template struct padded_base : T {}; //! Pads type T to fill out to a multiple of cache line size. template struct padded : padded_base {}; #if __TBB_CPP14_INTEGER_SEQUENCE_PRESENT using std::index_sequence; using std::make_index_sequence; #else template class index_sequence {}; template struct make_index_sequence_impl : make_index_sequence_impl < N - 1, N - 1, S... > {}; template struct make_index_sequence_impl <0, S...> { using type = index_sequence; }; template using make_index_sequence = typename make_index_sequence_impl::type; #endif /* __TBB_CPP14_INTEGER_SEQUENCE_PRESENT */ #if __TBB_CPP17_LOGICAL_OPERATIONS_PRESENT using std::conjunction; using std::disjunction; #else // __TBB_CPP17_LOGICAL_OPERATIONS_PRESENT template struct conjunction : std::true_type {}; template struct conjunction : std::conditional, First>::type {}; template struct conjunction : T {}; template struct disjunction : std::false_type {}; template struct disjunction : std::conditional>::type {}; template struct disjunction : T {}; #endif // __TBB_CPP17_LOGICAL_OPERATIONS_PRESENT template using iterator_value_t = typename std::iterator_traits::value_type; template using iterator_key_t = typename std::remove_const::first_type>::type; template using iterator_mapped_t = typename iterator_value_t::second_type; template using iterator_alloc_pair_t = std::pair>::type, iterator_mapped_t>; template using alloc_value_type = typename A::value_type; template using alloc_ptr_t = typename std::allocator_traits::pointer; template using has_allocate = decltype(std::declval&>() = std::declval().allocate(0)); template using has_deallocate = decltype(std::declval().deallocate(std::declval>(), 0)); // alloc_value_type should be checked first, because it can be used in other checks template using is_allocator = supports; #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT template inline constexpr bool is_allocator_v = is_allocator::value; #endif // Template class in which the "type" determines the type of the element number N in pack Args template struct pack_element { using type = void; }; template struct pack_element { using type = typename pack_element::type; }; template struct pack_element<0, T, Args...> { using type = T; }; template using pack_element_t = typename pack_element::type; template class raii_guard { public: static_assert( std::is_nothrow_copy_constructible::value && std::is_nothrow_move_constructible::value, "Throwing an exception during the Func copy or move construction cause an unexpected behavior." ); raii_guard( Func f ) noexcept : my_func(f), is_active(true) {} raii_guard( raii_guard&& g ) noexcept : my_func(std::move(g.my_func)), is_active(g.is_active) { g.is_active = false; } ~raii_guard() { if (is_active) { my_func(); } } void dismiss() { is_active = false; } private: Func my_func; bool is_active; }; // class raii_guard template raii_guard make_raii_guard( Func f ) { return raii_guard(f); } template struct try_call_proxy { try_call_proxy( Body b ) : body(b) {} template void on_exception( OnExceptionBody on_exception_body ) { auto guard = make_raii_guard(on_exception_body); body(); guard.dismiss(); } template void on_completion(OnCompletionBody on_completion_body) { auto guard = make_raii_guard(on_completion_body); body(); } Body body; }; // struct try_call_proxy // Template helper function for API // try_call(lambda1).on_exception(lambda2) // Executes lambda1 and if it throws an exception - executes lambda2 template try_call_proxy try_call( Body b ) { return try_call_proxy(b); } #if __TBB_CPP17_IS_SWAPPABLE_PRESENT using std::is_nothrow_swappable; using std::is_swappable; #else // __TBB_CPP17_IS_SWAPPABLE_PRESENT namespace is_swappable_detail { using std::swap; template using has_swap = decltype(swap(std::declval(), std::declval())); #if _MSC_VER && _MSC_VER <= 1900 && !__INTEL_COMPILER // Workaround for VS2015: it fails to instantiate noexcept(...) inside std::integral_constant. template struct noexcept_wrapper { static const bool value = noexcept(swap(std::declval(), std::declval())); }; template struct is_nothrow_swappable_impl : std::integral_constant::value> {}; #else template struct is_nothrow_swappable_impl : std::integral_constant(), std::declval()))> {}; #endif } template struct is_swappable : supports {}; template struct is_nothrow_swappable : conjunction, is_swappable_detail::is_nothrow_swappable_impl> {}; #endif // __TBB_CPP17_IS_SWAPPABLE_PRESENT //! Allows to store a function parameter pack as a variable and later pass it to another function template< typename... Types > struct stored_pack; template<> struct stored_pack<> { using pack_type = stored_pack<>; stored_pack() {} // Friend front-end functions template< typename F, typename Pack > friend void call(F&& f, Pack&& p); template< typename Ret, typename F, typename Pack > friend Ret call_and_return(F&& f, Pack&& p); protected: // Ideally, ref-qualified non-static methods would be used, // but that would greatly reduce the set of compilers where it works. template< typename Ret, typename F, typename... Preceding > static Ret call(F&& f, const pack_type& /*pack*/, Preceding&&... params) { return std::forward(f)(std::forward(params)...); } template< typename Ret, typename F, typename... Preceding > static Ret call(F&& f, pack_type&& /*pack*/, Preceding&&... params) { return std::forward(f)(std::forward(params)...); } }; template< typename T, typename... Types > struct stored_pack : stored_pack { using pack_type = stored_pack; using pack_remainder = stored_pack; // Since lifetime of original values is out of control, copies should be made. // Thus references should be stripped away from the deduced type. typename std::decay::type leftmost_value; // Here rvalue references act in the same way as forwarding references, // as long as class template parameters were deduced via forwarding references. stored_pack(T&& t, Types&&... types) : pack_remainder(std::forward(types)...), leftmost_value(std::forward(t)) {} // Friend front-end functions template< typename F, typename Pack > friend void call(F&& f, Pack&& p); template< typename Ret, typename F, typename Pack > friend Ret call_and_return(F&& f, Pack&& p); protected: template< typename Ret, typename F, typename... Preceding > static Ret call(F&& f, pack_type& pack, Preceding&&... params) { return pack_remainder::template call( std::forward(f), static_cast(pack), std::forward(params)... , pack.leftmost_value ); } template< typename Ret, typename F, typename... Preceding > static Ret call(F&& f, pack_type&& pack, Preceding&&... params) { return pack_remainder::template call( std::forward(f), static_cast(pack), std::forward(params)... , std::move(pack.leftmost_value) ); } }; //! Calls the given function with arguments taken from a stored_pack template< typename F, typename Pack > void call(F&& f, Pack&& p) { std::decay::type::template call(std::forward(f), std::forward(p)); } template< typename Ret, typename F, typename Pack > Ret call_and_return(F&& f, Pack&& p) { return std::decay::type::template call(std::forward(f), std::forward(p)); } template< typename... Types > stored_pack save_pack(Types&&... types) { return stored_pack(std::forward(types)...); } // A structure with the value which is equal to Trait::value // but can be used in the immediate context due to parameter T template struct dependent_bool : std::integral_constant {}; template struct body_arg_detector; template struct body_arg_detector { using arg_type = Arg; }; template struct body_arg_detector { using arg_type = Arg; }; template struct argument_detector; template struct argument_detector { using type = typename body_arg_detector::arg_type; }; template struct argument_detector { using type = Arg; }; // Detects the argument type of callable, works for callable with one argument. template using argument_type_of = typename argument_detector::type>::type; template struct type_identity { using type = T; }; template using type_identity_t = typename type_identity::type; } // inline namespace d0 } // namespace detail } // namespace tbb #endif // __TBB_detail__template_helpers_H