[libcxx] adds `cpp17-.*iterator` concepts for iterator_traits

The `iterator_traits` patch became too large for a concise review, so
the "bloat" —as it were— was moved into this patch. Also tests most
C++[98,17] iterator types to confirm backwards compatibility is
successful (regex iterators are intentionally not present, but directory
iterators are due to a peculiar error encountered while patching
`iterator_traits`).

Depends on D99461.

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

GitOrigin-RevId: 0148b653727592279e1e399129f9c623cd83bb38
diff --git a/include/iterator b/include/iterator
index cc2b264..5e9e822 100644
--- a/include/iterator
+++ b/include/iterator
@@ -40,6 +40,9 @@
     typedef random_access_iterator_tag iterator_category;
 };
 
+template<dereferenceable T>
+  using iter_reference_t = decltype(*declval<T&>());
+
 template<class Category, class T, class Distance = ptrdiff_t,
          class Pointer = T*, class Reference = T&>
 struct iterator
@@ -429,7 +432,6 @@
 #include <__memory/addressof.h>
 #include <__memory/pointer_traits.h>
 #include <version>
-#include <concepts>
 
 #include <__debug>
 
@@ -440,6 +442,20 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if !defined(_LIBCPP_HAS_NO_RANGES)
+
+template<class _Tp>
+using __with_reference = _Tp&;
+
+template<class _Tp>
+concept __referenceable = requires {
+  typename __with_reference<_Tp>;
+};
+
+template<class _Tp>
+concept __dereferenceable = requires(_Tp& __t) {
+  { *__t } -> __referenceable; // not required to be equality-preserving
+};
+
 // [incrementable.traits]
 template<class> struct incrementable_traits {};
 
@@ -520,6 +536,9 @@
 struct indirectly_readable_traits<_Tp>
   : __cond_value_type<typename _Tp::value_type> {};
 
+// [iterator.traits]
+template<__dereferenceable _Tp>
+using iter_reference_t = decltype(*declval<_Tp&>());
 #endif // !defined(_LIBCPP_HAS_NO_RANGES)
 
 template <class _Iter>
@@ -630,6 +649,71 @@
     typedef typename _Iter::iterator_category iterator_category;
 };
 
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+// The `cpp17-*-iterator` exposition-only concepts are easily confused with the Cpp17*Iterator tables,
+// so they've been banished to a namespace that makes it obvious they have a niche use-case.
+namespace __iterator_traits_detail {
+template<class _Ip>
+concept __cpp17_iterator =
+  requires(_Ip __i) {
+    {   *__i } -> __referenceable;
+    {  ++__i } -> same_as<_Ip&>;
+    { *__i++ } -> __referenceable;
+  } &&
+  copyable<_Ip>;
+
+template<class _Ip>
+concept __cpp17_input_iterator =
+  __cpp17_iterator<_Ip> &&
+  equality_comparable<_Ip> &&
+  requires(_Ip __i) {
+    typename incrementable_traits<_Ip>::difference_type;
+    typename indirectly_readable_traits<_Ip>::value_type;
+    typename common_reference_t<iter_reference_t<_Ip>&&,
+                                typename indirectly_readable_traits<_Ip>::value_type&>;
+    typename common_reference_t<decltype(*__i++)&&,
+                                typename indirectly_readable_traits<_Ip>::value_type&>;
+    requires signed_integral<typename incrementable_traits<_Ip>::difference_type>;
+  };
+
+template<class _Ip>
+concept __cpp17_forward_iterator =
+  __cpp17_input_iterator<_Ip> &&
+  constructible_from<_Ip> &&
+  is_lvalue_reference_v<iter_reference_t<_Ip>> &&
+  same_as<remove_cvref_t<iter_reference_t<_Ip>>,
+          typename indirectly_readable_traits<_Ip>::value_type> &&
+  requires(_Ip __i) {
+    {  __i++ } -> convertible_to<_Ip const&>;
+    { *__i++ } -> same_as<iter_reference_t<_Ip>>;
+  };
+
+template<class _Ip>
+concept __cpp17_bidirectional_iterator =
+  __cpp17_forward_iterator<_Ip> &&
+  requires(_Ip __i) {
+    {  --__i } -> same_as<_Ip&>;
+    {  __i-- } -> convertible_to<_Ip const&>;
+    { *__i-- } -> same_as<iter_reference_t<_Ip>>;
+  };
+
+template<class _Ip>
+concept __cpp17_random_access_iterator =
+  __cpp17_bidirectional_iterator<_Ip> and
+  totally_ordered<_Ip> and
+  requires(_Ip __i, typename incrementable_traits<_Ip>::difference_type __n) {
+    { __i += __n } -> same_as<_Ip&>;
+    { __i -= __n } -> same_as<_Ip&>;
+    { __i +  __n } -> same_as<_Ip>;
+    { __n +  __i } -> same_as<_Ip>;
+    { __i -  __n } -> same_as<_Ip>;
+    { __i -  __i } -> same_as<decltype(__n)>;
+    {  __i[__n]  } -> convertible_to<iter_reference_t<_Ip>>;
+  };
+} // namespace __iterator_traits_detail
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
 template <class _Iter, bool> struct __iterator_traits {};
 
 template <class _Iter>
