change template args of RangeInterface (static polymorphism) + fixes in MRange -> first tests compile

This commit is contained in:
Christian Zimmermann 2022-11-14 00:35:05 +01:00
parent 62a9df39d3
commit 3a6ffc209b
14 changed files with 186 additions and 93 deletions

View file

@ -3,6 +3,7 @@
#define __cxz_to_string_cc_h__
#include "to_string.h"
#include "iter.h"
#include <sstream>
namespace CNORXZ
@ -29,7 +30,7 @@ namespace CNORXZ
}
template <typename T, size_t N>
String ToString<std::array<T,N>>::func(const std::array<T,N>& a)
String ToString<Arr<T,N>>::func(const Arr<T,N>& a)
{
std::stringstream ss;
ss << "(";
@ -41,6 +42,19 @@ namespace CNORXZ
return ss.str();
}
template <typename... Ts>
String ToString<Tuple<Ts...>>::func(const Tuple<Ts...>& t)
{
const String blim = "(";
const String elim = ")";
const String dlim = ",";
return iter<1,sizeof...(Ts)>
( [&](auto i) { return toString(std::get<i>(t)); },
[&](const auto&... xs) {
return blim + toString(std::get<0>(t)) + ( (dlim + xs) + ... ) + elim;
} );
}
template <typename T>
String toString(const T& a)
{

View file

@ -30,6 +30,12 @@ namespace CNORXZ
static String func(const Arr<T,N>& a);
};
template <typename... Ts>
struct ToString<Tuple<Ts...>>
{
static String func(const Tuple<Ts...>& t);
};
template <>
struct ToString<DType>
{

View file

@ -15,6 +15,7 @@ namespace CNORXZ
typedef IndexInterface<CIndex,SizeT> 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<CIndex,SizeT>
class CRange : public RangeInterface<CRange>
{
public:
typedef RangeBase RB;

View file

@ -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 <class... Indices>
constexpr decltype(auto) MIndex<Indices...>::mkBlockSizes() const
template <SizeT... Is>
constexpr decltype(auto) MIndex<Indices...>::mkBlockSizes(const IndexPack& ipack, Isq<Is...> is)
{
return std::make_tuple
( iter<Is,NI>
( [&](auto i) { return std::get<i>(mIPack)->max(); },
// replace UPos by SPos where possible !!!
( [&](auto i) { return UPos(std::get<i>(ipack)->max()); },
[&](const auto&... as) { return (as * ...); } )...,
SPos<1>() );
}
@ -38,13 +38,13 @@ namespace CNORXZ
auto& i = std::get<I>(mIPack);
if constexpr(I != 0){
if(i->pos() == i->max()-1){
IB::mPos -= std::get<I>(mBlockSize) * i->pos();
IB::mPos -= std::get<I>(mBlockSizes).val() * i->pos();
(*i) = 0;
upi<N-1>();
up<I-1>();
return;
}
}
IB::mPos += std::get<I>(mBlockSize);
IB::mPos += std::get<I>(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<I>(mBlockSize) * i->pos();
downi<N-1>();
IB::mPos += std::get<I>(mBlockSizes).val() * i->pos();
down<I-1>();
return;
}
}
IB::mPos -= std::get<I>(mBlockSize);
IB::mPos -= std::get<I>(mBlockSizes).val();
--(*i);
}
@ -69,7 +69,7 @@ namespace CNORXZ
template <SizeT I, class Xpr, class F>
constexpr decltype(auto) MIndex<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);
}
else {
@ -85,27 +85,26 @@ namespace CNORXZ
MIndex<Indices...>::MIndex(const MIndex& i) :
IndexInterface<MIndex<Indices...>,Tuple<typename Indices::MetaType...>>(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<RangeType>(i.range()))
{}
template <class... Indices>
MIndex& MIndex<Indices...>::operator=(const MIndex& i)
MIndex<Indices...>& MIndex<Indices...>::operator=(const MIndex& i)
{
IndexInterface<MIndex<Indices...>,Tuple<typename Indices::MetaType...>>::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<RangeType>(i.range());
return *this;
}
template <class... Indices>
template <class MRange>
MIndex<Indices...>::MIndex(const Sptr<MRange>& range, SizeT pos) :
MIndex<Indices...>::MIndex(const RangePtr& range, SizeT pos) :
IndexInterface<MIndex<Indices...>,Tuple<typename Indices::MetaType...>>(0),
mIPack(mkIPack(IB::mPos, Isqr<0,NI>{})),
mBlockSizes(mkBlockSizes(), Isqr<0,NI>{}),
mRange(range),
mBlockSizes(mkBlockSizes(mIPack,Isqr<0,NI-1>{})),
mRange(rangeCast<RangeType>(range))
{
(*this) = pos;
}
@ -114,7 +113,7 @@ namespace CNORXZ
MIndex<Indices...>& MIndex<Indices...>::operator=(SizeT pos)
{
IB::mPos = pos;
iter<0,NI>( [&](auto i) { std::get<i>(mIPack) = (IB::mPos / std::get<i>(mBlockSize)) % std::get<i>(mIPack)->max() }, NoF{} );
iter<0,NI>( [&](auto i) { *std::get<i>(mIPack) = (IB::mPos / std::get<i>(mBlockSizes).val()) % std::get<i>(mIPack)->max(); }, NoF{} );
return *this;
}
@ -153,9 +152,9 @@ namespace CNORXZ
}
template <class... Indices>
MIndex& MIndex<Indices...>::operator+=(Int n)
MIndex<Indices...>& MIndex<Indices...>::operator+=(Int n)
{
if(-n > IB::mPos){
if(-n > static_cast<long int>(IB::mPos)){
(*this) = 0;
}
const SizeT p = IB::mPos + n;
@ -167,9 +166,9 @@ namespace CNORXZ
}
template <class... Indices>
MIndex& MIndex<Indices...>::operator-=(Int n)
MIndex<Indices...>& MIndex<Indices...>::operator-=(Int n)
{
if(n > IB::mPos){
if(n > static_cast<long int>(IB::mPos)){
(*this) = 0;
}
const SizeT p = IB::mPos + n;
@ -193,7 +192,7 @@ namespace CNORXZ
}
template <class... Indices>
MetaType MIndex<Indices...>::operator*() const
typename MIndex<Indices...>::MetaType MIndex<Indices...>::operator*() const
{
return meta();
}
@ -205,25 +204,25 @@ namespace CNORXZ
}
template <class... Indices>
Sptr<RangeType> MIndex<Indices...>::range() const
Sptr<typename MIndex<Indices...>::RangeType> MIndex<Indices...>::range() const
{
return mRange;
}
template <class... Indices>
template <SizeT I>
decltype(auto) MIndex<Indices...>::stepSize(const IndexId<I>& id) const;
decltype(auto) MIndex<Indices...>::stepSize(const IndexId<I>& id) const
{
return iter<0,NI>
( [&](auto i) { return std::get<i>(mIPack)->stepSize(id) * std::get<i>(mBlockSize); },
( [&](auto i) { return std::get<i>(mIPack)->stepSize(id) * std::get<i>(mBlockSizes); },
[](const auto&... ss) { return ( ss + ... ); });
}
template <class... Indices>
String MIndex<Indices...>::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<i>(mIPack)->stringMeta(); },
@ -242,9 +241,9 @@ namespace CNORXZ
template <class... Indices>
MIndex<Indices...>& MIndex<Indices...>::at(const MetaType& metaPos)
{
iter<0,NI>( [&](auto i) { std::get<Is>(mIPack)->at( std::get<Is>(meta) ) }, NoF {} );
iter<0,NI>( [&](auto i) { std::get<i>(mIPack)->at( std::get<i>(metaPos) ); }, NoF {} );
IB::mPos = iter<0,NI>
( [&](auto i) { return std::get<i>(mIPack)*std::get<i>(mBlockSizes); },
( [&](auto i) { return std::get<i>(mIPack)->pos()*std::get<i>(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<i>(mIPack)*std::get<i>(mBlockSizes); },
( [&](auto i) { return std::get<i>(mIPack)->pos()*std::get<i>(mBlockSizes).val(); },
[](const auto&... xs) { return (xs + ...); });
return *this;
}
template <class... Indices>
const IndexPack& pack() const
const typename MIndex<Indices...>::IndexPack& MIndex<Indices...>::pack() const
{
return mIPack;
}
template <class... Indices>
const auto& blockSizes() const
const auto& MIndex<Indices...>::blockSizes() const
{
return mBlockSizes;
}
@ -298,14 +297,14 @@ namespace CNORXZ
template <class... Ranges>
void MRangeFactory<Ranges...>::make()
{
auto info = typeid(MRange<Ranges...>);
const auto& info = typeid(MRange<Ranges...>);
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<MRange<Ranges...>>
( new MRange<Ranges...>( mSpace ) );
if(mRef != nullptr) { key = mRef }
( new MRange<Ranges...>( mRs ) );
if(mRef != nullptr) { key = mRef; }
this->addToCreated(info, { key->id() }, mProd);
}
}
@ -317,7 +316,7 @@ namespace CNORXZ
template <class... Ranges>
MRange<Ranges...>::MRange(const Tuple<Sptr<Ranges>...>& rs) :
mRs(rs),
mA( mkA( std::make_index_sequence<NR>{} ) )
mA( mkA() )
{}
template <class... Ranges>
@ -330,7 +329,7 @@ namespace CNORXZ
template <class... Ranges>
SizeT MRange<Ranges...>::size() const
{
return iter<0,NR>( [&](auto i) { return std::get<i>(mRs)->size() },
return iter<0,NR>( [&](auto i) { return std::get<i>(mRs)->size(); },
[](const auto&... xs) { return (xs * ...); } );
}
@ -343,7 +342,19 @@ namespace CNORXZ
template <class... Ranges>
String MRange<Ranges...>::stringMeta(SizeT pos) const
{
return (begin()+pos).stringMeta();
return (this->begin()+pos).stringMeta();
}
template <class... Ranges>
const TypeInfo& MRange<Ranges...>::type() const
{
return typeid(MRange<Ranges...>);
}
template <class... Ranges>
const TypeInfo& MRange<Ranges...>::metaType() const
{
return typeid(MetaType);
}
template <class... Ranges>
@ -353,15 +364,15 @@ namespace CNORXZ
}
template <class... Ranges>
const MetaType MRange<Ranges...>::get(SizeT pos) const
const typename MRange<Ranges...>::MetaType MRange<Ranges...>::get(SizeT pos) const
{
return (begin()+pos)->meta();
return (this->begin()+pos)->meta();
}
template <class... Ranges>
SizeT MRange<Ranges...>::getMeta(const MetaType& metaPos) const
{
auto i = begin();
auto i = this->begin();
return i.at(metaPos).pos();
}
@ -372,8 +383,18 @@ namespace CNORXZ
template <class... Ranges>
decltype(auto) MRange<Ranges...>::mkA() const
{
return iter<0,NR>([&](auto i) { return std::get<Is>(mRs); },
[](const auto&... xs) { return Arr<RangePtr,NR> { xs... } } );
return iter<0,NR>([&](auto i) { return std::get<i>(mRs); },
[](const auto&... xs) { return Arr<RangePtr,NR> { xs... }; } );
}
/****************************
* non-member functions *
****************************/
template <class... Ranges>
RangePtr mrange(const Sptr<Ranges>&... rs)
{
return MRangeFactory<Ranges...>(std::make_tuple(rs...)).create();
}
}

View file

@ -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<RangeType> range() const;
template <SizeT I>
@ -67,16 +67,12 @@ namespace CNORXZ
const auto& blockSizes() const;
private:
IndexPack mIPack;
typedef decltype(mkBlockSizes(Isqr<0,NI-1>{})) BlockTuple;
BlockTuple mBlockSizes;
Sptr<RangeType> mRange;
template <SizeT... Is>
static constexpr decltype(auto) mkBlockSizes(const IndexPack& ipack, Isq<Is...> is);
template <SizeT... Is>
constexpr decltype(auto) mkIPack(SizeT pos, Isq<Is...> is) const;
constexpr decltype(auto) mkBlockSizes() const;
template <SizeT I>
inline void up();
@ -85,6 +81,11 @@ namespace CNORXZ
template <SizeT I, class Xpr, class F>
constexpr decltype(auto) mkIFor(const Xpr& xpr, F&& f) const;
IndexPack mIPack;
typedef RemoveRef<decltype(mkBlockSizes(mIPack,Isqr<0,NI-1>{}))> BlockTuple;
BlockTuple mBlockSizes;
Sptr<RangeType> mRange;
};
// modified blockSizes; to be used for Slices; can be created from MIndices
@ -123,8 +124,7 @@ namespace CNORXZ
};
template <class... Ranges>
class MRange : public RangeInterface<MIndex<typename Ranges::IndexType...>,
Tuple<typename Ranges::IndexType::MetaType...>>
class MRange : public RangeInterface<MRange<Ranges...>>
{
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 <class... Ranges>
RangePtr mrange(const Sptr<Ranges>&... rs);
}
#endif

