#ifndef __xfor_h__ #define __xfor_h__ #include #include #include #include "xfor/for_utils.h" namespace MultiArrayHelper { template class For { public: static size_t layer() { return typename Expr::layer() + 1; } For(For&& in) = default; For& operator=(For&& in) = default; template For(const std::shared_ptr& indPtr, std::tuple...>&& ext, const Args&... args); For(const std::shared_ptr& indPtr, Expr&& expr, std::tuple...>&& ext); template For(IndexClass* indPtr, std::tuple...>&& ext, const Args&... args); For(IndexClass* indPtr, Expr&& expr, std::tuple...>&& ext); inline void operator()(size_t mlast, const std::tuple...>& last) const; inline void operator()(size_t mlast = 0) const; private: For() = default; IndexClass* mIndPtr; const Expr mExpr; const std::tuple...> mExt; }; 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 template For::For(const std::shared_ptr& indPtr, std::tuple...>&& ext, const Args&... args) : mIndPtr(indPtr.get()), mExpr(args...), mExt(ext) {} template For::For(const std::shared_ptr& indPtr, Expr&& expr, std::tuple...>&& ext) : mIndPtr(indPtr.get()), mExpr(expr), mExt(ext) {} template template For::For(IndexClass* indPtr, std::tuple...>&& ext, const Args&... args) : mIndPtr(indPtr), mExpr(args...), mExt(ext) {} template For::For(IndexClass* indPtr, Expr&& expr, std::tuple...>&& ext) : mIndPtr(indPtr), mExpr(expr), mExt(ext) {} template inline void For::operator()(size_t mlast, const std::tuple...>& last) const { static const size_t opNum = sizeof...(Ops); auto& ind = *mIndPtr; const size_t max = exceptMax::layer()>( ind.max() ); // blocking for(ind = 0; ind.pos() != max; ++ind){ const size_t mnpos = mlast * max + ind.pos(); const std::tuple...> npos = std::move( XFPackNum::mkPos(ind, mExt, last) ); mExpr(mnpos, npos); } } template inline void For::operator()(size_t mlast) const { static const size_t opNum = sizeof...(Ops); std::tuple...> last(to_size_t(0)...); auto& ind = *mIndPtr; const size_t max = exceptMax::layer()>( ind.max() ); // blocking for(ind = 0; ind.pos() != max; ++ind){ const size_t mnpos = mlast * max + ind.pos(); const std::tuple...> npos = std::move( XFPackNum::mkPos(ind, mExt, last) ); mExpr(mnpos, npos); } } } // namespace MultiArrayHelper #endif