// -*- C++ -*- #ifndef __anonymous_range_h__ #define __anonymous_range_h__ #include #include #include "rbase_def.h" #include "ranges/range_base.h" #include "ranges/rpheader.h" #include "ranges/x_to_string.h" #include "ranges/type_map.h" namespace MultiArrayTools { typedef GenSingleIndex AnonymousIndex; //template //using SIZET = size_t; typedef GenSingleRange AnonymousRange; // NOT THREAD SAVE!! class AnonymousRangeFactory : public RangeFactoryBase { public: typedef AnonymousRange oType; AnonymousRangeFactory(); template AnonymousRangeFactory(const std::tuple...>& origs); template AnonymousRangeFactory(std::shared_ptr... origs); AnonymousRangeFactory(const std::vector>& 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 GenSingleRange : 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 typename RangeInterface::IndexType IndexType; typedef GenSingleRange RangeType; typedef size_t MetaType; virtual size_t size() const final; virtual size_t dim() const final; size_t anonymousDim() const; size_t get(size_t pos) const; size_t getMeta(size_t metaPos) const; virtual IndexType begin() const final; virtual IndexType end() const final; virtual SpaceType spaceType() const final; virtual DataHeader dataHeader() 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 const std::vector >& orig() const; std::shared_ptr sreplace(const std::shared_ptr in, size_t num) const; std::shared_ptr sreplace(const std::vector>& in, size_t num) const; bool isEmpty() const; friend AnonymousRangeFactory; static AnonymousRangeFactory factory() { return AnonymousRangeFactory(); } protected: GenSingleRange() = default; GenSingleRange(const AnonymousRange& in) = default; template GenSingleRange(const std::tuple...>& origs); template GenSingleRange(std::shared_ptr... origs); GenSingleRange(const std::vector>& origs); size_t mSize = 1; bool mEmpty = true; std::vector > mOrig; }; } /* ========================= * * --- TEMPLATE CODE --- * * ========================= */ namespace MultiArrayTools { /*********************** * AnonymousRange * ***********************/ template AnonymousRangeFactory::AnonymousRangeFactory(const std::tuple...>& origs) { mProd = std::shared_ptr( new AnonymousRange( origs ) ); } template AnonymousRangeFactory::AnonymousRangeFactory(std::shared_ptr... origs) { mProd = std::shared_ptr( new AnonymousRange( origs... ) ); } template void AnonymousRangeFactory::append(std::shared_ptr r) { if(mProductCreated){ mProd = std::shared_ptr( new AnonymousRange( *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) { AnonymousRangeFactory 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->anonymousDim(); i != 0; --i){ v.insert(v.begin(), r->sub(i-1)); } } } } namespace MultiArrayTools { /*********************** * AnonymousRange * ***********************/ template GenSingleRange::GenSingleRange(const std::tuple...>& origs) : RangeInterface() { RPackNum::RangesToVec( origs, mOrig ); mSize = RPackNum::getSize( origs ); if(sizeof...(RangeTypes)){ mEmpty = false; } } template GenSingleRange::GenSingleRange(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 GenSingleRange::fullsub(size_t num) const { return std::dynamic_pointer_cast( mOrig.at(num) ); } template std::shared_ptr > GenSingleRange::scast(SIZET... sizes) const { std::tuple...> rtp; RPackNum::resolveRangeType(mOrig, rtp, 0, sizes...); MultiRangeFactory mrf(rtp); return std::dynamic_pointer_cast >( mrf.create() ); } } #endif