// -*- C++ -*- #ifndef __container_range_h__ #define __container_range_h__ #include #include #include #include "ranges/range_base.h" #include "ranges/index_base.h" #include "rpack_num.h" namespace MultiArrayTools { template class ContainerIndex : public IndexInterface, std::tuple >, public std::iterator { public: typedef IndexInterface, std::tuple > IB; typedef std::tuple MetaType; typedef std::tuple...> IndexPack; typedef ContainerRange RangeType; static constexpr IndexType sType() { return IndexType::CONT; } static constexpr size_t sDim() { return sizeof...(Indices); } static constexpr size_t totalDim() { return mkTotalDim(); } static constexpr SpaceType STYPE = SpaceType::ANY; private: ContainerIndex() = default; bool mNonTrivialBlocks = false; bool mExternControl = false; IndexPack mIPack; std::array mBlockSizes; const T* mData = nullptr; //const MultiArrayBase* mMa = nullptr; std::intptr_t mObjPtrNum; public: ContainerIndex(const ContainerIndex& in) = default; ContainerIndex& operator=(const ContainerIndex& in) = default; template ContainerIndex(const std::shared_ptr& range, std::intptr_t objPtrNum); template ContainerIndex(const std::shared_ptr& range, std::intptr_t objPtrNum, const std::array& blockSizes); template auto get() const -> decltype( *std::get( mIPack ) )&; template auto getPtr() const -> decltype( std::get( mIPack ) )&; template size_t getBlockSize() const { return std::get(mBlockSizes); } const IndexPack& pack() const { return mIPack; } ContainerIndex& sync(); // recalculate 'IB::mPos' when externalControl == true ContainerIndex& operator()(const std::shared_ptr&... inds); // control via external indices ContainerIndex& operator()(); // -> sync; just to shorten the code // ==== >>>>> STATIC POLYMORPHISM <<<<< ==== IndexType type() const; ContainerIndex& operator++(); ContainerIndex& operator--(); ContainerIndex& operator=(size_t pos); int pp(std::intptr_t idxPtrNum); int mm(std::intptr_t idxPtrNum); std::string stringMeta() const; MetaType meta() const; ContainerIndex& at(const MetaType& metaPos); size_t dim() const; bool first() const; bool last() const; bool sliceMode() const; std::shared_ptr range(); template auto getPtr() -> decltype( std::get( mIPack ) )&; size_t getStepSize(size_t n); std::string id() const; void print(size_t offset); template auto ifor(size_t step, Exprs exs) const -> decltype(RPackNum::mkFor(step, mIPack, mBlockSizes, exs)); template auto iforh(size_t step, Exprs exs) const -> decltype(RPackNum::mkForh(step, mIPack, mBlockSizes, exs)); std::intptr_t container() const; ContainerIndex& format(const std::array& blocks); // Iterator Stuff ContainerIndex& setData(const T* data); const T& operator*() const; const T* operator->() const; //T& operator*(); //T* operator->(); ContainerIndex operator++(int); ContainerIndex operator--(int); ContainerIndex& operator+=(int diff); ContainerIndex& operator-=(int diff); ContainerIndex operator+(int num) const; ContainerIndex operator-(int num) const; int operator-(const ContainerIndex& it) const; const T& operator[](int num) const; bool operator<(const ContainerIndex& it) const; bool operator>(const ContainerIndex& it) const; bool operator<=(const ContainerIndex& it) const; bool operator>=(const ContainerIndex& it) const; }; /* template class ContainerRangeFactory : public RangeFactoryBase { public: typedef ContainerRange oType; ContainerRangeFactory(); ContainerRangeFactory(const std::shared_ptr&... rs); ContainerRangeFactory(const typename ContainerRange::SpaceType& space); virtual std::shared_ptr create() override; protected: };*/ /* template class ContainerRange : public RangeInterface > { public: typedef RangeBase RB; typedef std::tuple...> SpaceType; typedef ContainerIndex IndexType; protected: ContainerRange() = default; ContainerRange(const ContainerRange& in) = delete; ContainerRange& operator=(const ContainerRange& in) = delete; ContainerRange(const std::shared_ptr&... rs); ContainerRange(const SpaceType& space); SpaceType mSpace; public: static const size_t sdim = sizeof...(Ranges); virtual size_t dim() const override; virtual size_t size() const override; template auto get() const -> decltype( *std::get( mSpace ) )&; template auto getPtr() const -> decltype( std::get( mSpace ) )&; const SpaceType& space() const; virtual IndexType begin() const override; virtual IndexType end() const override; friend ContainerRangeFactory; static constexpr bool defaultable = false; static constexpr size_t ISSTATIC = SubProp::ISSTATIC; static constexpr size_t SIZE = SubProp::SIZE; }; */ //template //using ContainerRange = MultiRange; } // end namespace MultiArrayTools /* ========================= * * --- TEMPLATE CODE --- * * ========================= */ namespace MultiArrayTools { namespace { using namespace MultiArrayHelper; } /********************** * ContainerIndex * **********************/ template template ContainerIndex::ContainerIndex(const std::shared_ptr& range, std::intptr_t objPtrNum) : IndexInterface,std::tuple >(range, 0), mObjPtrNum(objPtrNum) { RPackNum::construct(mIPack, *range); std::get(mBlockSizes) = 1; RPackNum::initBlockSizes(mBlockSizes, mIPack); IB::mPos = RPackNum::makePos(mIPack, mBlockSizes); } template template ContainerIndex::ContainerIndex(const std::shared_ptr& range, std::intptr_t objPtrNum, const std::array& blockSizes) : IndexInterface,std::tuple >(range, 0), mObjPtrNum(objPtrNum) { RPackNum::construct(mIPack, *range); mBlockSizes = blockSizes; IB::mPos = RPackNum::makePos(mIPack, mBlockSizes); mNonTrivialBlocks = true; } template ContainerIndex& ContainerIndex::sync() { if(mExternControl){ IB::mPos = RPackNum::makePos(mIPack); //VCHECK(id()); //VCHECK(sizeof...(Indices)); //assert(IB::mPos < IB::max()); } return *this; } template template auto ContainerIndex::get() const -> decltype( *std::get( mIPack ) )& { return *std::get( mIPack ); } template template auto ContainerIndex::getPtr() const -> decltype( std::get( mIPack ) )& { return std::get( mIPack ); } template ContainerIndex& ContainerIndex::operator()(const std::shared_ptr&... inds) { RPackNum::swapIndices(mIPack, inds...); mExternControl = true; return sync(); } template ContainerIndex& ContainerIndex::operator()() { return sync(); } template IndexType ContainerIndex::type() const { return IndexType::CONT; } template ContainerIndex& ContainerIndex::operator++() { if(mExternControl){ IB::mPos = RPackNum::makePos(mIPack); } RPackNum::pp( mIPack ); ++IB::mPos; return *this; } template ContainerIndex& ContainerIndex::operator--() { if(mExternControl){ IB::mPos = RPackNum::makePos(mIPack); } RPackNum::mm( mIPack ); --IB::mPos; return *this; } template ContainerIndex& ContainerIndex::operator=(size_t pos) { IB::mPos = pos; RPackNum::setIndexPack(mIPack, pos); return *this; } template int ContainerIndex::pp(std::intptr_t idxPtrNum) { int tmp = RPackNum::pp(mIPack, mBlockSizes, idxPtrNum); IB::mPos += tmp; return tmp; } template int ContainerIndex::mm(std::intptr_t idxPtrNum) { int tmp = RPackNum::mm(mIPack, mBlockSizes, idxPtrNum); IB::mPos -= tmp; return tmp; } template std::string ContainerIndex::stringMeta() const { return std::dynamic_pointer_cast( IB::mRangePtr )->stringMeta(IB::mPos); } template typename ContainerIndex::MetaType ContainerIndex::meta() const { MetaType metaTuple; RPackNum::getMetaPos(metaTuple, mIPack); return metaTuple; } template ContainerIndex& ContainerIndex::at(const MetaType& metaPos) { RPackNum::setMeta(mIPack, metaPos); IB::mPos = RPackNum::makePos(mIPack, mBlockSizes); return *this; } template size_t ContainerIndex::dim() const { return sizeof...(Indices); } template bool ContainerIndex::first() const { return IB::pos() == 0; } template bool ContainerIndex::last() const { return IB::pos() == IB::mMax - 1; } template bool ContainerIndex::sliceMode() const { return mNonTrivialBlocks; } template std::shared_ptr::RangeType> ContainerIndex::range() { return std::dynamic_pointer_cast( IB::mRangePtr ); } template template auto ContainerIndex::getPtr() -> decltype( std::get( mIPack ) )& { return std::get( mIPack ); } template size_t ContainerIndex::getStepSize(size_t n) { if(n >= sizeof...(Indices)){ assert(0); // throw !! } return mBlockSizes[n+1]; } template std::string ContainerIndex::id() const { return std::string("con") + std::to_string(IB::mId); } template void ContainerIndex::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; RPackNum::printIndex(mIPack, offset+1); } template template auto ContainerIndex::ifor(size_t step, Exprs exs) const -> decltype(RPackNum::mkFor(step, mIPack, mBlockSizes, exs)) { return RPackNum::mkFor(step, mIPack, mBlockSizes, exs); } template template auto ContainerIndex::iforh(size_t step, Exprs exs) const -> decltype(RPackNum::mkForh(step, mIPack, mBlockSizes, exs)) { return RPackNum::mkForh(step, mIPack, mBlockSizes, exs); } template std::intptr_t ContainerIndex::container() const { return mObjPtrNum; } template ContainerIndex& ContainerIndex:: format(const std::array& blocks) { mBlockSizes = blocks; return *this; } template ContainerIndex& ContainerIndex::setData(const T* data) { mData = data; return *this; } template const T& ContainerIndex::operator*() const { //return mMa[*this]; return mData[IB::mPos]; } template const T* ContainerIndex::operator->() const { //return &mMa[*this]; return &mData[IB::mPos]; } /* template T& ContainerIndex::operator*() { //return mMa[*this]; return mData[IB::mPos]; } template T* ContainerIndex::operator->() { //return &mMa[*this]; return &mData[IB::mPos]; } */ template ContainerIndex ContainerIndex::operator++(int) { auto tmp = *this; ++(*this); return tmp; } template ContainerIndex ContainerIndex::operator--(int) { auto tmp = *this; --(*this); return tmp; } template ContainerIndex& ContainerIndex::operator+=(int diff) { if(diff < 0){ for(int i = 0; i != diff; ++i){ (*this)--; } } else { for(int i = 0; i != diff; ++i){ (*this)++; } } return *this; } template ContainerIndex& ContainerIndex::operator-=(int diff) { if(diff < 0){ for(int i = 0; i != diff; ++i){ (*this)++; } } else { for(int i = 0; i != diff; ++i){ (*this)--; } } return *this; } template ContainerIndex ContainerIndex::operator+(int num) const { auto tmp = *this; return tmp += num; } template ContainerIndex ContainerIndex::operator-(int num) const { auto tmp = *this; return tmp -= num; } template int ContainerIndex::operator-(const ContainerIndex& it) const { return static_cast( IB::mPos ) - static_cast( it.pos() ); } template const T& ContainerIndex::operator[](int num) const { return mData[IB::mPos + num]; } template bool ContainerIndex::operator<(const ContainerIndex& it) const { return IB::mPos < it.pos(); } template bool ContainerIndex::operator>(const ContainerIndex& it) const { return IB::mPos > it.pos(); } template bool ContainerIndex::operator<=(const ContainerIndex& it) const { return IB::mPos <= it.pos(); } template bool ContainerIndex::operator>=(const ContainerIndex& it) const { return IB::mPos >= it.pos(); } /***************************** * ContainerRangeFactory * *****************************/ /* template ContainerRangeFactory::ContainerRangeFactory(const std::shared_ptr&... rs) { mProd = std::shared_ptr >( new ContainerRange( rs... ) ); } template ContainerRangeFactory:: ContainerRangeFactory(const typename ContainerRange::SpaceType& space) { mProd = std::shared_ptr >( new ContainerRange( space ) ); } template std::shared_ptr ContainerRangeFactory::create() { setSelf(); return mProd; } */ /********************** * ContainerRange * **********************/ /* template ContainerRange::ContainerRange(const std::shared_ptr&... rs) : mSpace( std::make_tuple( rs... ) ) {} template ContainerRange::ContainerRange(const SpaceType& space) : mSpace( space ) {} template size_t ContainerRange::dim() const { return sizeof...(Ranges); } template size_t ContainerRange::size() const { return RPackNum::getSize(mSpace); } template template auto ContainerRange::get() const -> decltype( *std::get( mSpace ) )& { return *std::get( mSpace ); } template template auto ContainerRange::getPtr() const -> decltype( std::get( mSpace ) )& { return std::get( mSpace ); } template const typename ContainerRange::SpaceType& ContainerRange::space() const { return mSpace; } template typename ContainerRange::IndexType ContainerRange::begin() const { ContainerIndex i( std::dynamic_pointer_cast > ( std::shared_ptr( RB::mThis ) ) ); i = 0; return i; } template typename ContainerRange::IndexType ContainerRange::end() const { ContainerIndex i( std::dynamic_pointer_cast > ( std::shared_ptr( RB::mThis ) ) ); i = size(); return i; } */ } // end namespace MultiArrayTools #endif