#ifndef __value_range_h__ #define __value_range_h__ #include #include #include #include #include "rbase_def.h" //#include "base_def.h" #include "ranges/rpheader.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 ValueIndex : public IndexInterface,U> { public: typedef IndexInterface,U> IB; typedef U MetaType; typedef ValueRange RangeType; typedef ValueIndex IType; ValueIndex(const std::shared_ptr& rptr); 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 = SpaceType::NONE; IndexType type() const; ValueIndex& operator=(size_t pos); ValueIndex& operator++(); ValueIndex& operator--(); int pp(std::intptr_t idxPtrNum); int mm(std::intptr_t idxPtrNum); std::string stringMeta() const; const U& meta() const; const U* metaPtr() const; ValueIndex& at(const U& metaPos); size_t posAt(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,Expr>; template auto iforh(size_t step, Expr ex) const -> For,Expr,ForType::HIDDEN>; private: std::shared_ptr mExplicitRangePtr; U mMeta; }; template class ValueRangeFactory : public RangeFactoryBase { public: typedef ValueRange oType; ValueRangeFactory(); std::shared_ptr create(); }; template class ValueRange : public RangeInterface > { public: typedef RangeBase RB; typedef ValueIndex IndexType; typedef ValueRange RangeType; typedef U MetaType; typedef ValueRangeFactory FType; virtual size_t size() const final; virtual size_t dim() const final; virtual SpaceType spaceType() const final; virtual DataHeader dataHeader() const final; virtual size_t typeNum() const final; virtual size_t cmeta(char* target, size_t pos) const final; virtual std::string stringMeta(size_t pos) const final; virtual vector data() const final; U get(size_t pos) const; virtual IndexType begin() const final; virtual IndexType end() const final; friend ValueRangeFactory; static constexpr bool defaultable = true; static constexpr size_t ISSTATIC = 1; static constexpr size_t SIZE = 1; static constexpr bool HASMETACONT = false; static std::shared_ptr Default() { ValueRangeFactory vrf; return std::dynamic_pointer_cast( vrf.create() ); } protected: mutable U const* mMeta; ValueRange() = default; }; } // namespace MultiArrayTools /* ========================= * * --- TEMPLATE CODE --- * * ========================= */ namespace MultiArrayTools { /***************** * ValueIndex * *****************/ namespace { template std::shared_ptr mkDefaultValueRange() { ValueRangeFactory vrf; return vrf.create(); } } template ValueIndex::ValueIndex(const std::shared_ptr& rptr) : IndexInterface,U>(rptr, 0), mExplicitRangePtr(std::dynamic_pointer_cast(IB::mRangePtr)) {} template IndexType ValueIndex::type() const { return IndexType::SINGLE; } template ValueIndex& ValueIndex::operator=(size_t pos) { IB::mPos = pos; return *this; } template ValueIndex& ValueIndex::operator++() { ++IB::mPos; return *this; } template ValueIndex& ValueIndex::operator--() { --IB::mPos; return *this; } template int ValueIndex::pp(std::intptr_t idxPtrNum) { ++(*this); return 1; } template int ValueIndex::mm(std::intptr_t idxPtrNum) { --(*this); return 1; } template std::string ValueIndex::stringMeta() const { return xToString(mMeta); } template const U& ValueIndex::meta() const { return mMeta; } template const U* ValueIndex::metaPtr() const { return &mMeta; } template ValueIndex& ValueIndex::at(const U& metaPos) { mMeta = metaPos; return *this; } template size_t ValueIndex::posAt(const U& metaPos) const { return 0; } template size_t ValueIndex::dim() // = 1 { return 1; } template bool ValueIndex::last() { return IB::mPos == IB::mMax - 1; } template bool ValueIndex::first() { return IB::mPos == 0; } template std::shared_ptr::RangeType> ValueIndex::range() { return mExplicitRangePtr; } template template void ValueIndex::getPtr() {} template size_t ValueIndex::getStepSize(size_t n) { return 1; } template std::string ValueIndex::id() const { return std::string("val") + std::to_string(IB::mId); } template void ValueIndex::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 ValueIndex::ifor(size_t step, Expr ex) const -> For,Expr> { //static const size_t LAYER = typename Expr::LAYER; return For,Expr>(this, step, ex); } template template auto ValueIndex::iforh(size_t step, Expr ex) const -> For,Expr,ForType::HIDDEN> { //static const size_t LAYER = typename Expr::LAYER; return For,Expr,ForType::HIDDEN>(this, step, ex); } /************************** * ValueRangeFactory * **************************/ template ValueRangeFactory::ValueRangeFactory() { mProd = std::shared_ptr( new ValueRange() ); } template std::shared_ptr ValueRangeFactory::create() { setSelf(); return mProd; } /******************* * ValueRange * *******************/ template size_t ValueRange::size() const { return 1; } template size_t ValueRange::dim() const { return 1; } template SpaceType ValueRange::spaceType() const { return SpaceType::NONE; } template size_t ValueRange::typeNum() const { return NumTypeMap::num; } template size_t ValueRange::cmeta(char* target, size_t pos) const { if(target){ *reinterpret_cast(target) = *mMeta; } return sizeof(U); } template std::string ValueRange::stringMeta(size_t pos) const { return ""; } template U ValueRange::get(size_t pos) const { return *mMeta; } template vector ValueRange::data() const { assert(0); DataHeader h = dataHeader(); 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 DataHeader ValueRange::dataHeader() const { DataHeader h; h.spaceType = static_cast( SpaceType::NONE ); h.metaSize = 0; h.metaType = NumTypeMap::num; h.multiple = 0; return h; } template typename ValueRange::IndexType ValueRange::begin() const { ValueIndex i( std::dynamic_pointer_cast > ( std::shared_ptr( RB::mThis ) ) ); i = 0; mMeta = &i.meta(); return i; } template typename ValueRange::IndexType ValueRange::end() const { ValueIndex i( std::dynamic_pointer_cast > ( std::shared_ptr( RB::mThis ) ) ); i = size(); mMeta = &i.meta(); return i; } } // namespace MultiArrayTools #endif