intermediate commit; does not compile...

This commit is contained in:
Christian Zimmermann 2017-02-20 17:18:53 +01:00
parent 887547d5e1
commit 00c6cf49d5
8 changed files with 286 additions and 58 deletions

View file

@ -58,5 +58,18 @@ namespace MultiArrayTools
{ {
return mRange->size(); return mRange->size();
} }
template <typename T, class Range>
auto MultiArray<T,Range>::begin() -> decltype(Range().begin())
{
return mRange->begin();
}
template <typename T, class Range>
auto MultiArray<T,Range>::end() -> decltype(Range().end())
{
return mRange->end();
}
} }

View file

@ -32,6 +32,9 @@ namespace MultiArrayTools
const T& operator[](const typename Range::IndexType& i) const; const T& operator[](const typename Range::IndexType& i) const;
size_t size() const; size_t size() const;
auto begin() -> decltype(Range().begin());
auto end() -> decltype(Range().end());
private: private:
bool mInit = false; bool mInit = false;

View file

@ -19,7 +19,18 @@ namespace MultiArrayTools
return in.getIndex<N>(); return in.getIndex<N>();
} }
else { else {
return getIndex<N-1>(in, n); return IndexGetter<N-1>::getIndex(in, n);
}
}
template <class MultiIndex>
static const IndefinitIndexBase& getIndex(const MultiIndex& in, size_t n)
{
if(n == N){
return in.getIndex<N>();
}
else {
return IndexGetter<N-1>::getIndex(in, n);
} }
} }
}; };
@ -32,6 +43,12 @@ namespace MultiArrayTools
{ {
return in.getIndex<0>(); return in.getIndex<0>();
} }
template <class MultiIndex>
static const IndefinitIndexBase& getIndex(const MultiIndex& in, size_t n)
{
return in.getIndex<0>();
}
}; };
template <size_t N> template <size_t N>
@ -40,8 +57,8 @@ namespace MultiArrayTools
template <class MultiIndex> template <class MultiIndex>
static size_t evaluate(const MultiIndex& index) static size_t evaluate(const MultiIndex& index)
{ {
const auto& subIndex = index.getIndex<N>(0); //const auto& subIndex = index.getIndex<N>();
return Evaluation<N-1>::evaluate(index) * subIndex.size() + subIndex.pos(); return Evaluation<N-1>::evaluate(index) * index.getIndex<N>().size() + index.getIndex<N>().pos();
} }
}; };
@ -51,18 +68,18 @@ namespace MultiArrayTools
template <class MultiIndex> template <class MultiIndex>
static size_t evaluate(const MultiIndex& index) static size_t evaluate(const MultiIndex& index)
{ {
const auto& subIndex = index.getIndex<0>(0); //const auto& subIndex = index.getIndex<0>();
return subIndex.pos(); return index.getIndex<0>().pos();
} }
}; };
template <class MultiIndex> template <class MultiIndex>
inline void plus(MultiIndex& index, size_t digit, int num) inline void plus(MultiIndex& index, size_t digit, int num)
{ {
IndefinitIndexBase& si = index.getIndex(digit); IndefinitIndexBase& si = index.get(digit);
si.setPos( si.pos() + num ); si.setPos( si.pos() + num );
size_t oor = si.outOfRange(); size_t oor = si.outOfRange();
if(oor and digit != MultiIndex::mult - 1){ if(oor and digit != index.dim() - 1){
plus(index, digit + 1, 1); plus(index, digit + 1, 1);
plus(index, digit, oor - si.max()); plus(index, digit, oor - si.max());
} }
@ -75,7 +92,7 @@ namespace MultiArrayTools
static void nameTuple(IndexPack& iPack, Name& name) static void nameTuple(IndexPack& iPack, Name& name)
{ {
std::get<N>(iPack).name(name.get(N)); std::get<N>(iPack).name(name.get(N));
nameTuple<N-1>(iPack, name); TupleNamer<N-1>::nameTuple(iPack, name);
} }
}; };
@ -91,12 +108,22 @@ namespace MultiArrayTools
} }
template <class... Indices> template <class... Indices>
MultiIndex<Indices...>::MultiIndex(Indices&&... inds) : mIPack(std::make_tuple(inds...)) {} MultiIndex<Indices...>::MultiIndex(Indices&&... inds) : mIPack(std::make_tuple(inds...))
{
IIB::mPos = evaluate(*this);
}
template <class... Indices>
MultiIndex<Indices...>::MultiIndex(const IndexPack& ipack) : mIPack(ipack)
{
IIB::mPos = evaluate(*this);
}
template <class... Indices> template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator++() MultiIndex<Indices...>& MultiIndex<Indices...>::operator++()
{ {
setPos( IIB::pos() + 1 ); IIB::setPos( IIB::pos() + 1 );
plus(*this, 0, 1); plus(*this, 0, 1);
return *this; return *this;
} }
@ -104,7 +131,7 @@ namespace MultiArrayTools
template <class... Indices> template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator--() MultiIndex<Indices...>& MultiIndex<Indices...>::operator--()
{ {
setPos( IIB::pos() - 1 ); IIB::setPos( IIB::pos() - 1 );
plus(*this, 0, -1); plus(*this, 0, -1);
return *this; return *this;
} }
@ -112,7 +139,7 @@ namespace MultiArrayTools
template <class... Indices> template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator+=(int n) MultiIndex<Indices...>& MultiIndex<Indices...>::operator+=(int n)
{ {
setPos( IIB::pos() + n ); IIB::setPos( IIB::pos() + n );
plus(*this, 0, n); plus(*this, 0, n);
return *this; return *this;
} }
@ -120,10 +147,24 @@ namespace MultiArrayTools
template <class... Indices> template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator-=(int n) MultiIndex<Indices...>& MultiIndex<Indices...>::operator-=(int n)
{ {
setPos( IIB::pos() - n ); IIB::setPos( IIB::pos() - n );
plus(*this, 0, 0-n); plus(*this, 0, 0-n);
return *this; return *this;
} }
template <class... Indices>
IndefinitIndexBase& MultiIndex<Indices...>::operator=(size_t pos)
{
IIB::setPos( pos );
setIndexPack(mIPack, pos); // -> implement !!!
return *this;
}
template <class... Indices>
MultiRangeType MultiIndex<Indices...>::rangeType() const
{
return IB::mRange->type();
}
template <class... Indices> template <class... Indices>
size_t MultiIndex<Indices...>::evaluate(const MultiIndex<Indices...>& in) const size_t MultiIndex<Indices...>::evaluate(const MultiIndex<Indices...>& in) const
@ -144,13 +185,21 @@ namespace MultiArrayTools
TupleNamer<sizeof...(Indices)-1>::nameTuple(mIPack, nm); TupleNamer<sizeof...(Indices)-1>::nameTuple(mIPack, nm);
} }
} }
template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator()(Indices&&... inds)
{
mIPack = std::make_tuple(inds...);
IIB::mPos = evaluate(*this);
return *this;
}
template <class... Indices> template <class... Indices>
size_t MultiIndex<Indices...>::dim() const size_t MultiIndex<Indices...>::dim() const
{ {
size_t res = 1; size_t res = 1;
for(size_t i = 0; i != sizeof...(Indices); ++i){ for(size_t i = 0; i != sizeof...(Indices); ++i){
res *= getIndex(i).dim(); res *= get(i).dim();
} }
return res; return res;
} }
@ -158,11 +207,11 @@ namespace MultiArrayTools
template <class... Indices> template <class... Indices>
bool MultiIndex<Indices...>::link(IndefinitIndexBase* toLink) bool MultiIndex<Indices...>::link(IndefinitIndexBase* toLink)
{ {
if(toLink->rangeType() != IIB::rangeType() and toLink->name() == name()){ if(toLink->rangeType() != IIB::rangeType() and toLink->name() == IIB::name()){
// throw !! // throw !!
} }
if(toLink->rangeType() == IIB::rangeType() and toLink->name() == name()){ if(toLink->rangeType() == IIB::rangeType() and toLink->name() == IIB::name()){
if(IIB::mLinked == toLink){ if(IIB::mLinked == toLink){
return true; // dont link twice the same return true; // dont link twice the same
} }
@ -181,15 +230,15 @@ namespace MultiArrayTools
template <class... Indices> template <class... Indices>
template <size_t N> template <size_t N>
auto MultiIndex<Indices...>::getIndex(size_t x) -> decltype(std::get<N>(MultiIndex<Indices...>::IndexPack())) auto MultiIndex<Indices...>::getIndex() -> decltype(std::get<N>(mIPack))&
{ {
return std::get<N>(mIPack); return std::get<N>(mIPack);
} }
template <class... Indices> template <class... Indices>
template <size_t N> template <size_t N>
auto MultiIndex<Indices...>::getIndex(size_t x) const -> auto MultiIndex<Indices...>::getIndex() const ->
decltype(std::get<N>(MultiIndex<Indices...>::IndexPack())) const decltype(std::get<N>(mIPack))&
{ {
return std::get<N>(mIPack); return std::get<N>(mIPack);
} }
@ -201,7 +250,7 @@ namespace MultiArrayTools
// throw !! // throw !!
} }
MultiIndex<Indices...>* t = this; MultiIndex<Indices...>* t = this;
return IndexGetter<sizeof...(Indices)>::getIndex(*t, n); return IndexGetter<sizeof...(Indices)-1>::getIndex(*t, n);
} }
template <class... Indices> template <class... Indices>
@ -210,8 +259,8 @@ namespace MultiArrayTools
if(n >= sizeof...(Indices)){ if(n >= sizeof...(Indices)){
// throw !! // throw !!
} }
MultiIndex<Indices...>* t = this; MultiIndex<Indices...> const* t = this;
return IndexGetter<sizeof...(Indices)>::getIndex(*t, n); return IndexGetter<sizeof...(Indices)-1>::getIndex(*t, n);
} }
template <class... Indices> template <class... Indices>
@ -219,7 +268,7 @@ namespace MultiArrayTools
{ {
bool res = false; bool res = false;
for(size_t i = 0; i != sizeof...(Indices); ++i){ for(size_t i = 0; i != sizeof...(Indices); ++i){
res |= getIndex(i).link(toLink); res |= get(i).link(toLink);
} }
return res; return res;
} }
@ -229,7 +278,7 @@ namespace MultiArrayTools
{ {
target->link(this); target->link(this);
for(size_t i = 0; i != sizeof...(Indices); ++i){ for(size_t i = 0; i != sizeof...(Indices); ++i){
getIndex(i).linkTo(target); get(i).linkTo(target);
} }
} }
@ -237,29 +286,124 @@ namespace MultiArrayTools
* MultiRange * * MultiRange *
******************/ ******************/
template <class... Ranges>
MultiRange<Ranges...>::MultiRange(const Ranges&... rs) : mSpace(std::make_tuple(rs...)) {}
template <class... Ranges> template <class... Ranges>
template <size_t N> template <size_t N>
auto MultiRange<Ranges...>::get() -> decltype( std::get<N>(MultiRange<Ranges...>::SpaceType()) ) auto MultiRange<Ranges...>::getRange() -> decltype( std::get<N>(MultiRange<Ranges...>::SpaceType()) )
{ {
return std::get<N>(mSpace); return std::get<N>(mSpace);
} }
template <class... Ranges> template <class... Ranges>
template <size_t N> template <size_t N>
auto MultiRange<Ranges...>::get() const -> decltype( std::get<N>(MultiRange<Ranges...>::SpaceType()) ) auto MultiRange<Ranges...>::getRange() const -> decltype( std::get<N>(MultiRange<Ranges...>::SpaceType()) )
{ {
return std::get<N>(mSpace); return std::get<N>(mSpace);
} }
template <size_t N>
struct TupleSize
{
template <class RangeTuple>
static size_t getSize(const RangeTuple& rt)
{
return std::get<N>(rt).size() * TupleSize<N-1>::getSize(rt);
}
};
template <>
struct TupleSize<0>
{
template <class RangeTuple>
static size_t getSize(const RangeTuple& rt)
{
return std::get<0>(rt).size();
}
};
template <class... Ranges>
size_t MultiRange<Ranges...>::size() const
{
return TupleSize<sizeof...(Ranges)-1>::getSize(mSpace);
}
template <size_t N>
struct IndexSetter
{
template <class... Ranges>
static void setBegin(std::tuple<typename Ranges::IndexType...>& i, const std::tuple<Ranges...>& r)
{
std::get<N>(i) = std::get<N>(r).begin();
IndexSetter<N-1>::setBegin(i,r);
}
template <class... Ranges>
static void setEnd(std::tuple<typename Ranges::IndexType...>& i, const std::tuple<Ranges...>& r)
{
std::get<N>(i) = std::get<N>(r).end();
IndexSetter<N-1>::setEnd(i,r);
}
};
template <>
struct IndexSetter<0>
{
template <class... Ranges>
static void setBegin(std::tuple<typename Ranges::IndexType...>& i, const std::tuple<Ranges...>& r)
{
std::get<0>(i) = std::get<0>(r).begin();
}
template <class... Ranges>
static void setEnd(std::tuple<typename Ranges::IndexType...>& i, const std::tuple<Ranges...>& r)
{
std::get<0>(i) = std::get<0>(r).end();
}
};
template <size_t N>
struct RangeVecBuilder
{
template <class... Ranges>
static void buildRangeVec(std::vector<MultiRangeType>& rvec, const std::tuple<Ranges...>& rs)
{
rvec.push_back(std::get<sizeof...(Ranges)-N-1>(rs).type());
RangeVecBuilder<N-1>::buildRangeVec(rvec, rs);
}
};
template <>
struct RangeVecBuilder<0>
{
template <class... Ranges>
static void buildRangeVec(std::vector<MultiRangeType>& rvec, const std::tuple<Ranges...>& rs)
{
rvec.push_back(std::get<sizeof...(Ranges)-1>(rs).type());
}
};
template <class... Ranges>
MultiRangeType MultiRange<Ranges...>::type() const
{
std::vector<MultiRangeType> rvec;
RangeVecBuilder<sizeof...(Ranges)-1>::buildRangeVec(rvec, mSpace);
return MultiRangeType(rvec);
}
template <class... Ranges> template <class... Ranges>
MultiIndex<typename Ranges::IndexType...> MultiRange<Ranges...>::begin() const MultiIndex<typename Ranges::IndexType...> MultiRange<Ranges...>::begin() const
{ {
return MultiIndex<typename Ranges::IndexType...>(/*!!!!!!*/); std::tuple<typename Ranges::IndexType...> is;
IndexSetter<sizeof...(Ranges)-1>::setBegin(is,mSpace);
return MultiIndex<typename Ranges::IndexType...>(is);
} }
template <class... Ranges> template <class... Ranges>
MultiIndex<typename Ranges::IndexType...> MultiRange<Ranges...>::end() const MultiIndex<typename Ranges::IndexType...> MultiRange<Ranges...>::end() const
{ {
return MultiIndex<typename Ranges::IndexType...>(/*!!!!!!*/); std::tuple<typename Ranges::IndexType...> is;
IndexSetter<sizeof...(Ranges)-1>::setEnd(is,mSpace);
return MultiIndex<typename Ranges::IndexType...>(is);
} }
} }

