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.

121 line
3.2KB

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