#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; typedef OperationRoot OpCD; typedef OperationRoot OpD; extern template class OperationRoot; extern template class OperationRoot; template DynamicO mkDynOp1(const Op& op); std::shared_ptr mkSubSpaceX(const std::shared_ptr& di, size_t max); template class HighLevelOpBase { public: typedef OperationValue VOP; 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" reg_ind1(ClassicRange::IndexType); reg_ind2(ClassicRange::IndexType,ClassicRange::IndexType); reg_ind3(ClassicRange::IndexType,ClassicRange::IndexType,ClassicRange::IndexType); #undef reg_ind1 #undef reg_ind2 #undef reg_ind3 virtual ROP* get() = 0; virtual VOP* vget() = 0; }; template class HighLevelOpRoot : public HighLevelOpBase { private: typedef HighLevelOpBase B; typedef typename B::VOP VOP; 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" reg_ind1(ClassicRange::IndexType); reg_ind2(ClassicRange::IndexType,ClassicRange::IndexType); reg_ind3(ClassicRange::IndexType,ClassicRange::IndexType,ClassicRange::IndexType); virtual ROP* get() override final; virtual VOP* vget() override final; }; extern template class HighLevelOpBase; extern template class HighLevelOpBase; extern template class HighLevelOpRoot; extern template class HighLevelOpRoot; template class HighLevelOpValue : public HighLevelOpBase { private: typedef HighLevelOpBase B; typedef typename B::VOP VOP; template typename B::template RetT xcreate(const std::shared_ptr&... inds); VOP mOp; public: HighLevelOpValue(const VOP& vop); virtual bool root() const override final; //#include "hl_reg_ind.h" reg_ind1(ClassicRange::IndexType); reg_ind2(ClassicRange::IndexType,ClassicRange::IndexType); reg_ind3(ClassicRange::IndexType,ClassicRange::IndexType,ClassicRange::IndexType); virtual ROP* get() override final; virtual VOP* vget() override final; }; template auto mkFOp(const Ops&... ops) { return Operation(ops...); } template class HighLevelOp : public HighLevelOpBase { public: typedef HighLevelOpBase B; typedef typename B::VOP VOP; 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 ROP* get() override final; virtual VOP* vget() override final; //#include "hl_reg_ind.h" reg_ind1(ClassicRange::IndexType); reg_ind2(ClassicRange::IndexType,ClassicRange::IndexType); reg_ind3(ClassicRange::IndexType,ClassicRange::IndexType,ClassicRange::IndexType); #undef reg_ind1 #undef reg_ind2 #undef reg_ind3 }; extern template class HighLevelOp,2>; extern template class HighLevelOp,2>; extern template class HighLevelOp,2>; extern template class HighLevelOp,2>; extern template class HighLevelOp,2>; extern template class HighLevelOp,2>; extern template class HighLevelOp,2>; extern template class HighLevelOp,2>; #define regFunc1(fff) \ extern template class HighLevelOp,1>; \ extern template class HighLevelOp,1>; #include "extensions/math.h" #undef regFunc1 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() -> 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& xassign(const HighLevelOpHolder& in, const std::shared_ptr& di, const std::shared_ptr&... is); template HighLevelOpHolder& xplus(const HighLevelOpHolder& in, const std::shared_ptr& di, const std::shared_ptr&... is); 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); }; extern template class HighLevelOpHolder; extern template class HighLevelOpHolder; template HighLevelOpHolder mkSFunc(const HighLevelOpHolder& a, const HighLevelOpHolder&... as); template HighLevelOpHolder mkHLO(const ROP& op); template HighLevelOpHolder mkHLOV(double val); extern template HighLevelOpHolder mkHLO(const OpCD& op); extern template HighLevelOpHolder mkHLO(const OpD& op); extern template HighLevelOpHolder mkHLOV(double val); extern template HighLevelOpHolder mkHLOV(double val); #define regFunc1(fff) template \ HighLevelOpHolder hl_##fff (const HighLevelOpHolder& in); #include "extensions/math.h" #undef regFunc1 #define regFunc1(fff) template \ HighLevelOpHolder hl_##fff (const HighLevelOpHolder& in); \ extern template HighLevelOpHolder hl_##fff (const HighLevelOpHolder& in); \ extern template HighLevelOpHolder hl_##fff (const HighLevelOpHolder& in); #include "extensions/math.h" #undef regFunc1 } #endif