MySQL 9.6.0
Source Code Documentation
mysql::iterators::Iterator_interface< Self_tp > Class Template Reference

CRTP base class (mixin) that makes your class a standard-compliant iterator, given only a minimal set of functions to read, move and compare iterators. More...

#include <iterator_interface.h>

Inheritance diagram for mysql::iterators::Iterator_interface< Self_tp >:
[legend]

Public Member Functions

decltype(auto) operator* () const
 Dereference operator, which returns the current value. More...
 
auto operator-> () const
 Arrow operator, return a pointer (possibly a fancy pointer) to the current element. More...
 
Self_toperator++ ()
 Pre-increment operator, which advances the position one step and returns a reference to the iterator itself. More...
 
auto operator++ (int)
 Post-increment operator, which advances the position one step. More...
 
Self_toperator-- ()
 Pre-decrement iterator, which moves one step back and returns a reference to the iterator itself. More...
 
auto operator-- (int)
 Post-decrement operator, which moves one step back and returns a copy of the iterator before the decrement. More...
 
Self_toperator+= (std::ptrdiff_t delta)
 Addition assignment operator, which moves the iterator forward by the given number of steps, and returns a reference to the iterator itself. More...
 
Self_toperator-= (std::ptrdiff_t delta)
 Subtraction assignment operator, which moves the iterator backward by the given number of steps, and returns a reference to the iterator itself. More...
 
Self_t operator+ (std::ptrdiff_t delta) const
 Addition operator, which returns a new iterator that is the given number of steps ahead of the current iterator. More...
 
Self_t operator- (std::ptrdiff_t delta) const
 Subtraction-of-integer operator, which returns a new iterator that is the given number of steps behind of the current iterator. More...
 
std::ptrdiff_t operator- (const Self_t &other) const
 Subtraction-of-iterator operator, which returns the number of steps from other this. More...
 
decltype(auto) operator[] (std::ptrdiff_t delta) const
 Subscript operator, which returns a new iterator that is the given number of steps ahead of the current iterator. More...
 

Protected Types

using Self_t = Self_tp
 

Private Member Functions

const Self_tself () const
 Return a const reference to the subclass. More...
 
Self_tself ()
 Return a non-const reference to the subclass. More...
 

Detailed Description

template<class Self_tp>
class mysql::iterators::Iterator_interface< Self_tp >

CRTP base class (mixin) that makes your class a standard-compliant iterator, given only a minimal set of functions to read, move and compare iterators.

Based on the member functions you define, this class deduces all the operators, as well as the iterator traits. This ensures that your class will meet the appropriate named requirement, LegacyInputIterator, LegacyForwardIterator, LegacyBidirectionalIterator, LegacyRandomAccessIterator, or LegacyContiguousIterator, as well as satisfy the appropriate concept, std::input_iterator, std::forward_iterator, std::bidirectional_iterator, std::random_access_iterator, or std::contiguous_iterator.

Defining member functions

To make It an iterator that iterates over values of type V, inherit like:

class It : public Iterator_interface<It> {
public:
/* define member functions as described below */
};

It must be default-constructible, copy/move-constructible, and copy/move-assignable. In addition, define a subset of the following member functions:

// Exactly one of the following, to read the current value:
V get() const;
V &get() const;
V *get_pointer() const;
// At least one of next and advance to move the position; prev is optional.
void next();
void prev();
void advance(std::ptrdiff_t);
// Optionally one of the following, to compare iterators:
bool is_equal(const It &) const;
std::ptrdiff_t distance_from(const It &) const;
bool is_sentinel() const;
std::ptrdiff_t distance_from_sentinel() const;
constexpr bool is_equal(const Set1_t &set1, const Set2_t &set2)
Return true if the two sets are equal, which must be of the same Set category and Set traits.
Definition: common_predicates.h:101
static mysql_service_status_t get(THD **thd) noexcept
Definition: mysql_current_thread_reader_all_empty.cc:31

