#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; #define reg_ind1(I1) virtual RetT create \ (const std::shared_ptr& ind1) = 0 #define reg_ind2(I1,I2) virtual RetT create \ (const std::shared_ptr& ind1,const std::shared_ptr& ind2) = 0 #define reg_ind3(I1,I2,I3) virtual RetT create \ (const std::shared_ptr& ind1,const std::shared_ptr& ind2,const std::shared_ptr& ind3) = 0 #include "hl_reg_ind.h" #undef reg_ind1 #undef reg_ind2 #undef reg_ind3 virtual const ROP* get() const = 0; }; template class HighLevelOpRoot : public HighLevelOpBase { private: typedef HighLevelOpBase B; template typename B::template RetT xcreate(const std::shared_ptr&... inds); ROP mOp; public: HighLevelOpRoot(const ROP& op); virtual bool root() const override final; #define reg_ind1(I1) virtual typename B::template RetT create \ (const std::shared_ptr& ind1) \ override final { return xcreate(ind1); } #define reg_ind2(I1,I2) virtual typename B::template RetT create \ (const std::shared_ptr& ind1, const std::shared_ptr& ind2) \ override final { return xcreate(ind1,ind2); } #define reg_ind3(I1,I2,I3) virtual typename B::template RetT create \ (const std::shared_ptr& ind1, const std::shared_ptr& ind2, const std::shared_ptr& ind3) \ override final { return xcreate(ind1,ind2,ind3); } #include "hl_reg_ind.h" virtual const ROP* get() const override final; }; template auto mkFOp(const Ops&... ops) { return Operation(ops...); } template class HighLevelOp : public HighLevelOpBase { public: typedef HighLevelOpBase B; private: std::array>,N> mIn; template auto xcreate(const std::shared_ptr&... inds) -> typename B::template RetT; public: HighLevelOp(std::array>,N> in); virtual bool root() const override final; virtual const ROP* get() const override final; #include "hl_reg_ind.h" #undef reg_ind1 #undef reg_ind2 #undef reg_ind3 }; 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; template auto create(const std::shared_ptr&... inds) const -> decltype(mOp->create(inds...)); 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); #define SP " " #define regFunc1(fff) template \ HighLevelOpHolder hl_##fff (const HighLevelOpHolder& in); #include "extensions/math.h" #undef regFunc1 #undef SP template struct SetLInds { template static inline void mkLIT(const ITuple& itp, const std::shared_ptr& di); template struct xx { template static inline void assign(Tar& tar, const Args&... args, const ITp& itp, const std::shared_ptr&... is); template static inline void plus(Tar& tar, const Args&... args, const ITp& itp, const std::shared_ptr&... is); }; }; template <> struct SetLInds<0> { template static inline void mkLIT(const ITuple& itp, const std::shared_ptr& di); template struct xx { template static inline void assign(Tar& tar, const Args&... args, const ITp& itp, const std::shared_ptr&... is); template static inline void plus(Tar& tar, const Args&... args, const ITp& itp, const std::shared_ptr&... is); }; }; template struct INDS { class CallHLOpBase { private: size_t mDepth; public: size_t depth() const; void assign(const HighLevelOpHolder& target, const HighLevelOpHolder& source, const std::shared_ptr&... is, const std::shared_ptr& di) const = 0; void plus(const HighLevelOpHolder& target, const HighLevelOpHolder& source, const std::shared_ptr&... is, const std::shared_ptr& di) const = 0; }; template class CallHLOp { private: typedef std::tuple...> ITuple; static vector> sNext; public: void assign(HighLevelOpHolder& target, const HighLevelOpHolder& source, const std::shared_ptr&... is, const std::shared_ptr& di) const override final; void plus(HighLevelOpHolder& target, const HighLevelOpHolder& source, const std::shared_ptr&... is, const std::shared_ptr& di) const override final; }; }; } #endif