diff --git a/src/include/ranges/subrange.h b/src/include/ranges/subrange.h new file mode 100644 index 0000000..8ded014 --- /dev/null +++ b/src/include/ranges/subrange.h @@ -0,0 +1,448 @@ + +#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> + { + typedef IndexInterface> IB; + typedef typename SubIndex::MetaType MetaType; + typedef SubRange::RangeType> RangeType; + typedef SubIndex IndexType; + + SubIndex(const std::shared_ptr& range); + + static constexpr IndexType sType() { return typename Index::sType(); } + static constexpr size_t totalDim() { return typename Index::totalDim(); } + static constexpr size_t sDim() { return typename Index::sDim(); } + + static constexpr SpaceType STYPE = typename Index::STYPE; + + IndexType type() const; + + SubIndex& operator=(size_t pos); + SubIndex& operator++(); + SubIndex& operator--(); + + int pp(std::intptr_t idxPtrNum); + int mm(std::intptr_t idxPtrNum); + + std::string stringMeta() const; + U meta() const; + const U* metaPtr() const; + SubIndex& at(const U& metaPos); + size_t posAt(const U& metaPos) const; + + bool isMeta(const U& 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,Expr,ForType::HIDDEN>; + */ + 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 std::vector& subset); + std::shared_ptr create(); + } + + template + class SubRange : public RangeInterface> + { + 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 std::string stringMeta(size_t pos) const final; + virtual std::vector data() const final; + + bool isMeta(const U& metaPos) const; + + const U& get(size_t pos) const; + size_t getMeta(const U& metaPos) const; + + virtual IndexType begin() const final; + virtual IndexType end() const final; + + std::shared_ptr fullRange() const; + const std::vector& subset() 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; + + private: + + SubRange() = delete; + SubRange(const SubRange& in) = delete; + + SubRange(const std::shared_ptr& fullRange, const std::vector& subset); + + std::shared_ptr mFullRange; + std::vector mSubSet; + }; + +} // namespace MultiArrayTools + +namespace MultiArrayTools +{ + + /***************** + * SubIndex * + *****************/ + + template + SubIndex::SubIndex(const std::shared_ptr& range) : + IndexInterface>(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 + 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 + U SubIndex::meta() const + { + return MetaPtrHandle::RangeType::HASMETACONT>::getMeta + ( mMetaPtr, IB::mPos, mExplicitRangePtr ); + } + + template + const U* SubIndex::metaPtr() const + { + assert(0); // not sure where it is used + return mFullIndex->metaPtr(); + } + + template + SubIndex& SubIndex::at(const U& metaPos) + { + (*this) = mExplicitRangePtr->getMeta( metaPos ); + return *this; + } + + template + size_t SubIndex::posAt(const U& metaPos) const + { + return mExplicitRangePtr->getMeta( metaPos ); + } + + template + bool SubIndex::isMeta(const U& 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, /**/, SubExpr( mFullIndex, /**/ ) ); + } + + /************************ + * SubRangeFactory * + ************************/ + + template + SubRangeFactory::SubRangeFactory(const std::shared_ptr& fullRange, + const std::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 std::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; + } + + std::string SubRange::stringMeta(size_t pos) const + { + return xToString(get(pos)); + } + + template + std::vector SubRange::data() const + { + DataHeader h = dataHeader(); + std::vector out; + out.reserve(h.metaSize + sizeof(DataHeader)); + char* hcp = reinterpret_cast(&h); + out.insert(out.end(), hcp, hcp + sizeof(DataHeader)); + std::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 U& metaPos) const + { + for(size_t i = 0; i != size(); ++i){ + if(get(i) == metaPos){ + return true; + } + } + return false; + } + + template + const SubRange::MetaType& SubRange::get(size_t pos) const + { + return mFullRange->get( mSubSet[pos] ); + } + + template + size_t SubRange::getMeta(const U& metaPos) const + { + for(size_t i = 0; i != size(); ++i){ + if(get(i) == metaPos){ + return i; + } + } + return -1; + } + + template + SubRange::IndexType SubRange::begin() const + { + SubRange::IndexType i( std::dynamic_pointer_cast> + ( std::shared_ptr( RB::mThis ) ) ); + i = 0; + return i; + } + + template + 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 std::vector& SubRange::subset() const + { + return mSubSet; + } + +} + +#endif