first operation test works -- yaygit add * there are some memory issues (deletion of index ptr)

This commit is contained in:
Christian Zimmermann 2017-02-22 19:06:23 +01:00
parent b3f7dad655
commit db4ad28f02
8 changed files with 226 additions and 45 deletions

View file

@ -7,6 +7,14 @@ namespace MultiArrayTools
* IndefinitIndexBase *
************************/
IndefinitIndexBase::~IndefinitIndexBase()
{
freeLinked();
mLinked = nullptr;
mMajor = nullptr;
mSoftLinked = nullptr;
}
size_t IndefinitIndexBase::pos() const
{
return mPos;
@ -30,9 +38,9 @@ namespace MultiArrayTools
bool IndefinitIndexBase::link(IndefinitIndexBase* toLink)
{
if(toLink->rangeType() != rangeType() and toLink->name() == name()){
assert(0);
// throw !!
}
if(toLink->rangeType() == rangeType() and toLink->name() == name()){
if(mLinked == toLink){
return true; // dont link twice the same
@ -52,10 +60,14 @@ namespace MultiArrayTools
void IndefinitIndexBase::freeLinked()
{
if(linked()){
if(mLinked != nullptr){
mLinked->freeLinked();
mLinked = nullptr;
}
if(mSoftLinked != nullptr){
mSoftLinked->freeLinked();
mSoftLinked = nullptr;
}
}
bool IndefinitIndexBase::linked() const
@ -66,11 +78,9 @@ namespace MultiArrayTools
void IndefinitIndexBase::setPos(size_t pos)
{
mPos = pos;
//VCHECK(mName);
if(linked()){
mLinked->setPos(pos);
mLinked->evalMajor();
//VCHECK(mLinked->name());
}
}

View file

@ -18,7 +18,7 @@ namespace MultiArrayTools
{
public:
DEFAULT_MEMBERS(IndefinitIndexBase);
virtual ~IndefinitIndexBase() {}
virtual ~IndefinitIndexBase();
virtual IndefinitIndexBase& operator=(size_t pos) = 0;
virtual IndefinitIndexBase& operator++() = 0;
@ -64,6 +64,7 @@ namespace MultiArrayTools
IndefinitIndexBase* mLinked = nullptr;
IndefinitIndexBase* mMajor = nullptr;
IndefinitIndexBase* mSoftLinked = nullptr;
};
template <class Index>

View file

@ -11,7 +11,8 @@ namespace MultiArrayTools
MultiArrayOperationBase<T,Range>::
MultiArrayOperationBase(MultiArray<T,Range>& ma,
const Name& nm) : mArrayRef(ma),
mIibPtr(new IndexType(mArrayRef.begin()))
mIibPtr(new IndexType(mArrayRef.begin())),
mNm(nm)
{
mIibPtr->name(nm);
}
@ -19,7 +20,7 @@ namespace MultiArrayTools
template <typename T, class Range>
MultiArrayOperationBase<T,Range>::~MultiArrayOperationBase()
{
delete mIibPtr;
//delete mIibPtr;
}
template <typename T, class Range>
@ -30,11 +31,9 @@ namespace MultiArrayTools
IndexType& iref = dynamic_cast<IndexType&>(*mIibPtr);
for(iref = mArrayRef.begin().pos(); iref != mArrayRef.end(); ++iref){
// build in vectorization later
//VCHECK(iref.pos());
//VCHECK(in.mIibPtr->pos());
//VCHECK(in.get());
get() = in.get();
}
mIibPtr->freeLinked();
return *this;
}
@ -43,21 +42,62 @@ namespace MultiArrayTools
MultiArrayOperationBase<T,Range>&
MultiArrayOperationBase<T,Range>::operator=(const MultiArrayOperationBase<T, Range2>& in)
{
//CHECK;
in.linkIndicesTo(mIibPtr);
for(*mIibPtr = mArrayRef.begin(); *mIibPtr != mArrayRef.end(); ++(*mIibPtr)){
// build in vectorization later
get() = in.get();
}
mIibPtr->freeLinked();
return *this;
}
template <typename T, class Range>
template <class Operation, class... Ranges>
MultiArrayOperation<T,Range,Operation,Ranges...>
MultiArrayOperationBase<T,Range>::operator()(Operation& op, MultiArrayOperationBase<T,Ranges>&... secs)
MultiArrayOperationBase<T,Range>::operator()(Operation& op, const MultiArrayOperationBase<T,Ranges>&... secs)
{
return MultiArrayOperation<T,Range,Operation,Ranges...>(op, secs...);
return MultiArrayOperation<T,Range,Operation,Ranges...>(mArrayRef, mNm, op, secs...);
}
template <typename T, class Range>
template <class Operation, class... Ranges>
MultiArrayOperation<T,Range,Operation,Ranges...>
MultiArrayOperationBase<T,Range>::operator()(const Operation& op,
const MultiArrayOperationBase<T,Ranges>&... secs)
{
return MultiArrayOperation<T,Range,Operation,Ranges...>(mArrayRef, mNm, op, secs...);
}
template <typename T, class Range>
template <class Range2>
MultiArrayOperation<T,Range,std::plus<T>,Range2>
MultiArrayOperationBase<T,Range>::operator+(const MultiArrayOperationBase<T,Range2>& sec)
{
return operator()(std::plus<T>(), sec);
}
template <typename T, class Range>
template <class Range2>
MultiArrayOperation<T,Range,std::minus<T>,Range2>
MultiArrayOperationBase<T,Range>::operator-(const MultiArrayOperationBase<T,Range2>& sec)
{
return operator()(std::minus<T>(), sec);
}
template <typename T, class Range>
template <class Range2>
MultiArrayOperation<T,Range,std::multiplies<T>,Range2>
MultiArrayOperationBase<T,Range>::operator*(const MultiArrayOperationBase<T,Range2>& sec)
{
return operator()(std::multiplies<T>(), sec);
}
template <typename T, class Range>
template <class Range2>
MultiArrayOperation<T,Range,std::divides<T>,Range2>
MultiArrayOperationBase<T,Range>::operator/(const MultiArrayOperationBase<T,Range2>& sec)
{
return operator()(std::divides<T>(), sec);
}
template <typename T, class Range>
@ -112,7 +152,7 @@ namespace MultiArrayTools
template <class IndexTuple>
static void linkTupleIndicesTo(IndexTuple& itp, IndefinitIndexBase* target)
{
std::get<N>(itp).linkTo(target);
std::get<N>(itp).linkIndicesTo(target);
linkTupleIndicesTo<N-1>(itp, target);
}
};
@ -123,30 +163,63 @@ namespace MultiArrayTools
template <class IndexTuple>
static void linkTupleIndicesTo(IndexTuple& itp, IndefinitIndexBase* target)
{
std::get<0>(itp).linkTo(target);
std::get<0>(itp).linkIndicesTo(target);
}
};
template <size_t N>
struct OperationCall
{
template <class Operation, class Tuple, class... MBases>
auto callOperation(Operation& op, Tuple& tp, MBases&... secs)
-> decltype(callOperation(op, tp, std::get<N-1>(tp), secs...))
{
template <typename T, class Operation, class Tuple, class... MBases>
static auto callOperation(Operation& op, const Tuple& tp, const T& first, const MBases&... secs)
-> decltype(OperationCall<N-1>::template callOperation(op, tp, std::get<N>(tp), secs...))
{
return callOperation(op, tp, std::get<N-1>(tp), secs...);
return OperationCall<N-1>::template callOperation(op, tp, first, std::get<N>(tp), secs...);
}
template <typename T, class Operation, class Tuple, class... MBases>
static auto callOperation(const Operation& op, const Tuple& tp, const T& first, const MBases&... secs)
-> decltype(OperationCall<N-1>::template callOperation(op, tp, std::get<N>(tp), secs...))
{
return OperationCall<N-1>::template callOperation(op, tp, first, std::get<N>(tp), secs...);
}
};
template <>
struct OperationCall<0>
{
template <class Operation, class Tuple, class... MBases>
auto callOperation(Operation& op, Tuple& tp, MBases&... secs) -> decltype(op(secs.get()...))
{
template <typename T, class Operation, class Tuple, class... MBases>
static auto callOperation(Operation& op, const Tuple& tp, const T& first, const MBases&... secs)
-> decltype(op(first, std::get<0>(tp).get(), secs.get()...))
{
return op(secs.get()...);
return op(first, std::get<0>(tp).get(), secs.get()...);
}
template <typename T, class Operation, class Tuple, class... MBases>
static auto callOperation(const Operation& op, const Tuple& tp, const T& first, const MBases&... secs)
-> decltype(op(first.get(), std::get<0>(tp).get(), secs.get()...))
{
return op(first, std::get<0>(tp).get(), secs.get()...);
}
};
template <typename T, class Range, class Operation, class... Ranges>
MultiArrayOperation<T,Range,Operation,Ranges...>::
MultiArrayOperation(MultiArray<T,Range>& ma, const Name& nm,
Operation& op,
const MultiArrayOperationBase<T,Ranges>&... secs) :
MultiArrayOperationBase<T,Range>(ma, nm),
mOp(op),
mSecs(std::make_tuple(secs...)) {}
template <typename T, class Range, class Operation, class... Ranges>
MultiArrayOperation<T,Range,Operation,Ranges...>::
MultiArrayOperation(MultiArray<T,Range>& ma, const Name& nm,
const Operation& op,
const MultiArrayOperationBase<T,Ranges>&... secs) :
MultiArrayOperationBase<T,Range>(ma, nm),
mOp(op),
mSecs(std::make_tuple(secs...)) {}
template <typename T, class Range, class Operation, class... Ranges>
size_t MultiArrayOperation<T,Range,Operation,Ranges...>::argNum() const
@ -158,20 +231,24 @@ namespace MultiArrayTools
void MultiArrayOperation<T,Range,Operation,Ranges...>::linkIndicesTo(IndefinitIndexBase* target) const
{
OB::mIibPtr->linkTo(target);
TupleIndicesLinker<sizeof...(Ranges)>::linkTupleIndicesTo(mSecs, target);
TupleIndicesLinker<sizeof...(Ranges)-1>::linkTupleIndicesTo(mSecs, target);
}
template <typename T, class Range, class Operation, class... Ranges>
T& MultiArrayOperation<T,Range,Operation,Ranges...>::get()
{
mVal = OperationCall<sizeof...(Ranges)>::callOperation(mOp, mSecs);
mVal = OperationCall<sizeof...(Ranges)-1>::
template callOperation(mOp, mSecs,
OB::mArrayRef[*dynamic_cast<typename OB::IndexType*>(OB::mIibPtr)]);
return mVal;
}
template <typename T, class Range, class Operation, class... Ranges>
const T& MultiArrayOperation<T,Range,Operation,Ranges...>::get() const
{
mVal = OperationCall<sizeof...(Ranges)>::callOperation(mOp, mSecs);
mVal = OperationCall<sizeof...(Ranges)-1>::
template callOperation(mOp, mSecs,
OB::mArrayRef[*dynamic_cast<typename OB::IndexType*>(OB::mIibPtr)]);
return mVal;
}

View file

@ -33,19 +33,23 @@ namespace MultiArrayTools
template <class Operation, class... Ranges>
MultiArrayOperation<T,Range,Operation,Ranges...>
operator()(Operation& op, MultiArrayOperationBase<T,Ranges>&... secs);
operator()(Operation& op, const MultiArrayOperationBase<T,Ranges>&... secs);
template <class Operation, class... Ranges>
MultiArrayOperation<T,Range,Operation,Ranges...>
operator()(const Operation& op, const MultiArrayOperationBase<T,Ranges>&... secs);
template <class Range2>
MultiArrayOperation<T,Range,std::plus<T>,Range2> operator+(MultiArrayOperationBase<T,Range2>& sec);
MultiArrayOperation<T,Range,std::plus<T>,Range2> operator+(const MultiArrayOperationBase<T,Range2>& sec);
template <class Range2>
MultiArrayOperation<T,Range,std::minus<T>,Range2> operator-(MultiArrayOperationBase<T,Range2>& sec);
MultiArrayOperation<T,Range,std::minus<T>,Range2> operator-(const MultiArrayOperationBase<T,Range2>& sec);
template <class Range2>
MultiArrayOperation<T,Range,std::multiplies<T>,Range2> operator*(MultiArrayOperationBase<T,Range2>& sec);
MultiArrayOperation<T,Range,std::multiplies<T>,Range2> operator*(const MultiArrayOperationBase<T,Range2>& sec);
template <class Range2>
MultiArrayOperation<T,Range,std::divides<T>,Range2> operator/(MultiArrayOperationBase<T,Range2>& sec);
MultiArrayOperation<T,Range,std::divides<T>,Range2> operator/(const MultiArrayOperationBase<T,Range2>& sec);
virtual size_t argNum() const;
@ -60,12 +64,10 @@ namespace MultiArrayTools
virtual const T& get(IndefinitIndexBase* iibPtr) const;
protected:
// HERE !!!!!!
MultiArray<T,Range>& mArrayRef;
IndefinitIndexBase mutable* mIibPtr = nullptr;
Name mNm;
};
template <typename T, class Range, class Operation, class... Ranges>
@ -74,8 +76,14 @@ namespace MultiArrayTools
public:
typedef MultiArrayOperationBase<T,Range> OB;
typedef std::tuple<MultiArrayOperationBase<T,Ranges>... > OBT;
MultiArrayOperation(Operation& op, MultiArrayOperationBase<T,Ranges>&... secs);
MultiArrayOperation(MultiArray<T,Range>& ma, const Name& nm,
Operation& op, const MultiArrayOperationBase<T,Ranges>&... secs);
MultiArrayOperation(MultiArray<T,Range>& ma, const Name& nm,
const Operation& op, const MultiArrayOperationBase<T,Ranges>&... secs);
virtual size_t argNum() const override;
virtual void linkIndicesTo(IndefinitIndexBase* target) const override;
@ -87,7 +95,7 @@ namespace MultiArrayTools
mutable T mVal;
Operation mOp;
std::tuple<MultiArrayOperationBase<T,Ranges>... > mSecs;
OBT mSecs;
};

View file

@ -145,7 +145,13 @@ namespace MultiArrayTools
IndexSubOrder<sizeof...(Indices)-1>::subOrd(mIPack, this);
IIB::mPos = evaluate(*this);
}
template <class... Indices>
MultiIndex<Indices...>::~MultiIndex()
{
IndexSubOrder<sizeof...(Indices)-1>::subOrd(mIPack, nullptr);
}
template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator++()
{
@ -256,25 +262,32 @@ namespace MultiArrayTools
template <class... Indices>
bool MultiIndex<Indices...>::link(IndefinitIndexBase* toLink)
{
if(toLink->rangeType() != rangeType() and toLink->name() == IIB::name()){
if(toLink->rangeType() != rangeType() and
toLink->name() == IIB::name() and
not (IIB::name() == "master")){
// throw !!
assert(0);
}
if(toLink->rangeType() == rangeType() and toLink->name() == IIB::name()){
if(IIB::mLinked == toLink){
if(IIB::mLinked == toLink or IIB::mSoftLinked == toLink){
return true; // dont link twice the same
}
else if(IIB::mLinked == nullptr){
else if(IIB::mLinked == nullptr and IIB::mSoftLinked == nullptr){
IIB::mLinked = toLink;
return true;
}
else {
return IIB::mLinked->link(toLink);
if(IIB::mLinked == nullptr){
return IIB::mSoftLinked->link(toLink);
}
else {
return IIB::mLinked->link(toLink);
}
}
}
else {
if(linkLower(toLink)){
IIB::mSoftLinked = IIB::mLinked;
IIB::mLinked = nullptr;
return true;
}

View file

@ -38,6 +38,8 @@ namespace MultiArrayTools
MultiIndex(RangeBase<MultiIndex<Indices...> > const* range,
const IndexPack& ipack);
virtual ~MultiIndex();
virtual MultiIndex& operator++() override;
virtual MultiIndex& operator--() override;
virtual MultiIndex& operator+=(int n) override;

View file

@ -48,6 +48,9 @@ namespace MultiArrayTools
bool MultiRangeType::operator==(const MultiRangeType& in) const
{
if(multi() xor in.multi()){
return false;
}
if(multi()){
return *mMultiType == *in.mMultiType;
}
@ -58,6 +61,9 @@ namespace MultiArrayTools
bool MultiRangeType::operator!=(const MultiRangeType& in) const
{
if(multi() xor in.multi()){
return true;
}
if(multi()){
return *mMultiType != *in.mMultiType;
}

View file

@ -77,6 +77,32 @@ namespace {
MultiArray3dAny ma3d;
};
class OperationTest : public ::testing::Test
{
protected:
typedef MAT::SingleRange<char,MAT::RangeType::ANY> Range1dAny;
typedef MAT::MultiRange<Range1dAny,Range1dAny> Range2dAny;
typedef MAT::MultiRange<Range1dAny,Range1dAny,Range1dAny> Range3dAny;
typedef MAT::MultiArray<int,Range2dAny> MultiArray2dAny;
typedef MAT::MultiArray<int,Range3dAny> MultiArray3dAny;
OperationTest() : r1({'a','b','c'}), r2({'a','b','c','d'}), r3({'a','b'}),
ra(r1,r2),
r3d(r1,r2,r3),
ma(ra, {-5,6,2,1,9,54,27,-7,-13,32,90,-67}),
ma3d(r3d, {-5,6,2,1,9,54,27,-7,-13,32,90,-67,
-10,16,-2,101,39,-64,81,-22,14,34,95,-62}) {}
Range1dAny r1;
Range1dAny r2;
Range1dAny r3;
Range2dAny ra;
Range3dAny r3d;
MultiArray2dAny ma;
MultiArray3dAny ma3d;
};
TEST_F(OneDimTest, CorrectExtensions)
{
EXPECT_EQ(ma.size(), 5);
@ -186,7 +212,7 @@ namespace {
auto i1 = i.template getIndex<0>();
auto i2 = i.template getIndex<1>();
auto i3 = i.template getIndex<2>();
ma3d2("gamma","alpha","beta") = ma3d("alpha","beta","gamma");
EXPECT_EQ(ma3d2[i(i1 = 0,i2 = 0,i3 = 0)],-5);
@ -216,7 +242,45 @@ namespace {
EXPECT_EQ(ma3d2[i(i1 = 0,i2 = 2,i3 = 3)],95);
EXPECT_EQ(ma3d2[i(i1 = 1,i2 = 2,i3 = 3)],-62);
}
TEST_F(OperationTest, CorrectlyAdded)
{
MultiArray3dAny ma3d2(r3d);
auto i = ma3d2.begin();
auto i1 = i.template getIndex<0>();
auto i2 = i.template getIndex<1>();
auto i3 = i.template getIndex<2>();
ma3d2("alpha","beta","gamma") = ma3d("alpha","beta","gamma") + ma("alpha","beta");
EXPECT_EQ(ma3d2[i(i1 = 0, i2 = 0, i3 = 0)], -10);
EXPECT_EQ(ma3d2[i(i1 = 0, i2 = 0, i3 = 1)], 1);
EXPECT_EQ(ma3d2[i(i1 = 0, i2 = 1, i3 = 0)], 8);
EXPECT_EQ(ma3d2[i(i1 = 0, i2 = 1, i3 = 1)], 7);
EXPECT_EQ(ma3d2[i(i1 = 0, i2 = 2, i3 = 0)], 11);
EXPECT_EQ(ma3d2[i(i1 = 0, i2 = 2, i3 = 1)], 56);
EXPECT_EQ(ma3d2[i(i1 = 0, i2 = 3, i3 = 0)], 28);
EXPECT_EQ(ma3d2[i(i1 = 0, i2 = 3, i3 = 1)], -6);
EXPECT_EQ(ma3d2[i(i1 = 1, i2 = 0, i3 = 0)], -4);
EXPECT_EQ(ma3d2[i(i1 = 1, i2 = 0, i3 = 1)], 41);
EXPECT_EQ(ma3d2[i(i1 = 1, i2 = 1, i3 = 0)], 144);
EXPECT_EQ(ma3d2[i(i1 = 1, i2 = 1, i3 = 1)], -13);
EXPECT_EQ(ma3d2[i(i1 = 1, i2 = 2, i3 = 0)], 17);
EXPECT_EQ(ma3d2[i(i1 = 1, i2 = 2, i3 = 1)], 43);
EXPECT_EQ(ma3d2[i(i1 = 1, i2 = 3, i3 = 0)], -9);
EXPECT_EQ(ma3d2[i(i1 = 1, i2 = 3, i3 = 1)], 94);
EXPECT_EQ(ma3d2[i(i1 = 2, i2 = 0, i3 = 0)], 26);
EXPECT_EQ(ma3d2[i(i1 = 2, i2 = 0, i3 = 1)], -77);
EXPECT_EQ(ma3d2[i(i1 = 2, i2 = 1, i3 = 0)], 113);
EXPECT_EQ(ma3d2[i(i1 = 2, i2 = 1, i3 = 1)], 10);
EXPECT_EQ(ma3d2[i(i1 = 2, i2 = 2, i3 = 0)], 104);
EXPECT_EQ(ma3d2[i(i1 = 2, i2 = 2, i3 = 1)], 124);
EXPECT_EQ(ma3d2[i(i1 = 2, i2 = 3, i3 = 0)], 28);
EXPECT_EQ(ma3d2[i(i1 = 2, i2 = 3, i3 = 1)], -129);
}
} // end namespace
int main(int argc, char** argv)