From b86ea957ba7db4d468b1fa3c6856ece72d2a4769 Mon Sep 17 00:00:00 2001 From: Christian Zimmermann Date: Wed, 28 Dec 2022 21:21:11 +0100 Subject: [PATCH] index format + slice --- src/include/array/array_base.cc.h | 2 +- src/include/base/iter.cc.h | 27 ++++++++++++++ src/include/base/iter.h | 6 +++ src/include/ranges/dindex.h | 8 +++- src/include/ranges/mrange.cc.h | 62 +++++++++++++++++++++++++------ src/include/ranges/mrange.h | 4 +- src/include/ranges/urange.cc.h | 19 ++++++++++ src/include/ranges/urange.h | 6 +++ src/include/ranges/xindex.cc.h | 28 ++++++++++++-- src/include/ranges/xindex.h | 17 +++++++-- src/include/ranges/yrange.h | 4 ++ src/lib/ranges/dindex.cc | 10 +++++ src/lib/ranges/yrange.cc | 12 ++++++ 13 files changed, 185 insertions(+), 20 deletions(-) diff --git a/src/include/array/array_base.cc.h b/src/include/array/array_base.cc.h index 31021d1..ca1f4f9 100644 --- a/src/include/array/array_base.cc.h +++ b/src/include/array/array_base.cc.h @@ -118,7 +118,7 @@ namespace CNORXZ if(npack.size() == 0){ return nullptr; } - return mkXIndex(yindexPtr(npack)); + return xindexPtr(yindexPtr(npack)); } /****************** diff --git a/src/include/base/iter.cc.h b/src/include/base/iter.cc.h index 73c97b7..2798132 100644 --- a/src/include/base/iter.cc.h +++ b/src/include/base/iter.cc.h @@ -23,6 +23,33 @@ namespace CNORXZ { return iteri(g, f, Isqr{}); } + + template + constexpr decltype(auto) iterIfi(const G& g, const F& f, const C& c, const Args&... args) + { + if constexpr(I >= E){ + if constexpr(std::is_same::value){ + return; + } + else { + return f(args...); + } + } + else { + if constexpr(c(std::integral_constant{})){ + return iterIfi(g, f, c, args..., g(std::integral_constant{})); + } + else { + return iterIfi(g, f, c, args...); + } + } + } + + template + constexpr decltype(auto) iterIf(const G& g, const F& f, const C& c) + { + return iterIfi(g, f, c); + } } #endif diff --git a/src/include/base/iter.h b/src/include/base/iter.h index abc088e..5ed55dd 100644 --- a/src/include/base/iter.h +++ b/src/include/base/iter.h @@ -12,6 +12,12 @@ namespace CNORXZ template constexpr decltype(auto) iter(const G& g, const F& f); + + template + constexpr decltype(auto) iterIfi(const G& g, const F& f, const C& c, const Args&... args); + + template + constexpr decltype(auto) iterIf(const G& g, const F& f, const C& c); } #endif diff --git a/src/include/ranges/dindex.h b/src/include/ranges/dindex.h index 2681337..f2827e8 100644 --- a/src/include/ranges/dindex.h +++ b/src/include/ranges/dindex.h @@ -54,6 +54,9 @@ namespace CNORXZ DType meta() const; DIndex& at(const DType& meta); + Sptr format(const Sptr& ind) const; + Sptr slice(const Sptr& ind) const; + DXpr ifor(const DXpr& xpr, std::function&& f) const; const XIndexPtr& xptr() const; @@ -61,7 +64,10 @@ namespace CNORXZ private: XIndexPtr mI; }; - + + template <> + struct has_sub + { static constexpr bool value = true; }; } #endif diff --git a/src/include/ranges/mrange.cc.h b/src/include/ranges/mrange.cc.h index 6538b31..3534477 100644 --- a/src/include/ranges/mrange.cc.h +++ b/src/include/ranges/mrange.cc.h @@ -414,29 +414,24 @@ namespace CNORXZ static_assert(has_sub::value, "try to format single index"); if constexpr(has_static_sub::value){ static_assert(index_dim::value == NI, "got index with conflicting static dimension"); - typedef std::remove_referenceblockSizes())>::type BT; return iter<0,NI> ( [&](auto i) { - std::get(mIPack)->format(std::get(ind->pack())); + return std::get(mIPack)->format(std::get(ind->pack())); }, - [](const auto&... e) { - return std::make_shared> - (mBlockSizes, e... ); + [&](const auto&... e) { + return gmindexPtr(mBlockSizes, e... ); } ); } else { - typedef Arr BT; auto pack = ind->pack(); CXZ_ASSERT(pack.size() == NI, "attempt to format index of dimension " << NI - << " using index of dimension " << bs.size()); - auto bs = ind->blockSizes(); + << " using index of dimension " << pack.size()); return iter<0,NI> ( [&](auto i) { return std::get(mIPack)->format(pack[i]); }, - [](const auto&... e) { - return std::make_shared> - (mBlockSizes, e... ); + [&](const auto&... e) { + return gmindexPtr(mBlockSizes, e... ); } ); } } @@ -446,6 +441,46 @@ namespace CNORXZ decltype(auto) GMIndex::slice(const Sptr& ind) const { static_assert(is_index::value, "got non-index type"); + static_assert(has_sub::value, "try to slice single index"); + if constexpr(has_static_sub::value and + ((has_static_sub::value and ...) or + (not has_sub::value and ...)) ){ + static_assert(index_dim::value == NI, "got index with conflicting static dimension"); + const auto bs = iterIf<0,NI> + ( [&](auto i) { return std::get(mBlockSizes); }, + [](const auto&... e) { std::make_tuple(e...); }, + [](auto i) { + return std::is_same::type,NIndex>::value; + }); + return iterIf<0,NI> + ( [&](auto i) { return std::get(mIPack)->slice(std::get(ind->pack())); }, + [&](const auto&... e) { return gmindex(bs, e... ); }, + [](auto i) { + return std::is_same::type,NIndex>::value; + } ); + } + else { + Vector bs; + Vector ivec; + bs.reserve(NI); + ivec.reserve(NI); + auto pack = ind->pack(); + CXZ_ASSERT(pack.size() == NI, "attempt to slice index of dimension " << NI + << " using index of dimension " << pack.size()); + iter<0,NI> + ( [&](auto i) { + if(std::get(mIPack)->dim() == 0){ + bs.push_back(std::get(mBlockSizes).val()); + if constexpr(has_static_sub::value){ + ivec.push_back( xindexPtr( std::get(ind->pack()) ) ); + } + else { + ivec.push_back( xindexPtr( ind->pack()[i] ) ); + } + } + }, NoF {}); + return yindexPtr(bs, ivec); + } } template @@ -523,6 +558,11 @@ namespace CNORXZ return MIndex(is...); } + template + constexpr decltype(auto) gmindexPtr(const BlockType& bs, const Sptr&... is) + { + return std::make_shared>(bs, is...); + } /********************* * MRangeFactory * diff --git a/src/include/ranges/mrange.h b/src/include/ranges/mrange.h index 835aac4..a54cd9b 100644 --- a/src/include/ranges/mrange.h +++ b/src/include/ranges/mrange.h @@ -72,7 +72,7 @@ namespace CNORXZ template decltype(auto) slice(const Sptr& ind) const; // -> IndexInterface; - // drop index instance or drop blockSize if that if ind is Null + // drop index instance or drop blockSize of ind if that of *this is not Null // return result as new instance template @@ -152,6 +152,8 @@ namespace CNORXZ template constexpr decltype(auto) mindex(const Sptr&... is); + template + constexpr decltype(auto) gmindexPtr(const BlockType& bs, const Sptr&... is); template class MRangeFactory : public RangeFactoryBase diff --git a/src/include/ranges/urange.cc.h b/src/include/ranges/urange.cc.h index c0923b1..4964586 100644 --- a/src/include/ranges/urange.cc.h +++ b/src/include/ranges/urange.cc.h @@ -136,6 +136,25 @@ namespace CNORXZ { return UPos(id == this->id() ? 1 : 0); } + + template + template + decltype(auto) UIndex::format(const Sptr& ind) const + { + return ind; + } + + template + template + decltype(auto) UIndex::slice(const Sptr& ind) const + { + if(ind != nullptr){ + if(ind->dim() != 0) { + return Sptr(); + } + } + return std::make_shared(*this); + } template template diff --git a/src/include/ranges/urange.h b/src/include/ranges/urange.h index 5ee64fc..b6493e1 100644 --- a/src/include/ranges/urange.h +++ b/src/include/ranges/urange.h @@ -47,6 +47,12 @@ namespace CNORXZ const MetaT& meta() const; UIndex& at(const MetaT& metaPos); + template + decltype(auto) format(const Sptr& ind) const; + + template + decltype(auto) slice(const Sptr& ind) const; + template decltype(auto) ifor(const Xpr& xpr, F&& f) const; diff --git a/src/include/ranges/xindex.cc.h b/src/include/ranges/xindex.cc.h index a3b6c24..bc277a2 100644 --- a/src/include/ranges/xindex.cc.h +++ b/src/include/ranges/xindex.cc.h @@ -133,7 +133,7 @@ namespace CNORXZ if constexpr(has_static_sub::value){ constexpr SizeT D = index_dim::value; return iter<0,D> - ( [&](auto i) { return mkXIndex(std::get(mI->THIS().pack())); }, + ( [&](auto i) { return xindexPtr(std::get(mI->THIS().pack())); }, [](const auto&... e) { return Vector({ e ... }); } ); } else if constexpr(has_sub::value){ @@ -177,7 +177,7 @@ namespace CNORXZ return nullptr; } else { - return mkXIndex(replaceBlockSizes(arr, std::static_pointer_cast(mI))); + return xindexPtr(replaceBlockSizes(arr, std::static_pointer_cast(mI))); } } else if constexpr(has_sub::value) { @@ -209,6 +209,22 @@ namespace CNORXZ return *this; } + template + Sptr XIndex::format(const Sptr& ind) const + { + CXZ_ERROR("IMPLEMENT!!!"); + return nullptr; + //return std::make_shared(xindexPtr(mI->format(ind))); + } + + template + Sptr XIndex::slice(const Sptr& ind) const + { + CXZ_ERROR("IMPLEMENT!!!"); + return nullptr; + //return std::make_shared(xindexPtr(mI->slice(ind))); + } + template DXpr XIndex::ifor(const DXpr& xpr, std::function&& f) const @@ -217,12 +233,18 @@ namespace CNORXZ } template - XIndexPtr mkXIndex(const Sptr& i) + inline XIndexPtr xindexPtr(const Sptr& i) { typedef typename Index::MetaType Meta; return std::make_shared> (std::dynamic_pointer_cast>(i)); } + + template <> + inline XIndexPtr xindexPtr(const Sptr& i) + { + return i; + } } #endif diff --git a/src/include/ranges/xindex.h b/src/include/ranges/xindex.h index 4da6a42..df4c604 100644 --- a/src/include/ranges/xindex.h +++ b/src/include/ranges/xindex.h @@ -9,10 +9,12 @@ namespace CNORXZ { - // Future IndexWrapper class XIndexBase { public: + + //typedef DType MetaType; + DEFAULT_MEMBERS(XIndexBase); virtual ~XIndexBase() = default; virtual XIndexPtr copy() const = 0; @@ -44,6 +46,9 @@ namespace CNORXZ virtual DType meta() const = 0; virtual XIndexBase& at(const DType& meta) = 0; + virtual Sptr format(const Sptr& ind) const = 0; + virtual Sptr slice(const Sptr& ind) const = 0; + virtual DXpr ifor(const DXpr& xpr, std::function&& f) const = 0; @@ -96,6 +101,9 @@ namespace CNORXZ virtual DType meta() const override final; virtual XIndexBase& at(const DType& meta) override final; + virtual Sptr format(const Sptr& ind) const override final; + virtual Sptr slice(const Sptr& ind) const override final; + virtual DXpr ifor(const DXpr& xpr, std::function&& f) const override final; @@ -109,8 +117,11 @@ namespace CNORXZ { static constexpr bool value = true; }; template - XIndexPtr mkXIndex(const Sptr& i); - + inline XIndexPtr xindexPtr(const Sptr& i); + + template <> + inline XIndexPtr xindexPtr(const Sptr& i); + } #endif diff --git a/src/include/ranges/yrange.h b/src/include/ranges/yrange.h index b88027a..49a2b1a 100644 --- a/src/include/ranges/yrange.h +++ b/src/include/ranges/yrange.h @@ -52,6 +52,9 @@ namespace CNORXZ DType meta() const; YIndex& at(const DType& meta); + Sptr format(const Sptr& ind) const; + Sptr slice(const Sptr& ind) const; + DXpr ifor(const DXpr& xpr, std::function&& f) const; YIndex& operator()(const Sptr& i); @@ -87,6 +90,7 @@ namespace CNORXZ YIndex yindex(const Vector& is); Sptr yindexPtr(const Vector& is); + Sptr yindexPtr(const Vector& bs, const Vector& is); class YRangeFactory : public RangeFactoryBase { diff --git a/src/lib/ranges/dindex.cc b/src/lib/ranges/dindex.cc index dda7a95..7fd74f2 100644 --- a/src/lib/ranges/dindex.cc +++ b/src/lib/ranges/dindex.cc @@ -162,6 +162,16 @@ namespace CNORXZ return *this; } + Sptr DIndex::format(const Sptr& ind) const + { + return mI->format(ind); + } + + Sptr DIndex::slice(const Sptr& ind) const + { + return mI->slice(ind); + } + DXpr DIndex::ifor(const DXpr& xpr, std::function&& f) const { return DXpr(mI->ifor(xpr, std::forward>(f)) ); diff --git a/src/lib/ranges/yrange.cc b/src/lib/ranges/yrange.cc index cc6ecbf..f9027a3 100644 --- a/src/lib/ranges/yrange.cc +++ b/src/lib/ranges/yrange.cc @@ -339,6 +339,18 @@ namespace CNORXZ return *this; } + Sptr YIndex::format(const Sptr& ind) const + { + CXZ_ERROR("IMPLEMENT!!!"); + return nullptr; + } + + Sptr YIndex::slice(const Sptr& ind) const + { + CXZ_ERROR("IMPLEMENT!!!"); + return nullptr; + } + DXpr YIndex::ifor(const DXpr& xpr, std::function&& f) const { return mkIFor(0, xpr, std::forward>(f));