Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 35 additions & 19 deletions stl/inc/iterator
Original file line number Diff line number Diff line change
Expand Up @@ -1038,10 +1038,35 @@ struct iterator_traits<common_iterator<_Iter, _Se>> {
};

// CLASS TEMPLATE counted_iterator
template <class _Iter>
struct _Counted_iterator_value_type_base {};

template <indirectly_readable _Iter>
struct _Counted_iterator_value_type_base<_Iter> {
using value_type = iter_value_t<_Iter>;
};

template <class _Iter>
struct _Counted_iterator_category_base : _Counted_iterator_value_type_base<_Iter> {};

template <_Has_member_iterator_category _Iter>
struct _Counted_iterator_category_base<_Iter> : _Counted_iterator_value_type_base<_Iter> {
using iterator_category = typename _Iter::iterator_category;
};

template <class _Iter>
struct _Counted_iterator_concept_base : _Counted_iterator_category_base<_Iter> {};

template <_Has_member_iterator_concept _Iter>
struct _Counted_iterator_concept_base<_Iter> : _Counted_iterator_category_base<_Iter> {
using iterator_concept = typename _Iter::iterator_concept;
};

template <input_or_output_iterator _Iter>
class counted_iterator {
class counted_iterator : public _Counted_iterator_concept_base<_Iter> {
public:
using iterator_type = _Iter;
using iterator_type = _Iter;
using difference_type = iter_difference_t<_Iter>;

// [counted.iter.const]
constexpr counted_iterator() requires default_initializable<_Iter> = default;
Expand Down Expand Up @@ -1099,6 +1124,10 @@ public:
return *_Current;
}

_NODISCARD constexpr auto operator->() const noexcept requires contiguous_iterator<_Iter> {
return _STD to_address(_Current);
}

_NODISCARD constexpr decltype(auto) operator[](const iter_difference_t<_Iter> _Diff) const
requires random_access_iterator<_Iter> {
#if _ITERATOR_DEBUG_LEVEL != 0
Expand Down Expand Up @@ -1323,25 +1352,12 @@ private:
iter_difference_t<_Iter> _Length = 0;
};

template <class _Iter>
struct incrementable_traits<counted_iterator<_Iter>> {
using difference_type = iter_difference_t<_Iter>;
};

// clang-format off
template <input_iterator _Iter>
requires (!_Is_from_primary<iterator_traits<_Iter>>)
struct iterator_traits<counted_iterator<_Iter>> : iterator_traits<_Iter> {
using pointer = void;
};

template <contiguous_iterator _Iter>
struct pointer_traits<counted_iterator<_Iter>> { // TRANSITION, address LWG-3408 and include this
using pointer = counted_iterator<_Iter>;
using element_type = remove_reference_t<iter_reference_t<_Iter>>;
using difference_type = iter_difference_t<_Iter>;

_NODISCARD static constexpr element_type* to_address(const pointer _It) noexcept {
return _STD to_address(_It.base());
}
// clang-format on
using pointer = conditional_t<contiguous_iterator<_Iter>, add_pointer_t<iter_reference_t<_Iter>>, void>;
};
#endif // __cpp_lib_concepts

Expand Down
2 changes: 2 additions & 0 deletions stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@
// P2102R0 Making "Implicit Expression Variations" More Explicit
// P2106R0 Range Algorithm Result Types
// P2116R0 Removing tuple-Like Protocol Support From Fixed-Extent span
// P2259R1 Repairing Input Range Adaptors And counted_iterator
// (partially implemented)
// P2325R3 Views Should Not Be Required To Be Default Constructible
// P????R? directory_entry::clear_cache()

Expand Down
2 changes: 1 addition & 1 deletion tests/std/tests/P0896R4_common_iterator/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ bool test_operator_arrow() {
assert(*countedIter == P(0, 1));
assert(countedIter->first == 0);
assert(countedIter->second == 1);
static_assert(is_same_v<decltype(countedIter.operator->()), P*>);
static_assert(is_same_v<decltype(countedIter.operator->()), counted_iterator<P*> const&>);

return true;
}
Expand Down
39 changes: 39 additions & 0 deletions tests/std/tests/P0896R4_counted_iterator/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,43 @@ struct instantiator {
}
};

// Also test P2259R1 Repairing input range adaptors and counted_iterator
struct simple_forward_iter {
using value_type = double;
using difference_type = long;
using iterator_category = input_iterator_tag;
using iterator_concept = forward_iterator_tag;

value_type operator*() const;
simple_forward_iter& operator++();
simple_forward_iter operator++(int);

bool operator==(const simple_forward_iter&) const;
};

using CI = counted_iterator<simple_forward_iter>;

static_assert(same_as<iterator_traits<simple_forward_iter>::iterator_category, input_iterator_tag>);
static_assert(forward_iterator<simple_forward_iter>);
static_assert(forward_iterator<CI>);
static_assert(!contiguous_iterator<CI>);
static_assert(same_as<CI::value_type, double>);
static_assert(same_as<CI::difference_type, long>);
static_assert(same_as<CI::iterator_category, input_iterator_tag>);
static_assert(same_as<CI::iterator_concept, forward_iterator_tag>);

void test_P2259() {
struct A {
int m;
};
A a[2] = {{1}, {2}};
counted_iterator ci{a, 2};
reverse_iterator ri{ci + 1};
static_assert(contiguous_iterator<decltype(ci)>);
assert(ci->m == 1);
assert(ri->m == 1);
}

int main() {
STATIC_ASSERT((with_writable_iterators<instantiator, int>::call(), true));
with_writable_iterators<instantiator, int>::call();
Expand All @@ -317,4 +354,6 @@ int main() {
_Seek_wrapped(ci, uci);
assert((ci == counted_iterator{ranges::next(lst.begin()), 1}));
}

test_P2259();
}