Horizon
Loading...
Searching...
No Matches
generate_n.hpp
Go to the documentation of this file.
1
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
14#ifndef RANGES_V3_VIEW_GENERATE_N_HPP
15#define RANGES_V3_VIEW_GENERATE_N_HPP
16
17#include <type_traits>
18#include <utility>
19
20#include <meta/meta.hpp>
21
23
29#include <range/v3/utility/static_const.hpp>
32
33#include <range/v3/detail/prologue.hpp>
34
35namespace ranges
36{
39 template<typename G>
40 struct generate_n_view : view_facade<generate_n_view<G>, finite>
41 {
42 private:
43 friend range_access;
44 using result_t = invoke_result_t<G &>;
45 semiregular_box_t<G> gen_;
46 detail::non_propagating_cache<result_t> val_;
47 std::size_t n_;
48 struct cursor
49 {
50 private:
51 generate_n_view * rng_;
52
53 public:
54 cursor() = default;
55 explicit cursor(generate_n_view * rng)
56 : rng_(rng)
57 {}
58 bool equal(default_sentinel_t) const
59 {
60 return 0 == rng_->n_;
61 }
62 result_t && read() const
63 {
64 if(!rng_->val_)
65 rng_->val_.emplace(rng_->gen_());
66 return static_cast<result_t &&>(static_cast<result_t &>(*rng_->val_));
67 }
68 void next()
69 {
70 RANGES_EXPECT(0 != rng_->n_);
71 if(rng_->val_)
72 rng_->val_.reset();
73 else
74 static_cast<void>(rng_->gen_());
75 --rng_->n_;
76 }
77 };
78 cursor begin_cursor()
79 {
80 return cursor{this};
81 }
82
83 public:
84 generate_n_view() = default;
85 explicit generate_n_view(G g, std::size_t n)
86 : gen_(std::move(g))
87 , n_(n)
88 {}
89 result_t & cached()
90 {
91 return *val_;
92 }
93 std::size_t size() const
94 {
95 return n_;
96 }
97 };
98
99 namespace views
100 {
102 {
103 template(typename G)(
104 requires invocable<G &> AND copy_constructible<G> AND
105 std::is_object<detail::decay_t<invoke_result_t<G &>>>::value AND
106 constructible_from<detail::decay_t<invoke_result_t<G &>>,
107 invoke_result_t<G &>> AND
108 assignable_from<detail::decay_t<invoke_result_t<G &>> &,
109 invoke_result_t<G &>>)
110 generate_n_view<G> operator()(G g, std::size_t n) const
111 {
112 return generate_n_view<G>{std::move(g), n};
113 }
114 };
115
118 RANGES_INLINE_VARIABLE(generate_n_fn, generate_n)
119 } // namespace views
121} // namespace ranges
122
123#include <range/v3/detail/epilogue.hpp>
124#include <range/v3/detail/satisfy_boost_range.hpp>
125RANGES_SATISFY_BOOST_RANGE(::ranges::generate_n_view)
126
127#endif
The invocable concept.
Tiny meta-programming library.
Definition default_sentinel.hpp:26
Definition generate_n.hpp:41
A utility for constructing a view from a (derived) type that implements begin and end cursors.
Definition facade.hpp:66
Definition generate_n.hpp:102