#ifndef __xfor_h__ #define __xfor_h__ #include #include #include #include "xfor/for_utils.h" namespace MultiArrayHelper { template class For { private: For() = default; //For(const For& in) = default; //For& operator=(const For& in) = default; const IndexClass* mIndPtr; Expr mExpr; decltype(mExpr.rootSteps()) mExt; public: static size_t layer() { return Expr::layer() + 1; } static const size_t LAYER = Expr::LAYER + 1; static const size_t SIZE = std::remove_reference::type::SIZE; typedef decltype(mExpr.rootSteps()) ETuple; For(For&& in) = default; For& operator=(For&& in) = default; For(const std::shared_ptr& indPtr, Expr&& expr); For(const IndexClass* indPtr, Expr&& expr); inline void operator()(size_t mlast, const ETuple& last) const; inline void operator()(size_t mlast = 0) const; ETuple rootSteps(std::intptr_t iPtrNum = 0) const; }; template size_t exceptMax(size_t max) { return max; } template <> size_t exceptMax<1>(size_t max) { return 1; } } // namespace MultiArrayHelper /* ========================= * * --- TEMPLATE CODE --- * * ========================= */ namespace MultiArrayHelper { template For::For(const std::shared_ptr& indPtr, Expr&& expr) : mIndPtr(indPtr.get()), mExpr(expr), mExt(expr.rootSteps( static_cast( mIndPtr.get() ))) {} template For::For(const IndexClass* indPtr, Expr&& expr) : mIndPtr(indPtr), mExpr(expr), mExt(expr.rootSteps( static_cast( mIndPtr ) )) {} template inline void For::operator()(size_t mlast, const ETuple& last) const { auto& ind = *mIndPtr; const size_t max = ind.max(); // blocking for(size_t pos = ind.pos(); pos != max; ++pos){ const size_t mnpos = mlast * max + pos; const ETuple npos = std::move( XFPackNum::mkPos(pos, mExt, last) ); mExpr(mnpos, npos); } } template inline void For::operator()(size_t mlast) const { const ETuple last; auto& ind = *mIndPtr; const size_t max = ind.max(); // blocking for(size_t pos = ind.pos(); pos != max; ++pos){ const size_t mnpos = mlast * max + pos; const ETuple npos = std::move( XFPackNum::mkPos(pos, mExt, last) ); mExpr(mnpos, npos); } } template typename For::ETuple For::rootSteps(std::intptr_t iPtrNum) const { return mExpr.rootSteps(iPtrNum); } } // namespace MultiArrayHelper #endif