cMHN 1.2
C++ library for learning MHNs with pRC
Loading...
Searching...
No Matches
subscripts.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-2-Clause
2
3#ifndef pRC_CORE_CONTAINER_SUBSCRIPTS_H
4#define pRC_CORE_CONTAINER_SUBSCRIPTS_H
5
14#include <prc/core/log/log.hpp>
15#include <prc/pragma.hpp>
16
17namespace pRC
18{
19 template<Size... Ns>
21 {
22 public:
23 using Sizes = pRC::Sizes<Ns...>;
24
25 static constexpr auto Dimension = Sizes::Dimension;
26
27 static constexpr auto size()
28 requires requires { Sizes::size(); }
29 {
30 return Sizes::size();
31 }
32
33 static constexpr auto size(Index const dimension)
34 {
35 return Sizes::size(dimension);
36 }
37
38 public:
39 ~Subscripts() = default;
40 constexpr Subscripts() = default;
41 constexpr Subscripts(Subscripts const &) = default;
42 constexpr Subscripts(Subscripts &&) = default;
43 constexpr Subscripts &operator=(Subscripts const &) & = default;
44 constexpr Subscripts &operator=(Subscripts &&) & = default;
45
46 template<IsConvertible<Index>... Ss>
47 requires(sizeof...(Ss) == Dimension)
48 explicit constexpr Subscripts(Ss const... subscripts)
49 : mSubscripts(subscripts...)
50 {
51 }
52
53 explicit constexpr Subscripts(Index const index)
54 requires(Dimension == 0)
55 {
56 check(index);
57 }
58
59 explicit constexpr Subscripts(Index const index)
60 requires(Dimension > 1) && requires { Sizes::size(); }
61 {
62 check(index);
63
64 expand(
66 [this](auto index, auto const... seq)
67 {
68 operator[](0) = index % size(0);
69 ((operator[](seq + 1) =
70 (index /= size(seq)) % size(seq + 1)),
71 ...);
72 },
73 index);
74 }
75
76 explicit constexpr operator Index() const
77 requires requires { Sizes::size(); }
78 {
79 if constexpr(cDebugLevel >= DebugLevel::Low)
80 {
81 if(isOutOfRange())
82 {
83 Logging::error("Subscripts out of range.");
84 }
85 }
86
87 return expand(
89 [](auto subscripts, auto const... seq)
90 {
91 [[maybe_unused]] Index scale = 1;
92 ((subscripts[seq] *= scale, scale *= size(seq)), ...);
93 return (subscripts[seq] + ... + 0);
94 },
95 mSubscripts);
96 }
97
98 constexpr decltype(auto) operator[](Index const dimension) &&
99 {
100 return move(mSubscripts)[dimension];
101 }
102
103 constexpr decltype(auto) operator[](Index const dimension) const &&
104 {
105 return move(mSubscripts)[dimension];
106 }
107
108 constexpr decltype(auto) operator[](Index const dimension) &
109 {
110 return mSubscripts[dimension];
111 }
112
113 constexpr decltype(auto) operator[](Index const dimension) const &
114 {
115 return mSubscripts[dimension];
116 }
117
118 constexpr bool operator<(const Subscripts &rhs) const
119 {
120 for(std::size_t i = Dimension; i > 0; --i)
121 {
122
123 auto lhsE = mSubscripts[i - 1];
124 auto rhsE = rhs[i - 1];
125 if(lhsE < rhsE)
126 {
127 return true;
128 }
129 if(lhsE > rhsE)
130 {
131 return false;
132 }
133 }
134 /*for(std::size_t dimension = 0; dimension < Dimension;
135 ++dimension)
136 {
137 if(mSubscripts[dimension] < rhs[dimension])
138 {
139 return true;
140 }
141 if(mSubscripts[dimension] > rhs[dimension])
142 {
143 return false;
144 }
145 }*/
146 return false;
147 }
148
149 constexpr auto isOutOfRange() const
150 {
152 [this](auto const... seq)
153 {
154 return !((this->operator[](seq) < size(seq)) && ...);
155 });
156 }
157
158 constexpr decltype(auto) periodize() &
159 {
160 return *this %= Sizes();
161 }
162
163 template<class X>
165 constexpr auto &operator+=(X &&rhs) &
166 {
167 return *this = *this + forward<X>(rhs);
168 }
169
170 template<class X>
172 constexpr auto &operator-=(X &&rhs) &
173 {
174 return *this = *this - forward<X>(rhs);
175 }
176
177 template<class X>
179 constexpr auto &operator*=(X &&rhs) &
180 {
181 return *this = *this * forward<X>(rhs);
182 }
183
184 template<class X>
186 constexpr auto &operator/=(X &&rhs) &
187 {
188 return *this = *this / forward<X>(rhs);
189 }
190
191 template<class X>
193 constexpr auto &operator%=(X &&rhs) &
194 {
195 return *this = *this % forward<X>(rhs);
196 }
197
198 private:
199 constexpr auto check([[maybe_unused]] Index const index)
200 {
201 if constexpr(cDebugLevel >= DebugLevel::Low)
202 {
203 if(!(index < size()))
204 {
205 Logging::error("Index out of range.");
206 }
207 }
208 }
209
210 private:
211 BEGIN_IGNORE_DIAGNOSTIC_GCC("-Wpedantic")
212 StackArray<Index, Dimension> mSubscripts = {};
214 };
215
216 template<class T>
217 concept IsSubscripts = !IsReference<T> && requires {
218 {
219 []<Size... Ns>(Subscripts<Ns...> const &&)
220 {
221 }(std::declval<T>())
222 };
223 };
224
225 template<Size... Ns>
226 static inline constexpr auto operator+(Subscripts<Ns...> const &lhs,
227 Subscripts<Ns...> const &rhs)
228 {
230 [&lhs, &rhs](auto const... seq)
231 {
232 return Subscripts<Ns...>((lhs[seq] + rhs[seq])...);
233 });
234 }
235
236 template<Size... Ns>
237 static inline constexpr auto operator-(Subscripts<Ns...> const &lhs,
238 Subscripts<Ns...> const &rhs)
239 {
241 [&lhs, &rhs](auto const... seq)
242 {
243 return Subscripts<Ns...>((lhs[seq] - rhs[seq])...);
244 });
245 }
246
247 template<Size... Ns, Size... Ss>
248 requires(sizeof...(Ns) == sizeof...(Ss))
249 static inline constexpr auto operator*(Subscripts<Ns...> const &lhs,
250 Sizes<Ss...> const)
251 {
253 [&lhs](auto const... seq)
254 {
255 return Subscripts<(
256 Sizes<Ns...>::size(seq) * Sizes<Ss...>::size(seq))...>(
257 (lhs[seq] * Sizes<Ss...>::size(seq))...);
258 });
259 }
260
261 template<Size... Ns, Size... Ss>
262 requires(sizeof...(Ns) == sizeof...(Ss))
263 static inline constexpr auto operator*(Sizes<Ss...> const,
264 Subscripts<Ns...> const &rhs)
265 {
266 return rhs * Sizes<Ss...>();
267 }
268
269 template<Size... Ns, Size... Ss>
270 requires(sizeof...(Ns) == sizeof...(Ss))
271 static inline constexpr auto operator/(Subscripts<Ns...> const &lhs,
272 Sizes<Ss...> const)
273 {
275 [&lhs](auto const... seq)
276 {
277 return Subscripts<(
278 Sizes<Ns...>::size(seq) / Sizes<Ss...>::size(seq))...>(
279 (lhs[seq] / Sizes<Ss...>::size(seq))...);
280 });
281 }
282
283 template<Size... Ns, Size... Ss>
284 requires(sizeof...(Ns) == sizeof...(Ss))
285 static inline constexpr auto operator%(Subscripts<Ns...> const &lhs,
286 Sizes<Ss...> const)
287 {
289 [&lhs](auto const... seq)
290 {
291 return Subscripts<Ss...>(
292 (lhs[seq] % Sizes<Ss...>::size(seq))...);
293 });
294 }
295
296 template<Size... Ns>
297 static inline constexpr auto operator==(Subscripts<Ns...> const &lhs,
298 Subscripts<Ns...> const &rhs)
299 {
301 [&lhs, &rhs](auto const... seq)
302 {
303 return ((lhs[seq] == rhs[seq]) && ...);
304 });
305 }
306
307 template<Size... Ns>
308 static inline constexpr auto operator!=(Subscripts<Ns...> const &lhs,
309 Subscripts<Ns...> const &rhs)
310 {
311 return !(lhs == rhs);
312 }
313
314 template<Index... Ps, Size... Ns>
315 requires requires { permute<Ps...>(makeSeriesFor<Index, Ns...>()); }
316 static inline constexpr auto permute(Subscripts<Ns...> const &arg)
317 {
319 [&arg](auto const... seq)
320 {
321 return Subscripts<Sizes<Ns...>::size(seq)...>(arg[seq]...);
322 });
323 }
324
325 template<Size... Ns>
326 static inline constexpr auto reverse(Subscripts<Ns...> const &arg)
327 {
329 [&arg](auto const... seq)
330 {
331 return permute<seq...>(arg);
332 });
333 }
334
335 template<Direction D, Size Step, Size... Ns>
336 requires requires { rotate<D, Step>(makeSeriesFor<Index, Ns...>()); }
337 static inline constexpr auto rotate(Subscripts<Ns...> const &arg)
338 {
340 [&arg](auto const... seq)
341 {
342 return permute<seq...>(arg);
343 });
344 }
345
346 template<Index... Ds, Size... Ns>
347 requires requires { chip<Ds...>(Sequence<Index, Ns...>()); }
348 static inline constexpr auto chip(Subscripts<Ns...> const &arg)
349 {
351 [&arg](auto const... seq)
352 {
353 return Subscripts<Sizes<Ns...>::size(seq)...>(arg[seq]...);
354 });
355 }
356}
357#endif // pRC_CORE_CONTAINER_SUBSCRIPTS_H
pRC::Size const D
Definition CalculatePThetaTests.cpp:9
Definition sequence.hpp:29
static constexpr Size Dimension
Definition sequence.hpp:47
static constexpr auto size()
Definition sequence.hpp:69
Definition subscripts.hpp:21
constexpr auto & operator%=(X &&rhs) &
Definition subscripts.hpp:193
constexpr Subscripts & operator=(Subscripts const &) &=default
constexpr decltype(auto) operator[](Index const dimension) &&
Definition subscripts.hpp:98
constexpr auto & operator+=(X &&rhs) &
Definition subscripts.hpp:165
static constexpr auto size()
Definition subscripts.hpp:27
constexpr auto isOutOfRange() const
Definition subscripts.hpp:149
constexpr Subscripts(Index const index)
Definition subscripts.hpp:53
constexpr Subscripts()=default
constexpr Subscripts & operator=(Subscripts &&) &=default
constexpr Subscripts(Ss const ... subscripts)
Definition subscripts.hpp:48
constexpr auto & operator*=(X &&rhs) &
Definition subscripts.hpp:179
constexpr auto & operator-=(X &&rhs) &
Definition subscripts.hpp:172
~Subscripts()=default
constexpr decltype(auto) periodize() &
Definition subscripts.hpp:158
constexpr Subscripts(Index const index)
Definition subscripts.hpp:59
static constexpr auto size(Index const dimension)
Definition subscripts.hpp:33
constexpr Subscripts(Subscripts &&)=default
constexpr Subscripts(Subscripts const &)=default
pRC::Sizes< Ns... > Sizes
Definition subscripts.hpp:23
static constexpr auto Dimension
Definition subscripts.hpp:25
constexpr bool operator<(const Subscripts &rhs) const
Definition subscripts.hpp:118
constexpr auto & operator/=(X &&rhs) &
Definition subscripts.hpp:186
Definition concepts.hpp:31
Definition concepts.hpp:19
Definition subscripts.hpp:217
int i
Definition gmock-matchers-comparisons_test.cc:603
static void error(Xs &&...args)
Definition log.hpp:14
Definition cholesky.hpp:10
static constexpr auto operator-(Sequence< T, As... > const, Sequence< T, Bs... > const)
Definition sequence.hpp:131
Size Index
Definition basics.hpp:32
std::size_t Size
Definition basics.hpp:31
static constexpr auto makeSeriesFor()
Definition sequence.hpp:399
static constexpr auto rotate(Sequence< T, Is... > const)
Definition sequence.hpp:506
static constexpr auto reverse(Direction const D)
Definition direction.hpp:24
static constexpr auto makeSeries()
Definition sequence.hpp:390
CommonArray< Allocation::Stack, T, Ns... > StackArray
Definition declarations.hpp:15
static constexpr auto chip(Sequence< T, Is... > const)
Definition sequence.hpp:584
static constexpr auto operator!=(JacobiRotation< TA > const &a, JacobiRotation< TB > const &b)
Definition jacobi_rotation.hpp:291
constexpr auto cDebugLevel
Definition config.hpp:48
static constexpr auto arg(T const &a)
Definition arg.hpp:11
static constexpr auto operator==(JacobiRotation< TA > const &a, JacobiRotation< TB > const &b)
Definition jacobi_rotation.hpp:284
static constexpr auto permute(Sequence< T, Is... > const)
Definition sequence.hpp:487
Direction
Definition direction.hpp:9
static constexpr auto operator+(Sequence< T, As... > const, Sequence< T, Bs... > const)
Definition sequence.hpp:107
static constexpr decltype(auto) expand(Sequence< T, Seq... > const, F &&f, Xs &&...args)
Definition sequence.hpp:383
#define BEGIN_IGNORE_DIAGNOSTIC_GCC(warning)
Definition pragma.hpp:42
#define END_IGNORE_DIAGNOSTIC_GCC
Definition pragma.hpp:43