// -*- C++ -*- #ifndef __pack_num_h__ #define __pack_num_h__ #include //#include #include #include #include "base_def.h" #include "xfor/exttype.h" namespace MultiArrayHelper { template struct Application { template static inline T apply(std::shared_ptr f, T a, Ts... as) { return (*f)(a, as...); } }; template <> struct Application { template static inline T apply(std::shared_ptr f, T a, Ts... as) { return OpFunction::apply(a, as...); } }; template struct PackNum { template static auto mkElemOperation(const MA& ma, const ITuple& ituple, IPtrs... iptrs) -> decltype(PackNum::mkElemOperation(ma, ituple, std::get(ituple), iptrs...)) { return PackNum::mkElemOperation(ma, ituple, std::get(ituple), iptrs...); } template static void printTuple(std::ostream& out, const std::tuple& tp) { out << std::get(tp) << ", "; PackNum::printTuple(out, tp); } template static auto mkSteps(std::intptr_t ii, const std::tuple& otp) -> decltype(PackNum::mkSteps(ii, otp).extend( std::get(otp).rootSteps(ii)) ) { return PackNum::mkSteps(ii, otp).extend( 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); } template static inline T mkOpExpr(std::shared_ptr f, const ETuple& pos, const OpTuple& ops, const Args&... args) { typedef typename std::remove_reference(ops))>::type NextOpType; static_assert(LAST > NextOpType::SIZE, "inconsistent array positions"); static constexpr size_t NEXT = LAST - NextOpType::SIZE; return PackNum::template mkOpExpr ( f, pos, ops, std::get(ops).get(Getter::template getX( pos )), args...); } 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 static void mkSliceBlocks(std::array& blocks, const ContainerIndex& index, const Op& op, size_t total = 1) { const size_t tmp = op.rootSteps(reinterpret_cast ( index.template getPtr().get() ) ) .val(); std::get(blocks) = tmp; PackNum::template mkSliceBlocks(blocks, index, op, total * tmp); } }; template<> struct PackNum<0> { template static auto mkElemOperation(const MA& ma, const ITuple& ituple, IPtrs... iptrs) -> decltype(ma(iptrs...)) { return ma(iptrs...); } template static void printTuple(std::ostream& out, const std::tuple& tp) { out << std::get(tp); } template static auto mkSteps(std::intptr_t ii, const 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 inline T mkOpExpr(std::shared_ptr f, const ETuple& pos, const OpTuple& ops, const Args&... args) { typedef typename std::remove_reference(ops))>::type NextOpType; static constexpr size_t NEXT = LAST - NextOpType::SIZE; static_assert(NEXT == 0, "inconsistent array positions"); return Application::apply(f, std::get<0>(ops).get(Getter<0>::template getX( pos )), args...); //return OpFunction::apply(std::get<0>(ops).get(Getter<0>::template getX( pos )), args...); } template static auto mkLoop( const OpTuple& ot, Expr exp ) -> decltype(std::get<0>(ot).loop( exp )) { return std::get<0>(ot).loop( exp ); } template static void mkSliceBlocks(std::array& blocks, const ContainerIndex& index, const Op& op, size_t total = 1) { const size_t tmp = op.rootSteps(reinterpret_cast ( index.template getPtr<0>().get() ) ) .val(); std::get<1>(blocks) = tmp; std::get<0>(blocks) = total * tmp; // this is not correct, but not used so far ... !!! } }; } // end namespace MultiArrayHelper #endif