@@ -5919,6 +5919,338 @@ namespace ranges {
5919
5919
} // namespace views
5920
5920
5921
5921
#if _HAS_CXX23
5922
+ template <class _Rng>
5923
+ concept _Range_with_movable_references = input_range<_Rng> && move_constructible<range_reference_t<_Rng>>
5924
+ && move_constructible<range_rvalue_reference_t<_Rng>>;
5925
+
5926
+ _EXPORT_STD template <view _Vw>
5927
+ requires _Range_with_movable_references<_Vw>
5928
+ class enumerate_view : public view_interface<enumerate_view<_Vw>> {
5929
+ private:
5930
+ /* [[no_unique_address]] */ _Vw _Range{};
5931
+
5932
+ template <bool _Const>
5933
+ class _Iterator {
5934
+ private:
5935
+ friend enumerate_view;
5936
+
5937
+ using _Base_t = _Maybe_const<_Const, _Vw>;
5938
+ using _Base_iterator = iterator_t<_Base_t>;
5939
+ using _Reference_type = tuple<range_difference_t<_Base_t>, range_reference_t<_Base_t>>;
5940
+
5941
+ /* [[no_unique_address]] */ _Base_iterator _Current{};
5942
+ range_difference_t<_Base_t> _Pos = 0;
5943
+
5944
+ constexpr explicit _Iterator(_Base_iterator _Current_, range_difference_t<_Base_t> _Pos_) noexcept(
5945
+ is_nothrow_move_constructible_v<_Base_iterator>) // strengthened
5946
+ : _Current(_STD move(_Current_)), _Pos(_Pos_) {}
5947
+
5948
+ public:
5949
+ using iterator_category = input_iterator_tag;
5950
+ using iterator_concept = conditional_t<random_access_range<_Base_t>, random_access_iterator_tag,
5951
+ conditional_t<bidirectional_range<_Base_t>, bidirectional_iterator_tag,
5952
+ conditional_t<forward_range<_Base_t>, forward_iterator_tag, input_iterator_tag>>>;
5953
+ using difference_type = range_difference_t<_Base_t>;
5954
+ using value_type = tuple<difference_type, range_value_t<_Base_t>>;
5955
+
5956
+ // clang-format off
5957
+ _Iterator() requires default_initializable<_Base_iterator> = default;
5958
+ // clang-format on
5959
+
5960
+ constexpr _Iterator(_Iterator<!_Const> _Other) noexcept(
5961
+ is_nothrow_constructible_v<_Base_iterator, iterator_t<_Vw>>) // strengthened
5962
+ requires _Const && convertible_to<iterator_t<_Vw>, _Base_iterator>
5963
+ : _Current(_STD move(_Other._Current)), _Pos(_Other._Pos) {}
5964
+
5965
+ _NODISCARD constexpr const _Base_iterator& base() const& noexcept {
5966
+ return _Current;
5967
+ }
5968
+
5969
+ _NODISCARD constexpr _Base_iterator base() && noexcept(
5970
+ is_nothrow_move_constructible_v<_Base_iterator>) /* strengthened */ {
5971
+ return _STD move(_Current);
5972
+ }
5973
+
5974
+ _NODISCARD constexpr difference_type index() const noexcept {
5975
+ return _Pos;
5976
+ }
5977
+
5978
+ _NODISCARD constexpr auto operator*() const noexcept(
5979
+ noexcept(*_Current) && is_nothrow_copy_constructible_v<range_reference_t<_Base_t>>) /* strengthened */ {
5980
+ return _Reference_type{_Pos, *_Current};
5981
+ }
5982
+
5983
+ constexpr _Iterator& operator++() noexcept(noexcept(++_Current)) /* strengthened */ {
5984
+ ++_Current;
5985
+ ++_Pos;
5986
+ return *this;
5987
+ }
5988
+
5989
+ constexpr void operator++(int) noexcept(noexcept(++_Current)) /* strengthened */ {
5990
+ ++*this;
5991
+ }
5992
+
5993
+ constexpr _Iterator operator++(int) noexcept(
5994
+ noexcept(++*this) && is_nothrow_copy_constructible_v<_Iterator>) // strengthened
5995
+ requires forward_range<_Base_t>
5996
+ {
5997
+ auto _Tmp = *this;
5998
+ ++*this;
5999
+ return _Tmp;
6000
+ }
6001
+
6002
+ constexpr _Iterator& operator--() noexcept(noexcept(--_Current)) // strengthened
6003
+ requires bidirectional_range<_Base_t>
6004
+ {
6005
+ --_Current;
6006
+ --_Pos;
6007
+ return *this;
6008
+ }
6009
+
6010
+ constexpr _Iterator operator--(int) noexcept(
6011
+ noexcept(--*this) && is_nothrow_copy_constructible_v<_Iterator>) // strengthened
6012
+ requires bidirectional_range<_Base_t>
6013
+ {
6014
+ auto _Tmp = *this;
6015
+ --*this;
6016
+ return _Tmp;
6017
+ }
6018
+
6019
+ constexpr _Iterator& operator+=(const difference_type _Off) noexcept(
6020
+ noexcept(_Current += _Off)) // strengthened
6021
+ requires random_access_range<_Base_t>
6022
+ {
6023
+ _Current += _Off;
6024
+ _Pos += _Off;
6025
+ return *this;
6026
+ }
6027
+
6028
+ constexpr _Iterator& operator-=(const difference_type _Off) noexcept(
6029
+ noexcept(_Current -= _Off)) // strengthened
6030
+ requires random_access_range<_Base_t>
6031
+ {
6032
+ _Current -= _Off;
6033
+ _Pos -= _Off;
6034
+ return *this;
6035
+ }
6036
+
6037
+ _NODISCARD constexpr auto operator[](const difference_type _Off) const noexcept(
6038
+ noexcept(_Current[_Off]) && is_nothrow_copy_constructible_v<range_reference_t<_Base_t>>) // strengthened
6039
+ requires random_access_range<_Base_t>
6040
+ {
6041
+ return _Reference_type{static_cast<difference_type>(_Pos + _Off), _Current[_Off]};
6042
+ }
6043
+
6044
+ _NODISCARD_FRIEND constexpr bool operator==(const _Iterator& _Left, const _Iterator& _Right) noexcept {
6045
+ return _Left._Pos == _Right._Pos;
6046
+ }
6047
+
6048
+ _NODISCARD_FRIEND constexpr strong_ordering operator<=>(
6049
+ const _Iterator& _Left, const _Iterator& _Right) noexcept {
6050
+ return _Left._Pos <=> _Right._Pos;
6051
+ }
6052
+
6053
+ _NODISCARD_FRIEND constexpr _Iterator operator+(const _Iterator& _It, const difference_type _Off) noexcept(
6054
+ is_nothrow_copy_constructible_v<_Iterator>&& noexcept(
6055
+ _STD declval<_Iterator&>() += _Off)) // strengthened
6056
+ requires random_access_range<_Base_t>
6057
+ {
6058
+ auto _Tmp = _It;
6059
+ _Tmp += _Off;
6060
+ return _Tmp;
6061
+ }
6062
+
6063
+ _NODISCARD_FRIEND constexpr _Iterator operator+(const difference_type _Off, const _Iterator& _It) noexcept(
6064
+ noexcept(_It + _Off)) // strengthened
6065
+ requires random_access_range<_Base_t>
6066
+ {
6067
+ return _It + _Off;
6068
+ }
6069
+
6070
+ _NODISCARD_FRIEND constexpr _Iterator operator-(const _Iterator& _It, const difference_type _Off) noexcept(
6071
+ is_nothrow_copy_constructible_v<_Iterator>&& noexcept(
6072
+ _STD declval<_Iterator&>() -= _Off)) // strengthened
6073
+ requires random_access_range<_Base_t>
6074
+ {
6075
+ auto _Tmp = _It;
6076
+ _Tmp -= _Off;
6077
+ return _Tmp;
6078
+ }
6079
+
6080
+ _NODISCARD_FRIEND constexpr difference_type operator-(
6081
+ const _Iterator& _Left, const _Iterator& _Right) noexcept /* strengthened */ {
6082
+ return _Left._Pos - _Right._Pos;
6083
+ }
6084
+
6085
+ _NODISCARD_FRIEND constexpr auto iter_move(const _Iterator& _It) noexcept(
6086
+ noexcept(_RANGES iter_move(_It._Current))
6087
+ && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base_t>>) {
6088
+ return tuple<difference_type, range_rvalue_reference_t<_Base_t>>{
6089
+ _It._Pos, _RANGES iter_move(_It._Current)};
6090
+ }
6091
+ };
6092
+
6093
+ template <bool _Const>
6094
+ class _Sentinel {
6095
+ private:
6096
+ friend enumerate_view;
6097
+
6098
+ using _Base_t = _Maybe_const<_Const, _Vw>;
6099
+ using _Base_sentinel = sentinel_t<_Base_t>;
6100
+
6101
+ /* [[no_unique_address]] */ _Base_sentinel _End{};
6102
+
6103
+ constexpr explicit _Sentinel(_Base_sentinel _End_) noexcept(
6104
+ is_nothrow_move_constructible_v<_Base_sentinel>) // strengthened
6105
+ : _End(_STD move(_End_)) {}
6106
+
6107
+ template <bool _OtherConst>
6108
+ requires sentinel_for<_Base_sentinel, iterator_t<_Maybe_const<_OtherConst, _Vw>>>
6109
+ _NODISCARD constexpr bool _Equal(const _Iterator<_OtherConst>& _It) const
6110
+ noexcept(noexcept(_Fake_copy_init<bool>(_It._Current == _End))) {
6111
+ return _It._Current == _End;
6112
+ }
6113
+
6114
+ template <bool _OtherConst>
6115
+ requires sized_sentinel_for<_Base_sentinel, iterator_t<_Maybe_const<_OtherConst, _Vw>>>
6116
+ _NODISCARD constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> _Distance_from(
6117
+ const _Iterator<_OtherConst>& _It) const noexcept(noexcept(_End - _It._Current)) {
6118
+ return _End - _It._Current;
6119
+ }
6120
+
6121
+ public:
6122
+ _Sentinel() = default;
6123
+
6124
+ constexpr _Sentinel(_Sentinel<!_Const> _Other) noexcept(
6125
+ is_nothrow_constructible_v<_Base_sentinel, sentinel_t<_Vw>>) // strengthened
6126
+ requires _Const && convertible_to<sentinel_t<_Vw>, _Base_sentinel>
6127
+ : _End(_STD move(_Other._End)) {}
6128
+
6129
+ _NODISCARD constexpr _Base_sentinel base() const
6130
+ noexcept(is_nothrow_copy_constructible_v<_Base_sentinel>) /* strengthened */ {
6131
+ return _End;
6132
+ }
6133
+
6134
+ template <bool _OtherConst>
6135
+ requires sentinel_for<_Base_sentinel, iterator_t<_Maybe_const<_OtherConst, _Vw>>>
6136
+ _NODISCARD_FRIEND constexpr bool operator==(const _Iterator<_OtherConst>& _It, const _Sentinel& _Se) //
6137
+ noexcept(noexcept(_Se._Equal(_It))) /* strengthened */ {
6138
+ return _Se._Equal(_It);
6139
+ }
6140
+
6141
+ template <bool _OtherConst>
6142
+ requires sized_sentinel_for<_Base_sentinel, iterator_t<_Maybe_const<_OtherConst, _Vw>>>
6143
+ _NODISCARD_FRIEND constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> operator-(
6144
+ const _Iterator<_OtherConst>& _It, const _Sentinel& _Se) //
6145
+ noexcept(noexcept(_Se._Distance_from(_It))) /* strengthened */ {
6146
+ return -_Se._Distance_from(_It);
6147
+ }
6148
+
6149
+ template <bool _OtherConst>
6150
+ requires sized_sentinel_for<_Base_sentinel, iterator_t<_Maybe_const<_OtherConst, _Vw>>>
6151
+ _NODISCARD_FRIEND constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> operator-(
6152
+ const _Sentinel& _Se, const _Iterator<_OtherConst>& _It) //
6153
+ noexcept(noexcept(_Se._Distance_from(_It))) /* strengthened */ {
6154
+ return _Se._Distance_from(_It);
6155
+ }
6156
+ };
6157
+
6158
+ template <class _Rng>
6159
+ static constexpr bool _Is_end_nothrow_v = is_nothrow_move_constructible_v<sentinel_t<_Rng>> //
6160
+ && noexcept(_RANGES end(_STD declval<_Rng&>()));
6161
+
6162
+ template <class _Rng>
6163
+ requires common_range<_Rng> && sized_range<_Rng>
6164
+ static constexpr bool _Is_end_nothrow_v<_Rng> = is_nothrow_move_constructible_v<sentinel_t<_Rng>> //
6165
+ && noexcept(_RANGES end(_STD declval<_Rng&>())) //
6166
+ && noexcept(_RANGES distance(_STD declval<_Rng&>()));
6167
+
6168
+ public:
6169
+ // clang-format off
6170
+ constexpr enumerate_view() requires default_initializable<_Vw> = default;
6171
+ // clang-format on
6172
+
6173
+ constexpr explicit enumerate_view(_Vw _Range_) noexcept(is_nothrow_move_constructible_v<_Vw>) // strengthened
6174
+ : _Range(_STD move(_Range_)) {}
6175
+
6176
+ _NODISCARD constexpr auto begin() noexcept(
6177
+ noexcept(_RANGES begin(_Range)) && is_nothrow_move_constructible_v<iterator_t<_Vw>>) // strengthened
6178
+ requires (!_Simple_view<_Vw>)
6179
+ {
6180
+ return _Iterator<false>{_RANGES begin(_Range), 0};
6181
+ }
6182
+
6183
+ _NODISCARD constexpr auto begin() const noexcept(
6184
+ noexcept(_RANGES begin(_Range)) && is_nothrow_move_constructible_v<iterator_t<const _Vw>>) // strengthened
6185
+ requires _Range_with_movable_references<const _Vw>
6186
+ {
6187
+ return _Iterator<true>{_RANGES begin(_Range), 0};
6188
+ }
6189
+
6190
+ _NODISCARD constexpr auto end() noexcept(_Is_end_nothrow_v<_Vw>) // strengthened
6191
+ requires (!_Simple_view<_Vw>)
6192
+ {
6193
+ if constexpr (common_range<_Vw> && sized_range<_Vw>) {
6194
+ return _Iterator<false>{_RANGES end(_Range), _RANGES distance(_Range)};
6195
+ } else {
6196
+ return _Sentinel<false>{_RANGES end(_Range)};
6197
+ }
6198
+ }
6199
+
6200
+ _NODISCARD constexpr auto end() const noexcept(_Is_end_nothrow_v<const _Vw>) // strengthened
6201
+ requires _Range_with_movable_references<const _Vw>
6202
+ {
6203
+ if constexpr (common_range<const _Vw> && sized_range<const _Vw>) {
6204
+ return _Iterator<true>{_RANGES end(_Range), _RANGES distance(_Range)};
6205
+ } else {
6206
+ return _Sentinel<true>{_RANGES end(_Range)};
6207
+ }
6208
+ }
6209
+
6210
+ _NODISCARD constexpr auto size() noexcept(noexcept(_RANGES size(_Range))) // strengthened
6211
+ requires sized_range<_Vw>
6212
+ {
6213
+ return _RANGES size(_Range);
6214
+ }
6215
+
6216
+ _NODISCARD constexpr auto size() const noexcept(noexcept(_RANGES size(_Range))) // strengthened
6217
+ requires sized_range<const _Vw>
6218
+ {
6219
+ return _RANGES size(_Range);
6220
+ }
6221
+
6222
+ _NODISCARD constexpr _Vw base() const& noexcept(is_nothrow_copy_constructible_v<_Vw>) // strengthened
6223
+ requires copy_constructible<_Vw>
6224
+ {
6225
+ return _Range;
6226
+ }
6227
+
6228
+ _NODISCARD constexpr _Vw base() && noexcept(is_nothrow_move_constructible_v<_Vw>) /* strengthened */ {
6229
+ return _STD move(_Range);
6230
+ }
6231
+ };
6232
+
6233
+ template <class _Rng>
6234
+ enumerate_view(_Rng&&) -> enumerate_view<views::all_t<_Rng>>;
6235
+
6236
+ template <class _Rng>
6237
+ inline constexpr bool enable_borrowed_range<enumerate_view<_Rng>> = enable_borrowed_range<_Rng>;
6238
+
6239
+ namespace views {
6240
+ class _Enumerate_fn : public _Pipe::_Base<_Enumerate_fn> {
6241
+ public:
6242
+ template <viewable_range _Rng>
6243
+ _NODISCARD constexpr auto operator()(_Rng&& _Range) const
6244
+ noexcept(noexcept(enumerate_view<views::all_t<_Rng>>{_STD forward<_Rng>(_Range)}))
6245
+ requires requires { enumerate_view<views::all_t<_Rng>>{_STD forward<_Rng>(_Range)}; }
6246
+ {
6247
+ return enumerate_view<views::all_t<_Rng>>{_STD forward<_Rng>(_Range)};
6248
+ }
6249
+ };
6250
+
6251
+ _EXPORT_STD inline constexpr _Enumerate_fn enumerate;
6252
+ } // namespace views
6253
+
5922
6254
template <class _Size>
5923
6255
_NODISCARD constexpr _Size _Div_ceil(const _Size _Num, const _Size _Denom) noexcept {
5924
6256
_Size _Result = _Num / _Denom;
@@ -6573,8 +6905,8 @@ namespace ranges {
6573
6905
6574
6906
_Iterator() = default;
6575
6907
6576
- constexpr _Iterator(_Iterator<!_Const> _Other) noexcept(is_nothrow_constructible_v<_Base_iterator,
6577
- typename _Iterator<!_Const>::_Base_iterator >) /* strengthened */
6908
+ constexpr _Iterator(_Iterator<!_Const> _Other) noexcept(
6909
+ is_nothrow_constructible_v<_Base_iterator, iterator_t<_Vw> >) // strengthened
6578
6910
requires _Const && convertible_to<iterator_t<_Vw>, _Base_iterator>
6579
6911
: _Current(_STD move(_Other._Current)), _Count(_Other._Count) {}
6580
6912
0 commit comments