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
110{
112 struct Value
113 {
114 template <is::realNumber T>
115 constexpr operator T() const { return std::numeric_limits<T>::max(); }
116
117 template <is::realNumber T>
118 constexpr operator std::complex<T>() const { return { std::numeric_limits<T>::max(), std::numeric_limits<T>::max() }; }
119 };
120
121 static constexpr Value value {};
122};
123
134template <template <size_t, class...> class ExpressionType, class RuntimeArgs, class... AdditionalCompileTimeParameters>
136{
137 template <size_t extent, class SrcType>
138 using Expression = ExpressionType<extent, SrcType, AdditionalCompileTimeParameters...>;
139
140 RuntimeArgs runtimeArgs;
141
142 constexpr ExpressionChainBuilderWithRuntimeArgs (RuntimeArgs&& rtArgs)
143 : runtimeArgs (std::move (rtArgs))
144 {}
145
147
149 template <is::anyVctr Src>
150 constexpr auto operator<< (const Src& src) const
151 {
152 auto expression = Expression<extentOf<Src>, const Src&> { src };
153 expression.template iterateOverRuntimeArgChain<0> (runtimeArgs);
154
155 if constexpr (is::reductionExpression<decltype (expression)>)
156 {
157 return ReductionExpression::reduce (expression);
158 }
159 else
160 {
161 return expression;
162 }
163 }
164
166 template <is::anyVctr Src>
167 constexpr auto operator<< (Src& src) const
168 {
169 auto expression = Expression<extentOf<Src>, const Src&> { src };
170 expression.template iterateOverRuntimeArgChain<0> (runtimeArgs);
171
172 if constexpr (is::reductionExpression<decltype (expression)>)
173 {
174 return ReductionExpression::reduce (expression);
175 }
176 else
177 {
178 return expression;
179 }
180 }
181
183 template <is::anyVctr Src>
184 constexpr auto operator<< (Src&& src) const
185 {
186 auto expression = Expression<extentOf<Src>, Src> { std::move (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::expression SrcExpression>
201 constexpr auto operator<< (SrcExpression&& e) const
202 {
203 auto expression = Expression<extentOf<SrcExpression>, SrcExpression> (std::forward<SrcExpression> (e));
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
219 template <is::expressionChainBuilder SrcExpressionChainBuilder>
220 constexpr auto operator<< (SrcExpressionChainBuilder srcExpressionChainBuilder) const
221 {
222 auto newRuntimeArgChain = srcExpressionChainBuilder.runtimeArgs.prepend (runtimeArgs);
223
224 using ChainingHelper = detail::ExpressionChainingHelper<SrcExpressionChainBuilder, Expression>;
225
226 return typename ChainingHelper::template NewExpressionChainBuilder<decltype(newRuntimeArgChain)> (std::move (newRuntimeArgChain));
227 }
228};
229
231template <template <size_t, class...> class ExpressionType, class... AdditionalCompileTimeParameters>
233
255template <template <size_t, class...> class ExpressionType, class... RuntimeArgs>
256requires (sizeof... (RuntimeArgs) > 0)
257auto makeExpressionChainBuilderWithRuntimeArgs (RuntimeArgs... runtimeArgs)
258{
259 return ExpressionChainBuilderWithRuntimeArgs<ExpressionType, detail::RuntimeArgChain<std::tuple<RuntimeArgs...>>> (detail::RuntimeArgChain<std::tuple<RuntimeArgs...>> (std::move (runtimeArgs)...));
260}
261
267template <template <size_t, class...> class ExpressionType, class ExpressionTemplateArg, class... RuntimeArgs>
268requires (sizeof... (RuntimeArgs) > 0)
270{
271 return ExpressionChainBuilderWithRuntimeArgs<ExpressionType, detail::RuntimeArgChain<std::tuple<RuntimeArgs...>>, ExpressionTemplateArg> (detail::RuntimeArgChain<std::tuple<RuntimeArgs...>> (std::move (runtimeArgs)...));
272}
273
274} // namespace vctr
static VCTR_FORCEDINLINE constexpr auto reduce(const Expression &e)
Returns the reduction result of the expression passed in.
Definition: ReductionExpression.h:42
Definition: ContainerAndExpressionConcepts.h:369
The main namespace of the VCTR project.
Definition: Array.h:24
auto makeTemplateExpressionChainBuilderWithRuntimeArgs(RuntimeArgs... runtimeArgs)
Helper function to build factory functions for expressions that rely on runtime argument values.
Definition: ExpressionChainBuilder.h:269
auto makeExpressionChainBuilderWithRuntimeArgs(RuntimeArgs... runtimeArgs)
Helper function to build factory functions for expressions that rely on runtime argument values.
Definition: ExpressionChainBuilder.h:257
A simple helper struct to pass a constant as argument wrapped in a struct with a single public static...
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:113
A helper struct to indicate that a constant template should be considered disabled.
Definition: ExpressionChainBuilder.h:110
An expression chain builder is an object which supplies various operator<< overloads which build chai...
Definition: ExpressionChainBuilder.h:136
constexpr auto operator<<(const Src &src) const
Returns an expression which holds a reference to the Vector passed in as source.
Definition: ExpressionChainBuilder.h:150