// -*- C++ -*- #ifndef __index_base_h__ #define __index_base_h__ #include #include #include #include "base_def.h" #include "range_base.h" namespace MultiArrayTools { size_t indexId() { static size_t id = 0; ++id; return id; } enum class IndexType{ SINGLE = 0, MULTI = 1, CONT = 2 }; class VirtualIndexWrapperBase { public: DEFAULT_MEMBERS(VirtualIndexWrapperBase); virtual IndexType type() const = 0; virtual size_t dim() const = 0; virtual size_t pos() const = 0; virtual size_t max() const = 0; virtual std::shared_ptr rangePtr() const = 0; virtual VirtualIndexWrapperBase getPtr(size_t n) const = 0; virtual intptr_t getPtrNum() const = 0; }; typedef VirtualIndexWrapperBase VIWB; template std::shared_ptr > make_viwb(std::shared_ptr idxPtr) { return std::make_shared >(idxPtr); } template std::shared_ptr > make_viwb(const I& idxPtr) { return make_viwb( std::make_shared(idxPtr) ); } template class IndexWrapper { public: DEFAULT_MEMBERS(IndexWrapper); IndexWrapper(std::shared_ptr& idxPtr); virtual IndexType type() const override { return mIdxPtr->type(); } virtual size_t dim() const override { return mIdxPtr->dim(); } virtual size_t pos() const override { return mIdxPtr->pos(); } virtual size_t max() const override { return mIdxPtr->max(); } virtual std::shared_ptr rangePtr() const override { return mIdxPtr->rangePtr(); } virtual std::shared_ptr getPtr(size_t n) const override { return mIdxPtr->getv(n); } virtual intptr_t getPtrNum() const override { return static_cast( mIdxPtr.get() ); }; private: std::shared_ptr mIdxPtr; }; template class IndexInterface { public: //DEFAULT_MEMBERS(IndexInterface); I* THIS() { return static_cast(this); } ~IndexInterface() = default; IndexType type() const { return I::S_type(THIS()); } IndexInterface& operator=(size_t pos) { return I::S_ass_op(THIS(), pos); } IndexInterface& operator++() { return I::S_pp_op(THIS()); } IndexInterface& operator--() { return I::S_mm_op(THIS()); } int pp(std::shared_ptr& idxPtr) { return I::S_pp(THIS()); } int mm(std::shared_ptr& idxPtr) { return I::S_mm(THIS()); } bool operator==(const IndexInterface& in) const; bool operator!=(const IndexInterface& in) const; size_t dim() const { return I::S_dim(THIS()); } size_t pos() const; size_t max() const; bool last() const { return I::S_last(THIS()); } bool first() const { return I::S_first(THIS()); } std::shared_ptr rangePtr() const; template auto getPtr() const -> decltype(I::S_get(THIS())) { return I::S_get(THIS()); } std::shared_ptr getVPtr(size_t n) const { return I::S_getVPtr(THIS(),n); } size_t getStepSize(size_t n) const { return I::S_getStepSize(THIS(),n); } operator size_t() const; std::string id() const { return I::S_id(THIS()); } MetaType meta() const { return I::S_meta(THIS()); } IndexInterface& at(const MetaType& meta) { return I::S_at(THIS(), meta); } protected: IndexInterface() { mId = indexId(); } IndexInterface(IndexInterface&& in) = default; IndexInterface& operator=(IndexInterface&& in) = default; IndexInterface(const std::shared_ptr& range, size_t pos); std::shared_ptr mRangePtr; size_t mPos; size_t mId; }; } /* ========================= * * --- TEMPLATE CODE --- * * ========================= */ namespace MultiArrayTools { /***************** * IndexInterface * *****************/ template IndexInterface::IndexInterface(const std::shared_ptr& range, size_t pos) : mRangePtr(range), mPos(pos) { mId = indexId(); } template bool IndexInterface::operator==(const IndexInterface& in) const { return in.mPos == mPos and in.mRangePtr.get() == mRangePtr.get(); } template bool IndexInterface::operator!=(const IndexInterface& in) const { return in.mPos != mPos or in.mRangePtr.get() != mRangePtr.get(); } template size_t IndexInterface::pos() const { return mPos; } template size_t IndexInterface::max() const { return mRangePtr->size(); } template std::shared_ptr IndexInterface::rangePtr() const { return mRangePtr; } template IndexInterface::operator size_t() const { return pos(); } } #endif