File indexing completed on 2026-05-27 07:24:06
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012 #include "detray/definitions/detail/qualifiers.hpp"
0013
0014
0015 #include <type_traits>
0016 #include <utility>
0017
0018 namespace detray {
0019
0020 template <typename... Ts>
0021 struct tuple {};
0022
0023 template <typename T, typename... Ts>
0024 struct tuple<T, Ts...> {
0025 constexpr tuple() = default;
0026
0027 constexpr tuple(const tuple &o)
0028 requires(std::is_copy_constructible_v<T> &&
0029 (std::is_copy_constructible_v<Ts> && ...))
0030 = default;
0031
0032 template <typename U, typename... Us>
0033 requires std::is_constructible_v<T, U &&> &&
0034 std::is_constructible_v<tuple<Ts...>, Us &&...>
0035 DETRAY_HOST_DEVICE explicit constexpr tuple(const tuple<U, Us...> &o)
0036 : v(o.v), r(o.r) {}
0037
0038 constexpr tuple(tuple &&o) noexcept
0039 requires(std::is_move_constructible_v<T> &&
0040 (std::is_move_constructible_v<Ts> && ...))
0041 = default;
0042
0043 template <typename U, typename... Us>
0044 requires std::is_constructible_v<T, U &&> &&
0045 std::is_constructible_v<tuple<Ts...>, Us &&...>
0046 DETRAY_HOST_DEVICE explicit constexpr tuple(tuple<U, Us...> &&o)
0047 : v(std::move(o.v)), r(std::move(o.r)) {}
0048
0049 template <typename U, typename... Us>
0050 requires std::is_constructible_v<T, U &&> &&
0051 std::is_constructible_v<tuple<Ts...>, Us &&...> &&
0052 (!(std::is_same_v<tuple, U> ||
0053 (std::is_same_v<tuple, Us> || ...)))
0054 DETRAY_HOST_DEVICE explicit constexpr tuple(U &&_v, Us &&..._r)
0055 : v(std::forward<U>(_v)), r(std::forward<Us>(_r)...) {}
0056
0057 constexpr ~tuple() noexcept = default;
0058
0059 constexpr tuple &operator=(const tuple &other)
0060 requires(std::is_copy_assignable_v<T> &&
0061 (std::is_copy_assignable_v<Ts> && ...))
0062 = default;
0063
0064 template <typename U, typename... Us>
0065 DETRAY_HOST_DEVICE constexpr tuple &operator=(const tuple<U, Us...> &other)
0066 requires(std::is_assignable_v<T &, const U &> &&
0067 (std::is_assignable_v<Ts &, const Us &> && ...))
0068 {
0069 v = other.v;
0070 r = other.r;
0071 return *this;
0072 }
0073
0074 constexpr tuple &operator=(tuple &&other) noexcept
0075 requires(std::is_move_assignable_v<T> &&
0076 (std::is_move_assignable_v<Ts> && ...))
0077 = default;
0078
0079 template <typename U, typename... Us>
0080 DETRAY_HOST_DEVICE constexpr tuple &operator=(tuple<U, Us...> &&other)
0081 requires(std::is_assignable_v<T &, U> &&
0082 (std::is_assignable_v<Ts &, Us> && ...))
0083 {
0084 v = std::move(other.v);
0085 r = std::move(other.r);
0086 return *this;
0087 }
0088
0089 T v;
0090 tuple<Ts...> r{};
0091 };
0092
0093 template <typename T1, typename T2>
0094 using pair = tuple<T1, T2>;
0095
0096 template <std::size_t I, typename... Ts>
0097 DETRAY_HOST_DEVICE const auto &get(const detray::tuple<Ts...> &t) noexcept {
0098 static_assert(I < sizeof...(Ts),
0099 "Attempt to access index greater than tuple size.");
0100
0101 if constexpr (I == 0) {
0102 return t.v;
0103 } else {
0104 return ::detray::get<I - 1>(t.r);
0105 }
0106 }
0107
0108 template <std::size_t I, typename... Ts>
0109 DETRAY_HOST_DEVICE auto &get(detray::tuple<Ts...> &t) noexcept {
0110 static_assert(I < sizeof...(Ts),
0111 "Attempt to access index greater than tuple size.");
0112
0113 if constexpr (I == 0) {
0114 return t.v;
0115 } else {
0116 return ::detray::get<I - 1>(t.r);
0117 }
0118 }
0119
0120 template <typename U, typename T, typename... Ts>
0121 DETRAY_HOST_DEVICE const auto &get(const detray::tuple<T, Ts...> &t) noexcept {
0122 if constexpr (std::is_same_v<U, T>) {
0123 return t.v;
0124 } else if constexpr (sizeof...(Ts) > 0) {
0125 static_assert((std::is_same_v<U, Ts> || ...), "Type not found in tuple.");
0126 return ::detray::get<U, Ts...>(t.r);
0127 }
0128 }
0129
0130 template <typename U, typename T, typename... Ts>
0131 DETRAY_HOST_DEVICE auto &get(detray::tuple<T, Ts...> &t) noexcept {
0132 if constexpr (std::is_same_v<U, T>) {
0133 return t.v;
0134 } else if constexpr (sizeof...(Ts) > 0) {
0135 static_assert((std::is_same_v<U, Ts> || ...), "Type not found in tuple.");
0136 return ::detray::get<U, Ts...>(t.r);
0137 }
0138 }
0139
0140 template <typename... Ts>
0141 DETRAY_HOST_DEVICE constexpr detray::tuple<Ts &...> tie(Ts &...args) {
0142 return detray::tuple<Ts &...>(args...);
0143 }
0144
0145 template <typename... Ts>
0146 DETRAY_HOST_DEVICE constexpr detray::tuple<std::decay_t<Ts>...> make_tuple(
0147 Ts &&...vs) {
0148 return detray::tuple<std::decay_t<Ts>...>(std::forward<Ts>(vs)...);
0149 }
0150
0151 template <typename T1, typename T2>
0152 DETRAY_HOST_DEVICE constexpr detray::pair<std::decay_t<T1>, std::decay_t<T2>>
0153 make_pair(T1 &&v1, T2 &&v2) {
0154 return detray::pair<std::decay_t<T1>, std::decay_t<T2>>(std::forward<T1>(v1),
0155 std::forward<T2>(v2));
0156 }
0157 }