// -*- C++ -*- #ifndef __multi_array_operation_h__ #define __multi_array_operation_h__ #include #include #include "base_def.h" #include "index_base.h" namespace MultiArrayTools { template class MultiArrayOperationBase { public: MultiArrayOperationBase() = default; virtual ~MultiArrayOperationBase(); virtual size_t argNum() const = 0; IndefinitIndexBase* index(); virtual void linkIndicesTo(IndefinitIndexBase* target) const = 0; virtual T& get() = 0; virtual const T& get() const = 0; protected: IndefinitIndexBase* mIibPtr = nullptr; }; template class MultiArrayOperationRoot : public MultiArrayOperationBase { public: typedef MultiArrayOperationBase MAOB; typedef decltype(MultiArray().begin()) IndexType; MultiArrayOperationRoot(MultiArrayBase& ma, const Name& nm); MultiArrayOperationRoot& operator=(const MultiArrayOperationRoot& in); MultiArrayOperationRoot& operator=(MultiArrayOperationRoot& in); template MultiArrayOperationRoot& operator=(MultiArrayOperationRoot& in); template MultiArrayOperationRoot& operator=(const MultiArrayOperation& in); template MultiArrayOperation, MAOps...> operator()(Operation& op, const MAOps&... secs); template MultiArrayOperation, MAOps...> operator()(const Operation& op, const MAOps&... secs); template auto operator+(const MAOp& sec) -> decltype(operator()(std::plus(), sec)); template auto operator-(const MAOp& sec) -> decltype(operator()(std::minus(), sec)); template auto operator*(const MAOp& sec) -> decltype(operator()(std::multiplies(), sec)); template auto operator/(const MAOp& sec) -> decltype(operator()(std::divides(), sec)); virtual size_t argNum() const override; IndexType& index(); // set index MultiArrayOperationRoot& operator[](const IndexType& ind); virtual void linkIndicesTo(IndefinitIndexBase* target) const override; virtual T& get() override; virtual const T& get() const override; const Name& name() const; protected: void performAssignment(const MultiArrayOperationBase& in); template MultiArrayOperationRoot& makeSlice(MultiArrayOperationRoot& in); MultiArrayBase& mArrayRef; mutable IndexType mIndex; Name mNm; }; template class MultiArrayOperation : public MultiArrayOperationBase { public: typedef MultiArrayOperationBase MAOB; typedef std::tuple OBT; MultiArrayOperation(Operation& op, const MAOps&... secs); MultiArrayOperation(const Operation& op, const MAOps&... secs); template MultiArrayOperation,MAOps2...> operator()(Operation2& op, const MAOps2&... secs); template MultiArrayOperation,MAOps2...> operator()(const Operation2& op, const MAOps2&... secs); template auto operator+(const MAOp2& sec) -> decltype(operator()(std::plus(), sec)); template auto operator-(const MAOp2& sec) -> decltype(operator()(std::minus(), sec)); template auto operator*(const MAOp2& sec) -> decltype(operator()(std::multiplies(), sec)); template auto operator/(const MAOp2& sec) -> decltype(operator()(std::divides(), sec)); virtual size_t argNum() const override; virtual void linkIndicesTo(IndefinitIndexBase* target) const override; virtual T& get() override; virtual const T& get() const override; protected: mutable T mVal; Operation mOp; OBT mArgs; // include first arg also here !!! }; } #include "multi_array_operation.cc" #endif