#ifndef __dynamic_range_h__ #define __dynamic_range_h__ #include "ranges/rbase_def.h" #include "ranges/range_base.h" #include "ranges/index_base.h" namespace MultiArrayTools { typedef std::pair DynamicMetaElem; class DynamicMetaT { private: std::vector mMeta; public: DynamicMetaT() = default; DynamicMetaT(const DynamicMetaT& in) = default; DynamicMetaT(DynamicMetaT&& in) = default; DynamicMetaT& operator=(const DynamicMetaT& in) = default; DynamicMetaT& operator=(DynamicMetaT&& in) = default; template DynamicMetaT(const std::tuple& meta); bool operator==(const DynamicMetaT& in) const; bool operator!=(const DynamicMetaT& in) const; DynamicMetaElem& operator[](size_t pos); const DynamicMetaElem& operator[](size_t pos) const; }; class IndexWrapperBase { public: IndexWrapperBase() = default; IndexWrapperBase(const IndexWrapperBase& in) = default; IndexWrapperBase(IndexWrapperBase&& in) = default; IndexWrapperBase& operator=(const IndexWrapperBase& in) = default; IndexWrapperBase& operator=(IndexWrapperBase&& in) = default; virtual IndexType type() const = 0; virtual IndexWrapperBase& operator=(size_t pos) = 0; virtual IndexWrapperBase& operator++() = 0; virtual IndexWrapperBase& operator--() = 0; virtual int pp(std::intptr_t idxPtrNum) = 0; virtual int mm(std::intptr_t idxPtrNum) = 0; virtual std::string stringMeta() const = 0; virtual DynamicMetaT meta() const = 0; virtual const DynamicMetaT* metaPtr() const = 0; //virtual IndexWrapperBase& at(const U& metaPos) = 0; //virtual size_t posAt(const U& metaPos) const = 0; //virtual bool isMeta(const U& metaPos) const = 0; virtual size_t dim() const = 0; virtual bool last() const = 0; virtual bool first() const = 0; virtual std::shared_ptr range() const = 0; virtual size_t getStepSize(size_t n) const = 0; virtual std::intptr_t get() const = 0; virtual DynamicalExpression ifor(size_t step, DynamicalExpression ex) const = 0; virtual DynamicalExpression iforh(size_t step, DynamicalExpression ex) const = 0; }; typedef IndexWrapperBase IndexW; template class IndexWrapper : public IndexWrapperBase { protected: IndexWrapper() = default; private: std::shared_ptr mI; public: IndexWrapper(const IndexWrapper& in) = default; IndexWrapper(IndexWrapper&& in) = default; IndexWrapper& operator=(const IndexWrapper& in) = default; IndexWrapper& operator=(IndexWrapper&& in) = default; IndexWrapper(const std::shared_ptr& i) : mI(i) {} virtual IndexType type() const final { return mI->type(); } virtual IndexWrapperBase& operator=(size_t pos) final { (*mI) = pos; return *this; } virtual IndexWrapperBase& operator++() final { ++(*mI); return *this; } virtual IndexWrapperBase& operator--() final { --(*mI); return *this; } virtual int pp(std::intptr_t idxPtrNum) final { return mI->pp(idxPtrNum); } virtual int mm(std::intptr_t idxPtrNum) final { return mI->mm(idxPtrNum); } virtual std::string stringMeta() const final { return mI->stringMeta(); } virtual DynamicMetaT meta() const final { return DynamicMetaT(mI->meta()); } virtual const DynamicMetaT* metaPtr() const final { return nullptr; } IndexWrapperBase& at(const typename Index::MetaType& metaPos) { mI->at(metaPos); return *this; } size_t posAt(const typename Index::MetaType& metaPos) const { return mI->posAt(metaPos); } //virtual bool isMeta(const U& metaPos) const final { return mI->isMeta(); } virtual size_t dim() const final { return mI->dim(); } virtual bool last() const final { return mI->last(); } virtual bool first() const final { return mI->first(); } virtual std::shared_ptr range() const final { return mI->range(); } virtual size_t getStepSize(size_t n) const final { return mI->getStepSize(n); } virtual std::intptr_t get() const final { return reinterpret_cast(mI.get()); } virtual DynamicalExpression ifor(size_t step, DynamicalExpression ex) const final { return mI->ifor(step, ex); } virtual DynamicalExpression iforh(size_t step, DynamicalExpression ex) const final { return mI->iforh(step, ex); } }; typedef SingleRange DynamicRange; class DynamicIndex : public IndexInterface { private: std::vector,size_t>> mIVec; inline DynamicalExpression mkFor(size_t i, size_t step, DynamicalExpression ex, bool hidden = false) const; public: typedef IndexInterface IB; typedef DynamicMetaT MetaType; typedef DynamicRange RangeType; typedef DynamicIndex IType; DynamicIndex(const std::shared_ptr& range); static constexpr IndexType sType() { return IndexType::SINGLE; } static constexpr size_t totalDim() { return 1; } static constexpr size_t sDim() { return 1; } static constexpr SpaceType STYPE = SpaceType::DYN; IndexType type() const; DynamicIndex& operator=(size_t pos); DynamicIndex& operator++(); DynamicIndex& operator--(); int pp(std::intptr_t idxPtrNum); int mm(std::intptr_t idxPtrNum); std::string stringMeta() const; MetaType meta() const; const MetaType* metaPtr() const; DynamicIndex& at(const MetaType& metaPos); size_t posAt(const MetaType& metaPos) const; //bool isMeta(const MetaType& metaPos) const; size_t dim(); bool last(); bool first(); std::shared_ptr range(); template void getPtr(); size_t getStepSize(size_t n); std::string id() const; void print(size_t offset); template auto ifor(size_t step, Expr ex) const -> DynamicalExpression; template auto iforh(size_t step, Expr ex) const -> DynamicalExpression; }; // NOT THREAD SAVE!! class DynamicRangeFactory : public RangeFactoryBase { public: typedef DynamicRange oType; DynamicRangeFactory(); template DynamicRangeFactory(const std::tuple...>& origs); template DynamicRangeFactory(std::shared_ptr... origs); template void append(std::shared_ptr r); std::shared_ptr create(); private: std::shared_ptr checkIfCreated(const std::vector >& pvec); static std::map,std::vector > mAleadyCreated; bool mProductCreated = false; }; template <> class SingleRange : public RangeInterface { public: static constexpr bool defaultable = true; static constexpr size_t ISSTATIC = 0; static constexpr size_t SIZE = -1; static constexpr bool HASMETACONT = false; typedef RangeBase RB; typedef DynamicIndex IndexType; typedef DynamicRange RangeType; typedef DynamicMetaT MetaType; private: SingleRange() = default; SingleRange(const SingleRange& in) = default; template SingleRange(const std::tuple...>& origs); template SingleRange(std::shared_ptr... origs); size_t mSize = 1; bool mEmpty = true; std::vector > mOrig; public: virtual size_t size() const final; virtual size_t dim() const final; MetaType get(size_t pos) const; size_t getMeta(const MetaType& metaPos) const; virtual IndexType begin() const final; virtual IndexType end() const final; virtual SpaceType spaceType() const final; virtual std::string stringMeta(size_t pos) const final; virtual std::vector data() const final; std::shared_ptr sub(size_t num) const; template std::shared_ptr fullsub(size_t num) const; template std::shared_ptr > scast(SIZET... sizes) const; // save cast void sreplace(const std::shared_ptr in, size_t num); bool isEmpty() const; friend DynamicRangeFactory; static DynamicRangeFactory factory() { return DynamicRangeFactory(); } }; } // namespace MultiArrayTools /* ========================= * * --- TEMPLATE CODE --- * * ========================= */ namespace MultiArrayTools { /*********************** * DynamicRange * ***********************/ 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; } /***************** * Functions * *****************/ //std::shared_ptr defaultRange(size_t size = 0); } namespace MultiArrayHelper { using namespace MultiArrayTools; template <> inline void resolveSetRange(std::shared_ptr& rp, const std::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(std::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)); } } } } namespace MultiArrayTools { /*********************** * DynamicRange * ***********************/ template SingleRange::SingleRange(const std::tuple...>& origs) : RangeInterface() { RPackNum::RangesToVec( origs, mOrig ); mSize = RPackNum::getSize( origs ); if(sizeof...(RangeTypes)){ mEmpty = false; } } template SingleRange::SingleRange(std::shared_ptr... origs) : RangeInterface() { auto rst = std::make_tuple(origs...); RPackNum::RangesToVec( rst, mOrig ); mSize = RPackNum::getSize( rst ); if(sizeof...(RangeTypes)){ mEmpty = false; } } template std::shared_ptr SingleRange::fullsub(size_t num) const { return std::dynamic_pointer_cast( mOrig.at(num) ); } template std::shared_ptr > SingleRange::scast(SIZET... sizes) const { std::tuple...> rtp; RPackNum::resolveRangeType(mOrig, rtp, 0, sizes...); MultiRangeFactory mrf(rtp); return std::dynamic_pointer_cast >( mrf.create() ); } inline DynamicalExpression DynamicIndex::mkFor(size_t i, size_t step, DynamicalExpression ex, bool hidden) const { if(i != 0){ auto& ii = *mIVec[i].first; return mkFor(i-1, step, hidden ? ii.iforh(step, ex) : ii.ifor(step, ex)); } else { auto& ii = *mIVec[0].first; return hidden ? ii.iforh(step, ex) : ii.ifor(step, ex); } } template auto DynamicIndex::ifor(size_t step, Expr ex) const -> DynamicalExpression { DynamicalExpression expr(std::make_shared(ex)); return mkFor(mIVec.size()-1, step, expr); } template auto DynamicIndex::iforh(size_t step, Expr ex) const -> DynamicalExpression { DynamicalExpression expr(std::make_shared(ex)); return mkFor(mIVec.size()-1, step, expr, true); } } #endif