#include "ranges/dynamic_range.h" //#include "ranges/dynamic_meta.h" #include "rpack_num.h" namespace MultiArrayTools { namespace { using namespace MultiArrayHelper; } /**************************** * 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::appendx(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; //std::dynamic_pointer_cast(mProd)->mProtoI.push_back(mkIndexWrapper(r->begin())); } 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; std::dynamic_pointer_cast(mProd)->mProtoI.push_back(mkIndexWrapper(r->begin())); } /********************* * 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() == 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() == 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 struct InitProto { template static void mk(vector>& proto, const std::tuple...>& orig) { proto[N] = mkIndexWrapper(std::get(orig)->begin()); InitProto::mk(proto, orig); } template static void mk(vector>& proto, size_t n, std::shared_ptr o, std::shared_ptr... origs) { proto[n-1-N] = mkIndexWrapper(o->begin()); InitProto::mk(proto, n, origs...); } }; template <> struct InitProto<0> { template static void mk(vector>& proto, const std::tuple...>& orig) { proto[0] = mkIndexWrapper(std::get<0>(orig)->begin()); } template static void mk(vector>& proto, size_t n, std::shared_ptr o, std::shared_ptr... origs) { proto[n-1] = mkIndexWrapper(o->begin()); } }; template DynamicRange::DynamicRange(const std::tuple...>& origs) : RangeInterface() { RPackNum::RangesToVec( origs, mOrig ); mProtoI.resize(sizeof...(RangeTypes)); InitProto::mk(mProtoI, origs); mSize = RPackNum::getSize( origs ); if(sizeof...(RangeTypes)){ mEmpty = false; } } template DynamicRange::DynamicRange(std::shared_ptr... origs) : RangeInterface() { auto rst = std::make_tuple(origs...); RPackNum::RangesToVec( rst, mOrig ); mProtoI.resize(sizeof...(RangeTypes)); InitProto::mk(mProtoI, sizeof...(RangeTypes), origs...); mSize = RPackNum::getSize( rst ); 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; RPackNum::resolveRangeType(mOrig, rtp, 0, sizes...); MultiRangeFactory mrf(rtp); return std::dynamic_pointer_cast >( mrf.create() ); } } // end namespace MultiArrayTools