C++ defines two hierarchies of iterators, which are confusingly similar and subtly different:

  • Pre-C++20 named requirements such as LegacyInputIterator, which can be queried at compile-time using std::iterator_traits<It>iterator_category.
  • C++20 concepts such as std::input_iterator, which can be queried at compile-time using these concepts.

This class deduces both the iterator category and the iterator concept, as follows:

  • LegacyInputIterator requries any get or get_pointer function, either next or advance, and either is_equal or distance_from.
  • LegacyForwardIterator requries LegacyInputIterator, and that get returns by reference, and the class must be copyable.
  • LegacyBidirectionalIterator requires LegacyForwardIterator, and either prev or advance.
  • LegacyRandomAccessIterator requries LegacyBidirectionalIterator, and advance, and distance_from.
  • LegacyContiguousIterator requries LegacyRandomAccessIterator, and requires get_pointer.
  • std::input_iterator requries any get or get_pointer function, and either next or advance. (It is weaker than LegacyInputIterator because it does not require that iterators can be compared.)
  • std::forward_iterator requries std::input_iterator, and either is_equal or distance_from, and the class must be copyable. (It is weaker than LegacyForwardIterator because it does not require that get returns by reference.)
  • std::bidirectional_iterator requries std::forward_iterator, and either prev or advance. (It is weaker than LegacyBidirectionalIterator because it does not require that get returns by reference.)
  • std::random_access_iterator requires std::bidirectional_iterator, and advance and distance_from. (It is weaker than LegacyRandomAccessIterator because it does not require that get returns by reference.)
  • std::contiguous_iterator requires std::random_access_iterator, and requires get_pointer. This coincides with the requirements for LegacyContiguousIterator.
  • Diagram of concept/category strengths

To summarize the previous section, the following diagram illustrates the relative strengths between deduced iterator concepts and categories for types derived from this class. The notation A-->B indicates that B is stronger that A, i.e., requires everything that A requires and more. The abbreviations I/F/B/R/C/ct/cy mean input/forward/bidirectional/random_access/contiguous/concept/category, respectively.

1 2 4 5
I_ct ----> I_cy ----> F_ct ----> B_ct ----> R_ct
| | |
3| 3| 3|
V 4 V 5 V 6
F_cy ----> B_cy ----> R_cy ----> C_ct==C_cy

