[libcxx-commits] [libcxx] 2d400db - [libcxx] contiguous iterator concept: don't require pointer or complete element types

Joe Loser via libcxx-commits libcxx-commits at lists.llvm.org
Wed Sep 1 05:33:13 PDT 2021


Author: Joe Loser
Date: 2021-09-01T08:32:41-04:00
New Revision: 2d400db63cfb3585fd5200e41f281447e3b6ca6a

URL: https://github.com/llvm/llvm-project/commit/2d400db63cfb3585fd5200e41f281447e3b6ca6a
DIFF: https://github.com/llvm/llvm-project/commit/2d400db63cfb3585fd5200e41f281447e3b6ca6a.diff

LOG: [libcxx] contiguous iterator concept: don't require pointer or complete element types

`contiguous_iterator` requires the iterator type passed is either a
pointer type or that the element type of the iterator is a complete
object type. These constraints are not part of the current wording in
defining the `contiguous_iterator` concept - adjust the concept to
reflect this.

Inspired from discussion at https://reviews.llvm.org/D108645.

Reviewed By: #libc, ldionne

Differential Revision: https://reviews.llvm.org/D108855

Added: 
    libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/contiguous_iterator.verify.cpp

Modified: 
    libcxx/include/__iterator/concepts.h
    libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/contiguous_iterator.compile.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__iterator/concepts.h b/libcxx/include/__iterator/concepts.h
index 27474a37293fd..531acdf0a5b2c 100644
--- a/libcxx/include/__iterator/concepts.h
+++ b/libcxx/include/__iterator/concepts.h
@@ -171,7 +171,6 @@ concept contiguous_iterator =
   derived_from<_ITER_CONCEPT<_Ip>, contiguous_iterator_tag> &&
   is_lvalue_reference_v<iter_reference_t<_Ip>> &&
   same_as<iter_value_t<_Ip>, remove_cvref_t<iter_reference_t<_Ip>>> &&
-  (is_pointer_v<_Ip> || requires { sizeof(__pointer_traits_element_type<_Ip>); }) &&
   requires(const _Ip& __i) {
     { _VSTD::to_address(__i) } -> same_as<add_pointer_t<iter_reference_t<_Ip>>>;
   };

diff  --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/contiguous_iterator.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/contiguous_iterator.compile.pass.cpp
index e5d24f430297a..ba75ce2a9b52c 100644
--- a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/contiguous_iterator.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/contiguous_iterator.compile.pass.cpp
@@ -101,9 +101,10 @@ static_assert(!std::contiguous_iterator<mismatch_value_iter_ref_t>);
 struct wrong_iter_reference_t {
     typedef std::contiguous_iterator_tag    iterator_category;
     typedef short                           value_type;
+    typedef short                           element_type;
     typedef std::ptr
diff _t                  
diff erence_type;
-    typedef int*                            pointer;
-    typedef short&                          reference;
+    typedef short*                          pointer;
+    typedef int&                            reference;
     typedef wrong_iter_reference_t          self;
 
     wrong_iter_reference_t();
@@ -132,40 +133,6 @@ struct wrong_iter_reference_t {
 static_assert(std::random_access_iterator<wrong_iter_reference_t>);
 static_assert(!std::contiguous_iterator<wrong_iter_reference_t>);
 
-struct no_element_type {
-    typedef std::contiguous_iterator_tag    iterator_category;
-    typedef int                             value_type;
-    typedef std::ptr
diff _t                  
diff erence_type;
-    typedef int*                            pointer;
-    typedef int&                            reference;
-    typedef no_element_type                 self;
-
-    no_element_type();
-
-    reference operator*() const;
-    pointer operator->() const;
-    auto operator<=>(const self&) const = default;
-
-    self& operator++();
-    self operator++(int);
-
-    self& operator--();
-    self operator--(int);
-
-    self& operator+=(
diff erence_type n);
-    self operator+(
diff erence_type n) const;
-    friend self operator+(
diff erence_type n, self x);
-
-    self& operator-=(
diff erence_type n);
-    self operator-(
diff erence_type n) const;
-    
diff erence_type operator-(const self& n) const;
-
-    reference operator[](
diff erence_type n) const;
-};
-
-static_assert(std::random_access_iterator<no_element_type>);
-static_assert(!std::contiguous_iterator<no_element_type>);
-
 struct to_address_wrong_return_type {
     typedef std::contiguous_iterator_tag    iterator_category;
     typedef int                             value_type;

diff  --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/contiguous_iterator.verify.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/contiguous_iterator.verify.cpp
new file mode 100644
index 0000000000000..189a00d7975a8
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/contiguous_iterator.verify.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-no-concepts
+// REQUIRES: libc++
+
+// This test checks that std::contiguous_iterator uses std::to_address, which is not SFINAE-friendly
+// when the type is missing the `T::element_type` typedef.
+
+#include <iterator>
+
+#include <compare>
+#include <cstddef>
+
+struct no_element_type {
+    typedef std::contiguous_iterator_tag    iterator_category;
+    typedef int                             value_type;
+    typedef std::ptr
diff _t                  
diff erence_type;
+    typedef int*                            pointer;
+    typedef int&                            reference;
+    typedef no_element_type                 self;
+
+    no_element_type();
+
+    reference operator*() const;
+    pointer operator->() const;
+    auto operator<=>(const self&) const = default;
+
+    self& operator++();
+    self operator++(int);
+
+    self& operator--();
+    self operator--(int);
+
+    self& operator+=(
diff erence_type n);
+    self operator+(
diff erence_type n) const;
+    friend self operator+(
diff erence_type n, self x);
+
+    self& operator-=(
diff erence_type n);
+    self operator-(
diff erence_type n) const;
+    
diff erence_type operator-(const self& n) const;
+
+    reference operator[](
diff erence_type n) const;
+};
+
+void test() {
+    (void) std::contiguous_iterator<no_element_type>;
+		// expected-error@*:* {{implicit instantiation of undefined template}}
+		// expected-note@*:* {{to_address}}
+}


        


More information about the libcxx-commits mailing list