Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:09:55

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2014-present
0005 //
0006 //  Use, modification and distribution is subject to the
0007 //  Boost Software License, Version 1.0. (See accompanying
0008 //  file LICENSE_1_0.txt or copy at
0009 //  http://www.boost.org/LICENSE_1_0.txt)
0010 //
0011 // Project home: https://github.com/ericniebler/range-v3
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     /// \addtogroup group-views
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         /// \relates generate_fn
0110         /// \ingroup group-views
0111         RANGES_INLINE_VARIABLE(generate_fn, generate)
0112     } // namespace views
0113     /// \@}
0114 } // namespace ranges
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