ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
type_list.hpp
1// This file is part of the ACTS project.
2//
3// Copyright (C) 2016 CERN for the benefit of the ACTS project
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9#pragma once
10
11// Project include(s)
12#include "detray/utils/string_helpers.hpp"
13#include "detray/utils/tuple.hpp"
14#include "detray/utils/type_traits.hpp"
15
16// System include(s)
17#include <array>
18#include <limits>
19#include <string>
20#include <string_view>
21#include <type_traits>
22
23namespace detray {
24
25namespace types {
26
29template <typename... Ts>
30struct list {};
31
34template <typename = void>
35struct get_size {};
36
37template <typename... Ts>
38struct get_size<list<Ts...>>
39 : std::integral_constant<std::size_t, sizeof...(Ts)> {};
40
41template <typename L>
42constexpr inline std::size_t size{get_size<L>()};
44
47template <typename T, std::size_t = 0, typename = void>
48struct contains_impl : public std::false_type {};
49
51template <typename U, std::size_t I, typename T, typename... Ts>
52struct contains_impl<U, I, list<T, Ts...>>
53 : public contains_impl<U, I + 1u, list<Ts...>> {};
54
56template <typename T, std::size_t I, typename... Ts>
57struct contains_impl<T, I, list<T, Ts...>> : public std::true_type {
59 static constexpr std::size_t pos{I};
60};
61
63template <typename T, std::size_t I>
64struct contains_impl<T, I, list<>> : public std::false_type {
66 static constexpr auto pos{std::numeric_limits<std::size_t>::max()};
67};
68
69template <typename L, typename T>
70inline constexpr bool contains = contains_impl<T, 0u, L>::value;
71
72template <typename L, typename T>
73inline constexpr std::size_t position = contains_impl<T, 0u, L>::pos;
75
78template <typename = void>
79struct get_front {};
80
82template <typename T, typename... Ts>
83struct get_front<list<T, Ts...>> {
85 using type = T;
86};
87template <typename L>
88using front = typename get_front<L>::type;
90
93template <typename = void>
94struct get_back {};
95
97template <typename T, typename... Ts>
98struct get_back<list<T, Ts...>> {
100 using type = std::conditional_t<sizeof...(Ts) == 0, T,
101 typename get_back<list<Ts...>>::type>;
102};
103// Base case
105template <>
106struct get_back<list<>> {
108 using type = void;
109};
110template <typename L>
111using back = typename get_back<L>::type;
113
116template <std::size_t N, typename = void>
117struct get_at {};
118
120template <std::size_t N, typename T, typename... Ts>
121struct get_at<N, list<T, Ts...>> {
123 using type = std::remove_cvref_t<decltype(detray::get<N>(
124 std::declval<dtuple<T, Ts...>>()))>;
125};
126template <typename L, std::size_t N>
127using at = typename get_at<N, L>::type;
129
132template <typename N, typename = void>
133struct do_push_back {};
134
136template <typename N, typename... Ts>
137struct do_push_back<N, list<Ts...>> {
139 using type = list<Ts..., N>;
140};
141template <typename L, typename N>
142using push_back = typename do_push_back<N, L>::type;
144
147template <typename N, typename = void>
149
151template <typename N, typename... Ts>
152struct do_push_front<N, list<Ts...>> {
154 using type = list<N, Ts...>;
155};
156template <typename L, typename N>
157using push_front = typename do_push_front<N, L>::type;
159
162namespace detail {
163
164template <typename = void>
165struct is_type_list : public std::false_type {};
166
167template <typename... Ts>
168struct is_type_list<types::list<Ts...>> : public std::true_type {};
169
170template <typename L>
173
174} // namespace detail
175
176
179
182template <typename T>
183std::string demangle_type_name() {
184#if defined(__clang__)
185 constexpr std::string_view prefix{"[T = "};
186 constexpr std::string_view suffix{"]"};
187 constexpr std::string_view function{__PRETTY_FUNCTION__};
188#elif defined(__GNUC__)
189 constexpr std::string_view prefix{"with T = "};
190 constexpr std::string_view suffix{"; "};
191 constexpr std::string_view function{__PRETTY_FUNCTION__};
192#elif defined(_MSC_VER)
193 constexpr std::string_view prefix{"get_type_name<"};
194 constexpr std::string_view suffix{">(void)"};
195 constexpr std::string_view function{__FUNCSIG__};
196#else
197 std::string type_name{typeid(T).name()};
198 type_name += " ";
199 std::string_view function{type_name};
200 constexpr std::string_view prefix{""};
201 constexpr std::string_view suffix{" "};
202#endif
203
204 const std::size_t start{function.find(prefix) + prefix.size()};
205 const std::size_t end{function.find(suffix)};
206 const std::size_t length{end - start};
207
208 return std::string{function.substr(start, length)};
209}
210
213template <typename T>
214std::string get_name(bool full = false) {
215 std::string tp_str{""};
216 try {
217 tp_str = detray::types::demangle_type_name<T>();
218 } catch (...) {
219 return "unknown";
220 }
221
222 if (tp_str.empty()) {
223 return "unknown";
224 }
225
226 if (full) {
227 return tp_str;
228 }
229
230 // Remove template parameter list by removing everything behind the first
231 // occurrence of '<'
232 auto tokens = detray::utils::split_at_delim(tp_str, '<');
233 tp_str = tokens.front();
234
235 tokens.clear();
236
237 // Strip the namespaces by removing everything before the last occurrence of
238 // ':'
239 tokens = detray::utils::split_at_delim(tp_str, ':');
240 return tokens.back();
241}
242
244template <typename = void>
245struct print {
246 print() { std::puts("Not a type_list!\n"); }
247};
248
250template <typename... Ts>
251struct print<list<Ts...>> {
254 template <typename P = void, typename... Ps>
255 void print_typeid(bool full) {
256 std::printf("%s", get_name<P>(full).c_str());
257
258 // Keep unrolling the pack
259 if constexpr (sizeof...(Ps) > 0) {
260 std::puts(", ");
261 return print_typeid<Ps...>(full);
262 }
263 }
264
267 explicit print(bool full = true) {
268 std::puts("type_list<");
269 print_typeid<Ts...>(full);
270 std::puts(">\n");
271 }
272};
273
274
286template <typename orig_list_t, class type_selector, std::size_t I = 0u,
287 typename... Fs>
288DETRAY_HOST_DEVICE consteval auto filtered_list(
289 const list<Fs...>& filtered = list<>{}) {
290 static_assert(sizeof...(Fs) <= I, "Can only map down to list with ");
291
292 // The current list of mapped types
293 using list_t = list<Fs...>;
294
295 if constexpr (I == size<orig_list_t>) {
296 return filtered;
297 } else {
298 // Map the current type corresponding to position 'I'
299 // to the new type according to the given type_selector
300 using next_type = at<orig_list_t, I>;
301 using mapped_t = typename type_selector::template type<next_type>;
302
303 // Don't add the same type multiple times
304 if constexpr (contains<list_t, mapped_t>) {
305 return filtered_list<orig_list_t, type_selector, I + 1u>(filtered);
306 } else {
307 return filtered_list<orig_list_t, type_selector, I + 1u>(
308 push_back<list_t, mapped_t>{});
309 }
310 }
311}
312
325template <typename orig_list_t, class type_selector, std::size_t I = 0u,
326 typename... Fs>
327DETRAY_HOST_DEVICE consteval auto filtered_indices(
328 const list<Fs...>& filtered,
329 std::array<dindex, size<orig_list_t>> idx_array = {0}) {
330 // The current list of mapped types
331 using list_t = list<Fs...>;
332
333 if constexpr (I == size<orig_list_t>) {
334 return idx_array;
335 } else {
336 // Map the current type corresponding to position 'I'
337 // to the new type according to the given type_selector
338 using next_type = at<orig_list_t, I>;
339 using mapped_t = typename type_selector::template type<next_type>;
340
341 // If the type is already mapped, recover the index
342 if constexpr (contains<list_t, mapped_t>) {
343 idx_array[I] = position<list_t, mapped_t>;
344
345 return filtered_indices<orig_list_t, type_selector, I + 1u>(filtered,
346 idx_array);
347 } else {
348 idx_array[I] = sizeof...(Fs);
349
350 return filtered_indices<orig_list_t, type_selector, I + 1u>(
351 push_back<list_t, mapped_t>{}, idx_array);
352 }
353 }
354}
355
356} // namespace types
357
360namespace concepts {
361
362template <typename L>
364
365}
367
368} // namespace detray
Definition type_list.hpp:363
constexpr double T
Magnetic field, native unit (eV*s)/(e*m²).
Definition Units.hpp:168
constexpr double u
atomic mass unit u
Definition Units.hpp:155
Type list concepts.
Definition concepts.hpp:17
Traits for the type list.
Definition type_list.hpp:162
constexpr bool is_type_list_v
Whether L is a types::list specialization.
Definition type_list.hpp:172
Detray include(s).
Definition array_operators.hpp:18
unsigned int dindex
Default index type.
Definition indexing.hpp:18
detray::tuple< types... > dtuple
Tuple type used by detray storage and dispatch.
Definition containers.hpp:46
static constexpr std::size_t pos
Zero-based position of the matching type.
Definition type_list.hpp:59
static constexpr auto pos
Sentinel position used when the type is absent.
Definition type_list.hpp:66
Does the list contain a particular type?
Definition type_list.hpp:48
Definition type_list.hpp:165
list< Ts..., N > type
Resulting type list.
Definition type_list.hpp:139
Append a type.
Definition type_list.hpp:133
list< N, Ts... > type
Resulting type list.
Definition type_list.hpp:154
Prepend a type.
Definition type_list.hpp:148
std::remove_cvref_t< decltype(detray::get< N >( std::declval< dtuple< T, Ts... > >()))> type
Type at position N.
Definition type_list.hpp:123
Access the N-th type.
Definition type_list.hpp:117
std::conditional_t< sizeof...(Ts)==0, T, typename get_back< list< Ts... > >::type > type
Last type in the list.
Definition type_list.hpp:100
void type
Type returned for an empty list.
Definition type_list.hpp:108
Access the last type.
Definition type_list.hpp:94
T type
First type in the list.
Definition type_list.hpp:85
Access the first type.
Definition type_list.hpp:79
Number of types in the list.
Definition type_list.hpp:35
type list implementation
Definition type_list.hpp:30
void print_typeid(bool full)
Print one type name and recursively print the remaining names.
Definition type_list.hpp:255
print(bool full=true)
Print the complete type list.
Definition type_list.hpp:267