#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 void RPackNum::initBlockSizes(std::array& bs, std::tuple...>& ip) { std::get(bs) = RPackNum::blockSize(ip); RPackNum::initBlockSizes(bs, ip); } template template inline void RPackNum::pp(std::tuple...>& ip) { auto& si = *std::get(ip); if(si.last()){ si = 0; RPackNum::pp(ip); } else { ++si; } } template template inline int RPackNum::pp(std::tuple...>& ip, std::array& bs, std::intptr_t idxPtrNum) { auto& siPtr = std::get(ip); 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 template inline void RPackNum::mm(std::tuple...>& ip) { auto& si = *std::get(ip); if(si.first()){ si = si.max() - 1; RPackNum::mm(ip); } else { --si; } } // !!!! template template inline int RPackNum::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 template size_t RPackNum::getSize(const RangeTuple& rt) { return std::get(rt)->size() * RPackNum::getSize(rt); } template template void RPackNum::getMetaPos(MetaType& target, const IndexPack& source) { std::get(target) = std::get(source)->meta(); RPackNum::getMetaPos(target, source); } template template void RPackNum::setMeta(IndexPack& target, const MetaType& source) { std::get(target)->at( std::get(source) ); RPackNum::setMeta(target, source); } 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::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, "inconsistent types"); std::get(ip) = std::shared_ptr( new SubIndexType( range.template getPtr() ) ); *std::get(ip) = 0; RPackNum::construct(ip, range); } 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 auto& idx = *std::get(iPtrTup); return std::get(iPtrTup)->pos() + RPackNum::makePos(iPtrTup) * std::get(iPtrTup)->max(); } 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::printIndex(const std::tuple...>& ip, size_t offset) { std::get(ip)->print(offset); RPackNum::printIndex(ip, offset); } 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 void RPackNum<0>::initBlockSizes(std::array& bs, std::tuple...>& ip) { std::get<0>(bs) = RPackNum::blockSize(ip); } template inline void RPackNum<0>::pp(std::tuple...>& ip) { auto& si = *std::get<0>(ip); ++si; } template inline int RPackNum<0>::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 inline void RPackNum<0>::mm(std::tuple...>& ip) { auto& si = *std::get<0>(ip); --si; } template inline int RPackNum<0>::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 size_t RPackNum<0>::getSize(const RangeTuple& rt) { return std::get<0>(rt)->size(); } template void RPackNum<0>::getMetaPos(MetaType& target, const IndexPack& source) { std::get<0>(target) = std::get<0>(source)->meta(); } template void RPackNum<0>::setMeta(IndexPack& target, const MetaType& source) { std::get<0>(target)->at( std::get<0>( source ) ); } 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>::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, "inconsistent types"); std::get<0>(ip) = std::shared_ptr( new SubIndexType( range.template getPtr<0>() ) ); *std::get<0>(ip) = 0; } 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) { return std::get<0>(iPtrTup)->pos(); } 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>::printIndex(const std::tuple...>& ip, size_t offset) { std::get<0>(ip)->print(offset); } 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 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