// -*- C++ -*- #include #include namespace MultiArrayHelper { template struct PackNum { template static IndexBase& getIndex(MultiIndex& in, size_t n) { if(n == N){ return in.getIndex(); } else { return PackNum::getIndex(in, n); } } template static const IndexBase& getIndex(const MultiIndex& 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.pos() == si.last()){ si = 0; PackNum::pp(index); } else { ++si; } } template static inline void mm(std::tuple...>& ip) { auto& si = *std::get(ip); if(si.pos() == si.atEdge()){ si = si.max(); PackNum::mm(index); } else { --si; } } template static size_t getSize(const RangeTuple& rt) { return std::get(rt).size() * PackNum::getSize(rt); } template static void getMetaPos(std::tuple& target, const typename MultiIndex::IndexPack& source) { std::get(target) = std::get(source)->meta(); PackNum::getMetaPos(target, source); } template static void setMeta(typename MultiIndex::IndexPack& target, const typename MultiIndex::MetaType& source) { std::get(target).atMeta( std::get(source) ); PackNum::setMeta(target, source); } template static void setIndexPack(IndexPack& iPack, size_t pos) { auto i = std::get(iPack); const size_t ownPos = pos % i.max(); i = ownPos; if(ownPos == pos){ PackNum::setIndexPack(iPack, (pos - ownPos) / i.max() ); } } template static void construct(std::tuple...>& ip, const MRange& range) { typedef decltype(range.template get()) SubIndexType; typedef decltype(std::get(ip).get()) TypeFromIndexPack; static_assert(std::is_same::value, "inconsiśtent types"); std::get(ip).swap( std::make_shared( range.template get() ) ); PackNum::construct(ip, range); } template static void copy(std::tuple...>& ip, const MultiIndex& ind) { typedef decltype(ind.template get()) SubIndexType; std::get(ip).swap( std::make_shared( ind.template get() ) ); 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 print(std::ostream& os, const std::tuple& meta) { PackNum::print(os, meta); os << std::get(meta) << '\t'; } }; template<> struct PackNum<0> { template static IndefinitIndexBase& getIndex(MultiIndex& in, size_t n) { return in.getIndex<0>(); } template static const IndefinitIndexBase& 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(std::tuple& target, const typename MultiIndex::IndexPack& source) { std::get<0>(target) = std::get<0>(source)->meta(); } template static void setMeta(typename MultiIndex::IndexPack& target, const typename MultiIndex::MetaType& source) { std::get<0>(target).atMeta( 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 decltype(range.template get<0>()) SubIndexType; typedef decltype(std::get<0>(ip).get()) TypeFromIndexPack; static_assert(std::is_same::value, "inconsiśtent types"); std::get<0>(ip).swap( std::make_shared( range.template get<0>() ) ); } template static void copy(std::tuple...>& ip, const MultiIndex& ind) { typedef decltype(ind.template get<0>()) SubIndexType; std::get<0>(ip).swap( std::make_shared( ind.template get<0>() ) ); } template static size_t makePos(const std::tuple...>& iPtrTup) { return std::get<0>(iPtrTup)->pos(); } template static void print(std::ostream& os, const std::tuple& meta) { os << std::get<0>(meta) << '\t'; } }; } // end namespace MultiArrayHelper