View file

@ -4,25 +4,30 @@
#include "range_base.h"
#include "dindex.h"
#include "mrange.h"
namespace CNORXZ
{
template <class Index, typename Meta>
Index RangeInterface<Index,Meta>::begin() const
template <class Range>
decltype(auto) RangeInterface<Range>::begin() const
{
return Index(RangePtr(RB::mThis), 0);
typedef typename Range::IndexType IndexType;
return IndexType(RangePtr(RB::mThis), 0);
}
template <class Index, typename Meta>
Index RangeInterface<Index,Meta>::end() const
template <class Range>
decltype(auto) RangeInterface<Range>::end() const
{
return Index(RangePtr(RB::mThis), this->size());
typedef typename Range::IndexType IndexType;
return IndexType(RangePtr(RB::mThis), this->size());
}
template <class Index, typename Meta>
DIndex RangeInterface<Index,Meta>::index(SizeT pos) const
template <class Range>
DIndex RangeInterface<Range>::index(SizeT pos) const
{
return XIndexPtr(std::make_shared<XIndex<Index,Meta>>( this->begin()+pos ));
typedef typename Range::IndexType IndexType;
typedef typename IndexType::MetaType MetaType;
return XIndexPtr(std::make_shared<XIndex<IndexType,MetaType>>( this->begin()+pos ));
}
template <class Range>

View file

@ -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 <class Index, typename Meta>
template <class Range>
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 <class Range>
Sptr<Range> 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

View file

@ -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"

View file

@ -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"

View file

@ -172,7 +172,7 @@ namespace CNORXZ
template <typename MetaType>
URange<MetaType>::URange(const Vector<MetaType>& space) :
RangeInterface<URange<MetaType>,MetaType>(),
RangeInterface<URange<MetaType>>(),
mSpace(space)
{
std::sort(mSpace.begin(), mSpace.end(), std::less<MetaType>());
@ -182,7 +182,7 @@ namespace CNORXZ
template <typename MetaType>
URange<MetaType>::URange(Vector<MetaType>&& space) :
RangeInterface<UIndex<MetaType>,MetaType>(),
RangeInterface<URange<MetaType>>(),
mSpace(space)
{
std::sort(mSpace.begin(), mSpace.end(), std::less<MetaType>());

View file

@ -11,13 +11,14 @@
namespace CNORXZ
{
template <typename MetaType>
class UIndex : public IndexInterface<UIndex<MetaType>,MetaType>
template <typename MetaT>
class UIndex : public IndexInterface<UIndex<MetaT>,MetaT>
{
public:
typedef IndexInterface<UIndex<MetaType>,MetaType> IB;
typedef URange<MetaType> RangeType;
typedef IndexInterface<UIndex<MetaT>,MetaT> IB;
typedef URange<MetaT> 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<RangeType> range() const;
@ -41,15 +42,15 @@ namespace CNORXZ
UPos stepSize(const IndexId<I>& id) const;
String stringMeta() const;
const MetaType& meta() const;
UIndex& at(const MetaType& metaPos);
const MetaT& meta() const;
UIndex& at(const MetaT& metaPos);
template <class Xpr, class F>
decltype(auto) ifor(const Xpr& xpr, F&& f) const;
private:
Sptr<RangeType> mRangePtr;
const MetaType* mMetaPtr;
const MetaT* mMetaPtr;
};
template <typename MetaType>
@ -70,7 +71,7 @@ namespace CNORXZ
};
template <typename MetaType>
class URange : public RangeInterface<UIndex<MetaType>,MetaType>
class URange : public RangeInterface<URange<MetaType>>
{
public:
typedef RangeBase RB;

View file

@ -19,6 +19,7 @@ namespace CNORXZ
public:
typedef IndexInterface<YIndex,DType> 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<YIndex,DType>
class YRange : public RangeInterface<YRange>
{
public:
typedef RangeBase RB;

View file

@ -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

View file

@ -37,6 +37,21 @@ namespace
Vector<String> mMeta;
};
class MR_Test : public ::testing::Test
{
protected:
MR_Test()
{
mMeta = { "test", "strings", "foo" };
std::sort(mMeta.begin(), mMeta.end(), std::less<String>());
mSize = 7;
}
Vector<String> 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<CRange>(cr);
auto ur = URangeFactory<String>(mMeta).create();
auto urx = std::dynamic_pointer_cast<URange<String>>(ur);
auto mr = mrange(crx,urx);
auto mrx = std::dynamic_pointer_cast<MRange<CRange,URange<String>>>(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