// -*- C++ -*- #ifndef __single_range_h__ #define __single_range_h__ #include #include #include //#include "base_def.h" //#include "ranges/rpack_num.h" #include "ranges/index_base.h" #include "ranges/range_base.h" #include "ranges/x_to_string.h" #include "xfor/xfor.h" using MultiArrayHelper::For; namespace MultiArrayTools { template class SingleIndex : public IndexInterface,U> { public: typedef IndexInterface,U> IB; typedef U MetaType; typedef SingleRange RangeType; typedef SingleIndex IType; //DEFAULT_MEMBERS_X(SingleIndex); SingleIndex(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 POLYMORPHISM <<<<< ==== IndexType type() const; SingleIndex& operator=(size_t pos); SingleIndex& operator++(); SingleIndex& operator--(); int pp(std::intptr_t idxPtrNum); int mm(std::intptr_t idxPtrNum); std::string stringMeta() const; U meta() const; const U* metaPtr() const; SingleIndex& at(const U& metaPos); size_t dim(); // = 1 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(Expr ex) const -> For,Expr>; template auto iforh(Expr ex) const -> For,Expr,ForType::HIDDEN>; private: const U* mMetaPtr; }; 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 SingleRange RangeType; typedef U MetaType; //typedef typename RangeInterface >::IndexType IndexType; virtual size_t size() const override; virtual size_t dim() const override; virtual std::string stringMeta(size_t pos) const override; virtual std::vector data() 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; friend SingleRangeFactory; static constexpr bool defaultable = false; static constexpr size_t ISSTATIC = 0; static constexpr size_t SIZE = -1; static constexpr bool HASMETACONT = true; protected: SingleRange() = delete; SingleRange(const SingleRange& in) = delete; SingleRange(const std::vector& space); std::vector mSpace; }; } /* ========================= * * --- TEMPLATE CODE --- * * ========================= */ namespace MultiArrayTools { /****************** * SingleIndex * ******************/ template struct MetaPtrHandle { template static const typename Range::MetaType* set(Range* r) { return &r->get(0); } template static inline U getMeta(U* metaPtr, size_t pos, std::shared_ptr r) { return metaPtr[pos]; } }; template <> struct MetaPtrHandle { template static const typename Range::MetaType* set(Range* r) { return nullptr; } template static inline U getMeta(U* metaPtr, size_t pos, std::shared_ptr r) { return r->get(pos); } }; template SingleIndex::SingleIndex(const std::shared_ptr >& range) : IndexInterface,U>(range, 0), mMetaPtr(MetaPtrHandle::RangeType::HASMETACONT>::set ( dynamic_cast(IB::mRangePtr.get() ) ) ) {} template IndexType SingleIndex::type() const { return IndexType::SINGLE; } template SingleIndex& SingleIndex::operator=(size_t pos) { IB::mPos = pos; return *this; } template SingleIndex& SingleIndex::operator++() { ++IB::mPos; return *this; } template SingleIndex& SingleIndex::operator--() { --IB::mPos; return *this; } template int SingleIndex::pp(std::intptr_t idxPtrNum) { ++(*this); return 1; } template int SingleIndex::mm(std::intptr_t idxPtrNum) { --(*this); return 1; } template std::string SingleIndex::stringMeta() const { return std::dynamic_pointer_cast const>( IB::mRangePtr )->stringMeta(IB::mPos); } template U SingleIndex::meta() const { return MetaPtrHandle::RangeType::HASMETACONT>::getMeta ( mMetaPtr, IB::mPos, std::dynamic_pointer_cast const>( IB::mRangePtr ) ); } template const U* SingleIndex::metaPtr() const { return mMetaPtr; } template SingleIndex& SingleIndex::at(const U& metaPos) { (*this) = std::dynamic_pointer_cast const>( IB::mRangePtr )->getMeta( metaPos ); return *this; } template size_t SingleIndex::dim() // = 1 { return 1; } template bool SingleIndex::last() { return IB::mPos == IB::mMax - 1; } template bool SingleIndex::first() { return IB::mPos == 0; } template std::shared_ptr::RangeType> SingleIndex::range() { return std::dynamic_pointer_cast( IB::mRangePtr ); } template template void SingleIndex::getPtr() {} template size_t SingleIndex::getStepSize(size_t n) { return 1; } template std::string SingleIndex::id() const { return std::string("sin") + std::to_string(IB::mId); } template void SingleIndex::print(size_t offset) { if(offset == 0){ std::cout << " === " << std::endl; } for(size_t j = 0; j != offset; ++j) { std::cout << "\t"; } std::cout << id() << "[" << reinterpret_cast(this) << "](" << IB::mRangePtr << "): " << meta() << std::endl; } template template auto SingleIndex::ifor(Expr ex) const -> For,Expr> { //static const size_t LAYER = typename Expr::LAYER; return For,Expr>(this, ex); } template template auto SingleIndex::iforh(Expr ex) const -> For,Expr,ForType::HIDDEN> { //static const size_t LAYER = typename Expr::LAYER; return For,Expr,ForType::HIDDEN>(this, ex); } /******************** * 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 std::string SingleRange::stringMeta(size_t pos) const { return xToString(get(pos)); } template std::vector SingleRange::data() const { DataHeader h; h.spaceType = static_cast( TYPE ); h.metaSize = size() * sizeof(U); h.multiple = 0; std::vector out; out.reserve(h.metaSize + sizeof(DataHeader)); char* hcp = reinterpret_cast(&h); out.insert(out.end(), hcp, hcp + sizeof(DataHeader)); const char* scp = reinterpret_cast(mSpace.data()); out.insert(out.end(), scp, scp + h.metaSize); return out; } 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; } } #include "range_types/header.h" #endif