Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2013-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_TAKE_EXACTLY_HPP
0015 #define RANGES_V3_VIEW_TAKE_EXACTLY_HPP
0016 
0017 #include <type_traits>
0018 
0019 #include <range/v3/range_fwd.hpp>
0020 
0021 #include <range/v3/functional/bind_back.hpp>
0022 #include <range/v3/iterator/counted_iterator.hpp>
0023 #include <range/v3/iterator/default_sentinel.hpp>
0024 #include <range/v3/iterator/operations.hpp>
0025 #include <range/v3/iterator/traits.hpp>
0026 #include <range/v3/range/concepts.hpp>
0027 #include <range/v3/range/traits.hpp>
0028 #include <range/v3/utility/static_const.hpp>
0029 #include <range/v3/view/all.hpp>
0030 #include <range/v3/view/counted.hpp>
0031 #include <range/v3/view/interface.hpp>
0032 #include <range/v3/view/subrange.hpp>
0033 #include <range/v3/view/view.hpp>
0034 
0035 #include <range/v3/detail/prologue.hpp>
0036 
0037 namespace ranges
0038 {
0039     /// \cond
0040     namespace detail
0041     {
0042         template<typename Rng>
0043         struct is_random_access_common_
0044           : meta::bool_<(bool)random_access_range<Rng> && (bool)common_range<Rng>>
0045         {};
0046 
0047         // BUGBUG Per the discussion in https://github.com/ericniebler/stl2/issues/63,
0048         // it's unclear if we can infer anything from random_access_range<Rng> &&
0049         // common_range<Rng>
0050         template<typename Rng,
0051                  bool IsRandomAccessCommon /*= is_random_access_common_<Rng>::value*/>
0052         struct take_exactly_view_
0053           : view_interface<take_exactly_view_<Rng, IsRandomAccessCommon>, finite>
0054         {
0055         private:
0056             Rng rng_;
0057             range_difference_t<Rng> n_;
0058 
0059         public:
0060             take_exactly_view_() = default;
0061             take_exactly_view_(Rng rng, range_difference_t<Rng> n)
0062               : rng_(std::move(rng))
0063               , n_(n)
0064             {
0065                 RANGES_EXPECT(n >= 0);
0066             }
0067             counted_iterator<iterator_t<Rng>> begin()
0068             {
0069                 return {ranges::begin(rng_), n_};
0070             }
0071             template(typename BaseRng = Rng)(
0072                 requires range<BaseRng const>)
0073             counted_iterator<iterator_t<BaseRng const>> begin() const
0074             {
0075                 return {ranges::begin(rng_), n_};
0076             }
0077             default_sentinel_t end() const
0078             {
0079                 return {};
0080             }
0081             auto size() const
0082             {
0083                 return static_cast<detail::iter_size_t<iterator_t<Rng>>>(n_);
0084             }
0085             Rng base() const
0086             {
0087                 return rng_;
0088             }
0089         };
0090 
0091         template<typename Rng>
0092         struct take_exactly_view_<Rng, true>
0093           : view_interface<take_exactly_view_<Rng, true>, finite>
0094         {
0095         private:
0096             Rng rng_;
0097             range_difference_t<Rng> n_;
0098 
0099         public:
0100             take_exactly_view_() = default;
0101             take_exactly_view_(Rng rng, range_difference_t<Rng> n)
0102               : rng_(std::move(rng))
0103               , n_(n)
0104             {
0105                 RANGES_EXPECT(n >= 0);
0106                 RANGES_EXPECT(!(bool)sized_range<Rng> || n <= ranges::distance(rng_));
0107             }
0108             iterator_t<Rng> begin()
0109             {
0110                 return ranges::begin(rng_);
0111             }
0112             iterator_t<Rng> end()
0113             {
0114                 return ranges::begin(rng_) + n_;
0115             }
0116             CPP_auto_member
0117             auto CPP_fun(begin)()(const //
0118                 requires range<Rng const>)
0119             {
0120                 return ranges::begin(rng_);
0121             }
0122             CPP_auto_member
0123             auto CPP_fun(end)()(const //
0124                 requires range<Rng const>)
0125             {
0126                 return ranges::begin(rng_) + n_;
0127             }
0128             detail::iter_size_t<iterator_t<Rng>> size() const
0129             {
0130                 return static_cast<detail::iter_size_t<iterator_t<Rng>>>(n_);
0131             }
0132             Rng base() const
0133             {
0134                 return rng_;
0135             }
0136         };
0137     } // namespace detail
0138     /// \endcond
0139 
0140     /// \addtogroup group-views
0141     /// @{
0142     template<typename Rng>
0143     using take_exactly_view = detail::take_exactly_view_<Rng>;
0144 
0145     template<typename Rng, bool B>
0146     RANGES_INLINE_VAR constexpr bool //
0147         enable_borrowed_range<detail::take_exactly_view_<Rng, B>> = //
0148             enable_borrowed_range<Rng>;
0149 
0150     namespace views
0151     {
0152         struct take_exactly_base_fn
0153         {
0154         private:
0155             template<typename Rng>
0156             static constexpr take_exactly_view<all_t<Rng>> impl_(
0157                 Rng && rng, range_difference_t<Rng> n, input_range_tag)
0158             {
0159                 return {all(static_cast<Rng &&>(rng)), n};
0160             }
0161             template(typename Rng)(
0162                 requires borrowed_range<Rng>)
0163             static constexpr subrange<iterator_t<Rng>> impl_(Rng && rng,
0164                                                              range_difference_t<Rng> n,
0165                                                              random_access_range_tag)
0166             {
0167                 return {begin(rng), next(begin(rng), n)};
0168             }
0169 
0170         public:
0171             template(typename Rng)(
0172                 requires viewable_range<Rng> AND input_range<Rng>)
0173             constexpr auto operator()(Rng && rng, range_difference_t<Rng> n) const
0174             {
0175                 return take_exactly_base_fn::impl_(
0176                     static_cast<Rng &&>(rng), n, range_tag_of<Rng>{});
0177             }
0178         };
0179 
0180         struct take_exactly_fn : take_exactly_base_fn
0181         {
0182             using take_exactly_base_fn::operator();
0183 
0184             template(typename Int)(
0185                 requires detail::integer_like_<Int>)
0186             constexpr auto operator()(Int n) const
0187             {
0188                 return make_view_closure(bind_back(take_exactly_base_fn{}, n));
0189             }
0190         };
0191 
0192         /// \relates take_exactly_fn
0193         /// \ingroup group-views
0194         RANGES_INLINE_VARIABLE(take_exactly_fn, take_exactly)
0195     } // namespace views
0196     /// @}
0197 } // namespace ranges
0198 
0199 #include <range/v3/detail/epilogue.hpp>
0200 #include <range/v3/detail/satisfy_boost_range.hpp>
0201 RANGES_SATISFY_BOOST_RANGE(::ranges::detail::take_exactly_view_)
0202 
0203 #endif