diff --git a/src/include/ranges/dynamic_range.cc.h b/src/include/ranges/dynamic_range.cc.h index 3d12c40..214202f 100644 --- a/src/include/ranges/dynamic_range.cc.h +++ b/src/include/ranges/dynamic_range.cc.h @@ -37,6 +37,20 @@ namespace MultiArrayTools + 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) { @@ -48,6 +62,7 @@ namespace MultiArrayTools 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())); } @@ -138,12 +153,51 @@ namespace MultiArrayTools * 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; @@ -157,6 +211,8 @@ namespace MultiArrayTools { 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; diff --git a/src/include/ranges/dynamic_range.h b/src/include/ranges/dynamic_range.h index a35bde5..a380c69 100644 --- a/src/include/ranges/dynamic_range.h +++ b/src/include/ranges/dynamic_range.h @@ -165,6 +165,12 @@ namespace MultiArrayTools { return std::make_shared( std::make_shared( *mI ) ); } }; + + template + std::shared_ptr mkIndexWrapper(const Index& i) + { + return std::make_shared>(std::make_shared(i)); + } //typedef SingleRange DynamicRange; @@ -267,6 +273,9 @@ namespace MultiArrayTools template void append(std::shared_ptr r); + + template + void appendx(std::shared_ptr r); std::shared_ptr create(); @@ -287,6 +296,7 @@ namespace MultiArrayTools static constexpr size_t SIZE = -1; static constexpr bool HASMETACONT = false; + typedef vector> IVecT; typedef RangeBase RB; typedef DynamicIndex IndexType; typedef DynamicRange RangeType; @@ -309,6 +319,7 @@ namespace MultiArrayTools bool mEmpty = true; vector > mOrig; + IVecT mProtoI; public: virtual size_t size() const final; @@ -330,6 +341,7 @@ namespace MultiArrayTools virtual vector data() const final; std::shared_ptr sub(size_t num) const; + std::shared_ptr subI(size_t num) const; template std::shared_ptr fullsub(size_t num) const; @@ -364,7 +376,7 @@ namespace MultiArrayHelper DynamicRangeFactory arf; for(size_t op = origpos; op != origpos + size; ++op){ //VCHECK(op); - arf.append(orig[op]); + arf.appendx(orig[op]); } rp = std::dynamic_pointer_cast( arf.create() ); } diff --git a/src/lib/ranges/dynamic_range.cc b/src/lib/ranges/dynamic_range.cc index b5114a6..e620610 100644 --- a/src/lib/ranges/dynamic_range.cc +++ b/src/lib/ranges/dynamic_range.cc @@ -178,7 +178,7 @@ namespace MultiArrayTools assert(this->range()->sub(i) == sIMap.at(iname)->range()); } else { - sIMap[iname] = this->range()->sub(i)->aindex(); + sIMap[iname] = this->range()->subI(i); } mIVec[i].first = sIMap.at(iname); } @@ -444,6 +444,12 @@ namespace MultiArrayTools return mOrig.at(num); } + std::shared_ptr DynamicRange::subI(size_t num) const + { + assert(mProtoI.at(num) != nullptr); + return mProtoI.at(num)->duplicate(); + } + void DynamicRange::sreplace(const std::shared_ptr in, size_t num) {