advance.hpp 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // Copyright (C) 2017 Michel Morin.
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_ITERATOR_ADVANCE_HPP
  7. #define BOOST_ITERATOR_ADVANCE_HPP
  8. #include <boost/config.hpp>
  9. #include <boost/iterator/iterator_categories.hpp>
  10. namespace boost {
  11. namespace iterators {
  12. namespace detail {
  13. template< typename InputIterator, typename Distance >
  14. inline BOOST_CXX14_CONSTEXPR void advance_impl(InputIterator& it, Distance n, incrementable_traversal_tag)
  15. {
  16. while (n > 0)
  17. {
  18. ++it;
  19. --n;
  20. }
  21. }
  22. template< typename BidirectionalIterator, typename Distance >
  23. inline BOOST_CXX14_CONSTEXPR void advance_impl(BidirectionalIterator& it, Distance n, bidirectional_traversal_tag)
  24. {
  25. if (n >= 0)
  26. {
  27. while (n > 0)
  28. {
  29. ++it;
  30. --n;
  31. }
  32. }
  33. else
  34. {
  35. while (n < 0)
  36. {
  37. --it;
  38. ++n;
  39. }
  40. }
  41. }
  42. template< typename RandomAccessIterator, typename Distance >
  43. inline BOOST_CXX14_CONSTEXPR void advance_impl(RandomAccessIterator& it, Distance n, random_access_traversal_tag)
  44. {
  45. it += n;
  46. }
  47. } // namespace detail
  48. namespace advance_adl_barrier {
  49. template< typename InputIterator, typename Distance >
  50. inline BOOST_CXX14_CONSTEXPR void advance(InputIterator& it, Distance n)
  51. {
  52. detail::advance_impl(it, n, typename iterator_traversal< InputIterator >::type());
  53. }
  54. } // namespace advance_adl_barrier
  55. using namespace advance_adl_barrier;
  56. } // namespace iterators
  57. using namespace iterators::advance_adl_barrier;
  58. } // namespace boost
  59. #endif