cMHN 1.2
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{
14 template<Context C, Size I, Size L, Direction D = Direction::Forwards,
15 Size S = 1, class F, class... Xs>
16 requires(D == Direction::Forwards || D == Direction::Backwards) &&
18 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
19 Xs &&...args)
20 {
22 [&f, &args...](auto const... seq)
23 {
24 (f(args..., seq), ...);
25 });
26 }
27
28 template<Context C, Size I, Size L, Direction D = Direction::Forwards,
29 Size S = 1, class F, class... Xs>
30 requires(D == Direction::Forwards) && (C == Context::RunTime)
31 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
32 Xs &&...args)
33 {
34 for(Index i = I; i < L; i += S)
35 {
36 f(forward<Xs>(args)..., i);
37 }
38 }
39
40 template<Context C, Size I, Size L, Direction D = Direction::Forwards,
41 Size S = 1, class F, class... Xs>
42 requires(D == Direction::Backwards) && (C == Context::RunTime)
43 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
44 Xs &&...args)
45 {
46 for(Index i = I; i < L; i += S)
47 {
48 f(forward<Xs>(args)..., ((L - I) / S) * S + I - (i - I));
49 }
50 }
51
52 template<Size I, Size L, Direction D = Direction::Forwards, Size S = 1,
53 class F, class... Xs>
55 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
56 Xs &&...args)
57 {
58 if constexpr((L - I) / S <= 8)
59 {
61 forward<Xs>(args)...);
62 }
63 else
64 {
66 forward<Xs>(args)...);
67 }
68 }
69
70 template<Context C, Size L, Direction D = Direction::Forwards, Size S = 1,
71 class F, class... Xs>
73 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
74 Xs &&...args)
75 {
76 range<C, 0, L, D, S>(forward<F>(f), forward<Xs>(args)...);
77 }
78
79 template<Size L, Direction D = Direction::Forwards, Size S = 1, class F,
80 class... Xs>
82 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
83 Xs &&...args)
84 {
85 range<0, L, D, S>(forward<F>(f), forward<Xs>(args)...);
86 }
87
88 template<Context C, IsSizes I, IsSizes L,
90 IsSequence D = decltype(makeConstantSequence<Direction, L::Dimension,
93 class F, class... Xs>
94 requires IsSame<Direction, typename D::Type> &&
95 (L::Dimension == I::Dimension) && (L::Dimension == D::Dimension) &&
96 (L::Dimension == S::Dimension) &&
98 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
99 Xs &&...args)
100 {
101 if constexpr(L::Dimension > 0)
102 {
103 if constexpr(O == Direction::RightToLeft)
104 {
105 auto g = [&f, &args...](auto const... indices)
106 {
107 expand(
109 [&f, &args...](auto const &indices, auto const... seq)
110 {
111 f(forward<Xs>(args)..., get<seq>(indices)...);
112 },
113 Tuple(indices...));
114 };
115
116 using RI = decltype(reverse(I()));
117 using RL = decltype(reverse(L()));
118 using RD = decltype(reverse(D()));
119 using RS = decltype(reverse(S()));
120
122 }
123 if constexpr(O == Direction::LeftToRight)
124 {
125 auto g = [&f, &args...](auto const... indices)
126 {
128 [&f, &args..., &indices...](auto const i)
129 {
130 f(forward<Xs>(args)..., i, indices...);
131 });
132 };
133
134 using NI = decltype(chip<0>(I()));
135 using NL = decltype(chip<0>(L()));
136 using ND = decltype(chip<0>(D()));
137 using NS = decltype(chip<0>(S()));
139 }
140 }
141 else
142 {
143 forward<F>(f)(forward<Xs>(args)...);
144 }
145 }
146
147 template<IsSizes I, IsSizes L, Direction O = Direction::LeftToRight,
148 IsSequence D = decltype(makeConstantSequence<Direction, L::Dimension,
151 class F, class... Xs>
152 requires IsSame<Direction, typename D::Type> &&
153 (L::Dimension == I::Dimension) && (L::Dimension == D::Dimension) &&
154 (L::Dimension == S::Dimension) &&
156 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
157 Xs &&...args)
158 {
159 if constexpr(reduce<Mul>((L() - I()) / S()) <= 8)
160 {
162 forward<Xs>(args)...);
163 }
164 else
165 {
167 forward<Xs>(args)...);
168 }
169 }
170
171 template<Context C, IsSizes L, Direction O = Direction::LeftToRight,
172 IsSequence D = decltype(makeConstantSequence<Direction, L::Dimension,
175 class F, class... Xs>
176 requires IsSame<Direction, typename D::Type> &&
177 (L::Dimension == D::Dimension) && (L::Dimension == S::Dimension) &&
179 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
180 Xs &&...args)
181 {
183 range<C, I, L, O, D, S>(forward<F>(f), forward<Xs>(args)...);
184 }
185
186 template<IsSizes L, Direction O = Direction::LeftToRight,
187 IsSequence D = decltype(makeConstantSequence<Direction, L::Dimension,
190 class F, class... Xs>
191 requires IsSame<Direction, typename D::Type> &&
192 (L::Dimension == D::Dimension) && (L::Dimension == S::Dimension) &&
194 [[gnu::always_inline]] static inline constexpr auto range(F &&f,
195 Xs &&...args)
196 {
198 range<I, L, O, D, S>(forward<F>(f), forward<Xs>(args)...);
199 }
200}
201#endif // pRC_CORE_BASIC_RANGE_H
pRC::Size const D
Definition CalculatePThetaTests.cpp:9
TN::Subscripts S
Definition externs_nonTT.hpp:9
int i
Definition gmock-matchers-comparisons_test.cc:603
Definition cholesky.hpp:10
static constexpr auto makeConstantSequence()
Definition sequence.hpp:444
Size Index
Definition basics.hpp:32
std::size_t Size
Definition basics.hpp:31
std::tuple< Ts... > Tuple
Definition basics.hpp:23
static constexpr auto reverse(Direction const D)
Definition direction.hpp:24
static constexpr auto makeSeries()
Definition sequence.hpp:390
static constexpr auto reduce(Sequence< T, I1, I2, Is... > const)
Definition sequence.hpp:458
static constexpr auto makeRange()
Definition sequence.hpp:421
static constexpr auto chip(Sequence< T, Is... > const)
Definition sequence.hpp:584
Context
Definition context.hpp:9
static constexpr auto range(F &&f, Xs &&...args)
Definition range.hpp:18
Direction
Definition direction.hpp:9
static constexpr decltype(auto) expand(Sequence< T, Seq... > const, F &&f, Xs &&...args)
Definition sequence.hpp:383