add more docu for range_base / index_base code
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
Christian Zimmermann 2023-11-04 02:12:32 +01:00
parent 337774cd8f
commit 62f83de07b
2 changed files with 200 additions and 28 deletions

View file

@ -21,60 +21,177 @@
namespace CNORXZ 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 I, typename MetaType> template <class I, typename MetaType>
class IndexInterface class IndexInterface
{ {
public: public:
/** default destructor */
~IndexInterface() = default; ~IndexInterface() = default;
/** explicit static cast */
I& THIS() { return static_cast<I&>(*this); } I& THIS() { return static_cast<I&>(*this); }
/** explicit static cast (const) */
const I& THIS() const { return static_cast<const I&>(*this); } const I& THIS() const { return static_cast<const I&>(*this); }
/** increment lexicographic index position */
I& operator++() { return ++THIS(); } I& operator++() { return ++THIS(); }
/** decrement lexicographic index position */
I& operator--() { return --THIS();} I& operator--() { return --THIS();}
/** return index with lexicographic index position incremented n times
@param n
*/
I operator+(Int n) const { return THIS() + 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; } I operator-(Int n) const { return THIS() - n; }
/** increment lexicographic index position n times
@param n
*/
I& operator+=(Int n) { return THIS() += n; } I& operator+=(Int n) { return THIS() += n; }
/** decrement lexicographic index position n times
@param n
*/
I& operator-=(Int n) { return THIS() -= 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(); } Int operator-(const IndexInterface& i) const { return lex() - i.lex(); }
SizeT pos() const; // 'memory' pos /** memory position */
SizeT lex() const { return THIS().lex(); } // lexicographic pos SizeT pos() const;
SizeT pmax() const { return static_cast<SizeT>(THIS().pmax()); } // memory pos max
SizeT lmax() const { return static_cast<SizeT>(THIS().lmax()); } // lexicographic pos max /** lexicographic position */
SizeT lex() const { return THIS().lex(); }
/** maximal memory position */
SizeT pmax() const { return static_cast<SizeT>(THIS().pmax()); }
/** maximal lexicographic position */
SizeT lmax() const { return static_cast<SizeT>(THIS().lmax()); }
PtrId ptrId() const; PtrId ptrId() const;
/** index ID */
decltype(auto) id() const { return THIS().id(); } decltype(auto) id() const { return THIS().id(); }
bool operator==(const IndexInterface& in) const; /** check if indices are equal
bool operator!=(const IndexInterface& in) const; @param i Index to compare with
bool operator<(const IndexInterface& in) const; */
bool operator>(const IndexInterface& in) const; bool operator==(const IndexInterface& i) const;
bool operator<=(const IndexInterface& in) const;
bool operator>=(const IndexInterface& in) 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*(); } decltype(auto) operator*() const { return THIS().operator*(); }
/** index dimension */
SizeT dim() const { return THIS().dim(); } SizeT dim() const { return THIS().dim(); }
/** pointer to the range the index is defined on */
decltype(auto) range() const { return THIS().range(); } 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 <SizeT J> template <SizeT J>
decltype(auto) stepSize(const IndexId<J>& id) const { return THIS().stepSize(id); } decltype(auto) stepSize(const IndexId<J>& id) const { return THIS().stepSize(id); }
/** return string formatted meta data at current index position*/
String stringMeta() const { return THIS().stringMeta(); } String stringMeta() const { return THIS().stringMeta(); }
/** return meta data at current index position */
decltype(auto) meta() const { return THIS().meta(); } 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); } 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<I>& _this) const { return THIS().xpr(_this); } decltype(auto) xpr(const Sptr<I>& _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()); } RangePtr prange(const IndexInterface& end) const { return THIS().prange(end.THIS()); }
/** recursive index format */
decltype(auto) deepFormat() const { return THIS().deepFormat(); } 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 <class Xpr, class F = NoF> template <class Xpr, class F = NoF>
decltype(auto) ifor(const Xpr& xpr, F&& f) const decltype(auto) ifor(const Xpr& xpr, F&& f) const
{ return THIS().ifor(xpr,std::forward<F>(f)); } { return THIS().ifor(xpr,std::forward<F>(f)); }
protected: protected:
SizeT mPos = 0; SizeT mPos = 0; /**< the memory position */
private: private:
friend I; // why not protected???!!! friend I; // why not protected???!!!

View file

@ -80,7 +80,7 @@ namespace CNORXZ
}; };
/** /** ******
Abstract range base class Abstract range base class
A range defines a parameter space containers and operations are defined on. A range defines a parameter space containers and operations are defined on.
@ -173,6 +173,14 @@ namespace CNORXZ
Wptr<RangeBase> mThis; /**< weak pointer to this range */ Wptr<RangeBase> 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 Range> template <class Range>
class RangeInterface : public RangeBase class RangeInterface : public RangeBase
{ {
@ -180,33 +188,80 @@ namespace CNORXZ
typedef RangeBase RB; typedef RangeBase RB;
/** return index pointing to range's first element */
decltype(auto) begin() const; decltype(auto) begin() const;
/** return index pointing to element after range's last element */
decltype(auto) end() const; decltype(auto) end() const;
virtual DIndex index(SizeT pos) const override final; virtual DIndex index(SizeT pos) const override final;
protected: protected:
/** default constructor */
RangeInterface() = default; 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 <class Range> template <class Range>
struct RangeCast struct RangeCast
{ {
/** cast the range
@param r pointer to range to be casted
*/
static Sptr<Range> func(const RangePtr& r); static Sptr<Range> 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 <class Range> template <class Range>
Sptr<Range> rangeCast(const RangePtr r); Sptr<Range> rangeCast(const RangePtr r);
/** *****
Pack of ranges
Helper struct for the construction of
multi-dimensional ranges
*/
struct RangePack struct RangePack
{ {
Vector<RangePtr> mRs; Vector<RangePtr> mRs; /**< the ranges contained in the pack */
operator RangePtr() const; // -> Ptr to YRange
/** 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); 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); 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); 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); RangePack operator*(const RangePack& a, const RangePack& b);
RangePtr getSub(const RangePtr& r, SizeT num); RangePtr getSub(const RangePtr& r, SizeT num);