Each arrow is annotated by a number that refers to the following list, indicating what you need to implement to "follow the arrow": (1) Implement is_equal to make iterators equality-comparable. (2) Implement the copy constructor (actually, just don't delete it). (3) Make get return by reference. (4) Implement prev to enable moving backwards. (5) Implement advance and distance_from instead of get/next/is_equal, to make it possible to take long steps. (6) Implement get_pointer and ensure that returned objects are adjacent in memory.

  • Iterators returning values, not references

Iterators that return value rather than reference can't meet the LegacyForwardIterator requirement. This determines the behavior of standard algorithms like std::prev, std::advance, and std::distance. Thus, just because the iterator returns by value, both std::advance(it, negative_number) and std::prev produce undefined behavior (typically an infinite loop), and std::distance is linear-time (even if the iterator satisfies std::random_access_iterator). Use std::ranges::prev, std::ranges::advance, and std::ranges::distance instead.

  • Sentinel types

If your iterator needs a sentinel type, this class limits it to be the mysql::iterator::Default_sentinel type. Define one or both of the member functions is_sentinel or distance_from_sentinel.

Note
Thanks for inspiration from https://vector-of-bool.github.io/2020/06/13/cpp20-iter-facade.html
Template Parameters
Self_tpThe subclass that inherits from this class.

Member Typedef Documentation

◆ Self_t

template<class Self_tp >
using mysql::iterators::Iterator_interface< Self_tp >::Self_t = Self_tp
protected

Member Function Documentation

◆ operator*()

template<class Self_tp >
decltype(auto) mysql::iterators::Iterator_interface< Self_tp >::operator* ( ) const
inline

Dereference operator, which returns the current value.

This delegates the work to get.

◆ operator+()

template<class Self_tp >
Self_t mysql::iterators::Iterator_interface< Self_tp >::operator+ ( std::ptrdiff_t  delta) const
inline

Addition operator, which returns a new iterator that is the given number of steps ahead of the current iterator.

This delegates the work to advance.

◆ operator++() [1/2]

template<class Self_tp >
Self_t & mysql::iterators::Iterator_interface< Self_tp >::operator++ ( )
inline

Pre-increment operator, which advances the position one step and returns a reference to the iterator itself.

This delegates the work to the next member function if there is one; otherwise to the advance member function.

◆ operator++() [2/2]

template<class Self_tp >
auto mysql::iterators::Iterator_interface< Self_tp >::operator++ ( int  )
inline

Post-increment operator, which advances the position one step.

For forward iterators and higher, returns a copy of the iterator before the increment. For input iterators, returns a reference to the iterator itself.

This delegates the work to the next member function if there is one; otherwise to the advance member function.

◆ operator+=()

template<class Self_tp >
Self_t & mysql::iterators::Iterator_interface< Self_tp >::operator+= ( std::ptrdiff_t  delta)
inline

Addition assignment operator, which moves the iterator forward by the given number of steps, and returns a reference to the iterator itself.

This delegates the work to advance.

◆ operator-() [1/2]

template<class Self_tp >
std::ptrdiff_t mysql::iterators::Iterator_interface< Self_tp >::operator- ( const Self_t other) const
inline

Subtraction-of-iterator operator, which returns the number of steps from other this.

This delegates the work to distance_from.

◆ operator-() [2/2]

template<class Self_tp >
Self_t mysql::iterators::Iterator_interface< Self_tp >::operator- ( std::ptrdiff_t  delta) const
inline

Subtraction-of-integer operator, which returns a new iterator that is the given number of steps behind of the current iterator.

This delegates the work to advance.

◆ operator--() [1/2]

template<class Self_tp >
Self_t & mysql::iterators::Iterator_interface< Self_tp >::operator-- ( )
inline

Pre-decrement iterator, which moves one step back and returns a reference to the iterator itself.

This delegates the work to the prev member function if there is one; otherwise to the advance member function.

◆ operator--() [2/2]

template<class Self_tp >
auto mysql::iterators::Iterator_interface< Self_tp >::operator-- ( int  )
inline

Post-decrement operator, which moves one step back and returns a copy of the iterator before the decrement.

This delegates the work to the prev member function if there is one; otherwise to the advance member function.

◆ operator-=()

template<class Self_tp >
Self_t & mysql::iterators::Iterator_interface< Self_tp >::operator-= ( std::ptrdiff_t  delta)
inline

Subtraction assignment operator, which moves the iterator backward by the given number of steps, and returns a reference to the iterator itself.

This delegates the work to advance.

◆ operator->()

template<class Self_tp >
auto mysql::iterators::Iterator_interface< Self_tp >::operator-> ( ) const
inline

Arrow operator, return a pointer (possibly a fancy pointer) to the current element.

This delegates work to get_pointer if that is defined. Otherwise, if get returns a reference, returns the address of get(). Otherwise, returns an "arrow proxy": an object that stores a copy of the value and for which the arrow operator returns the address of the stored value. Note that the pointer returned from the arrow proxy only lives as long as the arrow proxy lives.

◆ operator[]()

template<class Self_tp >
decltype(auto) mysql::iterators::Iterator_interface< Self_tp >::operator[] ( std::ptrdiff_t  delta) const
inline

Subscript operator, which returns a new iterator that is the given number of steps ahead of the current iterator.

This delegates the work to advance.

◆ self() [1/2]

template<class Self_tp >
Self_t & mysql::iterators::Iterator_interface< Self_tp >::self ( )
inlineprivate

Return a non-const reference to the subclass.

◆ self() [2/2]

template<class Self_tp >
const Self_t & mysql::iterators::Iterator_interface< Self_tp >::self ( ) const
inlineprivate

Return a const reference to the subclass.


The documentation for this class was generated from the following file: