[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