[libcxx-commits] [libcxx] 1055cb9 - [libc++] Deprecate std::iterator and remove it as a base class

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Thu May 27 08:32:24 PDT 2021


Author: Louis Dionne
Date: 2021-05-27T11:34:04-04:00
New Revision: 1055cb91b48280da0c42c5287b227cfdaae633b2

URL: https://github.com/llvm/llvm-project/commit/1055cb91b48280da0c42c5287b227cfdaae633b2
DIFF: https://github.com/llvm/llvm-project/commit/1055cb91b48280da0c42c5287b227cfdaae633b2.diff

LOG: [libc++] Deprecate std::iterator and remove it as a base class

C++17 deprecated std::iterator and removed it as a base class for all
iterator adaptors. We implement that change, but we still provide a way
to inherit from std::iterator in the few cases where doing otherwise
would be an ABI break.

Supersedes D101729 and the std::iterator base parts of D103101 and D102657.

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

Added: 
    libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/cpp20_iter_traits.compile.pass.cpp
    libcxx/test/std/iterators/iterator.primitives/iterator.basic/deprecated.verify.cpp
    libcxx/test/std/utilities/memory/storage.iterator/types.compile.pass.cpp

Modified: 
    libcxx/include/__config
    libcxx/include/__memory/raw_storage_iterator.h
    libcxx/include/iterator
    libcxx/include/memory
    libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/cpp20_iter_concepts.pass.cpp
    libcxx/test/std/iterators/iterator.primitives/iterator.basic/iterator.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/types.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/types.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/types.pass.cpp
    libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iterator/types.pass.cpp
    libcxx/test/std/iterators/stream.iterators/istream.iterator/types.pass.cpp
    libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_proxy/proxy.pass.cpp
    libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/types.pass.cpp
    libcxx/test/std/iterators/stream.iterators/ostream.iterator/types.pass.cpp
    libcxx/test/std/iterators/stream.iterators/ostreambuf.iterator/types.pass.cpp

Removed: 
    libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/cpp20_iter_traits.pass.cpp


################################################################################
diff  --git a/libcxx/include/__config b/libcxx/include/__config
index d215fdd078a6b..dcb134bdaad23 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -94,6 +94,9 @@
 #  define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
 // Enable optimized version of __do_get_(un)signed which avoids redundant copies.
 #  define _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
+// Give reverse_iterator<T> one data member of type T, not two.
+// Also, in C++17 and later, don't derive iterator types from std::iterator.
+#  define _LIBCPP_ABI_NO_ITERATOR_BASES
 // Use the smallest possible integer type to represent the index of the variant.
 // Previously libc++ used "unsigned int" exclusively.
 #  define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION

diff  --git a/libcxx/include/__memory/raw_storage_iterator.h b/libcxx/include/__memory/raw_storage_iterator.h
index 8eed85311b88f..b43000b179486 100644
--- a/libcxx/include/__memory/raw_storage_iterator.h
+++ b/libcxx/include/__memory/raw_storage_iterator.h
@@ -27,17 +27,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR)
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <class _OutputIterator, class _Tp>
 class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 raw_storage_iterator
-    : public iterator<output_iterator_tag,
-                      _Tp,                                         // purposefully not C++03
-                      ptr
diff _t,                                   // purposefully not C++03
-                      _Tp*,                                        // purposefully not C++03
-                      raw_storage_iterator<_OutputIterator, _Tp>&> // purposefully not C++03
+#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
+    : public iterator<output_iterator_tag, void, void, void, void>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
 private:
     _OutputIterator __x_;
 public:
+    typedef output_iterator_tag iterator_category;
+    typedef void                value_type;
+    typedef void                
diff erence_type;
+    typedef void                pointer;
+    typedef void                reference;
+
     _LIBCPP_INLINE_VISIBILITY explicit raw_storage_iterator(_OutputIterator __x) : __x_(__x) {}
     _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator*() {return *this;}
     _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(const _Tp& __element)

diff  --git a/libcxx/include/iterator b/libcxx/include/iterator
index 8dbcc9d0f355c..e290a4922a294 100644
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -93,7 +93,7 @@ template<class I>
 
 template<class Category, class T, class Distance = ptr
diff _t,
          class Pointer = T*, class Reference = T&>
