Fastor
Fastor copied to clipboard
Move assignment functions to a namespace
Moving things to a namespace requires the definition of assign to be available while declaring the tensor which requires pre-including a lot of header files in Tensor.h. There is got to be a better way.
Maybe a class with specialisation would be nicer way
template<typename TLhs, typename TRhs, size_t DIM>
struct assignment<BinaryMulOp<TLhs,TRhs,DIM>> {
assign(...,...);
};
The above method does work for instance for tensor assignment
template<typename T, size_t ...Rest>
struct assignment<Tensor<T,Rest...>> {
template<typename Derived, size_t DIM>
static FASTOR_INLINE void assign(AbstractTensor<Derived,DIM> &dst, const Tensor<T,Rest...> &src) {
if (dst.self().data()==src.data()) return;
trivial_assign(dst.self(),src);
}
template<typename Derived, size_t DIM>
static FASTOR_INLINE void assign_add(AbstractTensor<Derived,DIM> &dst, const Tensor<T,Rest...> &src) {
trivial_assign_add(dst.self(),src);
}
template<typename Derived, size_t DIM>
static FASTOR_INLINE void assign_sub(AbstractTensor<Derived,DIM> &dst, const Tensor<T,Rest...> &src) {
trivial_assign_sub(dst.self(),src);
}
template<typename Derived, size_t DIM>
static FASTOR_INLINE void assign_mul(AbstractTensor<Derived,DIM> &dst, const Tensor<T,Rest...> &src) {
trivial_assign_mul(dst.self(),src);
}
template<typename Derived, size_t DIM>
static FASTOR_INLINE void assign_div(AbstractTensor<Derived,DIM> &dst, const Tensor<T,Rest...> &src) {
trivial_assign_div(dst.self(),src);
}
};
and all unary math op assignments in a single macro
// arithmetic assignments
#define FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT_FUNC(OP, NAME, ASSIGN_TYPE)\
template<typename Derived, size_t DIM, typename OtherDerived = Derived_, size_t OtherDIM = DIM_,\
typename std::enable_if<requires_evaluation_v<OtherDerived>,bool>::type = false>\
static FASTOR_INLINE void assign ##ASSIGN_TYPE (AbstractTensor<Derived,DIM> &dst, const Unary ##NAME ## Op<OtherDerived,OtherDIM> &src) {\
using result_type = typename Unary ##NAME ## Op<OtherDerived,OtherDIM>::result_type;\
const result_type tmp(src.expr().self());\
trivial_assign ##ASSIGN_TYPE (dst.self(), sqrt(tmp));\
}\
template<typename Derived, size_t DIM, typename OtherDerived = Derived_, size_t OtherDIM = DIM_,\
typename std::enable_if<!requires_evaluation_v<OtherDerived>,bool>::type = false>\
static FASTOR_INLINE void assign ##ASSIGN_TYPE (AbstractTensor<Derived,DIM> &dst, const Unary ##NAME ## Op<OtherDerived,OtherDIM> &src) {\
trivial_assign ##ASSIGN_TYPE (dst.self(), src.self());\
}\
#define FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(OP, NAME)\
template<typename Derived_, size_t DIM_>\
struct assignment<Unary ##NAME ## Op<Derived_,DIM_>> {\
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT_FUNC(OP, NAME, )\
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT_FUNC(OP, NAME, _add)\
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT_FUNC(OP, NAME, _sub)\
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT_FUNC(OP, NAME, _mul)\
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT_FUNC(OP, NAME, _div)\
};\
// FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(sqrt, Sqrt)
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT( , Add )
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(-, Sub )
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(abs, Abs )
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(sqrt, Sqrt)
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(exp, Exp )
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(log, Log )
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(sin, Sin )
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(cos, Cos )
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(tan, Tan )
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(asin, Asin)
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(acos, Acos)
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(atan, Atan)
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(sinh, Sinh)
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(cosh, Cosh)
FASTOR_MAKE_UNARY_MATH_OP_ARITHMETIC_ASSIGNMENT(tanh, Tanh)
without changing headers like the namespace solution. The tensor constructor would then just call
template<typename Derived, size_t DIMS>
FASTOR_INLINE Tensor(const AbstractTensor<Derived,DIMS>& src) {
FASTOR_ASSERT(src.self().size()==size(), "TENSOR SIZE MISMATCH");
assignment<Derived>::assign(*this, src.self());
}
However, this seems like a lot work for encapsulation plus two separate types need to be provided one for the struct assignment itself like assignment<Derived>::assign<DerivedAssignTo,DerivedAssignFrom> where is with free functions Derived and DerivedAssignFrom are the same.
Removing milestone from this for now