home | help
std::reverse_iterator(3)       C++ Standard Libary	std::reverse_iterator(3)

NAME
     std::reverse_iterator - std::reverse_iterator

Synopsis
	Defined in header <iterator>
	template< class Iter >
	class reverse_iterator;

	std::reverse_iterator is an iterator adaptor that reverses the direction
     of a given
	iterator, which must be at least a LegacyBidirectionalIterator
	or model bidirectional_iterator
	(since C++20). In other words, when provided with a bidirectional itera-
     tor,
	std::reverse_iterator produces a new iterator that moves from the end to
     the
	beginning of the sequence defined by the underlying bidirectional itera-
     tor.

	For  a	reverse iterator r constructed from an iterator i, the relation-
     ship &*r ==
	&*(i - 1) is always true (as long as r is dereferenceable); thus  a  re-
     verse iterator
	constructed  from  a  one-past-the-end iterator dereferences to the last
     element in a
	sequence.

	This is the iterator returned by member functions rbegin() and rend() of
     the
	standard library containers.

	range-rbegin-rend.svg

Member types
	Member type	  Definition
	iterator_type	  Iter
	iterator_category	   std::iterator_traits<Iter>::iterator_category
     (until
	value_type			  std::iterator_traits<Iter>::value_type
     C++20)
	difference_type   std::iterator_traits<Iter>::difference_type
	pointer 	  std::iterator_traits<Iter>::pointer
	reference	  std::iterator_traits<Iter>::reference
	Member type	  Definition
	iterator_type	  Iter
			  If Iter models std::random_access_iterator, this is
	iterator_concept  std::random_access_iterator_tag. Otherwise, this is
			  std::bidirectional_iterator_tag
			  If std::iterator_traits<Iter>::iterator_category  mod-
     els     (since
	iterator_category    std::derived_from<std::random_access_iterator_tag>,
     this is C++20)
			  std::random_access_iterator_tag. Otherwise, this is
			  std::iterator_traits<Iter>::iterator_category
	value_type	  std::iter_value_t<Iter>
	difference_type   std::iter_difference_t<Iter>
	pointer 	  std::iterator_traits<Iter>::pointer
	reference	  std::iter_reference_t<Iter>

	Member types iterator_category, value_type, difference_type, pointer
	and reference are required to be obtained by inheriting from
	std::iterator<
	    std::iterator_traits<Iter>::iterator_category,
	    std::iterator_traits<Iter>::value_type,
     (until C++17)
	    std::iterator_traits<Iter>::difference_type,
	    std::iterator_traits<Iter>::pointer,
	    std::iterator_traits<Iter>::reference
	>.

Member functions
	constructor	constructs a new iterator adaptor
			(public member function)
	operator=	assigns another iterator adaptor
			(public member function)
	base		accesses the underlying iterator
			(public member function)
	operator*	accesses the pointed-to element
	operator->	(public member function)
	operator[]	accesses an element by index
			(public member function)
	operator++
	operator++(int)
	operator+=
	operator+	advances or decrements the iterator
	operator--	(public member function)
	operator--(int)
	operator-=
	operator-

Member objects
	Member name	    Definition
	current (protected) the underlying iterator of which  base()  returns  a
     copy

Non-member functions
	operator==
	operator!=
	operator<
	operator<=	      compares the underlying iterators
	operator>	      (function template)
	operator>=
	operator<=>
	(C++20)
	operator+	      advances the iterator
			      (function template)
	operator-	       computes  the distance between two iterator adap-
     tors
			      (function template)
	iter_move	      casts the result of dereferencing the adjusted un-
     derlying
	(C++20) 	      iterator to its associated rvalue reference type
			      (function)
	iter_swap	      swaps the objects pointed to by two  adjusted  un-
     derlying
	(C++20) 	      iterators
			      (function template)
	make_reverse_iterator  creates	a std::reverse_iterator of type inferred
     from the
	(C++14) 	      argument
			      (function template)

	Helper templates

	template< class Iterator1, class Iterator2 >

	    requires (!std::sized_sentinel_for<Iterator1, Iterator2>)
	inline constexpr  bool	disable_sized_sentinel_for<		  (since
     C++20)
	    std::reverse_iterator<Iterator1>,

	    std::reverse_iterator<Iterator2>> = true;

	This partial specialization of std::disable_sized_sentinel_for prevents
	specializations  of  reverse_iterator from satisfying sized_sentinel_for
     if their
	underlying iterators do not satisfy the concept.

Possible implementation
	Below is a partial implementation focusing on the way the inner iterator
     is stored,
	calling std::prev only when the content is fetched via operator*.

     template<class It> class reverse_iterator { protected:
	 It current = It(); public:
	 reverse_iterator() = default;
	 constexpr explicit reverse_iterator(It itr) : current(itr) {}
	 template<class U>
	     requires (!std::is_same_v<U, It> &&  std::convertible_to<const  U&,
     It>)
	 constexpr    explicit	 reverse_iterator(const   U&   other)	:   cur-
     rent(other.base()) {}

	 constexpr decltype(auto) operator*() const
	 {
	     return *std::prev(current); // <== returns the content of prev
	 }

	 constexpr reverse_iterator& operator++() { --current; return *this; }
	 constexpr  reverse_iterator  operator++(int)  {  auto	tmp   =   *this;
     ++(*this); return tmp; }

	 constexpr reverse_iterator& operator--() { ++current; return *this; }
	 constexpr   reverse_iterator	operator--(int)  {  auto  tmp  =  *this;
     --(*this); return tmp; }

	 constexpr It base() const { return current; }

	 // Other member functions, friend functions, and  member  typedefs  are
     not shown here.  };

Notes
	std::reverse_iterator does not work with iterators whose dereference re-
     turns a
	reference  to a member of *this (so-called "stashing iterators"). An ex-
     ample of a
	stashing iterator is MSVC STL's std::filesystem::path::iterator.

Example
     // Run this code

      #include <cstddef>
      #include <iostream>
      #include <iterator>

      template<typename T, std::size_t SIZE>
      class Stack
      {
	  T arr[SIZE];
	  std::size_t pos = 0;
      public:
	  T pop()
	  {
	      return arr[--pos];
	  }

	  Stack& push(const T& t)
	  {
	      arr[pos++] = t;
	      return *this;
	  }

	  // we wish that looping on Stack would be in LIFO order
	  // thus we use std::reverse_iterator as an adaptor to existing  itera-
     tors
	  // (which are in this case the simple pointers: [arr, arr + pos)
	  auto begin() { return std::reverse_iterator(arr + pos); }
	  auto end() { return std::reverse_iterator(arr); }
      };

      int main()
      {
	  Stack<int, 8> s;
	  s.push(5).push(15).push(25).push(35);
	  for (int val : s)
	      std::cout << val << ' ';
	  std::cout << '\n';
      }

Output:
      35 25 15 5

See also
	make_reverse_iterator  creates	a std::reverse_iterator of type inferred
     from the
	(C++14) 	      argument
			      (function template)
	iterator	      base class to  ease  the	definition  of	required
     types for simple
	(deprecated in C++17) iterators
			      (class template)

http://cppreference.com 	   2024.06.10		std::reverse_iterator(3)

home | help