VCTR
Loading...
Searching...
No Matches
ExpressionChainBuilder.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
24{
25
26namespace detail
27{
37template <is::stdTuple... ArgTuples>
38class RuntimeArgChain
39{
40public:
41 template <class... Args>
42 requires (! (is::stdTuple<Args> || ...))
43 constexpr RuntimeArgChain (Args... firstArgs)
44 : chain {{ std::tuple (std::move (firstArgs)...) }}
45 {}
46
47 constexpr RuntimeArgChain()
48 requires (sizeof... (ArgTuples) == 1)
49 : chain {{ std::tuple<>() }}
50 {}
51
52 // TODO: This is a workaround for https://github.com/sonible/VCTR/issues/111 and should be replaced by a generic solution
53 constexpr RuntimeArgChain()
54 requires (sizeof... (ArgTuples) == 3)
55 : chain {{ std::tuple<>() }, { std::tuple<>() }, { std::tuple<>() }}
56 {}
57
58 static constexpr size_t size() { return sizeof... (ArgTuples); }
59
60 template <is::stdTuple... ArgTuplesToPrepend>
61 constexpr RuntimeArgChain<ArgTuplesToPrepend..., ArgTuples...> prepend (RuntimeArgChain<ArgTuplesToPrepend...> chainToPrepend) const
62 {
63 return { std::tuple_cat (chainToPrepend.chain, chain) };
64 }
65
66 template <size_t idx>
67 static constexpr bool hasValue()
68 {
69 return ! std::is_same_v<std::tuple<>, std::tuple_element_t<idx, decltype (chain)>>;
70 }
71
72 template <size_t idx>
73 constexpr auto& get() const
74 {
75 return std::get<idx> (chain);
76 }
77
78private:
79 template <is::stdTuple...> friend class RuntimeArgChain;
80
81 constexpr RuntimeArgChain (std::tuple<ArgTuples...>&& newChain)
82 : chain (std::move (newChain))
83 {}
84
85 std::tuple<ArgTuples...> chain;
86};
87
88template <class SrcChainer, template <size_t, class> class ExpressionToAdd>
89struct ExpressionChainingHelper
90{
91 template <size_t extent, class SrcType>
92 using NewExpressionChain = ExpressionToAdd<extent, typename SrcChainer::template Expression<extent, SrcType>>;
93
94 template <class RuntimeArgs>
95 using NewExpressionChainBuilder = ExpressionChainBuilderWithRuntimeArgs<NewExpressionChain, RuntimeArgs>;
96};
97} // namespace detail
98
104template <auto constantValue>
106{
107 static constexpr auto value = constantValue;
108};
109
115template <const auto& constantValue>
117{
118 static constexpr auto& value = constantValue;
119};
120
124template <const auto& range>
125requires is::range<decltype (range)>
127{
128 static constexpr auto value = range.getStart();
129};
130
134template <const auto& range>
135requires is::range<decltype (range)>
137{
138 static constexpr auto value = range.getEnd();
139};
140
141
144{
146 struct Value
147 {
148 template <is::realNumber T>
149 constexpr operator T() const { return std::numeric_limits<T>::max(); }
150
151 template <is::realNumber T>
152 constexpr operator std::complex<T>() const { return { std::numeric_limits<T>::max(), std::numeric_limits<T>::max() }; }
153 };
154
155 static constexpr Value value {};
156};
157
168template <template <size_t, class...> class ExpressionType, class RuntimeArgs, class... AdditionalCompileTimeParameters>
170{
171 template <size_t extent, class SrcType>
172 using Expression = ExpressionType<extent, SrcType, AdditionalCompileTimeParameters...>;
173
174 RuntimeArgs runtimeArgs;
175
176 constexpr ExpressionChainBuilderWithRuntimeArgs (RuntimeArgs&& rtArgs)
177 : runtimeArgs (std::move (rtArgs))
178 {}
179
181
183 template <is::anyVctr Src>
184 constexpr auto operator<< (const Src& src) const
185 {
186 auto expression = Expression<extentOf<Src>, const Src&> { src };
187 expression.template iterateOverRuntimeArgChain<0> (runtimeArgs);
188
189 if constexpr (is::reductionExpression<decltype (expression)>)
190 {
191 return ReductionExpression::reduce (expression);
192 }
193 else
194 {
195 return expression;
196 }
197 }
198
200 template <is::anyVctr Src>
201 constexpr auto operator<< (Src& src) const
202 {
203 auto expression = Expression<extentOf<Src>, const Src&> { src };
204 expression.template iterateOverRuntimeArgChain<0> (runtimeArgs);
205
206 if constexpr (is::reductionExpression<decltype (expression)>)
207 {
208 return ReductionExpression::reduce (expression);
209 }
210 else
211 {
212 return expression;
213 }
214 }
215
217 template <is::anyVctr Src>
218 constexpr auto operator<< (Src&& src) const
219 {
220 auto expression = Expression<extentOf<Src>, Src> { std::move (src) };
221 expression.template iterateOverRuntimeArgChain<0> (runtimeArgs);
222
223 if constexpr (is::reductionExpression<decltype (expression)>)
224 {
225 return ReductionExpression::reduce (expression);
226 }
227 else
228 {
229 return expression;
230 }
231 }
232
234 template <is::expression SrcExpression>
235 constexpr auto operator<< (SrcExpression&& e) const
236 {
237 auto expression = Expression<extentOf<SrcExpression>, SrcExpression> (std::forward<SrcExpression> (e));
238 expression.template iterateOverRuntimeArgChain<0> (runtimeArgs);
239
240 if constexpr (is::reductionExpression<decltype (expression)>)
241 {
242 return ReductionExpression::reduce (expression);
243 }
244 else
245 {
246 return expression;
247 }
248 }
249
253 template <is::expressionChainBuilder SrcExpressionChainBuilder>
254 constexpr auto operator<< (SrcExpressionChainBuilder srcExpressionChainBuilder) const
255 {
256 auto newRuntimeArgChain = srcExpressionChainBuilder.runtimeArgs.prepend (runtimeArgs);
257
258 using ChainingHelper = detail::ExpressionChainingHelper<SrcExpressionChainBuilder, Expression>;
259
260 return typename ChainingHelper::template NewExpressionChainBuilder<decltype(newRuntimeArgChain)> (std::move (newRuntimeArgChain));
261 }
262};
263
265template <template <size_t, class...> class ExpressionType, class... AdditionalCompileTimeParameters>
267
289template <template <size_t, class...> class ExpressionType, class... RuntimeArgs>
290requires (sizeof... (RuntimeArgs) > 0)
291constexpr auto makeExpressionChainBuilderWithRuntimeArgs (RuntimeArgs... runtimeArgs)
292{
293 return ExpressionChainBuilderWithRuntimeArgs<ExpressionType, detail::RuntimeArgChain<std::tuple<RuntimeArgs...>>> (detail::RuntimeArgChain<std::tuple<RuntimeArgs...>> (std::move (runtimeArgs)...));
294}
295
301template <template <size_t, class...> class ExpressionType, class ExpressionTemplateArg, class... RuntimeArgs>
302requires (sizeof... (RuntimeArgs) > 0)
303constexpr auto makeTemplateExpressionChainBuilderWithRuntimeArgs (RuntimeArgs... runtimeArgs)
304{
305 return ExpressionChainBuilderWithRuntimeArgs<ExpressionType, detail::RuntimeArgChain<std::tuple<RuntimeArgs...>>, ExpressionTemplateArg> (detail::RuntimeArgChain<std::tuple<RuntimeArgs...>> (std::move (runtimeArgs)...));
306}
307
308} // namespace vctr
static VCTR_FORCEDINLINE constexpr auto reduce(const Expression &e)
Returns the reduction result of the expression passed in.
Definition: ReductionExpression.h:51
Constrains the type to be a range, this is a class with a getStart, getLength and getEnd member funct...
Definition: GenericConcepts.h:127
Definition: ContainerAndExpressionConcepts.h:391
The main namespace of the VCTR project.
Definition: Array.h:24
constexpr auto makeTemplateExpressionChainBuilderWithRuntimeArgs(RuntimeArgs... runtimeArgs)
Helper function to build factory functions for expressions that rely on runtime argument values.
Definition: ExpressionChainBuilder.h:303
constexpr auto makeExpressionChainBuilderWithRuntimeArgs(RuntimeArgs... runtimeArgs)
Helper function to build factory functions for expressions that rely on runtime argument values.
Definition: ExpressionChainBuilder.h:291
Evaluates the return value of getEnd called on the constant reference template argument and wraps tha...
Definition: ExpressionChainBuilder.h:137
Evaluates the return value of getStart called on the constant reference template argument and wraps t...
Definition: ExpressionChainBuilder.h:127
A helper struct to pass a constant reference as argument wrapped in a struct with a single public sta...
Definition: ExpressionChainBuilder.h:117
A helper struct to pass a constant as argument wrapped in a struct with a single public static conste...
Definition: ExpressionChainBuilder.h:106
A stupid type that converts itself to std::numeric_limits<T>::max when assigned to any numeric type T...
Definition: ExpressionChainBuilder.h:147
A helper struct to indicate that a constant template should be considered disabled.
Definition: ExpressionChainBuilder.h:144
An expression chain builder is an object which supplies various operator<< overloads which build chai...
Definition: ExpressionChainBuilder.h:170
constexpr auto operator<<(const Src &src) const
Returns an expression which holds a reference to the Vector passed in as source.
Definition: ExpressionChainBuilder.h:184