first operation test works -- yaygit add * there are some memory issues (deletion of index ptr)
This commit is contained in:
parent
b3f7dad655
commit
db4ad28f02
8 changed files with 226 additions and 45 deletions
|
@ -7,6 +7,14 @@ namespace MultiArrayTools
|
||||||
* IndefinitIndexBase *
|
* IndefinitIndexBase *
|
||||||
************************/
|
************************/
|
||||||
|
|
||||||
|
IndefinitIndexBase::~IndefinitIndexBase()
|
||||||
|
{
|
||||||
|
freeLinked();
|
||||||
|
mLinked = nullptr;
|
||||||
|
mMajor = nullptr;
|
||||||
|
mSoftLinked = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
size_t IndefinitIndexBase::pos() const
|
size_t IndefinitIndexBase::pos() const
|
||||||
{
|
{
|
||||||
return mPos;
|
return mPos;
|
||||||
|
@ -30,9 +38,9 @@ namespace MultiArrayTools
|
||||||
bool IndefinitIndexBase::link(IndefinitIndexBase* toLink)
|
bool IndefinitIndexBase::link(IndefinitIndexBase* toLink)
|
||||||
{
|
{
|
||||||
if(toLink->rangeType() != rangeType() and toLink->name() == name()){
|
if(toLink->rangeType() != rangeType() and toLink->name() == name()){
|
||||||
|
assert(0);
|
||||||
// throw !!
|
// throw !!
|
||||||
}
|
}
|
||||||
|
|
||||||
if(toLink->rangeType() == rangeType() and toLink->name() == name()){
|
if(toLink->rangeType() == rangeType() and toLink->name() == name()){
|
||||||
if(mLinked == toLink){
|
if(mLinked == toLink){
|
||||||
return true; // dont link twice the same
|
return true; // dont link twice the same
|
||||||
|
@ -52,10 +60,14 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
void IndefinitIndexBase::freeLinked()
|
void IndefinitIndexBase::freeLinked()
|
||||||
{
|
{
|
||||||
if(linked()){
|
if(mLinked != nullptr){
|
||||||
mLinked->freeLinked();
|
mLinked->freeLinked();
|
||||||
mLinked = nullptr;
|
mLinked = nullptr;
|
||||||
}
|
}
|
||||||
|
if(mSoftLinked != nullptr){
|
||||||
|
mSoftLinked->freeLinked();
|
||||||
|
mSoftLinked = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IndefinitIndexBase::linked() const
|
bool IndefinitIndexBase::linked() const
|
||||||
|
@ -66,11 +78,9 @@ namespace MultiArrayTools
|
||||||
void IndefinitIndexBase::setPos(size_t pos)
|
void IndefinitIndexBase::setPos(size_t pos)
|
||||||
{
|
{
|
||||||
mPos = pos;
|
mPos = pos;
|
||||||
//VCHECK(mName);
|
|
||||||
if(linked()){
|
if(linked()){
|
||||||
mLinked->setPos(pos);
|
mLinked->setPos(pos);
|
||||||
mLinked->evalMajor();
|
mLinked->evalMajor();
|
||||||
//VCHECK(mLinked->name());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace MultiArrayTools
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DEFAULT_MEMBERS(IndefinitIndexBase);
|
DEFAULT_MEMBERS(IndefinitIndexBase);
|
||||||
virtual ~IndefinitIndexBase() {}
|
virtual ~IndefinitIndexBase();
|
||||||
|
|
||||||
virtual IndefinitIndexBase& operator=(size_t pos) = 0;
|
virtual IndefinitIndexBase& operator=(size_t pos) = 0;
|
||||||
virtual IndefinitIndexBase& operator++() = 0;
|
virtual IndefinitIndexBase& operator++() = 0;
|
||||||
|
@ -64,6 +64,7 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
IndefinitIndexBase* mLinked = nullptr;
|
IndefinitIndexBase* mLinked = nullptr;
|
||||||
IndefinitIndexBase* mMajor = nullptr;
|
IndefinitIndexBase* mMajor = nullptr;
|
||||||
|
IndefinitIndexBase* mSoftLinked = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Index>
|
template <class Index>
|
||||||
|
|
|
@ -11,7 +11,8 @@ namespace MultiArrayTools
|
||||||
MultiArrayOperationBase<T,Range>::
|
MultiArrayOperationBase<T,Range>::
|
||||||
MultiArrayOperationBase(MultiArray<T,Range>& ma,
|
MultiArrayOperationBase(MultiArray<T,Range>& ma,
|
||||||
const Name& nm) : mArrayRef(ma),
|
const Name& nm) : mArrayRef(ma),
|
||||||
mIibPtr(new IndexType(mArrayRef.begin()))
|
mIibPtr(new IndexType(mArrayRef.begin())),
|
||||||
|
mNm(nm)
|
||||||
{
|
{
|
||||||
mIibPtr->name(nm);
|
mIibPtr->name(nm);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +20,7 @@ namespace MultiArrayTools
|
||||||
template <typename T, class Range>
|
template <typename T, class Range>
|
||||||
MultiArrayOperationBase<T,Range>::~MultiArrayOperationBase()
|
MultiArrayOperationBase<T,Range>::~MultiArrayOperationBase()
|
||||||
{
|
{
|
||||||
delete mIibPtr;
|
//delete mIibPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, class Range>
|
template <typename T, class Range>
|
||||||
|
@ -30,11 +31,9 @@ namespace MultiArrayTools
|
||||||
IndexType& iref = dynamic_cast<IndexType&>(*mIibPtr);
|
IndexType& iref = dynamic_cast<IndexType&>(*mIibPtr);
|
||||||
for(iref = mArrayRef.begin().pos(); iref != mArrayRef.end(); ++iref){
|
for(iref = mArrayRef.begin().pos(); iref != mArrayRef.end(); ++iref){
|
||||||
// build in vectorization later
|
// build in vectorization later
|
||||||
//VCHECK(iref.pos());
|
|
||||||
//VCHECK(in.mIibPtr->pos());
|
|
||||||
//VCHECK(in.get());
|
|
||||||
get() = in.get();
|
get() = in.get();
|
||||||
}
|
}
|
||||||
|
mIibPtr->freeLinked();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,21 +42,62 @@ namespace MultiArrayTools
|
||||||
MultiArrayOperationBase<T,Range>&
|
MultiArrayOperationBase<T,Range>&
|
||||||
MultiArrayOperationBase<T,Range>::operator=(const MultiArrayOperationBase<T, Range2>& in)
|
MultiArrayOperationBase<T,Range>::operator=(const MultiArrayOperationBase<T, Range2>& in)
|
||||||
{
|
{
|
||||||
//CHECK;
|
|
||||||
in.linkIndicesTo(mIibPtr);
|
in.linkIndicesTo(mIibPtr);
|
||||||
for(*mIibPtr = mArrayRef.begin(); *mIibPtr != mArrayRef.end(); ++(*mIibPtr)){
|
for(*mIibPtr = mArrayRef.begin(); *mIibPtr != mArrayRef.end(); ++(*mIibPtr)){
|
||||||
// build in vectorization later
|
// build in vectorization later
|
||||||
get() = in.get();
|
get() = in.get();
|
||||||
}
|
}
|
||||||
|
mIibPtr->freeLinked();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, class Range>
|
template <typename T, class Range>
|
||||||
template <class Operation, class... Ranges>
|
template <class Operation, class... Ranges>
|
||||||
MultiArrayOperation<T,Range,Operation,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>
|
template <typename T, class Range>
|
||||||
|
@ -112,7 +152,7 @@ namespace MultiArrayTools
|
||||||
template <class IndexTuple>
|
template <class IndexTuple>
|
||||||
static void linkTupleIndicesTo(IndexTuple& itp, IndefinitIndexBase* target)
|
static void linkTupleIndicesTo(IndexTuple& itp, IndefinitIndexBase* target)
|
||||||
{
|
{
|
||||||
std::get<N>(itp).linkTo(target);
|
std::get<N>(itp).linkIndicesTo(target);
|
||||||
linkTupleIndicesTo<N-1>(itp, target);
|
linkTupleIndicesTo<N-1>(itp, target);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -123,30 +163,63 @@ namespace MultiArrayTools
|
||||||
template <class IndexTuple>
|
template <class IndexTuple>
|
||||||
static void linkTupleIndicesTo(IndexTuple& itp, IndefinitIndexBase* target)
|
static void linkTupleIndicesTo(IndexTuple& itp, IndefinitIndexBase* target)
|
||||||
{
|
{
|
||||||
std::get<0>(itp).linkTo(target);
|
std::get<0>(itp).linkIndicesTo(target);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
struct OperationCall
|
struct OperationCall
|
||||||
{
|
{
|
||||||
template <class Operation, class Tuple, class... MBases>
|
template <typename T, class Operation, class Tuple, class... MBases>
|
||||||
auto callOperation(Operation& op, Tuple& tp, MBases&... secs)
|
static auto callOperation(Operation& op, const Tuple& tp, const T& first, const MBases&... secs)
|
||||||
-> decltype(callOperation(op, tp, std::get<N-1>(tp), 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 <>
|
template <>
|
||||||
struct OperationCall<0>
|
struct OperationCall<0>
|
||||||
{
|
{
|
||||||
template <class Operation, class Tuple, class... MBases>
|
template <typename T, class Operation, class Tuple, class... MBases>
|
||||||
auto callOperation(Operation& op, Tuple& tp, MBases&... secs) -> decltype(op(secs.get()...))
|
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>
|
template <typename T, class Range, class Operation, class... Ranges>
|
||||||
size_t MultiArrayOperation<T,Range,Operation,Ranges...>::argNum() const
|
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
|
void MultiArrayOperation<T,Range,Operation,Ranges...>::linkIndicesTo(IndefinitIndexBase* target) const
|
||||||
{
|
{
|
||||||
OB::mIibPtr->linkTo(target);
|
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>
|
template <typename T, class Range, class Operation, class... Ranges>
|
||||||
T& MultiArrayOperation<T,Range,Operation,Ranges...>::get()
|
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;
|
return mVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, class Range, class Operation, class... Ranges>
|
template <typename T, class Range, class Operation, class... Ranges>
|
||||||
const T& MultiArrayOperation<T,Range,Operation,Ranges...>::get() const
|
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;
|
return mVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,19 +33,23 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
template <class Operation, class... Ranges>
|
template <class Operation, class... Ranges>
|
||||||
MultiArrayOperation<T,Range,Operation,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>
|
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>
|
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>
|
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>
|
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;
|
virtual size_t argNum() const;
|
||||||
|
|
||||||
|
@ -60,12 +64,10 @@ namespace MultiArrayTools
|
||||||
virtual const T& get(IndefinitIndexBase* iibPtr) const;
|
virtual const T& get(IndefinitIndexBase* iibPtr) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// HERE !!!!!!
|
|
||||||
|
|
||||||
MultiArray<T,Range>& mArrayRef;
|
MultiArray<T,Range>& mArrayRef;
|
||||||
IndefinitIndexBase mutable* mIibPtr = nullptr;
|
IndefinitIndexBase mutable* mIibPtr = nullptr;
|
||||||
|
Name mNm;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, class Range, class Operation, class... Ranges>
|
template <typename T, class Range, class Operation, class... Ranges>
|
||||||
|
@ -74,8 +76,14 @@ namespace MultiArrayTools
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef MultiArrayOperationBase<T,Range> OB;
|
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 size_t argNum() const override;
|
||||||
|
|
||||||
virtual void linkIndicesTo(IndefinitIndexBase* target) const override;
|
virtual void linkIndicesTo(IndefinitIndexBase* target) const override;
|
||||||
|
@ -87,7 +95,7 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
mutable T mVal;
|
mutable T mVal;
|
||||||
Operation mOp;
|
Operation mOp;
|
||||||
std::tuple<MultiArrayOperationBase<T,Ranges>... > mSecs;
|
OBT mSecs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,13 @@ namespace MultiArrayTools
|
||||||
IndexSubOrder<sizeof...(Indices)-1>::subOrd(mIPack, this);
|
IndexSubOrder<sizeof...(Indices)-1>::subOrd(mIPack, this);
|
||||||
IIB::mPos = evaluate(*this);
|
IIB::mPos = evaluate(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class... Indices>
|
||||||
|
MultiIndex<Indices...>::~MultiIndex()
|
||||||
|
{
|
||||||
|
IndexSubOrder<sizeof...(Indices)-1>::subOrd(mIPack, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
template <class... Indices>
|
template <class... Indices>
|
||||||
MultiIndex<Indices...>& MultiIndex<Indices...>::operator++()
|
MultiIndex<Indices...>& MultiIndex<Indices...>::operator++()
|
||||||
{
|
{
|
||||||
|
@ -256,25 +262,32 @@ namespace MultiArrayTools
|
||||||
template <class... Indices>
|
template <class... Indices>
|
||||||
bool MultiIndex<Indices...>::link(IndefinitIndexBase* toLink)
|
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 !!
|
// throw !!
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(toLink->rangeType() == rangeType() and toLink->name() == IIB::name()){
|
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
|
return true; // dont link twice the same
|
||||||
}
|
}
|
||||||
else if(IIB::mLinked == nullptr){
|
else if(IIB::mLinked == nullptr and IIB::mSoftLinked == nullptr){
|
||||||
IIB::mLinked = toLink;
|
IIB::mLinked = toLink;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return IIB::mLinked->link(toLink);
|
if(IIB::mLinked == nullptr){
|
||||||
|
return IIB::mSoftLinked->link(toLink);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return IIB::mLinked->link(toLink);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(linkLower(toLink)){
|
if(linkLower(toLink)){
|
||||||
|
IIB::mSoftLinked = IIB::mLinked;
|
||||||
IIB::mLinked = nullptr;
|
IIB::mLinked = nullptr;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,8 @@ namespace MultiArrayTools
|
||||||
MultiIndex(RangeBase<MultiIndex<Indices...> > const* range,
|
MultiIndex(RangeBase<MultiIndex<Indices...> > const* range,
|
||||||
const IndexPack& ipack);
|
const IndexPack& ipack);
|
||||||
|
|
||||||
|
virtual ~MultiIndex();
|
||||||
|
|
||||||
virtual MultiIndex& operator++() override;
|
virtual MultiIndex& operator++() override;
|
||||||
virtual MultiIndex& operator--() override;
|
virtual MultiIndex& operator--() override;
|
||||||
virtual MultiIndex& operator+=(int n) override;
|
virtual MultiIndex& operator+=(int n) override;
|
||||||
|
|
|
@ -48,6 +48,9 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
bool MultiRangeType::operator==(const MultiRangeType& in) const
|
bool MultiRangeType::operator==(const MultiRangeType& in) const
|
||||||
{
|
{
|
||||||
|
if(multi() xor in.multi()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if(multi()){
|
if(multi()){
|
||||||
return *mMultiType == *in.mMultiType;
|
return *mMultiType == *in.mMultiType;
|
||||||
}
|
}
|
||||||
|
@ -58,6 +61,9 @@ namespace MultiArrayTools
|
||||||
|
|
||||||
bool MultiRangeType::operator!=(const MultiRangeType& in) const
|
bool MultiRangeType::operator!=(const MultiRangeType& in) const
|
||||||
{
|
{
|
||||||
|
if(multi() xor in.multi()){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if(multi()){
|
if(multi()){
|
||||||
return *mMultiType != *in.mMultiType;
|
return *mMultiType != *in.mMultiType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,32 @@ namespace {
|
||||||
MultiArray3dAny ma3d;
|
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)
|
TEST_F(OneDimTest, CorrectExtensions)
|
||||||
{
|
{
|
||||||
EXPECT_EQ(ma.size(), 5);
|
EXPECT_EQ(ma.size(), 5);
|
||||||
|
@ -186,7 +212,7 @@ namespace {
|
||||||
auto i1 = i.template getIndex<0>();
|
auto i1 = i.template getIndex<0>();
|
||||||
auto i2 = i.template getIndex<1>();
|
auto i2 = i.template getIndex<1>();
|
||||||
auto i3 = i.template getIndex<2>();
|
auto i3 = i.template getIndex<2>();
|
||||||
|
|
||||||
ma3d2("gamma","alpha","beta") = ma3d("alpha","beta","gamma");
|
ma3d2("gamma","alpha","beta") = ma3d("alpha","beta","gamma");
|
||||||
|
|
||||||
EXPECT_EQ(ma3d2[i(i1 = 0,i2 = 0,i3 = 0)],-5);
|
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 = 0,i2 = 2,i3 = 3)],95);
|
||||||
EXPECT_EQ(ma3d2[i(i1 = 1,i2 = 2,i3 = 3)],-62);
|
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
|
} // end namespace
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
|
|
Loading…
Reference in a new issue