1#ifndef __DUNE_ACFEM_EXPRESSIONS_SUBEXPRESSION_HH__
2#define __DUNE_ACFEM_EXPRESSIONS_SUBEXPRESSION_HH__
4#include "expressionoperations.hh"
6#include "densestorage.hh"
8#include "../common/literals.hh"
18 using namespace Literals;
34 template<class T, std::enable_if_t<IsSubExpressionExpression<T>::value,
int> = 0>
37 return std::forward<T>(t).template operand<1>();
45 std::enable_if_t<(!IsSubExpressionExpression<T>::value
46 && !IsClosure<T>::value
50 return std::forward<T>(t);
53 template<class T, std::enable_if_t<IsClosure<T>::value,
int> = 0>
59 template<std::size_t... OperandPos,
class T, std::enable_if_t<IsExpression<T>::value,
int> = 0>
60 auto subExpression(T&& t, IndexSequence<OperandPos...> = IndexSequence<OperandPos...>{})
63 return subExpression(DenseStorageType<T>{}, std::forward<T>(t), TreePos{});
66 template<
template<
class...>
class Storage, std::size_t... OperandPos,
class T, std::enable_if_t<IsExpression<T>::value,
int> = 0>
67 auto subExpression(T&& t, IndexSequence<OperandPos...> = IndexSequence<OperandPos...>{})
70 return subExpression(Storage<T>(), std::forward<T>(t), TreePos{});
76 template<
class Functor>
77 struct EvaluateSubExpression;
78 template<
class Optimize>
79 struct ExpandSubExpression;
92 constexpr decltype(
auto)
operator()(Src&& src)
const
94 return std::forward<Src>(src);
101 constexpr auto operator()(Dst&& dst)
const
103 return zero(std::forward<Dst>(dst));
121 class Functor = SExpForward,
122 std::enable_if_t<(IsSubExpressionExpression<T>::value
123 && std::is_assignable<decltype(std::declval<T>().operand(0_c)), Operand<1, T> >::value
127 if constexpr (!IsConstantExprArg<Operand<1, T> >::value) {
131 traverse(std::forward<T>(t).operand(1_c), impl::EvaluateSubExpression<Functor>{f});
132 std::forward<T>(t).operand(0_c) =
asExpression(std::forward<Functor>(f)(std::forward<T>(t).operand(1_c)));
153 class Functor = SExpForward,
154 std::enable_if_t<(IsSubExpressionExpression<T>::value
155 && !std::is_assignable<decltype(std::declval<T>().operand(0_c)), Operand<1, T> >::value
161 template<class T, class Functor = SExpForward, std::enable_if_t<IsClosure<T>::value,
int> = 0>
167 template<
class T,
class Optimize = OptimizeTop,
class Functor = impl::ExpandSubExpression<Optimize> >
168 constexpr decltype(
auto) expandSubExpression(T&& t, Optimize = Optimize{}, Functor = Functor{})
170 static_assert(IsSubExpressionExpression<T>::value,
171 "Attempt to expand subexpression of non subexpression-expression.");
173 return transform(
static_cast<Operand<1, T>
>(std::forward<T>(t).operand(1_c)), Functor{}, Operate<Optimize>{});
194 template<
class Functor>
197 template<class T, std::enable_if_t<IsSubExpressionExpression<T>::value,
int> = 0>
198 constexpr auto operator()(T&& t)
const
207 template<
class Optimize>
208 struct ExpandSubExpression
210 template<class T, std::enable_if_t<IsSubExpressionExpression<T>::value,
int> = 0>
211 constexpr decltype(
auto)
operator()(T&& t)
const
213 return expandSubExpression(std::forward<T>(t), Optimize{});
216 template<
class T, std::enable_if_t<(IsPlaceholderExpression<T>::value
217 || IsIndeterminateExpression<T>::value
219 constexpr decltype(
auto)
operator()(T&& t)
const
221 return std::forward<T>(t);
236 template<
class T,
class Functor = SExpForward>
239 static_assert(IsExpression<T>::value,
"Called with something which is not an expression.");
241 traverse(std::forward<T>(t), impl::EvaluateSubExpression<Functor>{f});
245 template<
class T,
class Optimize = OptimizeTop>
248 return transform(std::forward<T>(t), impl::ExpandSubExpression<Optimize>{}, Operate<Optimize>{});
258 struct ExpressionTraits<T,
std::enable_if_t<IsSubExpressionExpression<T>::value> >
259 : ExpressionTraits<Expressions::Operand<1, T> >
261 using BaseType = ExpressionTraits<Expressions::Operand<1, T> >;
263 static constexpr bool isTypedValue =
false;
constexpr decltype(auto) asExpression(T &&t)
Return a non-closure expression as is.
Definition: interface.hh:122
decltype(operate(std::declval< OptOrF >(), std::declval< Rest >()...)) ExpressionType
Generate the type of an expression by calling operate().
Definition: optimizationbase.hh:256
constexpr decltype(auto) subExpressionExpression(T &&t)
Recurse to the wrapped expression if T fulfills IsSubExpressionExpression<T>.
Definition: subexpression.hh:35
constexpr auto zero(T &&t)
Use the zero fraction as canonical zero element for scalars.
Definition: constantoperations.hh:80
void evaluateSubExpression(T &&t, Functor=Functor{})
Do-nothing dummy for expressions where evaluateSubExpression() would fail otherwise.
Definition: subexpression.hh:157
constexpr auto expandAllSubExpressions(T &&t, Optimize=Optimize{})
Expand all contained sub-expressions.
Definition: subexpression.hh:246
void evaluateAllSubExpressions(T &&t, Functor &&f=Functor{})
Evaluate all contained subexpressions.
Definition: subexpression.hh:237
constexpr bool isConstant(Sequence< T, T0, Ts... >)
Definition: compare.hh:285
Sequence< std::size_t, V... > IndexSequence
Sequence of std::size_t values.
Definition: types.hh:64
Operation functor for transform() which evaluates all contained sub-expressions.
Definition: subexpression.hh:196