/// \file // Range v3 library // // Copyright Eric Niebler 2014-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_GENERATE_N_HPP #define RANGES_V3_VIEW_GENERATE_N_HPP #include #include #include #include #include #include #include #include #include #include #include #include namespace ranges { /// \addtogroup group-views /// @{ template struct generate_n_view : view_facade, finite> { private: friend range_access; using result_t = invoke_result_t; semiregular_box_t gen_; detail::non_propagating_cache val_; std::size_t n_; struct cursor { private: generate_n_view * rng_; public: cursor() = default; explicit cursor(generate_n_view * rng) : rng_(rng) {} bool equal(default_sentinel_t) const { return 0 == rng_->n_; } result_t && read() const { if(!rng_->val_) rng_->val_.emplace(rng_->gen_()); return static_cast(static_cast(*rng_->val_)); } void next() { RANGES_EXPECT(0 != rng_->n_); if(rng_->val_) rng_->val_.reset(); else rng_->gen_(); --rng_->n_; } }; cursor begin_cursor() { return cursor{this}; } public: generate_n_view() = default; explicit generate_n_view(G g, std::size_t n) : gen_(std::move(g)) , n_(n) {} result_t & cached() { return *val_; } std::size_t size() const { return n_; } }; namespace views { struct generate_n_fn { template auto operator()(G g, std::size_t n) const -> CPP_ret(generate_n_view)( // requires invocable && copy_constructible && std::is_object>>::value && constructible_from>, invoke_result_t> && assignable_from> &, invoke_result_t>) { return generate_n_view{std::move(g), n}; } }; /// \relates generate_n_fn /// \ingroup group-views RANGES_INLINE_VARIABLE(generate_n_fn, generate_n) } // namespace views /// @} } // namespace ranges #include RANGES_SATISFY_BOOST_RANGE(::ranges::generate_n_view) #endif