diff --git a/src/include/base/to_string.cc.h b/src/include/base/to_string.cc.h index 2ac4878..dac3678 100644 --- a/src/include/base/to_string.cc.h +++ b/src/include/base/to_string.cc.h @@ -3,6 +3,7 @@ #define __cxz_to_string_cc_h__ #include "to_string.h" +#include "iter.h" #include namespace CNORXZ @@ -29,7 +30,7 @@ namespace CNORXZ } template - String ToString>::func(const std::array& a) + String ToString>::func(const Arr& a) { std::stringstream ss; ss << "("; @@ -41,6 +42,19 @@ namespace CNORXZ return ss.str(); } + template + String ToString>::func(const Tuple& t) + { + const String blim = "("; + const String elim = ")"; + const String dlim = ","; + return iter<1,sizeof...(Ts)> + ( [&](auto i) { return toString(std::get(t)); }, + [&](const auto&... xs) { + return blim + toString(std::get<0>(t)) + ( (dlim + xs) + ... ) + elim; + } ); + } + template String toString(const T& a) { diff --git a/src/include/base/to_string.h b/src/include/base/to_string.h index 148ef1f..08f055b 100644 --- a/src/include/base/to_string.h +++ b/src/include/base/to_string.h @@ -30,6 +30,12 @@ namespace CNORXZ static String func(const Arr& a); }; + template + struct ToString> + { + static String func(const Tuple& t); + }; + template <> struct ToString { diff --git a/src/include/ranges/crange.h b/src/include/ranges/crange.h index 354df24..8daf6c4 100644 --- a/src/include/ranges/crange.h +++ b/src/include/ranges/crange.h @@ -15,6 +15,7 @@ namespace CNORXZ typedef IndexInterface IB; typedef CRange RangeType; + typedef SizeT MetaType; CIndex(const RangePtr& range, SizeT pos = 0); @@ -63,7 +64,7 @@ namespace CNORXZ RangePtr mRef; }; - class CRange : public RangeInterface + class CRange : public RangeInterface { public: typedef RangeBase RB; diff --git a/src/include/ranges/mrange.cc.h b/src/include/ranges/mrange.cc.h index 6c8442a..376a61e 100644 --- a/src/include/ranges/mrange.cc.h +++ b/src/include/ranges/mrange.cc.h @@ -3,8 +3,6 @@ #define __cxz_mrange_cc_h__ #include "mrange.h" -#include "range_helper.h" -#include "statics/static_for.h" namespace CNORXZ { @@ -22,11 +20,13 @@ namespace CNORXZ } template - constexpr decltype(auto) MIndex::mkBlockSizes() const + template + constexpr decltype(auto) MIndex::mkBlockSizes(const IndexPack& ipack, Isq is) { return std::make_tuple ( iter - ( [&](auto i) { return std::get(mIPack)->max(); }, + // replace UPos by SPos where possible !!! + ( [&](auto i) { return UPos(std::get(ipack)->max()); }, [&](const auto&... as) { return (as * ...); } )..., SPos<1>() ); } @@ -38,13 +38,13 @@ namespace CNORXZ auto& i = std::get(mIPack); if constexpr(I != 0){ if(i->pos() == i->max()-1){ - IB::mPos -= std::get(mBlockSize) * i->pos(); + IB::mPos -= std::get(mBlockSizes).val() * i->pos(); (*i) = 0; - upi(); + up(); return; } } - IB::mPos += std::get(mBlockSize); + IB::mPos += std::get(mBlockSizes).val(); ++(*i); } @@ -56,12 +56,12 @@ namespace CNORXZ if constexpr(I != 0){ if(i->pos() == 0){ (*i) = i->max()-1; - IB::mPos += std::get(mBlockSize) * i->pos(); - downi(); + IB::mPos += std::get(mBlockSizes).val() * i->pos(); + down(); return; } } - IB::mPos -= std::get(mBlockSize); + IB::mPos -= std::get(mBlockSizes).val(); --(*i); } @@ -69,7 +69,7 @@ namespace CNORXZ template constexpr decltype(auto) MIndex::mkIFor(const Xpr& xpr, F&& f) const { - if constexpr(I == sizeof..(Indices)-1){ + if constexpr(I == sizeof...(Indices)-1){ return std::get(mIPack)->ifor(xpr,f); } else { @@ -85,27 +85,26 @@ namespace CNORXZ MIndex::MIndex(const MIndex& i) : IndexInterface,Tuple>(i.pos()), mIPack(mkIPack(IB::mPos, Isqr<0,NI>{})), - mBlockSizes(mkBlockSizes(), Isqr<0,NI>{}), - mRange(i.range()) + mBlockSizes(mkBlockSizes(mIPack,Isqr<0,NI-1>{})), + mRange(rangeCast(i.range())) {} template - MIndex& MIndex::operator=(const MIndex& i) + MIndex& MIndex::operator=(const MIndex& i) { IndexInterface,Tuple>::operator=(i); mIPack = mkIPack(IB::mPos, Isqr<0,NI>{}); - mBlockSizes(mkBlockSizes(), Isqr<0,NI>{}); - mRange = i.range(); + mBlockSizes = mkBlockSizes(mIPack,Isqr<0,NI-1>{}); + mRange = rangeCast(i.range()); return *this; } template - template - MIndex::MIndex(const Sptr& range, SizeT pos) : + MIndex::MIndex(const RangePtr& range, SizeT pos) : IndexInterface,Tuple>(0), mIPack(mkIPack(IB::mPos, Isqr<0,NI>{})), - mBlockSizes(mkBlockSizes(), Isqr<0,NI>{}), - mRange(range), + mBlockSizes(mkBlockSizes(mIPack,Isqr<0,NI-1>{})), + mRange(rangeCast(range)) { (*this) = pos; } @@ -114,7 +113,7 @@ namespace CNORXZ MIndex& MIndex::operator=(SizeT pos) { IB::mPos = pos; - iter<0,NI>( [&](auto i) { std::get(mIPack) = (IB::mPos / std::get(mBlockSize)) % std::get(mIPack)->max() }, NoF{} ); + iter<0,NI>( [&](auto i) { *std::get(mIPack) = (IB::mPos / std::get(mBlockSizes).val()) % std::get(mIPack)->max(); }, NoF{} ); return *this; } @@ -153,9 +152,9 @@ namespace CNORXZ } template - MIndex& MIndex::operator+=(Int n) + MIndex& MIndex::operator+=(Int n) { - if(-n > IB::mPos){ + if(-n > static_cast(IB::mPos)){ (*this) = 0; } const SizeT p = IB::mPos + n; @@ -167,9 +166,9 @@ namespace CNORXZ } template - MIndex& MIndex::operator-=(Int n) + MIndex& MIndex::operator-=(Int n) { - if(n > IB::mPos){ + if(n > static_cast(IB::mPos)){ (*this) = 0; } const SizeT p = IB::mPos + n; @@ -193,7 +192,7 @@ namespace CNORXZ } template - MetaType MIndex::operator*() const + typename MIndex::MetaType MIndex::operator*() const { return meta(); } @@ -205,25 +204,25 @@ namespace CNORXZ } template - Sptr MIndex::range() const + Sptr::RangeType> MIndex::range() const { return mRange; } template template - decltype(auto) MIndex::stepSize(const IndexId& id) const; + decltype(auto) MIndex::stepSize(const IndexId& id) const { return iter<0,NI> - ( [&](auto i) { return std::get(mIPack)->stepSize(id) * std::get(mBlockSize); }, + ( [&](auto i) { return std::get(mIPack)->stepSize(id) * std::get(mBlockSizes); }, [](const auto&... ss) { return ( ss + ... ); }); } template String MIndex::stringMeta() const { - const String blim = "["; - const String elim = "]"; + const String blim = "("; + const String elim = ")"; const String dlim = ","; return iter<1,NI> ( [&](auto i) { return std::get(mIPack)->stringMeta(); }, @@ -242,9 +241,9 @@ namespace CNORXZ template MIndex& MIndex::at(const MetaType& metaPos) { - iter<0,NI>( [&](auto i) { std::get(mIPack)->at( std::get(meta) ) }, NoF {} ); + iter<0,NI>( [&](auto i) { std::get(mIPack)->at( std::get(metaPos) ); }, NoF {} ); IB::mPos = iter<0,NI> - ( [&](auto i) { return std::get(mIPack)*std::get(mBlockSizes); }, + ( [&](auto i) { return std::get(mIPack)->pos()*std::get(mBlockSizes).val(); }, [](const auto&... xs) { return (xs + ...); }); return *this; } @@ -261,19 +260,19 @@ namespace CNORXZ { mIPack = mi.mIPack; IB::mPos = iter<0,NI> - ( [&](auto i) { return std::get(mIPack)*std::get(mBlockSizes); }, + ( [&](auto i) { return std::get(mIPack)->pos()*std::get(mBlockSizes).val(); }, [](const auto&... xs) { return (xs + ...); }); return *this; } template - const IndexPack& pack() const + const typename MIndex::IndexPack& MIndex::pack() const { return mIPack; } template - const auto& blockSizes() const + const auto& MIndex::blockSizes() const { return mBlockSizes; } @@ -298,14 +297,14 @@ namespace CNORXZ template void MRangeFactory::make() { - auto info = typeid(MRange); + const auto& info = typeid(MRange); if(mRef != nullptr) { - mProd = this->fromCreated[info.hash_code()][mRef->id()]; + mProd = this->fromCreated(info, {mRef->id()}); } if(mProd == nullptr) { RangePtr key = mProd = std::shared_ptr> - ( new MRange( mSpace ) ); - if(mRef != nullptr) { key = mRef } + ( new MRange( mRs ) ); + if(mRef != nullptr) { key = mRef; } this->addToCreated(info, { key->id() }, mProd); } } @@ -317,7 +316,7 @@ namespace CNORXZ template MRange::MRange(const Tuple...>& rs) : mRs(rs), - mA( mkA( std::make_index_sequence{} ) ) + mA( mkA() ) {} template @@ -330,7 +329,7 @@ namespace CNORXZ template SizeT MRange::size() const { - return iter<0,NR>( [&](auto i) { return std::get(mRs)->size() }, + return iter<0,NR>( [&](auto i) { return std::get(mRs)->size(); }, [](const auto&... xs) { return (xs * ...); } ); } @@ -343,7 +342,19 @@ namespace CNORXZ template String MRange::stringMeta(SizeT pos) const { - return (begin()+pos).stringMeta(); + return (this->begin()+pos).stringMeta(); + } + + template + const TypeInfo& MRange::type() const + { + return typeid(MRange); + } + + template + const TypeInfo& MRange::metaType() const + { + return typeid(MetaType); } template @@ -353,15 +364,15 @@ namespace CNORXZ } template - const MetaType MRange::get(SizeT pos) const + const typename MRange::MetaType MRange::get(SizeT pos) const { - return (begin()+pos)->meta(); + return (this->begin()+pos)->meta(); } template SizeT MRange::getMeta(const MetaType& metaPos) const { - auto i = begin(); + auto i = this->begin(); return i.at(metaPos).pos(); } @@ -372,8 +383,18 @@ namespace CNORXZ template decltype(auto) MRange::mkA() const { - return iter<0,NR>([&](auto i) { return std::get(mRs); }, - [](const auto&... xs) { return Arr { xs... } } ); + return iter<0,NR>([&](auto i) { return std::get(mRs); }, + [](const auto&... xs) { return Arr { xs... }; } ); + } + + /**************************** + * non-member functions * + ****************************/ + + template + RangePtr mrange(const Sptr&... rs) + { + return MRangeFactory(std::make_tuple(rs...)).create(); } } diff --git a/src/include/ranges/mrange.h b/src/include/ranges/mrange.h index 1b0437a..a4a2e80 100644 --- a/src/include/ranges/mrange.h +++ b/src/include/ranges/mrange.h @@ -28,8 +28,8 @@ namespace CNORXZ // ( have to assign sub-indices (ptr!) correctly ) MIndex() = default; MIndex(const MIndex& i); - MIndex(MIndex&& i); - MIndex& operator=(const MIndex& i) = default; + MIndex& operator=(const MIndex& i); + MIndex(MIndex&& i) = default; MIndex& operator=(MIndex&& i) = default; MIndex(const RangePtr& range, SizeT pos = 0); @@ -47,7 +47,7 @@ namespace CNORXZ MetaType operator*() const; - SizeT dim() const + SizeT dim() const; Sptr range() const; template @@ -67,16 +67,12 @@ namespace CNORXZ const auto& blockSizes() const; private: - IndexPack mIPack; - typedef decltype(mkBlockSizes(Isqr<0,NI-1>{})) BlockTuple; - BlockTuple mBlockSizes; - Sptr mRange; + template + static constexpr decltype(auto) mkBlockSizes(const IndexPack& ipack, Isq is); template constexpr decltype(auto) mkIPack(SizeT pos, Isq is) const; - constexpr decltype(auto) mkBlockSizes() const; - template inline void up(); @@ -85,6 +81,11 @@ namespace CNORXZ template constexpr decltype(auto) mkIFor(const Xpr& xpr, F&& f) const; + + IndexPack mIPack; + typedef RemoveRef{}))> BlockTuple; + BlockTuple mBlockSizes; + Sptr mRange; }; // modified blockSizes; to be used for Slices; can be created from MIndices @@ -123,8 +124,7 @@ namespace CNORXZ }; template - class MRange : public RangeInterface, - Tuple> + class MRange : public RangeInterface> { public: typedef RangeBase RB; @@ -138,8 +138,8 @@ namespace CNORXZ 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; + virtual const TypeInfo& type() const override final; + virtual const TypeInfo& metaType() const override final; decltype(auto) space() const; const MetaType get(SizeT pos) const; @@ -157,7 +157,9 @@ namespace CNORXZ decltype(auto) mkA() const; }; - + + template + RangePtr mrange(const Sptr&... rs); } #endif diff --git a/src/include/ranges/range_base.cc.h b/src/include/ranges/range_base.cc.h index a66abf2..8c80a4f 100644 --- a/src/include/ranges/range_base.cc.h +++ b/src/include/ranges/range_base.cc.h @@ -4,25 +4,30 @@ #include "range_base.h" #include "dindex.h" +#include "mrange.h" namespace CNORXZ { - template - Index RangeInterface::begin() const + template + decltype(auto) RangeInterface::begin() const { - return Index(RangePtr(RB::mThis), 0); + typedef typename Range::IndexType IndexType; + return IndexType(RangePtr(RB::mThis), 0); } - template - Index RangeInterface::end() const + template + decltype(auto) RangeInterface::end() const { - return Index(RangePtr(RB::mThis), this->size()); + typedef typename Range::IndexType IndexType; + return IndexType(RangePtr(RB::mThis), this->size()); } - template - DIndex RangeInterface::index(SizeT pos) const + template + DIndex RangeInterface::index(SizeT pos) const { - return XIndexPtr(std::make_shared>( this->begin()+pos )); + typedef typename Range::IndexType IndexType; + typedef typename IndexType::MetaType MetaType; + return XIndexPtr(std::make_shared>( this->begin()+pos )); } template diff --git a/src/include/ranges/range_base.h b/src/include/ranges/range_base.h index a4d91df..96c4a29 100644 --- a/src/include/ranges/range_base.h +++ b/src/include/ranges/range_base.h @@ -45,7 +45,7 @@ namespace CNORXZ virtual ~RangeBase() = default; - virtual RangePtr sub() const; + virtual RangePtr sub(SizeT num) const; virtual SizeT size() const = 0; virtual SizeT dim() const = 0; virtual const TypeInfo& type() const = 0; @@ -72,16 +72,15 @@ namespace CNORXZ RangePtr mRel; // used, if created from another range, to point on it }; - template + template class RangeInterface : public RangeBase { public: - typedef Index IndexType; typedef RangeBase RB; - Index begin() const; - Index end() const; + decltype(auto) begin() const; + decltype(auto) end() const; virtual DIndex index(SizeT pos) const override final; protected: @@ -97,7 +96,8 @@ namespace CNORXZ template Sptr rangeCast(const RangePtr r); - RangePtr operator*(const RangePtr& a, const RangePtr& b); // -> Ptr to MultiRange + RangePtr operator*(const RangePtr& a, const RangePtr& b); // -> Ptr to YRange + } #endif diff --git a/src/include/ranges/ranges.cc.h b/src/include/ranges/ranges.cc.h index 606acb6..fc79abd 100644 --- a/src/include/ranges/ranges.cc.h +++ b/src/include/ranges/ranges.cc.h @@ -1,6 +1,7 @@ #include "index_base.cc.h" #include "range_base.cc.h" +#include "mrange.cc.h" #include "xindex.cc.h" #include "urange.cc.h" #include "crange.cc.h" diff --git a/src/include/ranges/ranges.h b/src/include/ranges/ranges.h index 3aa6ea2..b9a799f 100644 --- a/src/include/ranges/ranges.h +++ b/src/include/ranges/ranges.h @@ -1,7 +1,7 @@ #include "range_base.h" #include "index_base.h" -//#include "mrange.h" +#include "mrange.h" //#include "range_helper.h" #include "crange.h" //#include "subrange.h" diff --git a/src/include/ranges/urange.cc.h b/src/include/ranges/urange.cc.h index 1d1c46c..91e3926 100644 --- a/src/include/ranges/urange.cc.h +++ b/src/include/ranges/urange.cc.h @@ -172,7 +172,7 @@ namespace CNORXZ template URange::URange(const Vector& space) : - RangeInterface,MetaType>(), + RangeInterface>(), mSpace(space) { std::sort(mSpace.begin(), mSpace.end(), std::less()); @@ -182,7 +182,7 @@ namespace CNORXZ template URange::URange(Vector&& space) : - RangeInterface,MetaType>(), + RangeInterface>(), mSpace(space) { std::sort(mSpace.begin(), mSpace.end(), std::less()); diff --git a/src/include/ranges/urange.h b/src/include/ranges/urange.h index 9543b94..35fb4da 100644 --- a/src/include/ranges/urange.h +++ b/src/include/ranges/urange.h @@ -11,13 +11,14 @@ namespace CNORXZ { - template - class UIndex : public IndexInterface,MetaType> + template + class UIndex : public IndexInterface,MetaT> { public: - typedef IndexInterface,MetaType> IB; - typedef URange RangeType; + typedef IndexInterface,MetaT> IB; + typedef URange RangeType; + typedef MetaT MetaType; UIndex(const RangePtr& range, SizeT pos = 0); @@ -32,7 +33,7 @@ namespace CNORXZ SizeT max() const; IndexId<0> id() const; - const MetaType& operator*() const; + const MetaT& operator*() const; SizeT dim() const; // = 1 Sptr range() const; @@ -41,15 +42,15 @@ namespace CNORXZ UPos stepSize(const IndexId& id) const; String stringMeta() const; - const MetaType& meta() const; - UIndex& at(const MetaType& metaPos); + const MetaT& meta() const; + UIndex& at(const MetaT& metaPos); template decltype(auto) ifor(const Xpr& xpr, F&& f) const; private: Sptr mRangePtr; - const MetaType* mMetaPtr; + const MetaT* mMetaPtr; }; template @@ -70,7 +71,7 @@ namespace CNORXZ }; template - class URange : public RangeInterface,MetaType> + class URange : public RangeInterface> { public: typedef RangeBase RB; diff --git a/src/include/ranges/yrange.h b/src/include/ranges/yrange.h index c078900..94097fb 100644 --- a/src/include/ranges/yrange.h +++ b/src/include/ranges/yrange.h @@ -19,6 +19,7 @@ namespace CNORXZ public: typedef IndexInterface IB; typedef YRange RangeType; + typedef DType MetaType; DEFAULT_MEMBERS(YIndex); YIndex(const RangePtr& range, SizeT pos = 0); @@ -73,7 +74,7 @@ namespace CNORXZ RangePtr mRef; }; - class YRange : public RangeInterface + class YRange : public RangeInterface { public: typedef RangeBase RB; diff --git a/src/lib/ranges/range_base.cc b/src/lib/ranges/range_base.cc index 0084b96..b64d7b1 100644 --- a/src/lib/ranges/range_base.cc +++ b/src/lib/ranges/range_base.cc @@ -39,7 +39,7 @@ namespace CNORXZ * RangeBase * ******************/ - RangePtr RangeBase::sub() const + RangePtr RangeBase::sub(SizeT num) const { return nullptr; } @@ -77,4 +77,14 @@ namespace CNORXZ RangeBase::RangeBase(const RangePtr& rel) : mRel(rel) {} + /**************************** + * Non-member functions * + ****************************/ + + RangePtr operator*(const RangePtr& a, const RangePtr& b) + { + assert(0); // check segfault + "flatten" yrange (no yrange of yranges etc) + return YRangeFactory({a,b}).create(); + } + } // end namespace CNORXZ diff --git a/src/tests/range_unit_test.cc b/src/tests/range_unit_test.cc index 44667f1..2fb7369 100644 --- a/src/tests/range_unit_test.cc +++ b/src/tests/range_unit_test.cc @@ -37,6 +37,21 @@ namespace Vector mMeta; }; + + class MR_Test : public ::testing::Test + { + protected: + + MR_Test() + { + mMeta = { "test", "strings", "foo" }; + std::sort(mMeta.begin(), mMeta.end(), std::less()); + mSize = 7; + } + + Vector mMeta; + SizeT mSize; + }; TEST_F(CR_Test, Basics) { @@ -103,6 +118,22 @@ namespace EXPECT_EQ(x, mMeta[cnt2++]); } } + + TEST_F(MR_Test, Basics) + { + auto cr = CRangeFactory(mSize).create(); + auto crx = std::dynamic_pointer_cast(cr); + auto ur = URangeFactory(mMeta).create(); + auto urx = std::dynamic_pointer_cast>(ur); + auto mr = mrange(crx,urx); + auto mrx = std::dynamic_pointer_cast>>(mr); + + EXPECT_EQ(mr->size(), mMeta.size()*mSize); + EXPECT_EQ(mrx->size(), mMeta.size()*mSize); + EXPECT_EQ(mrx->dim(), 2u); + + // further tests!!! + } // UR_Test // RCast_Test