VCTR
Loading...
Searching...
No Matches
Traits.h
1/*
2 ==============================================================================
3 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
5 Copyright 2022- by sonible GmbH.
6
7 This file is part of VCTR - Versatile Container Templates Reconceptualized.
8
9 VCTR is free software: you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License version 3
11 only, as published by the Free Software Foundation.
12
13 VCTR is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Lesser General Public License version 3 for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 version 3 along with VCTR. If not, see <https://www.gnu.org/licenses/>.
20 ==============================================================================
21*/
22
23namespace vctr::detail
24{
25
26template <class T>
27struct VctrBaseInspector
28{
29};
30
31template <class E, class S, size_t e, class I>
32struct VctrBaseInspector<VctrBase<E, S, e, I>>
33{
34 using ElementType = E;
35 using StorageType = S;
36};
37
38template <class T>
39struct ExpressionInspector
40{
41};
42
43template <template <size_t, class...> class Expression, size_t e, class S>
44struct ExpressionInspector<Expression<e, S>>
45{
46 using ReturnType = typename Expression<e, S>::value_type;
47 using SourceType = S;
48
49 static constexpr size_t numSources = 1;
50 static constexpr size_t extent = e;
51};
52
53template <template <size_t, class...> class Expression, size_t e, class SA, class SB>
54struct ExpressionInspector<Expression<e, SA, SB>>
55{
56 using ReturnType = typename Expression<e, SA, SB>::value_type;
57 using SourceTypeA = SA;
58 using SourceTypeB = SB;
59
60 static constexpr size_t numSources = 2;
61 static constexpr size_t extent = e;
62};
63
64template <template <size_t, class...> class Expression, size_t e, class... S>
65requires (sizeof...(S) > 2)
66struct ExpressionInspector<Expression<e, S...>>
67{
68 using ReturnType = typename Expression<e, S...>::value_type;
69
70 static constexpr size_t numSources = sizeof...(S);
71 static constexpr size_t extent = e;
72};
73
74template <class T>
75struct ValueType
76{
77 using Type = typename T::value_type;
78};
79
80template <has::size StorageType>
81struct Extent
82{
83 static constexpr size_t value = std::dynamic_extent;
84};
85
86template <class T, size_t extent>
87struct Extent<std::array<T, extent>>
88{
89 static constexpr size_t value = extent;
90};
91
92template <class T, size_t extent>
93struct Extent<std::span<T, extent>>
94{
95 static constexpr size_t value = extent;
96};
97
98template <class E, class S, size_t extent, class I>
99struct Extent<VctrBase<E, S, extent, I>>
100{
101 static constexpr size_t value = extent;
102};
103
104template <class T, size_t extent, size_t s>
105struct Extent<Array<T, extent, s>>
106{
107 static constexpr size_t value = extent;
108};
109
110template <class T, size_t extent, class S>
111struct Extent<Span<T, extent, S>>
112{
113 static constexpr size_t value = extent;
114};
115
116template <is::expression T>
117struct Extent<T>
118{
119 static constexpr size_t value = ExpressionInspector<T>::extent;
120};
121
122template <class T>
123struct RealType
124{
125 using Type = T;
126};
127
128template <class T>
129struct RealType<std::complex<T>>
130{
131 using Type = T;
132};
133
134template <class T>
135struct FloatType
136{};
137
138template <std::integral T>
139struct FloatType<T>
140{
141 using Type = std::conditional_t<sizeof (T) < 4, float, double>;
142};
143
144template <std::floating_point T>
145struct FloatType<T>
146{
147 using Type = T;
148};
149
150template <class T>
151struct StorageInfoType
152{
153 using Type = StorageInfo<T>;
154};
155
156template <is::anyVctr T>
157struct StorageInfoType<T>
158{
159 using Type = std::remove_cvref_t<std::invoke_result_t<decltype (&T::getStorageInfo), const T>>;
160};
161
162template <class T>
163struct RemovePointer
164{
165};
166
167template <class T>
168struct RemovePointer<T*>
169{
170 using Type = T;
171};
172
173template <class T>
174struct RemovePointer<T* const>
175{
176 using Type = const T;
177};
178
179template <has::data T>
180class DataType
181{
182private:
183 // This function is only used to deduce a return type, so we can safely ignore warnings about returning a stack address
184 VCTR_START_IGNORE_WARNING_CLANG (return-stack-address)
185 static auto* invokeData (T t) { return t.data(); }
186 VCTR_END_IGNORE_WARNING_CLANG
187
188public:
189 using Type = typename RemovePointer<std::invoke_result_t<decltype (&DataType::invokeData), T>>::Type;
190};
191
192} // namespace vctr::detail
193
194namespace vctr
195{
196
200template <class T>
201using ValueType = typename detail::ValueType<std::remove_cvref_t<T>>::Type;
202
204template <class T>
205using DataType = typename detail::DataType<std::remove_reference_t<T>>::Type;
206
210template <is::number T>
211using RealType = typename detail::RealType<std::remove_cvref_t<T>>::Type;
212
218template <is::realNumber T>
219using FloatType = typename detail::FloatType<std::remove_cvref_t<T>>::Type;
220
221
222
226template <has::sizeAndData T>
227using StorageInfoType = typename detail::StorageInfoType<std::remove_cvref_t<T>>::Type;
228
230template <has::size T>
231constexpr size_t extentOf = detail::Extent<std::remove_cvref_t<T>>::value;
232
237template <class A, class B>
238consteval size_t getCommonExtent()
239{
240 if constexpr (extentOf<A> == std::dynamic_extent && extentOf<B> == std::dynamic_extent)
241 return std::dynamic_extent;
242
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");
245
246 return extentOf<A> != std::dynamic_extent ? extentOf<A> : extentOf<B>;
247}
248
252template <class A, class B>
253constexpr void assertCommonSize ([[maybe_unused]] const A& a, [[maybe_unused]] const B& b)
254{
255 if constexpr (extentOf<A> == std::dynamic_extent || extentOf<B> == std::dynamic_extent)
256 {
257 VCTR_ASSERT (a.size() == b.size());
258 }
259 else
260 {
261 static_assert (extentOf<A> == extentOf<B>);
262 }
263}
264
278template <auto v>
280
281} // namespace vctr
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