File indexing completed on 2026-05-27 07:23:55
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012 #include "detray/algebra/type_traits.hpp"
0013
0014
0015 #include <concepts>
0016
0017 namespace detray::concepts {
0018
0019
0020 template <typename T>
0021 concept arithmetic = std::is_arithmetic_v<T>;
0022
0023 template <typename T>
0024 concept arithmetic_cvref = concepts::arithmetic<std::remove_cvref_t<T>>;
0025
0026
0027 template <typename T>
0028 concept enumeration = std::is_enum_v<T>;
0029
0030
0031 template <typename T>
0032 concept value = concepts::arithmetic<std::decay_t<T>>;
0033
0034
0035 template <typename T>
0036 concept element = concepts::value<T> || concepts::enumeration<std::decay_t<T>>;
0037
0038
0039 template <typename T>
0040 concept scalar =
0041 !traits::is_matrix<T> && !traits::is_vector<T> && requires(T a, T b) {
0042 { a + b } -> std::convertible_to<T>;
0043 { a - b } -> std::convertible_to<T>;
0044 { a * b } -> std::convertible_to<T>;
0045 { a / b } -> std::convertible_to<T>;
0046 };
0047
0048
0049 template <typename T>
0050 concept simd_scalar = scalar<T> && !std::is_scalar_v<T>;
0051
0052
0053 template <typename T>
0054 concept index = std::is_integral_v<T> && !std::same_as<T, bool>;
0055
0056
0057
0058 template <typename V>
0059 concept vector = traits::is_vector<V>;
0060
0061 template <typename V>
0062 concept vector2D = vector<V> && (traits::size<V> == 2);
0063
0064 template <typename V>
0065 concept vector3D = vector<V> && (traits::size<V> == 3);
0066
0067
0068
0069
0070 template <typename V>
0071 concept point = vector<V>;
0072
0073 template <typename V>
0074 concept point2D = point<V> && (traits::size<V> == 2);
0075
0076 template <typename V>
0077 concept point3D = point<V> && (traits::size<V> == 3);
0078
0079
0080
0081
0082 template <typename M>
0083 concept matrix = traits::is_matrix<M>;
0084
0085 template <typename M>
0086 concept square_matrix = matrix<M> && traits::is_square<M>;
0087
0088 template <typename M>
0089 concept row_matrix = matrix<M> && (traits::rows<M> == 1);
0090
0091 template <typename M>
0092 concept row_matrix3D = row_matrix<M> && (traits::rows<M> == 3);
0093
0094 template <typename M>
0095 concept column_matrix = matrix<M> && (traits::columns<M> == 1);
0096
0097 template <typename M>
0098 concept column_matrix3D = column_matrix<M> && (traits::rows<M> == 3);
0099
0100 template <typename MA, typename MB>
0101 concept matrix_compatible =
0102 matrix<MA> && matrix<MB> &&
0103 std::convertible_to<traits::index_t<MA>, traits::index_t<MB>> &&
0104 std::convertible_to<traits::index_t<MB>, traits::index_t<MA>>;
0105
0106 template <typename MA, typename MB>
0107 concept matrix_multipliable =
0108 matrix_compatible<MA, MB> && (traits::columns<MA> == traits::rows<MB>) &&
0109 requires(traits::scalar_t<MA> sa, traits::scalar_t<MB> sb) {
0110 { (sa * sb) + (sa * sb) };
0111 };
0112
0113 template <typename MA, typename MB, typename MC>
0114 concept matrix_multipliable_into =
0115 matrix_multipliable<MA, MB> && matrix_compatible<MA, MC> &&
0116 matrix_compatible<MB, MC> && (traits::rows<MC> == traits::rows<MA>) &&
0117 (traits::columns<MC> == traits::columns<MB>) &&
0118 requires(traits::scalar_t<MA> sa, traits::scalar_t<MB> sb,
0119 traits::scalar_t<MC>& sc) {
0120 { sc += (sa * sb) };
0121 };
0122
0123
0124
0125 template <typename T>
0126 concept transform3D = requires(T trf) {
0127
0128 requires scalar<typename T::scalar_type>;
0129 requires vector3D<typename T::vector3>;
0130 requires point2D<typename T::point2>;
0131 requires point3D<typename T::point3>;
0132
0133
0134 trf.rotation();
0135 trf.translation();
0136 trf.point_to_global(typename T::vector3());
0137 trf.point_to_local(typename T::vector3());
0138 trf.vector_to_global(typename T::vector3());
0139 trf.vector_to_local(typename T::vector3());
0140 };
0141
0142
0143 template <typename A>
0144 concept algebra = (concepts::value<typename A::value_type> &&
0145 concepts::scalar<typename A::scalar> &&
0146 concepts::index<typename A::index_type> &&
0147 concepts::vector3D<typename A::vector3D> &&
0148 concepts::point2D<typename A::point2D> &&
0149 concepts::point3D<typename A::point3D> &&
0150 concepts::transform3D<typename A::transform3D> &&
0151 concepts::matrix<typename A::template matrix<3, 3>>);
0152
0153
0154
0155 template <typename A>
0156 concept soa = (!concepts::arithmetic<get_scalar_t<A>>);
0157
0158 template <typename A>
0159 concept aos = (!concepts::soa<A>);
0160
0161
0162
0163
0164 template <typename M>
0165 concept has_compile_time_2d_access = requires(const M& m) {
0166 { m.template element<0, 0>() };
0167 };
0168
0169 template <typename V>
0170 concept has_compile_time_1d_access = requires(const V& v) {
0171 { v.template element<0>() };
0172 };
0173
0174 }