File indexing completed on 2026-05-03 08:13:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___CXX03___RANGES_REPEAT_VIEW_H
0011 #define _LIBCPP___CXX03___RANGES_REPEAT_VIEW_H
0012
0013 #include <__cxx03/__assert>
0014 #include <__cxx03/__concepts/constructible.h>
0015 #include <__cxx03/__concepts/same_as.h>
0016 #include <__cxx03/__concepts/semiregular.h>
0017 #include <__cxx03/__config>
0018 #include <__cxx03/__iterator/concepts.h>
0019 #include <__cxx03/__iterator/iterator_traits.h>
0020 #include <__cxx03/__iterator/unreachable_sentinel.h>
0021 #include <__cxx03/__memory/addressof.h>
0022 #include <__cxx03/__ranges/iota_view.h>
0023 #include <__cxx03/__ranges/movable_box.h>
0024 #include <__cxx03/__ranges/view_interface.h>
0025 #include <__cxx03/__type_traits/decay.h>
0026 #include <__cxx03/__type_traits/is_object.h>
0027 #include <__cxx03/__type_traits/make_unsigned.h>
0028 #include <__cxx03/__type_traits/remove_cv.h>
0029 #include <__cxx03/__utility/forward.h>
0030 #include <__cxx03/__utility/in_place.h>
0031 #include <__cxx03/__utility/move.h>
0032 #include <__cxx03/__utility/piecewise_construct.h>
0033 #include <__cxx03/tuple>
0034
0035 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0036 # pragma GCC system_header
0037 #endif
0038
0039 _LIBCPP_PUSH_MACROS
0040 #include <__cxx03/__undef_macros>
0041
0042 _LIBCPP_BEGIN_NAMESPACE_STD
0043
0044 #if _LIBCPP_STD_VER >= 23
0045
0046 namespace ranges {
0047
0048 template <class _Tp>
0049 concept __integer_like_with_usable_difference_type =
0050 __signed_integer_like<_Tp> || (__integer_like<_Tp> && weakly_incrementable<_Tp>);
0051
0052 template <class _Tp>
0053 struct __repeat_view_iterator_difference {
0054 using type = _IotaDiffT<_Tp>;
0055 };
0056
0057 template <__signed_integer_like _Tp>
0058 struct __repeat_view_iterator_difference<_Tp> {
0059 using type = _Tp;
0060 };
0061
0062 template <class _Tp>
0063 using __repeat_view_iterator_difference_t = typename __repeat_view_iterator_difference<_Tp>::type;
0064
0065 namespace views::__drop {
0066 struct __fn;
0067 }
0068
0069 namespace views::__take {
0070 struct __fn;
0071 }
0072
0073 template <move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
0074 requires(is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>> &&
0075 (__integer_like_with_usable_difference_type<_Bound> || same_as<_Bound, unreachable_sentinel_t>))
0076 class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS repeat_view : public view_interface<repeat_view<_Tp, _Bound>> {
0077 friend struct views::__take::__fn;
0078 friend struct views::__drop::__fn;
0079 class __iterator;
0080
0081 public:
0082 _LIBCPP_HIDE_FROM_ABI repeat_view()
0083 requires default_initializable<_Tp>
0084 = default;
0085
0086 _LIBCPP_HIDE_FROM_ABI constexpr explicit repeat_view(const _Tp& __value, _Bound __bound_sentinel = _Bound())
0087 requires copy_constructible<_Tp>
0088 : __value_(in_place, __value), __bound_(__bound_sentinel) {
0089 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
0090 _LIBCPP_ASSERT_UNCATEGORIZED(__bound_ >= 0, "The value of bound must be greater than or equal to 0");
0091 }
0092
0093 _LIBCPP_HIDE_FROM_ABI constexpr explicit repeat_view(_Tp&& __value, _Bound __bound_sentinel = _Bound())
0094 : __value_(in_place, std::move(__value)), __bound_(__bound_sentinel) {
0095 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
0096 _LIBCPP_ASSERT_UNCATEGORIZED(__bound_ >= 0, "The value of bound must be greater than or equal to 0");
0097 }
0098
0099 template <class... _TpArgs, class... _BoundArgs>
0100 requires(constructible_from<_Tp, _TpArgs...> && constructible_from<_Bound, _BoundArgs...>)
0101 _LIBCPP_HIDE_FROM_ABI constexpr explicit repeat_view(
0102 piecewise_construct_t, tuple<_TpArgs...> __value_args, tuple<_BoundArgs...> __bound_args = tuple<>{})
0103 : __value_(in_place, std::make_from_tuple<_Tp>(std::move(__value_args))),
0104 __bound_(std::make_from_tuple<_Bound>(std::move(__bound_args))) {
0105 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
0106 _LIBCPP_ASSERT_UNCATEGORIZED(
0107 __bound_ >= 0, "The behavior is undefined if Bound is not unreachable_sentinel_t and bound is negative");
0108 }
0109
0110 _LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() const { return __iterator(std::addressof(*__value_)); }
0111
0112 _LIBCPP_HIDE_FROM_ABI constexpr __iterator end() const
0113 requires(!same_as<_Bound, unreachable_sentinel_t>)
0114 {
0115 return __iterator(std::addressof(*__value_), __bound_);
0116 }
0117
0118 _LIBCPP_HIDE_FROM_ABI constexpr unreachable_sentinel_t end() const noexcept { return unreachable_sentinel; }
0119
0120 _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
0121 requires(!same_as<_Bound, unreachable_sentinel_t>)
0122 {
0123 return std::__to_unsigned_like(__bound_);
0124 }
0125
0126 private:
0127 _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Tp> __value_;
0128 _LIBCPP_NO_UNIQUE_ADDRESS _Bound __bound_ = _Bound();
0129 };
0130
0131 template <class _Tp, class _Bound = unreachable_sentinel_t>
0132 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
0133
0134
0135 template <move_constructible _Tp, semiregular _Bound>
0136 requires(is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>> &&
0137 (__integer_like_with_usable_difference_type<_Bound> || same_as<_Bound, unreachable_sentinel_t>))
0138 class repeat_view<_Tp, _Bound>::__iterator {
0139 friend class repeat_view;
0140
0141 using _IndexT = conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
0142
0143 _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(const _Tp* __value, _IndexT __bound_sentinel = _IndexT())
0144 : __value_(__value), __current_(__bound_sentinel) {}
0145
0146 public:
0147 using iterator_concept = random_access_iterator_tag;
0148 using iterator_category = random_access_iterator_tag;
0149 using value_type = _Tp;
0150 using difference_type = __repeat_view_iterator_difference_t<_IndexT>;
0151
0152 _LIBCPP_HIDE_FROM_ABI __iterator() = default;
0153
0154 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const noexcept { return *__value_; }
0155
0156 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
0157 ++__current_;
0158 return *this;
0159 }
0160
0161 _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) {
0162 auto __tmp = *this;
0163 ++*this;
0164 return __tmp;
0165 }
0166
0167 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--() {
0168 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
0169 _LIBCPP_ASSERT_UNCATEGORIZED(__current_ > 0, "The value of bound must be greater than or equal to 0");
0170 --__current_;
0171 return *this;
0172 }
0173
0174 _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int) {
0175 auto __tmp = *this;
0176 --*this;
0177 return __tmp;
0178 }
0179
0180 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n) {
0181 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
0182 _LIBCPP_ASSERT_UNCATEGORIZED(__current_ + __n >= 0, "The value of bound must be greater than or equal to 0");
0183 __current_ += __n;
0184 return *this;
0185 }
0186
0187 _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n) {
0188 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
0189 _LIBCPP_ASSERT_UNCATEGORIZED(__current_ - __n >= 0, "The value of bound must be greater than or equal to 0");
0190 __current_ -= __n;
0191 return *this;
0192 }
0193
0194 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](difference_type __n) const noexcept { return *(*this + __n); }
0195
0196 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) {
0197 return __x.__current_ == __y.__current_;
0198 }
0199
0200 _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y) {
0201 return __x.__current_ <=> __y.__current_;
0202 }
0203
0204 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(__iterator __i, difference_type __n) {
0205 __i += __n;
0206 return __i;
0207 }
0208
0209 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, __iterator __i) {
0210 __i += __n;
0211 return __i;
0212 }
0213
0214 _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(__iterator __i, difference_type __n) {
0215 __i -= __n;
0216 return __i;
0217 }
0218
0219 _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) {
0220 return static_cast<difference_type>(__x.__current_) - static_cast<difference_type>(__y.__current_);
0221 }
0222
0223 private:
0224 const _Tp* __value_ = nullptr;
0225 _IndexT __current_ = _IndexT();
0226 };
0227
0228
0229 namespace views {
0230 namespace __repeat {
0231 struct __fn {
0232 template <class _Tp>
0233 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Tp&& __value)
0234 noexcept(noexcept(ranges::repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value))))
0235 -> decltype( ranges::repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value)))
0236 { return ranges::repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value)); }
0237
0238 template <class _Tp, class _Bound>
0239 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Tp&& __value, _Bound&& __bound_sentinel)
0240 noexcept(noexcept(ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel))))
0241 -> decltype( ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel)))
0242 { return ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel)); }
0243 };
0244 }
0245
0246
0247 inline namespace __cpo {
0248 inline constexpr auto repeat = __repeat::__fn{};
0249 }
0250 }
0251
0252 template <class _Tp>
0253 inline constexpr bool __is_repeat_specialization = false;
0254
0255 template <class _Tp, class _Bound>
0256 inline constexpr bool __is_repeat_specialization<repeat_view<_Tp, _Bound>> = true;
0257
0258 }
0259
0260 #endif
0261
0262 _LIBCPP_END_NAMESPACE_STD
0263
0264 _LIBCPP_POP_MACROS
0265
0266 #endif