diff --git a/libcxx/test/std/iterators/predef.iterators/iterators.common/arrow.pass.cpp b/libcxx/test/std/iterators/predef.iterators/iterators.common/arrow.pass.cpp --- a/libcxx/test/std/iterators/predef.iterators/iterators.common/arrow.pass.cpp +++ b/libcxx/test/std/iterators/predef.iterators/iterators.common/arrow.pass.cpp @@ -14,13 +14,48 @@ #include #include +#include +#include "test_iterators.h" #include "test_macros.h" #include "types.h" +struct IteratorWithArrow { + using iterator_category = std::input_iterator_tag; + using difference_type = std::ptrdiff_t; + using value_type = int; + + explicit IteratorWithArrow(int* p) : p_(p) { } + int& operator*() const { return *p_; } + IteratorWithArrow operator->() const { return *this; } + IteratorWithArrow& operator++() { ++p_; return *this; } + IteratorWithArrow operator++(int) { return IteratorWithArrow(p_++); } + + friend int* base(IteratorWithArrow const& i) { return i.p_; } + int* p_; +}; +static_assert(std::input_iterator); + void test() { int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8}; + // Case 1: http://eel.is/c++draft/iterators.common#common.iter.access-5.1 + { + IteratorWithArrow iter(buffer); + using Common = std::common_iterator>; + { + Common common(iter); + std::same_as auto result = common.operator->(); + assert(base(result) == buffer); + } + + { + Common const common(iter); + std::same_as auto result = common.operator->(); + assert(base(result) == buffer); + } + } + // Case 2: http://eel.is/c++draft/iterators.common#common.iter.access-5.2 { auto iter1 = simple_iterator(buffer); @@ -31,6 +66,23 @@ assert(commonIter2.operator->() == buffer); } + // Case 2: http://eel.is/c++draft/iterators.common#common.iter.access-5.2 + { + contiguous_iterator iter(buffer); + using Common = std::common_iterator, sentinel_wrapper>>; + { + Common common(iter); + std::same_as auto result = common.operator->(); + assert(result == buffer); + } + + { + Common const common(iter); + std::same_as auto result = common.operator->(); + assert(result == buffer); + } + } + // Case 3: http://eel.is/c++draft/iterators.common#common.iter.access-5.3 { auto iter1 = value_iterator(buffer); @@ -50,36 +102,6 @@ assert(*commonIter1.operator->().operator->() == 1); assert(*commonIter2.operator->().operator->() == 1); } - - // Case 1: http://eel.is/c++draft/iterators.common#common.iter.access-5.1 - { - auto iter1 = cpp17_input_iterator(buffer); - auto commonIter1 = std::common_iterator>(iter1); - const auto commonIter2 = std::common_iterator>(iter1); - - assert(commonIter1.operator->().base() == buffer); - assert(commonIter2.operator->().base() == buffer); - } - - // Case 1: http://eel.is/c++draft/iterators.common#common.iter.access-5.1 - { - auto iter1 = forward_iterator(buffer); - auto commonIter1 = std::common_iterator>(iter1); - const auto commonIter2 = std::common_iterator>(iter1); - - assert(commonIter1.operator->().base() == buffer); - assert(commonIter2.operator->().base() == buffer); - } - - // Case 1: http://eel.is/c++draft/iterators.common#common.iter.access-5.1 - { - auto iter1 = random_access_iterator(buffer); - auto commonIter1 = std::common_iterator>(iter1); - const auto commonIter2 = std::common_iterator>(iter1); - - assert(commonIter1.operator->().base() == buffer); - assert(commonIter2.operator->().base() == buffer); - } } int main(int, char**) { diff --git a/libcxx/test/std/iterators/predef.iterators/iterators.common/iterator_traits.compile.pass.cpp b/libcxx/test/std/iterators/predef.iterators/iterators.common/iterator_traits.compile.pass.cpp --- a/libcxx/test/std/iterators/predef.iterators/iterators.common/iterator_traits.compile.pass.cpp +++ b/libcxx/test/std/iterators/predef.iterators/iterators.common/iterator_traits.compile.pass.cpp @@ -91,7 +91,7 @@ static_assert(std::same_as); static_assert(std::same_as); static_assert(std::same_as); - static_assert(std::same_as); + static_assert(std::same_as); static_assert(std::same_as); } { @@ -103,7 +103,7 @@ static_assert(std::same_as); static_assert(std::same_as); static_assert(std::same_as); - static_assert(std::same_as); + static_assert(std::same_as); static_assert(std::same_as); } { @@ -115,7 +115,7 @@ static_assert(std::same_as); static_assert(std::same_as); static_assert(std::same_as); - static_assert(std::same_as); + static_assert(std::same_as); static_assert(std::same_as); } diff --git a/libcxx/test/support/test_iterators.h b/libcxx/test/support/test_iterators.h --- a/libcxx/test/support/test_iterators.h +++ b/libcxx/test/support/test_iterators.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -68,7 +69,6 @@ TEST_CONSTEXPR cpp17_input_iterator(const cpp17_input_iterator& u) : it_(u.it_) {} TEST_CONSTEXPR reference operator*() const {return *it_;} - TEST_CONSTEXPR pointer operator->() const {return it_;} TEST_CONSTEXPR_CXX14 cpp17_input_iterator& operator++() {++it_; return *this;} TEST_CONSTEXPR_CXX14 cpp17_input_iterator operator++(int) {return cpp17_input_iterator(it_++);} @@ -102,7 +102,6 @@ TEST_CONSTEXPR forward_iterator(const forward_iterator& u) : it_(u.it_) {} TEST_CONSTEXPR reference operator*() const {return *it_;} - TEST_CONSTEXPR pointer operator->() const {return it_;} TEST_CONSTEXPR_CXX14 forward_iterator& operator++() {++it_; return *this;} TEST_CONSTEXPR_CXX14 forward_iterator operator++(int) {return forward_iterator(it_++);} @@ -136,7 +135,6 @@ TEST_CONSTEXPR bidirectional_iterator(const bidirectional_iterator& u) : it_(u.it_) {} TEST_CONSTEXPR reference operator*() const {return *it_;} - TEST_CONSTEXPR pointer operator->() const {return it_;} TEST_CONSTEXPR_CXX14 bidirectional_iterator& operator++() {++it_; return *this;} TEST_CONSTEXPR_CXX14 bidirectional_iterator& operator--() {--it_; return *this;} @@ -172,7 +170,6 @@ TEST_CONSTEXPR random_access_iterator(const random_access_iterator& u) : it_(u.it_) {} TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;} - TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;} TEST_CONSTEXPR_CXX14 reference operator[](difference_type n) const {return it_[n];} TEST_CONSTEXPR_CXX14 random_access_iterator& operator++() {++it_; return *this;} @@ -226,7 +223,6 @@ TEST_CONSTEXPR_CXX14 contiguous_iterator(const contiguous_iterator& u) : it_(u.it_) {} TEST_CONSTEXPR reference operator*() const {return *it_;} - TEST_CONSTEXPR pointer operator->() const {return it_;} TEST_CONSTEXPR reference operator[](difference_type n) const {return it_[n];} TEST_CONSTEXPR_CXX14 contiguous_iterator& operator++() {++it_; return *this;} @@ -254,6 +250,19 @@ void operator,(T const &) = delete; }; +namespace std { + template + struct pointer_traits<::contiguous_iterator> { + using pointer = ::contiguous_iterator; + using element_type = typename pointer_traits::element_type; + using difference_type = typename pointer_traits::difference_type; + template + using rebind = ::contiguous_iterator; + static constexpr pointer pointer_to(element_type& x) { return ::contiguous_iterator(pointer_traits::pointer_to(x)); } + static constexpr element_type* to_address(pointer p) { return std::to_address(base(p)); } + }; +} + template class three_way_contiguous_iterator { @@ -278,7 +287,6 @@ constexpr three_way_contiguous_iterator(const three_way_contiguous_iterator& u) : it_(u.it_) {} constexpr reference operator*() const {return *it_;} - constexpr pointer operator->() const {return it_;} constexpr reference operator[](difference_type n) const {return it_[n];} constexpr three_way_contiguous_iterator& operator++() {++it_; return *this;} @@ -299,6 +307,19 @@ template void operator,(T const &) = delete; }; + +namespace std { + template + struct pointer_traits<::three_way_contiguous_iterator> { + using pointer = ::three_way_contiguous_iterator; + using element_type = typename pointer_traits::element_type; + using difference_type = typename pointer_traits::difference_type; + template + using rebind = ::three_way_contiguous_iterator; + static constexpr pointer pointer_to(element_type& x) { return ::three_way_contiguous_iterator(pointer_traits::pointer_to(x)); } + static constexpr element_type* to_address(pointer p) { return std::to_address(base(p)); } + }; +} #endif // TEST_STD_VER > 17 template // ADL base() for everything else (including pointers)