75 lines · c
1// -*- C++ -*-2//===----------------------------------------------------------------------===//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP___CXX03___ITERATOR_ADVANCE_H11#define _LIBCPP___CXX03___ITERATOR_ADVANCE_H12 13#include <__cxx03/__assert>14#include <__cxx03/__config>15#include <__cxx03/__iterator/iterator_traits.h>16#include <__cxx03/__type_traits/enable_if.h>17#include <__cxx03/__type_traits/is_integral.h>18#include <__cxx03/__utility/convert_to_integral.h>19#include <__cxx03/__utility/declval.h>20#include <__cxx03/__utility/move.h>21#include <__cxx03/__utility/unreachable.h>22#include <__cxx03/limits>23 24#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)25# pragma GCC system_header26#endif27 28_LIBCPP_PUSH_MACROS29#include <__cxx03/__undef_macros>30 31_LIBCPP_BEGIN_NAMESPACE_STD32 33template <class _InputIter>34_LIBCPP_HIDE_FROM_ABI void35__advance(_InputIter& __i, typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag) {36 for (; __n > 0; --__n)37 ++__i;38}39 40template <class _BiDirIter>41_LIBCPP_HIDE_FROM_ABI void42__advance(_BiDirIter& __i, typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag) {43 if (__n >= 0)44 for (; __n > 0; --__n)45 ++__i;46 else47 for (; __n < 0; ++__n)48 --__i;49}50 51template <class _RandIter>52_LIBCPP_HIDE_FROM_ABI void53__advance(_RandIter& __i, typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag) {54 __i += __n;55}56 57template < class _InputIter,58 class _Distance,59 class _IntegralDistance = decltype(std::__convert_to_integral(std::declval<_Distance>())),60 __enable_if_t<is_integral<_IntegralDistance>::value, int> = 0>61_LIBCPP_HIDE_FROM_ABI void advance(_InputIter& __i, _Distance __orig_n) {62 typedef typename iterator_traits<_InputIter>::difference_type _Difference;63 _Difference __n = static_cast<_Difference>(std::__convert_to_integral(__orig_n));64 // Calling `advance` with a negative value on a non-bidirectional iterator is a no-op in the current implementation.65 _LIBCPP_ASSERT_PEDANTIC(__n >= 0 || __has_bidirectional_iterator_category<_InputIter>::value,66 "Attempt to advance(it, n) with negative n on a non-bidirectional iterator");67 std::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category());68}69 70_LIBCPP_END_NAMESPACE_STD71 72_LIBCPP_POP_MACROS73 74#endif // _LIBCPP___CXX03___ITERATOR_ADVANCE_H75