File indexing completed on 2025-01-18 10:09:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
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
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
0048
0049
0050 template<typename Rng,
0051 bool IsRandomAccessCommon >
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 }
0138
0139
0140
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
0193
0194 RANGES_INLINE_VARIABLE(take_exactly_fn, take_exactly)
0195 }
0196
0197 }
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