operation classes
This commit is contained in:
parent
d4f8402f29
commit
211c731273
2 changed files with 327 additions and 57 deletions
246
src/me.cc
246
src/me.cc
|
@ -143,7 +143,10 @@ namespace ME
|
|||
|
||||
void IndefinitIndexBase::freeLinked()
|
||||
{
|
||||
mLinked = nullptr;
|
||||
if(linked()){
|
||||
mLinked->freeLinked();
|
||||
mLinked = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool IndefinitIndexBase::linked() const
|
||||
|
@ -158,6 +161,17 @@ namespace ME
|
|||
mLinked->setPos(pos);
|
||||
}
|
||||
}
|
||||
|
||||
size_t IndefinitIndexBase::max() const
|
||||
{
|
||||
return static_cast<size_t>( -1 );
|
||||
}
|
||||
|
||||
size_t IndefinitIndexBase::outOfRange() const
|
||||
{
|
||||
int res = pos() - max();
|
||||
return res > 0 ? static_cast<size_t>(res) : 0;
|
||||
}
|
||||
|
||||
/**************
|
||||
* IndexBase *
|
||||
|
@ -216,6 +230,13 @@ namespace ME
|
|||
return mRange != i.mRange or mPos != i.mPos;
|
||||
}
|
||||
|
||||
template <class Index>
|
||||
size_t IndexBase<Index>::max() const
|
||||
{
|
||||
return mRange->size();
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
* SingleIndexBase *
|
||||
********************/
|
||||
|
@ -226,12 +247,23 @@ namespace ME
|
|||
return dynamic_cast<SingleRange*>( mRange )->get(mPos);
|
||||
}
|
||||
|
||||
template <typename U, IndexType TYPE>
|
||||
size_t dim() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <typename U, IndexType TYPE>
|
||||
size_t SingleIndexBase<TYPE>::evaluate(const Index& in)
|
||||
{
|
||||
return in.mPos;
|
||||
}
|
||||
|
||||
|
||||
template <typename U, IndexType TYPE>
|
||||
void linkTo(IndefinitIndexBase* target)
|
||||
{
|
||||
target->link(this);
|
||||
}
|
||||
|
||||
/*******************
|
||||
* MultiIndexBase *
|
||||
|
@ -239,6 +271,23 @@ namespace ME
|
|||
|
||||
namespace
|
||||
{
|
||||
template <class MultiIndex, size_t N>
|
||||
IndefinitIndexBase& getIndex(MultiIndex& in, size_t n)
|
||||
{
|
||||
if(n == N){
|
||||
return in.getIndex<N>();
|
||||
}
|
||||
else {
|
||||
return getIndex<N-1>(in, n);
|
||||
}
|
||||
}
|
||||
|
||||
template <class MultiIndex>
|
||||
IndefinitIndexBase& getIndex<MultiIndex,0>(MultiIndex& in, size_t n)
|
||||
{
|
||||
return in.getIndex<0>();
|
||||
}
|
||||
|
||||
template <size_t N, class MultiIndex>
|
||||
size_t evaluate_x(const MultiIndex& index)
|
||||
{
|
||||
|
@ -252,6 +301,51 @@ namespace ME
|
|||
const auto& subIndex = index.getIndex<0>();
|
||||
return subIndex.pos();
|
||||
}
|
||||
|
||||
template <class MultiIndex>
|
||||
void plus(MultiIndex& index, size_t digit, int num)
|
||||
{
|
||||
IndefinitIndexBase& si = index.getIndex(digit);
|
||||
si.setPos( si.pos() + num );
|
||||
size_t oor = si.outOfRange();
|
||||
if(oor and digit != MultiIndex::mult - 1){
|
||||
plus(index, digit + 1, 1);
|
||||
plus(index, digit, oor - max());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class... Indices>
|
||||
MultiIndex& MultiIndex<Indices...>::operator++()
|
||||
{
|
||||
setPos( pos() + 1 );
|
||||
plus(*this, 0, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
MultiIndex& MultiIndex<Indices...>::operator--()
|
||||
{
|
||||
setPos( pos() - 1 );
|
||||
plus(*this, 0, -1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
MultiIndex& MultiIndex<Indices...>::operator+=(int n)
|
||||
{
|
||||
setPos( pos() + n );
|
||||
plus(*this, 0, n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
MultiIndex& MultiIndex<Indices...>::operator-=(int n)
|
||||
{
|
||||
setPos( pos() - n );
|
||||
plus(*this, 0, 0-n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
|
@ -260,29 +354,88 @@ namespace ME
|
|||
return evaluate_x<sizeof...(Indices)-1>(in);
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
size_t MultiIndex<Indices...>::dim() const
|
||||
{
|
||||
size_t res = 1;
|
||||
for(size_t i = 0; i != sMult; ++i){
|
||||
res *= getIndex(i).dim();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
bool MultiIndex<Indices...>::link(IndefinitIndexBase* toLink)
|
||||
{
|
||||
if(toLink->name() == name() and toLink->rangeType() == rangeType()){
|
||||
bool isAlready = false;
|
||||
if(mLinked != nullptr){
|
||||
for(auto& x: *mLinked){
|
||||
if(x == toLink){
|
||||
isAlready = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(toLink->rangeType() != rangeType() and toLink->name() == name()){
|
||||
// throw !!
|
||||
}
|
||||
|
||||
if(toLink->rangeType() == rangeType() and toLink->name() == name()){
|
||||
if(mLinked == toLink){
|
||||
return true; // dont link twice the same
|
||||
}
|
||||
else if(mLinked == nullptr){
|
||||
mLinked = toLink;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
mLinked = new std::vector<IndefinitIndexBase*>();
|
||||
return mLinked->link(toLink);
|
||||
}
|
||||
if(not isAlready){
|
||||
mLinked->push_back(toLink);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return /*try each element in mIPack*/;
|
||||
return linkLower(toLink);
|
||||
}
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
auto& getIndex() -> decltype(std::get<N>(mIPack))
|
||||
{
|
||||
return std::get<N>(mIPack);
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
const auto& getIndex() const -> decltype(std::get<N>(mIPack));
|
||||
{
|
||||
return std::get<N>(mIPack);
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
IndefinitIndexBase& MultiIndex<Indices...>::getIndex(size_t n)
|
||||
{
|
||||
if(n >= sMult){
|
||||
// throw !!
|
||||
}
|
||||
MultiIndex<Indices...>* t = this;
|
||||
return getIndex<sizeof...(Indices)>(*t, n);
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
const IndefinitIndexBase& MultiIndex<Indices...>::getIndex(size_t n) const
|
||||
{
|
||||
if(n >= sMult){
|
||||
// throw !!
|
||||
}
|
||||
MultiIndex<Indices...>* t = this;
|
||||
return getIndex<sizeof...(Indices)>(*t, n);
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
bool MultiIndex<Indices...>::linkLower(IndefinitIndexBase* toLink)
|
||||
{
|
||||
bool res = false;
|
||||
for(size_t i = 0; i != sMult; ++i){
|
||||
res |= getIndex(i).link(toLink);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class... Indices>
|
||||
void MultiIndex<Indices...>::linkTo(IndefinitIndexBase* target)
|
||||
{
|
||||
target->link(this);
|
||||
for(size_t i = 0; i != sMult; ++i){
|
||||
getIndex(i).linkTo(target);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,31 +443,72 @@ namespace ME
|
|||
* MultiArray *
|
||||
*******************/
|
||||
|
||||
template <typename... Ranges>
|
||||
void giveNames(const std::string& name, /**/);
|
||||
|
||||
template <typename... Ranges>
|
||||
void giveNames(const std::vector<std::string>& names, /**/);
|
||||
|
||||
/*!!!! giveNames(...) !!!!!*/
|
||||
|
||||
template <typename T, class Range>
|
||||
T& MultiArray<T,Is...>::operator()(const typename Range::indexType& i)
|
||||
{
|
||||
return i.pos();
|
||||
return mCont[ i.pos() ];
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
const T& MultiArray<T,Is...>::operator()(const typename Range::indexType& i) const
|
||||
{
|
||||
return i.pos();
|
||||
return mCont[ i.pos() ];
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
template <class... NameTypes>
|
||||
MultiArrayOperation<T,Range>& operator()(const NameTypes&... str) const
|
||||
{
|
||||
auto index = mRange->begin();
|
||||
// give names... !!!
|
||||
return MultiArrayOperation<T,Range>(*this, index);
|
||||
}
|
||||
|
||||
/***************************
|
||||
* NamedMultiArray *
|
||||
***************************/
|
||||
|
||||
/*********************************
|
||||
* MultiArrayOperationBase *
|
||||
*********************************/
|
||||
|
||||
IndefinitIndexBase& getIndex(const std::string& name)
|
||||
template <typename T, class Range>
|
||||
template <class Range2>
|
||||
MultiArrayOperationBase<T,Range>&
|
||||
MultiArrayOperationBase<T,Range>::operator=(const MultiArrayOperationBase<T, Range2>& in)
|
||||
{
|
||||
return mIndexNameMap.at(name);
|
||||
// perform operation (iterate head index)
|
||||
}
|
||||
|
||||
const IndefinitIndexBase& getIndex(const std::string& name) const
|
||||
template <typename T, class Range>
|
||||
template <class Operation, class... Ranges>
|
||||
MultiArrayOperation<Operation>
|
||||
MultiArrayOperationBase<T,Range>::operator()(Operation& op, MultiArrayOperationBase<T,Ranges>&... secs)
|
||||
{
|
||||
return mIndexNameMap.at(name);
|
||||
// set operation
|
||||
// set mSecs
|
||||
// link Indices
|
||||
}
|
||||
|
||||
template <typename T, class Range>
|
||||
size_t MultiArrayOperationBase<T,Range>::argNum() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*****************************
|
||||
* MultiArrayOperation *
|
||||
*****************************/
|
||||
|
||||
template <typename T, class Range, class Operation, class... Ranges>
|
||||
size_t MultiArrayOperation<T,Range,Operation,Ranges...>::argNum() const
|
||||
{
|
||||
return sizeof...(Ranges) + 1;
|
||||
}
|
||||
|
||||
} // end namespace ME
|
||||
|
|
138
src/me.h
138
src/me.h
|
@ -8,6 +8,12 @@
|
|||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#define DEFAULT_MEMBERS(__class_name__) __class_name__() = default; \
|
||||
__class_name__(const __class_name__& in) = default; \
|
||||
__class_name__& operator=(const __class_name__& in) = default; \
|
||||
__class_name__(__class_name__&& in) = default; \
|
||||
__class_name__& operator=(__class_name__&& in) = default
|
||||
|
||||
namespace ME
|
||||
{
|
||||
|
||||
|
@ -70,6 +76,8 @@ namespace ME
|
|||
{
|
||||
public:
|
||||
|
||||
DEFAULT_MEMBERS(MultiRangeType);
|
||||
|
||||
MultiRangeType& operator=(RangeType& type);
|
||||
MultiRangeType& operator=(const std::vector<MultiRangeType>& multiType);
|
||||
|
||||
|
@ -101,6 +109,9 @@ namespace ME
|
|||
virtual RangeBase<Index>* base() = 0;
|
||||
virtual bool isSubRange() const;
|
||||
|
||||
protected:
|
||||
DEFAULT_MEMBERS(RangeBase);
|
||||
|
||||
};
|
||||
|
||||
template <class Range>
|
||||
|
@ -115,6 +126,7 @@ namespace ME
|
|||
public:
|
||||
virtual bool isSubRange() const override;
|
||||
protected:
|
||||
DEFAULT_MEMBERS(SubRangeBase);
|
||||
RangeBase<Index>* mBase;
|
||||
std::vector<bool> mOccupation;
|
||||
};
|
||||
|
@ -129,6 +141,8 @@ namespace ME
|
|||
class SingleRange : public RangeBase<SingleIndex<U,TYPE> >
|
||||
{
|
||||
public:
|
||||
DEFAULT_MEMBERS(SingleRange);
|
||||
|
||||
const U& get(size_t pos) const;
|
||||
size_t get(const U& metaPos) const;
|
||||
|
||||
|
@ -141,6 +155,7 @@ namespace ME
|
|||
{
|
||||
public:
|
||||
|
||||
DEFAULT_MEMBERS(MultiRange);
|
||||
static size_t dim = sizeof...(Ranges);
|
||||
|
||||
template <size_t N>
|
||||
|
@ -176,13 +191,19 @@ namespace ME
|
|||
|
||||
MultiRangeType rangeType() const = 0;
|
||||
|
||||
virtual bool link(IndefinitIndexBase* toLink);
|
||||
virtual bool link(IndefinitIndexBase* toLink);
|
||||
virtual void freeLinked();
|
||||
virtual bool linked() const;
|
||||
|
||||
virtual void linkTo(IndefinitIndexBase* target) = 0;
|
||||
|
||||
virtual void setPos(size_t pos);
|
||||
|
||||
virtual size_t max() const;
|
||||
virtual size_t outOfRange() const;
|
||||
|
||||
protected:
|
||||
|
||||
DEFAULT_MEMBERS(IndefinitIndexBase);
|
||||
|
||||
std::string mName;
|
||||
size_t mPos;
|
||||
|
@ -208,6 +229,9 @@ namespace ME
|
|||
virtual size_t pos() const override; // = mPos; implement !!!
|
||||
|
||||
protected:
|
||||
|
||||
DEFAULT_MEMBERS(IndexBase);
|
||||
|
||||
// translate index into position
|
||||
virtual size_t evaluate(const Index& in) const = 0;
|
||||
RangeBase<Index>* mRange;
|
||||
|
@ -218,13 +242,17 @@ namespace ME
|
|||
{
|
||||
public:
|
||||
|
||||
DEFAULT_MEMBERS(SingleIndex);
|
||||
|
||||
virtual size_t size() const override;
|
||||
virtual SingleIndexBase& operator=(size_t pos) override;
|
||||
//virtual SingleIndexBase& operator=(const U& upos);
|
||||
//virtual const U& getMetaPos() const;
|
||||
virtual SingleIndexBase& operator=(const U& upos);
|
||||
virtual const U& getMetaPos() const;
|
||||
|
||||
// = 1
|
||||
virtual size_t dim() const override; // implement !!!
|
||||
virtual size_t dim() const override; // = 1
|
||||
|
||||
virtual void linkTo(IndefinitIndexBase* target) override;
|
||||
|
||||
protected:
|
||||
virtual size_t evaluate(const Index& in) const override;
|
||||
};
|
||||
|
@ -234,22 +262,40 @@ namespace ME
|
|||
{
|
||||
public:
|
||||
|
||||
DEFAULT_MEMBERS(MultiIndex);
|
||||
|
||||
typedef std::tuple<Indices...> IndexPack;
|
||||
static size_t sMult = sizeof...(Indices);
|
||||
|
||||
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() -> decltype(std::get<N>(mIPack));
|
||||
auto& getIndex() -> decltype(std::get<N>(mIPack));
|
||||
|
||||
template <size_t N>
|
||||
const auto& getIndex() const -> decltype(std::get<N>(mIPack));
|
||||
|
||||
IndefinitIndexBase& getIndex(size_t n);
|
||||
const IndefinitIndexBase& getIndex(size_t n) const;
|
||||
|
||||
// dimension of MultiRange
|
||||
virtual size_t dim() const override; // implement !!!
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************
|
||||
* MultiArray *
|
||||
******************/
|
||||
|
@ -259,19 +305,14 @@ namespace ME
|
|||
{
|
||||
public:
|
||||
|
||||
MultiArray() = default;
|
||||
MultiArray(const MultiArray& in) = default;
|
||||
MultiArray& operator=(const MultiArray& in) = default;
|
||||
MultiArray(MultiArray&& in) = default;
|
||||
MultiArray& operator=(MultiArray&& in) = default;
|
||||
|
||||
DEFAULT_MEMBERS(MultiArray);
|
||||
MultiArray(const Range& range); // !!!!
|
||||
|
||||
template <class Operation, typename... Strings>
|
||||
MultiArrayOperation<T,Range>& operator()(Operation op, const Strings&... str) const;
|
||||
|
||||
T& operator()(const typename Range::indexType& i); // implement
|
||||
const T& operator()(const typename Range::indexType& i) const; // implement
|
||||
template <class... NameTypes>
|
||||
MultiArrayOperation<T,Range>& operator()(const NameTypes&... str) const;
|
||||
|
||||
T& operator()(const typename Range::indexType& i);
|
||||
const T& operator()(const typename Range::indexType& i) const;
|
||||
|
||||
private:
|
||||
bool mInit = false;
|
||||
|
@ -280,25 +321,60 @@ namespace ME
|
|||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************
|
||||
* MultiArrayOperation *
|
||||
***************************/
|
||||
|
||||
class NamedMultiArray
|
||||
|
||||
template <typename T, class Range>
|
||||
class MultiArrayOperationBase
|
||||
{
|
||||
public:
|
||||
|
||||
MultiArrayOperation(MultiArray<T,Range>& ma, const IndefinitIndexBase& iib);
|
||||
|
||||
// execute AnyOperation
|
||||
// exception if range types are inconsitent with names
|
||||
template <class Range2>
|
||||
MultiArrayOperationBase& operator=(const MultiArrayOperationBase<T, Range2>& in);
|
||||
|
||||
|
||||
template <class Operation, class... Ranges>
|
||||
MultiArrayOperation<Operation> operator()(Operation& op, MultiArrayOperationBase<T,Ranges>&... secs);
|
||||
|
||||
template <class Range2>
|
||||
MultiArrayOperation<std::plus<T>,Range2> operator+(MultiArrayOperationBase<T,Range2>& sec);
|
||||
|
||||
template <class Range2>
|
||||
MultiArrayOperation<std::minus<T>,Range2> operator-(MultiArrayOperationBase<T,Range2>& sec);
|
||||
|
||||
template <class Range2>
|
||||
MultiArrayOperation<std::multiplies<T>,Range2> operator*(MultiArrayOperationBase<T,Range2>& sec);
|
||||
|
||||
template <class Range2>
|
||||
MultiArrayOperation<std::divides<T>,Range2> operator/(MultiArrayOperationBase<T,Range2>& sec);
|
||||
|
||||
virtual size_t argNum() const;
|
||||
|
||||
protected:
|
||||
|
||||
MultiArray<T,Range>& mArrayRef;
|
||||
IndefinitIndexBase* mIibPtr;
|
||||
|
||||
};
|
||||
|
||||
template <typename T, class Range, class Operation, class... Ranges>
|
||||
class MultiArrayOperation : public MultiArrayOperationBase<T,Range>
|
||||
{
|
||||
public:
|
||||
|
||||
// execute AnyOperation
|
||||
// exception if range types are inconsitent with names
|
||||
template <class Range2, class AnyOperation>
|
||||
MultiArrayOperation& operator=(const MultiArrayOperation<T, Range2, AnyOperation>& in);
|
||||
|
||||
IndefinitIndexBase& getIndex(const std::string& name);
|
||||
const IndefinitIndexBase& getIndex(const std::string& name) const;
|
||||
|
||||
private:
|
||||
std::map<std::string, IndefinitIndexBase> mIndexNameMap;
|
||||
virtual size_t argNum() const override;
|
||||
|
||||
protected:
|
||||
|
||||
Operation mOp;
|
||||
std::tuple<MultiArrayOperationBase<T,Ranges>... > mSecs;
|
||||
};
|
||||
|
||||
// =========
|
||||
|
|
Loading…
Reference in a new issue