ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
tuple_helpers.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/definitions/detail/qualifiers.hpp"
13#include "detray/utils/tuple.hpp"
14#include "detray/utils/type_traits.hpp"
15
16// System include(s)
17#include <limits>
18#include <tuple>
19#include <type_traits>
20#include <utility>
21
22namespace detray::detail {
23
29using std::get;
30
31template <std::size_t I, typename... value_types>
32DETRAY_HOST_DEVICE constexpr decltype(auto) get(
33 const ::detray::dtuple<value_types...>& tuple) noexcept {
34 return ::detray::get<I>(tuple);
35}
36
37template <std::size_t I, typename... value_types>
38DETRAY_HOST_DEVICE constexpr decltype(auto) get(
39 ::detray::dtuple<value_types...>& tuple) noexcept {
40 return ::detray::get<I>(tuple);
41}
42
43template <typename query_t, typename... value_types>
44DETRAY_HOST_DEVICE constexpr decltype(auto) get(
45 const ::detray::dtuple<value_types...>& tuple) noexcept {
46 return ::detray::get<get_type_pos_v<query_t, value_types...>>(tuple);
47}
48
49template <typename query_t, typename... value_types>
50DETRAY_HOST_DEVICE constexpr decltype(auto) get(
51 ::detray::dtuple<value_types...>& tuple) noexcept {
52 return ::detray::get<get_type_pos_v<query_t, value_types...>>(tuple);
53}
55
61template <std::size_t N, class T>
63
64// std::tuple
65template <std::size_t N, typename... value_types>
66struct tuple_element<N, std::tuple<value_types...>>
67 : std::tuple_element<N, std::tuple<value_types...>> {};
68
69// detray::dtuple
71template <std::size_t N, typename... value_types>
72struct tuple_element<N, detray::dtuple<value_types...>> {
74 using type = std::decay_t<decltype(::detray::get<N>(
75 std::declval<detray::dtuple<value_types...>>()))>;
76};
77
78template <std::size_t N, class T>
79using tuple_element_t = typename tuple_element<N, T>::type;
81
87template <class T>
89
90// std::tuple
91template <typename... value_types>
92struct tuple_size<std::tuple<value_types...>>
93 : std::tuple_size<std::tuple<value_types...>> {};
94
95// detray::dtuple
97template <typename... value_types>
98struct tuple_size<::detray::dtuple<value_types...>> {
100 static constexpr std::size_t value = sizeof...(value_types);
101};
102
103template <class T>
104constexpr std::size_t tuple_size_v{tuple_size<T>::value};
106
113template <class T>
116 using type = T;
117};
118
119template <class T>
120struct unwrap_refwrapper<std::reference_wrapper<T>> {
122 using type = T&;
123};
124
125template <class T>
126using unwrap_decay_t = typename unwrap_refwrapper<std::decay_t<T>>::type;
127
128// make_tuple for std::tuple
129template <template <typename...> class tuple_t, class... value_types>
130 requires std::is_same_v<tuple_t<value_types...>, std::tuple<value_types...>>
131DETRAY_HOST constexpr std::tuple<unwrap_decay_t<value_types>...> make_tuple(
132 value_types&&... args) {
133 return std::make_tuple(std::forward<value_types>(args)...);
134}
135
136// make_tuple for detray::dtuple
137template <template <typename...> class tuple_t, class... value_types>
138 requires std::is_same_v<tuple_t<value_types...>,
139 detray::dtuple<value_types...>>
140DETRAY_HOST_DEVICE constexpr detray::dtuple<unwrap_decay_t<value_types>...>
141make_tuple(value_types&&... args) {
143 std::forward<value_types>(args)...};
144}
146
151template <typename T, typename tuple_t>
152struct has_type;
153
154// std::tuple
155template <typename T>
156struct has_type<T, std::tuple<>> : std::false_type {};
157
158template <typename T, typename U, typename... Ts>
159struct has_type<T, std::tuple<U, Ts...>> : has_type<T, std::tuple<Ts...>> {};
160
161template <typename T, typename... Ts>
162struct has_type<T, std::tuple<T, Ts...>> : std::true_type {};
163
164// detray::dtuple
165template <typename T>
166struct has_type<T, detray::dtuple<>> : std::false_type {};
167
168template <typename T, typename U, typename... Ts>
169struct has_type<T, detray::dtuple<U, Ts...>>
170 : has_type<T, detray::dtuple<Ts...>> {};
171
172template <typename T, typename... Ts>
173struct has_type<T, detray::dtuple<T, Ts...>> : std::true_type {};
174
175template <typename T, class tuple_t>
176constexpr bool has_type_v = has_type<T, tuple_t>::value;
178
181template <typename... tuple_ts>
183
184template <typename... Args>
185struct tuple_cat_type<std::tuple<Args...>> {
186 using type = std::tuple<Args...>;
187};
188
189template <typename... Args1, typename... Args2, typename... tuple_ts>
190struct tuple_cat_type<std::tuple<Args1...>, std::tuple<Args2...>, tuple_ts...> {
191 using type = typename tuple_cat_type<std::tuple<Args1..., Args2...>,
192 tuple_ts...>::type;
193};
194
196template <typename... Args>
197struct tuple_cat_type<detray::dtuple<Args...>> {
199 using type = detray::dtuple<Args...>;
200};
201
203template <typename... Args1, typename... Args2, typename... tuple_ts>
204struct tuple_cat_type<detray::dtuple<Args1...>, detray::dtuple<Args2...>,
205 tuple_ts...> {
207 using type = typename tuple_cat_type<detray::dtuple<Args1..., Args2...>,
208 tuple_ts...>::type;
209};
210
211template <typename... tuple_ts>
212using tuple_cat_t = typename tuple_cat_type<tuple_ts...>::type;
214
217template <std::size_t I, typename... tuple_ts>
218struct unique_types {};
219
221template <std::size_t I>
222struct unique_types<I, std::tuple<>> {
223 using type = std::tuple<>;
224};
225
227template <std::size_t I, typename Arg1, typename... Args>
228struct unique_types<I, std::tuple<Arg1, Args...>> {
229 using type = std::conditional_t<
230 has_type_v<Arg1, std::tuple<Args...>>,
231 typename unique_types<I - 1u, std::tuple<Args...>>::type,
232 typename unique_types<I - 1u, std::tuple<Args..., Arg1>>::type>;
233};
234
236template <typename Arg1, typename... Args>
237struct unique_types<0u, std::tuple<Arg1, Args...>> {
238 using type = std::tuple<Arg1, Args...>;
239};
240
242template <std::size_t I>
246};
247
249template <std::size_t I, typename Arg1, typename... Args>
250struct unique_types<I, detray::dtuple<Arg1, Args...>> {
252 using type = std::conditional_t<
253 has_type_v<Arg1, detray::dtuple<Args...>>,
254 typename unique_types<I - 1u, detray::dtuple<Args...>>::type,
255 typename unique_types<I - 1u, detray::dtuple<Args..., Arg1>>::type>;
256};
257
259template <typename Arg1, typename... Args>
260struct unique_types<0u, detray::dtuple<Arg1, Args...>> {
262 using type = detray::dtuple<Arg1, Args...>;
263};
264
265template <typename tuple_t>
266using unique_t =
267 typename unique_types<tuple_size_v<tuple_t> - 1u, tuple_t>::type;
269
272template <typename T1, typename T2>
273struct is_permutation : public std::false_type {};
274
275template <>
277 : public std::true_type {};
278
280template <typename... Args1, typename... Args2>
281struct is_permutation<detray::dtuple<Args1...>, detray::dtuple<Args2...>> {
283 using T1 = detray::dtuple<Args1...>;
285 using T2 = detray::dtuple<Args2...>;
286
289 template <typename o_tuple_t, typename T, typename... U>
290 static consteval bool compare() {
291 if constexpr (detray::detail::has_type_v<T, o_tuple_t>) {
292 if constexpr (sizeof...(U) == 0u) {
293 return true;
294 } else {
295 return compare<o_tuple_t, U...>();
296 }
297 } else {
298 return false;
299 }
300 }
301
303 static constexpr bool value =
304 ((detray::detail::tuple_size_v<T1> == detray::detail::tuple_size_v<T2>) &&
305 (compare<T1, Args2...>() && compare<T2, Args1...>()));
306};
307
308template <typename T1, typename T2>
309constexpr bool is_permutation_v = is_permutation<T1, T2>::value;
311
314
315// Any
316template <template <typename...> class trait, typename tuple_t>
317struct tuple_any {};
318
319template <template <typename...> class trait, typename... Args>
320struct tuple_any<trait, std::tuple<Args...>> {
321 static constexpr bool value = (trait<Args>::value || ...);
322};
324template <template <typename...> class trait, typename... Args>
325struct tuple_any<trait, detray::dtuple<Args...>> {
327 static constexpr bool value = (trait<Args>::value || ...);
328};
329
330template <template <typename...> class trait, typename tuple_t>
331constexpr bool tuple_any_v = tuple_any<trait, tuple_t>::value;
332
333// All
334template <template <typename...> class trait, typename tuple_t>
335struct tuple_all {};
336
337template <template <typename...> class trait, typename... Args>
338struct tuple_all<trait, std::tuple<Args...>> {
339 static constexpr bool value = (trait<Args>::value && ...);
340};
342template <template <typename...> class trait, typename... Args>
343struct tuple_all<trait, detray::dtuple<Args...>> {
345 static constexpr bool value = (trait<Args>::value && ...);
346};
347
348template <template <typename...> class trait, typename tuple_t>
349constexpr bool tuple_all_v = tuple_all<trait, tuple_t>::value;
350
352
353} // namespace detray::detail
Detray include(s).
Definition array_operators.hpp:18
constexpr detray::tuple< std::decay_t< Ts >... > make_tuple(Ts &&...vs)
Construct a tuple by decaying and forwarding its arguments.
Definition tuple.hpp:219
detray::tuple< types... > dtuple
Tuple type used by detray storage and dispatch.
Definition containers.hpp:46
Check if the tuple contains a type.
Definition tuple_helpers.hpp:152
detray::dtuple< Args2... > T2
Second tuple type being compared.
Definition tuple_helpers.hpp:285
static consteval bool compare()
Check whether every type in the pack occurs in the other tuple.
Definition tuple_helpers.hpp:290
static constexpr bool value
Whether both tuples contain the same types, regardless of order.
Definition tuple_helpers.hpp:303
detray::dtuple< Args1... > T1
First tuple type being compared.
Definition tuple_helpers.hpp:283
Check for equality of tuple types modulo permutation.
Definition tuple_helpers.hpp:273
static constexpr bool value
Whether every element type satisfies trait.
Definition tuple_helpers.hpp:345
Definition tuple_helpers.hpp:335
static constexpr bool value
Whether at least one element type satisfies trait.
Definition tuple_helpers.hpp:327
Check trait on ever element of the tuple.
Definition tuple_helpers.hpp:317
typename tuple_cat_type< detray::dtuple< Args1..., Args2... >, tuple_ts... >::type type
Tuple type containing the concatenated element types.
Definition tuple_helpers.hpp:207
detray::dtuple< Args... > type
Tuple type produced by concatenation.
Definition tuple_helpers.hpp:199
Concatenate tuple types.
Definition tuple_helpers.hpp:182
std::decay_t< decltype(::detray::get< N >( std::declval< detray::dtuple< value_types... > >()))> type
Decayed type of the selected element.
Definition tuple_helpers.hpp:74
tuple_element for std::tuple
Definition tuple_helpers.hpp:62
static constexpr std::size_t value
Number of element types in the tuple.
Definition tuple_helpers.hpp:100
tuple_size for std::tuple
Definition tuple_helpers.hpp:88
detray::dtuple< Arg1, Args... > type
Tuple type at the end of duplicate removal.
Definition tuple_helpers.hpp:262
std::conditional_t< has_type_v< Arg1, detray::dtuple< Args... > >, typename unique_types< I - 1u, detray::dtuple< Args... > >::type, typename unique_types< I - 1u, detray::dtuple< Args..., Arg1 > >::type > type
Tuple type with repeated element types removed.
Definition tuple_helpers.hpp:252
detray::dtuple<> type
Empty tuple type.
Definition tuple_helpers.hpp:245
Remove duplicate types from tuple.
Definition tuple_helpers.hpp:218
make_tuple for std::tuple users have to specify tuple_t for detail::make_tuple
Definition tuple_helpers.hpp:114
T type
Decayed type when the argument is not a reference wrapper.
Definition tuple_helpers.hpp:116
Default tuple type.
Definition tuple.hpp:26