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 #include "detray/utils/tuple.hpp"
0014 #include "detray/utils/type_traits.hpp"
0015
0016
0017 #include <limits>
0018 #include <tuple>
0019 #include <type_traits>
0020 #include <utility>
0021
0022 namespace detray::detail {
0023
0024
0025
0026
0027
0028
0029 using std::get;
0030
0031 template <std::size_t I, typename... value_types>
0032 DETRAY_HOST_DEVICE constexpr decltype(auto) get(
0033 const ::detray::dtuple<value_types...>& tuple) noexcept {
0034 return ::detray::get<I>(tuple);
0035 }
0036
0037 template <std::size_t I, typename... value_types>
0038 DETRAY_HOST_DEVICE constexpr decltype(auto) get(
0039 ::detray::dtuple<value_types...>& tuple) noexcept {
0040 return ::detray::get<I>(tuple);
0041 }
0042
0043 template <typename query_t, typename... value_types>
0044 DETRAY_HOST_DEVICE constexpr decltype(auto) get(
0045 const ::detray::dtuple<value_types...>& tuple) noexcept {
0046 return ::detray::get<get_type_pos_v<query_t, value_types...>>(tuple);
0047 }
0048
0049 template <typename query_t, typename... value_types>
0050 DETRAY_HOST_DEVICE constexpr decltype(auto) get(
0051 ::detray::dtuple<value_types...>& tuple) noexcept {
0052 return ::detray::get<get_type_pos_v<query_t, value_types...>>(tuple);
0053 }
0054
0055
0056
0057
0058
0059
0060
0061 template <std::size_t N, class T>
0062 struct tuple_element;
0063
0064
0065 template <std::size_t N, typename... value_types>
0066 struct tuple_element<N, std::tuple<value_types...>>
0067 : std::tuple_element<N, std::tuple<value_types...>> {};
0068
0069
0070 template <std::size_t N, typename... value_types>
0071 struct tuple_element<N, detray::dtuple<value_types...>> {
0072 using type = std::decay_t<decltype(::detray::get<N>(
0073 std::declval<detray::dtuple<value_types...>>()))>;
0074 };
0075
0076 template <std::size_t N, class T>
0077 using tuple_element_t = typename tuple_element<N, T>::type;
0078
0079
0080
0081
0082
0083
0084
0085 template <class T>
0086 struct tuple_size;
0087
0088
0089 template <typename... value_types>
0090 struct tuple_size<std::tuple<value_types...>>
0091 : std::tuple_size<std::tuple<value_types...>> {};
0092
0093
0094 template <typename... value_types>
0095 struct tuple_size<::detray::dtuple<value_types...>> {
0096 static constexpr std::size_t value = sizeof...(value_types);
0097 };
0098
0099 template <class T>
0100 constexpr std::size_t tuple_size_v{tuple_size<T>::value};
0101
0102
0103
0104
0105
0106
0107
0108
0109 template <class T>
0110 struct unwrap_refwrapper {
0111 using type = T;
0112 };
0113
0114 template <class T>
0115 struct unwrap_refwrapper<std::reference_wrapper<T>> {
0116 using type = T&;
0117 };
0118
0119 template <class T>
0120 using unwrap_decay_t = typename unwrap_refwrapper<std::decay_t<T>>::type;
0121
0122
0123 template <template <typename...> class tuple_t, class... value_types>
0124 requires std::is_same_v<tuple_t<value_types...>, std::tuple<value_types...>>
0125 DETRAY_HOST constexpr std::tuple<unwrap_decay_t<value_types>...> make_tuple(
0126 value_types&&... args) {
0127 return std::make_tuple(std::forward<value_types>(args)...);
0128 }
0129
0130
0131 template <template <typename...> class tuple_t, class... value_types>
0132 requires std::is_same_v<tuple_t<value_types...>,
0133 detray::dtuple<value_types...>>
0134 DETRAY_HOST_DEVICE constexpr detray::dtuple<unwrap_decay_t<value_types>...>
0135 make_tuple(value_types&&... args) {
0136 return detray::dtuple<unwrap_decay_t<value_types>...>{
0137 std::forward<value_types>(args)...};
0138 }
0139
0140
0141
0142
0143
0144
0145 template <typename T, typename tuple_t>
0146 struct has_type;
0147
0148
0149 template <typename T>
0150 struct has_type<T, std::tuple<>> : std::false_type {};
0151
0152 template <typename T, typename U, typename... Ts>
0153 struct has_type<T, std::tuple<U, Ts...>> : has_type<T, std::tuple<Ts...>> {};
0154
0155 template <typename T, typename... Ts>
0156 struct has_type<T, std::tuple<T, Ts...>> : std::true_type {};
0157
0158
0159 template <typename T>
0160 struct has_type<T, detray::dtuple<>> : std::false_type {};
0161
0162 template <typename T, typename U, typename... Ts>
0163 struct has_type<T, detray::dtuple<U, Ts...>>
0164 : has_type<T, detray::dtuple<Ts...>> {};
0165
0166 template <typename T, typename... Ts>
0167 struct has_type<T, detray::dtuple<T, Ts...>> : std::true_type {};
0168
0169 template <typename T, class tuple_t>
0170 constexpr bool has_type_v = has_type<T, tuple_t>::value;
0171
0172
0173
0174
0175 template <typename... tuple_ts>
0176 struct tuple_cat_type {};
0177
0178 template <typename... Args>
0179 struct tuple_cat_type<std::tuple<Args...>> {
0180 using type = std::tuple<Args...>;
0181 };
0182
0183 template <typename... Args1, typename... Args2, typename... tuple_ts>
0184 struct tuple_cat_type<std::tuple<Args1...>, std::tuple<Args2...>, tuple_ts...> {
0185 using type = typename tuple_cat_type<std::tuple<Args1..., Args2...>,
0186 tuple_ts...>::type;
0187 };
0188
0189 template <typename... Args>
0190 struct tuple_cat_type<detray::dtuple<Args...>> {
0191 using type = detray::dtuple<Args...>;
0192 };
0193
0194 template <typename... Args1, typename... Args2, typename... tuple_ts>
0195 struct tuple_cat_type<detray::dtuple<Args1...>, detray::dtuple<Args2...>,
0196 tuple_ts...> {
0197 using type = typename tuple_cat_type<detray::dtuple<Args1..., Args2...>,
0198 tuple_ts...>::type;
0199 };
0200
0201 template <typename... tuple_ts>
0202 using tuple_cat_t = typename tuple_cat_type<tuple_ts...>::type;
0203
0204
0205
0206
0207 template <std::size_t I, typename... tuple_ts>
0208 struct unique_types {};
0209
0210
0211 template <std::size_t I>
0212 struct unique_types<I, std::tuple<>> {
0213 using type = std::tuple<>;
0214 };
0215
0216
0217 template <std::size_t I, typename Arg1, typename... Args>
0218 struct unique_types<I, std::tuple<Arg1, Args...>> {
0219 using type = std::conditional_t<
0220 has_type_v<Arg1, std::tuple<Args...>>,
0221 typename unique_types<I - 1u, std::tuple<Args...>>::type,
0222 typename unique_types<I - 1u, std::tuple<Args..., Arg1>>::type>;
0223 };
0224
0225
0226 template <typename Arg1, typename... Args>
0227 struct unique_types<0u, std::tuple<Arg1, Args...>> {
0228 using type = std::tuple<Arg1, Args...>;
0229 };
0230
0231 template <std::size_t I>
0232 struct unique_types<I, detray::dtuple<>> {
0233 using type = detray::dtuple<>;
0234 };
0235
0236 template <std::size_t I, typename Arg1, typename... Args>
0237 struct unique_types<I, detray::dtuple<Arg1, Args...>> {
0238 using type = std::conditional_t<
0239 has_type_v<Arg1, detray::dtuple<Args...>>,
0240 typename unique_types<I - 1u, detray::dtuple<Args...>>::type,
0241 typename unique_types<I - 1u, detray::dtuple<Args..., Arg1>>::type>;
0242 };
0243
0244 template <typename Arg1, typename... Args>
0245 struct unique_types<0u, detray::dtuple<Arg1, Args...>> {
0246 using type = detray::dtuple<Arg1, Args...>;
0247 };
0248
0249 template <typename tuple_t>
0250 using unique_t =
0251 typename unique_types<tuple_size_v<tuple_t> - 1u, tuple_t>::type;
0252
0253
0254
0255
0256 template <typename T1, typename T2>
0257 struct is_permutation : public std::false_type {};
0258
0259 template <>
0260 struct is_permutation<detray::dtuple<>, detray::dtuple<>>
0261 : public std::true_type {};
0262
0263 template <typename... Args1, typename... Args2>
0264 struct is_permutation<detray::dtuple<Args1...>, detray::dtuple<Args2...>> {
0265 using T1 = detray::dtuple<Args1...>;
0266 using T2 = detray::dtuple<Args2...>;
0267
0268 template <typename o_tuple_t, typename T, typename... U>
0269 static consteval bool compare() {
0270 if constexpr (detray::detail::has_type_v<T, o_tuple_t>) {
0271 if constexpr (sizeof...(U) == 0u) {
0272 return true;
0273 } else {
0274 return compare<o_tuple_t, U...>();
0275 }
0276 } else {
0277 return false;
0278 }
0279 }
0280
0281 static constexpr bool value =
0282 ((detray::detail::tuple_size_v<T1> == detray::detail::tuple_size_v<T2>) &&
0283 (compare<T1, Args2...>() && compare<T2, Args1...>()));
0284 };
0285
0286 template <typename T1, typename T2>
0287 constexpr bool is_permutation_v = is_permutation<T1, T2>::value;
0288
0289
0290
0291
0292
0293
0294 template <template <typename...> class trait, typename tuple_t>
0295 struct tuple_any {};
0296
0297 template <template <typename...> class trait, typename... Args>
0298 struct tuple_any<trait, std::tuple<Args...>> {
0299 static constexpr bool value = (trait<Args>::value || ...);
0300 };
0301 template <template <typename...> class trait, typename... Args>
0302 struct tuple_any<trait, detray::dtuple<Args...>> {
0303 static constexpr bool value = (trait<Args>::value || ...);
0304 };
0305
0306 template <template <typename...> class trait, typename tuple_t>
0307 constexpr bool tuple_any_v = tuple_any<trait, tuple_t>::value;
0308
0309
0310 template <template <typename...> class trait, typename tuple_t>
0311 struct tuple_all {};
0312
0313 template <template <typename...> class trait, typename... Args>
0314 struct tuple_all<trait, std::tuple<Args...>> {
0315 static constexpr bool value = (trait<Args>::value && ...);
0316 };
0317 template <template <typename...> class trait, typename... Args>
0318 struct tuple_all<trait, detray::dtuple<Args...>> {
0319 static constexpr bool value = (trait<Args>::value && ...);
0320 };
0321
0322 template <template <typename...> class trait, typename tuple_t>
0323 constexpr bool tuple_all_v = tuple_all<trait, tuple_t>::value;
0324
0325
0326
0327 }