@@ -1038,10 +1038,35 @@ struct iterator_traits<common_iterator<_Iter, _Se>> {
1038
1038
};
1039
1039
1040
1040
// CLASS TEMPLATE counted_iterator
1041
+ template <class _Iter>
1042
+ struct _Counted_iterator_value_type_base {};
1043
+
1044
+ template <indirectly_readable _Iter>
1045
+ struct _Counted_iterator_value_type_base<_Iter> {
1046
+ using value_type = iter_value_t<_Iter>;
1047
+ };
1048
+
1049
+ template <class _Iter>
1050
+ struct _Counted_iterator_category_base : _Counted_iterator_value_type_base<_Iter> {};
1051
+
1052
+ template <_Has_member_iterator_category _Iter>
1053
+ struct _Counted_iterator_category_base<_Iter> : _Counted_iterator_value_type_base<_Iter> {
1054
+ using iterator_category = typename _Iter::iterator_category;
1055
+ };
1056
+
1057
+ template <class _Iter>
1058
+ struct _Counted_iterator_concept_base : _Counted_iterator_category_base<_Iter> {};
1059
+
1060
+ template <_Has_member_iterator_concept _Iter>
1061
+ struct _Counted_iterator_concept_base<_Iter> : _Counted_iterator_category_base<_Iter> {
1062
+ using iterator_concept = typename _Iter::iterator_concept;
1063
+ };
1064
+
1041
1065
template <input_or_output_iterator _Iter>
1042
- class counted_iterator {
1066
+ class counted_iterator : public _Counted_iterator_concept_base<_Iter> {
1043
1067
public:
1044
- using iterator_type = _Iter;
1068
+ using iterator_type = _Iter;
1069
+ using difference_type = iter_difference_t<_Iter>;
1045
1070
1046
1071
// [counted.iter.const]
1047
1072
constexpr counted_iterator() requires default_initializable<_Iter> = default;
@@ -1099,6 +1124,10 @@ public:
1099
1124
return *_Current;
1100
1125
}
1101
1126
1127
+ _NODISCARD constexpr auto operator->() const noexcept requires contiguous_iterator<_Iter> {
1128
+ return _STD to_address(_Current);
1129
+ }
1130
+
1102
1131
_NODISCARD constexpr decltype(auto) operator[](const iter_difference_t<_Iter> _Diff) const
1103
1132
requires random_access_iterator<_Iter> {
1104
1133
#if _ITERATOR_DEBUG_LEVEL != 0
@@ -1323,25 +1352,12 @@ private:
1323
1352
iter_difference_t<_Iter> _Length = 0;
1324
1353
};
1325
1354
1326
- template <class _Iter>
1327
- struct incrementable_traits<counted_iterator<_Iter>> {
1328
- using difference_type = iter_difference_t<_Iter>;
1329
- };
1330
-
1355
+ // clang-format off
1331
1356
template <input_iterator _Iter>
1357
+ requires (!_Is_from_primary<iterator_traits<_Iter>>)
1332
1358
struct iterator_traits<counted_iterator<_Iter>> : iterator_traits<_Iter> {
1333
- using pointer = void;
1334
- };
1335
-
1336
- template <contiguous_iterator _Iter>
1337
- struct pointer_traits<counted_iterator<_Iter>> { // TRANSITION, address LWG-3408 and include this
1338
- using pointer = counted_iterator<_Iter>;
1339
- using element_type = remove_reference_t<iter_reference_t<_Iter>>;
1340
- using difference_type = iter_difference_t<_Iter>;
1341
-
1342
- _NODISCARD static constexpr element_type* to_address(const pointer _It) noexcept {
1343
- return _STD to_address(_It.base());
1344
- }
1359
+ // clang-format on
1360
+ using pointer = conditional_t<contiguous_iterator<_Iter>, add_pointer_t<iter_reference_t<_Iter>>, void>;
1345
1361
};
1346
1362
#endif // __cpp_lib_concepts
1347
1363
0 commit comments