#include "ranges/dynamic_range.h" namespace CNORXZ { namespace { using namespace CNORXZInternal; } /**************************** * DynamicRangeFactory * ****************************/ template DynamicRangeFactory::DynamicRangeFactory(const std::tuple...>& origs) { mProd = std::shared_ptr( new DynamicRange( origs ) ); } template DynamicRangeFactory::DynamicRangeFactory(std::shared_ptr... origs) { mProd = std::shared_ptr( new DynamicRange( origs... ) ); } template void DynamicRangeFactory::append(std::shared_ptr r) { if(mProductCreated){ mProd = std::shared_ptr( new DynamicRange( *std::dynamic_pointer_cast(mProd) ) ); mProductCreated = false; } std::dynamic_pointer_cast(mProd)->mOrig.push_back(r); std::dynamic_pointer_cast(mProd)->mSize *= r->size(); std::dynamic_pointer_cast(mProd)->mEmpty = false; } /********************* * DynamicIndex * *********************/ template DynamicIndex& DynamicIndex::operator()(const std::shared_ptr&... is) { mIvecInit = true; vector> tmp = { std::make_shared>(is)... }; assert(mIVec.size() == tmp.size()); for(size_t i = 0; i != mIVec.size(); ++i){ mIVec[i].first = tmp[i]; } sync(); return *this; } template void DynamicIndex::getPtr() {} struct ForMaker { template static inline auto mk(size_t i, size_t step, DynamicExpression ex, const IVecT& ivec, bool hidden = false) -> DynamicExpression { if(i == 0) { auto& ii = *ivec[0].first; return hidden ? ii.iforh(step*ivec[i].second, ex) : ii.ifor(step*ivec[i].second, ex); } else { auto& ii = *ivec[i].first; return mk(i-1, step, (hidden ? ii.iforh(step*ivec[i].second, ex) : ii.ifor(step*ivec[i].second, ex)), ivec, hidden); } } }; template DynamicExpression DynamicIndex::ifor(size_t step, Expr ex) const { if(mIVec.size() == 0){ return ex; } else if(mIVec.size() == 1){ return mIVec.back().first->ifor(step,ex); } else { return ForMaker::mk(mIVec.size()-2, step, mIVec.back().first->ifor(step,ex),mIVec); } } template DynamicExpression DynamicIndex::iforh(size_t step, Expr ex) const { if(mIVec.size() == 0){ return ex; } else if(mIVec.size() == 1){ return mIVec.back().first->iforh(step,ex); } else { return ForMaker::mk(mIVec.size()-2, step, mIVec.back().first->iforh(step,ex), mIVec, true); } } template DynamicExpression DynamicIndex::pifor(size_t step, Expr ex) const { return ifor(step, ex); // no multithreading here at the moment... } /*********************** * DynamicRange * ***********************/ template DynamicRange::DynamicRange(const std::tuple...>& origs) : RangeInterface() { mOrig.resize(sizeof...(RangeTypes)); sfor_pn<0,sizeof...(RangeTypes)> ( [&](auto i) { mOrig[i] = std::get(origs); return 0; } ); mSize = sfor_p<0,sizeof...(RangeTypes)> ( [&](auto i) { return std::get(origs)->size(); }, [&](auto a, auto b) { return a * b; } ); if(sizeof...(RangeTypes)){ mEmpty = false; } } template DynamicRange::DynamicRange(std::shared_ptr... origs) : RangeInterface() { auto rst = std::make_tuple(origs...); mOrig.resize(sizeof...(RangeTypes)); sfor_pn<0,sizeof...(RangeTypes)> ( [&](auto i) { mOrig[i] = std::get(rst); return 0; } ); mSize = sfor_p<0,sizeof...(RangeTypes)> ( [&](auto i) { return std::get(rst)->size(); }, [&](auto a, auto b) { return a * b; } ); if(sizeof...(RangeTypes)){ mEmpty = false; } } template std::shared_ptr DynamicRange::fullsub(size_t num) const { return std::dynamic_pointer_cast( mOrig.at(num) ); } template std::shared_ptr > DynamicRange::scast(SIZET... sizes) const { std::tuple...> rtp; RangeHelper::resolveRangeType<0>(mOrig, rtp, 0, sizes...); MultiRangeFactory mrf(rtp); return std::dynamic_pointer_cast >( mrf.create() ); } } // end namespace CNORXZ namespace CNORXZ { namespace RangeHelper { template <> inline void resolveSetRange(std::shared_ptr& rp, const vector >& orig, size_t origpos, size_t size) { DynamicRangeFactory arf; for(size_t op = origpos; op != origpos + size; ++op){ //VCHECK(op); arf.append(orig[op]); } rp = std::dynamic_pointer_cast( arf.create() ); } template <> inline void setRangeToVec(vector >& v, std::shared_ptr r) { if(not r->isEmpty()){ for(size_t i = r->dim(); i != 0; --i){ v.insert(v.begin(), r->sub(i-1)); } } } template <> inline size_t getStepSize(const DynamicIndex& ii, std::intptr_t j) { size_t ss = 0; size_t sx = 1; for(size_t k = ii.dim(); k != 0; --k){ const size_t i = k-1; const auto& ni = ii.get(i); const size_t max = ni.max(); const size_t tmp = ni.getStepSizeComp(j); ss += tmp * ii.getStepSize(i); sx *= max; } return ss; } } }