diff --git a/src/tests/op4_unit_test.h b/src/tests/op4_unit_test.h index d25fb0e..61f7eda 100644 --- a/src/tests/op4_unit_test.h +++ b/src/tests/op4_unit_test.h @@ -13,51 +13,6 @@ DynamicO mkDynOp1(const Op& op) return DynamicO(op); } - -class OpHolderBase -{ -public: - virtual std::string stype() const = 0; - virtual size_t ntype() const = 0; -}; - -template -struct OpName -{ - static std::string sget() - { - return "none"; - } - - static size_t nget() - { - return 0; - } -}; - -template -class OpHolder : public OpHolderBase -{ -private: - Op mOp; -public: - - OpHolder(const Op& op) : mOp(op) {} - - virtual std::string stype() const override final - { - return OpName::sget(); - } - - virtual size_t ntype() const override final - { - return OpName::nget(); - } - -}; - - - class HighLevelOpBase { public: @@ -66,23 +21,27 @@ public: typedef OperationRoot OpCD; typedef OperationRoot OpD; + template struct RetT { - DynamicO> op; + DynamicO>> op; DynamicO outer; - template - void appendOuterM(const Ops&... ops) + template + void appendOuterM(const Op& op, const Ops&... ops) { // does not check anything regarding input !!! if(outer.init()){ - outer = mkDynOp1(mkMOp(outer,ops...)); + outer = mkDynOp1(mkMOp(outer,op,ops...)); } else { - outer = mkDynOp1(mkMOp(ops...)); + outer = mkDynOp1(mkMOp(op,ops...)); } } - + + void appendOuterM() + {} + void appendOuter(const DynamicO& in) { if(in.init()){ @@ -104,8 +63,8 @@ public: virtual bool root() const = 0; - virtual RetT create(const std::shared_ptr ind1, - const std::shared_ptr ind2) = 0; + virtual RetT create(const std::shared_ptr ind1, + const std::shared_ptr ind2) = 0; virtual const OperationRoot* get1() const = 0; virtual const OperationRoot* get2() const = 0; @@ -151,11 +110,11 @@ public: return true; } - virtual B::RetT create(const std::shared_ptr ind1, - const std::shared_ptr ind2) override final + virtual B::RetT create(const std::shared_ptr ind1, + const std::shared_ptr ind2) override final { assert(0); - return B::RetT(); + return B::RetT(); } virtual const OType1* get1() const override final @@ -171,103 +130,117 @@ public: }; +template +auto mkFOp(const Ops&... ops) +{ + return Operation(ops...); +} -template -class HighLevelOp2 : public HighLevelOpBase + +template +struct Create +{ + template + struct cx + { + template + struct ccx + { + template + static inline void + cccx(HighLevelOpBase::RetT& res, + const std::array,M>& in, + const std::shared_ptr&... inds, + const OPs&... ops, + const DOPs&... dops) + { + static_assert(N > 0, "N > 0 failed"); + auto& inn = std::get(in); + if(not inn->root()){ + auto dop = inn->create(inds...); + auto op = *dop.op.data()->mOp; + typedef decltype(op) OP; + res.appendOuter(dop); + Create::template cx::template ccx::template cccx + (res, in, inds..., op, ops..., dop, dops...); + } + else { + auto& op = *inn->get2(); + typedef typename std::remove_reference::type OP; + Create::template cx::template ccx::template cccx + (res, in, inds..., op, ops..., dops...); + } + } + }; + }; +}; + +template <> +struct Create<0> +{ + template + struct cx + { + template + struct ccx + { + template + static inline void + cccx(HighLevelOpBase::RetT& res, + const std::array,M>& in, + const std::shared_ptr&... inds, + const OPs&... ops, + const DOPs&... dops) + { + auto& inn = std::get<0>(in); + if(not inn->root()){ + auto dop = inn->create(inds...); + auto op = *dop.op.data()->mOp; + res.appendOuter(dop); + res.op = mkDynOutOp(mkFOp(op,ops...), inds...); + res.appendOuterM(dop.op,dops.op...); + } + else { + auto& op = *inn->get2(); + res.op = mkDynOutOp(mkFOp(op,ops...), inds...); + res.appendOuterM(dops.op...); + } + } + }; + }; +}; + +template +class HighLevelOp : public HighLevelOpBase { private: - std::shared_ptr mIn1; - std::shared_ptr mIn2; + std::array,N> mIn; public: typedef HighLevelOpBase B; - typedef Operation OxCCxCC; - typedef Operation OxCDxCD; - typedef Operation OxCCxCD; - typedef Operation OxCDxCC; - HighLevelOp2(const std::shared_ptr& in1, - const std::shared_ptr& in2) : mIn1(in1), mIn2(in2) {} + HighLevelOp(std::array,N> in) : mIn(in) {} virtual bool root() const override final { return false; } + virtual const OperationRoot* get1() const override final { assert(0); return nullptr; } virtual const OperationRoot* get2() const override final { assert(0); return nullptr; } - virtual B::RetT create(const std::shared_ptr ind1, + virtual B::RetT create(const std::shared_ptr ind1, const std::shared_ptr ind2) override final { - B::RetT res; - if(not mIn2->root()){ - auto dop2 = mIn2->create(ind1,ind2); - auto op2 = *dop2.op.data()->mOp; - res.outer = dop2.outer; - if(not mIn1->root()){ - auto dop1 = mIn1->create(ind1,ind2); - auto op1 = *dop1.op.data()->mOp; - res.op = mkDynOutOp(OxCCxCC(op1,op2), ind1, ind2); - res.appendOuter(dop1); - res.appendOuterM(dop1.op,dop2.op); - return res; - } - else { - const OperationRoot& op1 = *mIn1->get2(); - res.op = mkDynOutOp(OxCDxCC(op1,op2), ind1, ind2); - res.appendOuterM(dop2.op); - return res; - } - } - assert(0); + B::RetT res; + Create::template cx::template ccx::template cccx(res,mIn,ind1,ind2); return res; } }; -template -class HighLevelOp1 : public HighLevelOpBase -{ -private: - std::shared_ptr mIn1; -public: - typedef HighLevelOpBase B; - typedef Operation OxCC; - typedef Operation OxCD; - - HighLevelOp1(const std::shared_ptr& in1) : mIn1(in1) {} - - virtual bool root() const override final - { - return false; - } - virtual const OperationRoot* get1() const override final - { assert(0); return nullptr; } - virtual const OperationRoot* get2() const override final - { assert(0); return nullptr; } - - virtual B::RetT create(const std::shared_ptr ind1, - const std::shared_ptr ind2) override final - { - if(not mIn1->root()){ - auto dop1 = mIn1->create(ind1,ind2); - auto op1 = *dop1.op.data()->mOp; - dop1.appendOuterM(dop1.op); - dop1.op = mkDynOutOp(OxCC(op1), ind1, ind2); - return dop1; - } - else { - const OperationRoot& op1 = *mIn1->get2(); - B::RetT res; - res.op = mkDynOutOp(OxCD(op1), ind1, ind2); - return res; - } - } - - -}; class HighLevelOpHolder { @@ -296,8 +269,8 @@ public: HighLevelOpHolder operator*(const HighLevelOpHolder in) const { return HighLevelOpHolder - ( std::make_shared>> - ( mOp, in.mOp ) ); + ( std::make_shared,2>> + ( std::array,2>({mOp, in.mOp}) ) ); } }; @@ -309,5 +282,6 @@ HighLevelOpHolder mkHLO(const OR& op) HighLevelOpHolder exp(const HighLevelOpHolder& in) { - return HighLevelOpHolder( std::make_shared>>( in.op() ) ); + return HighLevelOpHolder( std::make_shared,1>> + ( std::array,1>( {in.op()} ) ) ); }