Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-27 07:24:06

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 // Project include(s)
0012 #include "detray/definitions/detail/qualifiers.hpp"
0013 #include "detray/utils/tuple.hpp"
0014 #include "detray/utils/type_traits.hpp"
0015 
0016 // System include(s)
0017 #include <limits>
0018 #include <tuple>
0019 #include <type_traits>
0020 #include <utility>
0021 
0022 namespace detray::detail {
0023 
0024 /// get function accessor for std::tuple
0025 ///
0026 /// usage example:
0027 /// detail::get<0>(tuple)
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 /// tuple_element for std::tuple
0057 ///
0058 /// usage example:
0059 /// detail::tuple_element< int, tuple_t >::type
0060 /// @{
0061 template <std::size_t N, class T>
0062 struct tuple_element;
0063 
0064 // std::tuple
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 // detray::dtuple
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 /// tuple_size for std::tuple
0081 ///
0082 /// usage example:
0083 /// detail::tuple_size< tuple_t >::value
0084 /// @{
0085 template <class T>
0086 struct tuple_size;
0087 
0088 // std::tuple
0089 template <typename... value_types>
0090 struct tuple_size<std::tuple<value_types...>>
0091     : std::tuple_size<std::tuple<value_types...>> {};
0092 
0093 // detray::dtuple
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 /// make_tuple for std::tuple
0104 /// users have to specify tuple_t for detail::make_tuple
0105 ///
0106 /// usage example
0107 /// detail::make_tuple<tuple_t>(args...)
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 // make_tuple for std::tuple
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 // make_tuple for detray::dtuple
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 /// Check if the tuple contains a type
0142 /// @see
0143 /// https://stackoverflow.com/questions/25958259/how-do-i-find-out-if-a-tuple-contains-a-type
0144 /// @{
0145 template <typename T, typename tuple_t>
0146 struct has_type;
0147 
0148 // std::tuple
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 // detray::dtuple
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 /// Concatenate tuple types
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 /// Remove duplicate types from tuple
0206 /// @{
0207 template <std::size_t I, typename... tuple_ts>
0208 struct unique_types {};
0209 
0210 /// No elements in tuple
0211 template <std::size_t I>
0212 struct unique_types<I, std::tuple<>> {
0213   using type = std::tuple<>;
0214 };
0215 
0216 /// Recursively check for duplicate entries in the tuple and remove them
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 /// All elements have been checked
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 /// Check for equality of tuple types modulo permutation
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 /// Check trait on ever element of the tuple
0291 /// @{
0292 
0293 // Any
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 // All
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 }  // namespace detray::detail