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_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     /// \addtogroup group-views
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         /// \relates generate_n_fn
0117         /// \ingroup group-views
0118         RANGES_INLINE_VARIABLE(generate_n_fn, generate_n)
0119     } // namespace views
0120     /// @}
0121 } // namespace ranges
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