#ifndef __high_level_operation_h__ #define __high_level_operation_h__ #include "base_def.h" #include "ranges/rheader.h" #include "dynamic_operation.h" namespace MultiArrayTools { typedef ClassicRange CR; typedef CR::IndexType CI; typedef std::shared_ptr CIP; template DynamicO mkDynOp1(const Op& op); template class HighLevelOpBase { public: template struct RetT { DynamicO>> op; DynamicO outer; template void appendOuterM(const Op& op, const Ops&... ops); void appendOuterM(); void appendOuter(const DynamicO& in); void appendOuter(const RetT& in); }; virtual bool root() const = 0; virtual RetT create(const std::shared_ptr ind1, const std::shared_ptr ind2) = 0; virtual const ROP* get() const = 0; }; template class HighLevelOpRoot : public HighLevelOpBase { private: typedef HighLevelOpBase B; ROP mOp; public: HighLevelOpRoot(const ROP& op); virtual bool root() const override final; virtual typename B::RetT create(const std::shared_ptr ind1, const std::shared_ptr ind2) override final; virtual const ROP* get() const override final; }; template auto mkFOp(const Ops&... ops) { return Operation(ops...); } template class HighLevelOp : public HighLevelOpBase { private: std::array>,N> mIn; public: typedef HighLevelOpBase B; HighLevelOp(std::array>,N> in); virtual bool root() const override final; virtual const ROP* get() const override final; virtual typename B::RetT create(const std::shared_ptr ind1, const std::shared_ptr ind2) override final; }; template class HighLevelOpHolder { private: std::shared_ptr> mOp; public: HighLevelOpHolder() = default; HighLevelOpHolder(const HighLevelOpHolder& in) = default; HighLevelOpHolder(HighLevelOpHolder&& in) = default; HighLevelOpHolder& operator=(const HighLevelOpHolder& in) = default; HighLevelOpHolder& operator=(HighLevelOpHolder&& in) = default; HighLevelOpHolder(const std::shared_ptr>& op); bool root() const; auto create(const std::shared_ptr ind1, const std::shared_ptr ind2) const -> decltype(mOp->create(ind1,ind2)); auto get() const -> decltype(mOp->get()); std::shared_ptr> op() const; HighLevelOpHolder operator*(const HighLevelOpHolder& in) const; HighLevelOpHolder operator+(const HighLevelOpHolder& in) const; HighLevelOpHolder operator-(const HighLevelOpHolder& in) const; HighLevelOpHolder operator/(const HighLevelOpHolder& in) const; template HighLevelOpHolder& assign(const HighLevelOpHolder& in, const std::shared_ptr& mi, const std::shared_ptr&... inds); template HighLevelOpHolder& plus(const HighLevelOpHolder& in, const std::shared_ptr& mi, const std::shared_ptr&... inds); }; template HighLevelOpHolder mkHLO(const ROP& op); template HighLevelOpHolder exp(const HighLevelOpHolder& in); } #endif