/// \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_HPP #define RANGES_V3_VIEW_GENERATE_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include namespace ranges { /// \addtogroup group-views /// @{ template struct generate_view : view_facade, infinite> { private: friend range_access; using result_t = invoke_result_t; semiregular_box_t gen_; detail::non_propagating_cache val_; struct cursor { private: generate_view * view_; public: cursor() = default; explicit cursor(generate_view * view) : view_(view) {} result_t && read() const { if(!view_->val_) view_->val_.emplace(view_->gen_()); return static_cast(static_cast(*view_->val_)); } void next() { if(view_->val_) view_->val_.reset(); else view_->gen_(); } }; cursor begin_cursor() { return cursor{this}; } unreachable_sentinel_t end_cursor() const { return {}; } public: generate_view() = default; explicit generate_view(G g) : gen_(std::move(g)) {} result_t & cached() { return *val_; } }; namespace views { struct generate_fn { template auto operator()(G g) const -> CPP_ret(generate_view)( // requires invocable && copy_constructible && std::is_object>>::value && constructible_from>, invoke_result_t> && assignable_from> &, invoke_result_t>) { return generate_view{std::move(g)}; } }; /// \relates generate_fn /// \ingroup group-views RANGES_INLINE_VARIABLE(generate_fn, generate) } // namespace views /// \@} } // namespace ranges #include RANGES_SATISFY_BOOST_RANGE(::ranges::generate_view) #endif