// -*- C++ -*- #ifndef __pack_num_h__ #define __pack_num_h__ #include //#include #include #include #include "base_def.h" namespace MultiArrayHelper { template struct PackNum { template static void makeBlockTypeVec(std::vector >& btv, const std::tuple& ops, std::shared_ptr idxPtr, bool init) { auto subvec = std::move( std::get(ops).block(idxPtr, init) ); btv.insert(btv.end(), subvec.begin(), subvec.end() ); PackNum::makeBlockTypeVec(btv, ops, idxPtr, init); } template static void makeBlockTypeVec(std::vector >& btv, const std::tuple& ops, const IndexInfo* idxPtr, bool init) { auto subvec = std::move( std::get(ops).block(idxPtr, init) ); btv.insert(btv.end(), subvec.begin(), subvec.end() ); PackNum::makeBlockTypeVec(btv, ops, idxPtr, init); } template static void unpackArgs(BlockResult& res, const ArgTuple& tp, const Args&... args) { PackNum::template unpackArgs(res, tp, std::get(tp).get(), args...); } template static void printTuple(std::ostream& out, const std::tuple& tp) { out << std::get(tp) << ", "; PackNum::printTuple(out, tp); } template static auto mkStepTuple(std::intptr_t ii, std::tuple otp) -> decltype(std::tuple_cat( PackNum::mkStepTuple(ii, otp), std::get(otp).rootSteps(ii) )) { return std::tuple_cat( PackNum::mkStepTuple(ii, otp), std::get(otp).rootSteps(ii) ); } template static void mkExt(std::array& out, const std::array& siar, const OpClass& second) { std::get(out) = second.rootSteps( std::get(siar) ); PackNum::mkExt(out, siar, second); } // call with -2 (instead of -1) template static T&& mkOpExpr(const ETuple& pos, const OpTuple& ops) { static const size_t NEXT = START - std::tuple_element::type::SIZE; return std::forward ( OpFunction::apply( std::get(ops).template get(pos), PackNum::template mkOpExpr(pos, ops) ) ); } template static auto mkLoop( const OpTuple& ot, Expr&& exp ) -> decltype(std::get(ot).loop( PackNum::mkLoop(ot,exp) ))&& { return std::get(ot).loop( PackNum::mkLoop(ot,exp) ); } }; template<> struct PackNum<0> { template static void unpackArgs(BlockResult& res, const ArgTuple& tp, const Args&... args) { static_assert(sizeof...(Args) == std::tuple_size::value-1, "inconsistent number of arguments"); BlockBinaryOp(tp).get()), decltype(args)...> f(res); f(std::get<0>(tp).get(), args...); } template static void makeBlockTypeVec(std::vector >& btv, const std::tuple& ops, std::shared_ptr idxPtr, bool init) { auto subvec = std::move( std::get<0>(ops).block(idxPtr, init) ); btv.insert(btv.end(), subvec.begin(), subvec.end() ); } template static void makeBlockTypeVec(std::vector >& btv, const std::tuple& ops, const IndexInfo* idxPtr, bool init) { auto subvec = std::move( std::get<0>(ops).block(idxPtr, init) ); btv.insert(btv.end(), subvec.begin(), subvec.end() ); } template static void printTuple(std::ostream& out, const std::tuple& tp) { out << std::get(tp); } template static auto mkStepTuple(std::intptr_t ii, std::tuple otp) -> decltype(std::get<0>(otp).rootSteps(ii)) { return std::get<0>(otp).rootSteps(ii); } template static void mkExt(std::array& out, const std::array& siar, const OpClass& second) { std::get<0>(out) = second.rootSteps( std::get<0>(siar) ); } template static T&& mkOpExpr(const ETuple& pos, const OpTuple& ops) { static const size_t NEXT = START - std::tuple_element<1,OpTuple>::type::SIZE; return std::forward ( OpFunction::apply( std::get<1>(ops).template get(pos), std::get<0>(ops).template get(pos) ) ); } template static auto mkLoop( const OpTuple& ot, Expr&& exp ) -> decltype(std::get<0>(ot).loop( exp ))&& { return std::get<0>(ot).loop( exp ); } }; } // end namespace MultiArrayHelper #endif