Project
Loading...
Searching...
No Matches
Pack.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#ifndef O2_FRAMEWORK_PACK_H_
12#define O2_FRAMEWORK_PACK_H_
13
14#include <cstddef>
15#include <utility>
16
17namespace o2::framework
18{
19
22template <typename...>
23struct pack {
24};
25
27template <typename... Ts>
28constexpr std::size_t pack_size(pack<Ts...> const&)
29{
30 return sizeof...(Ts);
31}
32
33template <std::size_t I, typename T>
35
36#if __has_builtin(__type_pack_element)
37template <std::size_t I, typename... Ts>
38struct pack_element<I, pack<Ts...>> {
39 using type = __type_pack_element<I, Ts...>;
40};
41#else
42// recursive case
43template <std::size_t I, typename Head, typename... Tail>
44struct pack_element<I, pack<Head, Tail...>>
45 : pack_element<I - 1, pack<Tail...>> {
46};
47
48// base case
49template <typename Head, typename... Tail>
50struct pack_element<0, pack<Head, Tail...>> {
51 typedef Head type;
52};
53#endif
54
55template <std::size_t I, typename T>
57
58template <typename T>
60
61template <typename Head, typename... Tail>
63{
64 return pack<Tail...>{};
65}
66
77template <typename... Args1, typename... Args2>
79{
80 return pack<Args1..., Args2...>{};
81}
82
83template <typename P1, typename P2, typename... Ps>
84constexpr auto concatenate_pack(P1 p1, P2 p2, Ps... ps)
85{
86 return concatenate_pack(p1, concatenate_pack(p2, ps...));
87}
88
89template <typename... Ps>
90using concatenated_pack_t = decltype(concatenate_pack(Ps{}...));
91
92template <typename... Args1, typename... Args2>
97
98template <typename P1, typename P2>
99using interleaved_pack_t = decltype(interleave_pack(P1{}, P2{}));
100
102template <template <typename...> typename Condition, typename... Ts>
104
105template <typename... Ts>
106consteval auto count_non_void_pack(pack<Ts...> const&)
107{
108 return ((std::is_void_v<Ts> ? 0 : 1) + ...);
109}
110
111template <typename Result>
112consteval auto prune_voids_pack(Result result, pack<>)
113{
114 return result;
115}
116
117template <typename T>
118concept void_pack_element = std::is_void_v<T>;
119
120template <typename T>
122
123// The first one is non void, but one of the others is void
124template <typename... Rs, nonvoid_pack_element T, typename... Ts>
129
130// The first one is void
131template <typename... Rs, void_pack_element V, typename... Ts>
133{
134 return prune_voids_pack(pack<Rs...>{}, pack<Ts...>{});
135}
136
137// The first one is non void, but one of the others is void
138template <typename... Rs, nonvoid_pack_element T1, nonvoid_pack_element T2, typename... Ts>
143
144// Eats 4 types at the time
145template <typename... Rs, nonvoid_pack_element T1, nonvoid_pack_element T2, nonvoid_pack_element T3, nonvoid_pack_element T4, typename... Ts>
150
151// Eats 8 types at the time
152template <typename... Rs, nonvoid_pack_element T1, nonvoid_pack_element T2, nonvoid_pack_element T3, nonvoid_pack_element T4,
153 nonvoid_pack_element T5, nonvoid_pack_element T6, nonvoid_pack_element T7, nonvoid_pack_element T8, typename... Ts>
158
162template <template <typename...> typename Condition, typename Result, typename... Cs>
163consteval auto select_pack(Result result, pack<>, pack<Cs...>)
164{
165 return result;
166}
167
168template <template <typename...> typename Condition, typename Result, typename T, typename... Cs, typename... Ts>
169consteval auto select_pack(Result result, pack<T, Ts...>, pack<Cs...> condPack)
170{
171 if constexpr (Condition<T, Cs...>()) {
172 return select_pack<Condition>(concatenate_pack(result, pack<T>{}), pack<Ts...>{}, condPack);
173 } else {
174 return select_pack<Condition>(result, pack<Ts...>{}, condPack);
175 }
176}
177
178template <template <typename...> typename Condition, typename... Types>
179using selected_pack = std::decay_t<decltype(prune_voids_pack(pack<>{}, with_condition_pack<Condition, Types...>{}))>;
180template <template <typename...> typename Condition, typename CondPack, typename Pack>
181using selected_pack_multicondition = std::decay_t<decltype(select_pack<Condition>(pack<>{}, Pack{}, CondPack{}))>;
182
184template <template <typename> typename Condition, typename Result>
185constexpr auto filter_pack(Result result, pack<>)
186{
187 return result;
188}
189
190template <template <typename> typename Condition, typename Result, typename T, typename... Ts>
191constexpr auto filter_pack(Result result, pack<T, Ts...>)
192{
193 if constexpr (Condition<T>()) {
194 return filter_pack<Condition>(result, pack<Ts...>{});
195 } else {
196 return filter_pack<Condition>(concatenate_pack(result, pack<T>{}), pack<Ts...>{});
197 }
198}
199
200template <typename T>
202{
203 puts(__PRETTY_FUNCTION__);
204}
205
206template <template <typename> typename Condition, typename... Types>
207using filtered_pack = std::decay_t<decltype(filter_pack<Condition>(pack<>{}, pack<Types...>{}))>;
208
209template <typename T, typename... Us>
211{
212 return (std::same_as<T, Us> || ...);
213}
214
215template <typename T, typename P>
216inline constexpr bool has_type_v = has_type<T>(P{});
217
218template <template <typename, typename> typename Condition, typename T, typename... Us>
220{
221 return (Condition<T, Us>::value || ...);
222}
223
224template <template <typename, typename> typename Condition, typename T, typename P>
225inline constexpr bool has_type_conditional_v = has_type_conditional<Condition, T>(P{});
226
227template <typename T, typename... Ts>
228consteval size_t has_type_at_v(pack<Ts...>)
229{
230 constexpr size_t size = sizeof...(Ts);
231 constexpr bool found[size] = {std::same_as<T, Ts>...};
232 for (size_t i = 0; i < size; ++i) {
233 if (found[i]) {
234 return i;
235 }
236 }
237 return size + 1;
238}
239
240template <template <typename, typename> typename Condition, typename T, typename... Ts>
242{
243 constexpr size_t size = sizeof...(Ts);
244 constexpr bool found[size] = {Condition<T, Ts>::value...};
245 for (size_t i = 0; i < size; ++i) {
246 if (found[i]) {
247 return i;
248 }
249 }
250 return size + 1;
251}
252
254template <typename S1, typename S2>
256 template <std::size_t... Indices>
257 static constexpr auto make_intersection(std::index_sequence<Indices...>)
258 {
259 return filtered_pack<std::is_void,
260 std::conditional_t<
261 has_type<pack_element_t<Indices, S1>>(S2{}),
262 pack_element_t<Indices, S1>, void>...>{};
263 }
264 using type = decltype(make_intersection(std::make_index_sequence<pack_size(S1{})>{}));
265};
266
267template <typename S1, typename S2>
269
270template <typename... A1, typename... A2>
272{
273 return intersected_pack_t<pack<A1...>, pack<A2...>>{};
274}
275
276template <typename P1, typename P2, typename... Ps>
277constexpr auto intersected_pack(P1 p1, P2 p2, Ps... ps)
278{
279 return intersected_pack(p1, intersected_pack(p2, ps...));
280}
281
282template <typename... Ps>
283using full_intersected_pack_t = decltype(intersected_pack(Ps{}...));
284
286template <typename S1, typename S2>
288 template <std::size_t... Indices>
289 static constexpr auto make_subtraction(std::index_sequence<Indices...>)
290 {
291 return filtered_pack<std::is_void,
292 std::conditional_t<
293 !has_type<pack_element_t<Indices, S1>>(S2{}),
294 pack_element_t<Indices, S1>, void>...>{};
295 }
296 using type = decltype(make_subtraction(std::make_index_sequence<pack_size(S1{})>{}));
297};
298
299template <typename... Args1, typename... Args2>
301{
302 using p1 = typename subtract_pack<pack<Args1...>, pack<Args2...>>::type;
303 return concatenate_pack(p1{}, pack<Args2...>{});
304}
305
306template <typename P1>
307constexpr auto concatenate_pack_unique(P1 p1)
308{
309 return p1;
310}
311
312template <typename P1, typename P2, typename... Ps>
313constexpr auto concatenate_pack_unique(P1 p1, P2 p2, Ps... ps)
314{
316}
317
318template <typename... Ps>
320
321template <typename PT>
322constexpr auto unique_pack(pack<>, PT p2)
323{
324 return p2;
325}
326
327template <typename PT, typename T, typename... Ts>
328constexpr auto unique_pack(pack<T, Ts...>, PT p2)
329{
331}
332
333template <typename P>
334using unique_pack_t = decltype(unique_pack(P{}, pack<>{}));
335
336template <typename... Ts>
337inline constexpr std::tuple<Ts...> pack_to_tuple(pack<Ts...>)
338{
339 return std::tuple<Ts...>{};
340}
341
342template <typename P>
343using pack_to_tuple_t = decltype(pack_to_tuple(P{}));
344
345template <typename T, std::size_t... Is>
346inline auto sequence_to_pack(std::integer_sequence<std::size_t, Is...>)
347{
348 return pack<decltype((Is, T{}))...>{};
349};
350
351template <typename T, std::size_t N>
352using repeated_type_pack_t = decltype(sequence_to_pack<T>(std::make_index_sequence<N>()));
353
354} // namespace o2::framework
355
356#endif // O2_FRAMEWORK_PACK_H_
int32_t i
constexpr int p2()
constexpr int p1()
constexpr to accelerate the coordinates changing
GLuint64EXT * result
Definition glcorearb.h:5662
GLsizeiptr size
Definition glcorearb.h:659
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
typename intersect_pack< S1, S2 >::type intersected_pack_t
Definition Pack.h:268
decltype(unique_pack(P{}, pack<>{})) unique_pack_t
Definition Pack.h:334
constexpr bool has_type_conditional_v
Definition Pack.h:225
constexpr auto pack_tail(pack< Head, Tail... >)
Definition Pack.h:62
decltype(interleave_pack(P1{}, P2{})) interleaved_pack_t
Definition Pack.h:99
decltype(sequence_to_pack< T >(std::make_index_sequence< N >())) repeated_type_pack_t
Definition Pack.h:352
std::decay_t< decltype(select_pack< Condition >(pack<>{}, Pack{}, CondPack{}))> selected_pack_multicondition
Definition Pack.h:181
std::decay_t< decltype(prune_voids_pack(pack<>{}, with_condition_pack< Condition, Types... >{}))> selected_pack
Definition Pack.h:179
consteval size_t has_type_at_conditional_v(pack< Ts... >)
Definition Pack.h:241
bool consteval has_type(framework::pack< Us... >)
Definition Pack.h:210
auto sequence_to_pack(std::integer_sequence< std::size_t, Is... >)
Definition Pack.h:346
decltype(intersected_pack(Ps{}...)) full_intersected_pack_t
Definition Pack.h:283
constexpr auto intersected_pack(pack< A1... >, pack< A2... >)
Definition Pack.h:271
constexpr auto filter_pack(Result result, pack<>)
Select only the items of a pack which match Condition.
Definition Pack.h:185
@ Condition
Eventually a message whose content is retrieved from CCDB.
decltype(concatenate_pack(Ps{}...)) concatenated_pack_t
Definition Pack.h:90
constexpr auto interleave_pack(pack< Args1... >, pack< Args2... >)
Definition Pack.h:93
constexpr bool has_type_v
Definition Pack.h:216
typename pack_element< I, T >::type pack_element_t
Definition Pack.h:56
std::decay_t< decltype(filter_pack< Condition >(pack<>{}, pack< Types... >{}))> filtered_pack
Definition Pack.h:207
consteval size_t has_type_at_v(pack< Ts... >)
Definition Pack.h:228
constexpr std::tuple< Ts... > pack_to_tuple(pack< Ts... >)
Definition Pack.h:337
constexpr auto concatenate_pack(pack< Args1... >, pack< Args2... >)
Definition Pack.h:78
constexpr auto unique_pack(pack<>, PT p2)
Definition Pack.h:322
constexpr std::size_t pack_size(pack< Ts... > const &)
template function to determine number of types in a pack
Definition Pack.h:28
decltype(concatenate_pack_unique(Ps{}...)) concatenated_pack_unique_t
Definition Pack.h:319
consteval auto prune_voids_pack(Result result, pack<>)
Definition Pack.h:112
constexpr auto concatenate_pack_unique(pack< Args1... >, pack< Args2... >)
Definition Pack.h:300
typename pack_element< 0, T >::type pack_head_t
Definition Pack.h:59
void print_pack()
Definition Pack.h:201
consteval auto count_non_void_pack(pack< Ts... > const &)
Definition Pack.h:106
decltype(pack_to_tuple(P{})) pack_to_tuple_t
Definition Pack.h:343
bool consteval has_type_conditional(framework::pack< Us... >)
Definition Pack.h:219
consteval auto select_pack(Result result, pack<>, pack< Cs... >)
Definition Pack.h:163
Intersect two packs.
Definition Pack.h:255
static constexpr auto make_intersection(std::index_sequence< Indices... >)
Definition Pack.h:257
decltype(make_intersection(std::make_index_sequence< pack_size(S1{})>{})) type
Definition Pack.h:264
Subtract two packs.
Definition Pack.h:287
static constexpr auto make_subtraction(std::index_sequence< Indices... >)
Definition Pack.h:289
decltype(make_subtraction(std::make_index_sequence< pack_size(S1{})>{})) type
Definition Pack.h:296