View file

@ -17,35 +17,9 @@ namespace MultiArrayTools
class MultiIndex : public IndexBase<MultiIndex<Indices...> > class MultiIndex : public IndexBase<MultiIndex<Indices...> >
{ {
public: public:
DEFAULT_MEMBERS(MultiIndex);
MultiIndex(Indices&&... inds);
typedef std::tuple<Indices...> IndexPack; typedef std::tuple<Indices...> IndexPack;
typedef IndefinitIndexBase IIB; typedef IndefinitIndexBase IIB;
typedef IndexBase<MultiIndex<Indices...> > IB;
virtual MultiIndex& operator++() override;
virtual MultiIndex& operator--() override;
virtual MultiIndex& operator+=(int n) override;
virtual MultiIndex& operator-=(int n) override;
template <size_t N>
auto getIndex(size_t x) -> decltype(std::get<N>(IndexPack()));
template <size_t N>
auto getIndex(size_t x) const -> decltype(std::get<N>(IndexPack()));
IndefinitIndexBase& get(size_t n);
const IndefinitIndexBase& get(size_t n) const;
virtual void name(const Name& nm) override;
// dimension of MultiRange; includes ALL degrees of freedom
virtual size_t dim() const override;
virtual bool link(IndefinitIndexBase* toLink) override;
virtual void linkTo(IndefinitIndexBase* target) override;
protected: protected:
@ -53,6 +27,40 @@ namespace MultiArrayTools
virtual size_t evaluate(const MultiIndex& in) const override; virtual size_t evaluate(const MultiIndex& in) const override;
IndexPack mIPack; IndexPack mIPack;
public:
DEFAULT_MEMBERS(MultiIndex);
MultiIndex(Indices&&... inds);
MultiIndex(const IndexPack& ipack);
virtual MultiIndex& operator++() override;
virtual MultiIndex& operator--() override;
virtual MultiIndex& operator+=(int n) override;
virtual MultiIndex& operator-=(int n) override;
virtual IIB& operator=(size_t pos) override;
virtual MultiRangeType rangeType() const override;
template <size_t N>
auto getIndex() -> decltype(std::get<N>(mIPack))&;
template <size_t N>
auto getIndex() const -> const decltype(std::get<N>(mIPack))&;
IndefinitIndexBase& get(size_t n);
const IndefinitIndexBase& get(size_t n) const;
MultiIndex& operator()(Indices&&... inds);
virtual void name(const Name& nm) override;
// dimension of MultiRange; includes ALL degrees of freedom
virtual size_t dim() const override;
virtual bool link(IndefinitIndexBase* toLink) override;
virtual void linkTo(IndefinitIndexBase* target) override;
}; };
template <class... Ranges> template <class... Ranges>
@ -63,14 +71,20 @@ namespace MultiArrayTools
typedef std::tuple<Ranges...> SpaceType; typedef std::tuple<Ranges...> SpaceType;
DEFAULT_MEMBERS(MultiRange); DEFAULT_MEMBERS(MultiRange);
MultiRange(const Ranges&... rs);
static const size_t dim = sizeof...(Ranges); static const size_t dim = sizeof...(Ranges);
template <size_t N> template <size_t N>
auto get() -> decltype( std::get<N>(SpaceType()) ); auto getRange() -> decltype( std::get<N>(SpaceType()) );
template <size_t N> template <size_t N>
auto get() const -> decltype( std::get<N>(SpaceType()) ); auto getRange() const -> decltype( std::get<N>(SpaceType()) );
size_t size() const override;
virtual MultiRangeType type() const override;
virtual MultiIndex<typename Ranges::IndexType...> begin() const override; virtual MultiIndex<typename Ranges::IndexType...> begin() const override;
virtual MultiIndex<typename Ranges::IndexType...> end() const override; virtual MultiIndex<typename Ranges::IndexType...> end() const override;

