Files CCore/inc/gadget/PtrLenReverse.h CCore/src/gadget/PtrLenReverse.cpp
PtrLenReverse represents a range in the reverse order. It have a bunch of methods to work with a range in its reverse representation. They are similar to PtrLen methods.
template <class T>
struct PtrLenReverse
{
T *ptr;
ulen len;
ptr points to the past-the-last element of the range.
len is the range length.
So the range itself is (ptr-len,len).
A reverse range can be constructed from the base pointer and the length using a constructor. But it's better to use the RangeReverse() and RangeReverse_const() functions.
// constructors PtrLenReverse() noexcept : ptr(0),len(0) {} PtrLenReverse(NothingType) : ptr(0),len(0) {} PtrLenReverse(T *ptr_,ulen len_) : ptr(ptr_+len_),len(len_) {} operator PtrLenReverse<const T>() const;
ptr_ is the base pointer of the range.
You can cast to the const version.
The method reverse() creates the reverse range (i.e. the usual PtrLen object).
// reverse PtrLen<T> reverse() const { return {ptr-len,len}; }
The set of cursor methods:
// cursor ulen operator + () const { return len; } // get length // range is not empty bool operator ! () const { return !len; } // range is empty T & operator * () const { return ptr[-1]; } // first element T * operator -> () const { return ptr-1; } // pointer to the first element void operator ++ () { ptr--; len--; } // advance void operator -- () { ptr++; len++; } // back PtrLenReverse<T> operator += (ulen delta); // advance on delta PtrLenReverse<T> takeup(ulen delta); // advance up to delta elements T & take(); // take first element and advance PtrLenReverse<T> getFinal() const;
"First element" here is the last element of the range.
operator += advances on the given number of elements and returns the reverse range of these elements. You must be sure the number does not exceed the range length.
takeup() is similar, but it checks the range length and advances up to the given number of elements.
getFinal() returns the "final" (past the last) cursor over the range.
Methods fit() can be used to check the length of the range.
// fit bool fit(ulen length) const { return length<=len; } bool fit(ulen off,ulen length) const { return off<=len && length<=(len-off) ; }
The first checks is there at least the length elements. The second can be used to check if the subrange with the given off(set) and length can be selected.
You can select a desired part of the range using parts methods:
// parts static PtrLenReverse<T> MakeFrom(T *ptr,ulen len); PtrLenReverse<T> prefix(ulen length) const; // prefix of the given length PtrLenReverse<T> prefix(PtrLenReverse<T> suffix) const; // prefix, complementary to the given suffix PtrLenReverse<T> suffix(ulen length) const; // suffix of the given length PtrLenReverse<T> part(ulen off,ulen length) const; // inner part with the given off(set) and length PtrLenReverse<T> part(ulen off) const; // suffix with the given off(set) PtrLenReverse<T> inner(ulen off,ulen endoff) const; // inner part with the given off(set) and offset from the end (endoff)
Parts are selected using the reverse order. I.e. "prefix" is, in fact, the last part of the range.
MakeFrom() creates a reverse range from the past-the-last pointer and the length.
You can pick an element of the range based on its index:
// index access T & operator [] (ulen index) const; T & at(ulen index) const; T & back(ulen index) const; // 1 is the last
Again, the reverse order is used to arrange elements.
The last method is required to support range-based for with the PtrLenReverse:
// begin()/end() support bool operator != (PtrLenReverse<T> end) const { return len!=end.len; } };
RangeReverse() and RangeReverse_const() is a family of Creator functions for the reverse range creation.
template <class T> PtrLenReverse<T> RangeReverse(PtrLenReverse<T> a); template <class T> PtrLenReverse<T> RangeReverse(PtrLen<T> a); template <class T,ulen Len> PtrLenReverse<T> RangeReverse(T (&buf)[Len]); template <class T> PtrLenReverse<T> RangeReverse(T *ptr,ulen len); template <class T> PtrLenReverse<T> RangeReverse(T *ptr,T *lim);
And the correspondent const-variants.
template <class T> PtrLenReverse<const T> RangeReverse_const(PtrLenReverse<T> a); template <class T> PtrLenReverse<const T> RangeReverse_const(PtrLen<T> a); template <class T,ulen Len> PtrLenReverse<const T> RangeReverse_const(T (&buf)[Len]); template <class T> PtrLenReverse<const T> RangeReverse_const(T *ptr,ulen len); template <class T> PtrLenReverse<const T> RangeReverse_const(T *ptr,T *lim);
Following generic functions can be used with objects of types with the Range Access Interface:
template <class S> auto RangeReverse(S &&src); template <class S> auto RangeReverse_const(const S &src);