diff --git a/src/include/array/array_base.cc.h b/src/include/array/array_base.cc.h index 0bab4b2..afb6c92 100644 --- a/src/include/array/array_base.cc.h +++ b/src/include/array/array_base.cc.h @@ -3,9 +3,124 @@ #define __cxz_array_base_cc_h__ #include "array_base.h" +#include "slice.h" namespace CNORXZ { + /****************************** + * CArrayBase (protected) * + ******************************/ + + template + template + YIndex CArrayBase::mkSliceIndex(const YIndex& yi, const Index& ind) const + { + // TODO: if ind.dim() < iy.dim: assume Null-Indices on missing positions; + static_assert(has_sub::value, "got non-mutliple index"); + CXZ_ASSERT(yi.dim() == ind.dim(), "got index of incompatible dimension = " + << ind.dim() << ", expected: " << yi.dim()); + Vector npack; + Vector nbs; + auto ypack = yi.pack(); + auto ipack = ind.pack(); + const auto& bs = yi.blockSizes(); + if constexpr(has_static_sub::value){ + constexpr SizeT ID = index_dim::value; + npack.reserve(ID); + nbs.reserve(ID); + iter<0,ID>( [&](auto i) { + const auto& ii1 = ypack[i]; + const auto& ii2 = std::get(ipack); + if(ii2->dim() != 0){ + npack.push_back( mkSliceIndex(ii1, ii2) ); + nbs.push_back(bs[i]); + } + }, NoF {} ); + } + else { + const SizeT idim = ind.dim(); + npack.reserve(idim); + nbs.reserve(idim); + for(SizeT i = 0; i != idim; ++i){ + const auto& ii1 = ypack[i]; + const auto& ii2 = ipack[i]; + if(ii2->dim() != 0){ + npack.push_back( mkSliceIndex(ii1, ii2) ); + nbs.push_back(bs[i]); + } + } + } + return yindex(npack); + } + + template + template + XIndexPtr CArrayBase::mkSliceIndex(const XIndexPtr& xi, const Sptr& ind) const + { + // TODO: if ind.dim() < iy.dim: assume Null-Indices on missing positions; + CXZ_ASSERT(xi->dim() == ind->dim(), "got index of incompatible dimension = " + << ind->dim() << ", expected: " << xi->dim()); + Vector npack; + Vector nbs; + auto xpack = xi->pack(); + const auto& bs = xi->blockSizes(); + if constexpr(has_static_sub::value){ + auto ipack = ind->pack(); + constexpr SizeT ID = index_dim::value; + npack.reserve(ID); + nbs.reserve(ID); + iter<0,ID>( [&](auto i) { + const auto& ii1 = xpack[i]; + const auto& ii2 = std::get(ipack); + const XIndexPtr si = mkSliceIndex(ii1, ii2); + if(si != nullptr){ + npack.push_back( si ); + nbs.push_back(bs[i]); + } + }, NoF {} ); + } + else if constexpr(has_static_sub::value){ + auto ipack = ind->pack(); + const SizeT idim = ind->dim(); + const SizeT xdim = xi->dim(); + const SizeT isize = ipack.size(); + const SizeT xsize = xpack.size(); + if(isize == 0 or xsize == 0){ + if(idim == 0){ + return xi->copy(); + } + else { + return nullptr; + } + } + CXZ_ASSERT(isize == idim and xsize == xdim, "index error"); + npack.reserve(idim); + nbs.reserve(idim); + for(SizeT i = 0; i != idim; ++i){ + const auto& ii1 = xpack[i]; + const auto& ii2 = ipack[i]; + const XIndexPtr si = mkSliceIndex(ii1, ii2); + if(si != nullptr){ + npack.push_back( si ); + nbs.push_back(bs[i]); + } + } + } + else { + const SizeT idim = ind->dim(); + if(idim == 0){ + return xi->copy(); + } + else { + return nullptr; + } + } + if(npack.size() == 0){ + return nullptr; + } + return mkXIndex(yindexPtr(npack)); + } + /****************** * CArrayBase * ******************/ @@ -39,13 +154,11 @@ namespace CNORXZ template Sptr> CArrayBase::sl(const IndexInterface& i) const { - ////auto r = mkSliceRange(i.range()); - //auto beg = this->begin(); - //assertCompatible(i,beg); - ////auto bs = mkSliceBlockSizes(i, beg); - //auto it = beg + i.lex(); - ////return std::make_shared(r, this, bs, it.pos()); - return std::make_shared(); + auto beg = this->begin(); + auto si = mkSliceIndex(beg, i); + auto it = beg + i.lex(); + return std::make_shared(this, si, it.pos()); + //return std::make_shared(); } template diff --git a/src/include/array/array_base.h b/src/include/array/array_base.h index c84af8a..9be12c4 100644 --- a/src/include/array/array_base.h +++ b/src/include/array/array_base.h @@ -21,6 +21,12 @@ namespace CNORXZ protected: RangePtr mRange; + + template + YIndex mkSliceIndex(const YIndex& yi, const Index& i) const; + + template + XIndexPtr mkSliceIndex(const XIndexPtr& xi, const Sptr& i) const; public: @@ -92,34 +98,6 @@ namespace CNORXZ }; - // to extra header file !!!: - template - constexpr decltype(auto) flattenIndexPack(const Tuple...>& ipack) - { - constexpr SizeT D = sizeof...(Indices); - - } - - inline Vector flattenIndexPack(const Vector& ipack) - { - - } - - template - inline SizeT indexPackDim(Tuple...> ipack) - { - constexpr SizeT D = sizeof...(Indices); - return iter<0,D>([&](const auto& i) { return std::get(ipack)->dim(); }, - [](const auto&... e) { return (e + ...); }); - } - - inline SizeT indexPackDim(const Vector& ipack) - { - return std::accumulate(ipack.begin(), ipack.end(), ipack[0]->dim(), - [](auto a, auto b) { return a->dim() + b->dim(); }); - } - - } #endif diff --git a/src/include/ranges/index_base.h b/src/include/ranges/index_base.h index ddea450..c00959f 100644 --- a/src/include/ranges/index_base.h +++ b/src/include/ranges/index_base.h @@ -86,7 +86,15 @@ namespace CNORXZ template struct index_dim { static constexpr SizeT value = 1; }; - + + template + struct has_sub + { static constexpr bool value = false; }; + + template + struct has_static_sub + { static constexpr bool value = false; }; + template IndexPtr& operator++(const IndexPtr& i); diff --git a/src/include/ranges/index_utils.cc.h b/src/include/ranges/index_utils.cc.h index 66f0569..c5c1967 100644 --- a/src/include/ranges/index_utils.cc.h +++ b/src/include/ranges/index_utils.cc.h @@ -6,71 +6,6 @@ namespace CNORZX { - inline decltype(auto) getPack(const XIndexPtr& i) - { - typedef Vector OutT; - OutT p = i.pack(); - while(p.size() == 1u){ - p = p[0]->pack(); - } - return p; - } - - // -> base - template - Vector mkVector(const T&... t) { return Vector({t...}); } - - template - inline decltype(auto) indexZip(const XIndexPtr& a, const XIndexPtr& b, F&& f) - { - const auto ap = getPack(a); - const auto bp = getPack(b); - if(ap.size() == 1u or bp.size() == 1u){ - return mkVector( f(a, b) ); - } - else { - return indexPackZip(ap, bp, std::forward(f)); - } - } - - template - inline decltype(auto) indexPackZip(const Vector& a, const Vector& b, F&& f) - { - if(a.size() > b.size()) { - Vector bn; - for(const auto& x: b){ - auto p = getPack(x); - if(p.size() == 0){ - bn.push_back(x); - } - else { - bn.insert(bn.end(), p.begin(), p.end()); - } - } - return indexPackZip(a, bn, std::forward(f)); - } - else if(a.size() < b.size()) { - Vector an; - for(const auto& x: a){ - auto p = getPack(x); - if(p.size() == 0){ - an.push_back(x); - } - else { - an.insert(bn.end(), p.begin(), p.end()); - } - } - return indexPackZip(an, b, std::forward(f)); - } - else { - typedef decltype(indexZip(a[0], b[0], std::forward(f))) OutT; - OutT o(a.size()); - std::transform(o.begin(), o.end(), a.begin(), b.begin(), - [](const auto& ax, const auto& bx) { F fc = f; return indexZip(ax, bx, std::move(fc)); }); - return o; - } - } - template constexpr decltype(auto) getIndexDepth(const Index& ind) { diff --git a/src/include/ranges/index_utils.h b/src/include/ranges/index_utils.h index cafaa2f..4c2ab55 100644 --- a/src/include/ranges/index_utils.h +++ b/src/include/ranges/index_utils.h @@ -6,19 +6,13 @@ namespace CNORZX { - inline decltype(auto) getPack(const XIndexPtr& i); - - template - inline decltype(auto) indexZip(const XIndexPtr& a, const XIndexPtr& b, F&& f); - - template - inline decltype(auto) indexPackZip(const Vector& a, const Vector& b, F&& f); - template constexpr decltype(auto) getIndexDepth(const Index& ind); template constexpr decltype(auto) getDimension(const Index& ind, IntT depth); + + } #endif diff --git a/src/include/ranges/mrange.cc.h b/src/include/ranges/mrange.cc.h index 333e533..0f3c9b7 100644 --- a/src/include/ranges/mrange.cc.h +++ b/src/include/ranges/mrange.cc.h @@ -434,50 +434,6 @@ namespace CNORXZ return mIPack; } - template - template - constexpr decltype(auto) GMIndex::zip(const Index& ind, const F& f, const G& g) const - { - static_assert(is_index::value, "got non-index type"); - if constexpr(has_static_sub::value){ - static_assert(index_dim::value == NI, - "got static-dimensional index with wrong dimension"); - if constexpr(std::is_same::value or std::is_same::value){ - iter<0,NI>( [&](auto i) { return std::get(mIPack)->zip(*std::get(ind.pack()), f); }, - NoF {} ); - f(*this, ind); - return; - } - else { - return iter<0,NI>( [&](auto i) { return std::get(mIPack)->zip(*std::get(ind.pack()), f); }, - [](auto... e) { return g(std::make_tuple(e...), f(*this, ind)); } ); - } - } - else if constexpr(has_sub::value){ - CXZ_ASSERT(ind.dim() == NI, "got index with wrong dimension = " << ind.dim() - << ", expected: " << NI); - if constexpr(std::is_same::value or std::is_same::value){ - iter<0,NI>( [&](auto i) { return std::get(mIPack)->zip(*ind.pack()[i],f); }, - NoF {} ); - f(*this, ind); - return; - } - else { - return iter<0,NI>( [&](auto i) { return std::get(mIPack)->zip(*ind.pack()[i],f); }, - [](auto... e) { return g(std::make_tuple(e...), f(*this, ind)); } ); - } - } - else { - if constexpr(std::is_same::value){ - f(*this, ind); - return; - } - else { - return f(*this, ind); - } - } - } - template const auto& GMIndex::blockSizes() const { @@ -496,7 +452,7 @@ namespace CNORXZ } template - GMIndex& GMIndex::setBlockSizes(const BlockType& bs) + GMIndex& GMIndex::setBlockSizes(const BlockType& bs) { if constexpr(not std::is_same::value){ mBlockSizes = bs; @@ -505,10 +461,20 @@ namespace CNORXZ } template - decltype(auto) replaceBlockSize(const BT1& bs1, const Sptr>& gmi) + decltype(auto) replaceBlockSizes(const BT1& bs1, const Sptr>& gmi) { return iter<0,sizeof...(Indices)> - ( [&](auto i) { return std::get(gmi.pack()); }, + ( [&](auto i) { return std::get(gmi->pack()); }, + [&](const auto&... e) { return std::make_shared> + ( bs1, e... ); } ); + } + + template + decltype(auto) replaceBlockSizes(const BT1& bs1, + const Sptr,typename GMIndex::MetaType>>& gmi) + { + return iter<0,sizeof...(Indices)> + ( [&](auto i) { return std::get(gmi->THIS().pack()); }, [&](const auto&... e) { return std::make_shared> ( bs1, e... ); } ); } diff --git a/src/include/ranges/mrange.h b/src/include/ranges/mrange.h index b89f5e9..1df0ce2 100644 --- a/src/include/ranges/mrange.h +++ b/src/include/ranges/mrange.h @@ -70,9 +70,6 @@ namespace CNORXZ GMIndex& operator()(const Sptr>& mi); GMIndex& operator()(); - template - constexpr decltype(auto) zip(const Index& ind, const F& f, const G& g) const; // also non-const version !!! - const IndexPack& pack() const; const auto& blockSizes() const; const auto& lexBlockSizes() const; @@ -113,7 +110,11 @@ namespace CNORXZ }; template - decltype(auto) replaceBlockSize(const BT1& bs1, const Sptr>& gmi); + decltype(auto) replaceBlockSizes(const BT1& bs1, const Sptr>& gmi); + + template + decltype(auto) replaceBlockSizes(const BT1& bs1, + const Sptr,typename GMIndex::MetaType>>& gmi); template decltype(auto) operator*(const Sptr>& a, const Sptr>& b); @@ -132,6 +133,14 @@ namespace CNORXZ struct index_dim> { static constexpr SizeT value = sizeof...(Indices); }; + template + struct has_sub> + { static constexpr bool value = true; }; + + template + struct has_static_sub> + { static constexpr bool value = true; }; + template constexpr decltype(auto) mindex(const Sptr&... is); diff --git a/src/include/ranges/xindex.cc.h b/src/include/ranges/xindex.cc.h index f4dc5a5..56a48f8 100644 --- a/src/include/ranges/xindex.cc.h +++ b/src/include/ranges/xindex.cc.h @@ -133,14 +133,14 @@ 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->pack())); }, - [](const auto&... e) { return { e ... }; } ); + ( [&](auto i) { return mkXIndex(std::get(mI->THIS().pack())); }, + [](const auto&... e) { return Vector({ e ... }); } ); } else if constexpr(has_sub::value){ - return mI->pack(); + return mI->THIS().pack(); } else { - return {}; + return Vector(); } } @@ -149,15 +149,16 @@ namespace CNORXZ { if constexpr(has_static_sub::value){ constexpr SizeT D = index_dim::value; + const auto& bs = mI->THIS().blockSizes(); return iter<0,D> - ( [&](auto i) { return std::get(mI->blockSizes()); }, - [](const auto&... e) { return Vector( { e... } ); } ); + ( [&](auto i) { return std::get(bs); }, + [](const auto&... e) { return Vector( { static_cast(e)... } ); } ); } else if constexpr(has_sub::value) { - return mI->blockSizes(); + return mI->THIS().blockSizes(); } else { - return {}; + return Vector(); } } @@ -168,19 +169,19 @@ namespace CNORXZ constexpr SizeT D = index_dim::value; CXZ_ASSERT(bs.size() == D, "got block sizes of wrong dimension: " << bs.size() << " vs " << D); - typedef decltype(mI->blockSizes()) BT; - Arr arr; + typedef decltype(mI->THIS().blockSizes()) BT; + Arr arr; std::copy_n(bs.begin(), D, arr.begin()); - if constexpr(std::is_same>::value){ - mI->setBlockSizes(arr); + if constexpr(std::is_same>::value){ + mI->THIS().setBlockSizes(arr); return nullptr; } else { - return replaceBlockSizes(arr, mI); + return mkXIndex(replaceBlockSizes(arr, mI)); } } else if constexpr(has_sub::value) { - mI->setBlockSizes(bs); + mI->THIS().setBlockSizes(bs); return nullptr; } else { diff --git a/src/include/ranges/xindex.h b/src/include/ranges/xindex.h index 987d675..4da6a42 100644 --- a/src/include/ranges/xindex.h +++ b/src/include/ranges/xindex.h @@ -46,6 +46,7 @@ namespace CNORXZ virtual DXpr ifor(const DXpr& xpr, std::function&& f) const = 0; + }; //Sptr& operator++(Sptr& i); @@ -103,6 +104,10 @@ namespace CNORXZ }; + template <> + struct has_sub + { static constexpr bool value = true; }; + template XIndexPtr mkXIndex(const Sptr& i); diff --git a/src/include/ranges/yrange.h b/src/include/ranges/yrange.h index a9b96da..b88027a 100644 --- a/src/include/ranges/yrange.h +++ b/src/include/ranges/yrange.h @@ -85,6 +85,9 @@ namespace CNORXZ UPos mLMax = 0; }; + YIndex yindex(const Vector& is); + Sptr yindexPtr(const Vector& is); + class YRangeFactory : public RangeFactoryBase { public: diff --git a/src/include/xpr/pos_type.cc.h b/src/include/xpr/pos_type.cc.h index 40dffa5..8adf78a 100644 --- a/src/include/xpr/pos_type.cc.h +++ b/src/include/xpr/pos_type.cc.h @@ -111,6 +111,12 @@ namespace CNORXZ return UPos(mExt + in.val()); } + template + constexpr UPos UPos::operator-(const PosT& in) const + { + return UPos(mExt - in.val()); + } + constexpr SPos<0> UPos::operator*(const SPos<0>& a) const { return SPos<0>(); diff --git a/src/include/xpr/pos_type.h b/src/include/xpr/pos_type.h index cac728f..b7eaa68 100644 --- a/src/include/xpr/pos_type.h +++ b/src/include/xpr/pos_type.h @@ -54,6 +54,9 @@ namespace CNORXZ template constexpr UPos operator+(const PosT& a) const; + template + constexpr UPos operator-(const PosT& a) const; + constexpr SPos<0> operator*(const SPos<0>& a) const; template diff --git a/src/lib/ranges/yrange.cc b/src/lib/ranges/yrange.cc index dfc97e2..cc6ecbf 100644 --- a/src/lib/ranges/yrange.cc +++ b/src/lib/ranges/yrange.cc @@ -378,7 +378,20 @@ namespace CNORXZ return *this; } - + /**************************** + * non-member functions * + ****************************/ + + YIndex yindex(const Vector& is) + { + return YIndex(is); + } + + Sptr yindexPtr(const Vector& is) + { + return std::make_shared(is); + } + /********************** * YRangeFactory * **********************/