File indexing completed on 2025-01-18 10:09:55
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef RANGES_V3_VIEW_GENERATE_HPP
0015 #define RANGES_V3_VIEW_GENERATE_HPP
0016
0017 #include <type_traits>
0018 #include <utility>
0019
0020 #include <meta/meta.hpp>
0021
0022 #include <range/v3/range_fwd.hpp>
0023
0024 #include <range/v3/functional/invoke.hpp>
0025 #include <range/v3/iterator/unreachable_sentinel.hpp>
0026 #include <range/v3/range/access.hpp>
0027 #include <range/v3/range/primitives.hpp>
0028 #include <range/v3/range/traits.hpp>
0029 #include <range/v3/utility/optional.hpp>
0030 #include <range/v3/utility/semiregular_box.hpp>
0031 #include <range/v3/utility/static_const.hpp>
0032 #include <range/v3/view/facade.hpp>
0033
0034 #include <range/v3/detail/prologue.hpp>
0035
0036 namespace ranges
0037 {
0038
0039
0040 template<typename G>
0041 struct generate_view : view_facade<generate_view<G>, infinite>
0042 {
0043 private:
0044 friend range_access;
0045 using result_t = invoke_result_t<G &>;
0046 semiregular_box_t<G> gen_;
0047 detail::non_propagating_cache<result_t> val_;
0048 struct cursor
0049 {
0050 private:
0051 generate_view * view_;
0052
0053 public:
0054 cursor() = default;
0055 explicit cursor(generate_view * view)
0056 : view_(view)
0057 {}
0058 result_t && read() const
0059 {
0060 if(!view_->val_)
0061 view_->val_.emplace(view_->gen_());
0062 return static_cast<result_t &&>(static_cast<result_t &>(*view_->val_));
0063 }
0064 void next()
0065 {
0066 if(view_->val_)
0067 view_->val_.reset();
0068 else
0069 static_cast<void>(view_->gen_());
0070 }
0071 };
0072 cursor begin_cursor()
0073 {
0074 return cursor{this};
0075 }
0076 unreachable_sentinel_t end_cursor() const
0077 {
0078 return {};
0079 }
0080
0081 public:
0082 generate_view() = default;
0083 explicit generate_view(G g)
0084 : gen_(std::move(g))
0085 {}
0086 result_t & cached()
0087 {
0088 return *val_;
0089 }
0090 };
0091
0092 namespace views
0093 {
0094 struct generate_fn
0095 {
0096 template(typename G)(
0097 requires invocable<G &> AND copy_constructible<G> AND
0098 std::is_object<detail::decay_t<invoke_result_t<G &>>>::value AND
0099 constructible_from<detail::decay_t<invoke_result_t<G &>>,
0100 invoke_result_t<G &>> AND
0101 assignable_from<detail::decay_t<invoke_result_t<G &>> &,
0102 invoke_result_t<G &>>)
0103 generate_view<G> operator()(G g) const
0104 {
0105 return generate_view<G>{std::move(g)};
0106 }
0107 };
0108
0109
0110
0111 RANGES_INLINE_VARIABLE(generate_fn, generate)
0112 }
0113
0114 }
0115
0116 #include <range/v3/detail/epilogue.hpp>
0117 #include <range/v3/detail/satisfy_boost_range.hpp>
0118 RANGES_SATISFY_BOOST_RANGE(::ranges::generate_view)
0119
0120 #endif