ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
tuple.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
14// System include(s)
15#include <type_traits>
16#include <utility>
17
18namespace detray {
19
25template <typename... Ts>
26struct tuple {
27 // As long as we did everything correctly, this should only get instantiated
28 // with an empty parameter list, for the implementation to work correctly.
29 static_assert(sizeof...(Ts) == 0, "There's a coding error in detray::tuple!");
30};
31
33template <typename T, typename... Ts>
34struct tuple<T, Ts...> {
35 // Deliberately not value-initializing: that would require every element to
36 // be default constructible, which is not a requirement of this tuple type.
37 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
39 constexpr tuple() = default;
40
43 constexpr tuple(const tuple &o)
44 requires(std::is_copy_constructible_v<T> &&
45 (std::is_copy_constructible_v<Ts> && ...))
46 = default;
47
52 template <typename U, typename... Us>
53 requires std::is_constructible_v<T, U &&> &&
54 std::is_constructible_v<tuple<Ts...>, Us &&...>
55 DETRAY_HOST_DEVICE explicit constexpr tuple(const tuple<U, Us...> &o)
56 : v(o.v), r(o.r) {}
57
60 constexpr tuple(tuple &&o) noexcept
61 requires(std::is_move_constructible_v<T> &&
62 (std::is_move_constructible_v<Ts> && ...))
63 = default;
64
69 template <typename U, typename... Us>
70 requires std::is_constructible_v<T, U &&> &&
71 std::is_constructible_v<tuple<Ts...>, Us &&...>
72 DETRAY_HOST_DEVICE explicit constexpr tuple(tuple<U, Us...> &&o)
73 : v(std::move(o.v)), r(std::move(o.r)) {}
74
80 template <typename U, typename... Us>
81 requires std::is_constructible_v<T, U &&> &&
82 std::is_constructible_v<tuple<Ts...>, Us &&...> &&
83 (!(std::is_same_v<tuple, U> ||
84 (std::is_same_v<tuple, Us> || ...)))
85 DETRAY_HOST_DEVICE explicit constexpr tuple(U &&_v, Us &&..._r)
86 : v(std::forward<U>(_v)), r(std::forward<Us>(_r)...) {}
87
88 constexpr ~tuple() noexcept = default;
89
93 constexpr tuple &operator=(const tuple &other)
94 requires(std::is_copy_assignable_v<T> &&
95 (std::is_copy_assignable_v<Ts> && ...))
96 = default;
97
103 template <typename U, typename... Us>
104 DETRAY_HOST_DEVICE constexpr tuple &operator=(const tuple<U, Us...> &other)
105 requires(std::is_assignable_v<T &, const U &> &&
106 (std::is_assignable_v<Ts &, const Us &> && ...))
107 {
108 v = other.v;
109 r = other.r;
110 return *this;
111 }
112
116 constexpr tuple &operator=(tuple &&other) noexcept
117 requires(std::is_move_assignable_v<T> &&
118 (std::is_move_assignable_v<Ts> && ...))
119 = default;
120
126 template <typename U, typename... Us>
127 DETRAY_HOST_DEVICE constexpr tuple &operator=(tuple<U, Us...> &&other)
128 requires(std::is_assignable_v<T &, U> &&
129 (std::is_assignable_v<Ts &, Us> && ...))
130 {
131 v = std::move(other.v);
132 r = std::move(other.r);
133 return *this;
134 }
135
136 T v;
137 // Value-initialization would require every tail element to be default
138 // constructible, which is not a requirement of this tuple type.
140 tuple<Ts...> r; // NOLINT(cppcoreguidelines-pro-type-member-init)
141};
142
144template <typename T1, typename T2>
146
151template <std::size_t I, typename... Ts>
152DETRAY_HOST_DEVICE const auto &get(const detray::tuple<Ts...> &t) noexcept {
153 static_assert(I < sizeof...(Ts),
154 "Attempt to access index greater than tuple size.");
155
156 if constexpr (I == 0) {
157 return t.v;
158 } else {
159 return ::detray::get<I - 1>(t.r);
160 }
161}
162
167template <std::size_t I, typename... Ts>
168DETRAY_HOST_DEVICE auto &get(detray::tuple<Ts...> &t) noexcept {
169 static_assert(I < sizeof...(Ts),
170 "Attempt to access index greater than tuple size.");
171
172 if constexpr (I == 0) {
173 return t.v;
174 } else {
175 return ::detray::get<I - 1>(t.r);
176 }
177}
178
183template <typename U, typename T, typename... Ts>
184DETRAY_HOST_DEVICE const auto &get(const detray::tuple<T, Ts...> &t) noexcept {
185 if constexpr (std::is_same_v<U, T>) {
186 return t.v;
187 } else if constexpr (sizeof...(Ts) > 0) {
188 static_assert((std::is_same_v<U, Ts> || ...), "Type not found in tuple.");
189 return ::detray::get<U, Ts...>(t.r);
190 }
191}
192
197template <typename U, typename T, typename... Ts>
198DETRAY_HOST_DEVICE auto &get(detray::tuple<T, Ts...> &t) noexcept {
199 if constexpr (std::is_same_v<U, T>) {
200 return t.v;
201 } else if constexpr (sizeof...(Ts) > 0) {
202 static_assert((std::is_same_v<U, Ts> || ...), "Type not found in tuple.");
203 return ::detray::get<U, Ts...>(t.r);
204 }
205}
206
210template <typename... Ts>
211DETRAY_HOST_DEVICE constexpr detray::tuple<Ts &...> tie(Ts &...args) {
212 return detray::tuple<Ts &...>(args...);
213}
214
218template <typename... Ts>
219DETRAY_HOST_DEVICE constexpr detray::tuple<std::decay_t<Ts>...> make_tuple(
220 Ts &&...vs) {
221 return detray::tuple<std::decay_t<Ts>...>(std::forward<Ts>(vs)...);
222}
223
228template <typename T1, typename T2>
229DETRAY_HOST_DEVICE constexpr detray::pair<std::decay_t<T1>, std::decay_t<T2>>
230make_pair(T1 &&v1, T2 &&v2) {
231 return detray::pair<std::decay_t<T1>, std::decay_t<T2>>(std::forward<T1>(v1),
232 std::forward<T2>(v2));
233}
234} // namespace detray
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
const auto & get(const detray::tuple< Ts... > &t) noexcept
Get a tuple element by index from a const tuple.
Definition tuple.hpp:152
tuple< T1, T2 > pair
A two-element tuple alias.
Definition tuple.hpp:145
constexpr detray::tuple< Ts &... > tie(Ts &...args)
Create a tuple of references to the supplied objects.
Definition tuple.hpp:211
constexpr detray::pair< std::decay_t< T1 >, std::decay_t< T2 > > make_pair(T1 &&v1, T2 &&v2)
Construct a pair by decaying and forwarding its two arguments.
Definition tuple.hpp:230
constexpr tuple(U &&_v, Us &&..._r)
Construct the tuple elements from individual values.
Definition tuple.hpp:85
constexpr tuple(const tuple &o)=default
Copy construct this tuple when every element is copy constructible.
constexpr tuple(tuple &&o) noexcept=default
Move construct this tuple when every element is movable.
tuple< Ts... > r
Remaining tuple elements.
Definition tuple.hpp:140
constexpr tuple()=default
Default construct the recursive tuple node when all elements allow it.
constexpr tuple & operator=(tuple &&other) noexcept=default
Move assign this tuple when all elements are movable.
constexpr tuple & operator=(tuple< U, Us... > &&other)
Move assign from a tuple with compatible element types.
Definition tuple.hpp:127
T v
Value stored in this tuple node.
Definition tuple.hpp:136
constexpr tuple(const tuple< U, Us... > &o)
Construct from a tuple with element types convertible to this tuple.
Definition tuple.hpp:55
constexpr tuple(tuple< U, Us... > &&o)
Move construct from a tuple with compatible element types.
Definition tuple.hpp:72
Default tuple type.
Definition tuple.hpp:26