diff --git a/src/me.cc b/src/me.cc index 6399ba7..9d5382a 100644 --- a/src/me.cc +++ b/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( -1 ); + } + + size_t IndefinitIndexBase::outOfRange() const + { + int res = pos() - max(); + return res > 0 ? static_cast(res) : 0; + } /************** * IndexBase * @@ -216,6 +230,13 @@ namespace ME return mRange != i.mRange or mPos != i.mPos; } + template + size_t IndexBase::max() const + { + return mRange->size(); + } + + /******************** * SingleIndexBase * ********************/ @@ -226,12 +247,23 @@ namespace ME return dynamic_cast( mRange )->get(mPos); } + template + size_t dim() const + { + return 1; + } + template size_t SingleIndexBase::evaluate(const Index& in) { return in.mPos; } - + + template + void linkTo(IndefinitIndexBase* target) + { + target->link(this); + } /******************* * MultiIndexBase * @@ -239,6 +271,23 @@ namespace ME namespace { + template + IndefinitIndexBase& getIndex(MultiIndex& in, size_t n) + { + if(n == N){ + return in.getIndex(); + } + else { + return getIndex(in, n); + } + } + + template + IndefinitIndexBase& getIndex(MultiIndex& in, size_t n) + { + return in.getIndex<0>(); + } + template size_t evaluate_x(const MultiIndex& index) { @@ -252,6 +301,51 @@ namespace ME const auto& subIndex = index.getIndex<0>(); return subIndex.pos(); } + + template + 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 + MultiIndex& MultiIndex::operator++() + { + setPos( pos() + 1 ); + plus(*this, 0, 1); + return *this; + } + + template + MultiIndex& MultiIndex::operator--() + { + setPos( pos() - 1 ); + plus(*this, 0, -1); + return *this; + } + + template + MultiIndex& MultiIndex::operator+=(int n) + { + setPos( pos() + n ); + plus(*this, 0, n); + return *this; + } + + template + MultiIndex& MultiIndex::operator-=(int n) + { + setPos( pos() - n ); + plus(*this, 0, 0-n); + return *this; } template @@ -260,29 +354,88 @@ namespace ME return evaluate_x(in); } + template + size_t MultiIndex::dim() const + { + size_t res = 1; + for(size_t i = 0; i != sMult; ++i){ + res *= getIndex(i).dim(); + } + return res; + } + template bool MultiIndex::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(); + return mLinked->link(toLink); } - if(not isAlready){ - mLinked->push_back(toLink); - } - return true; } else { - return /*try each element in mIPack*/; + return linkLower(toLink); + } + } + + template + auto& getIndex() -> decltype(std::get(mIPack)) + { + return std::get(mIPack); + } + + template + const auto& getIndex() const -> decltype(std::get(mIPack)); + { + return std::get(mIPack); + } + + template + IndefinitIndexBase& MultiIndex::getIndex(size_t n) + { + if(n >= sMult){ + // throw !! + } + MultiIndex* t = this; + return getIndex(*t, n); + } + + template + const IndefinitIndexBase& MultiIndex::getIndex(size_t n) const + { + if(n >= sMult){ + // throw !! + } + MultiIndex* t = this; + return getIndex(*t, n); + } + + template + bool MultiIndex::linkLower(IndefinitIndexBase* toLink) + { + bool res = false; + for(size_t i = 0; i != sMult; ++i){ + res |= getIndex(i).link(toLink); + } + return res; + } + + template + void MultiIndex::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 + void giveNames(const std::string& name, /**/); + + template + void giveNames(const std::vector& names, /**/); + + /*!!!! giveNames(...) !!!!!*/ + template T& MultiArray::operator()(const typename Range::indexType& i) { - return i.pos(); + return mCont[ i.pos() ]; } template const T& MultiArray::operator()(const typename Range::indexType& i) const { - return i.pos(); + return mCont[ i.pos() ]; } + template + template + MultiArrayOperation& operator()(const NameTypes&... str) const + { + auto index = mRange->begin(); + // give names... !!! + return MultiArrayOperation(*this, index); + } - /*************************** - * NamedMultiArray * - ***************************/ + + /********************************* + * MultiArrayOperationBase * + *********************************/ - IndefinitIndexBase& getIndex(const std::string& name) + template + template + MultiArrayOperationBase& + MultiArrayOperationBase::operator=(const MultiArrayOperationBase& in) { - return mIndexNameMap.at(name); + // perform operation (iterate head index) } - const IndefinitIndexBase& getIndex(const std::string& name) const + template + template + MultiArrayOperation + MultiArrayOperationBase::operator()(Operation& op, MultiArrayOperationBase&... secs) { - return mIndexNameMap.at(name); + // set operation + // set mSecs + // link Indices + } + + template + size_t MultiArrayOperationBase::argNum() const + { + return 1; + } + + /***************************** + * MultiArrayOperation * + *****************************/ + + template + size_t MultiArrayOperation::argNum() const + { + return sizeof...(Ranges) + 1; } } // end namespace ME diff --git a/src/me.h b/src/me.h index 03462c9..1edc2ba 100644 --- a/src/me.h +++ b/src/me.h @@ -8,6 +8,12 @@ #include #include +#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& multiType); @@ -101,6 +109,9 @@ namespace ME virtual RangeBase* base() = 0; virtual bool isSubRange() const; + protected: + DEFAULT_MEMBERS(RangeBase); + }; template @@ -115,6 +126,7 @@ namespace ME public: virtual bool isSubRange() const override; protected: + DEFAULT_MEMBERS(SubRangeBase); RangeBase* mBase; std::vector mOccupation; }; @@ -129,6 +141,8 @@ namespace ME class SingleRange : public RangeBase > { 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 @@ -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* 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 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 - auto getIndex() -> decltype(std::get(mIPack)); + auto& getIndex() -> decltype(std::get(mIPack)); + template + const auto& getIndex() const -> decltype(std::get(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 - MultiArrayOperation& 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 + MultiArrayOperation& 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 + class MultiArrayOperationBase + { + public: + + MultiArrayOperation(MultiArray& ma, const IndefinitIndexBase& iib); + + // execute AnyOperation + // exception if range types are inconsitent with names + template + MultiArrayOperationBase& operator=(const MultiArrayOperationBase& in); + + + template + MultiArrayOperation operator()(Operation& op, MultiArrayOperationBase&... secs); + + template + MultiArrayOperation,Range2> operator+(MultiArrayOperationBase& sec); + + template + MultiArrayOperation,Range2> operator-(MultiArrayOperationBase& sec); + + template + MultiArrayOperation,Range2> operator*(MultiArrayOperationBase& sec); + + template + MultiArrayOperation,Range2> operator/(MultiArrayOperationBase& sec); + + virtual size_t argNum() const; + + protected: + + MultiArray& mArrayRef; + IndefinitIndexBase* mIibPtr; + + }; + + template + class MultiArrayOperation : public MultiArrayOperationBase { public: - // execute AnyOperation - // exception if range types are inconsitent with names - template - MultiArrayOperation& operator=(const MultiArrayOperation& in); - - IndefinitIndexBase& getIndex(const std::string& name); - const IndefinitIndexBase& getIndex(const std::string& name) const; - - private: - std::map mIndexNameMap; + virtual size_t argNum() const override; + protected: + + Operation mOp; + std::tuple... > mSecs; }; // =========