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
102template <auto constantValue>
104{
105 static constexpr auto value = constantValue;
106};
107
111template <const auto& range>
112requires is::range<decltype (range)>
114{
115 static constexpr auto value = range.getStart();
116};
117
121template <const auto& range>
122requires is::range<decltype (range)>
124{
125 static constexpr auto value = range.getEnd();
126};
127
128
131{
133 struct Value
134 {
135 template <is::realNumber T>
136 constexpr operator T() const { return std::numeric_limits<T>::max(); }
137
138 template <is::realNumber T>
139 constexpr operator std::complex<T>() const { return { std::numeric_limits<T>::max(), std::numeric_limits<T>::max() }; }
140 };
141
142 static constexpr Value value {};
143};
144
155template <template <size_t, class...> class ExpressionType, class RuntimeArgs, class... AdditionalCompileTimeParameters>
157{
158 template <size_t extent, class SrcType>
159 using Expression = ExpressionType<extent, SrcType, AdditionalCompileTimeParameters...>;
160
161 RuntimeArgs runtimeArgs;
162
163 constexpr ExpressionChainBuilderWithRuntimeArgs (RuntimeArgs&& rtArgs)
164 : runtimeArgs (std::move (rtArgs))
165 {}
166
168
170 template <is::anyVctr Src>
171 constexpr auto operator<< (const Src& src) const
172 {
173 auto expression = Expression<extentOf<Src>, const Src&> { src };
174 expression.template iterateOverRuntimeArgChain<0> (runtimeArgs);
175
176 if constexpr (is::reductionExpression<decltype (expression)>)
177 {
178 return ReductionExpression::reduce (expression);
179 }
180 else
181 {
182 return expression;
183 }
184 }
185
187 template <is::anyVctr Src>
188 constexpr auto operator<< (Src& src) const
189 {
190 auto expression = Expression<extentOf<Src>, const Src&> { src };
191 expression.template iterateOverRuntimeArgChain<0> (runtimeArgs);
192
193 if constexpr (is::reductionExpression<decltype (expression)>)
194 {
195 return ReductionExpression::reduce (expression);
196 }
197 else
198 {
199 return expression;
200 }
201 }
202
204 template <is::anyVctr Src>
205 constexpr auto operator<< (Src&& src) const
206 {
207 auto expression = Expression<extentOf<Src>, Src> { std::move (src) };
208 expression.template iterateOverRuntimeArgChain<0> (runtimeArgs);
209
210 if constexpr (is::reductionExpression<decltype (expression)>)
211 {
212 return ReductionExpression::reduce (expression);
213 }
214 else
215 {
216 return expression;
217 }
218 }
219
221 template <is::expression SrcExpression>
222 constexpr auto operator<< (SrcExpression&& e) const
223 {
224 auto expression = Expression<extentOf<SrcExpression>, SrcExpression> (std::forward<SrcExpression> (e));
225 expression.template iterateOverRuntimeArgChain<0> (runtimeArgs);
226
227 if constexpr (is::reductionExpression<decltype (expression)>)
228 {
229 return ReductionExpression::reduce (expression);
230 }
231 else
232 {
233 return expression;
234 }
235 }
236
240 template <is::expressionChainBuilder SrcExpressionChainBuilder>
241 constexpr auto operator<< (SrcExpressionChainBuilder srcExpressionChainBuilder) const
242 {
243 auto newRuntimeArgChain = srcExpressionChainBuilder.runtimeArgs.prepend (runtimeArgs);
244
245 using ChainingHelper = detail::ExpressionChainingHelper<SrcExpressionChainBuilder, Expression>;
246
247 return typename ChainingHelper::template NewExpressionChainBuilder<decltype(newRuntimeArgChain)> (std::move (newRuntimeArgChain));
248 }
249};
250
252template <template <size_t, class...> class ExpressionType, class... AdditionalCompileTimeParameters>
254
276template <template <size_t, class...> class ExpressionType, class... RuntimeArgs>
277requires (sizeof... (RuntimeArgs) > 0)
278constexpr auto makeExpressionChainBuilderWithRuntimeArgs (RuntimeArgs... runtimeArgs)
279{
280 return ExpressionChainBuilderWithRuntimeArgs<ExpressionType, detail::RuntimeArgChain<std::tuple<RuntimeArgs...>>> (detail::RuntimeArgChain<std::tuple<RuntimeArgs...>> (std::move (runtimeArgs)...));
281}
282
288template <template <size_t, class...> class ExpressionType, class ExpressionTemplateArg, class... RuntimeArgs>
289requires (sizeof... (RuntimeArgs) > 0)
290constexpr auto makeTemplateExpressionChainBuilderWithRuntimeArgs (RuntimeArgs... runtimeArgs)
291{
292 return ExpressionChainBuilderWithRuntimeArgs<ExpressionType, detail::RuntimeArgChain<std::tuple<RuntimeArgs...>>, ExpressionTemplateArg> (detail::RuntimeArgChain<std::tuple<RuntimeArgs...>> (std::move (runtimeArgs)...));
293}
294
295} // namespace vctr
static VCTR_FORCEDINLINE constexpr auto reduce(const Expression &e)
Returns the reduction result of the expression passed in.
Definition: ReductionExpression.h:42
Constrains the type to be a range, this is a class with a getStart, getLength and getEnd member funct...
Definition: GenericConcepts.h:125
Definition: ContainerAndExpressionConcepts.h:387
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:290
constexpr auto makeExpressionChainBuilderWithRuntimeArgs(RuntimeArgs... runtimeArgs)
Helper function to build factory functions for expressions that rely on runtime argument values.
Definition: ExpressionChainBuilder.h:278
Evaluates the return value of getEnd called on the constant reference template argument and wraps tha...
Definition: ExpressionChainBuilder.h:124
Evaluates the return value of getStart called on the constant reference template argument and wraps t...
Definition: ExpressionChainBuilder.h:114
A helper struct to pass a constant as argument wrapped in a struct with a single public static conste...
Definition: ExpressionChainBuilder.h:104
A stupid type that converts itself to std::numeric_limits<T>::max when assigned to any numeric type T...
Definition: ExpressionChainBuilder.h:134
A helper struct to indicate that a constant template should be considered disabled.
Definition: ExpressionChainBuilder.h:131
An expression chain builder is an object which supplies various operator<< overloads which build chai...
Definition: ExpressionChainBuilder.h:157
constexpr auto operator<<(const Src &src) const
Returns an expression which holds a reference to the Vector passed in as source.
Definition: ExpressionChainBuilder.h:171