diff --git a/src/include/ranges/mrange.cc.h b/src/include/ranges/mrange.cc.h index 1dc6460..37691ac 100644 --- a/src/include/ranges/mrange.cc.h +++ b/src/include/ranges/mrange.cc.h @@ -8,41 +8,74 @@ namespace CNORXZ { + /*********************** + * MIndex (private) * + ***********************/ + + template + template + constexpr decltype(auto) MIndex::indexSequencePlus(std::index_sequence is) const + { + return std::index_sequence {}; + } + + template + template + constexpr decltype(auto) MIndex::mkIndexSequence() const + { + return indexSequencePlus(std::make_index_sequence{}); + } + + template + template + constexpr decltype(auto) MIndex::accumulatei(const G& g, const F& f, std::index_sequence is) const + { + return f( g(std::get(mIPack))... ); + } + + template + template + constexpr decltype(auto) MIndex::accumulate(const G& g, const F& f) const + { + return accumulatei(g, f, mkIndexSequence()) + } + + template + template + constexpr decltype(auto) mkIPack(SizeT pos, std::index_sequence is) const + { + static_assert(sizeof...(Is) == sizeof...(Indices), + "sequence size does not match number of indices"); + return std::make_tuple( std::make_shared( mRange->sub(Is) )... ); + } + + template + template + constexpr decltype(auto) mkBlockSizes(std::index_sequence is) const + { + static_assert(sizeof...(Is) == sizeof...(Indices)-1, + "set lowest block size manually"); + return Arr + { accumulate( [](const auto& i) { return i->max(); }, + [](const auto&... as) { return (as * ...); } ), + 1 }; + } + /************** * MIndex * **************/ - + template template - MIndex::MIndex(const Sptr& range) : - IndexInterface,Tuple >(0) - { - std::get(mBlockSizes) = 1; - sfor_mn - ( [&](auto i) { - auto r = range->template getPtr(); - std::get(mIPack) = r->beginPtr(); - *std::get(mIPack) = 0; - - std::get(mBlockSizes) = sfor_p - ( [&](auto j) { return std::get(mIPack)->max(); } , - [&](auto a, auto b) { return a * b; }); - return 0; - }); - - IB::mPos = sfor_m - ( [&](auto i) { return std::get(mIPack); }, - [&](auto a, auto b) {return a->pos() + b*a->max();}, 0 ); - } + MIndex::MIndex(const Sptr& range, SizeT pos) : + IndexInterface,Tuple>(pos), + mIPack(mkIPack(IB::mPos, std::make_index_sequence{})), + mBlockSizes(mkBlockSizes(IB::mPos), std::make_index_sequence{}), + mRange(range) + {} template - MIndex& MIndex::operator()(Sptr&... indices) - { - return (*this)(std::make_tuple(indices...)); - } - - template - MIndex& MIndex::operator()(const Tuple...>& indices) + MIndex& MIndex::operator()(const Sptr& mi) { sfor_pn<0,sizeof...(Indices)> ( [&](auto i) { std::get(mIPack) = std::get(indices); return 0; } ); @@ -158,20 +191,6 @@ namespace CNORXZ { return RangeHelper::mkFor<0>(step, mIPack, mBlockSizes, exs); } - - template - template - auto MIndex::iforh(SizeT step, Exprs exs) const - { - return RangeHelper::mkForh<0>(step, mIPack, mBlockSizes, exs); - } - - template - template - auto MIndex::pifor(SizeT step, Exprs exs) const - { - return RangeHelper::mkPFor<0>(step, mIPack, mBlockSizes, exs); - } */ /********************* @@ -179,63 +198,115 @@ namespace CNORXZ *********************/ template - MRangeFactory::MRangeFactory(const Sptr&... rs) - { - mProd = Sptr< MRange >( new MRange( rs... ) ); - } - - template - MRangeFactory::MRangeFactory(const typename MRange::Space& st) - { - mProd = Sptr< MRange >( new MRange( st ) ); - } + MRangeFactory::MRangeFactory(const Tuple...>& rs) : + mRs(rs) + {} template - Sptr MRangeFactory::create() + MRangeFactory::MRangeFactory(const Tuple...>& rs, + const RangePtr& ref) : + mRs(rs), + mRef(ref) + {} + + template + void MRangeFactory::make() { - mProd = checkIfCreated( std::dynamic_pointer_cast( mProd )->mSpace ); - setSelf(); - return mProd; + auto info = typeid(MRange); + if(mRef != nullptr) { + mProd = this->fromCreated[info.hash_code()][mRef->id()]; + } + if(mProd == nullptr) { + RangePtr key = mProd = std::shared_ptr> + ( new MRange( mSpace ) ); + if(mRef != nullptr) { key = mRef } + this->addToCreated(info, { key->id() }, mProd); + } } - /****************** + /************** * MRange * - ******************/ + **************/ template - MRange::MRange(const Sptr&... rs) : mSpace(std::make_tuple(rs...)) {} + MRange::MRange(const Tuple...>& rs) : + mRs(rs), + mA( mkA( std::make_index_sequence{} ) ) + {} template - MRange::MRange(const Space& space) : mSpace( space ) {} - - template - SizeT MRange::getMeta(const MetaType& metaPos) const + RangePtr MRange::sub(SizeT num) const { - return RangeHelper::getMeta(mSpace,metaPos); + CXZ_ASSERT(num < this->dim(), "index out of range"); + return mA[num]; + } + + template + SizeT MRange::size() const + { + return this->sizei(std::make_index_sequence {}); } template SizeT MRange::dim() const { - return sdim; + return sizeof...(Ranges); } template - SizeT MRange::size() const + String MRange::stringMeta(SizeT pos) const { - return sfor_p<0,sizeof...(Ranges)> - ( [&](auto i) { return std::get(mSpace)->size(); }, - [&](auto a, auto b) { return a * b; } ); + } template - String MRange::stringMeta(SizeT pos) const + IndexType MRange::begin() const { - auto i = begin(); - i = pos; - return "[" + RangeHelper::getStringMeta<0>(i) + "]"; + + } + + template + IndexType MRange::end() const + { + } + template + decltype(auto) MRange::space() const + { + return mRs; + } + + template + const MetaType MRange::get(SizeT pos) const + { + + } + + template + SizeT MRange::getMeta(const MetaType& metaPos) const + { + assert(0); + //return RangeHelper::getMeta(mSpace,metaPos); + } + + /************************ + * MRange (private) * + ************************/ + + template + template + decltype(auto) MRange::mkA(std::index_sequence is) const + { + return Arr { std::get(mRs)... }; + } + + template + SizeT MRange::sizei(std::index_sequence is) const + { + return ( std::get(mRs)->size() * ... ); + } + } #endif diff --git a/src/include/ranges/mrange.h b/src/include/ranges/mrange.h index b84c88e..1a7cb3a 100644 --- a/src/include/ranges/mrange.h +++ b/src/include/ranges/mrange.h @@ -33,8 +33,7 @@ namespace CNORXZ MIndex(const RangePtr& range, SizeT pos = 0); // replace sub-index instances; only use if you know what you are doing! - MIndex& operator()(Sptr&... indices); - MIndex& operator()(const MIndex& indices); + MIndex& operator()(const Sptr& mi); const IndexPack& pack() const { return mIPack; } const auto& getBlockSizes() const { return mBlockSizes; } @@ -66,16 +65,36 @@ namespace CNORXZ MetaType meta() const; MIndex& at(const MetaType& metaPos); - template - auto ifor(const PosT& step, const Xpr& xpr) const; + template + decltype(auto) ifor(const Xpr& xpr, F&& f) const; private: MIndex() = default; IndexPack mIPack; - Arr mBlockSizes; + Arr mBlockSizes; Sptr mRange; + // shift to utils: + template + constexpr decltype(auto) indexSequencePlus(std::index_sequence is) const; + + // shift to utils: + template + constexpr decltype(auto) mkIndexSequence() const; + + + template + constexpr decltype(auto) accumulatei(const G& g, const F& f, std::index_sequence is) const; + + template + constexpr decltype(auto) accumulate(const G& g, const F& f) const; + + template + constexpr decltype(auto) mkIPack(SizeT pos, std::index_sequence is) const; + + template + constexpr decltype(auto) mkBlockSizes(std::index_sequence is) const; }; @@ -84,44 +103,54 @@ namespace CNORXZ class MRangeFactory : public RangeFactoryBase { public: - MRangeFactory() = delete; - MRangeFactory(const Sptr&... rs); MRangeFactory(const Tuple...>& rs); + MRangeFactory(const Tuple...>& rs, const RangePtr& ref); private: + MRangeFactory() = default; virtual void make() override final; Tuple...> mRs; + RangePtr mRef; }; template - class MRange : public RangeInterface > + class MRange : public RangeInterface, + Tuple> { public: typedef RangeBase RB; typedef MIndex IndexType; typedef Tuple MetaType; - const Space& space() const; - - SizeT getMeta(const MetaType& metaPos) const; - - virtual Sptr sub(SizeT num) const override; - - virtual SizeT dim() const final; - virtual SizeT size() const final; - - virtual String stringMeta(SizeT pos) const final; - friend MRangeFactory; + virtual RangePtr sub(SizeT num) const override final; + virtual SizeT size() const override final; + virtual SizeT dim() const override final; + virtual String stringMeta(SizeT pos) const override final; + virtual IndexType begin() const override final; + virtual IndexType end() const override final; + + decltype(auto) space() const; + const MetaType get(SizeT pos) const; + SizeT getMeta(const MetaType& metaPos) const; + protected: MRange() = delete; MRange(const MRange& in) = delete; MRange& operator=(const MRange& in) = delete; + MRange(const Tuple...>& rs); Tuple...> mRs; + Arr mA; + private: + template + decltype(auto) mkA(std::index_sequence is) const; + + template + SizeT sizei(std::index_sequence is) const; }; } diff --git a/src/include/ranges/range_base.h b/src/include/ranges/range_base.h index 0994070..a4d91df 100644 --- a/src/include/ranges/range_base.h +++ b/src/include/ranges/range_base.h @@ -44,7 +44,8 @@ namespace CNORXZ public: virtual ~RangeBase() = default; - + + virtual RangePtr sub() const; virtual SizeT size() const = 0; virtual SizeT dim() const = 0; virtual const TypeInfo& type() const = 0; diff --git a/src/lib/ranges/range_base.cc b/src/lib/ranges/range_base.cc index 1c12b37..0084b96 100644 --- a/src/lib/ranges/range_base.cc +++ b/src/lib/ranges/range_base.cc @@ -39,6 +39,11 @@ namespace CNORXZ * RangeBase * ******************/ + RangePtr RangeBase::sub() const + { + return nullptr; + } + bool RangeBase::operator==(const RangeBase& in) const { return this == ∈