diff --git a/src/include/ranges/index_base.h b/src/include/ranges/index_base.h index d541efb..b8c21b9 100644 --- a/src/include/ranges/index_base.h +++ b/src/include/ranges/index_base.h @@ -21,60 +21,177 @@ namespace CNORXZ { + /** ****** + Basic index interface class template + + Static polymorphism: This class defines an interface template; + all indices are supposed to be derived from the corresponding + template instance + + Indices are act as iterators over parameter spaces (ranges) and/or + the containers (arrays) defined on them + + Moreover, indices are used to define operations on the + corresponding parameters space + + In principle, one distinguishes between lexicographic position + (= index position) and the memory position of the corresponding + meta data w.r.t. the first element + + @tparam I Index type, recurring template argument + @tparam MetaType data type of the meta data + + @see RangeBase + @see RangeInterface + */ template class IndexInterface { public: + /** default destructor */ ~IndexInterface() = default; - + + /** explicit static cast */ I& THIS() { return static_cast(*this); } + + /** explicit static cast (const) */ const I& THIS() const { return static_cast(*this); } + /** increment lexicographic index position */ I& operator++() { return ++THIS(); } + + /** decrement lexicographic index position */ I& operator--() { return --THIS();} + + /** return index with lexicographic index position incremented n times + @param n + */ I operator+(Int n) const { return THIS() + n; } + + /** return index with lexicographic index position decremented n times + @param n + */ I operator-(Int n) const { return THIS() - n; } + + /** increment lexicographic index position n times + @param n + */ I& operator+=(Int n) { return THIS() += n; } + + /** decrement lexicographic index position n times + @param n + */ I& operator-=(Int n) { return THIS() -= n; } + + /** difference of lexicographic index postions + @param i Index to compare with + */ Int operator-(const IndexInterface& i) const { return lex() - i.lex(); } - - SizeT pos() const; // 'memory' pos - SizeT lex() const { return THIS().lex(); } // lexicographic pos - SizeT pmax() const { return static_cast(THIS().pmax()); } // memory pos max - SizeT lmax() const { return static_cast(THIS().lmax()); } // lexicographic pos max + + /** memory position */ + SizeT pos() const; + + /** lexicographic position */ + SizeT lex() const { return THIS().lex(); } + + /** maximal memory position */ + SizeT pmax() const { return static_cast(THIS().pmax()); } + + /** maximal lexicographic position */ + SizeT lmax() const { return static_cast(THIS().lmax()); } + PtrId ptrId() const; + + /** index ID */ decltype(auto) id() const { return THIS().id(); } - bool operator==(const IndexInterface& in) const; - bool operator!=(const IndexInterface& in) const; - bool operator<(const IndexInterface& in) const; - bool operator>(const IndexInterface& in) const; - bool operator<=(const IndexInterface& in) const; - bool operator>=(const IndexInterface& in) const; + /** check if indices are equal + @param i Index to compare with + */ + bool operator==(const IndexInterface& i) const; + /** check if indices are non-equal + @param i Index to compare with + */ + bool operator!=(const IndexInterface& i) const; + + /** check if index is smaller than i + @param i Index to compare with + */ + bool operator<(const IndexInterface& i) const; + + /** check if index is greater than i + @param i Index to compare with + */ + bool operator>(const IndexInterface& i) const; + + /** check if index is not greater than i + @param i Index to compare with + */ + bool operator<=(const IndexInterface& i) const; + + /** check if index is not smaller than i + @param i Index to compare with + */ + bool operator>=(const IndexInterface& i) const; + + /** return meta data at current index position */ decltype(auto) operator*() const { return THIS().operator*(); } + /** index dimension */ SizeT dim() const { return THIS().dim(); } + + /** pointer to the range the index is defined on */ decltype(auto) range() const { return THIS().range(); } + /** return the memory step size this index has w.r.t. to index of given ID + + @tparam J static index ID, size type + @param id input index ID + */ template decltype(auto) stepSize(const IndexId& id) const { return THIS().stepSize(id); } - + + /** return string formatted meta data at current index position*/ String stringMeta() const { return THIS().stringMeta(); } + + /** return meta data at current index position */ decltype(auto) meta() const { return THIS().meta(); } + + /** set index position so that it's meta data matches input + + @param meta meta data to be matched + */ I& at(const MetaType& meta) { return THIS().at(meta); } + + /** create expression on this index + + @param _this pointer to this index + */ decltype(auto) xpr(const Sptr& _this) const { return THIS().xpr(_this); } + /** create partial range starting at this index' position and ending + at the position of input index. The end position is included! + @param end end index + */ RangePtr prange(const IndexInterface& end) const { return THIS().prange(end.THIS()); } + /** recursive index format */ decltype(auto) deepFormat() const { return THIS().deepFormat(); } - + + /** create a for-loop expression + + @tparam Xpr loop internal expression + @tparam F accumulating function + @param xpr loop internal expression + @param f accumulating function + */ template decltype(auto) ifor(const Xpr& xpr, F&& f) const { return THIS().ifor(xpr,std::forward(f)); } protected: - SizeT mPos = 0; + SizeT mPos = 0; /**< the memory position */ private: friend I; // why not protected???!!! diff --git a/src/include/ranges/range_base.h b/src/include/ranges/range_base.h index 508877c..0ca0037 100644 --- a/src/include/ranges/range_base.h +++ b/src/include/ranges/range_base.h @@ -80,16 +80,16 @@ namespace CNORXZ }; - /** - Abstract range base class + /** ****** + Abstract range base class - A range defines a parameter space containers and operations are defined on. - Indices can be used to iterate over that space. - - Ranges have to be created though a corresponding factory. - @see RangeFactoryBase - - Ranges always exist within a shared pointer and cannot be copied. + A range defines a parameter space containers and operations are defined on. + Indices can be used to iterate over that space. + + Ranges have to be created though a corresponding factory. + @see RangeFactoryBase + + Ranges always exist within a shared pointer and cannot be copied. */ class RangeBase { @@ -173,40 +173,95 @@ namespace CNORXZ Wptr mThis; /**< weak pointer to this range */ }; + /** ****** + Interface template for ranges + + Provides begin() and end() returning indices of + corresponding type + + @tparam Range specify the range type + */ template class RangeInterface : public RangeBase { public: typedef RangeBase RB; - + + /** return index pointing to range's first element */ decltype(auto) begin() const; + + /** return index pointing to element after range's last element */ decltype(auto) end() const; + virtual DIndex index(SizeT pos) const override final; protected: + /** default constructor */ RangeInterface() = default; }; + /** ****** + Generic range case template + + Cast range of any type into range of type + specified by the template argument + + @tparam Range specify the range type to cast into + */ template struct RangeCast { + /** cast the range + @param r pointer to range to be casted + */ static Sptr func(const RangePtr& r); }; - + + /** wrapps RangeCast::func + @param r pointer to range to be casted + @tparam Range specify the range type to cast into + @see RangeCast + */ template Sptr rangeCast(const RangePtr r); + /** ***** + Pack of ranges + Helper struct for the construction of + multi-dimensional ranges + */ struct RangePack { - Vector mRs; - operator RangePtr() const; // -> Ptr to YRange + Vector mRs; /**< the ranges contained in the pack */ + + /** return YRange containig the ranges of the pack */ + operator RangePtr() const; }; + /** create a pack consisting of ranges a and b + @param a pointer to first range + @param b pointer to second range + */ RangePack operator*(const RangePtr& a, const RangePtr& b); + + /** create a pack consisting of ranges a and the ranges of b + @param a pointer to first range + @param b pack of ranges + */ RangePack operator*(const RangePtr& a, const RangePack& b); + + /** create a pack consisting of the ranges of a and the range b + @param a pack of ranges + @param b pointer to first range + */ RangePack operator*(const RangePack& a, const RangePtr& b); + + /** create a pack consisting of the ranges of a and b + @param a pack of ranges + @param b pack of ranges + */ RangePack operator*(const RangePack& a, const RangePack& b); RangePtr getSub(const RangePtr& r, SizeT num);