cMHN 1.1
C++ library for learning MHNs with pRC
Loading...
Searching...
No Matches
range.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-2-Clause
2
3#ifndef pRC_CORE_BASIC_RANGE_H
4#define pRC_CORE_BASIC_RANGE_H
5
11
12namespace pRC
13{
15 Size S = 1, class F, class... Xs>
16 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
17 Xs &&...args)
18 {
19 if constexpr(C == Context::CompileTime)
20 {
22 [&f, &args...](auto const... seq)
23 {
24 (f(args..., seq), ...);
25 });
26 }
27 if constexpr(C == Context::RunTime)
28 {
29 if constexpr(I < L)
30 {
31 for(Index i = I; i < L; i += S)
32 {
33 if constexpr(D == Direction::Forwards)
34 {
35 f(forward<Xs>(args)..., i);
36 }
37 if constexpr(D == Direction::Backwards)
38 {
39 f(forward<Xs>(args)..., L + I - S - i);
40 }
41 }
42 }
43 }
44 }
45
46 template<Size I, Size L, Direction D = Direction::Forwards, Size S = 1,
47 class F, class... Xs>
48 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
49 Xs &&...args)
50 {
51 if constexpr((L - I) / S <= 8)
52 {
54 forward<Xs>(args)...);
55 }
56 else
57 {
59 forward<Xs>(args)...);
60 }
61 }
62
63 template<Context C, Size L, Direction D = Direction::Forwards, Size S = 1,
64 class F, class... Xs>
65 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
66 Xs &&...args)
67 {
68 range<C, 0, L, D, S>(forward<F>(f), forward<Xs>(args)...);
69 }
70
71 template<Size L, Direction D = Direction::Forwards, Size S = 1, class F,
72 class... Xs>
73 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
74 Xs &&...args)
75 {
76 range<0, L, D, S>(forward<F>(f), forward<Xs>(args)...);
77 }
78
79 template<Context C, class I, class L, Direction O, class D,
80 class S =
81 decltype(makeConstantSequence<Size, typename I::Dimension{}, 1>()),
82 class F, class... Xs, If<IsSizes<I>> = 0, If<IsSizes<L>> = 0,
85 If<IsSame<typename I::Dimension, typename L::Dimension,
86 typename D::Dimension, typename S::Dimension>> = 0,
87 If<IsSatisfied<((L() - I()) % S() == Constant<Size, 0>())>> = 0,
90 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
91 Xs &&...args)
92 {
93 if constexpr(typename L::Dimension() > 0)
94 {
95 if constexpr(O == Direction::RightToLeft)
96 {
97 auto g = [&f, &args...](auto const... indices)
98 {
99 constexpr auto N = typename L::Dimension();
100
101 expand(
103 [&f, &args...](auto const &indices, auto const... seq)
104 {
105 f(forward<Xs>(args)..., get<seq>(indices)...);
106 },
107 tuple(indices...));
108 };
109
110 using RI = decltype(reverse(I()));
111 using RL = decltype(reverse(L()));
112 using RD = decltype(reverse(D()));
113 using RS = decltype(reverse(S()));
114
116 }
117 if constexpr(O == Direction::LeftToRight)
118 {
119 auto g = [&f, &args...](auto const... indices)
120 {
122 [&f, &args..., &indices...](auto const i)
123 {
124 f(forward<Xs>(args)..., i, indices...);
125 });
126 };
127
128 using NI = decltype(chip<0>(I()));
129 using NL = decltype(chip<0>(L()));
130 using ND = decltype(chip<0>(D()));
131 using NS = decltype(chip<0>(S()));
133 }
134 }
135 else
136 {
138 }
139 }
140
141 template<Context C, class I, class L, Direction O = Direction::LeftToRight,
142 class S =
143 decltype(makeConstantSequence<Size, typename I::Dimension{}, 1>()),
144 class D = decltype(makeConstantSequence<Direction,
145 typename I::Dimension{}, Direction::Forwards>()),
146 class F, class... Xs, If<IsSizes<I>> = 0, If<IsSizes<L>> = 0,
149 If<IsSame<typename I::Dimension, typename L::Dimension,
150 typename S::Dimension, typename D::Dimension>> = 0,
151 If<IsSatisfied<((L() - I()) % S() == Constant<Size, 0>())>> = 0,
154 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
155 Xs &&...args)
156 {
157 range<C, I, L, O, D, S>(forward<F>(f), forward<Xs>(args)...);
158 }
159
160 template<Context C, class L, Direction O, class D,
161 class S =
162 decltype(makeConstantSequence<Size, typename L::Dimension{}, 1>()),
163 class F, class... Xs, If<IsSizes<L>> = 0, If<IsSequence<D>> = 0,
165 If<IsSame<typename L::Dimension, typename D::Dimension,
166 typename S::Dimension>> = 0,
170 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
171 Xs &&...args)
172 {
173 using I =
174 decltype(makeConstantSequence<Size, typename L::Dimension{}, 0>());
175 range<C, I, L, O, D, S>(forward<F>(f), forward<Xs>(args)...);
176 }
177
178 template<Context C, class L, Direction O = Direction::LeftToRight,
179 class S =
180 decltype(makeConstantSequence<Size, typename L::Dimension{}, 1>()),
181 class D = decltype(makeConstantSequence<Direction,
182 typename L::Dimension{}, Direction::Forwards>()),
183 class F, class... Xs, If<IsSizes<L>> = 0, If<IsSizes<S>> = 0,
185 If<IsSame<typename L::Dimension, typename S::Dimension,
186 typename D::Dimension>> = 0,
190 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
191 Xs &&...args)
192 {
193 using I =
194 decltype(makeConstantSequence<Size, typename L::Dimension{}, 0>());
195 range<C, I, L, O, D, S>(forward<F>(f), forward<Xs>(args)...);
196 }
197
198 template<class I, class L, Direction O, class D,
199 class S =
200 decltype(makeConstantSequence<Size, typename I::Dimension{}, 1>()),
201 class F, class... Xs, If<IsSizes<I>> = 0, If<IsSizes<L>> = 0,
204 If<IsSame<typename I::Dimension, typename L::Dimension,
205 typename D::Dimension, typename S::Dimension>> = 0,
206 If<IsSatisfied<((L() - I()) % S() == Constant<Size, 0>())>> = 0,
209 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
210 Xs &&...args)
211 {
212 if constexpr(typename L::Dimension() == 0)
213 {
215 forward<Xs>(args)...);
216 }
217 else if constexpr(reduce<Mul>((L() - I()) / S()) <= 8)
218 {
220 forward<Xs>(args)...);
221 }
222 else
223 {
225 forward<Xs>(args)...);
226 }
227 }
228
229 template<class I, class L, Direction O = Direction::LeftToRight,
230 class S =
231 decltype(makeConstantSequence<Size, typename I::Dimension{}, 1>()),
232 class D = decltype(makeConstantSequence<Direction,
233 typename I::Dimension{}, Direction::Forwards>()),
234 class F, class... Xs, If<IsSizes<I>> = 0, If<IsSizes<L>> = 0,
237 If<IsSame<typename I::Dimension, typename L::Dimension,
238 typename S::Dimension, typename D::Dimension>> = 0,
239 If<IsSatisfied<((L() - I()) % S() == Constant<Size, 0>())>> = 0,
242 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
243 Xs &&...args)
244 {
245 range<I, L, O, D, S>(forward<F>(f), forward<Xs>(args)...);
246 }
247
248 template<class L, Direction O, class D,
249 class S =
250 decltype(makeConstantSequence<Size, typename L::Dimension{}, 1>()),
251 class F, class... Xs, If<IsSizes<L>> = 0, If<IsSequence<D>> = 0,
253 If<IsSame<typename L::Dimension, typename D::Dimension,
254 typename S::Dimension>> = 0,
258 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
259 Xs &&...args)
260 {
261 using I =
262 decltype(makeConstantSequence<Size, typename L::Dimension{}, 0>());
263 range<I, L, O, D, S>(forward<F>(f), forward<Xs>(args)...);
264 }
265
266 template<class L, Direction O = Direction::LeftToRight,
267 class S =
268 decltype(makeConstantSequence<Size, typename L::Dimension{}, 1>()),
269 class D = decltype(makeConstantSequence<Direction,
270 typename L::Dimension{}, Direction::Forwards>()),
271 class F, class... Xs, If<IsSizes<L>> = 0, If<IsSizes<S>> = 0,
273 If<IsSame<typename L::Dimension, typename S::Dimension,
274 typename D::Dimension>> = 0,
278 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
279 Xs &&...args)
280 {
281 using I =
282 decltype(makeConstantSequence<Size, typename L::Dimension{}, 0>());
283 range<I, L, O, D, S>(forward<F>(f), forward<Xs>(args)...);
284 }
285}
286#endif // pRC_CORE_BASIC_RANGE_H
pRC::Size const D
Definition CalculatePThetaTests.cpp:9
TN::Subscripts S
Definition externs_nonTT.hpp:9
Definition cholesky.hpp:18
static constexpr auto makeConstantSequence()
Definition sequence.hpp:402
Size Index
Definition type_traits.hpp:21
std::size_t Size
Definition type_traits.hpp:20
static constexpr auto reverse(Direction const D)
Definition direction.hpp:24
std::enable_if_t< B{}, int > If
Definition type_traits.hpp:68
Constant< Bool, B > IsSatisfied
Definition type_traits.hpp:71
static constexpr auto range(F &&f, Xs &&...args)
Definition range.hpp:16
Context
Definition context.hpp:9
Direction
Definition direction.hpp:9
static constexpr decltype(auto) expand(Sequence< T, Seq... > const, F &&f, Xs &&...args)
Definition sequence.hpp:344