File: repeat.hpp

package info (click to toggle)
range-v3 0.12.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,652 kB
  • sloc: cpp: 76,839; xml: 226; sh: 89; python: 34; makefile: 19; perl: 15
file content (123 lines) | stat: -rw-r--r-- 3,299 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/// \file
// Range v3 library
//
//  Copyright Eric Niebler 2013-present
//
//  Use, modification and distribution is subject to the
//  Boost Software License, Version 1.0. (See accompanying
//  file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//
// Project home: https://github.com/ericniebler/range-v3
//

#ifndef RANGES_V3_VIEW_REPEAT_HPP
#define RANGES_V3_VIEW_REPEAT_HPP

#include <utility>

#include <range/v3/range_fwd.hpp>

#include <range/v3/iterator/unreachable_sentinel.hpp>
#include <range/v3/range/concepts.hpp>
#include <range/v3/utility/semiregular_box.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/view/facade.hpp>

#include <range/v3/detail/prologue.hpp>

namespace ranges
{
    /// \addtogroup group-views
    /// @{

    // Ordinarily, a view shouldn't contain its elements. This is so that copying
    // and assigning ranges is O(1), and also so that in the event of element
    // mutation, all the copies of the range see the mutation the same way. The
    // repeat_view *does* own its lone element, though. This is OK because:
    //  - O(N) copying is fine when N==1 as it is in this case, and
    //  - The element is immutable, so there is no potential for incorrect
    //    semantics.
    template<typename Val>
    struct repeat_view : view_facade<repeat_view<Val>, infinite>
    {
    private:
        semiregular_box_t<Val> value_;
        friend range_access;

        struct cursor
        {
        private:
            Val const * value_;
            std::ptrdiff_t n_ = 0;

        public:
            cursor() = default;
            explicit cursor(Val const & value)
              : value_(std::addressof(value))
            {}
            Val const & read() const noexcept
            {
                return *value_;
            }
            bool equal(cursor const & that) const
            {
                return n_ == that.n_;
            }
            void next()
            {
                ++n_;
            }
            void prev()
            {
                --n_;
            }
            void advance(std::ptrdiff_t d)
            {
                n_ += d;
            }
            std::ptrdiff_t distance_to(cursor const & that) const
            {
                return that.n_ - n_;
            }
        };
        cursor begin_cursor() const
        {
            return cursor{value_};
        }
        unreachable_sentinel_t end_cursor() const
        {
            return unreachable;
        }

    public:
        repeat_view() = default;
        constexpr explicit repeat_view(Val value)
          : value_(detail::move(value))
        {}
    };

    namespace views
    {
        struct repeat_fn
        {
            template(typename Val)(
                requires copy_constructible<Val>)
            repeat_view<Val> operator()(Val value) const
            {
                return repeat_view<Val>{std::move(value)};
            }
        };

        /// \relates repeat_fn
        /// \ingroup group-views
        RANGES_INLINE_VARIABLE(repeat_fn, repeat)
    } // namespace views
    /// @}
} // namespace ranges

#include <range/v3/detail/epilogue.hpp>
#include <range/v3/detail/satisfy_boost_range.hpp>
RANGES_SATISFY_BOOST_RANGE(::ranges::repeat_view)

#endif