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

@ -59,4 +59,17 @@ namespace MultiArrayTools
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

@ -33,6 +33,9 @@ namespace MultiArrayTools
size_t size() const;
auto begin() -> decltype(Range().begin());
auto end() -> decltype(Range().end());
private:
bool mInit = false;
std::shared_ptr<Range> mRange;

View file

@ -19,7 +19,18 @@ namespace MultiArrayTools
return in.getIndex<N>();
}
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>();
}
template <class MultiIndex>
static const IndefinitIndexBase& getIndex(const MultiIndex& in, size_t n)
{
return in.getIndex<0>();
}
};
template <size_t N>
@ -40,8 +57,8 @@ namespace MultiArrayTools
template <class MultiIndex>
static size_t evaluate(const MultiIndex& index)
{
const auto& subIndex = index.getIndex<N>(0);
return Evaluation<N-1>::evaluate(index) * subIndex.size() + subIndex.pos();
//const auto& subIndex = index.getIndex<N>();
return Evaluation<N-1>::evaluate(index) * index.getIndex<N>().size() + index.getIndex<N>().pos();
}
};
@ -51,18 +68,18 @@ namespace MultiArrayTools
template <class MultiIndex>
static size_t evaluate(const MultiIndex& index)
{
const auto& subIndex = index.getIndex<0>(0);
return subIndex.pos();
//const auto& subIndex = index.getIndex<0>();
return index.getIndex<0>().pos();
}
};
template <class MultiIndex>
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 );
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, oor - si.max());
}
@ -75,7 +92,7 @@ namespace MultiArrayTools
static void nameTuple(IndexPack& iPack, Name& name)
{
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>
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>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator++()
{
setPos( IIB::pos() + 1 );
IIB::setPos( IIB::pos() + 1 );
plus(*this, 0, 1);
return *this;
}
@ -104,7 +131,7 @@ namespace MultiArrayTools
template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator--()
{
setPos( IIB::pos() - 1 );
IIB::setPos( IIB::pos() - 1 );
plus(*this, 0, -1);
return *this;
}
@ -112,7 +139,7 @@ namespace MultiArrayTools
template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator+=(int n)
{
setPos( IIB::pos() + n );
IIB::setPos( IIB::pos() + n );
plus(*this, 0, n);
return *this;
}
@ -120,11 +147,25 @@ namespace MultiArrayTools
template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator-=(int n)
{
setPos( IIB::pos() - n );
IIB::setPos( IIB::pos() - n );
plus(*this, 0, 0-n);
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>
size_t MultiIndex<Indices...>::evaluate(const MultiIndex<Indices...>& in) const
{
@ -145,12 +186,20 @@ namespace MultiArrayTools
}
}
template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator()(Indices&&... inds)
{
mIPack = std::make_tuple(inds...);
IIB::mPos = evaluate(*this);
return *this;
}
template <class... Indices>
size_t MultiIndex<Indices...>::dim() const
{
size_t res = 1;
for(size_t i = 0; i != sizeof...(Indices); ++i){
res *= getIndex(i).dim();
res *= get(i).dim();
}
return res;
}
@ -158,11 +207,11 @@ namespace MultiArrayTools
template <class... Indices>
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 !!
}
if(toLink->rangeType() == IIB::rangeType() and toLink->name() == name()){
if(toLink->rangeType() == IIB::rangeType() and toLink->name() == IIB::name()){
if(IIB::mLinked == toLink){
return true; // dont link twice the same
}
@ -181,15 +230,15 @@ namespace MultiArrayTools
template <class... Indices>
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);
}
template <class... Indices>
template <size_t N>
auto MultiIndex<Indices...>::getIndex(size_t x) const ->
decltype(std::get<N>(MultiIndex<Indices...>::IndexPack()))
auto MultiIndex<Indices...>::getIndex() const ->
const decltype(std::get<N>(mIPack))&
{
return std::get<N>(mIPack);
}
@ -201,7 +250,7 @@ namespace MultiArrayTools
// throw !!
}
MultiIndex<Indices...>* t = this;
return IndexGetter<sizeof...(Indices)>::getIndex(*t, n);
return IndexGetter<sizeof...(Indices)-1>::getIndex(*t, n);
}
template <class... Indices>
@ -210,8 +259,8 @@ namespace MultiArrayTools
if(n >= sizeof...(Indices)){
// throw !!
}
MultiIndex<Indices...>* t = this;
return IndexGetter<sizeof...(Indices)>::getIndex(*t, n);
MultiIndex<Indices...> const* t = this;
return IndexGetter<sizeof...(Indices)-1>::getIndex(*t, n);
}
template <class... Indices>
@ -219,7 +268,7 @@ namespace MultiArrayTools
{
bool res = false;
for(size_t i = 0; i != sizeof...(Indices); ++i){
res |= getIndex(i).link(toLink);
res |= get(i).link(toLink);
}
return res;
}
@ -229,7 +278,7 @@ namespace MultiArrayTools
{
target->link(this);
for(size_t i = 0; i != sizeof...(Indices); ++i){
getIndex(i).linkTo(target);
get(i).linkTo(target);
}
}
@ -237,29 +286,124 @@ namespace MultiArrayTools
* MultiRange *
******************/
template <class... Ranges>
MultiRange<Ranges...>::MultiRange(const Ranges&... rs) : mSpace(std::make_tuple(rs...)) {}
template <class... Ranges>
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);
}
template <class... Ranges>
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);
}
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>
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>
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

@ -16,29 +16,44 @@ namespace MultiArrayTools
template <class... Indices>
class MultiIndex : public IndexBase<MultiIndex<Indices...> >
{
public:
typedef std::tuple<Indices...> IndexPack;
typedef IndefinitIndexBase IIB;
typedef IndexBase<MultiIndex<Indices...> > IB;
protected:
virtual bool linkLower(IndefinitIndexBase* toLink);
virtual size_t evaluate(const MultiIndex& in) const override;
IndexPack mIPack;
public:
DEFAULT_MEMBERS(MultiIndex);
MultiIndex(Indices&&... inds);
typedef std::tuple<Indices...> IndexPack;
typedef IndefinitIndexBase IIB;
MultiIndex(const IndexPack& ipack);
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()));
virtual IIB& operator=(size_t pos) override;
virtual MultiRangeType rangeType() const override;
template <size_t N>
auto getIndex(size_t x) const -> decltype(std::get<N>(IndexPack()));
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
@ -46,13 +61,6 @@ namespace MultiArrayTools
virtual bool link(IndefinitIndexBase* toLink) override;
virtual void linkTo(IndefinitIndexBase* target) override;
protected:
virtual bool linkLower(IndefinitIndexBase* toLink);
virtual size_t evaluate(const MultiIndex& in) const override;
IndexPack mIPack;
};
template <class... Ranges>
@ -63,14 +71,20 @@ namespace MultiArrayTools
typedef std::tuple<Ranges...> SpaceType;
DEFAULT_MEMBERS(MultiRange);
MultiRange(const Ranges&... rs);
static const size_t dim = sizeof...(Ranges);
template <size_t N>
auto get() -> decltype( std::get<N>(SpaceType()) );
auto getRange() -> decltype( std::get<N>(SpaceType()) );
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...> end() const override;

View file

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

View file

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

View file

@ -62,6 +62,8 @@ namespace MultiArrayTools
const U& get(size_t pos) const;
size_t get(const U& metaPos) const;
virtual MultiRangeType type() const override;
SingleIndex<U,TYPE> begin() 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)
{
EXPECT_EQ(ma.size(), 5);
@ -40,6 +62,29 @@ namespace {
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
int main(int argc, char** argv)