diff --git a/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/iterator_traits_cpp17_iterators.h b/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/iterator_traits_cpp17_iterators.h
new file mode 100644
index 0000000..ffd33ae
--- /dev/null
+++ b/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/iterator_traits_cpp17_iterators.h
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TEST_LIBCXX_ITERATORS_ITERATOR_REQUIREMENTS_ITERATOR_ASSOC_TYPES_ITERATOR_TRAITS_ITERATOR_TRAITS_CPP17_ITERATORS
+#define TEST_LIBCXX_ITERATORS_ITERATOR_REQUIREMENTS_ITERATOR_ASSOC_TYPES_ITERATOR_TRAITS_ITERATOR_TRAITS_CPP17_ITERATORS
+
+struct iterator_traits_cpp17_iterator {
+  int& operator*();
+  iterator_traits_cpp17_iterator& operator++();
+  iterator_traits_cpp17_iterator operator++(int);
+};
+
+struct iterator_traits_cpp17_proxy_iterator {
+  int operator*();
+  iterator_traits_cpp17_proxy_iterator& operator++();
+
+  // this returns legcay_iterator, not iterator_traits_cpp17_proxy_iterator
+  iterator_traits_cpp17_iterator operator++(int);
+};
+
+struct iterator_traits_cpp17_input_iterator {
+  using difference_type = int;
+  using value_type = long;
+
+  int& operator*();
+  iterator_traits_cpp17_input_iterator& operator++();
+  iterator_traits_cpp17_input_iterator operator++(int);
+
+  bool operator==(iterator_traits_cpp17_input_iterator const&) const;
+};
+
+struct iterator_traits_cpp17_proxy_input_iterator {
+  using difference_type = int;
+  using value_type = long;
+
+  int operator*();
+  iterator_traits_cpp17_proxy_input_iterator& operator++();
+
+  // this returns legcay_input_iterator, not iterator_traits_cpp17_proxy_input_iterator
+  iterator_traits_cpp17_input_iterator operator++(int);
+
+  bool operator==(iterator_traits_cpp17_proxy_input_iterator const&) const;
+};
+
+struct iterator_traits_cpp17_forward_iterator {
+  using difference_type = int;
+  using value_type = int;
+
+  int& operator*();
+  iterator_traits_cpp17_forward_iterator& operator++();
+  iterator_traits_cpp17_forward_iterator operator++(int);
+
+  bool operator==(iterator_traits_cpp17_forward_iterator const&) const;
+};
+
+struct iterator_traits_cpp17_bidirectional_iterator {
+  using difference_type = int;
+  using value_type = int;
+
+  int& operator*();
+  iterator_traits_cpp17_bidirectional_iterator& operator++();
+  iterator_traits_cpp17_bidirectional_iterator operator++(int);
+  iterator_traits_cpp17_bidirectional_iterator& operator--();
+  iterator_traits_cpp17_bidirectional_iterator operator--(int);
+
+  bool operator==(iterator_traits_cpp17_bidirectional_iterator const&) const;
+};
+
+struct iterator_traits_cpp17_random_access_iterator {
+  using difference_type = int;
+  using value_type = int;
+
+  int& operator*();
+  int& operator[](difference_type);
+  iterator_traits_cpp17_random_access_iterator& operator++();
+  iterator_traits_cpp17_random_access_iterator operator++(int);
+  iterator_traits_cpp17_random_access_iterator& operator--();
+  iterator_traits_cpp17_random_access_iterator operator--(int);
+
+  bool operator==(iterator_traits_cpp17_random_access_iterator const&) const;
+  bool operator<(iterator_traits_cpp17_random_access_iterator const&) const;
+  bool operator>(iterator_traits_cpp17_random_access_iterator const&) const;
+  bool operator<=(iterator_traits_cpp17_random_access_iterator const&) const;
+  bool operator>=(iterator_traits_cpp17_random_access_iterator const&) const;
+
+  iterator_traits_cpp17_random_access_iterator& operator+=(difference_type);
+  iterator_traits_cpp17_random_access_iterator& operator-=(difference_type);
+
+  friend iterator_traits_cpp17_random_access_iterator operator+(iterator_traits_cpp17_random_access_iterator,
+                                                                difference_type);
+  friend iterator_traits_cpp17_random_access_iterator operator+(difference_type,
+                                                                iterator_traits_cpp17_random_access_iterator);
+  friend iterator_traits_cpp17_random_access_iterator operator-(iterator_traits_cpp17_random_access_iterator,
+                                                                difference_type);
+  friend difference_type operator-(iterator_traits_cpp17_random_access_iterator,
+                                   iterator_traits_cpp17_random_access_iterator);
+};
+
+#endif // TEST_LIBCXX_ITERATORS_ITERATOR_REQUIREMENTS_ITERATOR_ASSOC_TYPES_ITERATOR_TRAITS_ITERATOR_TRAITS_CPP17_ITERATORS
diff --git a/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_bidirectional_iterator.compile.pass.cpp b/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_bidirectional_iterator.compile.pass.cpp
new file mode 100644
index 0000000..19417c2
--- /dev/null
+++ b/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_bidirectional_iterator.compile.pass.cpp
@@ -0,0 +1,183 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// UNSUPPORTED: gcc-10
+
+// template<class I>
+// concept __iterator_traits_detail::__cpp17_bidirectional_iterator;
+
+#include <iterator>
+
+#include <array>
+#include <deque>
+#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY
+#include <filesystem>
+#endif
+#include <forward_list>
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "iterator_traits_cpp17_iterators.h"
+
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<iterator_traits_cpp17_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<iterator_traits_cpp17_proxy_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<iterator_traits_cpp17_input_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<iterator_traits_cpp17_proxy_input_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<iterator_traits_cpp17_forward_iterator>);
+static_assert(
+    std::__iterator_traits_detail::__cpp17_bidirectional_iterator<iterator_traits_cpp17_bidirectional_iterator>);
+static_assert(
+    std::__iterator_traits_detail::__cpp17_bidirectional_iterator<iterator_traits_cpp17_random_access_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int*>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int const*>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int volatile*>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int const volatile*>);
+
+// <array>
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::array<int, 10>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::array<int, 10>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::array<int, 10>::reverse_iterator>);
+static_assert(
+    std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::array<int, 10>::const_reverse_iterator>);
+
+// <deque>
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::deque<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::deque<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::deque<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::deque<int>::const_reverse_iterator>);
+
+// <filesystem>
+#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::filesystem::directory_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::filesystem::recursive_directory_iterator>);
+#endif
+
+// <forward_list>
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::forward_list<int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::forward_list<int>::const_iterator>);
+
+// <iterator>
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::back_insert_iterator<std::vector<int> > >);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::front_insert_iterator<std::vector<int> > >);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::insert_iterator<std::vector<int> > >);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::move_iterator<std::vector<int>::iterator> >);
+
+// <list>
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::list<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::list<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::list<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::list<int>::const_reverse_iterator>);
+
+// <map>
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::map<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::map<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::map<int, int>::reverse_iterator>);
+static_assert(
+    std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::map<int, int>::const_reverse_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::multimap<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::multimap<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::multimap<int, int>::reverse_iterator>);
+static_assert(
+    std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::multimap<int, int>::const_reverse_iterator>);
+
+// <set>
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::set<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::set<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::set<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::set<int>::const_reverse_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::multiset<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::multiset<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::multiset<int>::reverse_iterator>);
+static_assert(
+    std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::multiset<int>::const_reverse_iterator>);
+
+// <string>
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::string::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::string::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::string::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::string::const_reverse_iterator>);
+
+// <string_view>
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::string_view::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::string_view::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::string_view::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::string_view::const_reverse_iterator>);
+
+// <unordered_map>
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_map<int, int>::iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_map<int, int>::const_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_map<int, int>::local_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_map<int, int>::const_local_iterator>);
+
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_multimap<int, int>::iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_multimap<int, int>::const_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_multimap<int, int>::local_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<
+              std::unordered_multimap<int, int>::const_local_iterator>);
+
+// <unordered_set>
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_set<int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_set<int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_set<int>::local_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_set<int>::const_local_iterator>);
+
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_multiset<int>::iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_multiset<int>::const_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_multiset<int>::local_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::unordered_multiset<int>::const_local_iterator>);
+
+// <vector>
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::vector<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::vector<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::vector<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::vector<int>::const_reverse_iterator>);
+
+// Not iterators
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<void>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<void*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int* const>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::vector<int>::iterator volatile>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::vector<int>::iterator&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::vector<int>::iterator&&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int[]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int[10]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int (*)()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int (&)()>);
+
+struct S {};
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<S>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int S::*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_bidirectional_iterator<int (S::*)()>);
diff --git a/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_forward_iterator.compile.pass.cpp b/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_forward_iterator.compile.pass.cpp
new file mode 100644
index 0000000..3f628e7
--- /dev/null
+++ b/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_forward_iterator.compile.pass.cpp
@@ -0,0 +1,167 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// UNSUPPORTED: gcc-10
+
+// template<class I>
+// concept __iterator_traits_detail::__cpp17_forward_iterator;
+
+#include <iterator>
+
+#include <array>
+#include <deque>
+#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY
+#include <filesystem>
+#endif
+#include <forward_list>
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "iterator_traits_cpp17_iterators.h"
+
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<iterator_traits_cpp17_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<iterator_traits_cpp17_proxy_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<iterator_traits_cpp17_input_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<iterator_traits_cpp17_proxy_input_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<iterator_traits_cpp17_forward_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<iterator_traits_cpp17_bidirectional_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<iterator_traits_cpp17_random_access_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<int*>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<int const*>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<int volatile*>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<int const volatile*>);
+
+// <array>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::array<int, 10>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::array<int, 10>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::array<int, 10>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::array<int, 10>::const_reverse_iterator>);
+
+// <deque>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::deque<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::deque<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::deque<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::deque<int>::const_reverse_iterator>);
+
+// <filesystem>
+#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::filesystem::directory_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::filesystem::recursive_directory_iterator>);
+#endif
+
+// <forward_list>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::forward_list<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::forward_list<int>::const_iterator>);
+
+// <iterator>
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::back_insert_iterator<std::vector<int> > >);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::front_insert_iterator<std::vector<int> > >);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::insert_iterator<std::vector<int> > >);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_forward_iterator<std::move_iterator<std::vector<int>::iterator> >);
+
+// <list>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::list<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::list<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::list<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::list<int>::const_reverse_iterator>);
+
+// <map>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::map<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::map<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::map<int, int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::map<int, int>::const_reverse_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::multimap<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::multimap<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::multimap<int, int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::multimap<int, int>::const_reverse_iterator>);
+
+// <set>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::set<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::set<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::set<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::set<int>::const_reverse_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::multiset<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::multiset<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::multiset<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::multiset<int>::const_reverse_iterator>);
+
+// <string>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::string::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::string::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::string::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::string::const_reverse_iterator>);
+
+// <string_view>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::string_view::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::string_view::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::string_view::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::string_view::const_reverse_iterator>);
+
+// <unordered_map>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_map<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_map<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_map<int, int>::local_iterator>);
+static_assert(
+    std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_map<int, int>::const_local_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_multimap<int, int>::iterator>);
+static_assert(
+    std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_multimap<int, int>::const_iterator>);
+static_assert(
+    std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_multimap<int, int>::local_iterator>);
+static_assert(
+    std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_multimap<int, int>::const_local_iterator>);
+
+// <unordered_set>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_set<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_set<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_set<int>::local_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_set<int>::const_local_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_multiset<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_multiset<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_multiset<int>::local_iterator>);
+static_assert(
+    std::__iterator_traits_detail::__cpp17_forward_iterator<std::unordered_multiset<int>::const_local_iterator>);
+
+// <vector>
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::vector<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::vector<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::vector<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::vector<int>::const_reverse_iterator>);
+
+// Not iterators
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<void>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<void*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<int* const>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::vector<int>::iterator volatile>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::vector<int>::iterator&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::vector<int>::iterator&&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<int>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<int[]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<int[10]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<int()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<int (*)()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<int (&)()>);
+
+struct S {};
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<S>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<int S::*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<int (S::*)()>);
diff --git a/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_input_iterator.compile.pass.cpp b/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_input_iterator.compile.pass.cpp
new file mode 100644
index 0000000..99994da
--- /dev/null
+++ b/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_input_iterator.compile.pass.cpp
@@ -0,0 +1,164 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// UNSUPPORTED: gcc-10
+
+// template<class I>
+// concept __iterator_traits_detail::__cpp17_input_iterator;
+
+#include <iterator>
+
+#include <array>
+#include <deque>
+#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY
+#include <filesystem>
+#endif
+#include <forward_list>
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "iterator_traits_cpp17_iterators.h"
+
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<iterator_traits_cpp17_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<iterator_traits_cpp17_proxy_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<iterator_traits_cpp17_input_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<iterator_traits_cpp17_proxy_input_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<iterator_traits_cpp17_forward_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<iterator_traits_cpp17_bidirectional_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<iterator_traits_cpp17_random_access_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<int*>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<int const*>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<int volatile*>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<int const volatile*>);
+
+// <array>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::array<int, 10>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::array<int, 10>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::array<int, 10>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::array<int, 10>::const_reverse_iterator>);
+
+// <deque>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::deque<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::deque<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::deque<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::deque<int>::const_reverse_iterator>);
+
+// <filesystem>
+#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::filesystem::directory_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::filesystem::recursive_directory_iterator>);
+#endif
+
+// <forward_list>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::forward_list<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::forward_list<int>::const_iterator>);
+
+// <iterator>
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<std::back_insert_iterator<std::vector<int> > >);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<std::front_insert_iterator<std::vector<int> > >);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<std::insert_iterator<std::vector<int> > >);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::move_iterator<std::vector<int>::iterator> >);
+
+// <list>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::list<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::list<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::list<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::list<int>::const_reverse_iterator>);
+
+// <map>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::map<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::map<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::map<int, int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::map<int, int>::const_reverse_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::multimap<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::multimap<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::multimap<int, int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::multimap<int, int>::const_reverse_iterator>);
+
+// <set>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::set<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::set<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::set<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::set<int>::const_reverse_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::multiset<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::multiset<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::multiset<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::multiset<int>::const_reverse_iterator>);
+
+// <string>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::string::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::string::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::string::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::string::const_reverse_iterator>);
+
+// <string_view>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::string_view::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::string_view::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::string_view::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::string_view::const_reverse_iterator>);
+
+// <unordered_map>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_map<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_map<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_map<int, int>::local_iterator>);
+static_assert(
+    std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_map<int, int>::const_local_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_multimap<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_multimap<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_multimap<int, int>::local_iterator>);
+static_assert(
+    std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_multimap<int, int>::const_local_iterator>);
+
+// <unordered_set>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_set<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_set<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_set<int>::local_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_set<int>::const_local_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_multiset<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_multiset<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_multiset<int>::local_iterator>);
+static_assert(
+    std::__iterator_traits_detail::__cpp17_input_iterator<std::unordered_multiset<int>::const_local_iterator>);
+
+// <vector>
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::vector<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::vector<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::vector<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::vector<int>::const_reverse_iterator>);
+
+// Not iterators
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<void>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<void*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<int* const>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<std::vector<int>::iterator volatile>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<std::vector<int>::iterator&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<std::vector<int>::iterator&&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<int>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<int[]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<int[10]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<int()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<int (*)()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<int (&)()>);
+
+struct S {};
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<S>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<int S::*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<int (S::*)()>);
diff --git a/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_iterator.compile.pass.cpp b/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_iterator.compile.pass.cpp
new file mode 100644
index 0000000..040c705
--- /dev/null
+++ b/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_iterator.compile.pass.cpp
@@ -0,0 +1,161 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// UNSUPPORTED: gcc-10
+
+// template<class I>
+// concept __iterator_traits_detail::__cpp17_iterator;
+
+#include <iterator>
+
+#include <array>
+#include <deque>
+#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY
+#include <filesystem>
+#endif
+#include <forward_list>
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "iterator_traits_cpp17_iterators.h"
+
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<iterator_traits_cpp17_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<iterator_traits_cpp17_proxy_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<iterator_traits_cpp17_input_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<iterator_traits_cpp17_proxy_input_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<iterator_traits_cpp17_forward_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<iterator_traits_cpp17_bidirectional_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<iterator_traits_cpp17_random_access_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<int*>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<int const*>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<int volatile*>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<int const volatile*>);
+
+// <array>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::array<int, 10>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::array<int, 10>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::array<int, 10>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::array<int, 10>::const_reverse_iterator>);
+
+// <deque>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::deque<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::deque<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::deque<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::deque<int>::const_reverse_iterator>);
+
+// <filesystem>
+#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::filesystem::directory_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::filesystem::recursive_directory_iterator>);
+#endif
+
+// <forward_list>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::forward_list<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::forward_list<int>::const_iterator>);
+
+// <iterator>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::back_insert_iterator<std::vector<int> > >);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::front_insert_iterator<std::vector<int> > >);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::insert_iterator<std::vector<int> > >);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::move_iterator<std::vector<int>::iterator> >);
+
+// <list>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::list<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::list<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::list<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::list<int>::const_reverse_iterator>);
+
+// <map>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::map<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::map<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::map<int, int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::map<int, int>::const_reverse_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::multimap<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::multimap<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::multimap<int, int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::multimap<int, int>::const_reverse_iterator>);
+
+// <set>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::set<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::set<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::set<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::set<int>::const_reverse_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::multiset<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::multiset<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::multiset<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::multiset<int>::const_reverse_iterator>);
+
+// <string>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::string::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::string::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::string::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::string::const_reverse_iterator>);
+
+// <string_view>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::string_view::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::string_view::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::string_view::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::string_view::const_reverse_iterator>);
+
+// <unordered_map>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_map<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_map<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_map<int, int>::local_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_map<int, int>::const_local_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_multimap<int, int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_multimap<int, int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_multimap<int, int>::local_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_multimap<int, int>::const_local_iterator>);
+
+// <unordered_set>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_set<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_set<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_set<int>::local_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_set<int>::const_local_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_multiset<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_multiset<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_multiset<int>::local_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::unordered_multiset<int>::const_local_iterator>);
+
+// <vector>
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::vector<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::vector<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::vector<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::vector<int>::const_reverse_iterator>);
+
+// Not iterators
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<void>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<void*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<int* const>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<std::vector<int>::iterator volatile>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<std::vector<int>::iterator&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<std::vector<int>::iterator&&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<int>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<int[]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<int[10]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<int()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<int (*)()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<int (&)()>);
+
+struct S {};
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<S>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<int S::*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_iterator<int (S::*)()>);
diff --git a/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_random_access_iterator.compile.pass.cpp b/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_random_access_iterator.compile.pass.cpp
new file mode 100644
index 0000000..d024f43
--- /dev/null
+++ b/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/legacy_random_access_iterator.compile.pass.cpp
@@ -0,0 +1,184 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// UNSUPPORTED: gcc-10
+
+// template<class I>
+// concept __iterator_traits_detail::__cpp17_random_access_iterator;
+
+#include <iterator>
+
+#include <array>
+#include <deque>
+#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY
+#include <filesystem>
+#endif
+#include <forward_list>
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "iterator_traits_cpp17_iterators.h"
+
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<iterator_traits_cpp17_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<iterator_traits_cpp17_proxy_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<iterator_traits_cpp17_input_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<iterator_traits_cpp17_proxy_input_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<iterator_traits_cpp17_forward_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<iterator_traits_cpp17_bidirectional_iterator>);
+static_assert(
+    std::__iterator_traits_detail::__cpp17_random_access_iterator<iterator_traits_cpp17_random_access_iterator>);
+
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<int*>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<int const*>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<int volatile*>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<int const volatile*>);
+
+// <array>
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::array<int, 10>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::array<int, 10>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::array<int, 10>::reverse_iterator>);
+static_assert(
+    std::__iterator_traits_detail::__cpp17_random_access_iterator<std::array<int, 10>::const_reverse_iterator>);
+
+// <deque>
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::deque<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::deque<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::deque<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::deque<int>::const_reverse_iterator>);
+
+// <filesystem>
+#ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::filesystem::directory_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::filesystem::recursive_directory_iterator>);
+#endif
+
+// <forward_list>
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::forward_list<int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::forward_list<int>::const_iterator>);
+
+// <iterator>
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::back_insert_iterator<std::vector<int> > >);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::front_insert_iterator<std::vector<int> > >);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::insert_iterator<std::vector<int> > >);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::move_iterator<std::vector<int>::iterator> >);
+
+// <list>
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::list<int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::list<int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::list<int>::reverse_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::list<int>::const_reverse_iterator>);
+
+// <map>
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::map<int, int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::map<int, int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::map<int, int>::reverse_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::map<int, int>::const_reverse_iterator>);
+
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::multimap<int, int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::multimap<int, int>::const_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::multimap<int, int>::reverse_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::multimap<int, int>::const_reverse_iterator>);
+
+// <set>
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::set<int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::set<int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::set<int>::reverse_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::set<int>::const_reverse_iterator>);
+
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::multiset<int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::multiset<int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::multiset<int>::reverse_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::multiset<int>::const_reverse_iterator>);
+
+// <string>
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::string::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::string::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::string::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::string::const_reverse_iterator>);
+
+// <string_view>
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::string_view::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::string_view::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::string_view::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::string_view::const_reverse_iterator>);
+
+// <unordered_map>
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_map<int, int>::iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_map<int, int>::const_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_map<int, int>::local_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_map<int, int>::const_local_iterator>);
+
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_multimap<int, int>::iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_multimap<int, int>::const_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_multimap<int, int>::local_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<
+              std::unordered_multimap<int, int>::const_local_iterator>);
+
+// <unordered_set>
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_set<int>::iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_set<int>::const_iterator>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_set<int>::local_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_set<int>::const_local_iterator>);
+
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_multiset<int>::iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_multiset<int>::const_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_multiset<int>::local_iterator>);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::unordered_multiset<int>::const_local_iterator>);
+
+// <vector>
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::vector<int>::iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::vector<int>::const_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::vector<int>::reverse_iterator>);
+static_assert(std::__iterator_traits_detail::__cpp17_random_access_iterator<std::vector<int>::const_reverse_iterator>);
+
+// Not iterators
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<void>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<void*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<int* const>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::vector<int>::iterator volatile>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::vector<int>::iterator&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<std::vector<int>::iterator&&>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<int>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<int[]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<int[10]>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<int()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<int (*)()>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<int (&)()>);
+
+struct S {};
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<S>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<int S::*>);
+static_assert(!std::__iterator_traits_detail::__cpp17_random_access_iterator<int (S::*)()>);
diff --git a/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/locale_dependent.compile.pass.cpp b/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/locale_dependent.compile.pass.cpp
new file mode 100644
index 0000000..4239e2c
--- /dev/null
+++ b/test/libcxx/iterators/iterator.requirements/iterator.assoc.types/iterator.traits/locale_dependent.compile.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// UNSUPPORTED: gcc-10
+
+// REQUIRES: locale.en_US.UTF-8
+
+#include <iterator>
+
+#include <istream>
+#include <ostream>
+
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::istream_iterator<int, std::istream> >);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::istreambuf_iterator<int, std::istream> >);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::ostream_iterator<int, std::ostream> >);
+static_assert(std::__iterator_traits_detail::__cpp17_iterator<std::ostreambuf_iterator<int, std::ostream> >);
+
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::istream_iterator<int, std::istream> >);
+static_assert(std::__iterator_traits_detail::__cpp17_input_iterator<std::istreambuf_iterator<int, std::istream> >);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<std::ostream_iterator<int, std::ostream> >);
+static_assert(!std::__iterator_traits_detail::__cpp17_input_iterator<std::ostreambuf_iterator<int, std::ostream> >);
+
+// This is because the legacy iterator concepts don't care about iterator_category
+static_assert(std::__iterator_traits_detail::__cpp17_forward_iterator<std::istream_iterator<int, std::istream> >);
+
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::istreambuf_iterator<int, std::istream> >);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::ostream_iterator<int, std::ostream> >);
+static_assert(!std::__iterator_traits_detail::__cpp17_forward_iterator<std::ostreambuf_iterator<int, std::ostream> >);
+
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::istream_iterator<int, std::istream> >);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::istreambuf_iterator<int, std::istream> >);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::ostream_iterator<int, std::ostream> >);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_bidirectional_iterator<std::ostreambuf_iterator<int, std::ostream> >);
+
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::istream_iterator<int, std::istream> >);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::istreambuf_iterator<int, std::istream> >);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::ostream_iterator<int, std::ostream> >);
+static_assert(
+    !std::__iterator_traits_detail::__cpp17_random_access_iterator<std::ostreambuf_iterator<int, std::ostream> >);
diff --git a/test/std/iterators/iterator.primitives/iterator.traits/iter_reference_t.compile.pass.cpp b/test/std/iterators/iterator.primitives/iterator.traits/iter_reference_t.compile.pass.cpp
new file mode 100644
index 0000000..2c45e9a
--- /dev/null
+++ b/test/std/iterators/iterator.primitives/iterator.traits/iter_reference_t.compile.pass.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// template<class T>
+// using iter_reference_t = decltype(*declval<T&>());
+
+#include <iterator>
+
+#include <concepts>
+
+#include "test_iterators.h"
+
+static_assert(std::same_as<std::iter_reference_t<input_iterator<int*> >, int&>);
+static_assert(std::same_as<std::iter_reference_t<forward_iterator<int*> >, int&>);
+static_assert(std::same_as<std::iter_reference_t<bidirectional_iterator<int*> >, int&>);
+static_assert(std::same_as<std::iter_reference_t<random_access_iterator<int*> >, int&>);