// -*- C++ -*- #ifndef __pack_num_h__ #define __pack_num_h__ #include #include #include #include #include "base_def.h" namespace MultiArrayHelper { using namespace MultiArrayTools; template std::ostream& operator<<(std::ostream& out, const std::tuple& tp); template struct PackNum { template static std::shared_ptr getIndex(const IndexType& in, size_t n) { if(n == N){ return make_viwb( in.template get() ); } else { return PackNum::getIndex(in, n); } } /* template static const IndexBase& getIndex(const IndexType& in, size_t n) { if(n == N){ return in.template get(); } else { return PackNum::getIndex(in, n); } }*/ template static std::shared_ptr getIndexPtr(const IndexType& in, size_t n) { if(n == N){ return make_viwb( in.template getPtr() ); } else { return PackNum::getIndexPtr(in, n); } } /* template static void lock(std::tuple...>& ip, std::shared_ptr toLock) { std::get(ip)->lock(toLock); PackNum::lock(ip, toLock); } */ template static void initBlockSizes(std::array& bs, std::tuple...>& ip) { std::get(bs) = PackNum::blockSize(ip); PackNum::initBlockSizes(bs, ip); } template static inline void pp(std::tuple...>& ip) { auto& si = *std::get(ip); if(si.last()){ si = 0; PackNum::pp(ip); } else { ++si; } } template static inline int pp(std::tuple...>& ip, std::array& bs, std::intptr_t idxPtrNum) { auto& siPtr = std::get(ip); //VCHECK(siPtr.id()); if(reinterpret_cast(siPtr.get()) == idxPtrNum){ return PackNum::pp(ip, bs, idxPtrNum); } else { int tmp = siPtr->pp(idxPtrNum); if(siPtr->pos() == siPtr->max()){ (*siPtr) = 0; return PackNum::pp(ip, bs, idxPtrNum) - siPtr->max() + 1; } else { return tmp * std::get(bs); } } } template static inline void mm(std::tuple...>& ip) { auto& si = *std::get(ip); if(si.first()){ si = si.max() - 1; PackNum::mm(ip); } else { --si; } } // !!!! template static inline int mm(std::tuple...>& ip, std::array& bs, std::intptr_t idxPtrNum) { auto& siPtr = std::get(ip); if(reinterpret_cast(siPtr.get()) == idxPtrNum){ return std::get(bs) + PackNum::mm(ip, bs, idxPtrNum); } else { if(siPtr->first()){ (*siPtr) = siPtr->max() - 1; return PackNum::mm(ip, bs, idxPtrNum) - siPtr->max() + 1; } else { return siPtr->mm(idxPtrNum); } } } template static size_t getSize(const RangeTuple& rt) { return std::get(rt)->size() * PackNum::getSize(rt); } template static void getMetaPos(MetaType& target, const IndexPack& source) { std::get(target) = std::get(source)->meta(); PackNum::getMetaPos(target, source); } template static void setMeta(IndexPack& target, const MetaType& source) { std::get(target)->at( std::get(source) ); PackNum::setMeta(target, source); } template static void setIndexPack(IndexPack& iPack, size_t pos) { auto& i = *std::get(iPack).get(); const size_t ownPos = pos % i.max(); i = ownPos; PackNum::setIndexPack(iPack, (pos - ownPos) / i.max() ); } template static void construct(std::tuple...>& ip, const MRange& range) { typedef typename std::remove_reference())>::type SubRangeType; typedef typename SubRangeType::IndexType SubIndexType; typedef typename std::remove_reference(ip).get())>::type TypeFromIndexPack; static_assert(std::is_same::value, "inconsiśtent types"); std::get(ip) = std::shared_ptr( new SubIndexType( range.template getPtr() ) ); PackNum::construct(ip, range); } /* template class IndexType, class... Indices> static void copy(std::tuple...>& ip, const IndexType& ind) { typedef typename std::remove_reference())>::type SubIndexType; std::get(ip) = std::shared_ptr( new SubIndexType( ind.template get() ) ); PackNum::copy(ip, ind); } */ template class IndexType, class... Indices> static void copyInst(std::tuple...>& ip, const IndexType& ind) { std::get(ip) = ind.template getPtr() ; PackNum::copyInst(ip, ind); } template static size_t makePos(const std::tuple...>& iPtrTup) { auto ID = std::get(iPtrTup)->id(); //VCHECK(std::get(iPtrTup)->pos()); //VCHECK(std::get(iPtrTup)->max()); return std::get(iPtrTup)->pos() + PackNum::makePos(iPtrTup) * std::get(iPtrTup)->max(); } template static void swapIndices(Pack& ipack, const std::shared_ptr& nind, const std::shared_ptr&... ninds) { std::get::value-N-1>(ipack) = nind; PackNum::swapIndices(ipack, ninds...); } template static size_t blockSize(const std::tuple...>& pack) { return std::get(pack)->max() * PackNum::blockSize(pack); } template static BlockResult unpackArgs(const ArgTuple& tp, const Args&... args) { return PackNum::template unpackArgs(tp, std::get(tp).get(), args...); } template static void makeBlockTypeVec(std::vector >& btv, const std::tuple& ops, std::shared_ptr idxPtr) { auto subvec = std::move( std::get(ops).block(idxPtr) ); btv.insert(btv.end(), subvec.begin(), subvec.end() ); PackNum::makeBlockTypeVec(btv, ops, idxPtr); } template static void printTuple(std::ostream& out, const std::tuple& tp){ out << std::get(tp) << ", "; PackNum::printTuple(out, tp); } template static void RangesToVec(const std::tuple...>& rst, std::vector v) { v[N] = std::get(rst); PackNum::RangesToVec(rst, v); } template static void printIndex(const std::tuple...>& ip, size_t offset) { std::get(ip)->print(offset); PackNum::printIndex(ip, offset); } template static void checkDefaultable() { static_assert( Range::defaultable, "not defaultable" ); PackNum::template checkDefaultable(); } }; template<> struct PackNum<0> { template static std::shared_ptr getIndex(const IndexType& in, size_t n) { return make_viwb( in.template get<0>() ); } /* template static const IndexBase& getIndex(const MultiIndex& in, size_t n) { return in.template get<0>(); } */ template static std::shared_ptr getIndexPtr(const IndexType& in, size_t n) { return make_viwb( in.template getPtr<0>() ); } /* template static void lock(std::tuple...>& ip, std::shared_ptr toLock) { std::get<0>(ip)->lock(toLock); } */ template static void initBlockSizes(std::array& bs, std::tuple...>& ip) { std::get<0>(bs) = PackNum::blockSize(ip); } template static inline void pp(std::tuple...>& ip) { auto& si = *std::get<0>(ip); ++si; } template static inline int pp(std::tuple...>& ip, std::array& bs, std::intptr_t idxPtrNum) { auto& siPtr = std::get<0>(ip); if(reinterpret_cast(siPtr.get()) == idxPtrNum){ return std::get<0>(bs); } else { int tmp = siPtr->pp(idxPtrNum); return tmp * std::get<1>(bs); } } template static inline void mm(std::tuple...>& ip) { auto& si = *std::get<0>(ip); --si; } template static inline int mm(std::tuple...>& ip, std::array& bs, std::intptr_t idxPtrNum) { auto& siPtr = std::get<0>(ip); if(reinterpret_cast(siPtr.get()) == idxPtrNum){ return std::get<0>(bs); //return 1; } else { return siPtr->mm(idxPtrNum); } } template static size_t getSize(const RangeTuple& rt) { return std::get<0>(rt)->size(); } template static void getMetaPos(MetaType& target, const IndexPack& source) { std::get<0>(target) = std::get<0>(source)->meta(); } template static void setMeta(IndexPack& target, const MetaType& source) { std::get<0>(target)->at( std::get<0>( source ) ); } template static void setIndexPack(IndexPack& iPack, size_t pos) { auto& i = *std::get<0>(iPack); const size_t ownPos = pos % i.max(); i = ownPos; } template static void construct(std::tuple...>& ip, const MRange& range) { typedef typename std::remove_reference())>::type SubRangeType; typedef typename SubRangeType::IndexType SubIndexType; typedef typename std::remove_reference(ip).get())>::type TypeFromIndexPack; static_assert(std::is_same::value, "inconsiśtent types"); std::get<0>(ip) = std::shared_ptr( new SubIndexType( range.template getPtr<0>() ) ); } /* template class IndexType, class... Indices> static void copy(std::tuple...>& ip, const IndexType& ind) { typedef typename std::remove_reference())>::type SubIndexType; std::get<0>(ip) = std::shared_ptr( new SubIndexType( ind.template get<0>() ) ); } */ template class IndexType, class... Indices> static void copyInst(std::tuple...>& ip, const IndexType& ind) { std::get<0>(ip) = ind.template getPtr<0>(); } template static size_t makePos(const std::tuple...>& iPtrTup) { auto ID = std::get<0>(iPtrTup)->id(); //VCHECK(std::get<0>(iPtrTup)->pos()); //VCHECK(std::get<0>(iPtrTup)->max()); return std::get<0>(iPtrTup)->pos(); } template static void swapIndices(Pack& ipack, const std::shared_ptr& nind) { std::get::value-1>(ipack) = nind; } template static size_t blockSize(const std::tuple...>& pack) { return std::get(pack)->max(); } template static BlockResult unpackArgs(const ArgTuple& tp, const Args&... args) { static_assert(sizeof...(Args) == std::tuple_size::value-1, "inconsistent number of arguments"); static BlockBinaryOp(tp).get()), decltype(args)...> f; return f(std::get<0>(tp).get(), args...); } template static void makeBlockTypeVec(std::vector >& btv, const std::tuple& ops, std::shared_ptr idxPtr) { auto subvec = std::move( std::get<0>(ops).block(idxPtr) ); 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 void RangesToVec(const std::tuple...>& rst, std::vector v) { v[0] = std::get<0>(rst); } template static void printIndex(const std::tuple...>& ip, size_t offset) { std::get<0>(ip)->print(offset); } template static void checkDefaultable() { static_assert( Range::defaultable, "not defaultable" ); } }; template std::ostream& operator<<(std::ostream& out, const std::tuple& tp) { PackNum::printTuple(out, tp); return out; } } // end namespace MultiArrayHelper #endif