Horizon
Loading...
Searching...
No Matches
generate.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_HPP
15#define RANGES_V3_VIEW_GENERATE_HPP
16
17#include <type_traits>
18#include <utility>
19
20#include <meta/meta.hpp>
21
23
31#include <range/v3/utility/static_const.hpp>
33
34#include <range/v3/detail/prologue.hpp>
35
36namespace ranges
37{
40 template<typename G>
41 struct generate_view : view_facade<generate_view<G>, infinite>
42 {
43 private:
44 friend range_access;
45 using result_t = invoke_result_t<G &>;
46 semiregular_box_t<G> gen_;
47 detail::non_propagating_cache<result_t> val_;
48 struct cursor
49 {
50 private:
52
53 public:
54 cursor() = default;
55 explicit cursor(generate_view * view)
56 : view_(view)
57 {}
58 result_t && read() const
59 {
60 if(!view_->val_)
61 view_->val_.emplace(view_->gen_());
62 return static_cast<result_t &&>(static_cast<result_t &>(*view_->val_));
63 }
64 void next()
65 {
66 if(view_->val_)
67 view_->val_.reset();
68 else
69 static_cast<void>(view_->gen_());
70 }
71 };
72 cursor begin_cursor()
73 {
74 return cursor{this};
75 }
76 unreachable_sentinel_t end_cursor() const
77 {
78 return {};
79 }
80
81 public:
82 generate_view() = default;
83 explicit generate_view(G g)
84 : gen_(std::move(g))
85 {}
86 result_t & cached()
87 {
88 return *val_;
89 }
90 };
91
92 namespace views
93 {
95 {
96 template(typename G)(
97 requires invocable<G &> AND copy_constructible<G> AND
98 std::is_object<detail::decay_t<invoke_result_t<G &>>>::value AND
99 constructible_from<detail::decay_t<invoke_result_t<G &>>,
100 invoke_result_t<G &>> AND
101 assignable_from<detail::decay_t<invoke_result_t<G &>> &,
102 invoke_result_t<G &>>)
103 generate_view<G> operator()(G g) const
104 {
105 return generate_view<G>{std::move(g)};
106 }
107 };
108
111 RANGES_INLINE_VARIABLE(generate_fn, generate)
112 } // namespace views
114} // namespace ranges
115
116#include <range/v3/detail/epilogue.hpp>
117#include <range/v3/detail/satisfy_boost_range.hpp>
118RANGES_SATISFY_BOOST_RANGE(::ranges::generate_view)
119
120#endif
The invocable concept.
The view_ concept.
Tiny meta-programming library.
Definition generate.hpp:42
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 generate.hpp:95