View file

@ -63,7 +63,8 @@ namespace MultiArrayTools
virtual Index end() const = 0; virtual Index end() const = 0;
virtual RangeBase<Index>* base(); virtual RangeBase<Index>* base();
virtual bool isSubRange() const; virtual bool isSubRange() const;
virtual MultiRangeType type() const = 0;
protected: protected:
DEFAULT_MEMBERS(RangeBase); DEFAULT_MEMBERS(RangeBase);

View file

@ -36,6 +36,12 @@ namespace MultiArrayTools
return mSpace.size(); return mSpace.size();
} }
template <typename U, RangeType TYPE>
MultiRangeType SingleRange<U,TYPE>::type() const
{
return MultiRangeType(TYPE);
}
template <typename U, RangeType TYPE> template <typename U, RangeType TYPE>
SingleIndex<U,TYPE> SingleRange<U,TYPE>::begin() const SingleIndex<U,TYPE> SingleRange<U,TYPE>::begin() const
{ {

View file

@ -62,6 +62,8 @@ namespace MultiArrayTools
const U& get(size_t pos) const; const U& get(size_t pos) const;
size_t get(const U& metaPos) const; size_t get(const U& metaPos) const;
virtual MultiRangeType type() const override;
SingleIndex<U,TYPE> begin() const override; SingleIndex<U,TYPE> begin() const override;
SingleIndex<U,TYPE> end() const override; SingleIndex<U,TYPE> end() const override;

View file

@ -26,6 +26,28 @@ namespace {
}; };
class TwoDimTest : public ::testing::Test
{
protected:
typedef MAT::SingleRange<char,MAT::RangeType::ANY> Range1dAny;
typedef MAT::MultiRange<Range1dAny,Range1dAny> Range2dAny;
typedef MAT::MultiArray<int,Range2dAny> MultiArray2dAny;
TwoDimTest() : r1({'a','b','c'}),
r2({'a','b','c','d'}),
r(r1,r2),
ma(r, {-5,6,2,1,9,54,27,-7,-13,32,90,-67}) {}
//virtual void SetUp();
Range1dAny r1;
Range1dAny r2;
Range2dAny r;
MultiArray2dAny ma;
};
TEST_F(OneDimTest, CorrectExtensions) TEST_F(OneDimTest, CorrectExtensions)
{ {
EXPECT_EQ(ma.size(), 5); EXPECT_EQ(ma.size(), 5);
@ -39,6 +61,29 @@ namespace {
EXPECT_EQ(ma[3], 1); EXPECT_EQ(ma[3], 1);
EXPECT_EQ(ma[4], 9); EXPECT_EQ(ma[4], 9);
} }
TEST_F(TwoDimTest, CorrectExtensions)
{
EXPECT_EQ(ma.size(), 12);
}
TEST_F(TwoDimTest, CorrectAssigned)
{
auto i = ma.begin();
EXPECT_EQ(ma[i(0,0)], -5);
EXPECT_EQ(ma[i(0,1)], 6);
EXPECT_EQ(ma[i(0,2)], 2);
EXPECT_EQ(ma[i(0,3)], 1);
EXPECT_EQ(ma[i(1,0)], 9);
EXPECT_EQ(ma[i(1,1)], 54);
EXPECT_EQ(ma[i(1,2)], 27);
EXPECT_EQ(ma[i(1,3)], -7);
EXPECT_EQ(ma[i(2,0)], -13);
EXPECT_EQ(ma[i(2,1)], 32);
EXPECT_EQ(ma[i(2,2)], 90);
EXPECT_EQ(ma[i(2,3)], -67);
}
} // end namespace } // end namespace