mrange: different members for blockSizes and lexBlockSizes

This commit is contained in:
Christian Zimmermann 2022-11-20 23:18:58 +01:00
parent 2745eee0ff
commit 2f5f29f577
18 changed files with 326 additions and 213 deletions

View file

@ -82,6 +82,9 @@ namespace CNORXZ
B = (mutable) Array B = (mutable) Array
F = Functional, Map,... F = Functional, Map,...
***/ ***/
// default template parameter
class None {};
// definition: base/dtype.h // definition: base/dtype.h
class DType; class DType;
@ -174,8 +177,8 @@ namespace CNORXZ
class MRange; // multi range class MRange; // multi range
// definition: ranges/mrange.h // definition: ranges/mrange.h
template <class... Indices> template <class BlockType, class... Indices>
class MIndex; class GMIndex;
// definition: ranges/xindex.h // definition: ranges/xindex.h
class XIndexBase; // dynamic index wrapper class XIndexBase; // dynamic index wrapper

View file

@ -9,7 +9,7 @@ namespace CNORXZ
template <class Xpr, class F> template <class Xpr, class F>
decltype(auto) CIndex::ifor(const Xpr& xpr, F&& f) const decltype(auto) CIndex::ifor(const Xpr& xpr, F&& f) const
{ {
return For<0,Xpr,F>(this->pmax(), this->id(), xpr, std::forward<F>(f)); return For<0,Xpr,F>(this->pmax().val(), this->id(), xpr, std::forward<F>(f));
} }
} }

View file

@ -28,8 +28,8 @@ namespace CNORXZ
CIndex& operator-=(Int n); CIndex& operator-=(Int n);
SizeT lex() const; SizeT lex() const;
SizeT pmax() const; UPos pmax() const;
SizeT lmax() const; UPos lmax() const;
IndexId<0> id() const; IndexId<0> id() const;
SizeT operator*() const; SizeT operator*() const;

View file

@ -33,8 +33,8 @@ namespace CNORXZ
DIndex& operator-=(Int n); DIndex& operator-=(Int n);
SizeT lex() const; SizeT lex() const;
SizeT pmax() const; UPos pmax() const;
SizeT lmax() const; UPos lmax() const;
IndexId<0> id() const; IndexId<0> id() const;
DType operator*() const; DType operator*() const;

View file

@ -30,8 +30,8 @@ namespace CNORXZ
SizeT pos() const; // 'memory' pos SizeT pos() const; // 'memory' pos
SizeT lex() const { return THIS().lex(); } // lexicographic pos SizeT lex() const { return THIS().lex(); } // lexicographic pos
SizeT pmax() const { return THIS().pmax(); } // memory pos max SizeT pmax() const { return static_cast<SizeT>(THIS().pmax()); } // memory pos max
SizeT lmax() const { return THIS().lmax(); } // lexicographic pos max SizeT lmax() const { return static_cast<SizeT>(THIS().lmax()); } // lexicographic pos max
PtrId ptrId() const; PtrId ptrId() const;
decltype(auto) id() const { return THIS().id(); } decltype(auto) id() const { return THIS().id(); }

View file

