counted.hpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. #include <range/v3/detail/prologue.hpp>
  25. namespace ranges
  26. {
  27. /// \addtogroup group-views
  28. /// @{
  29. template<typename I>
  30. struct counted_view : view_interface<counted_view<I>, finite>
  31. {
  32. private:
  33. friend range_access;
  34. I it_;
  35. iter_difference_t<I> n_;
  36. public:
  37. counted_view() = default;
  38. counted_view(I it, iter_difference_t<I> n)
  39. : it_(it)
  40. , n_(n)
  41. {
  42. RANGES_EXPECT(0 <= n_);
  43. }
  44. counted_iterator<I> begin() const
  45. {
  46. return make_counted_iterator(it_, n_);
  47. }
  48. default_sentinel_t end() const
  49. {
  50. return {};
  51. }
  52. auto size() const
  53. {
  54. return static_cast<detail::iter_size_t<I>>(n_);
  55. }
  56. };
  57. template<typename I>
  58. RANGES_INLINE_VAR constexpr bool enable_borrowed_range<counted_view<I>> = true;
  59. #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
  60. template<typename I>
  61. counted_view(I, iter_difference_t<I>)
  62. -> counted_view<I>;
  63. #endif
  64. namespace views
  65. {
  66. struct cpp20_counted_fn
  67. {
  68. template(typename I)(
  69. requires input_or_output_iterator<I> AND (!random_access_iterator<I>)) //
  70. subrange<counted_iterator<I>, default_sentinel_t> //
  71. operator()(I it, iter_difference_t<I> n) const
  72. {
  73. return {make_counted_iterator(std::move(it), n), default_sentinel};
  74. }
  75. template(typename I)(
  76. requires random_access_iterator<I>)
  77. subrange<I> operator()(I it, iter_difference_t<I> n) const
  78. {
  79. return {it, it + n};
  80. }
  81. };
  82. struct counted_fn
  83. {
  84. template(typename I)(
  85. requires input_or_output_iterator<I> AND (!random_access_iterator<I>)) //
  86. counted_view<I> operator()(I it, iter_difference_t<I> n) const
  87. {
  88. return {std::move(it), n};
  89. }
  90. template(typename I)(
  91. requires random_access_iterator<I>)
  92. subrange<I> operator()(I it, iter_difference_t<I> n) const
  93. {
  94. return {it, it + n};
  95. }
  96. };
  97. /// \relates counted_fn
  98. /// \ingroup group-views
  99. RANGES_INLINE_VARIABLE(counted_fn, counted)
  100. } // namespace views
  101. namespace cpp20
  102. {
  103. namespace views
  104. {
  105. RANGES_INLINE_VARIABLE(ranges::views::cpp20_counted_fn, counted)
  106. }
  107. } // namespace cpp20
  108. /// @}
  109. } // namespace ranges
  110. #include <range/v3/detail/epilogue.hpp>
  111. #include <range/v3/detail/satisfy_boost_range.hpp>
  112. RANGES_SATISFY_BOOST_RANGE(::ranges::counted_view)
  113. #endif