// -*- C++ -*- #ifndef __single_range_h__ #define __single_range_h__ #include #include #include #include "base_def.h" #include "index_base.h" #include "range_base.h" namespace MultiArrayTools { template class SingleIndex : public IndexInterface,U> { public: typedef IndexInterface,U> IB; typedef U MetaType; typedef SingleRange RangeType; //DEFAULT_MEMBERS_X(SingleIndex); SingleIndex(const std::shared_ptr >& range); SingleIndex& operator=(size_t pos) { IB::operator=(pos); return *this; } std::shared_ptr range() const { return std::dynamic_pointer_cast( IB::mRangePtr ); } private: friend IB; // ==== >>>>> STATIC POLYMORPHISM <<<<< ==== static IndexType S_type(SingleIndex const* i) { return IndexType::SINGLE; } static SingleIndex& S_ass_op(SingleIndex* i, size_t pos) { i->mPos = pos; return *i; } static SingleIndex& S_pp_op(SingleIndex* i) { ++i->mPos; return *i; } static SingleIndex& S_mm_op(SingleIndex* i) { --i->mPos; return *i; } static int S_pp(SingleIndex* i, std::intptr_t idxPtrNum) { ++(*i); return 1; } static int S_mm(SingleIndex* i, std::intptr_t idxPtrNum) { --(*i); return 1; } static U S_meta(SingleIndex const* i) { return std::dynamic_pointer_cast const>( i->mRangePtr )->get( i->pos() ); } static SingleIndex& S_at(SingleIndex* i, const U& metaPos) { (*i) = std::dynamic_pointer_cast const>( i->mRangePtr )->getMeta( metaPos ); return *i; } static size_t S_dim(SingleIndex const* i) // = 1 { return 1; } static bool S_last(SingleIndex const* i) { return i->mPos == i->mMax - 1; } static bool S_first(SingleIndex const* i) { return i->mPos == 0; } static std::shared_ptr S_range(SingleIndex const* i) { return std::dynamic_pointer_cast( i->mRangePtr ); } template static void S_getPtr(SingleIndex* i) {} static std::shared_ptr S_getVPtr(SingleIndex const* i, size_t n) { return std::shared_ptr(); } static size_t S_getStepSize(SingleIndex const* i, size_t n) { return 1; } static std::string S_id(SingleIndex const* i) { return std::string("sin") + std::to_string(i->mId); } static void S_print(SingleIndex const* i, size_t offset) { if(offset == 0){ std::cout << " === " << std::endl; } for(size_t j = 0; j != offset; ++j) { std::cout << "\t"; } std::cout << S_id(i) << "[" << reinterpret_cast(i) << "](" << i->mRangePtr << "): " << S_meta(i) << std::endl; } }; template class SingleRangeFactory : public RangeFactoryBase { public: typedef SingleRange oType; SingleRangeFactory() = delete; SingleRangeFactory(const std::vector& space); std::shared_ptr create(); }; template class SingleRange : public RangeInterface > { public: typedef RangeBase RB; typedef SingleIndex IndexType; //typedef typename RangeInterface >::IndexType IndexType; virtual size_t size() const override; virtual size_t dim() const override; const U& get(size_t pos) const; size_t getMeta(const U& metaPos) const; virtual IndexType begin() const override; virtual IndexType end() const override; virtual std::shared_ptr index() const override; friend SingleRangeFactory; protected: SingleRange() = delete; SingleRange(const SingleRange& in) = delete; SingleRange(const std::vector& space); std::vector mSpace; }; } /* ========================= * * --- TEMPLATE CODE --- * * ========================= */ namespace MultiArrayTools { /****************** * SingleIndex * ******************/ template SingleIndex::SingleIndex(const std::shared_ptr >& range) : IndexInterface,U>(range, 0) {} /******************** * SingleRange * ********************/ template SingleRangeFactory::SingleRangeFactory(const std::vector& space) { mProd = std::shared_ptr( new SingleRange( space ) ); } template std::shared_ptr SingleRangeFactory::create() { setSelf(); return mProd; } /******************** * SingleRange * ********************/ template SingleRange::SingleRange(const std::vector& space) : RangeInterface >(), mSpace(space) {} template const U& SingleRange::get(size_t pos) const { return mSpace[pos]; } template size_t SingleRange::getMeta(const U& metaPos) const { size_t cnt = 0; for(auto& x: mSpace){ if(x == metaPos){ return cnt; } ++cnt; } return cnt; } template size_t SingleRange::size() const { return mSpace.size(); } template size_t SingleRange::dim() const { return 1; } template typename SingleRange::IndexType SingleRange::begin() const { SingleIndex i( std::dynamic_pointer_cast > ( std::shared_ptr( RB::mThis ) ) ); i = 0; return i; } template typename SingleRange::IndexType SingleRange::end() const { SingleIndex i( std::dynamic_pointer_cast > ( std::shared_ptr( RB::mThis ) ) ); i = size(); return i; } // put this in the interface class !!! template std::shared_ptr SingleRange::index() const { typedef IndexWrapper IW; return std::make_shared ( std::make_shared ( std::dynamic_pointer_cast > ( std::shared_ptr( RB::mThis ) ) ) ); } } #include "range_types/header.h" #endif