@ -6,13 +6,13 @@
namespace CNORXZ namespace CNORXZ
{ {
/*********************** /************************
* MIndex (private) * * GMIndex (private) *
***********************/ ************************/
template <class... Indices> template <class BlockType, class... Indices>
template <SizeT... Is> template <SizeT... Is>
constexpr decltype(auto) MIndex<Indices...>::mkIPack(Isq<Is...> is) const constexpr decltype(auto) GMIndex<BlockType,Indices...>::mkIPack(Isq<Is...> is) const
{ {
static_assert(sizeof...(Is) == NI, static_assert(sizeof...(Is) == NI,
"sequence sioze does not match number of indices"); "sequence sioze does not match number of indices");
@ -20,56 +20,88 @@ namespace CNORXZ
"subranges not available" ); "subranges not available" );
return std::make_tuple( std::make_shared<Indices>( mRange->sub(Is) )... ); return std::make_tuple( std::make_shared<Indices>( mRange->sub(Is) )... );
} }
template <class... Indices> template <class BlockType, class... Indices>
constexpr decltype(auto) GMIndex<BlockType,Indices...>::mkLMax(const IndexPack& ipack)
{
return iter<0,NI>( [&](auto i) { return std::get<i>(ipack)->lmax(); },
[](auto... e) { return (e * ...); });
}
template <class BlockType, class... Indices>
constexpr decltype(auto) GMIndex<BlockType,Indices...>::mkPMax(const IndexPack& ipack, const BlockType& blockSizes)
{
if constexpr(std::is_same<BlockType,None>::value){
return mkLMax(ipack);
}
else {
return iter<0,NI>
( [&](auto i)
{ return (std::get<i>(ipack)->pmax() - SPos<1>()) * std::get<i>(blockSizes); },
[](auto... e) { return (e + ...); }) + SPos<1>();
}
}
template <class BlockType, class... Indices>
template <SizeT... Is> template <SizeT... Is>
constexpr decltype(auto) MIndex<Indices...>::mkBlockSizes(const IndexPack& ipack, Isq<Is...> is) constexpr decltype(auto) GMIndex<BlockType,Indices...>::mkLexBlockSizes(const IndexPack& ipack, Isq<Is...> is)
{ {
return std::make_tuple return std::make_tuple
( iter<Is,NI> ( iter<Is,NI>
// replace UPos by SPos where possible !!! ( [&](auto i) { return std::get<i>(ipack)->pmax(); },
( [&](auto i) { return UPos(std::get<i>(ipack)->pmax()); },
[&](const auto&... as) { return (as * ...); } )..., [&](const auto&... as) { return (as * ...); } )...,
SPos<1>() ); SPos<1>() );
} }
template <class... Indices> template <class BlockType, class... Indices>
template <SizeT I> template <SizeT I>
inline void MIndex<Indices...>::up() inline void GMIndex<BlockType,Indices...>::up()
{ {
auto& i = std::get<I>(mIPack); auto& i = std::get<I>(mIPack);
if constexpr(I != 0){ if constexpr(I != 0){
if(i->lex() == i->lmax()-1){ if(i->lex() == i->lmax().val()-1){
IB::mPos -= std::get<I>(mBlockSizes).val() * i->pos(); IB::mPos -= std::get<I>(blockSizes()).val() * i->pos();
if constexpr(not std::is_same<BlockType,None>::value){
mLex -= std::get<I>(lexBlockSizes()).val() * i->lex();
}
(*i) = 0; (*i) = 0;
up<I-1>(); up<I-1>();
return; return;
} }
} }
IB::mPos += std::get<I>(mBlockSizes).val(); IB::mPos += std::get<I>(blockSizes()).val();
if constexpr(not std::is_same<BlockType,None>::value){
mLex += std::get<I>(lexBlockSizes()).val();
}
++(*i); ++(*i);
} }
template <class... Indices> template <class BlockType, class... Indices>
template <SizeT I> template <SizeT I>
inline void MIndex<Indices...>::down() inline void GMIndex<BlockType,Indices...>::down()
{ {
auto& i = std::get<I>(mIPack); auto& i = std::get<I>(mIPack);
if constexpr(I != 0){ if constexpr(I != 0){
if(i->lex() == 0){ if(i->lex() == 0){
(*i) = i->lmax()-1; (*i) = i->lmax().val()-1;
IB::mPos += std::get<I>(mBlockSizes).val() * i->pos(); IB::mPos += std::get<I>(blockSizes()).val() * i->pos();
if constexpr(not std::is_same<BlockType,None>::value){
mLex += std::get<I>(lexBlockSizes()).val() * i->lex();
}
down<I-1>(); down<I-1>();
return; return;
} }
} }
IB::mPos -= std::get<I>(mBlockSizes).val(); IB::mPos -= std::get<I>(blockSizes()).val();
if constexpr(not std::is_same<BlockType,None>::value){
mLex -= std::get<I>(lexBlockSizes()).val();
}
--(*i); --(*i);
} }
template <class... Indices> template <class BlockType, class... Indices>
template <SizeT I, class Xpr, class F> template <SizeT I, class Xpr, class F>
constexpr decltype(auto) MIndex<Indices...>::mkIFor(const Xpr& xpr, F&& f) const constexpr decltype(auto) GMIndex<BlockType,Indices...>::mkIFor(const Xpr& xpr, F&& f) const
{ {
if constexpr(I == sizeof...(Indices)-1){ if constexpr(I == sizeof...(Indices)-1){
return std::get<I>(mIPack)->ifor(xpr,f); return std::get<I>(mIPack)->ifor(xpr,f);
@ -79,169 +111,202 @@ namespace CNORXZ
} }
} }
/************** /***************
* MIndex * * GMIndex *
**************/ ***************/
template <class... Indices> template <class BlockType, class... Indices>
MIndex<Indices...>::MIndex(const MIndex& i) : constexpr GMIndex<BlockType,Indices...>::GMIndex(const GMIndex& i) :
IndexInterface<MIndex<Indices...>,Tuple<typename Indices::MetaType...>>(0), IndexInterface<GMIndex<BlockType,Indices...>,Tuple<typename Indices::MetaType...>>(0),
mRange(rangeCast<RangeType>(i.range())), mRange(rangeCast<RangeType>(i.range())),
mIPack(mkIPack(Isqr<0,NI>{})), mIPack(mkIPack(Isqr<0,NI>{})),
mBlockSizes(mkBlockSizes(mIPack,Isqr<0,NI-1>{})) mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<0,NI-1>{})),
mBlockSizes(i.mBlockSizes),
mLMax(mkLMax(mIPack)),
mPMax(mkPMax(mIPack,mBlockSizes))
{ {
mPMax = iter<0,NI>( [&](auto i) { return std::get<i>(mIPack)->pmax(); },
[](auto... e) { return (e * ...); });
*this = i.pos(); *this = i.pos();
} }
template <class... Indices> template <class BlockType, class... Indices>
MIndex<Indices...>& MIndex<Indices...>::operator=(const MIndex& i) constexpr GMIndex<BlockType,Indices...>& GMIndex<BlockType,Indices...>::operator=(const GMIndex& i)
{ {
IndexInterface<MIndex<Indices...>,Tuple<typename Indices::MetaType...>>::operator=(0); IndexInterface<GMIndex<BlockType,Indices...>,Tuple<typename Indices::MetaType...>>::operator=(0);
mRange = rangeCast<RangeType>(i.range()); mRange = rangeCast<RangeType>(i.range());
mIPack = mkIPack(Isqr<0,NI>{}); mIPack = mkIPack(Isqr<0,NI>{});
mBlockSizes = mkBlockSizes(mIPack,Isqr<0,NI-1>{}); mLexBlockSizes = mkLexBlockSizes(mIPack,Isqr<0,NI-1>{});
mPMax = iter<0,NI>( [&](auto i) { return std::get<i>(mIPack)->pmax(); }, mBlockSizes = i.mBlockSizes;
[](auto... e) { return (e * ...); }); mLMax = mkLMax(mIPack);
mPMax = mkPMax(mIPack,mBlockSizes);
return *this = i.pos(); return *this = i.pos();
} }
template <class... Indices> template <class BlockType, class... Indices>
MIndex<Indices...>::MIndex(const RangePtr& range, SizeT lexpos) : constexpr GMIndex<BlockType,Indices...>::GMIndex(const RangePtr& range, SizeT lexpos) :
IndexInterface<MIndex<Indices...>,Tuple<typename Indices::MetaType...>>(0), IndexInterface<GMIndex<BlockType,Indices...>,Tuple<typename Indices::MetaType...>>(0),
mRange(rangeCast<RangeType>(range)), mRange(rangeCast<RangeType>(range)),
mIPack(mkIPack(Isqr<0,NI>{})), mIPack(mkIPack(Isqr<0,NI>{})),
mBlockSizes(mkBlockSizes(mIPack,Isqr<0,NI-1>{})) mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<0,NI-1>{})),
mBlockSizes(),
mLMax(mkLMax(mIPack)),
mPMax(mkPMax(mIPack,mBlockSizes))
{ {
mPMax = iter<0,NI>( [&](auto i) { return std::get<i>(mIPack)->pmax(); },
[](auto... e) { return (e * ...); });
*this = lexpos; *this = lexpos;
} }
template <class... Indices> template <class BlockType, class... Indices>
MIndex<Indices...>& MIndex<Indices...>::operator=(SizeT lexpos) constexpr GMIndex<BlockType,Indices...>::GMIndex(const RangePtr& range, const BlockType& blockSizes, SizeT lexpos) :
IndexInterface<GMIndex<BlockType,Indices...>,Tuple<typename Indices::MetaType...>>(0),
mRange(rangeCast<RangeType>(range)),
mIPack(mkIPack(Isqr<0,NI>{})),
mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<0,NI-1>{})),
mBlockSizes(blockSizes),
mLMax(mkLMax(mIPack)),
mPMax(mkPMax(mIPack,mBlockSizes))
{ {
// Adapt in GMIndex *this = lexpos;
IB::mPos = lexpos; }
iter<0,NI>( [&](auto i) { *std::get<i>(mIPack) = (IB::mPos / std::get<i>(mBlockSizes).val()) % std::get<i>(mIPack)->pmax(); }, NoF{} );
template <class BlockType, class... Indices>
GMIndex<BlockType,Indices...>& GMIndex<BlockType,Indices...>::operator=(SizeT lexpos)
{
if(lexpos >= lmax().val()){
if constexpr(not std::is_same<BlockType,None>::value){ mLex = lmax().val(); }
IB::mPos = pmax().val();
return *this;
}
if constexpr(not std::is_same<BlockType,None>::value){ mLex = lexpos; }
IB::mPos = iter<0,NI>( [&](auto i) {
*std::get<i>(mIPack) = (lex() / std::get<i>(lexBlockSizes()).val()) % std::get<i>(mIPack)->lmax().val();
return std::get<i>(blockSizes()).val() * std::get<i>(mIPack)->pos();
}, [](const auto&... e) { return (e + ...); } );
return *this; return *this;
} }
template <class... Indices> template <class BlockType, class... Indices>
MIndex<Indices...>& MIndex<Indices...>::operator++() GMIndex<BlockType,Indices...>& GMIndex<BlockType,Indices...>::operator++()
{ {
// End state is defined by high-index being end while all other indices are zero if(lex() == lmax().val()-1){
if(lex() != lmax()){ return *this = lmax().val();
}
if(lex() != lmax().val()){
up<NI-1>(); up<NI-1>();
} }
return *this; return *this;
} }
template <class... Indices> template <class BlockType, class... Indices>
MIndex<Indices...>& MIndex<Indices...>::operator--() GMIndex<BlockType,Indices...>& GMIndex<BlockType,Indices...>::operator--()
{ {
if(lex() == lmax().val()){
return *this = lmax().val()-1;
}
if(lex() != 0){ if(lex() != 0){
down<NI-1>(); down<NI-1>();
} }
return *this; return *this;
} }
template <class... Indices> template <class BlockType, class... Indices>
MIndex<Indices...> MIndex<Indices...>::operator+(Int n) const GMIndex<BlockType,Indices...> GMIndex<BlockType,Indices...>::operator+(Int n) const
{ {
MIndex o(*this); GMIndex o(*this);
return o += n; return o += n;
} }
template <class... Indices> template <class BlockType, class... Indices>
MIndex<Indices...> MIndex<Indices...>::operator-(Int n) const GMIndex<BlockType,Indices...> GMIndex<BlockType,Indices...>::operator-(Int n) const
{ {
MIndex o(*this); GMIndex o(*this);
return o -= n; return o -= n;
} }
template <class... Indices> template <class BlockType, class... Indices>
MIndex<Indices...>& MIndex<Indices...>::operator+=(Int n) GMIndex<BlockType,Indices...>& GMIndex<BlockType,Indices...>::operator+=(Int n)
{ {
if(-n > static_cast<long int>(lex())){ if(-n > static_cast<long int>(lex())){
(*this) = 0; (*this) = 0;
} }
const SizeT p = lex() + n; const SizeT p = lex() + n;
if(p > lmax()){ if(p > lmax().val()){
(*this) = lmax(); (*this) = lmax().val();
} }
(*this) = p; (*this) = p;
return *this; return *this;
} }
template <class... Indices> template <class BlockType, class... Indices>
MIndex<Indices...>& MIndex<Indices...>::operator-=(Int n) GMIndex<BlockType,Indices...>& GMIndex<BlockType,Indices...>::operator-=(Int n)
{ {
if(n > static_cast<long int>(lex())){ if(n > static_cast<long int>(lex())){
(*this) = 0; (*this) = 0;
} }
const SizeT p = lex() + n; const SizeT p = lex() + n;
if(p > lmax()){ if(p > lmax().val()){
(*this) = lmax(); (*this) = lmax().val();
} }
(*this) = p; (*this) = p;
return *this; return *this;
} }
template <class... Indices> template <class BlockType, class... Indices>
SizeT MIndex<Indices...>::lex() const SizeT GMIndex<BlockType,Indices...>::lex() const
{ {
return IB::mPos; if constexpr(std::is_same<BlockType,None>::value){
return IB::mPos;
}
else {
return mLex;
}
} }
template <class... Indices> template <class BlockType, class... Indices>
SizeT MIndex<Indices...>::pmax() const constexpr decltype(auto) GMIndex<BlockType,Indices...>::pmax() const
{ {
return mPMax; return mPMax;
} }
template <class... Indices> template <class BlockType, class... Indices>
SizeT MIndex<Indices...>::lmax() const constexpr decltype(auto) GMIndex<BlockType,Indices...>::lmax() const
{ {
return mPMax; return mPMax;
} }
template <class... Indices> template <class BlockType, class... Indices>
IndexId<0> MIndex<Indices...>::id() const IndexId<0> GMIndex<BlockType,Indices...>::id() const
{ {
return IndexId<0>(this->ptrId()); return IndexId<0>(this->ptrId());
} }
template <class... Indices> template <class BlockType, class... Indices>
typename MIndex<Indices...>::MetaType MIndex<Indices...>::operator*() const typename GMIndex<BlockType,Indices...>::MetaType GMIndex<BlockType,Indices...>::operator*() const
{ {
return meta(); return meta();
} }
template <class... Indices> template <class BlockType, class... Indices>
SizeT MIndex<Indices...>::dim() const constexpr SizeT GMIndex<BlockType,Indices...>::dim() const
{ {
return NI; return NI;
} }
template <class... Indices> template <class BlockType, class... Indices>
Sptr<typename MIndex<Indices...>::RangeType> MIndex<Indices...>::range() const Sptr<typename GMIndex<BlockType,Indices...>::RangeType> GMIndex<BlockType,Indices...>::range() const
{ {
return mRange; return mRange;
} }
template <class... Indices> template <class BlockType, class... Indices>
template <SizeT I> template <SizeT I>
decltype(auto) MIndex<Indices...>::stepSize(const IndexId<I>& id) const decltype(auto) GMIndex<BlockType,Indices...>::stepSize(const IndexId<I>& id) const
{ {
return iter<0,NI> return iter<0,NI>
( [&](auto i) { return std::get<i>(mIPack)->stepSize(id) * std::get<i>(mBlockSizes); }, ( [&](auto i) { return std::get<i>(mIPack)->stepSize(id) * std::get<i>(blockSizes()); },
[](const auto&... ss) { return ( ss + ... ); }); [](const auto&... ss) { return ( ss + ... ); });
} }
template <class... Indices> template <class BlockType, class... Indices>
String MIndex<Indices...>::stringMeta() const String GMIndex<BlockType,Indices...>::stringMeta() const
{ {
const String blim = "("; const String blim = "(";
const String elim = ")"; const String elim = ")";
@ -253,50 +318,61 @@ namespace CNORXZ
} ); } );
} }
template <class... Indices> template <class BlockType, class... Indices>
typename MIndex<Indices...>::MetaType MIndex<Indices...>::meta() const typename GMIndex<BlockType,Indices...>::MetaType GMIndex<BlockType,Indices...>::meta() const
{ {
return iter<0,NI>( [&](auto i) { return std::get<i>(mIPack)->meta(); }, return iter<0,NI>( [&](auto i) { return std::get<i>(mIPack)->meta(); },
[](const auto&... xs) { return std::make_tuple(xs...); } ); [](const auto&... xs) { return std::make_tuple(xs...); } );
} }
template <class... Indices> template <class BlockType, class... Indices>
MIndex<Indices...>& MIndex<Indices...>::at(const MetaType& metaPos) GMIndex<BlockType,Indices...>& GMIndex<BlockType,Indices...>::at(const MetaType& metaPos)
{ {
iter<0,NI>( [&](auto i) { std::get<i>(mIPack)->at( std::get<i>(metaPos) ); }, NoF {} ); iter<0,NI>( [&](auto i) { std::get<i>(mIPack)->at( std::get<i>(metaPos) ); }, NoF {} );
IB::mPos = iter<0,NI> IB::mPos = iter<0,NI>
( [&](auto i) { return std::get<i>(mIPack)->pos()*std::get<i>(mBlockSizes).val(); }, ( [&](auto i) { return std::get<i>(mIPack)->pos()*std::get<i>(blockSizes()).val(); },
[](const auto&... xs) { return (xs + ...); }); [](const auto&... xs) { return (xs + ...); });
return *this; return *this;
} }
template <class... Indices> template <class BlockType, class... Indices>
template <class Xpr, class F> template <class Xpr, class F>
constexpr decltype(auto) MIndex<Indices...>::ifor(const Xpr& xpr, F&& f) const constexpr decltype(auto) GMIndex<BlockType,Indices...>::ifor(const Xpr& xpr, F&& f) const
{ {
return mkIFor<0>(xpr, f); return mkIFor<0>(xpr, f);
} }
template <class... Indices> template <class BlockType, class... Indices>
MIndex<Indices...>& MIndex<Indices...>::operator()(const Sptr<MIndex>& mi) GMIndex<BlockType,Indices...>& GMIndex<BlockType,Indices...>::operator()(const Sptr<GMIndex>& mi)
{ {
mIPack = mi.mIPack; mIPack = mi.mIPack;
IB::mPos = iter<0,NI> IB::mPos = iter<0,NI>
( [&](auto i) { return std::get<i>(mIPack)->pos()*std::get<i>(mBlockSizes).val(); }, ( [&](auto i) { return std::get<i>(mIPack)->pos()*std::get<i>(blockSizes()).val(); },
[](const auto&... xs) { return (xs + ...); }); [](const auto&... xs) { return (xs + ...); });
return *this; return *this;
} }
template <class... Indices> template <class BlockType, class... Indices>
const typename MIndex<Indices...>::IndexPack& MIndex<Indices...>::pack() const const typename GMIndex<BlockType,Indices...>::IndexPack& GMIndex<BlockType,Indices...>::pack() const
{ {
return mIPack; return mIPack;
} }
template <class... Indices> template <class BlockType, class... Indices>
const auto& MIndex<Indices...>::blockSizes() const const auto& GMIndex<BlockType,Indices...>::blockSizes() const
{ {
return mBlockSizes; if constexpr(std::is_same<BlockType,None>::value){
return mLexBlockSizes;
}
else {
return mBlockSizes;
}
}
template <class BlockType, class... Indices>
const auto& GMIndex<BlockType,Indices...>::lexBlockSizes() const
{
return mLexBlockSizes;
} }

