// -*- 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() /*{ CHECK; }*/ = default; virtual ~MultiArrayOperationBase(); virtual size_t argNum() const = 0; const IndefinitIndexBase& index() const; virtual IndefinitIndexBase* getLinked(const std::string& name) const = 0; virtual void linkIndicesTo(IndefinitIndexBase* target) const = 0; virtual const T& get() const = 0; virtual void setInternalLinks() const {} virtual void freeIndex() const; protected: mutable IndefinitIndexBase* mIibPtr = nullptr; }; template class MutableMultiArrayOperationBase : public MultiArrayOperationBase { public: MutableMultiArrayOperationBase() /*{ CHECK; }*/ = default; virtual T& get() = 0; }; template class MultiArrayOperationRoot : public MutableMultiArrayOperationBase { public: typedef MultiArrayOperationBase MAOB; typedef typename Range::IndexType IndexType; //typedef decltype(MultiArray().begin()) IndexType; MultiArrayOperationRoot(MutableMultiArrayBase& ma, const Name& nm); MultiArrayOperationRoot& operator=(const MultiArrayOperationRoot& in); MultiArrayOperationRoot& operator=(MultiArrayOperationRoot& in); template MultiArrayOperationRoot& operator=(MultiArrayOperationRoot& in); template const MultiArrayOperationRoot& operator=(const MultiArrayOperationRoot& in); template MultiArrayOperationRoot& operator=(const MultiArrayOperation& in); template MultiArrayOperationRoot& operator=(const MultiArrayContraction& in); //template //MultiArrayOperation, MAOps...> //operator()(Operation& op, const MAOps&... secs) const; template MultiArrayOperation, MAOps...> operator()(const Operation& op, const MAOps&... secs) const; template < class Range2, class ContractOperation, class... MAOps> MultiArrayContraction, MAOps...> contract(const ContractOperation& cop, const std::string& indexName, const MAOps&... mao) const; template MultiArrayContraction, MAOps...> contract(const ContractOperation& cop, const std::string& indexName, size_t begin, size_t end, const MAOps&... mao) const; 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)); MultiArrayOperationRoot copyThis(); template MultiArrayOperationRoot& operator+=(const MAOp& sec); template MultiArrayOperationRoot& operator-=(const MAOp& sec); template MultiArrayOperationRoot& operator*=(const MAOp& sec); template MultiArrayOperationRoot& operator/=(const MAOp& sec); const MultiArrayBase& operator*() const; //MultiArrayBase& operator*(); MultiArrayBase const* operator->() const; virtual size_t argNum() const override; // set index -> implement !!!!! MultiArrayOperationRoot& operator[](const IndexType& ind); const MultiArrayOperationRoot& operator[](const IndexType& ind) const; virtual IndefinitIndexBase* getLinked(const std::string& name) const override; virtual void linkIndicesTo(IndefinitIndexBase* target) const override; virtual T& get() override; virtual const T& get() const override; const Name& name() const; virtual void freeIndex() const override; const MultiArrayBase& getCont() const { return mArrayRef; } template friend class MultiArrayOperationRoot; template friend class ConstMultiArrayOperationRoot; protected: void performAssignment(const MultiArrayOperationBase& in); /* template MultiArrayOperationRoot& makeSlice(MultiArrayOperationRoot& in); template const MultiArrayOperationRoot& makeConstSlice(const MultiArrayOperationRoot& in); */ MutableMultiArrayBase& mArrayRef; mutable IndexType mIndex; Name mNm; }; template class ConstMultiArrayOperationRoot : public MultiArrayOperationBase { public: typedef MultiArrayOperationBase MAOB; typedef typename Range::IndexType IndexType; //typedef decltype(MultiArray().begin()) IndexType; ConstMultiArrayOperationRoot(const MultiArrayBase& ma, const Name& nm); ConstMultiArrayOperationRoot(const MultiArrayOperationRoot& in); template MultiArrayOperation, MAOps...> operator()(const Operation& op, const MAOps&... secs) const; template MultiArrayContraction, MAOps...> contract(const ContractOperation& cop, const std::string& indexName, const MAOps&... mao) const; template MultiArrayContraction, MAOps...> contract(const ContractOperation& cop, const std::string& indexName, size_t begin, size_t end, const MAOps&... mao) const; template auto operator+(const MAOp& sec) const -> decltype(operator()(std::plus(), sec)); template auto operator-(const MAOp& sec) const -> decltype(operator()(std::minus(), sec)); template auto operator*(const MAOp& sec) const -> decltype(operator()(std::multiplies(), sec)); template auto operator/(const MAOp& sec) const -> decltype(operator()(std::divides(), sec)); ConstMultiArrayOperationRoot copyThis() const; const MultiArrayBase& operator*() const; //MultiArrayBase& operator*(); MultiArrayBase const* operator->() const; virtual size_t argNum() const override; // set index -> implement !!!!! const ConstMultiArrayOperationRoot& operator[](const IndexType& ind) const; virtual IndefinitIndexBase* getLinked(const std::string& name) const override; virtual void linkIndicesTo(IndefinitIndexBase* target) const override; virtual const T& get() const override; const Name& name() const; virtual void freeIndex() const override; const MultiArrayBase& getCont() const { return mArrayRef; } template friend class ConstMultiArrayOperationRoot; template friend class MultiArrayOperationRoot; protected: /* template const ConstMultiArrayOperationRoot& makeConstSlice(const ConstMultiArrayOperationRoot& in); template const ConstMultiArrayOperationRoot& makeConstSlice(const MultiArrayOperationRoot& in); */ // const MultiArrayBase const& 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) const; template MultiArrayOperation,MAOps2...> operator()(const Operation2& op, const MAOps2&... secs) const; template MultiArrayContraction,MAOps2...> contract(const ContractOperation& cop, const std::string& indexName, const MAOps2&... mao) const; 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 IndefinitIndexBase* getLinked(const std::string& name) const override; virtual void linkIndicesTo(IndefinitIndexBase* target) const override; virtual const T& get() const override; protected: mutable T mVal; Operation mOp; OBT mArgs; // include first arg also here !!! }; template class MultiArrayContraction : public MultiArrayOperationBase { public: typedef MultiArrayOperationBase MAOB; typedef std::tuple OBT; MultiArrayContraction(const ContractOperation& cop, const typename Range::IndexType& runIndex, const MAOps&... args); MultiArrayContraction(const ContractOperation& cop, const typename Range::IndexType& runIndex, size_t begin, size_t end, const MAOps&... mao); template MultiArrayOperation,MAOps2...> operator()(Operation2& op, const MAOps2&... secs) const; template MultiArrayOperation,MAOps2...> operator()(const Operation2& op, const MAOps2&... secs) const; template MultiArrayContraction,MAOps2...> contract(const ContractOperation2& cop, const std::string& indexName, const MAOps2&... mao) const; 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 void setInternalLinks() const override; virtual size_t argNum() const override; virtual IndefinitIndexBase* getLinked(const std::string& name) const override; virtual void linkIndicesTo(IndefinitIndexBase* target) const override; virtual const T& get() const override; protected: mutable T mVal; ContractOperation mOp; OBT mArgs; // include first arg also here !!! typename Range::IndexType mBeginIndex; typename Range::IndexType mEndIndex; mutable typename Range::IndexType mRunIndex; }; /* template class MultiArrayContraction : public MultiArrayOperation { public: typedef MultiArrayOperationBase MAOB; typedef MultiArrayOperation MAO; MultiArrayContraction(const ContractOperation& cop, const typename Range::IndexType& runIndex, const MAOps&... mao); MultiArrayContraction(const ContractOperation& cop, const typename Range::IndexType& runIndex, size_t begin, size_t end, const MAOps&... mao); virtual const T& get() const override; protected: typename Range::IndexType mBeginIndex; typename Range::IndexType mEndIndex; mutable typename Range::IndexType mRunIndex; }; */ } #include "multi_array_operation.cc" #endif