27struct VctrBaseInspector
31template <
class E,
class S,
size_t e,
class I>
32struct VctrBaseInspector<VctrBase<E, S, e, I>>
34 using ElementType = E;
35 using StorageType = S;
39struct ExpressionInspector
43template <
template <size_t,
class...>
class Expression,
size_t e,
class S>
44struct ExpressionInspector<Expression<e, S>>
46 using ReturnType =
typename Expression<e, S>::value_type;
49 static constexpr size_t numSources = 1;
50 static constexpr size_t extent = e;
53template <
template <size_t,
class...>
class Expression,
size_t e,
class SA,
class SB>
54struct ExpressionInspector<Expression<e, SA, SB>>
56 using ReturnType =
typename Expression<e, SA, SB>::value_type;
57 using SourceTypeA = SA;
58 using SourceTypeB = SB;
60 static constexpr size_t numSources = 2;
61 static constexpr size_t extent = e;
64template <
template <size_t,
class...>
class Expression,
size_t e,
class... S>
65requires (
sizeof...(S) > 2)
66struct ExpressionInspector<Expression<e, S...>>
68 using ReturnType =
typename Expression<e, S...>::value_type;
70 static constexpr size_t numSources =
sizeof...(S);
71 static constexpr size_t extent = e;
77 using Type =
typename T::value_type;
80template <has::size StorageType>
83 static constexpr size_t value = std::dynamic_extent;
86template <
class T,
size_t extent>
87struct Extent<std::array<T, extent>>
89 static constexpr size_t value = extent;
92template <
class T,
size_t extent>
93struct Extent<std::span<T, extent>>
95 static constexpr size_t value = extent;
98template <
class E,
class S,
size_t extent,
class I>
99struct Extent<VctrBase<E, S, extent, I>>
101 static constexpr size_t value = extent;
104template <
class T,
size_t extent,
size_t s>
105struct Extent<Array<T, extent, s>>
107 static constexpr size_t value = extent;
110template <
class T,
size_t extent,
class S>
111struct Extent<Span<T, extent, S>>
113 static constexpr size_t value = extent;
116template <is::expression T>
119 static constexpr size_t value = ExpressionInspector<T>::extent;
138template <std::
integral T>
141 using Type = std::conditional_t<
sizeof (T) < 4,
float,
double>;
144template <std::
floating_po
int T>
153 using Type = StorageInfo<T>;
156template <is::anyVctr T>
159 using Type = std::remove_cvref_t<std::invoke_result_t<
decltype (&T::getStorageInfo),
const T>>;
168struct RemovePointer<T*>
174struct RemovePointer<T*
const>
176 using Type =
const T;
179template <has::data T>
184 VCTR_START_IGNORE_WARNING_CLANG (
return-stack-address)
185 static auto* invokeData (T t) {
return t.data(); }
186 VCTR_END_IGNORE_WARNING_CLANG
189 using Type =
typename RemovePointer<std::invoke_result_t<
decltype (&DataType::invokeData), T>>::Type;
201using ValueType =
typename detail::ValueType<std::remove_cvref_t<T>>::Type;
205using DataType =
typename detail::DataType<std::remove_reference_t<T>>::Type;
210template <is::number T>
211using RealType =
typename detail::RealType<std::remove_cvref_t<T>>::Type;
218template <is::realNumber T>
219using FloatType =
typename detail::FloatType<std::remove_cvref_t<T>>::Type;
226template <has::sizeAndData T>
227using StorageInfoType =
typename detail::StorageInfoType<std::remove_cvref_t<T>>::Type;
230template <has::size T>
231constexpr size_t extentOf = detail::Extent<std::remove_cvref_t<T>>::value;
237template <
class A,
class B>
240 if constexpr (extentOf<A> == std::dynamic_extent && extentOf<B> == std::dynamic_extent)
241 return std::dynamic_extent;
243 if constexpr (extentOf<A> != std::dynamic_extent && extentOf<B> != std::dynamic_extent && extentOf<A> != extentOf<B>)
244 throw std::logic_error (
"A and B both define different non-dynamic extents");
246 return extentOf<A> != std::dynamic_extent ? extentOf<A> : extentOf<B>;
252template <
class A,
class B>
255 if constexpr (extentOf<A> == std::dynamic_extent || extentOf<B> == std::dynamic_extent)
257 VCTR_ASSERT (a.size() == b.size());
261 static_assert (extentOf<A> == extentOf<B>);
The main namespace of the VCTR project.
Definition: Array.h:24
constexpr size_t extentOf
Equals the extent of the container or expression type.
Definition: Traits.h:231
typename detail::StorageInfoType< std::remove_cvref_t< T > >::Type StorageInfoType
If t is a type derived from VctrBase, this will equal the return value of T::getStorageInfo,...
Definition: Traits.h:227
consteval size_t getCommonExtent()
Returns std::dynamic_extent in case both sources specify a dynamic extent.
Definition: Traits.h:238
constexpr void assertCommonSize(const A &a, const B &b)
Ensures that both sources have the same size.
Definition: Traits.h:253
typename detail::ValueType< std::remove_cvref_t< T > >::Type ValueType
If T is an expression template, it equals its return type, if it's a type that defines value_type as ...
Definition: Traits.h:201
typename detail::FloatType< std::remove_cvref_t< T > >::Type FloatType
The best matching float type for the real number type T.
Definition: Traits.h:219
typename detail::RealType< std::remove_cvref_t< T > >::Type RealType
If T is any instance of std::complex, this will be the real value_type, otherwise this will be T.
Definition: Traits.h:211
typename detail::DataType< std::remove_reference_t< T > >::Type DataType
The const correct element type derived from a call to T::data.
Definition: Traits.h:205
A helper struct intended to check if a value is a constexpr.
Definition: Traits.h:279