View file

@ -11,14 +11,14 @@
namespace CNORXZ namespace CNORXZ
{ {
template <class... Indices> template <class BlockType, class... Indices>
class MIndex : public IndexInterface<MIndex<Indices...>, class GMIndex : public IndexInterface<GMIndex<BlockType,Indices...>,
Tuple<typename Indices::MetaType...> > Tuple<typename Indices::MetaType...> >
{ {
public: public:
typedef IndexInterface<MIndex<Indices...>, typedef IndexInterface<GMIndex<BlockType,Indices...>,
Tuple<typename Indices::MetaType...> > IB; Tuple<typename Indices::MetaType...>> IB;
typedef Tuple<Sptr<Indices>...> IndexPack; typedef Tuple<Sptr<Indices>...> IndexPack;
typedef Tuple<typename Indices::MetaType...> MetaType; typedef Tuple<typename Indices::MetaType...> MetaType;
typedef MRange<typename Indices::RangeType...> RangeType; typedef MRange<typename Indices::RangeType...> RangeType;
@ -26,31 +26,32 @@ namespace CNORXZ
// NO DEFAULT HERE !!! // NO DEFAULT HERE !!!
// ( have to assign sub-indices (ptr!) correctly ) // ( have to assign sub-indices (ptr!) correctly )
MIndex() = default; constexpr GMIndex() = default;
MIndex(MIndex&& i) = default; constexpr GMIndex(GMIndex&& i) = default;
MIndex& operator=(MIndex&& i) = default; constexpr GMIndex& operator=(GMIndex&& i) = default;
MIndex(const MIndex& i); constexpr GMIndex(const GMIndex& i);
MIndex& operator=(const MIndex& i); constexpr GMIndex& operator=(const GMIndex& i);
MIndex(const RangePtr& range, SizeT lexpos = 0); constexpr GMIndex(const RangePtr& range, SizeT lexpos = 0);
constexpr GMIndex(const RangePtr& range, const BlockType& blockSizes, SizeT lexpos = 0);
MIndex& operator=(SizeT pos); GMIndex& operator=(SizeT pos);
MIndex& operator++(); GMIndex& operator++();
MIndex& operator--(); GMIndex& operator--();
MIndex operator+(Int n) const; GMIndex operator+(Int n) const;
MIndex operator-(Int n) const; GMIndex operator-(Int n) const;
MIndex& operator+=(Int n); GMIndex& operator+=(Int n);
MIndex& operator-=(Int n); GMIndex& operator-=(Int n);
SizeT lex() const; SizeT lex() const;
SizeT pmax() const; constexpr decltype(auto) pmax() const;
SizeT lmax() const; constexpr decltype(auto) lmax() const;
IndexId<0> id() const; IndexId<0> id() const;
MetaType operator*() const; MetaType operator*() const;
SizeT dim() const; constexpr SizeT dim() const;
Sptr<RangeType> range() const; Sptr<RangeType> range() const;
template <SizeT I> template <SizeT I>
@ -58,20 +59,25 @@ namespace CNORXZ
String stringMeta() const; String stringMeta() const;
MetaType meta() const; MetaType meta() const;
MIndex& at(const MetaType& metaPos); GMIndex& at(const MetaType& metaPos);
template <class Xpr, class F> template <class Xpr, class F>
constexpr decltype(auto) ifor(const Xpr& xpr, F&& f) const; constexpr decltype(auto) ifor(const Xpr& xpr, F&& f) const;
// replace sub-index instances; only use if you know what you are doing! // replace sub-index instances; only use if you know what you are doing!
MIndex& operator()(const Sptr<MIndex>& mi); GMIndex& operator()(const Sptr<GMIndex>& mi);
const IndexPack& pack() const; const IndexPack& pack() const;
const auto& blockSizes() const; const auto& blockSizes() const;
const auto& lexBlockSizes() const;
private: private:
template <SizeT... Is> template <SizeT... Is>
static constexpr decltype(auto) mkBlockSizes(const IndexPack& ipack, Isq<Is...> is); static constexpr decltype(auto) mkLexBlockSizes(const IndexPack& ipack, Isq<Is...> is);
static constexpr decltype(auto) mkLMax(const IndexPack& ipack);
static constexpr decltype(auto) mkPMax(const IndexPack& ipack, const BlockType& blockSizes);
template <SizeT... Is> template <SizeT... Is>
constexpr decltype(auto) mkIPack(Isq<Is...> is) const; constexpr decltype(auto) mkIPack(Isq<Is...> is) const;
@ -87,31 +93,19 @@ namespace CNORXZ
Sptr<RangeType> mRange; Sptr<RangeType> mRange;
IndexPack mIPack; IndexPack mIPack;
typedef RemoveRef<decltype(mkBlockSizes(mIPack,Isqr<0,NI-1>{}))> BlockTuple; typedef RemoveRef<decltype(mkLexBlockSizes(mIPack,Isqr<0,NI-1>{}))> LexBlockType;
BlockTuple mBlockSizes; LexBlockType mLexBlockSizes;
SizeT mPMax = 0; // = LMax here, add new variable in GMIndex! BlockType mBlockSizes;
SizeT mLex;
typedef RemoveRef<decltype(mkLMax(mIPack))> LMaxT;
LMaxT mLMax;
typedef RemoveRef<decltype(mkPMax(mIPack,mBlockSizes))> PMaxT;
PMaxT mPMax;
}; };
// modified blockSizes; to be used for Slices; can be created from MIndices template <class... Indices>
template <class MIndexType, class BlockType> using MIndex = GMIndex<None,Indices...>;
class GMIndex : public MIndexType
{
public:
// override everything that modyfies IB::mPos or uses mBlockSizes!!!
constexpr GMIndex(const MIndexType& mi, const BlockType& b);
template <class Xpr, class F>
constexpr decltype(auto) ifor(const Xpr& xpr, F&& f) const;
private:
BlockType mLexBlockSizes;
template <SizeT... Is>
constexpr decltype(auto) mkPos(Isq<Is...> is) const;
};
// NOT THREAD SAVE
template <class... Ranges> template <class... Ranges>
class MRangeFactory : public RangeFactoryBase class MRangeFactory : public RangeFactoryBase
{ {

View file

@ -75,15 +75,15 @@ namespace CNORXZ
} }
template <typename MetaType> template <typename MetaType>
SizeT UIndex<MetaType>::pmax() const UPos UIndex<MetaType>::pmax() const
{ {
return mRangePtr->size(); return UPos(mRangePtr->size());
} }
template <typename MetaType> template <typename MetaType>
SizeT UIndex<MetaType>::lmax() const UPos UIndex<MetaType>::lmax() const
{ {
return mRangePtr->size(); return UPos(mRangePtr->size());
} }
template <typename MetaType> template <typename MetaType>
@ -140,7 +140,7 @@ namespace CNORXZ
template <class Xpr, class F> template <class Xpr, class F>
decltype(auto) UIndex<MetaType>::ifor(const Xpr& xpr, F&& f) const decltype(auto) UIndex<MetaType>::ifor(const Xpr& xpr, F&& f) const
{ {
return For<0,Xpr,F>(this->pmax(), this->id(), xpr, std::forward<F>(f)); return For<0,Xpr,F>(this->pmax().val(), this->id(), xpr, std::forward<F>(f));
} }
/********************** /**********************

View file

@ -31,8 +31,8 @@ namespace CNORXZ
UIndex& operator-=(Int n); UIndex& operator-=(Int n);
SizeT lex() const; SizeT lex() const;
SizeT pmax() const; UPos pmax() const;
SizeT lmax() const; UPos lmax() const;
IndexId<0> id() const; IndexId<0> id() const;
const MetaT& operator*() const; const MetaT& operator*() const;

View file

@ -86,15 +86,15 @@ namespace CNORXZ
} }
template <class Index, typename Meta> template <class Index, typename Meta>
SizeT XIndex<Index,Meta>::pmax() const UPos XIndex<Index,Meta>::pmax() const
{ {
return mI->pmax(); return UPos(mI->pmax());
} }
template <class Index, typename Meta> template <class Index, typename Meta>
SizeT XIndex<Index,Meta>::lmax() const UPos XIndex<Index,Meta>::lmax() const
{ {
return mI->lmax(); return UPos(mI->lmax());
} }
template <class Index, typename Meta> template <class Index, typename Meta>

View file

@ -26,8 +26,8 @@ namespace CNORXZ
virtual XIndexBase& operator-=(Int n) = 0; virtual XIndexBase& operator-=(Int n) = 0;
virtual SizeT lex() const = 0; virtual SizeT lex() const = 0;
virtual SizeT pmax() const = 0; virtual UPos pmax() const = 0;
virtual SizeT lmax() const = 0; virtual UPos lmax() const = 0;
virtual IndexId<0> id() const = 0; virtual IndexId<0> id() const = 0;
virtual DType operator*() const = 0; virtual DType operator*() const = 0;
@ -74,8 +74,8 @@ namespace CNORXZ
virtual XIndex& operator-=(Int n) override final; virtual XIndex& operator-=(Int n) override final;
virtual SizeT lex() const override final; virtual SizeT lex() const override final;
virtual SizeT pmax() const override final; virtual UPos pmax() const override final;
virtual SizeT lmax() const override final; virtual UPos lmax() const override final;
virtual IndexId<0> id() const override final; virtual IndexId<0> id() const override final;
virtual DType operator*() const override final; virtual DType operator*() const override final;

View file

@ -35,8 +35,8 @@ namespace CNORXZ
YIndex& operator-=(Int n); YIndex& operator-=(Int n);
SizeT lex() const; SizeT lex() const;
SizeT pmax() const; UPos pmax() const;
SizeT lmax() const; UPos lmax() const;
IndexId<0> id() const; IndexId<0> id() const;
DType operator*() const; DType operator*() const;
@ -69,8 +69,8 @@ namespace CNORXZ
Vector<SizeT> mBlockSizes; // dim() elements only!!! Vector<SizeT> mBlockSizes; // dim() elements only!!!
Vector<SizeT> mLexBlockSizes; // dim() elements only!!! Vector<SizeT> mLexBlockSizes; // dim() elements only!!!
SizeT mLex = 0; SizeT mLex = 0;
SizeT mPMax = 0; UPos mPMax = 0;
SizeT mLMax = 0; UPos mLMax = 0;
}; };
class YRangeFactory : public RangeFactoryBase class YRangeFactory : public RangeFactoryBase

View file

@ -83,6 +83,12 @@ namespace CNORXZ
return UPos(N); return UPos(N);
} }
template <SizeT N>
constexpr SPos<N>::operator SizeT() const
{
return val();
}
/************ /************
* UPos * * UPos *
************/ ************/
@ -138,7 +144,12 @@ namespace CNORXZ
{ {
return extend(a); return extend(a);
} }
constexpr UPos::operator SizeT() const
{
return val();
}
/************ /************
* FPos * * FPos *
************/ ************/
@ -185,6 +196,11 @@ namespace CNORXZ
return extend(a); return extend(a);
} }
constexpr FPos::operator SizeT() const
{
return val();
}
/************* /*************
* SFPos * * SFPos *
*************/ *************/
@ -265,6 +281,12 @@ namespace CNORXZ
return FPos(N, &sMs[0]); return FPos(N, &sMs[0]);
} }
template <SizeT N, SizeT... Ms>
constexpr SFPos<N,Ms...>::operator SizeT() const
{
return val();
}
/************ /************
* MPos * * MPos *
************/ ************/
@ -456,6 +478,11 @@ namespace CNORXZ
return MPos<DPos,PosT>(*this,a); return MPos<DPos,PosT>(*this,a);
} }
inline DPos::operator SizeT() const
{
return val();
}
/*************** /***************
* DPosRef * * DPosRef *
***************/ ***************/
@ -531,6 +558,11 @@ namespace CNORXZ
//return DPos(mP->vextend( a )); //return DPos(mP->vextend( a ));
return MPos<DPos,PosT>(*this,a); return MPos<DPos,PosT>(*this,a);
} }
inline DPosRef::operator SizeT() const
{
return val();
}
/************ /************
* EPos * * EPos *

View file

@ -36,6 +36,7 @@ namespace CNORXZ
constexpr decltype(auto) operator<<(const PosT& a) const; constexpr decltype(auto) operator<<(const PosT& a) const;
explicit constexpr operator UPos() const; explicit constexpr operator UPos() const;
explicit constexpr operator SizeT() const;
}; };
class UPos class UPos
@ -68,6 +69,8 @@ namespace CNORXZ
template <class PosT> template <class PosT>
constexpr decltype(auto) operator<<(const PosT& a) const; constexpr decltype(auto) operator<<(const PosT& a) const;
explicit constexpr operator SizeT() const;
}; };
class FPos class FPos
@ -98,6 +101,8 @@ namespace CNORXZ
template <class PosT> template <class PosT>
constexpr decltype(auto) operator<<(const PosT& a) const; constexpr decltype(auto) operator<<(const PosT& a) const;
explicit constexpr operator SizeT() const;
}; };
template <SizeT N, SizeT... Ms> template <SizeT N, SizeT... Ms>
@ -129,6 +134,8 @@ namespace CNORXZ
constexpr decltype(auto) operator<<(const PosT& a) const; constexpr decltype(auto) operator<<(const PosT& a) const;
explicit constexpr operator FPos() const; explicit constexpr operator FPos() const;
explicit constexpr operator SizeT() const;
}; };
template <class BPosT, class NPosT> template <class BPosT, class NPosT>
@ -204,6 +211,8 @@ namespace CNORXZ
template <class PosT> template <class PosT>
inline decltype(auto) operator<<(const PosT& a) const; inline decltype(auto) operator<<(const PosT& a) const;
explicit inline operator SizeT() const;
}; };
class DPosRef class DPosRef
@ -238,6 +247,8 @@ namespace CNORXZ
template <class PosT> template <class PosT>
inline decltype(auto) operator<<(const PosT& a) const; inline decltype(auto) operator<<(const PosT& a) const;
explicit inline operator SizeT() const;
}; };
// for common call of extension vector elements // for common call of extension vector elements

View file

@ -56,14 +56,14 @@ namespace CNORXZ
return IB::mPos; return IB::mPos;
} }
SizeT CIndex::lmax() const UPos CIndex::lmax() const
{ {
return mRangePtr->size(); return UPos(mRangePtr->size());
} }
SizeT CIndex::pmax() const UPos CIndex::pmax() const
{ {
return mRangePtr->size(); return UPos(mRangePtr->size());
} }
IndexId<0> CIndex::id() const IndexId<0> CIndex::id() const

View file

@ -87,12 +87,12 @@ namespace CNORXZ
return mI->lex(); return mI->lex();
} }
SizeT DIndex::pmax() const UPos DIndex::pmax() const
{ {
return mI->pmax(); return mI->pmax();
} }
SizeT DIndex::lmax() const UPos DIndex::lmax() const
{ {
return mI->lmax(); return mI->lmax();
} }

View file

@ -25,7 +25,7 @@ namespace CNORXZ
for(SizeT i = o.size(); i != 0; --i){ for(SizeT i = o.size(); i != 0; --i){
const SizeT j = i-1; const SizeT j = i-1;
o[j] = b; o[j] = b;
b *= mIs[j]->pmax(); b *= mIs[j]->pmax().val();
} }
return o; return o;
} }
@ -37,7 +37,7 @@ namespace CNORXZ
for(SizeT i = o.size(); i != 0; --i){ for(SizeT i = o.size(); i != 0; --i){
const SizeT j = i-1; const SizeT j = i-1;
o[j] = b; o[j] = b;
b *= mIs[j]->lmax(); b *= mIs[j]->lmax().val();
} }
return o; return o;
} }
@ -47,7 +47,7 @@ namespace CNORXZ
auto& idx = mIs[i]; auto& idx = mIs[i];
// it is guaranteed that the last accessible position // it is guaranteed that the last accessible position
// is one less than the max position (=end) // is one less than the max position (=end)
if(i != 0 and idx->lex() == idx->lmax()-1){ if(i != 0 and idx->lex() == idx->lmax().val()-1){
IB::mPos -= mBlockSizes[i] * idx->pos(); IB::mPos -= mBlockSizes[i] * idx->pos();
mLex -= mLexBlockSizes[i] * idx->lex(); mLex -= mLexBlockSizes[i] * idx->lex();
(*idx) = 0; (*idx) = 0;
@ -63,7 +63,7 @@ namespace CNORXZ
{ {
auto& idx = mIs[i]; auto& idx = mIs[i];
if(i != 0 and idx->pos() == 0){ if(i != 0 and idx->pos() == 0){
(*idx) = idx->lmax()-1; (*idx) = idx->lmax().val()-1;
IB::mPos += mBlockSizes[i] * idx->pos(); IB::mPos += mBlockSizes[i] * idx->pos();
mLex += mLexBlockSizes[i] * idx->lex(); mLex += mLexBlockSizes[i] * idx->lex();
down(i-1); down(i-1);
@ -89,7 +89,7 @@ namespace CNORXZ
{ {
SizeT o = 0; SizeT o = 0;
for(SizeT i = 0; i != mIs.size(); ++i){ for(SizeT i = 0; i != mIs.size(); ++i){
o += (mIs[i]->pmax()-1) * mBlockSizes[i]; o += (mIs[i]->pmax().val()-1) * mBlockSizes[i];
} }
return o+1; return o+1;
} }
@ -97,7 +97,7 @@ namespace CNORXZ
inline SizeT YIndex::mkLMax() const inline SizeT YIndex::mkLMax() const
{ {
return std::accumulate(mIs.begin(), mIs.end(),1, return std::accumulate(mIs.begin(), mIs.end(),1,
[](const auto& res, const auto& el) { return res * el->lmax(); } ); [](const auto& res, const auto& el) { return res * el->lmax().val(); } );
} }
@ -143,15 +143,15 @@ namespace CNORXZ
YIndex& YIndex::operator=(SizeT lexpos) YIndex& YIndex::operator=(SizeT lexpos)
{ {
if(lexpos >= lmax()){ if(lexpos >= lmax().val()){
mLex = lmax(); mLex = lmax().val();
IB::mPos = pmax(); IB::mPos = pmax().val();
return *this; return *this;
} }
mLex = lexpos; mLex = lexpos;
IB::mPos = 0; IB::mPos = 0;
for(SizeT i = 0; i != mIs.size(); ++i){ for(SizeT i = 0; i != mIs.size(); ++i){
*mIs[i] = (lex() / mLexBlockSizes[i]) % mIs[i]->lmax(); *mIs[i] = (lex() / mLexBlockSizes[i]) % mIs[i]->lmax().val();
IB::mPos += mBlockSizes[i] * mIs[i]->pos(); IB::mPos += mBlockSizes[i] * mIs[i]->pos();
} }
return *this; return *this;
@ -159,22 +159,19 @@ namespace CNORXZ
YIndex& YIndex::operator++() YIndex& YIndex::operator++()
{ {
auto& i0 = mIs[0]; if(lex() == lmax().val()-1){
if(i0->lex() != i0->lmax()){ return *this = lmax().val();
up(mIs.size()-1);
} }
// no else! up() changes i0! if(lex() != lmax().val()){
if(i0->lex() == i0->lmax()){ up(mIs.size()-1);
IB::mPos = pmax();
} }
return *this; return *this;
} }
YIndex& YIndex::operator--() YIndex& YIndex::operator--()
{ {
auto& i0 = mIs[0]; if(lex() == lmax().val()){
if(i0->lex() == i0->lmax()){ return *this = lmax().val()-1;
IB::mPos = mBlockSizes[0] * i0->pmax();
} }
if(lex() != 0){ if(lex() != 0){
down(mIs.size()-1); down(mIs.size()-1);
@ -215,12 +212,12 @@ namespace CNORXZ
return mLex; return mLex;
} }
SizeT YIndex::pmax() const UPos YIndex::pmax() const
{ {
return mPMax; return mPMax;
} }
SizeT YIndex::lmax() const UPos YIndex::lmax() const
{ {
return mLMax; return mLMax;
} }

View file

@ -231,8 +231,8 @@ namespace
auto yrx = std::dynamic_pointer_cast<YRange>(yr); auto yrx = std::dynamic_pointer_cast<YRange>(yr);
auto yi = yrx->begin(); auto yi = yrx->begin();
EXPECT_EQ(yi.pmax(), yr->size()); EXPECT_EQ(yi.pmax().val(), yr->size());
EXPECT_EQ(yi.lmax(), yr->size()); EXPECT_EQ(yi.lmax().val(), yr->size());
EXPECT_EQ(yi.range(), yr); EXPECT_EQ(yi.range(), yr);
EXPECT_EQ(yi.range(), yrx); EXPECT_EQ(yi.range(), yrx);
EXPECT_EQ(yi.dim(), 2u); EXPECT_EQ(yi.dim(), 2u);
@ -258,11 +258,11 @@ namespace
EXPECT_EQ(b.stringMeta(), toString(mmj)); EXPECT_EQ(b.stringMeta(), toString(mmj));
} }
} }
yi += yi.lmax() + 10; yi += yi.lmax().val() + 10;
EXPECT_EQ(yi.lex(), yi.lmax()); EXPECT_EQ(yi.lex(), yi.lmax().val());
EXPECT_EQ(yi.pos(), yi.pmax()); EXPECT_EQ(yi.pos(), yi.pmax().val());
yi -= yi.lmax() + 20; yi -= yi.lmax().val() + 20;
EXPECT_EQ(yi.lex(), 0u); EXPECT_EQ(yi.lex(), 0u);
EXPECT_EQ(yi.pos(), 0u); EXPECT_EQ(yi.pos(), 0u);
} }