Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

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

NAME
       std::advance - std::advance

Synopsis
	  Defined in header <iterator>
	  template< class InputIt, class Distance >	      (until C++17)
	  void advance(	InputIt& it, Distance n	);
	  template< class InputIt, class Distance >	      (since C++17)
	  constexpr void advance( InputIt& it, Distance	n );

	  Increments given iterator it by n elements.

	  If n is negative, the	iterator is decremented. In this case, InputIt
       must meet the
	  requirements	of LegacyBidirectionalIterator,	otherwise the behavior
       is undefined.

Parameters
	  it	  -	iterator to be advanced
	  n	  -	number of elements it should be	advanced

Type requirements
	  -
	  InputIt must meet the	requirements of	LegacyInputIterator.

Return value
	  (none)

Complexity
	  Linear.

	  However, if InputIt additionally meets the requirements of
	  LegacyRandomAccessIterator, complexity is constant.

Notes
	  The behavior is undefined if the specified sequence of increments or
       decrements
	  would	require	that a non-incrementable iterator (such	as  the	 past-
       the-end iterator)
	  is  incremented,  or	that a non-decrementable iterator (such	as the
       front iterator or
	  the singular iterator) is decremented.

Possible implementation
	  See also the implementations in libstdc++ and	libc++.

First version
	  // implementation via	tag dispatch, available	in C++98  with	const-
       expr removed
	  namespace detail {

	  template<class It>
	  constexpr // required	since C++17
	  void	do_advance(It&	it, typename std::iterator_traits<It>::differ-
       ence_type n,
			  std::input_iterator_tag)
	  {
	      while (n > 0) {
		  --n;
		  ++it;
	      }
	  }

	  template<class It>
	  constexpr // required	since C++17
	  void do_advance(It& it,  typename  std::iterator_traits<It>::differ-
       ence_type n,
			  std::bidirectional_iterator_tag)
	  {
	      while (n > 0) {
		  --n;
		  ++it;
	      }
	      while (n < 0) {
		  ++n;
		  --it;
	      }
	  }

	  template<class It>
	  constexpr // required	since C++17
	  void	do_advance(It&	it, typename std::iterator_traits<It>::differ-
       ence_type n,
			  std::random_access_iterator_tag)
	  {
	      it += n;
	  }

	  } // namespace detail

	  template<class It, class Distance>
	  constexpr // since C++17
	  void advance(It& it, Distance	n)
	  {
	      detail::do_advance(it,  typename	std::iterator_traits<It>::dif-
       ference_type(n),
				 typename     std::iterator_traits<It>::itera-
       tor_category());
	  }

Second version
	  // implementation via	constexpr if, available	in C++17
	  template<class It, class Distance>
	  constexpr void advance(It& it, Distance n)
	  {
	      using  category  =   typename   std::iterator_traits<It>::itera-
       tor_category;
	      static_assert(std::is_base_of_v<std::input_iterator_tag,	 cate-
       gory>);

	      auto   dist   =	 typename    std::iterator_traits<It>::differ-
       ence_type(n);
	      if constexpr (std::is_base_of_v<std::random_access_iterator_tag,
       category>)
		  it +=	dist;
	      else {
		  while	(dist >	0) {
		      --dist;
		      ++it;
		  }
		  if   constexpr  (std::is_base_of_v<std::bidirectional_itera-
       tor_tag,	category>) {
		      while (dist < 0) {
			  ++dist;
			  --it;
		      }
		  }
	      }
	  }

Example
       // Run this code

	#include <iostream>
	#include <iterator>
	#include <vector>

	int main()
	{
	    std::vector<int> v{	3, 1, 4	};

	    auto vi = v.begin();
	    std::advance(vi, 2);
	    std::cout << *vi <<	' ';

	    vi = v.end();
	    std::advance(vi, -2);
	    std::cout << *vi <<	'\n';
	}

Output:
	4 1

See also
	  next		  increment an iterator
	  (C++11)	  (function template)
	  prev		  decrement an iterator
	  (C++11)	  (function template)
	  distance	  returns the distance between two iterators
			  (function template)
	  ranges::advance advances an iterator by given	distance or to a given
       bound
	  (C++20)	  (niebloid)

http://cppreference.com		  2022.07.31		       std::advance(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=std::advance&sektion=3&manpath=FreeBSD+Ports+15.0>

home | help