// -*- C++ -*- #ifndef __pack_num_h__ #define __pack_num_h__ #include #include #include #include #include "base_def.h" namespace MultiArrayHelper { using namespace MultiArrayTools; template struct PackNum { template static IndexBase& getIndex(IndexType& in, size_t n) { if(n == N){ return in.getIndex(); } else { return PackNum::getIndex(in, n); } } template static const IndexBase& getIndex(const IndexType& in, size_t n) { if(n == N){ return in.getIndex(); } else { return PackNum::getIndex(in, n); } } 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 void mm(std::tuple...>& ip) { auto& si = *std::get(ip); if(si.first()){ si = si.max(); PackNum::mm(ip); } else { --si; } } 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::copy(ip, ind); } template static size_t makePos(const std::tuple...>& iPtrTup) { 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<> struct PackNum<0> { template static IndexBase& getIndex(MultiIndex& in, size_t n) { return in.getIndex<0>(); } template static const IndexBase& getIndex(const MultiIndex& in, size_t n) { return in.getIndex<0>(); } template static inline void pp(std::tuple...>& ip) { auto& si = *std::get<0>(ip); ++si; } template static inline void mm(std::tuple...>& ip) { auto& si = *std::get<0>(ip); --si; } 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) { 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(); } }; } // end namespace MultiArrayHelper #endif