PODIO v00-16-03
An Event-Data-Model Toolkit for High Energy Physics Experiments
Loading...
Searching...
No Matches
TypeHelpers.h
Go to the documentation of this file.
1#ifndef PODIO_UTILITIES_TYPEHELPERS_H
2#define PODIO_UTILITIES_TYPEHELPERS_H
3
4#include <map>
5#include <string>
6#include <tuple>
7#include <type_traits>
8#include <unordered_map>
9#include <vector>
10
11namespace podio {
12namespace detail {
13
14 /**
15 * Helper struct to determine whether a given type T is in a tuple of types
16 * that act as a type list in this case
17 */
18 template <typename T, typename>
19 struct TypeInTupleHelper : std::false_type {};
20
21 template <typename T, typename... Ts>
22 struct TypeInTupleHelper<T, std::tuple<Ts...>> : std::bool_constant<(std::is_same_v<T, Ts> || ...)> {};
23
24 /**
25 * variable template for determining whether type T is in a tuple with types
26 * Ts
27 */
28 template <typename T, typename Tuple>
29 static constexpr bool isInTuple = TypeInTupleHelper<T, Tuple>::value;
30
31 /**
32 * Helper struct to turn a tuple of types into a tuple of a template of types, e.g.
33 *
34 * std::tuple<int, float> -> std::tuple<std::vector<int>, std::vector<float>>
35 * if the passed template is std::vector
36 *
37 * NOTE: making the template template parameter to Template variadic because
38 * clang will not be satisfied otherwise if we use it with, e.g. std::vector.
39 * This will also make root dictionary generation fail. GCC works without this
40 * small workaround and is standard compliant in this case, whereas clang is
41 * not.
42 */
43 template <template <typename...> typename Template, typename T>
45
46 template <template <typename...> typename Template, typename... Ts>
47 struct ToTupleOfTemplateHelper<Template, std::tuple<Ts...>> {
48 using type = std::tuple<Template<Ts>...>;
49 };
50
51 /**
52 * Type alias to turn a tuple of types into a tuple of vector of types
53 */
54 template <typename Tuple>
56
57 /**
58 * Alias template to get the type of a tuple resulting from a concatenation of
59 * tuples
60 * See: https://devblogs.microsoft.com/oldnewthing/20200622-00/?p=103900
61 */
62 template <typename... Tuples>
63 using TupleCatType = decltype(std::tuple_cat(std::declval<Tuples>()...));
64
65 /**
66 * variable template for determining whether the type T is in the tuple of all
67 * types or in the tuple of all vector of the passed types
68 */
69 template <typename T, typename Tuple>
70 static constexpr bool isAnyOrVectorOf = isInTuple<T, TupleCatType<Tuple, TupleOfVector<Tuple>>>;
71
72 /**
73 * Helper struct to extract the type from a std::vector or return the
74 * original type if it is not a vector. Works only for "simple" types and does
75 * not strip const-ness
76 */
77 template <typename T>
79 using type = T;
80 };
81
82 template <typename T>
83 struct GetVectorTypeHelper<std::vector<T>> {
84 using type = T;
85 };
86
87 template <typename T>
89
90 /**
91 * Helper struct to detect whether a type is a std::vector
92 */
93 template <typename T>
94 struct IsVectorHelper : std::false_type {};
95
96 template <typename T>
97 struct IsVectorHelper<std::vector<T>> : std::true_type {};
98
99 /**
100 * Alias template for deciding whether the passed type T is a vector or not
101 */
102 template <typename T>
103 static constexpr bool isVector = IsVectorHelper<T>::value;
104
105 /**
106 * Helper struct to detect whether a type is a std::map or std::unordered_map
107 */
108 template <typename T>
109 struct IsMapHelper : std::false_type {};
110
111 template <typename K, typename V>
112 struct IsMapHelper<std::map<K, V>> : std::true_type {};
113
114 template <typename K, typename V>
115 struct IsMapHelper<std::unordered_map<K, V>> : std::true_type {};
116
117 /**
118 * Alias template for deciding whether the passed type T is a map or
119 * unordered_map
120 */
121 template <typename T>
122 static constexpr bool isMap = IsMapHelper<T>::value;
123
124 /**
125 * Helper struct to homogenize the (type) access for things that behave like
126 * maps, e.g. vectors of pairs (and obviously maps).
127 *
128 * NOTE: This is not SFINAE friendly.
129 */
130 template <typename T, typename IsMap = std::bool_constant<isMap<T>>,
131 typename IsVector = std::bool_constant<isVector<T> && (std::tuple_size<typename T::value_type>() == 2)>>
133
134 /**
135 * Specialization for actual maps
136 */
137 template <typename T>
138 struct MapLikeTypeHelper<T, std::bool_constant<true>, std::bool_constant<false>> {
139 using key_type = typename T::key_type;
140 using mapped_type = typename T::mapped_type;
141 };
142
143 /**
144 * Specialization for vector of pairs / tuples (of size 2)
145 */
146 template <typename T>
147 struct MapLikeTypeHelper<T, std::bool_constant<false>, std::bool_constant<true>> {
148 using key_type = typename std::tuple_element<0, typename T::value_type>::type;
149 using mapped_type = typename std::tuple_element<1, typename T::value_type>::type;
150 };
151
152 /**
153 * Type aliases for easier usage in actual code
154 */
155 template <typename T>
157
158 template <typename T>
160
161} // namespace detail
162
163// forward declaration to be able to use it below
164class CollectionBase;
165
166/**
167 * Alias template for checking whether a passed type T inherits from podio::CollectionBase
168 */
169template <typename T>
170static constexpr bool isCollection = std::is_base_of_v<CollectionBase, T>;
171
172} // namespace podio
173
174#endif // PODIO_UTILITIES_TYPEHELPERS_H
typename ToTupleOfTemplateHelper< std::vector, Tuple >::type TupleOfVector
Definition: TypeHelpers.h:55
typename MapLikeTypeHelper< T >::mapped_type GetMappedType
Definition: TypeHelpers.h:159
decltype(std::tuple_cat(std::declval< Tuples >()...)) TupleCatType
Definition: TypeHelpers.h:63
typename MapLikeTypeHelper< T >::key_type GetKeyType
Definition: TypeHelpers.h:156
typename GetVectorTypeHelper< T >::type GetVectorType
Definition: TypeHelpers.h:88
typename std::tuple_element< 1, typename T::value_type >::type mapped_type
Definition: TypeHelpers.h:149
typename std::tuple_element< 0, typename T::value_type >::type key_type
Definition: TypeHelpers.h:148