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,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. A range defines a parameter space containers and operations are defined on.
Indices can be used to iterate over that space. Indices can be used to iterate over that space.
Ranges have to be created though a corresponding factory. Ranges have to be created though a corresponding factory.
@see RangeFactoryBase @see RangeFactoryBase
Ranges always exist within a shared pointer and cannot be copied. Ranges always exist within a shared pointer and cannot be copied.
*/ */
class RangeBase class RangeBase
{ {
@ -173,40 +173,95 @@ 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
{ {
public: public:
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);