diff --git a/src/include/array/array_base.cc.h b/src/include/array/array_base.cc.h index da94e41..ae1218f 100644 --- a/src/include/array/array_base.cc.h +++ b/src/include/array/array_base.cc.h @@ -130,10 +130,20 @@ namespace CNORXZ } else { if(i->formatIsTrivial()){ - // try to apply container format - auto aformat = begin().deepFormat(); - CXZ_ERROR("IMPLEMENT " << toString(aformat)); - return coproot(*this, i); + // try to apply container format. + // if the reformat changes the index type in any manner + // the format is not applicable: + if constexpr(std::is_samereformat( Vector(), Vector() )),Index>::value){ + auto beg = begin(); + auto aformat = beg.deepFormat(); + auto amax = beg.deepMax(); + auto fi = i->reformat( aformat, amax ); + return coproot(*this, moveToPtr( fi ) ); + } + else { + this->checkFormatCompatibility(*i); + return coproot(*this, i); + } } else { // check if format is compatible @@ -313,10 +323,20 @@ namespace CNORXZ } else { if(i->formatIsTrivial()){ - // try to apply container format - auto aformat = begin().deepFormat(); - CXZ_ERROR("IMPLEMENT " << toString(aformat)); - return oproot(*this, i); + // try to apply container format. + // if the reformat changes the index type in any manner + // the format is not applicable: + if constexpr(std::is_samereformat( Vector(), Vector() )),Index>::value){ + auto beg = begin(); + auto aformat = beg.deepFormat(); + auto amax = beg.deepMax(); + auto fi = i->reformat( aformat, amax ); + return oproot(*this, moveToPtr( fi ) ); + } + else { + this->checkFormatCompatibility(*i); + return oproot(*this, i); + } } else { // check if format is compatible diff --git a/src/include/ranges/crange.h b/src/include/ranges/crange.h index 8937d8c..707b796 100644 --- a/src/include/ranges/crange.h +++ b/src/include/ranges/crange.h @@ -107,6 +107,9 @@ namespace CNORXZ /** @copydoc IndexInterface::deepFormat() */ SizeT deepFormat() const; + /** @copydoc IndexInterface::deepMax() */ + SizeT deepMax() const; + /** @copydoc IndexInterface::reformat() */ CIndex reformat(const Vector& f, const Vector& s) const; diff --git a/src/include/ranges/dindex.h b/src/include/ranges/dindex.h index 340a8eb..d0402d1 100644 --- a/src/include/ranges/dindex.h +++ b/src/include/ranges/dindex.h @@ -64,6 +64,7 @@ namespace CNORXZ DIndex& at(const DType& meta); RangePtr prange(const DIndex& end) const; Vector deepFormat() const; + Vector deepMax() const; /** @copydoc IndexInterface::reformat() */ DIndex reformat(const Vector& f, const Vector& s) const; diff --git a/src/include/ranges/index_base.h b/src/include/ranges/index_base.h index 4b371f7..14e0c2e 100644 --- a/src/include/ranges/index_base.h +++ b/src/include/ranges/index_base.h @@ -173,9 +173,13 @@ namespace CNORXZ /** recursive index format */ decltype(auto) deepFormat() const { return THIS().deepFormat(); } - /** reformat index, return new index instance + /** max of all single-indices (recursive) */ + decltype(auto) deepMax() const { return THIS().deepMax(); } + + /** reformat index, create new index instance @param f new format @param s new sub-index sizes + @return new reformatted index instance */ decltype(auto) reformat(const Vector& f, const Vector& s) const { return THIS().reformat(f,s); } diff --git a/src/include/ranges/mrange.cc.h b/src/include/ranges/mrange.cc.h index 08e7021..457cec1 100644 --- a/src/include/ranges/mrange.cc.h +++ b/src/include/ranges/mrange.cc.h @@ -462,7 +462,7 @@ namespace CNORXZ return false; } const bool ret2 = iter<0,NI-1> - ( [&](auto j) { return mFormat[CSizeT{}].val() == mIPack[CSizeT{}].lmax().val() * mFormat[CSizeT{}].val(); }, + ( [&](auto j) { return mFormat[CSizeT{}].val() == mIPack[CSizeT{}]->lmax().val() * mFormat[CSizeT{}].val(); }, [](const auto&... x) { return (x and ...); }); if(ret2 and mFormat[CSizeT{}].val() == 1){ return true; @@ -512,7 +512,7 @@ namespace CNORXZ } template - RangePtr GMIndex::prange(const MIndex& last) const + RangePtr GMIndex::prange(const GMIndex& last) const { return iter<0,NI> ( [&](auto i) { @@ -531,6 +531,13 @@ namespace CNORXZ [&](const auto&... e) { return concat(e...); } ); } + template + auto GMIndex::deepMax() const + { + return iter<0,NI>( [&](auto i) { return mIPack[i]->deepMax(); }, + [&](const auto&... e) { return concat(e...); } ); + } + template decltype(auto) GMIndex::reformat(const Vector& f, const Vector& s) const @@ -563,7 +570,7 @@ namespace CNORXZ { CXZ_ASSERT(x % nformat[i].val() == 0, "incompatible"); x /= nformat[i].val(); } ); std::copy(s.begin()+j0,s.begin()+j,ns.begin()); return moveToPtr( mIPack[i]->reformat(nf,ns) ); - }, [](auto&... e) { return std::make_tuple( e... ); } ); + }, [](const auto&... e) { return std::make_tuple( e... ); } ); GMIndex,Indices...> oi { MFormat(nformat),SPack(npack) }; oi = lex(); return oi; diff --git a/src/include/ranges/mrange.h b/src/include/ranges/mrange.h index ccdc64e..4e960c2 100644 --- a/src/include/ranges/mrange.h +++ b/src/include/ranges/mrange.h @@ -89,8 +89,9 @@ namespace CNORXZ const SPack& pack() const; const auto& format() const; const auto& lexFormat() const; - RangePtr prange(const MIndex& last) const; + RangePtr prange(const GMIndex& last) const; auto deepFormat() const; + auto deepMax() const; /** @copydoc IndexInterface::reformat() */ decltype(auto) reformat(const Vector& f, const Vector& s) const; @@ -248,6 +249,7 @@ namespace CNORXZ { static constexpr bool value = (index_expression_exists::value and ...); }; + } #endif diff --git a/src/include/ranges/prange.cc.h b/src/include/ranges/prange.cc.h index b4128e4..b5d82c9 100644 --- a/src/include/ranges/prange.cc.h +++ b/src/include/ranges/prange.cc.h @@ -167,6 +167,12 @@ namespace CNORXZ return mOrig->deepFormat(); } + template + decltype(auto) PIndex::deepMax() const + { + return mOrig->deepMax(); + } + template PIndex PIndex::reformat(const Vector& f, const Vector& s) const { diff --git a/src/include/ranges/prange.h b/src/include/ranges/prange.h index 729ded2..1f25453 100644 --- a/src/include/ranges/prange.h +++ b/src/include/ranges/prange.h @@ -55,6 +55,7 @@ namespace CNORXZ UPos stepSize(const IndexId& id) const; RangePtr prange(const PIndex& last) const; decltype(auto) deepFormat() const; + decltype(auto) deepMax() const; /** @copydoc IndexInterface::reformat() */ PIndex reformat(const Vector& f, const Vector& s) const; diff --git a/src/include/ranges/srange.cc.h b/src/include/ranges/srange.cc.h index c8add42..9c26769 100644 --- a/src/include/ranges/srange.cc.h +++ b/src/include/ranges/srange.cc.h @@ -177,6 +177,12 @@ namespace CNORXZ return 1; } + template + SizeT SIndex::deepMax() const + { + return lmax().val(); + } + template SIndex SIndex::reformat(const Vector& f, const Vector& s) const { diff --git a/src/include/ranges/srange.h b/src/include/ranges/srange.h index 3b8b560..34991f3 100644 --- a/src/include/ranges/srange.h +++ b/src/include/ranges/srange.h @@ -61,6 +61,7 @@ namespace CNORXZ RangePtr prange(const SIndex& last) const; SizeT deepFormat() const; + SizeT deepMax() const; /** @copydoc IndexInterface::reformat() */ SIndex reformat(const Vector& f, const Vector& s) const; diff --git a/src/include/ranges/urange.cc.h b/src/include/ranges/urange.cc.h index 9131ebd..68bea1c 100644 --- a/src/include/ranges/urange.cc.h +++ b/src/include/ranges/urange.cc.h @@ -163,14 +163,25 @@ namespace CNORXZ return 1; } + template + SizeT UIndex::deepMax() const + { + return lmax().val(); + } + template UIndex UIndex::reformat(const Vector& f, const Vector& s) const { + // can also get multi dim stuff, but: + // * overall extension must match + // * f must be trivial + /* CXZ_ASSERT(f.size() == 1, "expected format of dimension 1, got " << toString(f)); CXZ_ASSERT(s.size() == 1, "expected sizes of dimension 1, got " << toString(s)); CXZ_ASSERT(f[0] == 1, "trivial format ([1]), got " << toString(f)); CXZ_ASSERT(s[0] == lmax().val(), "expected size to be equal to index size (" << lmax().val() << "), got " << s[0]); + */ return *this; } diff --git a/src/include/ranges/urange.h b/src/include/ranges/urange.h index 534b2d9..9ddcbf4 100644 --- a/src/include/ranges/urange.h +++ b/src/include/ranges/urange.h @@ -67,6 +67,8 @@ namespace CNORXZ SizeT deepFormat() const; + SizeT deepMax() const; + /** @copydoc IndexInterface::reformat() */ UIndex reformat(const Vector& f, const Vector& s) const; diff --git a/src/include/ranges/xindex.cc.h b/src/include/ranges/xindex.cc.h index 5754c32..2f4537c 100644 --- a/src/include/ranges/xindex.cc.h +++ b/src/include/ranges/xindex.cc.h @@ -158,6 +158,12 @@ namespace CNORXZ return toVec( mI->deepFormat() ); } + template + Vector XIndex::deepMax() const + { + return toVec( mI->deepMax() ); + } + template XIndexPtr XIndex::reformat(const Vector& f, const Vector& s) const { diff --git a/src/include/ranges/xindex.h b/src/include/ranges/xindex.h index 4dce7bf..96b2ffe 100644 --- a/src/include/ranges/xindex.h +++ b/src/include/ranges/xindex.h @@ -52,6 +52,7 @@ namespace CNORXZ virtual UPos stepSize(const IndexId<0>& id) const = 0; virtual RangePtr prange(const XIndexPtr& last) const = 0; virtual Vector deepFormat() const = 0; + virtual Vector deepMax() const = 0; virtual XIndexPtr reformat(const Vector& f, const Vector& s) const = 0; virtual String stringMeta() const = 0; @@ -105,6 +106,7 @@ namespace CNORXZ virtual UPos stepSize(const IndexId<0>& id) const override final; virtual RangePtr prange(const XIndexPtr& last) const override final; virtual Vector deepFormat() const override final; + virtual Vector deepMax() const override final; virtual XIndexPtr reformat(const Vector& f, const Vector& s) const override final; virtual String stringMeta() const override final; diff --git a/src/include/ranges/yrange.h b/src/include/ranges/yrange.h index 547aa04..444b225 100644 --- a/src/include/ranges/yrange.h +++ b/src/include/ranges/yrange.h @@ -76,6 +76,7 @@ namespace CNORXZ const DPack& pack() const; RangePtr prange(const YIndex& last) const; Vector deepFormat() const; + Vector deepMax() const; const YFormat& format() const; const YFormat& lexFormat() const; YIndex& setFormat(const YFormat& bs); diff --git a/src/lib/ranges/crange.cc b/src/lib/ranges/crange.cc index 159c30f..b19dd2e 100644 --- a/src/lib/ranges/crange.cc +++ b/src/lib/ranges/crange.cc @@ -139,6 +139,11 @@ namespace CNORXZ return 1; } + SizeT CIndex::deepMax() const + { + return lmax().val(); + } + CIndex CIndex::reformat(const Vector& f, const Vector& s) const { CXZ_ASSERT(f.size() == 1, "expected format of dimension 1, got " << toString(f)); diff --git a/src/lib/ranges/dindex.cc b/src/lib/ranges/dindex.cc index 4c7e066..c1f7235 100644 --- a/src/lib/ranges/dindex.cc +++ b/src/lib/ranges/dindex.cc @@ -177,6 +177,11 @@ namespace CNORXZ return mI->deepFormat(); } + Vector DIndex::deepMax() const + { + return mI->deepMax(); + } + DIndex DIndex::reformat(const Vector& f, const Vector& s) const { return DIndex(mI->reformat(f,s)); diff --git a/src/lib/ranges/yrange.cc b/src/lib/ranges/yrange.cc index 41067a6..6a95961 100644 --- a/src/lib/ranges/yrange.cc +++ b/src/lib/ranges/yrange.cc @@ -395,6 +395,23 @@ namespace CNORXZ } return o; } + + Vector YIndex::deepMax() const + { + Vector> dmv(mIs.size()); + SizeT osize = 0; + for(SizeT j = 0; j != dmv.size(); ++j){ + dmv[j] = mIs[j]->deepMax(); + osize += dmv[j].size(); + } + Vector o(osize); + SizeT off = 0; + for(SizeT j = 0; j != dmv.size(); ++j){ + std::copy(dmv[j].begin(), dmv[j].end(), o.begin()+off); + off += dmv[j].size(); + } + return o; + } YIndex YIndex::reformat(const Vector& f, const Vector& s) const {