-struct iterator
+struct iterator                                            // deprecated in C++17
 {
     typedef T         value_type;
     typedef Distance  
diff erence_type;
@@ -137,7 +137,7 @@ namespace ranges {
 
 template <class Iterator>
 class reverse_iterator
-    : public iterator<typename iterator_traits<Iterator>::iterator_category,
+    : public iterator<typename iterator_traits<Iterator>::iterator_category, // until C++17
                       typename iterator_traits<Iterator>::value_type,
                       typename iterator_traits<Iterator>::
diff erence_type,
                       typename iterator_traits<Iterator>::pointer,
@@ -343,7 +343,7 @@ constexpr  move_iterator<Iterator> make_move_iterator(const Iterator& i);
 
 template <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptr
diff _t>
 class istream_iterator
-    : public iterator<input_iterator_tag, T, Distance, const T*, const T&>
+    : public iterator<input_iterator_tag, T, Distance, const T*, const T&> // until C++17
 {
 public:
     typedef charT char_type;
@@ -370,7 +370,7 @@ bool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
 
 template <class T, class charT = char, class traits = char_traits<charT> >
 class ostream_iterator
-    : public iterator<output_iterator_tag, void, void, void ,void>
+    : public iterator<output_iterator_tag, void, void, void ,void> // until C++17
 {
 public:
     typedef charT char_type;
@@ -390,7 +390,7 @@ public:
 
 template<class charT, class traits = char_traits<charT> >
 class istreambuf_iterator
-    : public iterator<input_iterator_tag, charT,
+    : public iterator<input_iterator_tag, charT,                // until C++17
                       typename traits::off_type, unspecified,
                       charT>
 {
@@ -423,7 +423,7 @@ bool operator!=(const istreambuf_iterator<charT,traits>& a,
 
 template <class charT, class traits = char_traits<charT> >
 class ostreambuf_iterator
-    : public iterator<output_iterator_tag, void, void, void, void>
+    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
 {
 public:
     typedef charT                         char_type;
@@ -509,7 +509,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template<class _Category, class _Tp, class _Distance = ptr
diff _t,
          class _Pointer = _Tp*, class _Reference = _Tp&>
-struct _LIBCPP_TEMPLATE_VIS iterator
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 iterator
 {
     typedef _Tp        value_type;
     typedef _Distance  
diff erence_type;
@@ -628,16 +628,22 @@ template <class _Tp>
 struct __is_stashing_iterator<_Tp, typename __void_t<typename _Tp::__stashing_iterator_tag>::type>
   : true_type {};
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <class _Iter>
 class _LIBCPP_TEMPLATE_VIS reverse_iterator
+#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
     : public iterator<typename iterator_traits<_Iter>::iterator_category,
                       typename iterator_traits<_Iter>::value_type,
                       typename iterator_traits<_Iter>::
diff erence_type,
                       typename iterator_traits<_Iter>::pointer,
                       typename iterator_traits<_Iter>::reference>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
 private:
-    /*mutable*/ _Iter __t;  // no longer used as of LWG #2360, not removed due to ABI break
+#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
+    _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break
+#endif
 
     static_assert(!__is_stashing_iterator<_Iter>::value,
       "The specified iterator type cannot be used with reverse_iterator; "
@@ -653,12 +659,15 @@ public:
     typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
         random_access_iterator_tag,
         typename iterator_traits<_Iter>::iterator_category>  iterator_category;
+    typedef typename iterator_traits<_Iter>::value_type      value_type;
+
 #if _LIBCPP_STD_VER > 17
     typedef _If<__is_cpp17_random_access_iterator<_Iter>::value,
         random_access_iterator_tag,
         bidirectional_iterator_tag>                          iterator_concept;
 #endif
 
+#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
     reverse_iterator() : __t(), current() {}
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
@@ -670,6 +679,19 @@ public:
         _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
         reverse_iterator& operator=(const reverse_iterator<_Up>& __u)
             { __t = current = __u.base(); return *this; }
+#else
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    reverse_iterator() : current() {}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+    explicit reverse_iterator(_Iter __x) : current(__x) {}
+    template <class _Up>
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+        reverse_iterator(const reverse_iterator<_Up>& __u) : current(__u.base()) {}
+    template <class _Up>
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
+        reverse_iterator& operator=(const reverse_iterator<_Up>& __u)
+            { current = __u.base(); return *this; }
+#endif
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
     _Iter base() const {return current;}
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
@@ -780,17 +802,22 @@ reverse_iterator<_Iter> make_reverse_iterator(_Iter __i)
 }
 #endif
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <class _Container>
 class _LIBCPP_TEMPLATE_VIS back_insert_iterator
-    : public iterator<output_iterator_tag,
-                      void,
-                      void,
-                      void,
-                      void>
+#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
+    : public iterator<output_iterator_tag, void, void, void, void>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
 protected:
     _Container* container;
 public:
+    typedef output_iterator_tag iterator_category;
+    typedef void value_type;
+    typedef void 
diff erence_type;
+    typedef void pointer;
+    typedef void reference;
     typedef _Container container_type;
 
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
@@ -813,17 +840,22 @@ back_inserter(_Container& __x)
     return back_insert_iterator<_Container>(__x);
 }
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <class _Container>
 class _LIBCPP_TEMPLATE_VIS front_insert_iterator
-    : public iterator<output_iterator_tag,
-                      void,
-                      void,
-                      void,
-                      void>
+#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
+    : public iterator<output_iterator_tag, void, void, void, void>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
 protected:
     _Container* container;
 public:
+    typedef output_iterator_tag iterator_category;
+    typedef void value_type;
+    typedef void 
diff erence_type;
+    typedef void pointer;
+    typedef void reference;
     typedef _Container container_type;
 
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
@@ -846,18 +878,23 @@ front_inserter(_Container& __x)
     return front_insert_iterator<_Container>(__x);
 }
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <class _Container>
 class _LIBCPP_TEMPLATE_VIS insert_iterator
-    : public iterator<output_iterator_tag,
-                      void,
-                      void,
-                      void,
-                      void>
+#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
+    : public iterator<output_iterator_tag, void, void, void, void>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
 protected:
     _Container* container;
     typename _Container::iterator iter;
 public:
+    typedef output_iterator_tag iterator_category;
+    typedef void value_type;
+    typedef void 
diff erence_type;
+    typedef void pointer;
+    typedef void reference;
     typedef _Container container_type;
 
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator(_Container& __x, typename _Container::iterator __i)
@@ -881,12 +918,21 @@ inserter(_Container& __x, typename _Container::iterator __i)
     return insert_iterator<_Container>(__x, __i);
 }
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <class _Tp, class _CharT = char,
           class _Traits = char_traits<_CharT>, class _Distance = ptr
diff _t>
 class _LIBCPP_TEMPLATE_VIS istream_iterator
+#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
     : public iterator<input_iterator_tag, _Tp, _Distance, const _Tp*, const _Tp&>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
 public:
+    typedef input_iterator_tag iterator_category;
+    typedef _Tp value_type;
+    typedef _Distance 
diff erence_type;
+    typedef const _Tp* pointer;
+    typedef const _Tp& reference;
     typedef _CharT char_type;
     typedef _Traits traits_type;
     typedef basic_istream<_CharT,_Traits> istream_type;
@@ -943,10 +989,14 @@ operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
     return !(__x == __y);
 }
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <class _Tp, class _CharT = char, class _Traits = char_traits<_CharT> >
 class _LIBCPP_TEMPLATE_VIS ostream_iterator
+#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
     : public iterator<output_iterator_tag, void, void, void, void>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
 public:
     typedef output_iterator_tag             iterator_category;
     typedef void                            value_type;
@@ -982,13 +1032,22 @@ public:
     _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++(int) {return *this;}
 };
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template<class _CharT, class _Traits>
 class _LIBCPP_TEMPLATE_VIS istreambuf_iterator
+#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
     : public iterator<input_iterator_tag, _CharT,
                       typename _Traits::off_type, _CharT*,
                       _CharT>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
 public:
+    typedef input_iterator_tag              iterator_category;
+    typedef _CharT                          value_type;
+    typedef typename _Traits::off_type      
diff erence_type;
+    typedef _CharT*                         pointer;
+    typedef _CharT                          reference;
     typedef _CharT                          char_type;
     typedef _Traits                         traits_type;
     typedef typename _Traits::int_type      int_type;
@@ -1052,10 +1111,14 @@ bool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a,
                 const istreambuf_iterator<_CharT,_Traits>& __b)
                 {return !__a.equal(__b);}
 
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
 template <class _CharT, class _Traits>
 class _LIBCPP_TEMPLATE_VIS ostreambuf_iterator
+#if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
     : public iterator<output_iterator_tag, void, void, void, void>
+#endif
 {
+_LIBCPP_SUPPRESS_DEPRECATED_POP
 public:
     typedef output_iterator_tag                 iterator_category;
     typedef void                                value_type;

diff  --git a/libcxx/include/memory b/libcxx/include/memory
index 5d53ea5448181..7c3c92c2015d7 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -154,11 +154,7 @@ bool operator!=(const allocator<T>&, const allocator<U>&) noexcept; // constexpr
 
 template <class OutputIterator, class T>
 class raw_storage_iterator
-    : public iterator<output_iterator_tag,
-                      T,                               // purposefully not C++03
-                      ptr
diff _t,                       // purposefully not C++03
-                      T*,                              // purposefully not C++03
-                      raw_storage_iterator&>           // purposefully not C++03
+    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
 {
 public:
     explicit raw_storage_iterator(OutputIterator x);

diff  --git a/libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/cpp20_iter_concepts.pass.cpp b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/cpp20_iter_concepts.pass.cpp
index 1fbba0263cdad..17ac69b65561f 100644
--- a/libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/cpp20_iter_concepts.pass.cpp
+++ b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/cpp20_iter_concepts.pass.cpp
@@ -24,26 +24,41 @@
 #include <iterator>
 struct OtherTag : std::input_iterator_tag {};
 struct OtherTagTwo : std::output_iterator_tag {};
-struct MyIter : std::iterator<std::random_access_iterator_tag, char> {
+
+struct MyIter {
+  using iterator_category = std::random_access_iterator_tag;
   using iterator_concept = int;
+  using value_type = char;
+  using 
diff erence_type = std::ptr
diff _t;
+  using pointer = char*;
+  using reference = char&;
 };
-struct MyIter2 : std::iterator<OtherTag, char> {
 
+struct MyIter2 {
+  using iterator_category = OtherTag;
+  using value_type = char;
+  using 
diff erence_type = std::ptr
diff _t;
+  using pointer = char*;
+  using reference = char&;
 };
+
 struct MyIter3 {};
 
 struct Empty {};
 struct EmptyWithSpecial {};
-namespace std {
 template <>
-struct iterator_traits<MyIter3>
-    : std::iterator<OtherTagTwo, char> {};
+struct std::iterator_traits<MyIter3> {
+  using iterator_category = OtherTagTwo;
+  using value_type = char;
+  using 
diff erence_type = std::ptr
diff _t;
+  using pointer = char*;
+  using reference = char&;
+};
 
 template <>
-struct iterator_traits<EmptyWithSpecial> {
+struct std::iterator_traits<EmptyWithSpecial> {
   // empty non-default.
 };
-} // namespace std
 
 int main(int, char**) {
   // If the qualified-id ITER_TRAITS(I)::iterator_concept is valid and names a type,

diff  --git a/libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/cpp20_iter_traits.compile.pass.cpp b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/cpp20_iter_traits.compile.pass.cpp
new file mode 100644
index 0000000000000..50047c1b90513
--- /dev/null
+++ b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/cpp20_iter_traits.compile.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// ITER_TRAITS(I)
+
+// For a type I, let ITER_TRAITS(I) denote the type I if iterator_traits<I> names
+// a specialization generated from the primary template. Otherwise,
+// ITER_TRAITS(I) denotes iterator_traits<I>.
+
+#include <iterator>
+#include <type_traits>
+
+#include "test_iterators.h"
+
+struct A : random_access_iterator<int*> {};
+struct B : random_access_iterator<int*> {};
+struct C : random_access_iterator<int*> {};
+struct D : random_access_iterator<int*> {};
+template<> struct std::iterator_traits<B> {};
+template<> struct std::iterator_traits<C> : std::iterator_traits<A> {};
+template<> struct std::iterator_traits<D> : std::iterator_traits<int*> {};
+
+static_assert(std::is_same<std::_ITER_TRAITS<int*>, std::iterator_traits<int*>>::value, "");
+static_assert(std::is_same<std::_ITER_TRAITS<A>, A>::value, "");
+static_assert(std::is_same<std::_ITER_TRAITS<B>, std::iterator_traits<B>>::value, "");
+static_assert(std::is_same<std::_ITER_TRAITS<C>, std::iterator_traits<C>>::value, "");
+static_assert(std::is_same<std::_ITER_TRAITS<D>, std::iterator_traits<D>>::value, "");

diff  --git a/libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/cpp20_iter_traits.pass.cpp b/libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/cpp20_iter_traits.pass.cpp
deleted file mode 100644
index 1d72bb7fb6074..0000000000000
--- a/libcxx/test/libcxx/iterators/iterator.requirements/iterator.concepts/cpp20_iter_traits.pass.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-
-// ITER_TRAITS(I)
-
-// For a type I, let ITER_TRAITS(I) denote the type I if iterator_traits<I> names
-// a specialization generated from the primary template. Otherwise,
-// ITER_TRAITS(I) denotes iterator_traits<I>.
-
-#include "test_macros.h"
-
-#include <iterator>
-
-struct MyIter : std::iterator<std::random_access_iterator_tag, char> {};
-struct MyIter2 : std::iterator<std::random_access_iterator_tag, char> {};
-struct MyIter3 : std::iterator<std::random_access_iterator_tag, char> {};
-
-namespace std {
-template <>
-struct iterator_traits<MyIter>
-    : iterator_traits<std::iterator<std::random_access_iterator_tag, char> > {};
-template <>
-struct iterator_traits<MyIter2>
-    : std::iterator<std::random_access_iterator_tag, char> {};
-
-} // namespace std
-
-int main(int, char**) {
-  ASSERT_SAME_TYPE(std::_ITER_TRAITS<char*>, std::iterator_traits<char*>);
-  {
-    using ClassIter = std::reverse_iterator<char*>;
-    ASSERT_SAME_TYPE(std::_ITER_TRAITS<ClassIter>, ClassIter);
-    ASSERT_SAME_TYPE(std::_ITER_TRAITS<MyIter3>, MyIter3);
-  }
-  {
-    ASSERT_SAME_TYPE(std::_ITER_TRAITS<MyIter>, std::iterator_traits<MyIter>);
-    ASSERT_SAME_TYPE(std::_ITER_TRAITS<MyIter2>, std::iterator_traits<MyIter2>);
-  }
-  return 0;
-}

diff  --git a/libcxx/test/std/iterators/iterator.primitives/iterator.basic/deprecated.verify.cpp b/libcxx/test/std/iterators/iterator.primitives/iterator.basic/deprecated.verify.cpp
new file mode 100644
index 0000000000000..097801d027198
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.primitives/iterator.basic/deprecated.verify.cpp
@@ -0,0 +1,15 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// std::iterator
+
+#include <iterator>
+
+std::iterator<std::input_iterator_tag, char> it; // expected-warning-re {{'iterator<{{.+}}>' is deprecated}}

diff  --git a/libcxx/test/std/iterators/iterator.primitives/iterator.basic/iterator.pass.cpp b/libcxx/test/std/iterators/iterator.primitives/iterator.basic/iterator.pass.cpp
index 49abf67692f66..c04f15e60b925 100644
--- a/libcxx/test/std/iterators/iterator.primitives/iterator.basic/iterator.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.primitives/iterator.basic/iterator.pass.cpp
@@ -19,6 +19,8 @@
 //   typedef Category  iterator_category;
 // };
 
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
 #include <iterator>
 #include <type_traits>
 

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/types.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/types.pass.cpp
index e1cc4974c66f1..baf2383d9f62e 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/types.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/types.pass.cpp
@@ -52,6 +52,11 @@ test()
     static_assert((std::is_same<typename R::reference, void>::value), "");
     static_assert((std::is_same<typename R::pointer, void>::value), "");
     static_assert((std::is_same<typename R::iterator_category, std::output_iterator_tag>::value), "");
+
+#if TEST_STD_VER <= 14
+    typedef std::iterator<std::output_iterator_tag, void, void, void, void> iterator_base;
+    static_assert((std::is_base_of<iterator_base, R>::value), "");
+#endif
 }
 
 int main(int, char**)

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/types.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/types.pass.cpp
index 97139ae2acbed..4d122538b4cd0 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/types.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/types.pass.cpp
@@ -53,6 +53,11 @@ test()
     static_assert((std::is_same<typename R::reference, void>::value), "");
     static_assert((std::is_same<typename R::pointer, void>::value), "");
     static_assert((std::is_same<typename R::iterator_category, std::output_iterator_tag>::value), "");
+
+#if TEST_STD_VER <= 14
+    typedef std::iterator<std::output_iterator_tag, void, void, void, void> iterator_base;
+    static_assert((std::is_base_of<iterator_base, R>::value), "");
+#endif
 }
 
 int main(int, char**)

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/types.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/types.pass.cpp
index 1e199b3051b31..d33079229cc66 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/types.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/types.pass.cpp
@@ -56,6 +56,11 @@ test()
     static_assert((std::is_same<typename R::reference, void>::value), "");
     static_assert((std::is_same<typename R::pointer, void>::value), "");
     static_assert((std::is_same<typename R::iterator_category, std::output_iterator_tag>::value), "");
+
+#if TEST_STD_VER <= 14
+    typedef std::iterator<std::output_iterator_tag, void, void, void, void> iterator_base;
+    static_assert((std::is_base_of<iterator_base, R>::value), "");
+#endif
 }
 
 int main(int, char**)

diff  --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iterator/types.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iterator/types.pass.cpp
index 0406bc23efc9f..939cf87a5d464 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iterator/types.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iterator/types.pass.cpp
@@ -49,6 +49,11 @@ test()
     static_assert((std::is_same<typename R::
diff erence_type, typename T::
diff erence_type>::value), "");
     static_assert((std::is_same<typename R::reference, typename T::reference>::value), "");
     static_assert((std::is_same<typename R::pointer, typename std::iterator_traits<It>::pointer>::value), "");
+
+#if TEST_STD_VER <= 14
+    typedef std::iterator<typename T::iterator_category, typename T::value_type> iterator_base;
+    static_assert((std::is_base_of<iterator_base, R>::value), "");
+#endif
 #if TEST_STD_VER > 17
     if constexpr (std::is_same_v<typename T::iterator_category, std::contiguous_iterator_tag>) {
         static_assert((std::is_same<typename R::iterator_category, std::random_access_iterator_tag>::value), "");

diff  --git a/libcxx/test/std/iterators/stream.iterators/istream.iterator/types.pass.cpp b/libcxx/test/std/iterators/stream.iterators/istream.iterator/types.pass.cpp
index aa00a0d53b100..2018be6c7d07e 100644
--- a/libcxx/test/std/iterators/stream.iterators/istream.iterator/types.pass.cpp
+++ b/libcxx/test/std/iterators/stream.iterators/istream.iterator/types.pass.cpp
@@ -10,9 +10,7 @@
 
 // template <class T, class charT = char, class traits = char_traits<charT>,
 //           class Distance = ptr
diff _t>
-// class istream_iterator
-//     : public iterator<input_iterator_tag, T, Distance, const T*, const T&>
-// {
+// class istream_iterator {
 // public:
 //     typedef charT char_type;
 //     typedef traits traits_type;
@@ -40,41 +38,41 @@
 
 int main(int, char**)
 {
+    {
     typedef std::istream_iterator<double> I1; // double is trivially destructible
 #if TEST_STD_VER <= 14
-    static_assert((std::is_convertible<I1,
-        std::iterator<std::input_iterator_tag, double, std::ptr
diff _t,
-        const double*, const double&> >::value), "");
-#else
+    typedef std::iterator<std::input_iterator_tag, double, std::ptr
diff _t, double const*, double const&> iterator_base;
+    static_assert((std::is_base_of<iterator_base, I1>::value), "");
+#endif
     static_assert((std::is_same<I1::iterator_category, std::input_iterator_tag>::value), "");
     static_assert((std::is_same<I1::value_type, double>::value), "");
     static_assert((std::is_same<I1::
diff erence_type, std::ptr
diff _t>::value), "");
     static_assert((std::is_same<I1::pointer, const double*>::value), "");
     static_assert((std::is_same<I1::reference, const double&>::value), "");
-#endif
     static_assert((std::is_same<I1::char_type, char>::value), "");
     static_assert((std::is_same<I1::traits_type, std::char_traits<char> >::value), "");
     static_assert((std::is_same<I1::istream_type, std::istream>::value), "");
     static_assert( std::is_trivially_copy_constructible<I1>::value, "");
     static_assert( std::is_trivially_destructible<I1>::value, "");
+    }
 
+    {
     typedef std::istream_iterator<unsigned, wchar_t> I2; // unsigned is trivially destructible
 #if TEST_STD_VER <= 14
-    static_assert((std::is_convertible<I2,
-        std::iterator<std::input_iterator_tag, unsigned, std::ptr
diff _t,
-        const unsigned*, const unsigned&> >::value), "");
-#else
+    typedef std::iterator<std::input_iterator_tag, unsigned, std::ptr
diff _t, const unsigned*, const unsigned&> iterator_base;
+    static_assert((std::is_base_of<iterator_base, I2>::value), "");
+#endif
     static_assert((std::is_same<I2::iterator_category, std::input_iterator_tag>::value), "");
     static_assert((std::is_same<I2::value_type, unsigned>::value), "");
     static_assert((std::is_same<I2::
diff erence_type, std::ptr
diff _t>::value), "");
     static_assert((std::is_same<I2::pointer, const unsigned*>::value), "");
     static_assert((std::is_same<I2::reference, const unsigned&>::value), "");
-#endif
     static_assert((std::is_same<I2::char_type, wchar_t>::value), "");
     static_assert((std::is_same<I2::traits_type, std::char_traits<wchar_t> >::value), "");
     static_assert((std::is_same<I2::istream_type, std::wistream>::value), "");
     static_assert( std::is_trivially_copy_constructible<I2>::value, "");
     static_assert( std::is_trivially_destructible<I2>::value, "");
+    }
 
     typedef std::istream_iterator<std::string> I3; // string is NOT trivially destructible
     static_assert(!std::is_trivially_copy_constructible<I3>::value, "");

diff  --git a/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_proxy/proxy.pass.cpp b/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_proxy/proxy.pass.cpp
index 62e7acf01156e..f385a4027ff4e 100644
--- a/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_proxy/proxy.pass.cpp
+++ b/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_proxy/proxy.pass.cpp
@@ -9,11 +9,7 @@
 // <iterator>
 
 // template<class charT, class traits = char_traits<charT> >
-// class istreambuf_iterator
-//     : public iterator<input_iterator_tag, charT,
-//                       typename traits::off_type, charT*,
-//                       charT>
-// {
+// class istreambuf_iterator {
 // public:
 //     ...
 //     proxy operator++(int);

diff  --git a/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/types.pass.cpp b/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/types.pass.cpp
index c2f323b03a6eb..d9cd65ad7f949 100644
--- a/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/types.pass.cpp
+++ b/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/types.pass.cpp
@@ -9,11 +9,7 @@
 // <iterator>
 
 // template<class charT, class traits = char_traits<charT> >
-// class istreambuf_iterator
-//     : public iterator<input_iterator_tag, charT,
-//                       typename traits::off_type, unspecified,
-//                       charT>
-// {
+// class istreambuf_iterator {
 // public:
 //     typedef charT                         char_type;
 //     typedef traits                        traits_type;
@@ -33,7 +29,12 @@
 
 int main(int, char**)
 {
+    {
     typedef std::istreambuf_iterator<char> I1;
+#if TEST_STD_VER <= 14
+    typedef std::iterator<std::input_iterator_tag, char, std::char_traits<char>::off_type, char*, char> iterator_base;
+    static_assert((std::is_base_of<iterator_base, I1>::value), "");
+#endif
     static_assert((std::is_same<I1::iterator_category, std::input_iterator_tag>::value), "");
     static_assert((std::is_same<I1::value_type, char>::value), "");
     static_assert((std::is_same<I1::
diff erence_type, std::char_traits<char>::off_type>::value), "");
@@ -47,8 +48,14 @@ int main(int, char**)
     static_assert((std::is_nothrow_default_constructible<I1>::value), "" );
     static_assert((std::is_trivially_copy_constructible<I1>::value), "" );
     static_assert((std::is_trivially_destructible<I1>::value), "" );
+    }
 
+    {
     typedef std::istreambuf_iterator<wchar_t> I2;
+#if TEST_STD_VER <= 14
+    typedef std::iterator<std::input_iterator_tag, wchar_t, std::char_traits<wchar_t>::off_type, wchar_t*, wchar_t> iterator_base;
+    static_assert((std::is_base_of<iterator_base, I2>::value), "");
+#endif
     static_assert((std::is_same<I2::iterator_category, std::input_iterator_tag>::value), "");
     static_assert((std::is_same<I2::value_type, wchar_t>::value), "");
     static_assert((std::is_same<I2::
diff erence_type, std::char_traits<wchar_t>::off_type>::value), "");
@@ -62,6 +69,7 @@ int main(int, char**)
     static_assert((std::is_nothrow_default_constructible<I2>::value), "" );
     static_assert((std::is_trivially_copy_constructible<I2>::value), "" );
     static_assert((std::is_trivially_destructible<I2>::value), "" );
+    }
 
   return 0;
 }

diff  --git a/libcxx/test/std/iterators/stream.iterators/ostream.iterator/types.pass.cpp b/libcxx/test/std/iterators/stream.iterators/ostream.iterator/types.pass.cpp
index 739e39d62b78f..b5ac8199e5208 100644
--- a/libcxx/test/std/iterators/stream.iterators/ostream.iterator/types.pass.cpp
+++ b/libcxx/test/std/iterators/stream.iterators/ostream.iterator/types.pass.cpp
@@ -10,9 +10,7 @@
 
 // template <class T, class charT = char, class traits = char_traits<charT>,
 //           class Distance = ptr
diff _t>
-// class ostream_iterator
-//     : public iterator<output_iterator_tag, void, void, void, void>
-// {
+// class ostream_iterator {
 // public:
 //     typedef charT char_type;
 //     typedef traits traits_type;
@@ -27,11 +25,12 @@
 
 int main(int, char**)
 {
+    {
     typedef std::ostream_iterator<double> I1;
 #if TEST_STD_VER <= 14
-    static_assert((std::is_convertible<I1,
-        std::iterator<std::output_iterator_tag, void, void, void, void> >::value), "");
-#else
+    typedef std::iterator<std::output_iterator_tag, void, void, void, void> iterator_base;
+    static_assert((std::is_base_of<iterator_base, I1>::value), "");
+#endif
     static_assert((std::is_same<I1::iterator_category, std::output_iterator_tag>::value), "");
     static_assert((std::is_same<I1::value_type, void>::value), "");
 #if TEST_STD_VER <= 17
@@ -41,15 +40,17 @@ int main(int, char**)
 #endif
     static_assert((std::is_same<I1::pointer, void>::value), "");
     static_assert((std::is_same<I1::reference, void>::value), "");
-#endif
     static_assert((std::is_same<I1::char_type, char>::value), "");
     static_assert((std::is_same<I1::traits_type, std::char_traits<char> >::value), "");
     static_assert((std::is_same<I1::ostream_type, std::ostream>::value), "");
+    }
+
+    {
     typedef std::ostream_iterator<unsigned, wchar_t> I2;
 #if TEST_STD_VER <= 14
-    static_assert((std::is_convertible<I2,
-        std::iterator<std::output_iterator_tag, void, void, void, void> >::value), "");
-#else
+    typedef std::iterator<std::output_iterator_tag, void, void, void, void> iterator_base;
+    static_assert((std::is_base_of<iterator_base, I2>::value), "");
+#endif
     static_assert((std::is_same<I2::iterator_category, std::output_iterator_tag>::value), "");
     static_assert((std::is_same<I2::value_type, void>::value), "");
 #if TEST_STD_VER <= 17
@@ -59,10 +60,10 @@ int main(int, char**)
 #endif
     static_assert((std::is_same<I2::pointer, void>::value), "");
     static_assert((std::is_same<I2::reference, void>::value), "");
-#endif
     static_assert((std::is_same<I2::char_type, wchar_t>::value), "");
     static_assert((std::is_same<I2::traits_type, std::char_traits<wchar_t> >::value), "");
     static_assert((std::is_same<I2::ostream_type, std::wostream>::value), "");
+    }
 
   return 0;
 }

diff  --git a/libcxx/test/std/iterators/stream.iterators/ostreambuf.iterator/types.pass.cpp b/libcxx/test/std/iterators/stream.iterators/ostreambuf.iterator/types.pass.cpp
index 2a4e6ffa5e6b6..4d3925f2e5285 100644
--- a/libcxx/test/std/iterators/stream.iterators/ostreambuf.iterator/types.pass.cpp
+++ b/libcxx/test/std/iterators/stream.iterators/ostreambuf.iterator/types.pass.cpp
@@ -9,9 +9,7 @@
 // <iterator>
 
 // template <class charT, class traits = char_traits<charT> >
-// class ostreambuf_iterator
-//   : public iterator<output_iterator_tag, void, void, void, void>
-// {
+// class ostreambuf_iterator {
 // public:
 //   typedef charT                          char_type;
 //   typedef traits                         traits_type;
@@ -28,11 +26,12 @@
 
 int main(int, char**)
 {
+    {
     typedef std::ostreambuf_iterator<char> I1;
 #if TEST_STD_VER <= 14
-    static_assert((std::is_convertible<I1,
-        std::iterator<std::output_iterator_tag, void, void, void, void> >::value), "");
-#else
+    typedef std::iterator<std::output_iterator_tag, void, void, void, void> iterator_base;
+    static_assert((std::is_base_of<iterator_base, I1>::value), "");
+#endif
     static_assert((std::is_same<I1::iterator_category, std::output_iterator_tag>::value), "");
     static_assert((std::is_same<I1::value_type, void>::value), "");
 #if TEST_STD_VER <= 17
@@ -42,17 +41,18 @@ int main(int, char**)
 #endif
     static_assert((std::is_same<I1::pointer, void>::value), "");
     static_assert((std::is_same<I1::reference, void>::value), "");
-#endif
     static_assert((std::is_same<I1::char_type, char>::value), "");
     static_assert((std::is_same<I1::traits_type, std::char_traits<char> >::value), "");
     static_assert((std::is_same<I1::streambuf_type, std::streambuf>::value), "");
     static_assert((std::is_same<I1::ostream_type, std::ostream>::value), "");
+    }
 
+    {
     typedef std::ostreambuf_iterator<wchar_t> I2;
 #if TEST_STD_VER <= 14
-    static_assert((std::is_convertible<I2,
-        std::iterator<std::output_iterator_tag, void, void, void, void> >::value), "");
-#else
+    typedef std::iterator<std::output_iterator_tag, void, void, void, void> iterator_base;
+    static_assert((std::is_base_of<iterator_base, I2>::value), "");
+#endif
     static_assert((std::is_same<I2::iterator_category, std::output_iterator_tag>::value), "");
     static_assert((std::is_same<I2::value_type, void>::value), "");
 #if TEST_STD_VER <= 17
@@ -62,11 +62,11 @@ int main(int, char**)
 #endif
     static_assert((std::is_same<I2::pointer, void>::value), "");
     static_assert((std::is_same<I2::reference, void>::value), "");
-#endif
     static_assert((std::is_same<I2::char_type, wchar_t>::value), "");
     static_assert((std::is_same<I2::traits_type, std::char_traits<wchar_t> >::value), "");
     static_assert((std::is_same<I2::streambuf_type, std::wstreambuf>::value), "");
     static_assert((std::is_same<I2::ostream_type, std::wostream>::value), "");
+    }
 
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/memory/storage.iterator/types.compile.pass.cpp b/libcxx/test/std/utilities/memory/storage.iterator/types.compile.pass.cpp
new file mode 100644
index 0000000000000..734e8d9937ef8
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/storage.iterator/types.compile.pass.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
+// raw_storage_iterator associated types
+
+#include <memory>
+#include <type_traits>
+
+struct T;
+typedef T* OutputIt;
+typedef std::raw_storage_iterator<OutputIt, T> It;
+
+static_assert(std::is_same<It::iterator_category, std::output_iterator_tag>::value, "");
+static_assert(std::is_same<It::value_type, void>::value, "");
+static_assert(std::is_same<It::
diff erence_type, void>::value, "");
+static_assert(std::is_same<It::pointer, void>::value, "");
+static_assert(std::is_same<It::reference, void>::value, "");


        


More information about the libcxx-commits mailing list