#include "rpack_num.h" namespace MultiArrayHelper { using namespace MultiArrayTools; template size_t mkTotalDim() { return Index1::totalDim(); } template size_t mkTotalDim() { return Index1::totalDim() * mkTotalDim(); } template inline void resolveSetRange(std::shared_ptr& rp, const vector >& orig, size_t origpos, size_t size) { assert(size == 1); rp = std::dynamic_pointer_cast( orig[origpos] ); // catch bad cast here!! } template inline void setRangeToVec(vector >& v, std::shared_ptr r) { v.insert(v.begin(), r); } template template size_t RPackNum::getSize(const RangeTuple& rt) { return std::get(rt)->size() * RPackNum::getSize(rt); } template template inline std::shared_ptr RPackNum::getSub(const SpaceClass& space, size_t num) { if(num == N){ return std::get(space); } else { return RPackNum::getSub(space, num); } } template template void RPackNum::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 template void RPackNum::copyInst(std::tuple...>& ip, const IndexType& ind) { std::get(ip) = ind.template getPtr() ; RPackNum::copyInst(ip, ind); } template template void RPackNum::copyIndex(std::tuple...>& ip, const IndexType& ind) { typedef typename std::remove_reference(ip))>::type SubType; std::get(ip) = std::make_shared( ind.template get() ) ; RPackNum::copyIndex(ip, ind); } template template inline size_t RPackNum::makePos(const std::tuple...>& iPtrTup, const std::array& blockSize) { return RPackNum::makePos(iPtrTup, blockSize) + std::get(iPtrTup)->pos() * std::get(blockSize); } template template void RPackNum::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 template void RPackNum::swapIndices(Pack& ipack, const std::tuple...>& ninds) { std::get(ipack) = std::get(ninds); RPackNum::swapIndices(ipack, ninds); } template template size_t RPackNum::blockSize(const std::tuple...>& pack) { return std::get(pack)->max() * RPackNum::blockSize(pack); } template template inline void RPackNum::RangesToVec(const std::tuple...>& rst, vector >& v) { setRangeToVec(v, std::get(rst)); RPackNum::RangesToVec(rst, v); } template template inline void RPackNum::RangesToVec(const std::tuple...>& rst, vector& v) { v[N] = reinterpret_cast( std::get(rst).get() ); RPackNum::RangesToVec(rst, v); } template template void RPackNum::checkDefaultable() { static_assert( Range::defaultable, "not defaultable" ); RPackNum::template checkDefaultable(); } template template auto RPackNum::mkFor(size_t step, const IndexPack& ipack, const BlockArray& ba, Exprs exs) -> decltype(std::get::value-N-1>(ipack) ->ifor( 0, RPackNum::mkFor(step, ipack, ba, exs) ) ) { constexpr size_t NN = std::tuple_size::value-N-1; return std::get(ipack) ->ifor( step*std::get(ba), RPackNum::mkFor(step, ipack, ba, exs) ); } template template auto RPackNum::mkForh(size_t step, const IndexPack& ipack, const BlockArray& ba, Exprs exs) -> decltype(std::get::value-N-1>(ipack) ->iforh( 0, RPackNum::mkForh(step, ipack, ba, exs) ) ) { constexpr size_t NN = std::tuple_size::value-N-1; return std::get(ipack) ->iforh( step*std::get(ba), RPackNum::mkForh(step, ipack, ba, exs) ); } template template auto RPackNum::mkPFor(size_t step, const IndexPack& ipack, const BlockArray& ba, Exprs exs) -> decltype(std::get::value-N-1>(ipack) ->pifor( 0, RPackNum::mkFor(step, ipack, ba, exs) ) ) { constexpr size_t NN = std::tuple_size::value-N-1; return std::get(ipack) ->pifor( step*std::get(ba), RPackNum::mkFor(step, ipack, ba, exs) ); // mkFor is correct here, because we want to multithread only the FIRST index!! } template template inline void RPackNum::getStepSizeX(const Index& ii, std::intptr_t j, size_t& ss, size_t& sx) { //constexpr size_t DIM = Index::sDim(); const auto& ni = ii.template get(); const size_t max = ni.max(); const size_t tmp = getStepSize(ni, j); //ss += tmp * sx; ss += tmp * ii.template getBlockSize(); sx *= max; RPackNum::getStepSizeX(ii, j, ss, sx); } template template inline void RPackNum::resolveRangeType(const vector >& orig, RangeTuple& rtp, size_t off, size_t size, SIZET... sizes) { constexpr size_t tps = std::tuple_size::value; resolveSetRange(std::get(rtp), orig, off, size); RPackNum::resolveRangeType(orig, rtp, off+size, sizes...); } template template inline bool RPackNum::checkIfCreated(const std::tuple...>& p, const vector& a) { return reinterpret_cast( std::get(p).get() ) == a[N] and RPackNum::checkIfCreated(p,a); } template template inline std::string RPackNum::getStringMeta(const MIndex& mi) { return RPackNum::getStringMeta(mi) + "," + mi.template getPtr()->stringMeta(); } template template inline void RPackNum::fillRangeDataVec(vector& out, const std::tuple...>& tp) { vector part = std::get(tp)->data(); out.insert(out.end(), part.begin(), part.end()); RPackNum::fillRangeDataVec(out, tp); } template template inline bool RPackNum::compareSpaceTypes(const vector >& rbvec) { return rbvec[SIZE-N-1]->spaceType() == Range::STYPE and RPackNum::template compareSpaceTypes(rbvec); } template template inline void RPackNum::setSpace(const vector >& rbvec, std::tuple...>& stp) { typedef typename std::remove_reference( stp ))>::type RType; std::get( stp ) = std::dynamic_pointer_cast( rbvec[N] ); RPackNum::setSpace(rbvec, stp); } template template inline size_t RPackNum::getCMeta(MetaType* xtarget, size_t pos, const std::tuple...>& stp, size_t off) { //constexpr size_t NN = sizeof...(Ranges); auto& r = *std::get(stp); const size_t ownPos = pos % r.size(); const size_t s = r.cmetaSize(); off -= s; r.cmeta(reinterpret_cast(&std::get(*xtarget)), ownPos); return s + RPackNum::getCMeta(xtarget, (pos - ownPos) / r.size(), stp, off); } template template inline size_t RPackNum::getCMetaSize(const std::tuple...>& stp) { constexpr size_t NN = sizeof...(Ranges); auto& r = *std::get(stp); return r.cmetaSize() + RPackNum::getCMetaSize(stp); } template template inline void RPackNum::getTypeNum(vector& res, const std::tuple...>& stp) { auto& r = *std::get(stp); auto tn = r.typeNum(); res.insert(res.begin(), tn.begin(), tn.end()); RPackNum::getTypeNum(res, stp); } template template inline size_t RPackNum::getMeta(const std::tuple...>& space, const std::tuple& meta) { return RPackNum::getMeta(space,meta) * std::get(space)->size() + std::get(space)->getMeta(std::get(meta)); } template size_t RPackNum<0>::getSize(const RangeTuple& rt) { return std::get<0>(rt)->size(); } template inline std::shared_ptr RPackNum<0>::getSub(const SpaceClass& space, size_t num) { if(num == 0){ return std::get<0>(space); } else { assert(0); return std::shared_ptr(); } } template void RPackNum<0>::setIndexPack(IndexPack& iPack, size_t pos) { auto& i = *std::get<0>(iPack); const size_t ownPos = pos % i.max(); i = ownPos; } template void RPackNum<0>::copyInst(std::tuple...>& ip, const IndexType& ind) { std::get<0>(ip) = ind.template getPtr<0>(); } template void RPackNum<0>::copyIndex(std::tuple...>& ip, const IndexType& ind) { typedef typename std::remove_reference(ip))>::type SubType; std::get<0>(ip) = std::make_shared( ind.template get<0>() ) ; } template inline size_t RPackNum<0>::makePos(const std::tuple...>& iPtrTup, const std::array& blockSize) { return std::get<0>(iPtrTup)->pos() * std::get<1>(blockSize); } template void RPackNum<0>::swapIndices(Pack& ipack, const std::shared_ptr& nind) { std::get::value-1>(ipack) = nind; } template void RPackNum<0>::swapIndices(Pack& ipack, const std::tuple...>& ninds) { std::get<0>(ipack) = std::get<0>(ninds); } template size_t RPackNum<0>::blockSize(const std::tuple...>& pack) { return 1; } template inline void RPackNum<0>::RangesToVec(const std::tuple...>& rst, vector& v) { v[0] = reinterpret_cast( std::get<0>(rst).get() );; } template inline void RPackNum<0>::RangesToVec(const std::tuple...>& rst, vector >& v) { setRangeToVec(v, std::get<0>(rst)); } template void RPackNum<0>::checkDefaultable() { static_assert( Range::defaultable, "not defaultable" ); } template auto RPackNum<0>::mkFor(size_t step, const IndexPack& ipack, const BlockArray& ba, Exprs exs) -> decltype(std::get::value-1>(ipack) ->ifor(0,exs) ) { constexpr size_t NN = std::tuple_size::value-1; return std::get(ipack) ->ifor( step*std::get(ba), exs); } template auto RPackNum<0>::mkForh(size_t step, const IndexPack& ipack, const BlockArray& ba, Exprs exs) -> decltype(std::get::value-1>(ipack) ->iforh(0,exs) ) { constexpr size_t NN = std::tuple_size::value-1; return std::get(ipack) ->iforh( step*std::get(ba), exs); } template auto RPackNum<0>::mkPFor(size_t step, const IndexPack& ipack, const BlockArray& ba, Exprs exs) -> decltype(std::get::value-1>(ipack) ->pifor(0,exs) ) { constexpr size_t NN = std::tuple_size::value-1; return std::get(ipack) ->pifor( step*std::get(ba), exs); } template inline void RPackNum<0>::getStepSizeX(const Index& ii, std::intptr_t j, size_t& ss, size_t& sx) { //constexpr size_t DIM = Index::sDim(); const auto& ni = ii.template get<0>(); const size_t max = ni.max(); const size_t tmp = getStepSize(ni, j); //ss += tmp * sx; ss += tmp * ii.template getBlockSize<1>(); sx *= max; } template inline void RPackNum<0>::resolveRangeType(const vector >& orig, RangeTuple& rtp, size_t off, size_t size) { constexpr size_t tps = std::tuple_size::value; resolveSetRange(std::get(rtp), orig, off, size); } template inline bool RPackNum<0>::checkIfCreated(const std::tuple...>& p, const vector& a) { return reinterpret_cast( std::get<0>(p).get() ) == a[0]; } template inline std::string RPackNum<0>::getStringMeta(const MIndex& mi) { return mi.template getPtr<0>()->stringMeta(); } template inline void RPackNum<0>::fillRangeDataVec(vector& out, const std::tuple...>& tp) { vector part = std::get(tp)->data(); out.insert(out.end(), part.begin(), part.end()); } template inline bool RPackNum<0>::compareSpaceTypes(const vector >& rbvec) { return rbvec[SIZE-1]->spaceType() == Range::STYPE; } template inline void RPackNum<0>::setSpace(const vector >& rbvec, std::tuple...>& stp) { typedef typename std::remove_reference( stp ))>::type RType; std::get<0>( stp ) = std::dynamic_pointer_cast( rbvec[0] ); } template inline size_t RPackNum<0>::getCMeta(MetaType* xtarget, size_t pos, const std::tuple...>& stp, size_t off) { //constexpr size_t NN = sizeof...(Ranges); auto& r = *std::get<0>(stp); const size_t ownPos = pos % r.size(); const size_t s = r.cmetaSize(); off -= s; assert(off == 0); r.cmeta(reinterpret_cast(&std::get<0>(*xtarget)), ownPos); return s; } template inline size_t RPackNum<0>::getCMetaSize(const std::tuple...>& stp) { constexpr size_t NN = sizeof...(Ranges); auto& r = *std::get(stp); return r.cmetaSize(); } template inline void RPackNum<0>::getTypeNum(vector& res, const std::tuple...>& stp) { auto& r = *std::get<0>(stp); auto tn = r.typeNum(); res.insert(res.begin(), tn.begin(), tn.end()); } template inline size_t RPackNum<0>::getMeta(const std::tuple...>& space, const std::tuple& meta) { return std::get<0>(space)->getMeta(std::get<0>(meta)); } template template inline size_t SSG::getStepSize(const Index& ii, std::intptr_t j) { size_t ss = 0; size_t sx = 1; constexpr size_t DIM = Index::sDim(); RPackNum::getStepSizeX(ii, j, ss, sx); return ss; } template inline size_t SSG::getStepSize(const Index& ii, std::intptr_t j) { const std::intptr_t ip = reinterpret_cast(&ii); return ip == j ? 1 : 0; //return ii.ptrNum() == j ? 1 : 0; } template inline size_t getStepSize(const Index& ii, std::intptr_t j) { constexpr IndexType IT = Index::sType(); return SSG::getStepSize(ii, j); } } // end namespace MultiArrayHelper