// -*- C++ -*- #ifndef __multi_array_operation_h__ #define __multi_array_operation_h__ #include #include #include #include #include #include #include "base_def.h" #include "mbase_def.h" #include "ranges/rheader.h" #include "arith.h" #include "xfor/xfor.h" #include "type_operations.h" #include "statics/static_for.h" namespace MultiArrayTools { namespace { using namespace MultiArrayHelper; } template class OperationBase { public: OperationClass& THIS() { return static_cast(*this); } const OperationClass& THIS() const { return static_cast(*this); } template auto operator+(const OperationBase& in) const; template auto operator-(const OperationBase& in) const; template auto operator*(const OperationBase& in) const; template auto operator/(const OperationBase& in) const; template auto c(const std::shared_ptr& ind) const; template auto sl(const std::shared_ptr&... inds) const; template auto p(const std::shared_ptr&... inds) const; template auto to(const std::shared_ptr&... inds) const; template auto addto(const std::shared_ptr&... inds) const; template auto pto(const std::shared_ptr&... inds) const; template auto paddto(const std::shared_ptr&... inds) const; template // Args = Operation Classes auto a(const std::shared_ptr>& ll, const Args&... args) const; auto ptr() const; private: friend OperationClass; friend OperationTemplate; OperationBase() = default; }; template class OperationTemplate : public OperationBase { /* empty per default; specialize if needed */ private: OperationTemplate() = default; friend OperationClass; }; template struct SelfIdentity { static inline T& sapply(T& a, T b) { return a = b; } }; enum class OpIndexAff { EXTERN = 0, TARGET = 1 }; template struct VType { typedef T type; static constexpr size_t MULT = sizeof(type)/sizeof(T); }; template <> struct VType { typedef v256 type; static constexpr size_t MULT = sizeof(type)/sizeof(double); }; template