repeat.hpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /// \file
  2. // Range v3 library
  3. //
  4. // Copyright Eric Niebler 2013-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_REPEAT_HPP
  14. #define RANGES_V3_VIEW_REPEAT_HPP
  15. #include <utility>
  16. #include <range/v3/range_fwd.hpp>
  17. #include <range/v3/iterator/unreachable_sentinel.hpp>
  18. #include <range/v3/range/concepts.hpp>
  19. #include <range/v3/utility/semiregular_box.hpp>
  20. #include <range/v3/utility/static_const.hpp>
  21. #include <range/v3/view/facade.hpp>
  22. #include <range/v3/detail/prologue.hpp>
  23. namespace ranges
  24. {
  25. /// \addtogroup group-views
  26. /// @{
  27. // Ordinarily, a view shouldn't contain its elements. This is so that copying
  28. // and assigning ranges is O(1), and also so that in the event of element
  29. // mutation, all the copies of the range see the mutation the same way. The
  30. // repeat_view *does* own its lone element, though. This is OK because:
  31. // - O(N) copying is fine when N==1 as it is in this case, and
  32. // - The element is immutable, so there is no potential for incorrect
  33. // semantics.
  34. template<typename Val>
  35. struct repeat_view : view_facade<repeat_view<Val>, infinite>
  36. {
  37. private:
  38. semiregular_box_t<Val> value_;
  39. friend range_access;
  40. struct cursor
  41. {
  42. private:
  43. Val const * value_;
  44. std::ptrdiff_t n_ = 0;
  45. public:
  46. cursor() = default;
  47. explicit cursor(Val const & value)
  48. : value_(std::addressof(value))
  49. {}
  50. Val const & read() const noexcept
  51. {
  52. return *value_;
  53. }
  54. bool equal(cursor const & that) const
  55. {
  56. return n_ == that.n_;
  57. }
  58. void next()
  59. {
  60. ++n_;
  61. }
  62. void prev()
  63. {
  64. --n_;
  65. }
  66. void advance(std::ptrdiff_t d)
  67. {
  68. n_ += d;
  69. }
  70. std::ptrdiff_t distance_to(cursor const & that) const
  71. {
  72. return that.n_ - n_;
  73. }
  74. };
  75. cursor begin_cursor() const
  76. {
  77. return cursor{value_};
  78. }
  79. unreachable_sentinel_t end_cursor() const
  80. {
  81. return unreachable;
  82. }
  83. public:
  84. repeat_view() = default;
  85. constexpr explicit repeat_view(Val value)
  86. : value_(detail::move(value))
  87. {}
  88. };
  89. namespace views
  90. {
  91. struct repeat_fn
  92. {
  93. template(typename Val)(
  94. requires copy_constructible<Val>)
  95. repeat_view<Val> operator()(Val value) const
  96. {
  97. return repeat_view<Val>{std::move(value)};
  98. }
  99. };
  100. /// \relates repeat_fn
  101. /// \ingroup group-views
  102. RANGES_INLINE_VARIABLE(repeat_fn, repeat)
  103. } // namespace views
  104. /// @}
  105. } // namespace ranges
  106. #include <range/v3/detail/epilogue.hpp>
  107. #include <range/v3/detail/satisfy_boost_range.hpp>
  108. RANGES_SATISFY_BOOST_RANGE(::ranges::repeat_view)
  109. #endif