advance.hpp 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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
  15. advance_impl(
  16. InputIterator& it
  17. , Distance n
  18. , incrementable_traversal_tag
  19. )
  20. {
  21. while (n > 0) {
  22. ++it;
  23. --n;
  24. }
  25. }
  26. template <typename BidirectionalIterator, typename Distance>
  27. inline BOOST_CXX14_CONSTEXPR void
  28. advance_impl(
  29. BidirectionalIterator& it
  30. , Distance n
  31. , bidirectional_traversal_tag
  32. )
  33. {
  34. if (n >= 0) {
  35. while (n > 0) {
  36. ++it;
  37. --n;
  38. }
  39. }
  40. else {
  41. while (n < 0) {
  42. --it;
  43. ++n;
  44. }
  45. }
  46. }
  47. template <typename RandomAccessIterator, typename Distance>
  48. inline BOOST_CXX14_CONSTEXPR void
  49. advance_impl(
  50. RandomAccessIterator& it
  51. , Distance n
  52. , random_access_traversal_tag
  53. )
  54. {
  55. it += n;
  56. }
  57. }
  58. namespace advance_adl_barrier {
  59. template <typename InputIterator, typename Distance>
  60. inline BOOST_CXX14_CONSTEXPR void
  61. advance(InputIterator& it, Distance n)
  62. {
  63. detail::advance_impl(
  64. it, n, typename iterator_traversal<InputIterator>::type()
  65. );
  66. }
  67. }
  68. using namespace advance_adl_barrier;
  69. } // namespace iterators
  70. using namespace iterators::advance_adl_barrier;
  71. } // namespace boost
  72. #endif