Monday, October 14, 2024

reverse_iterator adaptor

Overview
A  reverse iterator adapter reverses the direction in which a bidirectional or random-access  iterator iterates through a range. 

Details
A copy of the original iterator (the base iterator) is kept internally and used to reflect the operations performed on the reverse_iterator: whenever the reverse_iterator is incremented, its base iterator is decreased, and vice versa. A copy of the base iterator with the current state can be obtained at any time by calling member base.
This is the iterator returned by member functions rbegin() and rend() of the standard library containers.

Syntax
The syntax is as below. Template parameter Iter represents the original iterator for which 
reverse_ iterator is created. Iter can be bidirectional iterator or a random-access iterator
template < class Iter > 
class  reverse iterator;

Members
 It defines following types.
member typedefinition
iterator_typeIter
iterator_categoryiterator_traits<Iter>::iterator_category
value_typeiterator_traits<Iter>::value_type
difference_typeiterator_traits<Iter>::difference_type
pointeriterator_traits<Iter>::pointer
referenceiterator_traits<Iter>::reference

Operation
reverse_iterator can be graphically represented as below.

When an iterator is reversed, the reversed version does not point to the same element in the range, but to the one preceding it. 
Therefore, for a reverse iterator r constructed from an iterator i, the relationship &*r == &*(i - 1) is always true (as long as r is dereferenceable); thus a reverse iterator constructed from a one-past-the-end iterator dereferences to the last element in a sequence.
In other words, 
reverse_iterator(end(v)) == rbegin(v)
Similarly,  
reverse_iterator(begin(v)) == rend(v)

This can be clearly seen in the example below. 
vector<int> v{1, 2, 3, 4, 5};
reverse_iterator<vector<int>::iterator> rev = rbegin(v);
    
/*
distance(rbegin(v), rev) :0	*rev:5	distance(rev.base(), end(v):0	*base:0
distance(rbegin(v), rev) :1	*rev:4	distance(rev.base(), end(v):1	*base:5
distance(rbegin(v), rev) :2	*rev:3	distance(rev.base(), end(v):2	*base:4
distance(rbegin(v), rev) :3	*rev:2	distance(rev.base(), end(v):3	*base:3
distance(rbegin(v), rev) :4	*rev:1	distance(rev.base(), end(v):4	*base:2
distance(rbegin(v), rev) :5	*rev:0	distance(rev.base(), end(v):5	*base:1
*/
for (int i=0; i <= v.size(); ++rev,++i)
{
    cout << "distance(rbegin(v), rev) :" << distance(rbegin(v),rev);
    cout << "\t*rev:" << *rev;
    cout << "\tdistance(rev.base(), end(v):" << distance(rev.base(), end(v));
    cout << "\t*base:" << *rev.base() << endl;
}

Functionality

Constructors
NameDescription
reverse_iterator()
Default Constructor.

Example:
vector<int> v{1, 2, 3, 4, 5};
//*rev=exception
reverse_iterator<vector<int>::iterator> rev;
//*rev=5
rev = rbegin(v);
reverse_iterator(iterator_type it)
Constructs a reverse_iterator from it.

Example:
vector<int> v{1, 2, 3, 4, 5};
//*rev=5
reverse_iterator<vector<int>::iterator> rev = reverse_iterator(end(v));
reverse_iterator(const reverse_iterator& r)
Copy constructor.

Example:
vector<int> v{1, 2, 3, 4, 5};
//*rev=5
reverse_iterator<vector<int>::iterator> rev = reverse_iterator(end(v));
//*rev2=5
reverse_iterator<vector<int>::iterator> rev2(rev);
//rev=4 rev2=5    
++rev;

Overloaded operators
NameExample
reference operator*() Returns reference to the element at current position of the reverse iterator that can be used to read or write.

Example:
vector<int> v{1,2,3,4};
//*ita=4
auto ita = rbegin(v);
//prints 4
cout << *ita << endl;
  1. reverse_iterator& operator++()
  2. reverse_iterator  operator++(int)
  1. Returns a reference to self after incrementing of its position. 
  2. Returns copy of self and increments its position.eturns reference 
Example:
vector<int> v{1,2,3,4};
reverse_iterator<vector<int>::iterator> ita, itb;
//*ita=4
ita = rbegin(v);

//pre ++
//*ita=3 *itb=4
itb = ita++;


//*ita=4
ita = rbegin(v);

//post ++
//*ita=3 *itb=3
itb = ++ita;
  1. reverse_iterator& operator--()
  2. reverse_iterator  operator--(int)
  1. Returns a reference to self after decrementing of its position. 
  2. Returns copy of self and decrements its position.eturns reference 
