[libcxx-commits] [libcxx] c6b192a - [libc++][test] Do not assume array::iterator is a pointer (#100603)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jul 30 02:28:59 PDT 2024
Author: nicole mazzuca
Date: 2024-07-30T02:28:56-07:00
New Revision: c6b192ac2e1441b3484781488adef2986408ebdf
URL: https://github.com/llvm/llvm-project/commit/c6b192ac2e1441b3484781488adef2986408ebdf
DIFF: https://github.com/llvm/llvm-project/commit/c6b192ac2e1441b3484781488adef2986408ebdf.diff
LOG: [libc++][test] Do not assume array::iterator is a pointer (#100603)
In the tests I added for `ranges::find_last{_if{_not}}`, I accidentally
introduced an assumption that `same_as<array<T, 0>::iterator, T*>`; this
is a faulty assumption on MSVC-STL.
Fixes #100498.
Added:
Modified:
libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp
libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp
libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp
libcxx/test/support/test_iterators.h
Removed:
################################################################################
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp
index 2a2b12fb2c288..9da8c26db0f56 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last.pass.cpp
@@ -25,6 +25,7 @@
#include <algorithm>
#include <array>
#include <cassert>
+#include <memory>
#include <ranges>
#include <vector>
@@ -61,7 +62,8 @@ template <class It, class Sent = It>
constexpr void test_iterators() {
using ValueT = std::iter_value_t<It>;
auto make_range = [](auto& a) {
- return std::ranges::subrange(It(std::ranges::begin(a)), Sent(It(std::ranges::end(a))));
+ return std::ranges::subrange(
+ It(std::to_address(std::ranges::begin(a))), Sent(It(std::to_address(std::ranges::end(a)))));
};
{ // simple test
{
@@ -91,7 +93,7 @@ constexpr void test_iterators() {
std::array<ValueT, 0> a = {};
auto ret = std::ranges::find_last(make_range(a), 1).begin();
- assert(ret == It(a.begin()));
+ assert(ret == It(a.data()));
}
}
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp
index a15f81bd4e481..107fcf900d3e4 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if.pass.cpp
@@ -92,14 +92,14 @@ constexpr void test_iterator_classes() {
{
std::array<int, 0> a = {};
- auto ret = std::ranges::find_last_if(it(a.data()), sent(it(a.data())), [](auto&&) { return true; }).begin();
- assert(ret == it(a.data()));
+ auto ret = std::ranges::find_last_if(it(a.begin()), sent(it(a.end())), [](auto&&) { return true; }).begin();
+ assert(ret == it(a.end()));
}
{
std::array<int, 0> a = {};
auto ret = std::ranges::find_last_if(make_range<it, sent>(a), [](auto&&) { return true; }).begin();
- assert(ret == it(a.begin()));
+ assert(ret == it(a.end()));
}
}
@@ -183,8 +183,17 @@ struct NonConstComparable {
friend constexpr bool operator==(NonConstComparable&, const NonConstComparable&) { return true; }
};
+// TODO: this should really use `std::const_iterator`
template <class T>
-using add_const_to_ptr_t = std::add_pointer_t<std::add_const_t<std::remove_pointer_t<T>>>;
+struct add_const_to_ptr {
+ using type = T;
+};
+template <class T>
+struct add_const_to_ptr<T*> {
+ using type = const T*;
+};
+template <class T>
+using add_const_to_ptr_t = typename add_const_to_ptr<T>::type;
constexpr bool test() {
test_iterator_classes<std::type_identity_t, std::type_identity_t>();
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp
index bb0e411acf0fa..6602ac569c679 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.find.last/ranges.find_last_if_not.pass.cpp
@@ -92,14 +92,14 @@ constexpr void test_iterator_classes() {
{
std::array<int, 0> a = {};
- auto ret = std::ranges::find_last_if_not(it(a.data()), sent(it(a.data())), [](auto&&) { return false; }).begin();
- assert(ret == it(a.data()));
+ auto ret = std::ranges::find_last_if_not(it(a.begin()), sent(it(a.end())), [](auto&&) { return false; }).begin();
+ assert(ret == it(a.end()));
}
{
std::array<int, 0> a = {};
auto ret = std::ranges::find_last_if_not(make_range<it, sent>(a), [](auto&&) { return false; }).begin();
- assert(ret == it(a.begin()));
+ assert(ret == it(a.end()));
}
}
@@ -183,8 +183,17 @@ struct NonConstComparable {
friend constexpr bool operator!=(NonConstComparable&, const NonConstComparable&) { return false; }
};
+// TODO: this should really use `std::const_iterator`
template <class T>
-using add_const_to_ptr_t = std::add_pointer_t<std::add_const_t<std::remove_pointer_t<T>>>;
+struct add_const_to_ptr {
+ using type = T;
+};
+template <class T>
+struct add_const_to_ptr<T*> {
+ using type = const T*;
+};
+template <class T>
+using add_const_to_ptr_t = typename add_const_to_ptr<T>::type;
constexpr bool test() {
test_iterator_classes<std::type_identity_t, std::type_identity_t>();
diff --git a/libcxx/test/support/test_iterators.h b/libcxx/test/support/test_iterators.h
index 95d1b7df0007c..44bd4a597539d 100644
--- a/libcxx/test/support/test_iterators.h
+++ b/libcxx/test/support/test_iterators.h
@@ -339,62 +339,92 @@ cpp20_random_access_iterator(It) -> cpp20_random_access_iterator<It>;
static_assert(std::random_access_iterator<cpp20_random_access_iterator<int*>>);
-template <class It>
-class contiguous_iterator
-{
- static_assert(std::is_pointer_v<It>, "Things probably break in this case");
+template <std::contiguous_iterator It>
+class contiguous_iterator {
+ It it_;
- It it_;
+ template <std::contiguous_iterator U>
+ friend class contiguous_iterator;
- template <class U> friend class contiguous_iterator;
public:
- typedef std::contiguous_iterator_tag iterator_category;
- typedef typename std::iterator_traits<It>::value_type value_type;
- typedef typename std::iterator_traits<It>::
diff erence_type
diff erence_type;
- typedef It pointer;
- typedef typename std::iterator_traits<It>::reference reference;
- typedef typename std::remove_pointer<It>::type element_type;
+ using iterator_category = std::contiguous_iterator_tag;
+ using value_type = typename std::iterator_traits<It>::value_type;
+ using
diff erence_type = typename std::iterator_traits<It>::
diff erence_type;
+ using pointer = typename std::iterator_traits<It>::pointer;
+ using reference = typename std::iterator_traits<It>::reference;
+ using element_type = value_type;
- TEST_CONSTEXPR_CXX14 It base() const {return it_;}
+ constexpr It base() const { return it_; }
- TEST_CONSTEXPR_CXX14 contiguous_iterator() : it_() {}
- TEST_CONSTEXPR_CXX14 explicit contiguous_iterator(It it) : it_(it) {}
+ constexpr contiguous_iterator() : it_() {}
+ constexpr explicit contiguous_iterator(It it) : it_(it) {}
- template <class U>
- TEST_CONSTEXPR_CXX14 contiguous_iterator(const contiguous_iterator<U>& u) : it_(u.it_) {}
+ template <class U>
+ constexpr contiguous_iterator(const contiguous_iterator<U>& u) : it_(u.it_) {}
- template <class U, class = typename std::enable_if<std::is_default_constructible<U>::value>::type>
- constexpr contiguous_iterator(contiguous_iterator<U>&& u) : it_(u.it_) { u.it_ = U(); }
+ template <class U, class = typename std::enable_if<std::is_default_constructible<U>::value>::type>
+ constexpr contiguous_iterator(contiguous_iterator<U>&& u) : it_(u.it_) {
+ u.it_ = U();
+ }
- TEST_CONSTEXPR reference operator*() const {return *it_;}
- TEST_CONSTEXPR pointer operator->() const {return it_;}
- TEST_CONSTEXPR reference operator[](
diff erence_type n) const {return it_[n];}
-
- TEST_CONSTEXPR_CXX14 contiguous_iterator& operator++() {++it_; return *this;}
- TEST_CONSTEXPR_CXX14 contiguous_iterator& operator--() {--it_; return *this;}
- TEST_CONSTEXPR_CXX14 contiguous_iterator operator++(int) {return contiguous_iterator(it_++);}
- TEST_CONSTEXPR_CXX14 contiguous_iterator operator--(int) {return contiguous_iterator(it_--);}
-
- TEST_CONSTEXPR_CXX14 contiguous_iterator& operator+=(
diff erence_type n) {it_ += n; return *this;}
- TEST_CONSTEXPR_CXX14 contiguous_iterator& operator-=(
diff erence_type n) {it_ -= n; return *this;}
- friend TEST_CONSTEXPR_CXX14 contiguous_iterator operator+(contiguous_iterator x,
diff erence_type n) {x += n; return x;}
- friend TEST_CONSTEXPR_CXX14 contiguous_iterator operator+(
diff erence_type n, contiguous_iterator x) {x += n; return x;}
- friend TEST_CONSTEXPR_CXX14 contiguous_iterator operator-(contiguous_iterator x,
diff erence_type n) {x -= n; return x;}
- friend TEST_CONSTEXPR
diff erence_type operator-(contiguous_iterator x, contiguous_iterator y) {return x.it_ - y.it_;}
-
- friend TEST_CONSTEXPR bool operator==(const contiguous_iterator& x, const contiguous_iterator& y) {return x.it_ == y.it_;}
- friend TEST_CONSTEXPR bool operator!=(const contiguous_iterator& x, const contiguous_iterator& y) {return x.it_ != y.it_;}
- friend TEST_CONSTEXPR bool operator< (const contiguous_iterator& x, const contiguous_iterator& y) {return x.it_ < y.it_;}
- friend TEST_CONSTEXPR bool operator<=(const contiguous_iterator& x, const contiguous_iterator& y) {return x.it_ <= y.it_;}
- friend TEST_CONSTEXPR bool operator> (const contiguous_iterator& x, const contiguous_iterator& y) {return x.it_ > y.it_;}
- friend TEST_CONSTEXPR bool operator>=(const contiguous_iterator& x, const contiguous_iterator& y) {return x.it_ >= y.it_;}
+ constexpr reference operator*() const { return *it_; }
+ constexpr pointer operator->() const { return it_; }
+ constexpr reference operator[](
diff erence_type n) const { return it_[n]; }
+
+ constexpr contiguous_iterator& operator++() {
+ ++it_;
+ return *this;
+ }
+ constexpr contiguous_iterator& operator--() {
+ --it_;
+ return *this;
+ }
+ constexpr contiguous_iterator operator++(int) { return contiguous_iterator(it_++); }
+ constexpr contiguous_iterator operator--(int) { return contiguous_iterator(it_--); }
+
+ constexpr contiguous_iterator& operator+=(
diff erence_type n) {
+ it_ += n;
+ return *this;
+ }
+ constexpr contiguous_iterator& operator-=(
diff erence_type n) {
+ it_ -= n;
+ return *this;
+ }
+ friend constexpr contiguous_iterator operator+(contiguous_iterator x,
diff erence_type n) {
+ x += n;
+ return x;
+ }
+ friend constexpr contiguous_iterator operator+(
diff erence_type n, contiguous_iterator x) {
+ x += n;
+ return x;
+ }
+ friend constexpr contiguous_iterator operator-(contiguous_iterator x,
diff erence_type n) {
+ x -= n;
+ return x;
+ }
+ friend constexpr
diff erence_type operator-(contiguous_iterator x, contiguous_iterator y) { return x.it_ - y.it_; }
+
+ friend constexpr bool operator==(const contiguous_iterator& x, const contiguous_iterator& y) {
+ return x.it_ == y.it_;
+ }
+ friend constexpr bool operator!=(const contiguous_iterator& x, const contiguous_iterator& y) {
+ return x.it_ != y.it_;
+ }
+ friend constexpr bool operator<(const contiguous_iterator& x, const contiguous_iterator& y) { return x.it_ < y.it_; }
+ friend constexpr bool operator<=(const contiguous_iterator& x, const contiguous_iterator& y) {
+ return x.it_ <= y.it_;
+ }
+ friend constexpr bool operator>(const contiguous_iterator& x, const contiguous_iterator& y) { return x.it_ > y.it_; }
+ friend constexpr bool operator>=(const contiguous_iterator& x, const contiguous_iterator& y) {
+ return x.it_ >= y.it_;
+ }
// Note no operator<=>, use three_way_contiguous_iterator for testing operator<=>
- friend TEST_CONSTEXPR It base(const contiguous_iterator& i) { return i.it_; }
+ friend constexpr It base(const contiguous_iterator& i) { return i.it_; }
- template <class T>
- void operator,(T const &) = delete;
+ template <class T>
+ void operator,(T const&) = delete;
};
template <class It>
contiguous_iterator(It) -> contiguous_iterator<It>;
More information about the libcxx-commits
mailing list