#ifndef __rpack_num_h__ #define __rpack_num_h__ #include #include "vindex_wrapper.h" #include "index_info.h" namespace MultiArrayHelper { using namespace MultiArrayTools; template struct RPackNum { template static std::shared_ptr getIndex(const IndexType& in, size_t n) { if(n == N){ return make_viwb( in.template get() ); } else { return RPackNum::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 RPackNum::getIndexPtr(in, n); } } template static void initBlockSizes(std::array& bs, std::tuple...>& ip) { std::get(bs) = RPackNum::blockSize(ip); RPackNum::initBlockSizes(bs, ip); } template static inline void pp(std::tuple...>& ip) { auto& si = *std::get(ip); if(si.last()){ si = 0; RPackNum::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 RPackNum::pp(ip, bs, idxPtrNum); } else { int tmp = siPtr->pp(idxPtrNum); if(siPtr->pos() == siPtr->max()){ (*siPtr) = 0; return RPackNum::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; RPackNum::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) + RPackNum::mm(ip, bs, idxPtrNum); } else { if(siPtr->first()){ (*siPtr) = siPtr->max() - 1; return RPackNum::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() * RPackNum::getSize(rt); } template static void getMetaPos(MetaType& target, const IndexPack& source) { std::get(target) = std::get(source)->meta(); RPackNum::getMetaPos(target, source); } template static void setMeta(IndexPack& target, const MetaType& source) { std::get(target)->at( std::get(source) ); RPackNum::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; RPackNum::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() ) ); RPackNum::construct(ip, range); } template class IndexType, class... Indices> static void copyInst(std::tuple...>& ip, const IndexType& ind) { std::get(ip) = ind.template getPtr() ; RPackNum::copyInst(ip, ind); } template static size_t makePos(const std::tuple...>& iPtrTup) { const auto& idx = *std::get(iPtrTup); return idx.pos() + RPackNum::makePos(iPtrTup) * idx.max(); } template static void swapIndices(Pack& ipack, const std::shared_ptr& nind, const std::shared_ptr&... ninds) { std::get::value-N-1>(ipack) = nind; RPackNum::swapIndices(ipack, ninds...); } template static size_t blockSize(const std::tuple...>& pack) { return std::get(pack)->max() * RPackNum::blockSize(pack); } template static void RangesToVec(const std::tuple...>& rst, std::vector v) { v[N] = std::get(rst); RPackNum::RangesToVec(rst, v); } template static void printIndex(const std::tuple...>& ip, size_t offset) { std::get(ip)->print(offset); RPackNum::printIndex(ip, offset); } template static void checkDefaultable() { static_assert( Range::defaultable, "not defaultable" ); RPackNum::template checkDefaultable(); } template static void buildInfoVec(std::vector& out, const std::tuple...>& ip, const std::array& bs) { static const size_t POS = sizeof...(Indices)-N-1; out.emplace_back(*std::get(ip), std::get(bs)); RPackNum::buildInfoVec(out, ip, bs); } }; template<> struct RPackNum<0> { template static std::shared_ptr getIndex(const IndexType& in, size_t n) { return make_viwb( 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 initBlockSizes(std::array& bs, std::tuple...>& ip) { std::get<0>(bs) = RPackNum::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 copyInst(std::tuple...>& ip, const IndexType& ind) { std::get<0>(ip) = ind.template getPtr<0>(); } template static size_t makePos(const std::tuple...>& iPtrTup) { 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 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 static void buildInfoVec(std::vector& out, const std::tuple...>& ip, const std::array& bs) { static const size_t POS = sizeof...(Indices)-1; out.emplace_back(*std::get(ip), std::get(bs)); } }; } // end namespace MultiArrayHelper #endif