Example:
vector<int> v{1,2,3,4};
reverse_iterator<vector<int>::iterator> ita, itb;
//*ita=4 ita = rbegin(v); //*ita=3 ++ita; //pre -- //*ita=4 *itb=3 itb = ita--; //*ita=4 ita = rbegin(v); //*ita=3 ++ita; //post -- //*ita=4 *itb=4 itb = --ita;
pointer operator->() Returns member of the element(class).

Example:
vector<pair<int,int>> pv{{1,2}};
//prints 1
cout << rbegin(pv)->first << endl;
/*unspecified*/ operator[] (difference_type n) Returns reference to the element after adding in the index.

Example:
vector<int> v{1,2,3,4};
reverse_iterator<vector<int>::iterator> ita;

//*ita=4
ita = rbegin(v); 
//*ita=3
++ita;
//[]
//i=3
int i = ita[0];
//i=4
i = ita[-1];
//i=2
i = ita[1];
reverse_iterator operator+ (difference_type n)Returns iterator after adding index to the iterator.

Example:
vector<int> v{1,2,3,4};
vector<int>::iterator ita, itb;
//*ita=4
ita = rbegin(v); 
//+
//*itb=3
itb = ita+1;
reverse_iterator operator- (difference_type n)Returns iterator after subtracting index to the iterator.

Example:
vector<int> v{1,2,3,4};
reverse_iterator<vector<int>::iterator> ita, itb;
//*ita=4
ita = rbegin(v); 
//*ita=3
++ita;
//-
//*itb=4
itb = ita-1;
reverse_iterator operator-= (difference_type n)Subtracts index to self.

Example:
vector<int> v{1,2,3,4};
reverse_iterator<vector<int>::iterator> ita;

//*ita=4
ita = rbegin(v); 
//*ita=3
++ita;
//-=
//*ita=4
ita -= 1;
reverse_iterator operator+= (difference_type n)Adds index to self.

Example:
vector<int> v{1,2,3,4};
reverse_iterator<vector<int>::iterator> ita;

//*ita=4
ita = rbegin(v); 

//+=
//*ita=3
ita += 1;

Iterator
NameDescription
iterator_type base()

Returns a copy of the base iterator.

Example:
vector<int> v{1, 2, 3, 4, 5};
//prints 1 2 3 4 5
for (auto itr=rend(v).base(); itr!=rbegin(v).base(); ++itr)
    cout << *itr << ' ';

External overloaded operators
NameDescription
reverse_iterator<Iterator> operator+ (difference_type n,
const reverse_iterator<Iterator>& rev_it)
Returns reverse iterator after adding n to the iterator.

Example:
vector<int> v{1,2,3,4};
reverse_iterator<vector<int>::iterator> ita, itb;
//*ita=4 ita = rbegin(v); //+ //*itb=3 itb = 1+ita;
difference_type  operator-(const reverse_iterator<Iterator>& first_it, 
const reverse_iterator<Iterator>& second_it)
Returns distance between the iterators. i.e.,second_it - first_it.
Example:
vector<int> v{1,2,3,4};
reverse_iterator<vector<int>::iterator> ita, itb;
//*ita=4 ita = rbegin(v);
//*ita=3
itb = ita--;
//-
//d=1
int d = itb - ita;
  1. bool operator== (const reverse_iterator<iter>& lhs,
    const reverse_iterator<iter2>& rhs)
  2. bool operator!= (const reverse_iterator<iter>& lhs,
    const reverse_iterator<iter2>& rhs)
  3. bool operator> (const reverse_iterator<iter>& lhs,
    const reverse_iterator<iter2>& rhs)
  4. bool operator<(const reverse_iterator<iter>& lhs,
    const reverse_iterator<iter2>& rhs)
  5. bool operator>=(const reverse_iterator<iter>& lhs,
    const reverse_iterator<iter2>& rhs)
  6. bool operator<=(const reverse_iterator<iter>& lhs,
    const reverse_iterator<iter2>& rhs)
Relational Operators.
Example:
vector<int> v{1,2,3,4};
vector<int>::iterator ita, itb;

//*ita=1
ita = begin(v); 
//*ita=2 *itb=1
itb = ita++;

//== != < > >= <=
//ita == itb    F
//ita != itb    T
//ita >  itb    F
//ita >= itb    F
//ita <  itb    T
//ita <= itb    T

make_reverse_iterator
An utility function to create a reverse_iterator from an legacy iterator which can be a bidirectional iterator or a random-access iterator.

Syntax
The syntax is as below. Template parameter Iter represents the original iterator for which reverse_iterator is created. Iter can be bidirectional iterator or a random-access iterator
template < class Iter > 
reverse_iterator<Iter> make_reverse_iterator( Iter i )

The following example shows its usage.
vector<int> v{1,2,3,4};
//*it=4
reverse_iterator<vector<int>::iterator> it = make_reverse_iterator(end(v));



No comments:

Post a Comment