77// In applying this license CERN does not waive the privileges and immunities
88// granted to it by virtue of its status as an Intergovernmental Organization
99// or submit itself to any jurisdiction.
10- #ifndef o2_framework_FunctionalHelpers_H_INCLUDED
11- #define o2_framework_FunctionalHelpers_H_INCLUDED
10+ #ifndef O2_FRAMEWORK_FUNCTIONALHELPERS_H_
11+ #define O2_FRAMEWORK_FUNCTIONALHELPERS_H_
1212
13+ #include " Framework/Pack.h"
1314#include < functional>
1415
1516namespace o2 ::framework
@@ -23,150 +24,6 @@ struct memfun_type {
2324};
2425} // namespace
2526
26- // / Type helper to hold a parameter pack. This is different from a tuple
27- // / as there is no data associated to it.
28- template <typename ...>
29- struct pack {
30- };
31-
32- // / template function to determine number of types in a pack
33- template <typename ... Ts>
34- constexpr std::size_t pack_size (pack<Ts...> const &)
35- {
36- return sizeof ...(Ts);
37- }
38-
39- template <std::size_t I, typename T>
40- struct pack_element ;
41-
42- // recursive case
43- template <std::size_t I, typename Head, typename ... Tail>
44- struct pack_element <I, pack<Head, Tail...>>
45- : pack_element<I - 1 , pack<Tail...>> {
46- };
47-
48- // base case
49- template <typename Head, typename ... Tail>
50- struct pack_element <0 , pack<Head, Tail...>> {
51- typedef Head type;
52- };
53-
54- template <std::size_t I, typename T>
55- using pack_element_t = typename pack_element<I, T>::type;
56-
57- // / Templates for manipulating type lists in pack
58- // / (see https://codereview.stackexchange.com/questions/201209/filter-template-meta-function/201222#201222)
59- // / Example of use:
60- // / template<typename T>
61- // / struct is_not_double: std::true_type{};
62- // / template<>
63- // / struct is_not_double<double>: std::false_type{};
64- // / The following will return a pack, excluding double
65- // / filtered_pack<is_not_double, double, int, char, float*, double, char*, double>()
66- // /
67- template <typename ... Args1, typename ... Args2>
68- constexpr auto concatenate_pack (pack<Args1...>, pack<Args2...>)
69- {
70- return pack<Args1..., Args2...>{};
71- }
72-
73- template <typename P1, typename P2, typename ... Ps>
74- constexpr auto concatenate_pack (P1 p1, P2 p2, Ps... ps)
75- {
76- return concatenate_pack (p1, concatenate_pack (p2, ps...));
77- };
78-
79- template <typename ... Ps>
80- using concatenated_pack_t = decltype (concatenate_pack(Ps{}...));
81-
82- // / Selects from the pack types that satisfy the Condition
83- template <template <typename > typename Condition, typename Result>
84- constexpr auto select_pack (Result result, pack<>)
85- {
86- return result;
87- }
88-
89- template <template <typename > typename Condition, typename Result, typename T, typename ... Ts>
90- constexpr auto select_pack (Result result, pack<T, Ts...>)
91- {
92- if constexpr (Condition<T>())
93- return select_pack<Condition>(concatenate_pack (result, pack<T>{}), pack<Ts...>{});
94- else
95- return select_pack<Condition>(result, pack<Ts...>{});
96- }
97-
98- template <template <typename > typename Condition, typename ... Types>
99- using selected_pack = std::decay_t <decltype (select_pack<Condition>(pack<>{}, pack<Types...>{}))>;
100-
101- // / Select only the items of a pack which match Condition
102- template <template <typename > typename Condition, typename Result>
103- constexpr auto filter_pack (Result result, pack<>)
104- {
105- return result;
106- }
107-
108- template <template <typename > typename Condition, typename Result, typename T, typename ... Ts>
109- constexpr auto filter_pack (Result result, pack<T, Ts...>)
110- {
111- if constexpr (Condition<T>())
112- return filter_pack<Condition>(result, pack<Ts...>{});
113- else
114- return filter_pack<Condition>(concatenate_pack (result, pack<T>{}), pack<Ts...>{});
115- }
116-
117- template <typename T>
118- void print_pack ()
119- {
120- puts (__PRETTY_FUNCTION__);
121- }
122-
123- template <template <typename > typename Condition, typename ... Types>
124- using filtered_pack = std::decay_t <decltype (filter_pack<Condition>(pack<>{}, pack<Types...>{}))>;
125-
126- // / Check if a given pack Pack has a type T inside.
127- template <typename T, typename Pack>
128- struct has_type ;
129-
130- template <typename T, typename ... Us>
131- struct has_type <T, pack<Us...>> : std::disjunction<std::is_same<T, Us>...> {
132- };
133-
134- template <typename T, typename ... Us>
135- inline constexpr bool has_type_v = has_type<T, Us...>::value;
136-
137- template <typename T>
138- constexpr size_t has_type_at (pack<> const &)
139- {
140- return static_cast <size_t >(-1 );
141- }
142-
143- template <typename T, typename T1, typename ... Ts>
144- constexpr size_t has_type_at (pack<T1, Ts...> const &)
145- {
146- if constexpr (std::is_same_v<T, T1>)
147- return 0 ;
148- if constexpr (has_type_v<T, pack<T1, Ts...>>)
149- return 1 + has_type_at<T>(pack<Ts...>{});
150- return sizeof ...(Ts) + 2 ;
151- }
152-
153- // / Intersect two packs
154- template <typename S1, typename S2>
155- struct intersect_pack {
156- template <std::size_t ... Indices>
157- static constexpr auto make_intersection (std::index_sequence<Indices...>)
158- {
159- return filtered_pack<std::is_void,
160- std::conditional_t <
161- has_type_v<pack_element_t <Indices, S1>, S2>,
162- pack_element_t <Indices, S1>, void >...>{};
163- }
164- using type = decltype (make_intersection(std::make_index_sequence<pack_size(S1{})>{}));
165- };
166-
167- template <typename S1, typename S2>
168- using intersected_pack_t = typename intersect_pack<S1, S2>::type;
169-
17027// / Type helper to hold metadata about a lambda or a class
17128// / method.
17229template <typename Ret, typename Class, typename ... Args>
@@ -197,24 +54,6 @@ memfun_type<decltype(&F::operator())>
19754 return memfun_type<decltype (&F::operator ())>();
19855}
19956
200- // / Helper to understand if a given type is complete (declared fully) or not (forward declared).
201- // / See also: https://devblogs.microsoft.com/oldnewthing/20190710-00/?p=102678
202- template <typename , typename = void >
203- constexpr bool is_type_complete_v = false ;
204-
205- template <typename T>
206- constexpr bool is_type_complete_v<T, std::void_t <decltype (sizeof (T))>> = true ;
207-
208- // / Helper which will invoke lambda if the type T is actually available.
209- // / Can be used to check for existence or not of a given type.
210- template <typename T, typename TLambda>
211- void call_if_defined (TLambda&& lambda)
212- {
213- if constexpr (is_type_complete_v<T>) {
214- lambda (static_cast <T*>(nullptr ));
215- }
216- }
217-
21857} // namespace o2::framework
21958
220- #endif // o2_framework_FunctionalHelpers_H_INCLUDED
59+ #endif // O2_FRAMEWORK_FUNCTIONALHELPERS_H_
0 commit comments