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_N_HPP
0015 #define RANGES_V3_VIEW_GENERATE_N_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/default_sentinel.hpp>
0026 #include <range/v3/range/primitives.hpp>
0027 #include <range/v3/range/traits.hpp>
0028 #include <range/v3/utility/semiregular_box.hpp>
0029 #include <range/v3/utility/static_const.hpp>
0030 #include <range/v3/view/facade.hpp>
0031 #include <range/v3/view/generate.hpp>
0032
0033 #include <range/v3/detail/prologue.hpp>
0034
0035 namespace ranges
0036 {
0037
0038
0039 template<typename G>
0040 struct generate_n_view : view_facade<generate_n_view<G>, finite>
0041 {
0042 private:
0043 friend range_access;
0044 using result_t = invoke_result_t<G &>;
0045 semiregular_box_t<G> gen_;
0046 detail::non_propagating_cache<result_t> val_;
0047 std::size_t n_;
0048 struct cursor
0049 {
0050 private:
0051 generate_n_view * rng_;
0052
0053 public:
0054 cursor() = default;
0055 explicit cursor(generate_n_view * rng)
0056 : rng_(rng)
0057 {}
0058 bool equal(default_sentinel_t) const
0059 {
0060 return 0 == rng_->n_;
0061 }
0062 result_t && read() const
0063 {
0064 if(!rng_->val_)
0065 rng_->val_.emplace(rng_->gen_());
0066 return static_cast<result_t &&>(static_cast<result_t &>(*rng_->val_));
0067 }
0068 void next()
0069 {
0070 RANGES_EXPECT(0 != rng_->n_);
0071 if(rng_->val_)
0072 rng_->val_.reset();
0073 else
0074 static_cast<void>(rng_->gen_());
0075 --rng_->n_;
0076 }
0077 };
0078 cursor begin_cursor()
0079 {
0080 return cursor{this};
0081 }
0082
0083 public:
0084 generate_n_view() = default;
0085 explicit generate_n_view(G g, std::size_t n)
0086 : gen_(std::move(g))
0087 , n_(n)
0088 {}
0089 result_t & cached()
0090 {
0091 return *val_;
0092 }
0093 std::size_t size() const
0094 {
0095 return n_;
0096 }
0097 };
0098
0099 namespace views
0100 {
0101 struct generate_n_fn
0102 {
0103 template(typename G)(
0104 requires invocable<G &> AND copy_constructible<G> AND
0105 std::is_object<detail::decay_t<invoke_result_t<G &>>>::value AND
0106 constructible_from<detail::decay_t<invoke_result_t<G &>>,
0107 invoke_result_t<G &>> AND
0108 assignable_from<detail::decay_t<invoke_result_t<G &>> &,
0109 invoke_result_t<G &>>)
0110 generate_n_view<G> operator()(G g, std::size_t n) const
0111 {
0112 return generate_n_view<G>{std::move(g), n};
0113 }
0114 };
0115
0116
0117
0118 RANGES_INLINE_VARIABLE(generate_n_fn, generate_n)
0119 }
0120
0121 }
0122
0123 #include <range/v3/detail/epilogue.hpp>
0124 #include <range/v3/detail/satisfy_boost_range.hpp>
0125 RANGES_SATISFY_BOOST_RANGE(::ranges::generate_n_view)
0126
0127 #endif