You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
3.4KB

  1. /// \file
  2. // Range v3 library
  3. //
  4. // Copyright Eric Niebler 2014-present
  5. //
  6. // Use, modification and distribution is subject to the
  7. // Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Project home: https://github.com/ericniebler/range-v3
  12. //
  13. #ifndef RANGES_V3_VIEW_COUNTED_HPP
  14. #define RANGES_V3_VIEW_COUNTED_HPP
  15. #include <utility>
  16. #include <range/v3/range_fwd.hpp>
  17. #include <range/v3/iterator/concepts.hpp>
  18. #include <range/v3/iterator/counted_iterator.hpp>
  19. #include <range/v3/iterator/default_sentinel.hpp>
  20. #include <range/v3/iterator/traits.hpp>
  21. #include <range/v3/utility/static_const.hpp>
  22. #include <range/v3/view/interface.hpp>
  23. #include <range/v3/view/subrange.hpp>
  24. namespace ranges
  25. {
  26. /// \addtogroup group-views
  27. /// @{
  28. template<typename I>
  29. struct counted_view : view_interface<counted_view<I>, finite>
  30. {
  31. private:
  32. friend range_access;
  33. I it_;
  34. iter_difference_t<I> n_;
  35. public:
  36. counted_view() = default;
  37. counted_view(I it, iter_difference_t<I> n)
  38. : it_(it)
  39. , n_(n)
  40. {
  41. RANGES_EXPECT(0 <= n_);
  42. }
  43. counted_iterator<I> begin() const
  44. {
  45. return make_counted_iterator(it_, n_);
  46. }
  47. default_sentinel_t end() const
  48. {
  49. return {};
  50. }
  51. auto size() const
  52. {
  53. return static_cast<detail::iter_size_t<I>>(n_);
  54. }
  55. };
  56. #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
  57. template<typename I>
  58. counted_view(I, iter_difference_t<I>)->counted_view<I>;
  59. #endif
  60. namespace views
  61. {
  62. struct cpp20_counted_fn
  63. {
  64. template<typename I>
  65. auto operator()(I it, iter_difference_t<I> n) const
  66. -> CPP_ret(subrange<counted_iterator<I>, default_sentinel_t>)( //
  67. requires input_or_output_iterator<I> && (!random_access_iterator<I>))
  68. {
  69. return {make_counted_iterator(std::move(it), n), default_sentinel};
  70. }
  71. template<typename I>
  72. auto operator()(I it, iter_difference_t<I> n) const
  73. -> CPP_ret(subrange<I>)( //
  74. requires random_access_iterator<I>)
  75. {
  76. return {it, it + n};
  77. }
  78. };
  79. struct counted_fn
  80. {
  81. template<typename I>
  82. auto operator()(I it, iter_difference_t<I> n) const
  83. -> CPP_ret(counted_view<I>)( //
  84. requires input_or_output_iterator<I> && (!random_access_iterator<I>))
  85. {
  86. return {std::move(it), n};
  87. }
  88. template<typename I>
  89. auto operator()(I it, iter_difference_t<I> n) const
  90. -> CPP_ret(subrange<I>)( //
  91. requires random_access_iterator<I>)
  92. {
  93. return {it, it + n};
  94. }
  95. };
  96. /// \relates counted_fn
  97. /// \ingroup group-views
  98. RANGES_INLINE_VARIABLE(counted_fn, counted)
  99. } // namespace views
  100. namespace cpp20
  101. {
  102. namespace views
  103. {
  104. RANGES_INLINE_VARIABLE(ranges::views::cpp20_counted_fn, counted)
  105. }
  106. } // namespace cpp20
  107. /// @}
  108. } // namespace ranges
  109. #include <range/v3/detail/satisfy_boost_range.hpp>
  110. RANGES_SATISFY_BOOST_RANGE(::ranges::counted_view)
  111. #endif