operation classes

This commit is contained in:
Christian Zimmermann 2017-02-15 19:40:44 +01:00
parent d4f8402f29
commit 211c731273
2 changed files with 327 additions and 57 deletions

246
src/me.cc
View file

@ -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
View file

@ -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;
};
// =========