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