#ifndef __subrange_h__ #define __subrange_h__ #include #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 "ranges/type_map.h" #include "xfor/for_type.h" namespace MultiArrayTools { namespace { using namespace MultiArrayHelper; } template class SubIndex : public IndexInterface,typename Index::MetaType> { public: typedef IndexInterface,typename Index::MetaType> IB; typedef typename Index::MetaType MetaType; typedef SubRange RangeType; typedef SubIndex IType; SubIndex(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 constexpr SpaceType STYPE = Index::STYPE; IndexType type() const; SubIndex& operator=(size_t pos); SubIndex& operator++(); SubIndex& operator--(); SubIndex& operator()(const std::shared_ptr& ind); // set full index int pp(std::intptr_t idxPtrNum); int mm(std::intptr_t idxPtrNum); std::string stringMeta() const; MetaType meta() const; const MetaType* metaPtr() const; SubIndex& at(const MetaType& metaPos); size_t posAt(const MetaType& metaPos) const; bool isMeta(const MetaType& metaPos) const; 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(size_t step, Expr ex) const -> For,SubExpr>; template auto iforh(size_t step, Expr ex) const -> For,SubExpr,ForType::HIDDEN>; template auto pifor(size_t step, Expr ex) const -> decltype(ifor(step, ex)); // no multithreading here (check!!) private: std::shared_ptr mExplicitRangePtr; //const U* mMetaPtr; std::shared_ptr mFullIndex; }; template class SubRangeFactory : public RangeFactoryBase { public: typedef SubRange oType; SubRangeFactory() = delete; SubRangeFactory(const std::shared_ptr& fullRange, const vector& subset); std::shared_ptr create(); }; template class SubRange : public RangeInterface> { private: SubRange() = delete; SubRange(const SubRange& in) = delete; SubRange(const std::shared_ptr& fullRange, const vector& subset); std::shared_ptr mFullRange; vector mSubSet; public: typedef RangeBase RB; typedef SubIndex IndexType; typedef SubRange RangeType; typedef typename IndexType::MetaType MetaType; typedef SubRangeFactory FType; virtual size_t size() const final; virtual size_t dim() const final; virtual SpaceType spaceType() const final; virtual DataHeader dataHeader() const final; virtual vector typeNum() const final; virtual size_t cmeta(char* target, size_t pos) const final; virtual size_t cmetaSize() const final; virtual std::string stringMeta(size_t pos) const final; virtual vector data() const final; bool isMeta(const MetaType& metaPos) const; auto get(size_t pos) const -> decltype(mFullRange->get(mSubSet[pos])); size_t getMeta(const MetaType& metaPos) const; virtual IndexType begin() const final; virtual IndexType end() const final; std::shared_ptr fullRange() const; const vector& subset() const; std::shared_ptr> outRange() const; friend SubRangeFactory; static constexpr bool defaultable = false; static constexpr size_t ISSTATIC = 0; static constexpr size_t SIZE = -1; static constexpr bool HASMETACONT = false; }; } // namespace MultiArrayTools namespace MultiArrayTools { /***************** * SubIndex * *****************/ template SubIndex::SubIndex(const std::shared_ptr& range) : IndexInterface,typename Index::MetaType>(range, 0), mExplicitRangePtr(std::dynamic_pointer_cast(IB::mRangePtr)) { mFullIndex = std::make_shared(mExplicitRangePtr->fullRange()); } template IndexType SubIndex::type() const { return IndexType::SINGLE; } template SubIndex& SubIndex::operator=(size_t pos) { IB::mPos = pos; (*mFullIndex) = mExplicitRangePtr->subset()[IB::mPos]; return *this; } template SubIndex& SubIndex::operator++() { ++IB::mPos; (*mFullIndex) = mExplicitRangePtr->subset()[IB::mPos]; return *this; } template SubIndex& SubIndex::operator--() { --IB::mPos; (*mFullIndex) = mExplicitRangePtr->subset()[IB::mPos]; return *this; } template SubIndex& SubIndex::operator()(const std::shared_ptr& ind) { assert(mFullIndex->range() == ind->range()); mFullIndex = ind; return *this; } template int SubIndex::pp(std::intptr_t idxPtrNum) { ++(*this); return 1; } template int SubIndex::mm(std::intptr_t idxPtrNum) { --(*this); return 1; } template std::string SubIndex::stringMeta() const { return std::dynamic_pointer_cast const>( IB::mRangePtr )->stringMeta(IB::mPos); } template typename SubIndex::MetaType SubIndex::meta() const { MetaType* x = nullptr; return MetaPtrHandle::RangeType::HASMETACONT>::getMeta ( x, IB::mPos, mExplicitRangePtr ); } template const typename SubIndex::MetaType* SubIndex::metaPtr() const { assert(0); // not sure where it is used return mFullIndex->metaPtr(); } template SubIndex& SubIndex::at(const MetaType& metaPos) { (*this) = mExplicitRangePtr->getMeta( metaPos ); return *this; } template size_t SubIndex::posAt(const MetaType& metaPos) const { return mExplicitRangePtr->getMeta( metaPos ); } template bool SubIndex::isMeta(const MetaType& metaPos) const { return mExplicitRangePtr->isMeta( metaPos ); } template size_t SubIndex::dim() { return 1; } template bool SubIndex::last() { return IB::mPos == IB::mMax - 1; } template bool SubIndex::first() { return IB::mPos == 0; } template std::shared_ptr::RangeType> SubIndex::range() { return mExplicitRangePtr; } template template void SubIndex::getPtr() {} template size_t SubIndex::getStepSize(size_t n) { return 1; } template std::string SubIndex::id() const { return std::string("sub") + std::to_string(IB::mId); } template void SubIndex::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 SubIndex::ifor(size_t step, Expr ex) const -> For,SubExpr> { return For,SubExpr> (this, step, SubExpr ( mFullIndex, reinterpret_cast(this), &mExplicitRangePtr->subset(), ex ) ); } template template auto SubIndex::iforh(size_t step, Expr ex) const -> For,SubExpr,ForType::HIDDEN> { return For,SubExpr,ForType::HIDDEN> (this, step, SubExpr ( mFullIndex, reinterpret_cast(this), &mExplicitRangePtr->subset(), ex ) ); } template template auto SubIndex::pifor(size_t step, Expr ex) const -> decltype(ifor(step, ex)) { return ifor(step, ex); } /************************ * SubRangeFactory * ************************/ template SubRangeFactory::SubRangeFactory(const std::shared_ptr& fullRange, const vector& subset) { mProd = std::shared_ptr( new SubRange( fullRange, subset ) ); } template std::shared_ptr SubRangeFactory::create() { setSelf(); return mProd; } /***************** * SubRange * *****************/ template SubRange::SubRange(const std::shared_ptr& fullRange, const vector& subset) : RangeInterface>(), mFullRange(fullRange), mSubSet(subset) {} template size_t SubRange::size() const { return mSubSet.size(); } template size_t SubRange::dim() const { return 1; } template SpaceType SubRange::spaceType() const { return SpaceType::ANY; } template DataHeader SubRange::dataHeader() const { DataHeader h; h.spaceType = static_cast( SpaceType::ANY ); h.metaSize = metaSize(mSubSet); h.metaType = NumTypeMap::num; h.multiple = 0; return h; } template vector SubRange::typeNum() const { return mFullRange->typeNum(); } template size_t SubRange::cmeta(char* target, size_t pos) const { return mFullRange->cmeta(target, mSubSet[pos]); } template size_t SubRange::cmetaSize() const { return mFullRange->cmetaSize(); } template std::string SubRange::stringMeta(size_t pos) const { return xToString(get(pos)); } template vector SubRange::data() const { DataHeader h = dataHeader(); vector out; out.reserve(h.metaSize + sizeof(DataHeader)); char* hcp = reinterpret_cast(&h); out.insert(out.end(), hcp, hcp + sizeof(DataHeader)); vector subvec(mSubSet.size()); size_t i = 0; for(auto& x: mSubSet){ subvec[i++] = mFullRange->get(x); } stringCat(out, subvec); return out; } template bool SubRange::isMeta(const MetaType& metaPos) const { for(size_t i = 0; i != size(); ++i){ if(get(i) == metaPos){ return true; } } return false; } template auto SubRange::get(size_t pos) const -> decltype(mFullRange->get(mSubSet[pos])) { return mFullRange->get( mSubSet[pos] ); } template size_t SubRange::getMeta(const MetaType& metaPos) const { for(size_t i = 0; i != size(); ++i){ if(get(i) == metaPos){ return i; } } return -1; } template typename SubRange::IndexType SubRange::begin() const { SubRange::IndexType i( std::dynamic_pointer_cast> ( std::shared_ptr( RB::mThis ) ) ); i = 0; return i; } template typename SubRange::IndexType SubRange::end() const { SubRange::IndexType i( std::dynamic_pointer_cast> ( std::shared_ptr( RB::mThis ) ) ); i = size(); return i; } template std::shared_ptr SubRange::fullRange() const { return mFullRange; } template const vector& SubRange::subset() const { return mSubSet; } template std::shared_ptr::MetaType,SpaceType::ANY>> SubRange::outRange() const { vector ometa(mSubSet.size()); size_t i = 0; for(auto& x: mSubSet){ ometa[i++] = mFullRange->get(x); } SingleRangeFactory srf(ometa); return std::dynamic_pointer_cast>( srf.create() ); } } #endif