Horizon
repeat.hpp
Go to the documentation of this file.
1 // 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 
14 #ifndef RANGES_V3_VIEW_REPEAT_HPP
15 #define RANGES_V3_VIEW_REPEAT_HPP
16 
17 #include <utility>
18 
19 #include <range/v3/range_fwd.hpp>
20 
24 #include <range/v3/utility/static_const.hpp>
25 #include <range/v3/view/facade.hpp>
26 
27 #include <range/v3/detail/prologue.hpp>
28 
29 namespace ranges
30 {
33 
34  // Ordinarily, a view shouldn't contain its elements. This is so that copying
35  // and assigning ranges is O(1), and also so that in the event of element
36  // mutation, all the copies of the range see the mutation the same way. The
37  // repeat_view *does* own its lone element, though. This is OK because:
38  // - O(N) copying is fine when N==1 as it is in this case, and
39  // - The element is immutable, so there is no potential for incorrect
40  // semantics.
41  template<typename Val>
42  struct repeat_view : view_facade<repeat_view<Val>, infinite>
43  {
44  private:
45  semiregular_box_t<Val> value_;
46  friend range_access;
47 
48  struct cursor
49  {
50  private:
51  Val const * value_;
52  std::ptrdiff_t n_ = 0;
53 
54  public:
55  cursor() = default;
56  explicit cursor(Val const & value)
57  : value_(std::addressof(value))
58  {}
59  Val const & read() const noexcept
60  {
61  return *value_;
62  }
63  bool equal(cursor const & that) const
64  {
65  return n_ == that.n_;
66  }
67  void next()
68  {
69  ++n_;
70  }
71  void prev()
72  {
73  --n_;
74  }
75  void advance(std::ptrdiff_t d)
76  {
77  n_ += d;
78  }
79  std::ptrdiff_t distance_to(cursor const & that) const
80  {
81  return that.n_ - n_;
82  }
83  };
84  cursor begin_cursor() const
85  {
86  return cursor{value_};
87  }
88  unreachable_sentinel_t end_cursor() const
89  {
90  return unreachable;
91  }
92 
93  public:
94  repeat_view() = default;
95  constexpr explicit repeat_view(Val value)
96  : value_(detail::move(value))
97  {}
98  };
99 
100  namespace views
101  {
102  struct repeat_fn
103  {
104  template(typename Val)(
105  requires copy_constructible<Val>)
106  repeat_view<Val> operator()(Val value) const
107  {
108  return repeat_view<Val>{std::move(value)};
109  }
110  };
111 
115  } // namespace views
117 } // namespace ranges
118 
119 #include <range/v3/detail/epilogue.hpp>
120 #include <range/v3/detail/satisfy_boost_range.hpp>
121 RANGES_SATISFY_BOOST_RANGE(::ranges::repeat_view)
122 
123 #endif
RANGES_INLINE_VARIABLE(detail::to_container_fn< detail::from_range< std::vector >>, to_vector) template< template< typename... > class ContT > auto to(RANGES_HIDDEN_DETAIL(detail
For initializing a container of the specified type with the elements of an Range.
Definition: conversion.hpp:399
Definition: repeat.hpp:43
Definition: unreachable_sentinel.hpp:27
A utility for constructing a view from a (derived) type that implements begin and end cursors.
Definition: facade.hpp:66
Definition: repeat.hpp:103