1#ifndef __DUNE_ACFEM_TENSORS_MODULES_CONSTANT_HH__
2#define __DUNE_ACFEM_TENSORS_MODULES_CONSTANT_HH__
4#include "../../common/fractionconstant.hh"
5#include "../../expressions/terminal.hh"
6#include "../tensorbase.hh"
7#include "../bindings.hh"
23 template<
class Field,
class Signature>
26 template<
class T,
class Field>
27 constexpr inline bool IsConstantTensorV =
false;
29 template<
class T,
class Field>
30 constexpr inline bool IsConstantTensorV<T&, Field> = IsConstantTensorV<std::decay_t<T>, Field>;
32 template<
class Signature,
class Field>
33 constexpr inline bool IsConstantTensorV<ConstantTensor<Field, Signature>, Field> =
true;
35 template<
class T,
class SFINAE =
void>
36 struct IsConstantTensor
41 struct IsConstantTensor<T,
std::enable_if_t<!IsDecay<T>::value> >
42 : IsConstantTensor<std::decay_t<T> >
45 template<
class Field,
class Dims>
46 struct IsConstantTensor<ConstantTensor<Field, Dims> >
51 struct IsNamedConstantTensor
56 struct IsNamedConstantTensor<T&>
57 : IsNamedConstantTensor<std::decay_t<T> >
61 struct IsNamedConstantTensor<T&&>
62 : IsNamedConstantTensor<std::decay_t<T> >
65 template<
class Dims,
class T,
char... Name>
66 struct IsNamedConstantTensor<ConstantTensor<TypedValue::NamedConstant<T, Name...>, Dims> >
71 struct IsFractionConstantTensor
76 struct IsFractionConstantTensor<T&>
77 : IsFractionConstantTensor<std::decay_t<T> >
81 struct IsFractionConstantTensor<T&&>
82 : IsFractionConstantTensor<std::decay_t<T> >
85 template<
class Dims,
class Int, Int Numerator, Int Denominator>
86 struct IsFractionConstantTensor<ConstantTensor<FractionConstant<Int, Numerator, Denominator>, Dims> >
97 : IsOnes<std::decay_t<T> >
102 : IsOnes<std::decay_t<T> >
105 template<
class Dims,
class Int>
106 struct IsOnes<ConstantTensor<FractionConstant<Int, 1, 1>, Dims> >
110 template<
class T,
class SFINAE =
void>
111 struct ConstantDataWrapper;
114 struct ConstantDataWrapper<T,
std::enable_if_t<IsTypedValue<T>::value> >
118 ConstantDataWrapper()
121 template<class DataArg, std::enable_if_t<std::is_constructible<DataType, DataArg>::value,
int> = 0>
122 ConstantDataWrapper(DataArg&& = DataArg{})
125 static_assert(!IsTypedValue<DataType>::value || IsDecay<DataType>::value,
126 "Typed values should not be stored as references.");
128 static constexpr T data() {
return T{}; }
134 struct ConstantDataWrapper<T,
std::enable_if_t<!IsTypedValue<T>::value> >
138 template<class DataArg, std::enable_if_t<std::is_constructible<DataType, DataArg>::value,
int> = 0>
139 ConstantDataWrapper(DataArg&& data = DataArg{})
140 : data_(std::forward<DataArg>(data))
146 decltype(
auto) data()
const&
151 decltype(
auto) data() &
167 template<
class Field, std::size_t... Dimensions>
168 class ConstantTensor<Field, Seq<Dimensions...> >
169 :
public TensorBase<std::decay_t<Field>, Seq<Dimensions...>, ConstantTensor<Field, Seq<Dimensions...> > >
170 ,
public ConstantDataWrapper<Field>
172 ,
public MPL::UniqueTags<ConditionalType<IsConstantExprArg<Field>::value, ConstantExpression, void>,
173 ConditionalType<IsTypedValue<Field>::value, TypedValueExpression, void> >
175 using ThisType = ConstantTensor;
177 using DataWrapperType = ConstantDataWrapper<Field>;
179 using BaseType::rank;
180 using typename BaseType::FieldType;
181 using typename BaseType::Signature;
182 using typename DataWrapperType::DataType;
183 using DataWrapperType::data;
186 template<class DataArg, std::enable_if_t<std::is_constructible<DataType, DataArg>::value,
int> = 0>
187 explicit ConstantTensor(DataArg&& data)
188 : DataWrapperType(std::forward<DataArg>(data))
194 std::enable_if_t<(
sizeof...(Dummy) == 0
206 template<
class... Dims,
207 std::enable_if_t<(
sizeof...(Dims) == rank
211 decltype(
auto)
operator()(Dims... indices)
const
218 template<std::size_t... Indices,
219 std::enable_if_t<(
sizeof...(Indices) == rank
220 && ThisType::template isZero<Indices...>()
225 return IntFraction<0>{};
229 template<std::size_t... Indices,
230 std::enable_if_t<(
sizeof...(Indices) == rank
231 && !ThisType::template isZero<Indices...>()
239 template<std::size_t... Indices,
class Pos =
MakeIndexSequence<
sizeof...(Indices)> >
240 static bool constexpr isZero(Seq<Indices...> = Seq<Indices...>{}, Pos = Pos{})
242 return ExpressionTraits<FieldType>::isZero;
246 template<
class... Whatever>
247 void lookAt(Whatever&&...)
250 std::string name()
const
253 if (std::is_same<DataType, IntFraction<0> >{}) {
255 }
else if(std::is_same<DataType, IntFraction<1> >{}) {
258 prefix =
"tensor<"+toString(data());
259 if (std::is_reference<DataType>::value) {
260 prefix += std::is_const<DataType>::value ?
"cref" :
"ref";
262 prefix += rank > 0 ?
"@" :
"";
265 return prefix+toString(Signature{})+
">";
269 template<std::size_t... Dimensions,
class T,
class F = Closure>
270 constexpr auto constantTensor(T&& t, Seq<Dimensions...> = Seq<Dimensions...>{}, F closure = F{})
272 using ValueType = ConditionalType<IsTypedValue<T>::value, std::decay_t<T>, T>;
273 return closure(ConstantTensor<ValueType, Seq<Dimensions...> >(std::forward<T>(t)));
276 template<
class T,
class Tensor,
class F = Closure,
277 std::enable_if_t<IsTensorOperand<Tensor>::value,
int> = 0>
278 constexpr auto constantTensor(T&& t, Tensor&&, F = F{})
280 using Signature =
typename TensorTraits<Tensor>::Signature;
281 return constantTensor(std::forward<T>(t), Signature{}, F{});
284 template<std::size_t... Dimensions,
class F = Closure>
285 auto zeros(Seq<Dimensions...> = Seq<Dimensions...>{}, F = F{})
287 return constantTensor(IntFraction<0>{}, Seq<Dimensions...>{}, F{});
290 template<
class T,
class F = Closure,
291 std::enable_if_t<IsTensor<T>::value,
int> = 0>
292 constexpr auto zeros(F = F{})
294 using Signature =
typename TensorTraits<T>::Signature;
295 return zeros(Signature{}, F{});
298 template<
class T,
class F = Closure,
299 std::enable_if_t<IsTensorOperand<T>::value,
int> = 0>
300 constexpr auto zeros(T&&, F = F{})
302 return zeros<T>(F{});
305 template<std::size_t... Dimensions,
class F = Closure>
306 constexpr auto ones(Seq<Dimensions...> = Seq<Dimensions...>{}, F = F{})
308 return constantTensor(IntFraction<1>{}, Seq<Dimensions...>{}, F{});
311 template<
class T,
class F = Closure,
312 std::enable_if_t<IsTensor<T>::value,
int> = 0>
313 constexpr auto ones(F = F{})
315 using Signature =
typename TensorTraits<T>::Signature;
316 return ones(Signature{}, F{});
319 template<
class T,
class F = Closure,
320 std::enable_if_t<IsTensor<T>::value,
int> = 0>
321 constexpr auto ones(T&&, F = F{})
327 using Zeros = ConditionalType<IsSequence<T>::value,
328 ConstantTensor<IntFraction<0>, T>,
329 ConstantTensor<IntFraction<0>,
typename TensorTraits<T>::Signature> >;
332 using Ones = ConditionalType<IsSequence<T>::value,
333 ConstantTensor<IntFraction<1>, T>,
334 ConstantTensor<IntFraction<1>,
typename TensorTraits<T>::Signature> >;
342 namespace Expressions {
344 template<
class T,
class Seq>
345 constexpr inline std::size_t WeightV<Tensor::ConstantTensor<T, Seq> > = WeightV<std::decay_t<T> >;
351 template<
class Field,
class Signature>
352 struct FieldTraits<ACFem::Tensor::ConstantTensor<Field, Signature> >
353 : FieldTraits<std::decay_t<Field> >
decltype(auto) constexpr operator()(Seq< Indices... >) const
Constant access from index-sequence, zero optimization.
Definition: constant.hh:222
ConstantTensor(Dummy &&...)
Allow default construction if contained types fulfill IsTypedValue.
Definition: constant.hh:196
BoolConstant< ExpressionTraits< T >::isTypedValue > IsTypedValue
Compile-time true if T is a "typed value", e.g. a std::integral_constant.
Definition: expressiontraits.hh:90
MakeSequence< std::size_t, N, Offset, Stride, Repeat > MakeIndexSequence
Make a sequence of std::size_t elements.
Definition: generators.hh:34
decltype(isIntegralPack(std::declval< T >()...)) IsIntegralPack
Decide whether the given parameter pack contains only integral types.
Definition: compare.hh:377
BoolConstant< false > FalseType
Alias for std::false_type.
Definition: types.hh:110
BoolConstant< true > TrueType
Alias for std::true_type.
Definition: types.hh:107
Terminals may derive from this class to express that they are expressions.
Definition: terminal.hh:25
Base class for all tensors.
Definition: tensorbase.hh:144