1#ifndef __DUNE_ACFEM_EXPRESSIONS_EXTRACT_HH__
2#define __DUNE_ACFEM_EXPRESSIONS_EXTRACT_HH__
6#include "../common/typetraits.hh"
7#include "../common/literals.hh"
8#include "../mpl/conditionaljoin.hh"
10namespace Dune::ACFem::Expressions {
12 using namespace Literals;
17 template<
class E,
class Parent>
18 constexpr decltype(
auto)
operator()(E&& e, NoTreePos, Parent&&)
const
20 return std::forward<E>(e);
23 template<
class E,
class TreePos,
class Parent>
24 constexpr decltype(
auto)
operator()(E&& e, TreePos, Parent&&)
const
26 return std::pair<E, TreePos>(std::forward<E>(e), TreePos{});
37 template<
class E,
class Extracts,
class ArgIndices,
class F,
class Recursive,
class Unique,
class TreePos,
class Parent,
class PackData,
38 std::enable_if_t<(IsTransformInvocable<F, E, TreePos, Parent>::value
41 constexpr auto extractTupleHelper(E&& e,
const Extracts& t, ArgIndices, F&&, Recursive,
Unique, TreePos, Parent&& parent, PackData&& packData)
47 packData(std::forward<E>(e), TreePos{}, std::forward<Parent>(parent)),
52 template<
class E,
class Extracts, std::size_t... ArgIndex,
class F,
class Recursive,
class Unique,
class TreePos,
class Parent,
class PackData,
53 std::enable_if_t<(IsTransformInvocable<F, E, TreePos, Parent>::value
54 && !IsSelfExpression<E>::value
57 constexpr auto extractTupleHelper(E&& e,
const Extracts& t, IndexSequence<ArgIndex...>, F&& f, Recursive, Unique, TreePos, Parent&& parent, PackData&& packData)
59 if constexpr (!std::is_same<Parent, FalseType>::value) {
60 return TupleUtilities::joinUnless<Unique::template Predicate>(
63 std::forward<E>(e).template operand<ArgIndex>(),
64 std::forward<F>(f), Recursive{}, Unique{}, AppendTreePos<TreePos, ArgIndex>{},
68 return TupleUtilities::joinUnless<Unique::template Predicate>(
71 std::forward<E>(e).template operand<ArgIndex>(),
72 std::forward<F>(f), Recursive{}, Unique{}, AppendTreePos<TreePos, ArgIndex>{},
79 template<
class E,
class Extracts,
class ArgIndices,
class F,
class Recursive,
class Unique,
class TreePos,
class Parent,
class PackData,
80 std::enable_if_t<(!IsTransformInvocable<F, E, TreePos, Parent>::value
81 && IsSelfExpression<E>::value
83 constexpr auto extractTupleHelper(E&& e,
const Extracts& t, ArgIndices, F&&, Recursive, Unique, TreePos, Parent&&, PackData&&)
91 template<
class E,
class... P, std::size_t... ArgIndex,
class F,
class Recursive,
class Unique,
92 class TreePos,
class Parent,
class PackData,
93 std::enable_if_t<(!IsTransformInvocable<F, E, TreePos, Parent>::value
94 && !IsSelfExpression<E>::value
96 constexpr auto extractTupleHelper(E&& e,
const std::tuple<P...>& t, IndexSequence<ArgIndex...>, F&& f, Recursive, Unique, TreePos, Parent&&, PackData&& packData)
101 if constexpr (!std::is_same<Parent, FalseType>::value) {
102 return TupleUtilities::joinUnless<Unique::template Predicate>(
105 std::forward<E>(e).
template operand<ArgIndex>(),
106 std::forward<F>(f), Recursive{}, Unique{}, AppendTreePos<TreePos, ArgIndex>{},
108 std::forward<PackData>(packData)
112 return TupleUtilities::joinUnless<Unique::template Predicate>(
115 std::forward<E>(e).
template operand<ArgIndex>(),
116 std::forward<F>(f), Recursive{}, Unique{}, AppendTreePos<TreePos, ArgIndex>{},
118 std::forward<PackData>(packData)
146 bool Recursive =
false,
147 class Unique = PredicateProxy<AlwaysFalse>,
148 class TreePos = NoTreePos,
149 class Parent = NoParent,
150 class PackData = ExtractDataDefaultFunctor,
151 std::enable_if_t<IsExpression<E>::value,
int> = 0>
152 constexpr auto extract(E&& e, F&& f,
153 const std::tuple<P...>& initial,
154 BoolConstant<Recursive> r = BoolConstant<Recursive>{},
156 TreePos tp = TreePos{},
157 Parent&& parent = Parent{},
158 PackData&& packData = PackData{})
160 if constexpr (std::is_same<TreePos, TrueType>::value) {
161 using UniqueWrapper =
162 ConditionalType<std::is_same<PackData, ExtractDataDefaultFunctor>::value,
163 PredicateWrapper<PredicateProxy<Unique::template Predicate>::template BinaryFirstOfPair>,
165 return extractTupleHelper(std::forward<E>(e),
167 r, UniqueWrapper{}, IndexSequence<>{},
168 std::forward<Parent>(parent),
169 std::forward<PackData>(packData));
171 return extractTupleHelper(std::forward<E>(e),
174 std::forward<Parent>(parent),
175 std::forward<PackData>(packData));
183 class Unique = PredicateWrapper<AlwaysFalse>,
184 class TreePos = NoTreePos,
185 class Parent = NoParent,
186 class PackData = ExtractDataDefaultFunctor,
187 std::enable_if_t<IsExpression<E>::value,
int> = 0>
188 constexpr auto extract(E&& e, F&& f,
189 Recursive r = Recursive{},
191 TreePos tp = TreePos{},
192 Parent&& parent = Parent{},
193 PackData&& packData = PackData{})
195 if constexpr (std::is_same<TreePos, TrueType>::value) {
196 using UniqueWrapper =
197 ConditionalType<std::is_same<PackData, ExtractDataDefaultFunctor>::value,
198 PredicateWrapper<PredicateProxy<Unique::template Predicate>::template BinaryFirstOfPair>,
200 return extract(std::forward<E>(e), std::forward<F>(f), std::tuple<>{},
203 std::forward<Parent>(parent),
204 std::forward<PackData>(packData));
206 return extract(std::forward<E>(e), std::forward<F>(f), std::tuple<>{},
208 std::forward<Parent>(parent),
209 std::forward<PackData>(packData));
220 template<
template<
class T,
class...>
class F,
223 bool Recursive =
false,
224 class Unique = PredicateWrapper<AlwaysFalse>,
225 class TreePos = NoTreePos,
226 class Parent = NoParent,
227 class PackData = ExtractDataDefaultFunctor,
228 std::enable_if_t<IsExpression<E>::value && ExamineTreeOr<E, TreePos, Parent, F>::value,
int> = 0>
229 constexpr auto extract(E&& e,
230 const std::tuple<P...>& initial,
231 BoolConstant<Recursive> r = BoolConstant<Recursive>{},
233 TreePos tp = TreePos{},
234 Parent&& parent = Parent{},
235 PackData&& packData = PackData{})
239 using FunctorType = SimpleReplaceFunctor<int, PredicateProxy<F>::template ForwardFirst,
AlwaysFalse>;
241 if constexpr (std::is_same<TreePos, TrueType>::value) {
242 using UniqueWrapper =
243 ConditionalType<std::is_same<PackData, ExtractDataDefaultFunctor>::value,
244 PredicateWrapper<PredicateProxy<Unique::template Predicate>::template BinaryFirstOfPair>,
246 return extract(std::forward<E>(e), FunctorType{}, initial,
249 std::forward<Parent>(parent),
250 std::forward<PackData>(packData));
252 return extract(std::forward<E>(e), FunctorType{}, initial,
254 std::forward<Parent>(parent),
255 std::forward<PackData>(packData));
260 template<
template<
class T,
class...>
class F,
263 bool Recursive =
false,
264 class Unique = PredicateWrapper<AlwaysFalse>,
265 class TreePos = NoTreePos,
266 class Parent = NoParent,
267 class PackData = ExtractDataDefaultFunctor,
268 std::enable_if_t<(IsExpression<E>::value
269 && !ExamineTreeOr<E, TreePos, Parent, F>::value
271 constexpr auto extract(E&& e,
272 const std::tuple<P...>& initial,
273 BoolConstant<Recursive> = BoolConstant<Recursive>{},
276 Parent&& parent = Parent{},
277 PackData&& packData = PackData{})
287 template<
template<
class T,
class...>
class F,
289 bool Recursive =
false,
290 class Unique = PredicateWrapper<AlwaysFalse>,
291 class TreePos = NoTreePos,
292 class Parent = NoParent,
293 class PackData = ExtractDataDefaultFunctor,
294 std::enable_if_t<IsExpression<E>::value,
int> = 0>
295 constexpr auto extract(E&& e,
296 BoolConstant<Recursive> r = BoolConstant<Recursive>{},
298 TreePos tp = TreePos{},
299 Parent&& parent = Parent{},
300 PackData&& packData = PackData{})
302 if constexpr (std::is_same<TreePos, TrueType>::value) {
303 using UniqueWrapper =
304 ConditionalType<std::is_same<PackData, ExtractDataDefaultFunctor>::value,
305 PredicateWrapper<PredicateProxy<Unique::template Predicate>::template BinaryFirstOfPair>,
307 return extract<F>(std::forward<E>(e), std::tuple<>{},
310 std::forward<Parent>(parent),
311 std::forward<PackData>(packData));
313 return extract<F>(std::forward<E>(e), std::tuple<>{},
315 std::forward<Parent>(parent),
316 std::forward<PackData>(packData));
321 template<
template<
class...>
class Predicate,
class E,
template<
class...>
class DescendUntil =
AlwaysFalse>
322 constexpr decltype(
auto) extractLeftMost(E&& e, PredicateWrapper<DescendUntil> = PredicateWrapper<DescendUntil>{})
324 if constexpr (IsSelfExpression<E>::value || DescendUntil<E>::value) {
325 if constexpr (Predicate<E>::value) {
326 return std::forward<E>(e);
331 return extractLeftMost<Predicate>(std::forward<E>(e).operand(0_c), PredicateWrapper<DescendUntil>{});
335 template<
class E,
template<
class...>
class Predicate =
AlwaysTrue,
template<
class...>
class DescendUntil =
AlwaysFalse>
336 using LeftMostOperand =
decltype(extractLeftMost<Predicate>(std::declval<E>(), PredicateWrapper<DescendUntil>
340 template<
class E,
class Initial = std::tuple<>,
template<
class...>
class Unique =
AlwaysFalse>
341 constexpr auto extractPlaceholders(E&& e,
342 Initial&& initial = Initial{},
343 PredicateWrapper<Unique> u = PredicateWrapper<Unique>{})
345 return extract<IsPlaceholderExpression>(std::forward<E>(e), std::forward<Initial>(initial), NoTreePos{}, u);
351 template<std::
size_t Id,
class E>
352 constexpr auto extractIndeterminates(E&& e)
356 using FunctorType = ReplaceFunctor<IndexConstant<Id>, int, IndeterminateMatch,
AlwaysFalse>;
357 return extract(std::forward<E>(e), FunctorType{});
362 constexpr auto extractTerminals(E&& e)
364 return extract<IsTerminal>(std::forward<E>(e));
368 using TerminalOperands =
decltype(extractTerminals(std::declval<E>()));
370 template<
class F,
class... T>
371 using OperationTerminals = TerminalOperands<
ExpressionType<F, T...> >;
374 template<
template<
class T,
class...>
class F,
class E,
class Recursive =
FalseType>
375 using MatchingExpressionTuple = std::decay_t<decltype(extract<F>(std::declval<E>(), Recursive{}))>;
379 using PlaceholderTuple = std::decay_t<decltype(extractPlaceholders(std::declval<E>()))>;
382 template<std::
size_t Id,
class E>
383 using IndeterminateTuple = std::decay_t<decltype(extractIndeterminates<Id>(std::declval<E>()))>;
decltype(operate(std::declval< OptOrF >(), std::declval< Rest >()...)) ExpressionType
Generate the type of an expression by calling operate().
Definition: optimizationbase.hh:256
MakeSequence< std::size_t, N, Offset, Stride, Repeat > MakeIndexSequence
Make a sequence of std::size_t elements.
Definition: generators.hh:34
constexpr auto addFrontUnless(Tuple &&t, E &&e, PredicateWrapper< F >=PredicateWrapper< F >{})
Enforce kind of uniqueness.
Definition: conditionaljoin.hh:99
Constant< bool, V > BoolConstant
Short-cut for integral constant of type bool.
Definition: types.hh:48
typename MakeType< FalseType, Other... >::Type AlwaysFalse
Generate FalseType regardless of the template argument list.
Definition: types.hh:155
typename MakeType< TrueType, Other... >::Type AlwaysTrue
Generate TrueType regardless of the template argument list.
Definition: types.hh:159
BoolConstant< false > FalseType
Alias for std::false_type.
Definition: types.hh:110
BoolConstant< true > TrueType
Alias for std::true_type.
Definition: types.hh:107
FalseType by default.
Definition: runtimeequal.hh:103
Yields std::true_type if the expression E contains placeholders.
Definition: extract.hh:391
Identify self-contained terminals, see SelfExpression.
Definition: terminal.hh:60