[libcxx-commits] [libcxx] [libc++] P3016R6: Resolve inconsistencies in begin/end for `valarray` and braced initializer lists (PR #173637)

A. Jiang via libcxx-commits libcxx-commits at lists.llvm.org
Fri Dec 26 03:34:42 PST 2025


https://github.com/frederick-vs-ja updated https://github.com/llvm/llvm-project/pull/173637

>From 350a3cedb8330184c547e52494cca95d03c1955d Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Fri, 26 Dec 2025 18:14:37 +0800
Subject: [PATCH] [libc++] P3016R6: Resolve inconsistencies in begin/end for
 `valarray` and braced initializer lists

This paper is implemented as a Defect Report against C++11 and later
revisions.
- Inclusion of `<typeinfo>` in `<functional>` should be considered as a
patch to C++ TR1 [N1836](https://wg21.link/N1836), while the related
parts were merged into C++11.
- Changes of `initializer_list` should be considered as a patch to C++11
paper [N2672](https://wg21.link/n2672).
- Changes of `valarray`, `std::begin`, and `std::end` and availability
of range access functions in `<valarray>` should be considered as a
patch to C++11 paper [N2930](https://wg21.link/n2930).
- Inclusion of `<typeinfo>` in `<typeindex>` should be considered as a
patch to C++11 paper [N2932](https://wg21.link/n2932).
- Changes of `std::cbegin`, `std::cend`, `std::rbegin`, `std::rend`,
`std::crbegin`, and `std::crend` and the inclusion of
`<initializer_list>` in `<iterator>` should be considered as a patch to
[LWG2128](https://wg21.link/lwg2128), while LWG2128 is consistently
considered to be a pure feature addition in C++14 by implementations.
- Changes of `std::data`, `std::empty`, and `std::size` should be
considered as a patch to C++17 paper [N4280](https://wg21.link/n4280).
- Inclusion of `<initializer_list>` and `<typeinfo>` in `<any>` should
be considered as a patch to C++17 paper
[P0220R1](https://wg21.link/p0220r1).
- Changes of `std::ssize` should be considered as a patch to C++20 paper
[P1227R2](https://wg21.link/p1227r2).
- Inclusion of `<initializer_list>` in `<functional>` should be
considered as a patch to C++23 paper
[P0288R9](https://wg21.link/p0288r9).
- Availability of range access functions in `<stacktrace>` should be
considered as a patch to C++23 paper
[P0881R7](https://wg21.link/p0881r7).
- Availability of range access functions in `<optional>` should be
considered as a patch to C++26 paper
[P3168R2](https://wg21.link/p3168r2).

Notes for backported and missing parts:
- Changes of `<stacktrace>` are not implemented because P0881R7 is not
implemented. But I think P3016R6 should be considered complete with note
added.
- `constexpr` for member functions of `initializer_list` is only added
since C++14, in the spirit of C++14 paper
[N3471](https://wg21.link/n3471).
- Changes of inclusions and `valarray` are unconditionally implemented,
which follows the current convention of libc++.

Drive-by changes:
- Conditionally strengthen the constructor of `reverse_iterator` from
the underlying iterator, because many (un)conditionally `noexcept`
functions call that constructor now.
---
 libcxx/docs/FeatureTestMacroTable.rst         |   4 +
 libcxx/docs/ReleaseNotes/22.rst               |   2 +
 libcxx/docs/Status/Cxx2cPapers.csv            |   2 +-
 libcxx/include/__iterator/access.h            |  24 ++-
 libcxx/include/__iterator/reverse_access.h    |  46 +++--
 libcxx/include/__iterator/reverse_iterator.h  |   8 +-
 libcxx/include/any                            |   4 +
 libcxx/include/functional                     |   5 +
 libcxx/include/initializer_list               |  23 +--
 libcxx/include/iterator                       |  59 +++---
 libcxx/include/optional                       |   7 +
 libcxx/include/typeindex                      |   1 +
 libcxx/include/valarray                       |  47 ++---
 libcxx/include/version                        |   4 +
 .../language.support/nodiscard.verify.cpp     |   2 +
 .../numerics/numarray/nodiscard.verify.cpp    |  10 +-
 .../iterator.container/data.pass.cpp          |   9 +-
 .../iterator.container/empty.pass.cpp         |   9 +-
 .../iterator.container/size.pass.cpp          |  16 +-
 .../iterator.container/ssize.pass.cpp         |  28 +--
 .../iterator.range/begin-end.array.pass.cpp   |  10 +-
 .../begin-end.container.pass.cpp              | 179 ++++++++++++++++--
 .../begin-end.initializer_list.pass.cpp       |  10 +-
 .../mandatory_inclusions.gen.py               |   7 +-
 .../reverse.iter.cons/ctor.iter.pass.cpp      |  12 +-
 .../support.initlist.access/access.pass.cpp   |  89 ++++++---
 .../support.initlist.range/begin_end.pass.cpp |  68 -------
 .../initializer_list.version.compile.pass.cpp |  74 ++++++++
 .../valarray.version.compile.pass.cpp         |  74 ++++++++
 .../version.version.compile.pass.cpp          |  78 ++++++++
 .../template.valarray/types.compile.pass.cpp  |  49 +++++
 .../numarray/template.valarray/types.pass.cpp |  29 ---
 .../valarray.members/begin-end.pass.cpp       |  82 ++++++++
 .../valarray.range/begin-end.pass.cpp         |  69 -------
 .../generate_feature_test_macro_components.py |  10 +
 libcxx/utils/libcxx/header_information.py     |   6 +-
 36 files changed, 808 insertions(+), 348 deletions(-)
 delete mode 100644 libcxx/test/std/language.support/support.initlist/support.initlist.range/begin_end.pass.cpp
 create mode 100644 libcxx/test/std/language.support/support.limits/support.limits.general/initializer_list.version.compile.pass.cpp
 create mode 100644 libcxx/test/std/language.support/support.limits/support.limits.general/valarray.version.compile.pass.cpp
 create mode 100644 libcxx/test/std/numerics/numarray/template.valarray/types.compile.pass.cpp
 delete mode 100644 libcxx/test/std/numerics/numarray/template.valarray/types.pass.cpp
 create mode 100644 libcxx/test/std/numerics/numarray/template.valarray/valarray.members/begin-end.pass.cpp
 delete mode 100644 libcxx/test/std/numerics/numarray/valarray.range/begin-end.pass.cpp

diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 32911d0f64449..dca2c7747ccae 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -34,6 +34,8 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_generic_associative_lookup``                   ``201304L``
     ---------------------------------------------------------- -----------------
+    ``__cpp_lib_initializer_list``                             ``202511L``
+    ---------------------------------------------------------- -----------------
     ``__cpp_lib_integer_sequence``                             ``201304L``
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_integral_constant_callable``                   ``201304L``
@@ -66,6 +68,8 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_tuples_by_type``                               ``201304L``
     ---------------------------------------------------------- -----------------
+    ``__cpp_lib_valarray``                                     ``202511L``
+    ---------------------------------------------------------- -----------------
     **C++17**
     ----------------------------------------------------------------------------
     ``__cpp_lib_addressof_constexpr``                          ``201603L``
diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst
index 0d1a1fbc00f2c..abf81e3fff94a 100644
--- a/libcxx/docs/ReleaseNotes/22.rst
+++ b/libcxx/docs/ReleaseNotes/22.rst
@@ -50,6 +50,8 @@ Implemented Papers
   (`Github <https://llvm.org/PR105381>`__)
 - P2835R7: Expose ``std::atomic_ref``'s object address (`Github <https://llvm.org/PR118377>`__)
 - P2944R3: Comparisons for ``reference_wrapper`` (`Github <https://llvm.org/PR105424>`__)
+- P3016R6: Resolve inconsistencies in begin/end for ``valarray`` and braced initializer lists
+  (`Github <https://llvm.org/PR171271>`__)
 - P3168R2: Give ``std::optional`` Range Support (`Github <https://llvm.org/PR105430>`__)
 - P3567R2: ``flat_meow`` Fixes (`Github <https://llvm.org/PR162022>`__)
 - P3836R2: Make ``optional<T&>`` trivially copyable (`Github <https://llvm.org/PR171275>`__)
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index 9bb5d2bda3d4d..dce772eae7b53 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -158,7 +158,7 @@
 "`P1317R2 <https://wg21.link/P1317R2>`__","Remove return type deduction in ``std::apply``","2025-06 (Sofia)","","","`#148183 <https://github.com/llvm/llvm-project/issues/148183>`__",""
 "","","","","","",""
 "`P3920R0 <https://wg21.link/P3920R0>`__","Wording for NB comment resolution on trivial relocation","2025-11 (Kona)","|Nothing To Do|","","`#171269 <https://github.com/llvm/llvm-project/issues/171269>`__",""
-"`P3016R6 <https://wg21.link/P3016R6>`__","Resolve inconsistencies in begin/end for ``valarray`` and braced initializer lists","2025-11 (Kona)","","","`#171271 <https://github.com/llvm/llvm-project/issues/171271>`__",""
+"`P3016R6 <https://wg21.link/P3016R6>`__","Resolve inconsistencies in begin/end for ``valarray`` and braced initializer lists","2025-11 (Kona)","|Complete|","22","`#171271 <https://github.com/llvm/llvm-project/issues/171271>`__","Implemented as a DR against C++11. Change of ``<stacktrace>`` is blocked on `P0881R7 <https://wg21.link/P0881R7>`__."
 "`P3567R2 <https://wg21.link/P3567R2>`__","``flat_meow`` Fixes","2025-11 (Kona)","|Complete|","22","`#171272 <https://github.com/llvm/llvm-project/issues/171272>`__",""
 "`P3663R3 <https://wg21.link/P3663R3>`__","Future-proof ``submdspan_mapping``","2025-11 (Kona)","","","`#166089 <https://github.com/llvm/llvm-project/issues/166089>`__",""
 "`P3914R0 <https://wg21.link/P3914R0>`__","Assorted NB comment resolutions for Kona 2025","2025-11 (Kona)","","","`#171274 <https://github.com/llvm/llvm-project/issues/171274>`__",""
diff --git a/libcxx/include/__iterator/access.h b/libcxx/include/__iterator/access.h
index d42855f925487..209f249f79d2d 100644
--- a/libcxx/include/__iterator/access.h
+++ b/libcxx/include/__iterator/access.h
@@ -32,23 +32,31 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* end(_Tp (&__array)[_Np]) _NOEXCEPT
 #if !defined(_LIBCPP_CXX03_LANG)
 
 template <class _Cp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto begin(_Cp& __c) -> decltype(__c.begin()) {
-  return __c.begin();
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto begin(_Cp& __c) //
+    noexcept(noexcept(__c.begin()))                                      //
+    -> decltype(/*-*/ __c.begin()) {
+  return /*--------*/ __c.begin();
 }
 
 template <class _Cp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto begin(const _Cp& __c) -> decltype(__c.begin()) {
-  return __c.begin();
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto begin(const _Cp& __c) //
+    noexcept(noexcept(__c.begin()))                                            //
+    -> decltype(/*-*/ __c.begin()) {
+  return /*--------*/ __c.begin();
 }
 
 template <class _Cp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto end(_Cp& __c) -> decltype(__c.end()) {
-  return __c.end();
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto end(_Cp& __c) //
+    noexcept(noexcept(__c.end()))                                      //
+    -> decltype(/*-*/ __c.end()) {
+  return /*--------*/ __c.end();
 }
 
 template <class _Cp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto end(const _Cp& __c) -> decltype(__c.end()) {
-  return __c.end();
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto end(const _Cp& __c) //
+    noexcept(noexcept(__c.end()))                                            //
+    -> decltype(/*-*/ __c.end()) {
+  return /*--------*/ __c.end();
 }
 
 #  if _LIBCPP_STD_VER >= 14
diff --git a/libcxx/include/__iterator/reverse_access.h b/libcxx/include/__iterator/reverse_access.h
index f6e60c3fb75b3..ae1ebe98e1a36 100644
--- a/libcxx/include/__iterator/reverse_access.h
+++ b/libcxx/include/__iterator/reverse_access.h
@@ -23,53 +23,67 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if _LIBCPP_STD_VER >= 14
 
 template <class _Tp, size_t _Np>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np]) {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np]) noexcept {
   return reverse_iterator<_Tp*>(__array + _Np);
 }
 
 template <class _Tp, size_t _Np>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np]) {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np]) noexcept {
   return reverse_iterator<_Tp*>(__array);
 }
 
 template <class _Ep>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<const _Ep*> rbegin(initializer_list<_Ep> __il) {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<const _Ep*>
+rbegin(initializer_list<_Ep> __il) noexcept {
   return reverse_iterator<const _Ep*>(__il.end());
 }
 
 template <class _Ep>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<const _Ep*> rend(initializer_list<_Ep> __il) {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<const _Ep*>
+rend(initializer_list<_Ep> __il) noexcept {
   return reverse_iterator<const _Ep*>(__il.begin());
 }
 
 template <class _Cp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rbegin(_Cp& __c) -> decltype(__c.rbegin()) {
-  return __c.rbegin();
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rbegin(_Cp& __c) //
+    noexcept(noexcept(__c.rbegin()))                                      //
+    -> decltype(/*-*/ __c.rbegin()) {
+  return /*--------*/ __c.rbegin();
 }
 
 template <class _Cp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rbegin(const _Cp& __c) -> decltype(__c.rbegin()) {
-  return __c.rbegin();
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rbegin(const _Cp& __c) //
+    noexcept(noexcept(__c.rbegin()))                                            //
+    -> decltype(/*-*/ __c.rbegin()) {
+  return /*--------*/ __c.rbegin();
 }
 
 template <class _Cp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rend(_Cp& __c) -> decltype(__c.rend()) {
-  return __c.rend();
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rend(_Cp& __c) //
+    noexcept(noexcept(__c.rend()))                                      //
+    -> decltype(/*-*/ __c.rend()) {
+  return /*--------*/ __c.rend();
 }
 
 template <class _Cp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rend(const _Cp& __c) -> decltype(__c.rend()) {
-  return __c.rend();
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rend(const _Cp& __c) //
+    noexcept(noexcept(__c.rend()))                                            //
+    -> decltype(/*-*/ __c.rend()) {
+  return /*--------*/ __c.rend();
 }
 
 template <class _Cp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto crbegin(const _Cp& __c) -> decltype(std::rbegin(__c)) {
-  return std::rbegin(__c);
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto crbegin(const _Cp& __c) //
+    noexcept(noexcept(std::rbegin(__c)))                                         //
+    -> decltype(/*-*/ std::rbegin(__c)) {
+  return /*--------*/ std::rbegin(__c);
 }
 
 template <class _Cp>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto crend(const _Cp& __c) -> decltype(std::rend(__c)) {
-  return std::rend(__c);
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto crend(const _Cp& __c) //
+    noexcept(noexcept(std::rend(__c)))                                         //
+    -> decltype(/*-*/ std::rend(__c)) {
+  return /*--------*/ std::rend(__c);
 }
 
 #endif // _LIBCPP_STD_VER >= 14
diff --git a/libcxx/include/__iterator/reverse_iterator.h b/libcxx/include/__iterator/reverse_iterator.h
index 834695dd16703..dd6455b91f6d3 100644
--- a/libcxx/include/__iterator/reverse_iterator.h
+++ b/libcxx/include/__iterator/reverse_iterator.h
@@ -89,7 +89,9 @@ class reverse_iterator
 #ifndef _LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator() : __t_(), current() {}
 
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 explicit reverse_iterator(_Iter __x) : __t_(__x), current(__x) {}
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 explicit reverse_iterator(_Iter __x)
+      _NOEXCEPT_(is_nothrow_constructible<_Iter, _Iter&>::value)
+      : __t_(__x), current(__x) {}
 
   template <class _Up, __enable_if_t<!is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value, int> = 0>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator(const reverse_iterator<_Up>& __u)
@@ -106,7 +108,9 @@ class reverse_iterator
 #else
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator() : current() {}
 
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 explicit reverse_iterator(_Iter __x) : current(__x) {}
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 explicit reverse_iterator(_Iter __x)
+      _NOEXCEPT_(is_nothrow_constructible<_Iter, _Iter&>::value)
+      : current(__x) {}
 
   template <class _Up, __enable_if_t<!is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value, int> = 0>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator(const reverse_iterator<_Up>& __u)
diff --git a/libcxx/include/any b/libcxx/include/any
index 5c779e397c9ea..a77880a28cd26 100644
--- a/libcxx/include/any
+++ b/libcxx/include/any
@@ -110,6 +110,10 @@ namespace std {
 #  include <typeinfo>
 #  include <version>
 
+// standard-mandated includes
+#  include <initializer_list>
+#  include <typeinfo>
+
 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #    pragma GCC system_header
 #  endif
diff --git a/libcxx/include/functional b/libcxx/include/functional
index 9ebcd818ec840..fbc660f180349 100644
--- a/libcxx/include/functional
+++ b/libcxx/include/functional
@@ -604,6 +604,11 @@ POLICY:  For non-variadic implementations, the number of arguments is limited
 #  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER == 23
 #    include <__vector/vector.h>
 #  endif
+
+// standard-mandated includes
+#  include <initializer_list>
+#  include <typeinfo>
+
 #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
 
 #endif // _LIBCPP_FUNCTIONAL
diff --git a/libcxx/include/initializer_list b/libcxx/include/initializer_list
index 44cd45668388b..f8c0abcfbd3f3 100644
--- a/libcxx/include/initializer_list
+++ b/libcxx/include/initializer_list
@@ -30,14 +30,13 @@ public:
 
     initializer_list() noexcept; // constexpr in C++14
 
+    const E* data()  const noexcept; // constexpr in C++14
     size_t   size()  const noexcept; // constexpr in C++14
+    bool     empty() const noexcept; // constexpr in C++14
     const E* begin() const noexcept; // constexpr in C++14
     const E* end()   const noexcept; // constexpr in C++14
 };
 
-template<class E> const E* begin(initializer_list<E> il) noexcept; // constexpr in C++14
-template<class E> const E* end(initializer_list<E> il) noexcept; // constexpr in C++14
-
 }  // std
 
 */
@@ -78,10 +77,18 @@ public:
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 initializer_list() _NOEXCEPT : __begin_(nullptr), __size_(0) {}
 
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* data() const noexcept {
+    return __begin_;
+  }
+
   [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t size() const _NOEXCEPT {
     return __size_;
   }
 
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool empty() const noexcept {
+    return __size_ == 0;
+  }
+
   [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* begin() const _NOEXCEPT {
     return __begin_;
   }
@@ -91,16 +98,6 @@ public:
   }
 };
 
-template <class _Ep>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* begin(initializer_list<_Ep> __il) _NOEXCEPT {
-  return __il.begin();
-}
-
-template <class _Ep>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Ep* end(initializer_list<_Ep> __il) _NOEXCEPT {
-  return __il.end();
-}
-
 #  endif // !defined(_LIBCPP_CXX03_LANG)
 
 } // namespace std
diff --git a/libcxx/include/iterator b/libcxx/include/iterator
index fc8bdc5e6bcf6..4355c529cca22 100644
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -13,7 +13,9 @@
 /*
     iterator synopsis
 
+#include <compare>
 #include <concepts>
+#include <initializer_list>
 
 namespace std
 {
@@ -639,41 +641,49 @@ public:
     bool failed() const noexcept;
 };
 
-template <class C> constexpr auto begin(C& c) -> decltype(c.begin());                   // constexpr since C++17
-template <class C> constexpr auto begin(const C& c) -> decltype(c.begin());             // constexpr since C++17
-template <class C> constexpr auto end(C& c) -> decltype(c.end());                       // constexpr since C++17
-template <class C> constexpr auto end(const C& c) -> decltype(c.end());                 // constexpr since C++17
+template <class C> constexpr auto begin(C& c) noexcept(see-below) -> decltype(c.begin());       // constexpr since C++17
+template <class C> constexpr auto begin(const C& c) noexcept(see-below) -> decltype(c.begin()); // constexpr since C++17
+template <class C> constexpr auto end(C& c) noexcept(see-below) -> decltype(c.end());           // constexpr since C++17
+template <class C> constexpr auto end(const C& c) noexcept(see-below) -> decltype(c.end());     // constexpr since C++17
 template <class T, size_t N> constexpr T* begin(T (&array)[N]) noexcept;
 template <class T, size_t N> constexpr T* end(T (&array)[N]) noexcept;
 
 template <class C> constexpr auto cbegin(const C& c) noexcept(see-below) -> decltype(std::begin(c)); // C++14
 template <class C> constexpr auto cend(const C& c) noexcept(see-below) -> decltype(std::end(c));     // C++14
-template <class C> constexpr auto rbegin(C& c) -> decltype(c.rbegin());                 // C++14, constexpr since C++17
-template <class C> constexpr auto rbegin(const C& c) -> decltype(c.rbegin());           // C++14, constexpr since C++17
-template <class C> constexpr auto rend(C& c) -> decltype(c.rend());                     // C++14, constexpr since C++17
-template <class C> constexpr auto rend(const C& c) -> decltype(c.rend());               // C++14, constexpr since C++17
-template <class E> constexpr reverse_iterator<const E*> rbegin(initializer_list<E> il); // C++14, constexpr since C++17
-template <class E> constexpr reverse_iterator<const E*> rend(initializer_list<E> il);   // C++14, constexpr since C++17
-template <class T, size_t N> constexpr reverse_iterator<T*> rbegin(T (&array)[N]);      // C++14, constexpr since C++17
-template <class T, size_t N> constexpr reverse_iterator<T*> rend(T (&array)[N]);        // C++14, constexpr since C++17
-template <class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));      // C++14, constexpr since C++17
-template <class C> constexpr auto crend(const C& c) -> decltype(std::rend(c));          // C++14, constexpr since C++17
+template <class C>
+constexpr auto rbegin(C& c) noexcept(see-below) -> decltype(c.rbegin());            // C++14, constexpr since C++17
+template <class C>
+constexpr auto rbegin(const C& c) noexcept(see-below) -> decltype(c.rbegin());      // C++14, constexpr since C++17
+template <class C>
+constexpr auto rend(C& c) noexcept(see-below) -> decltype(c.rend());                // C++14, constexpr since C++17
+template <class C>
+constexpr auto rend(const C& c) noexcept(see-below) -> decltype(c.rend());          // C++14, constexpr since C++17
+template <class E>
+constexpr reverse_iterator<const E*> rbegin(initializer_list<E> il) noexcept;       // C++14, constexpr since C++17
+template <class E>
+constexpr reverse_iterator<const E*> rend(initializer_list<E> il) noexcept;         // C++14, constexpr since C++17
+template <class T, size_t N>
+constexpr reverse_iterator<T*> rbegin(T (&array)[N]) noexcept;                      // C++14, constexpr since C++17
+template <class T, size_t N>
+constexpr reverse_iterator<T*> rend(T (&array)[N]) noexcept;                        // C++14, constexpr since C++17
+template <class C>
+constexpr auto crbegin(const C& c) noexcept(see-below) -> decltype(std::rbegin(c)); // C++14, constexpr since C++17
+template <class C>
+constexpr auto crend(const C& c) noexcept(see-below) -> decltype(std::rend(c));     // C++14, constexpr since C++17
 
 // 24.8, container access:
-template <class C> constexpr auto size(const C& c) -> decltype(c.size());         // C++17
-template <class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept; // C++17
+template <class C> constexpr auto size(const C& c) noexcept(see-below) -> decltype(c.size()); // C++17
+template <class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept;             // C++17
 
-template <class C> constexpr auto ssize(const C& c)
+template <class C> constexpr auto ssize(const C& c) noexcept(see-below)
     -> common_type_t<ptrdiff_t, make_signed_t<decltype(c.size())>>;                    // C++20
 template <class T, ptrdiff_t> constexpr ptrdiff_t ssize(const T (&array)[N]) noexcept; // C++20
 
-template <class C> constexpr auto empty(const C& c) -> decltype(c.empty());       // C++17
-template <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept;  // C++17
-template <class E> constexpr bool empty(initializer_list<E> il) noexcept;         // C++17
-template <class C> constexpr auto data(C& c) -> decltype(c.data());               // C++17
-template <class C> constexpr auto data(const C& c) -> decltype(c.data());         // C++17
-template <class T, size_t N> constexpr T* data(T (&array)[N]) noexcept;           // C++17
-template <class E> constexpr const E* data(initializer_list<E> il) noexcept;      // C++17
+template <class C> constexpr auto empty(const C& c) noexcept(see-below) -> decltype(c.empty()); // C++17
+template <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept;                // C++17
+template <class C> constexpr auto data(C& c) noexcept(see-below) -> decltype(c.data());         // C++17
+template <class C> constexpr auto data(const C& c) noexcept(see-below) -> decltype(c.data());   // C++17
+template <class T, size_t N> constexpr T* data(T (&array)[N]) noexcept;                         // C++17
 
 }  // std
 
@@ -736,6 +746,7 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
 // [iterator.synopsis]
 #  include <compare>
 #  include <concepts>
+#  include <initializer_list>
 
 // [range.access.general]
 #  if _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/optional b/libcxx/include/optional
index 440fdf73a4310..c274e43819764 100644
--- a/libcxx/include/optional
+++ b/libcxx/include/optional
@@ -323,6 +323,13 @@ namespace std {
 // [optional.syn]
 #  include <compare>
 
+// [iterator.range]
+#  include <__iterator/access.h>
+#  include <__iterator/data.h>
+#  include <__iterator/empty.h>
+#  include <__iterator/reverse_access.h>
+#  include <__iterator/size.h>
+
 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #    pragma GCC system_header
 #  endif
diff --git a/libcxx/include/typeindex b/libcxx/include/typeindex
index 82ea3d616f35d..10be9e9331acc 100644
--- a/libcxx/include/typeindex
+++ b/libcxx/include/typeindex
@@ -55,6 +55,7 @@ struct hash<type_index>
 
 // standard-mandated includes
 #  include <compare>
+#  include <typeinfo>
 
 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #    pragma GCC system_header
diff --git a/libcxx/include/valarray b/libcxx/include/valarray
index f04923d08c269..728b80c564fcd 100644
--- a/libcxx/include/valarray
+++ b/libcxx/include/valarray
@@ -373,6 +373,13 @@ template <class T> unspecified2 end(const valarray<T>& v);
 // [valarray.syn]
 #  include <initializer_list>
 
+// [iterator.range]
+#  include <__iterator/access.h>
+#  include <__iterator/data.h>
+#  include <__iterator/empty.h>
+#  include <__iterator/reverse_access.h>
+#  include <__iterator/size.h>
+
 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #    pragma GCC system_header
 #  endif
@@ -786,6 +793,9 @@ public:
   typedef _Tp value_type;
   typedef _Tp __result_type;
 
+  typedef _Tp* iterator;
+  typedef const _Tp* const_iterator;
+
 private:
   value_type* __begin_;
   value_type* __end_;
@@ -908,6 +918,11 @@ public:
   _LIBCPP_HIDE_FROM_ABI valarray& operator>>=(const _Expr& __v);
 
   // member functions:
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator begin() { return __begin_; }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator end() { return __begin_; }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const { return __end_; }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const { return __end_; }
+
   _LIBCPP_HIDE_FROM_ABI void swap(valarray& __v) _NOEXCEPT;
 
   [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t size() const { return static_cast<size_t>(__end_ - __begin_); }
@@ -940,18 +955,6 @@ private:
   template <class>
   friend class __val_expr;
 
-  template <class _Up>
-  friend _Up* begin(valarray<_Up>& __v);
-
-  template <class _Up>
-  friend const _Up* begin(const valarray<_Up>& __v);
-
-  template <class _Up>
-  friend _Up* end(valarray<_Up>& __v);
-
-  template <class _Up>
-  friend const _Up* end(const valarray<_Up>& __v);
-
   _LIBCPP_HIDE_FROM_ABI void __clear(size_t __capacity);
   valarray& __assign_range(const value_type* __f, const value_type* __l);
 };
@@ -3280,26 +3283,6 @@ tanh(const _Expr& __x) {
   return __val_expr<_Op>(_Op(__tanh_expr<value_type>(), __x));
 }
 
-template <class _Tp>
-[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _Tp* begin(valarray<_Tp>& __v) {
-  return __v.__begin_;
-}
-
-template <class _Tp>
-[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI const _Tp* begin(const valarray<_Tp>& __v) {
-  return __v.__begin_;
-}
-
-template <class _Tp>
-[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _Tp* end(valarray<_Tp>& __v) {
-  return __v.__end_;
-}
-
-template <class _Tp>
-[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI const _Tp* end(const valarray<_Tp>& __v) {
-  return __v.__end_;
-}
-
 _LIBCPP_END_NAMESPACE_STD
 
 _LIBCPP_POP_MACROS
diff --git a/libcxx/include/version b/libcxx/include/version
index ab781466f5ed5..3dc2521c1df53 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -138,6 +138,7 @@ __cpp_lib_has_unique_object_representations             201606L <type_traits>
 __cpp_lib_hazard_pointer                                202306L <hazard_pointer>
 __cpp_lib_hypot                                         201603L <cmath>
 __cpp_lib_incomplete_container_elements                 201505L <forward_list> <list> <vector>
+__cpp_lib_initializer_list                              202511L <initializer_list>
 __cpp_lib_inplace_vector                                202406L <inplace_vector>
 __cpp_lib_int_pow2                                      202002L <bit>
 __cpp_lib_integer_comparison_functions                  202002L <utility>
@@ -280,6 +281,7 @@ __cpp_lib_uncaught_exceptions                           201411L <exception>
 __cpp_lib_unordered_map_try_emplace                     201411L <unordered_map>
 __cpp_lib_unreachable                                   202202L <utility>
 __cpp_lib_unwrap_ref                                    201811L <functional>
+__cpp_lib_valarray                                      202511L <valarray>
 __cpp_lib_variant                                       202306L <variant>
                                                         202106L // C++20
                                                         202102L // C++17
@@ -303,6 +305,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_complex_udls                         201309L
 # define __cpp_lib_exchange_function                    201304L
 # define __cpp_lib_generic_associative_lookup           201304L
+# define __cpp_lib_initializer_list                     202511L
 # define __cpp_lib_integer_sequence                     201304L
 # define __cpp_lib_integral_constant_callable           201304L
 # define __cpp_lib_is_final                             201402L
@@ -323,6 +326,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_transparent_operators                201210L
 # define __cpp_lib_tuple_element_t                      201402L
 # define __cpp_lib_tuples_by_type                       201304L
+# define __cpp_lib_valarray                             202511L
 #endif
 
 #if _LIBCPP_STD_VER >= 17
diff --git a/libcxx/test/libcxx/language.support/nodiscard.verify.cpp b/libcxx/test/libcxx/language.support/nodiscard.verify.cpp
index 6d784f27440e1..2f3c6c1acda23 100644
--- a/libcxx/test/libcxx/language.support/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/language.support/nodiscard.verify.cpp
@@ -123,7 +123,9 @@ void test() {
   { // <initializer_list>
     std::initializer_list<int> il{94, 82, 49};
 
+    il.data();  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
     il.size();  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    il.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
     il.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
     il.end();   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
   }
diff --git a/libcxx/test/libcxx/numerics/numarray/nodiscard.verify.cpp b/libcxx/test/libcxx/numerics/numarray/nodiscard.verify.cpp
index 84e810f6dfe25..c3e0104e0325d 100644
--- a/libcxx/test/libcxx/numerics/numarray/nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/numerics/numarray/nodiscard.verify.cpp
@@ -53,6 +53,11 @@ void test() {
   cva[std::move(sva)]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
 #endif
 
+  va.baegin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cva.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  va.end();    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+  cva.end();   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
   va.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
 
   va.sum(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
@@ -88,9 +93,4 @@ void test() {
   std::sqrt(va);      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
   std::tan(va);       // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
   std::tanh(va);      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-
-  std::begin(va);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::begin(cva); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::end(va);    // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  std::end(cva);   // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
 }
diff --git a/libcxx/test/std/iterators/iterator.container/data.pass.cpp b/libcxx/test/std/iterators/iterator.container/data.pass.cpp
index 1a6af4a95054d..b25587163f3c0 100644
--- a/libcxx/test/std/iterators/iterator.container/data.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.container/data.pass.cpp
@@ -12,7 +12,6 @@
 // template <class C> constexpr auto data(C& c) -> decltype(c.data());               // C++17
 // template <class C> constexpr auto data(const C& c) -> decltype(c.data());         // C++17
 // template <class T, size_t N> constexpr T* data(T (&array)[N]) noexcept;           // C++17
-// template <class E> constexpr const E* data(initializer_list<E> il) noexcept;      // C++17
 
 #include <iterator>
 #include <cassert>
@@ -29,8 +28,8 @@
 template<typename C>
 void test_const_container( const C& c )
 {
-//  Can't say noexcept here because the container might not be
-    assert ( std::data(c)   == c.data());
+  static_assert(noexcept(std::data(c)) == noexcept(c.data()));
+  assert(std::data(c) == c.data());
 }
 
 template<typename T>
@@ -43,8 +42,8 @@ void test_const_container( const std::initializer_list<T>& c )
 template<typename C>
 void test_container( C& c )
 {
-//  Can't say noexcept here because the container might not be
-    assert ( std::data(c)   == c.data());
+  static_assert(noexcept(std::data(c)) == noexcept(c.data()));
+  assert(std::data(c) == c.data());
 }
 
 template<typename T>
diff --git a/libcxx/test/std/iterators/iterator.container/empty.pass.cpp b/libcxx/test/std/iterators/iterator.container/empty.pass.cpp
index 1a00e88d22b15..2593ba3b0e56e 100644
--- a/libcxx/test/std/iterators/iterator.container/empty.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.container/empty.pass.cpp
@@ -11,7 +11,6 @@
 // <iterator>
 // template <class C> constexpr auto empty(const C& c) -> decltype(c.empty());       // C++17
 // template <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept;  // C++17
-// template <class E> constexpr bool empty(initializer_list<E> il) noexcept;         // C++17
 
 #include <iterator>
 #include <cassert>
@@ -29,8 +28,8 @@
 template<typename C>
 void test_const_container( const C& c )
 {
-//  Can't say noexcept here because the container might not be
-    assert ( std::empty(c)   == c.empty());
+  static_assert(noexcept(std::empty(c)) == noexcept(c.empty()));
+  assert(std::empty(c) == c.empty());
 }
 
 template<typename T>
@@ -42,8 +41,8 @@ void test_const_container( const std::initializer_list<T>& c )
 template<typename C>
 void test_container( C& c )
 {
-//  Can't say noexcept here because the container might not be
-    assert ( std::empty(c)   == c.empty());
+  static_assert(noexcept(std::empty(c)) == noexcept(c.empty()));
+  assert(std::empty(c) == c.empty());
 }
 
 template<typename T>
diff --git a/libcxx/test/std/iterators/iterator.container/size.pass.cpp b/libcxx/test/std/iterators/iterator.container/size.pass.cpp
index 975d3e80c2b78..460bf256bff42 100644
--- a/libcxx/test/std/iterators/iterator.container/size.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.container/size.pass.cpp
@@ -29,29 +29,29 @@
 template<typename C>
 void test_container( C& c)
 {
-//  Can't say noexcept here because the container might not be
-    assert ( std::size(c)   == c.size());
+  static_assert(noexcept(std::size(c)) == noexcept(c.size()));
+  assert(std::size(c) == c.size());
 }
 
 template<typename C>
 void test_const_container( const C& c )
 {
-//  Can't say noexcept here because the container might not be
-    assert ( std::size(c)   == c.size());
+  static_assert(noexcept(std::size(c)) == noexcept(c.size()));
+  assert(std::size(c) == c.size());
 }
 
 template<typename T>
 void test_const_container( const std::initializer_list<T>& c)
 {
-    LIBCPP_ASSERT_NOEXCEPT(std::size(c)); // our std::size is conditionally noexcept
-    assert ( std::size(c)   == c.size());
+  ASSERT_NOEXCEPT(std::size(c));
+  assert(std::size(c) == c.size());
 }
 
 template<typename T>
 void test_container( std::initializer_list<T>& c )
 {
-    LIBCPP_ASSERT_NOEXCEPT(std::size(c)); // our std::size is conditionally noexcept
-    assert ( std::size(c)   == c.size());
+  ASSERT_NOEXCEPT(std::size(c));
+  assert(std::size(c) == c.size());
 }
 
 template<typename T, std::size_t Sz>
diff --git a/libcxx/test/std/iterators/iterator.container/ssize.pass.cpp b/libcxx/test/std/iterators/iterator.container/ssize.pass.cpp
index e7531aec12b24..7ac403a0d00b5 100644
--- a/libcxx/test/std/iterators/iterator.container/ssize.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.container/ssize.pass.cpp
@@ -36,33 +36,33 @@ struct short_container {
 template<typename C>
 void test_container(C& c)
 {
-//  Can't say noexcept here because the container might not be
-    static_assert( std::is_signed_v<decltype(std::ssize(c))>, "");
-    assert ( std::ssize(c)   == static_cast<decltype(std::ssize(c))>(c.size()));
+  static_assert(noexcept(std::ssize(c)) == noexcept(c.size()));
+  static_assert(std::is_signed_v<decltype(std::ssize(c))>, "");
+  assert(std::ssize(c) == static_cast<decltype(std::ssize(c))>(c.size()));
 }
 
 template<typename C>
 void test_const_container(const C& c)
 {
-//  Can't say noexcept here because the container might not be
-    static_assert( std::is_signed_v<decltype(std::ssize(c))>, "");
-    assert ( std::ssize(c)   == static_cast<decltype(std::ssize(c))>(c.size()));
+  static_assert(noexcept(std::ssize(c)) == noexcept(c.size()));
+  static_assert(std::is_signed_v<decltype(std::ssize(c))>, "");
+  assert(std::ssize(c) == static_cast<decltype(std::ssize(c))>(c.size()));
 }
 
 template<typename T>
 void test_const_container(const std::initializer_list<T>& c)
 {
-    LIBCPP_ASSERT_NOEXCEPT(std::ssize(c)); // our std::ssize is conditionally noexcept
-    static_assert( std::is_signed_v<decltype(std::ssize(c))>, "");
-    assert ( std::ssize(c)   == static_cast<decltype(std::ssize(c))>(c.size()));
+  ASSERT_NOEXCEPT(std::ssize(c));
+  static_assert(std::is_signed_v<decltype(std::ssize(c))>, "");
+  assert(std::ssize(c) == static_cast<decltype(std::ssize(c))>(c.size()));
 }
 
 template<typename T>
 void test_container(std::initializer_list<T>& c)
 {
-    LIBCPP_ASSERT_NOEXCEPT(std::ssize(c)); // our std::ssize is conditionally noexcept
-    static_assert( std::is_signed_v<decltype(std::ssize(c))>, "");
-    assert ( std::ssize(c)   == static_cast<decltype(std::ssize(c))>(c.size()));
+  ASSERT_NOEXCEPT(std::ssize(c));
+  static_assert(std::is_signed_v<decltype(std::ssize(c))>, "");
+  assert(std::ssize(c) == static_cast<decltype(std::ssize(c))>(c.size()));
 }
 
 template<typename T, std::size_t Sz>
@@ -118,7 +118,7 @@ int main(int, char**)
     static_assert( std::numeric_limits<                   decltype(std::ssize(sc))>::max()  > 60000, "");
     static_assert( std::numeric_limits<std::make_signed_t<decltype(std:: size(sc))>>::max() < 60000, "");
     assert (std::ssize(sc) == 60000);
-    LIBCPP_ASSERT_NOT_NOEXCEPT(std::ssize(sc));
+    ASSERT_NOT_NOEXCEPT(std::ssize(sc));
 
-  return 0;
+    return 0;
 }
diff --git a/libcxx/test/std/iterators/iterator.range/begin-end.array.pass.cpp b/libcxx/test/std/iterators/iterator.range/begin-end.array.pass.cpp
index 5161069ec8667..7123e59c5c8a6 100644
--- a/libcxx/test/std/iterators/iterator.range/begin-end.array.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.range/begin-end.array.pass.cpp
@@ -13,8 +13,10 @@
 // template <class T, size_t N> constexpr T* begin(T (&array)[N]) noexcept;
 // template <class T, size_t N> constexpr T* end(T (&array)[N]) noexcept;
 //
-// template <class T, size_t N> constexpr reverse_iterator<T*> rbegin(T (&array)[N]);      // C++14, constexpr since C++17
-// template <class T, size_t N> constexpr reverse_iterator<T*> rend(T (&array)[N]);        // C++14, constexpr since C++17
+// template <class T, size_t N>
+// constexpr reverse_iterator<T*> rbegin(T (&array)[N]) noexcept; // C++14, constexpr since C++17
+// template <class T, size_t N>
+// constexpr reverse_iterator<T*> rend(T (&array)[N]) noexcept;   // C++14, constexpr since C++17
 
 #include <cassert>
 #include <iterator>
@@ -55,16 +57,20 @@ TEST_CONSTEXPR_CXX17 bool test_r() {
 
   // std::rbegin(T (&)[N]) / std::rend(T (&)[N])
   {
+    ASSERT_NOEXCEPT(std::rbegin(a));
     ASSERT_SAME_TYPE(decltype(std::rbegin(a)), std::reverse_iterator<int*>);
     assert(std::rbegin(a).base() == a + 3);
 
+    ASSERT_NOEXCEPT(std::rend(a));
     ASSERT_SAME_TYPE(decltype(std::rend(a)), std::reverse_iterator<int*>);
     assert(std::rend(a).base() == a);
 
     // kind of overkill since it follows from the definition, but worth testing
+    ASSERT_NOEXCEPT(std::rbegin(ca));
     ASSERT_SAME_TYPE(decltype(std::rbegin(ca)), std::reverse_iterator<const int*>);
     assert(std::rbegin(ca).base() == ca + 3);
 
+    ASSERT_NOEXCEPT(std::rend(ca));
     ASSERT_SAME_TYPE(decltype(std::rend(ca)), std::reverse_iterator<const int*>);
     assert(std::rend(ca).base() == ca);
   }
diff --git a/libcxx/test/std/iterators/iterator.range/begin-end.container.pass.cpp b/libcxx/test/std/iterators/iterator.range/begin-end.container.pass.cpp
index b795140c2e66a..53f62c763dfb9 100644
--- a/libcxx/test/std/iterators/iterator.range/begin-end.container.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.range/begin-end.container.pass.cpp
@@ -9,20 +9,25 @@
 // UNSUPPORTED: c++03
 
 // <iterator>
-//
-// template <class C> constexpr auto begin(C& c) -> decltype(c.begin());                   // constexpr since C++17
-// template <class C> constexpr auto begin(const C& c) -> decltype(c.begin());             // constexpr since C++17
-// template <class C> constexpr auto end(C& c) -> decltype(c.end());                       // constexpr since C++17
-// template <class C> constexpr auto end(const C& c) -> decltype(c.end());                 // constexpr since C++17
+// template <class C> constexpr auto begin(C& c) noexcept(see-below) -> decltype(c.begin());       // constexpr since C++17
+// template <class C> constexpr auto begin(const C& c) noexcept(see-below) -> decltype(c.begin()); // constexpr since C++17
+// template <class C> constexpr auto end(C& c) noexcept(see-below) -> decltype(c.end());           // constexpr since C++17
+// template <class C> constexpr auto end(const C& c) noexcept(see-below) -> decltype(c.end());     // constexpr since C++17
 //
 // template <class C> constexpr auto cbegin(const C& c) noexcept(see-below) -> decltype(std::begin(c)); // C++14
 // template <class C> constexpr auto cend(const C& c) noexcept(see-below) -> decltype(std::end(c));     // C++14
-// template <class C> constexpr auto rbegin(C& c) -> decltype(c.rbegin());                 // C++14, constexpr since C++17
-// template <class C> constexpr auto rbegin(const C& c) -> decltype(c.rbegin());           // C++14, constexpr since C++17
-// template <class C> constexpr auto rend(C& c) -> decltype(c.rend());                     // C++14, constexpr since C++17
-// template <class C> constexpr auto rend(const C& c) -> decltype(c.rend());               // C++14, constexpr since C++17
-// template <class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));      // C++14, constexpr since C++17
-// template <class C> constexpr auto crend(const C& c) -> decltype(std::rend(c));          // C++14, constexpr since C++17
+// template <class C>
+// constexpr auto rbegin(C& c) noexcept(see-below) -> decltype(c.rbegin());            // C++14, constexpr since C++17
+// template <class C>
+// constexpr auto rbegin(const C& c) noexcept(see-below) -> decltype(c.rbegin());      // C++14, constexpr since C++17
+// template <class C>
+// constexpr auto rend(C& c) noexcept(see-below) -> decltype(c.rend());                // C++14, constexpr since C++17
+// template <class C>
+// constexpr auto rend(const C& c) noexcept(see-below) -> decltype(c.rend());          // C++14, constexpr since C++17
+// template <class C>
+// constexpr auto crbegin(const C& c) noexcept(see-below) -> decltype(std::rbegin(c)); // C++14, constexpr since C++17
+// template <class C>
+// constexpr auto crend(const C& c) noexcept(see-below) -> decltype(std::rend(c));     // C++14, constexpr since C++17
 
 #include <array>
 #include <cassert>
@@ -44,18 +49,22 @@ TEST_CONSTEXPR_CXX17 bool test() {
   // std::begin(C& c) / std::end(C& c)
   {
     ASSERT_SAME_TYPE(decltype(std::begin(c)), Iterator);
+    static_assert(noexcept(std::begin(c)) == noexcept(c.begin()), "");
     assert(std::begin(c) == c.begin());
 
     ASSERT_SAME_TYPE(decltype(std::end(c)), Iterator);
+    static_assert(noexcept(std::end(c)) == noexcept(c.end()), "");
     assert(std::end(c) == c.end());
   }
 
   // std::begin(C const& c) / std::end(C const& c)
   {
     ASSERT_SAME_TYPE(decltype(std::begin(cc)), ConstIterator);
+    static_assert(noexcept(std::begin(cc)) == noexcept(cc.begin()), "");
     assert(std::begin(cc) == cc.begin());
 
     ASSERT_SAME_TYPE(decltype(std::end(cc)), ConstIterator);
+    static_assert(noexcept(std::end(cc)) == noexcept(cc.end()), "");
     assert(std::end(cc) == cc.end());
   }
 
@@ -83,34 +92,42 @@ TEST_CONSTEXPR_CXX17 bool test() {
   // std::rbegin(C& c) / std::rend(C& c)
   {
     ASSERT_SAME_TYPE(decltype(std::rbegin(c)), ReverseIterator);
+    static_assert(noexcept(std::rbegin(c)) == noexcept(c.rbegin()), "");
     assert(std::rbegin(c) == c.rbegin());
 
     ASSERT_SAME_TYPE(decltype(std::rend(c)), ReverseIterator);
+    static_assert(noexcept(std::rend(c)) == noexcept(c.rend()), "");
     assert(std::rend(c) == c.rend());
   }
 
   // std::rbegin(C const&) / std::rend(C const&)
   {
     ASSERT_SAME_TYPE(decltype(std::rbegin(cc)), ConstReverseIterator);
+    static_assert(noexcept(std::rbegin(cc)) == noexcept(cc.rbegin()), "");
     assert(std::rbegin(cc) == cc.rbegin());
 
     ASSERT_SAME_TYPE(decltype(std::rend(cc)), ConstReverseIterator);
+    static_assert(noexcept(std::rend(cc)) == noexcept(cc.rend()), "");
     assert(std::rend(cc) == cc.rend());
   }
 
   // std::crbegin(C const&) / std::crend(C const&)
   {
     ASSERT_SAME_TYPE(decltype(std::crbegin(cc)), ConstReverseIterator);
+    static_assert(noexcept(std::crbegin(cc)) == noexcept(std::rbegin(cc)), "");
     assert(std::crbegin(cc) == std::rbegin(cc));
 
     ASSERT_SAME_TYPE(decltype(std::crend(cc)), ConstReverseIterator);
+    static_assert(noexcept(std::crbegin(cc)) == noexcept(std::rend(cc)), "");
     assert(std::crend(cc) == std::rend(cc));
 
     // kind of overkill, but whatever
     ASSERT_SAME_TYPE(decltype(std::crbegin(c)), ConstReverseIterator);
+    static_assert(noexcept(std::crbegin(c)) == noexcept(std::rbegin(cc)), "");
     assert(std::crbegin(c) == std::rbegin(cc));
 
     ASSERT_SAME_TYPE(decltype(std::crend(c)), ConstReverseIterator);
+    static_assert(noexcept(std::crbegin(c)) == noexcept(std::rend(cc)), "");
     assert(std::crend(c) == std::rend(cc));
   }
 #endif // TEST_STD_VER >= 14
@@ -118,13 +135,149 @@ TEST_CONSTEXPR_CXX17 bool test() {
   return true;
 }
 
+TEST_CONSTEXPR_CXX17 bool test_ilist() {
+  // unqualified begin, etc.
+  {
+    std::initializer_list<int> il = {3, 2, 1};
+    ASSERT_NOEXCEPT(begin(il));
+    ASSERT_NOEXCEPT(end(il));
+#if TEST_STD_VER >= 14
+    ASSERT_NOEXCEPT(cbegin(il));
+    ASSERT_NOEXCEPT(cend(il));
+    ASSERT_NOEXCEPT(rbegin(il));
+    ASSERT_NOEXCEPT(rend(il));
+    ASSERT_NOEXCEPT(crbegin(il));
+    ASSERT_NOEXCEPT(crend(il));
+#endif
+    ASSERT_SAME_TYPE(decltype(begin(il)), const int*);
+    ASSERT_SAME_TYPE(decltype(end(il)), const int*);
+    const int* b = begin(il);
+    const int* e = end(il);
+    assert(il.size() == 3);
+    assert(static_cast<std::size_t>(e - b) == il.size());
+    assert(*b++ == 3);
+    assert(*b++ == 2);
+    assert(*b++ == 1);
+#if TEST_STD_VER >= 14
+    ASSERT_SAME_TYPE(decltype(cbegin(il)), const int*);
+    ASSERT_SAME_TYPE(decltype(cend(il)), const int*);
+    ASSERT_SAME_TYPE(decltype(rbegin(il)), std::reverse_iterator<const int*>);
+    ASSERT_SAME_TYPE(decltype(rend(il)), std::reverse_iterator<const int*>);
+    ASSERT_SAME_TYPE(decltype(crbegin(il)), std::reverse_iterator<const int*>);
+    ASSERT_SAME_TYPE(decltype(crend(il)), std::reverse_iterator<const int*>);
+
+    assert(cbegin(il) == begin(il));
+    assert(end(il) == end(il));
+    assert(rbegin(il) == std::reverse_iterator<const int*>(end(il)));
+    assert(rend(il) == std::reverse_iterator<const int*>(begin(il)));
+    assert(crbegin(il) == std::reverse_iterator<const int*>(end(il)));
+    assert(crend(il) == std::reverse_iterator<const int*>(begin(il)));
+
+    auto rb = rbegin(il);
+    auto re = rend(il);
+    assert(static_cast<std::size_t>(re - rb) == il.size());
+    assert(*rb++ == 1);
+    assert(*rb++ == 2);
+    assert(*rb++ == 3);
+#endif
+  }
+
+  // qualified begin, etc.
+  {
+    std::initializer_list<int> il = {1, 2, 3};
+    ASSERT_NOEXCEPT(std::begin(il));
+    ASSERT_NOEXCEPT(std::end(il));
+#if TEST_STD_VER >= 14
+    ASSERT_NOEXCEPT(std::cbegin(il));
+    ASSERT_NOEXCEPT(std::cend(il));
+    ASSERT_NOEXCEPT(std::rbegin(il));
+    ASSERT_NOEXCEPT(std::rend(il));
+    ASSERT_NOEXCEPT(std::crbegin(il));
+    ASSERT_NOEXCEPT(std::crend(il));
+#endif
+    ASSERT_SAME_TYPE(decltype(std::begin(il)), const int*);
+    ASSERT_SAME_TYPE(decltype(std::end(il)), const int*);
+    assert(std::begin(il) == il.begin());
+    assert(std::end(il) == il.end());
+#if TEST_STD_VER >= 14
+    ASSERT_SAME_TYPE(decltype(std::cbegin(il)), const int*);
+    ASSERT_SAME_TYPE(decltype(std::cend(il)), const int*);
+    ASSERT_SAME_TYPE(decltype(std::rbegin(il)), std::reverse_iterator<const int*>);
+    ASSERT_SAME_TYPE(decltype(std::rend(il)), std::reverse_iterator<const int*>);
+    ASSERT_SAME_TYPE(decltype(std::crbegin(il)), std::reverse_iterator<const int*>);
+    ASSERT_SAME_TYPE(decltype(std::crend(il)), std::reverse_iterator<const int*>);
+
+    assert(std::cbegin(il) == std::begin(il));
+    assert(std::end(il) == std::end(il));
+    assert(std::rbegin(il) == std::reverse_iterator<const int*>(std::end(il)));
+    assert(std::rend(il) == std::reverse_iterator<const int*>(std::begin(il)));
+    assert(std::crbegin(il) == std::reverse_iterator<const int*>(std::end(il)));
+    assert(std::crend(il) == std::reverse_iterator<const int*>(std::begin(il)));
+
+    {
+      auto rb = std::rbegin(il);
+      auto re = std::rend(il);
+      assert(static_cast<std::size_t>(re - rb) == il.size());
+      assert(*rb++ == 1);
+      assert(*rb++ == 2);
+      assert(*rb++ == 3);
+    }
+#endif
+
+    const auto& cil = il;
+    ASSERT_NOEXCEPT(std::begin(cil));
+    ASSERT_NOEXCEPT(std::end(cil));
+#if TEST_STD_VER >= 14
+    ASSERT_NOEXCEPT(std::cbegin(cil));
+    ASSERT_NOEXCEPT(std::cend(cil));
+    ASSERT_NOEXCEPT(std::rbegin(cil));
+    ASSERT_NOEXCEPT(std::rend(cil));
+    ASSERT_NOEXCEPT(std::crbegin(cil));
+    ASSERT_NOEXCEPT(std::crend(cil));
+#endif
+    ASSERT_SAME_TYPE(decltype(std::begin(cil)), const int*);
+    ASSERT_SAME_TYPE(decltype(std::end(cil)), const int*);
+    assert(std::begin(cil) == il.begin());
+    assert(std::end(cil) == il.end());
+#if TEST_STD_VER >= 14
+    ASSERT_SAME_TYPE(decltype(std::cbegin(cil)), const int*);
+    ASSERT_SAME_TYPE(decltype(std::cend(cil)), const int*);
+    ASSERT_SAME_TYPE(decltype(std::rbegin(cil)), std::reverse_iterator<const int*>);
+    ASSERT_SAME_TYPE(decltype(std::rend(cil)), std::reverse_iterator<const int*>);
+    ASSERT_SAME_TYPE(decltype(std::crbegin(cil)), std::reverse_iterator<const int*>);
+    ASSERT_SAME_TYPE(decltype(std::crend(cil)), std::reverse_iterator<const int*>);
+
+    assert(std::cbegin(cil) == std::begin(cil));
+    assert(std::end(cil) == std::end(cil));
+    assert(std::rbegin(cil) == std::reverse_iterator<const int*>(std::end(cil)));
+    assert(std::rend(cil) == std::reverse_iterator<const int*>(std::begin(cil)));
+    assert(std::crbegin(cil) == std::reverse_iterator<const int*>(std::end(cil)));
+    assert(std::crend(cil) == std::reverse_iterator<const int*>(std::begin(cil)));
+
+    {
+      auto rb = std::rbegin(cil);
+      auto re = std::rend(cil);
+      assert(static_cast<std::size_t>(re - rb) == cil.size());
+      assert(*rb++ == 1);
+      assert(*rb++ == 2);
+      assert(*rb++ == 3);
+    }
+#endif
+  }
+
+  return true;
+}
+
 int main(int, char**) {
   test<std::array<int, 3>>();
   test<std::list<int>>();
   test<std::vector<int>>();
 
+  test_ilist();
+
 #if TEST_STD_VER >= 17
   static_assert(test<std::array<int, 3>>());
+  static_assert(test_ilist());
 #endif
 
   // Note: Properly testing the conditional noexcept-ness propagation in std::cbegin and std::cend
@@ -136,10 +289,14 @@ int main(int, char**) {
     auto const& ca = a;
     ASSERT_NOEXCEPT(std::cbegin(ca));
     ASSERT_NOEXCEPT(std::cend(ca));
+    ASSERT_NOEXCEPT(std::crbegin(ca));
+    ASSERT_NOEXCEPT(std::crend(ca));
 
     // kind of overkill, but whatever
     ASSERT_NOEXCEPT(std::cbegin(a));
     ASSERT_NOEXCEPT(std::cend(a));
+    ASSERT_NOEXCEPT(std::crbegin(a));
+    ASSERT_NOEXCEPT(std::crend(a));
   }
 
   // Make sure std::cbegin and std::cend are constexpr in C++14 too (see LWG2280).
diff --git a/libcxx/test/std/iterators/iterator.range/begin-end.initializer_list.pass.cpp b/libcxx/test/std/iterators/iterator.range/begin-end.initializer_list.pass.cpp
index 2df9283b0576d..455aa56b1536a 100644
--- a/libcxx/test/std/iterators/iterator.range/begin-end.initializer_list.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.range/begin-end.initializer_list.pass.cpp
@@ -10,10 +10,10 @@
 
 // <iterator>
 //
-// Note that begin and end are tested in libcxx/test/std/language.support/support.initlist/support.initlist.range/begin_end.pass.cpp
-//
-// template <class E> constexpr reverse_iterator<const E*> rbegin(initializer_list<E> il); // C++14, constexpr since C++17
-// template <class E> constexpr reverse_iterator<const E*> rend(initializer_list<E> il);   // C++14, constexpr since C++17
+// template <class E>
+// constexpr reverse_iterator<const E*> rbegin(initializer_list<E> il) noexcept; // C++14, constexpr since C++17
+// template <class E>
+// constexpr reverse_iterator<const E*> rend(initializer_list<E> il) noexcept;   // C++14, constexpr since C++17
 
 #include <cassert>
 #include <initializer_list>
@@ -23,12 +23,14 @@
 
 TEST_CONSTEXPR_CXX17 bool test() {
   std::initializer_list<int> il = {1, 2, 3};
+  ASSERT_NOEXCEPT(std::rbegin(il));
   ASSERT_SAME_TYPE(decltype(std::rbegin(il)), std::reverse_iterator<const int*>);
   ASSERT_SAME_TYPE(decltype(std::rend(il)), std::reverse_iterator<const int*>);
   assert(std::rbegin(il).base() == il.end());
   assert(std::rend(il).base() == il.begin());
 
   const auto& cil = il;
+  ASSERT_NOEXCEPT(std::rbegin(cil));
   ASSERT_SAME_TYPE(decltype(std::rbegin(cil)), std::reverse_iterator<const int*>);
   ASSERT_SAME_TYPE(decltype(std::rend(cil)), std::reverse_iterator<const int*>);
   assert(std::rbegin(cil).base() == il.end());
diff --git a/libcxx/test/std/iterators/iterator.range/mandatory_inclusions.gen.py b/libcxx/test/std/iterators/iterator.range/mandatory_inclusions.gen.py
index 34ede107e5ed6..7d727e2fecc65 100644
--- a/libcxx/test/std/iterators/iterator.range/mandatory_inclusions.gen.py
+++ b/libcxx/test/std/iterators/iterator.range/mandatory_inclusions.gen.py
@@ -9,8 +9,8 @@
 # In addition to being available via inclusion of the <iterator> header,
 # the function templates in [iterator.range] are available when any of the following
 # headers are included: <array>, <deque>, <flat_map>, <flat_set>, <forward_list>,
-# <list>, <map>, <regex>, <set>, <span>, <string>, <string_view>, <unordered_map>,
-# <unordered_set>, <vector>.
+# <list>, <map>, <optional>, <regex>, <set>, <span>, <stacktrace>, <string>,
+# <string_view>, <unordered_map>, <unordered_set>, <valarray>, <vector>.
 
 # UNSUPPORTED: c++03
 
@@ -37,13 +37,16 @@
             "forward_list",
             "list",
             "map",
+            "optional",
             "regex",
             "set",
             "span",
+            # "stacktrace", # unimplemented
             "string",
             "string_view",
             "unordered_map",
             "unordered_set",
+            "valarray",
             "vector",
         ],
     )
diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.iter.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.iter.pass.cpp
index 72e77b0856421..2de83dddb058a 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.iter.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cons/ctor.iter.pass.cpp
@@ -14,14 +14,22 @@
 
 #include <iterator>
 #include <cassert>
+#include <type_traits>
 
 #include "test_macros.h"
 #include "test_iterators.h"
 
 template <class It>
 TEST_CONSTEXPR_CXX17 void test(It i) {
-    std::reverse_iterator<It> r(i);
-    assert(r.base() == i);
+#if TEST_STD_VER >= 11
+  // Verify that this constructor is conditionally noexcept in libc++.
+  // Because many (un)conditionally noexcept functions construct the returned reverse_iterator by this constructor.
+  LIBCPP_STATIC_ASSERT(std::is_nothrow_constructible<std::reverse_iterator<It>, It&>::value ==
+                           std::is_nothrow_constructible<It, It&>::value,
+                       "");
+#endif
+  std::reverse_iterator<It> r(i);
+  assert(r.base() == i);
 }
 
 TEST_CONSTEXPR_CXX17 bool tests() {
diff --git a/libcxx/test/std/language.support/support.initlist/support.initlist.access/access.pass.cpp b/libcxx/test/std/language.support/support.initlist/support.initlist.access/access.pass.cpp
index e6437d5fc0d74..103d4453f2e5b 100644
--- a/libcxx/test/std/language.support/support.initlist/support.initlist.access/access.pass.cpp
+++ b/libcxx/test/std/language.support/support.initlist/support.initlist.access/access.pass.cpp
@@ -10,9 +10,11 @@
 
 // template<class E> class initializer_list;
 
-// const E* begin() const;
-// const E* end() const;
-// size_t size() const;
+// const E* begin() const noexcept; // constexpr since C++14
+// const E* end() const noexcept;   // constexpr since C++14
+// const E* data() const noexcept;  // constexpr since C++14
+// size_t size() const noexcept;    // constexpr since C++14
+// bool empty() const noexcept;     // constexpr since C++14
 
 #include <initializer_list>
 #include <cassert>
@@ -20,43 +22,78 @@
 
 #include "test_macros.h"
 
+ASSERT_SAME_TYPE(decltype(std::initializer_list<int>{}.begin()), const int*);
+ASSERT_SAME_TYPE(decltype(std::initializer_list<int>{}.end()), const int*);
+ASSERT_SAME_TYPE(decltype(std::initializer_list<int>{}.data()), const int*);
+ASSERT_SAME_TYPE(decltype(std::initializer_list<int>{}.size()), std::size_t);
+ASSERT_SAME_TYPE(decltype(std::initializer_list<int>{}.empty()), bool);
+
+ASSERT_NOEXCEPT(std::initializer_list<int>{}.begin());
+ASSERT_NOEXCEPT(std::initializer_list<int>{}.end());
+ASSERT_NOEXCEPT(std::initializer_list<int>{}.data());
+ASSERT_NOEXCEPT(std::initializer_list<int>{}.size());
+ASSERT_NOEXCEPT(std::initializer_list<int>{}.empty());
+
 struct A
 {
-    A(std::initializer_list<int> il)
+  TEST_CONSTEXPR_CXX14 A(std::initializer_list<int> il) {
     {
-        const int* b = il.begin();
-        const int* e = il.end();
-        assert(il.size() == 3);
-        assert(static_cast<std::size_t>(e - b) == il.size());
-        assert(*b++ == 3);
-        assert(*b++ == 2);
-        assert(*b++ == 1);
+      const int* b = il.begin();
+      const int* e = il.end();
+      assert(il.data() == b);
+      assert(il.size() == 3);
+      assert(!il.empty());
+      assert(static_cast<std::size_t>(e - b) == il.size());
+      assert(*b++ == 3);
+      assert(*b++ == 2);
+      assert(*b++ == 1);
     }
-};
-
-#if TEST_STD_VER > 11
-struct B
-{
-    constexpr B(std::initializer_list<int> il)
     {
-        const int* b = il.begin();
-        const int* e = il.end();
-        assert(il.size() == 3);
-        assert(static_cast<std::size_t>(e - b) == il.size());
-        assert(*b++ == 3);
-        assert(*b++ == 2);
-        assert(*b++ == 1);
+      const auto cil = il;
+      const int* b   = cil.begin();
+      const int* e   = cil.end();
+      assert(cil.data() == b);
+      assert(cil.size() == 3);
+      assert(!cil.empty());
+      assert(static_cast<std::size_t>(e - b) == cil.size());
+      assert(*b++ == 3);
+      assert(*b++ == 2);
+      assert(*b++ == 1);
     }
+  }
 };
 
-#endif // TEST_STD_VER > 11
+TEST_CONSTEXPR_CXX14 bool test_empty_ilist() {
+  {
+    std::initializer_list<int> il{};
+    const int* b = il.begin();
+    const int* e = il.end();
+    assert(il.data() == b);
+    assert(il.size() == 0);
+    assert(il.empty());
+    assert(static_cast<std::size_t>(e - b) == il.size());
+  }
+  {
+    const std::initializer_list<int> cil{};
+    const int* b = cil.begin();
+    const int* e = cil.end();
+    assert(cil.data() == b);
+    assert(cil.size() == 0);
+    assert(cil.empty());
+    assert(static_cast<std::size_t>(e - b) == cil.size());
+  }
+
+  return true;
+}
 
 int main(int, char**)
 {
     A test1 = {3, 2, 1}; (void)test1;
+    test_empty_ilist();
 #if TEST_STD_VER > 11
-    constexpr B test2 = {3, 2, 1};
+    constexpr A test2 = {3, 2, 1};
     (void)test2;
+    static_assert(test_empty_ilist(), "");
 #endif // TEST_STD_VER > 11
 
   return 0;
diff --git a/libcxx/test/std/language.support/support.initlist/support.initlist.range/begin_end.pass.cpp b/libcxx/test/std/language.support/support.initlist/support.initlist.range/begin_end.pass.cpp
deleted file mode 100644
index b15a4586dda61..0000000000000
--- a/libcxx/test/std/language.support/support.initlist/support.initlist.range/begin_end.pass.cpp
+++ /dev/null
@@ -1,68 +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
-
-// <initializer_list>
-
-// template<class E> constexpr const E* begin(initializer_list<E> il) noexcept; // constexpr since C++14
-// template<class E> constexpr const E* end(initializer_list<E> il) noexcept;   // constexpr since C++14
-
-#include <initializer_list>
-#include <cassert>
-#include <cstddef>
-
-#include "test_macros.h"
-
-TEST_CONSTEXPR_CXX14 bool test() {
-  // unqualified begin/end
-  {
-    std::initializer_list<int> il = {3, 2, 1};
-    ASSERT_NOEXCEPT(begin(il));
-    ASSERT_NOEXCEPT(end(il));
-    ASSERT_SAME_TYPE(decltype(begin(il)), const int*);
-    ASSERT_SAME_TYPE(decltype(end(il)), const int*);
-    const int* b = begin(il);
-    const int* e = end(il);
-    assert(il.size() == 3);
-    assert(static_cast<std::size_t>(e - b) == il.size());
-    assert(*b++ == 3);
-    assert(*b++ == 2);
-    assert(*b++ == 1);
-  }
-
-  // qualified begin/end
-  {
-    std::initializer_list<int> il = {1, 2, 3};
-    ASSERT_NOEXCEPT(std::begin(il));
-    ASSERT_NOEXCEPT(std::end(il));
-    ASSERT_SAME_TYPE(decltype(std::begin(il)), const int*);
-    ASSERT_SAME_TYPE(decltype(std::end(il)), const int*);
-    assert(std::begin(il) == il.begin());
-    assert(std::end(il) == il.end());
-
-    const auto& cil = il;
-    ASSERT_NOEXCEPT(std::begin(cil));
-    ASSERT_NOEXCEPT(std::end(cil));
-    ASSERT_SAME_TYPE(decltype(std::begin(cil)), const int*);
-    ASSERT_SAME_TYPE(decltype(std::end(cil)), const int*);
-    assert(std::begin(cil) == il.begin());
-    assert(std::end(cil) == il.end());
-  }
-
-  return true;
-}
-
-int main(int, char**) {
-  test();
-#if TEST_STD_VER >= 14
-  static_assert(test(), "");
-#endif
-
-  return 0;
-}
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/initializer_list.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/initializer_list.version.compile.pass.cpp
new file mode 100644
index 0000000000000..74421975c138a
--- /dev/null
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/initializer_list.version.compile.pass.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <initializer_list>
+
+// Test the feature test macros defined by <initializer_list>
+
+// clang-format off
+
+#include <initializer_list>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+#  ifdef __cpp_lib_initializer_list
+#    error "__cpp_lib_initializer_list should not be defined before c++14"
+#  endif
+
+#elif TEST_STD_VER == 14
+
+#  ifndef __cpp_lib_initializer_list
+#    error "__cpp_lib_initializer_list should be defined in c++14"
+#  endif
+#  if __cpp_lib_initializer_list != 202511L
+#    error "__cpp_lib_initializer_list should have the value 202511L in c++14"
+#  endif
+
+#elif TEST_STD_VER == 17
+
+#  ifndef __cpp_lib_initializer_list
+#    error "__cpp_lib_initializer_list should be defined in c++17"
+#  endif
+#  if __cpp_lib_initializer_list != 202511L
+#    error "__cpp_lib_initializer_list should have the value 202511L in c++17"
+#  endif
+
+#elif TEST_STD_VER == 20
+
+#  ifndef __cpp_lib_initializer_list
+#    error "__cpp_lib_initializer_list should be defined in c++20"
+#  endif
+#  if __cpp_lib_initializer_list != 202511L
+#    error "__cpp_lib_initializer_list should have the value 202511L in c++20"
+#  endif
+
+#elif TEST_STD_VER == 23
+
+#  ifndef __cpp_lib_initializer_list
+#    error "__cpp_lib_initializer_list should be defined in c++23"
+#  endif
+#  if __cpp_lib_initializer_list != 202511L
+#    error "__cpp_lib_initializer_list should have the value 202511L in c++23"
+#  endif
+
+#elif TEST_STD_VER > 23
+
+#  ifndef __cpp_lib_initializer_list
+#    error "__cpp_lib_initializer_list should be defined in c++26"
+#  endif
+#  if __cpp_lib_initializer_list != 202511L
+#    error "__cpp_lib_initializer_list should have the value 202511L in c++26"
+#  endif
+
+#endif // TEST_STD_VER > 23
+
+// clang-format on
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/valarray.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/valarray.version.compile.pass.cpp
new file mode 100644
index 0000000000000..9f362141491f3
--- /dev/null
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/valarray.version.compile.pass.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <valarray>
+
+// Test the feature test macros defined by <valarray>
+
+// clang-format off
+
+#include <valarray>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+#  ifdef __cpp_lib_valarray
+#    error "__cpp_lib_valarray should not be defined before c++14"
+#  endif
+
+#elif TEST_STD_VER == 14
+
+#  ifndef __cpp_lib_valarray
+#    error "__cpp_lib_valarray should be defined in c++14"
+#  endif
+#  if __cpp_lib_valarray != 202511L
+#    error "__cpp_lib_valarray should have the value 202511L in c++14"
+#  endif
+
+#elif TEST_STD_VER == 17
+
+#  ifndef __cpp_lib_valarray
+#    error "__cpp_lib_valarray should be defined in c++17"
+#  endif
+#  if __cpp_lib_valarray != 202511L
+#    error "__cpp_lib_valarray should have the value 202511L in c++17"
+#  endif
+
+#elif TEST_STD_VER == 20
+
+#  ifndef __cpp_lib_valarray
+#    error "__cpp_lib_valarray should be defined in c++20"
+#  endif
+#  if __cpp_lib_valarray != 202511L
+#    error "__cpp_lib_valarray should have the value 202511L in c++20"
+#  endif
+
+#elif TEST_STD_VER == 23
+
+#  ifndef __cpp_lib_valarray
+#    error "__cpp_lib_valarray should be defined in c++23"
+#  endif
+#  if __cpp_lib_valarray != 202511L
+#    error "__cpp_lib_valarray should have the value 202511L in c++23"
+#  endif
+
+#elif TEST_STD_VER > 23
+
+#  ifndef __cpp_lib_valarray
+#    error "__cpp_lib_valarray should be defined in c++26"
+#  endif
+#  if __cpp_lib_valarray != 202511L
+#    error "__cpp_lib_valarray should have the value 202511L in c++26"
+#  endif
+
+#endif // TEST_STD_VER > 23
+
+// clang-format on
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index b3b424a1d77ce..917f7524fa79a 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -432,6 +432,10 @@
 #    error "__cpp_lib_incomplete_container_elements should not be defined before c++17"
 #  endif
 
+#  ifdef __cpp_lib_initializer_list
+#    error "__cpp_lib_initializer_list should not be defined before c++14"
+#  endif
+
 #  ifdef __cpp_lib_inplace_vector
 #    error "__cpp_lib_inplace_vector should not be defined before c++26"
 #  endif
@@ -924,6 +928,10 @@
 #    error "__cpp_lib_unwrap_ref should not be defined before c++20"
 #  endif
 
+#  ifdef __cpp_lib_valarray
+#    error "__cpp_lib_valarray should not be defined before c++14"
+#  endif
+
 #  ifdef __cpp_lib_variant
 #    error "__cpp_lib_variant should not be defined before c++17"
 #  endif
@@ -1358,6 +1366,13 @@
 #    error "__cpp_lib_incomplete_container_elements should not be defined before c++17"
 #  endif
 
+#  ifndef __cpp_lib_initializer_list
+#    error "__cpp_lib_initializer_list should be defined in c++14"
+#  endif
+#  if __cpp_lib_initializer_list != 202511L
+#    error "__cpp_lib_initializer_list should have the value 202511L in c++14"
+#  endif
+
 #  ifdef __cpp_lib_inplace_vector
 #    error "__cpp_lib_inplace_vector should not be defined before c++26"
 #  endif
@@ -1910,6 +1925,13 @@
 #    error "__cpp_lib_unwrap_ref should not be defined before c++20"
 #  endif
 
+#  ifndef __cpp_lib_valarray
+#    error "__cpp_lib_valarray should be defined in c++14"
+#  endif
+#  if __cpp_lib_valarray != 202511L
+#    error "__cpp_lib_valarray should have the value 202511L in c++14"
+#  endif
+
 #  ifdef __cpp_lib_variant
 #    error "__cpp_lib_variant should not be defined before c++17"
 #  endif
@@ -2422,6 +2444,13 @@
 #    error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++17"
 #  endif
 
+#  ifndef __cpp_lib_initializer_list
+#    error "__cpp_lib_initializer_list should be defined in c++17"
+#  endif
+#  if __cpp_lib_initializer_list != 202511L
+#    error "__cpp_lib_initializer_list should have the value 202511L in c++17"
+#  endif
+
 #  ifdef __cpp_lib_inplace_vector
 #    error "__cpp_lib_inplace_vector should not be defined before c++26"
 #  endif
@@ -3088,6 +3117,13 @@
 #    error "__cpp_lib_unwrap_ref should not be defined before c++20"
 #  endif
 
+#  ifndef __cpp_lib_valarray
+#    error "__cpp_lib_valarray should be defined in c++17"
+#  endif
+#  if __cpp_lib_valarray != 202511L
+#    error "__cpp_lib_valarray should have the value 202511L in c++17"
+#  endif
+
 #  ifndef __cpp_lib_variant
 #    error "__cpp_lib_variant should be defined in c++17"
 #  endif
@@ -3744,6 +3780,13 @@
 #    error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++20"
 #  endif
 
+#  ifndef __cpp_lib_initializer_list
+#    error "__cpp_lib_initializer_list should be defined in c++20"
+#  endif
+#  if __cpp_lib_initializer_list != 202511L
+#    error "__cpp_lib_initializer_list should have the value 202511L in c++20"
+#  endif
+
 #  ifdef __cpp_lib_inplace_vector
 #    error "__cpp_lib_inplace_vector should not be defined before c++26"
 #  endif
@@ -4536,6 +4579,13 @@
 #    error "__cpp_lib_unwrap_ref should have the value 201811L in c++20"
 #  endif
 
+#  ifndef __cpp_lib_valarray
+#    error "__cpp_lib_valarray should be defined in c++20"
+#  endif
+#  if __cpp_lib_valarray != 202511L
+#    error "__cpp_lib_valarray should have the value 202511L in c++20"
+#  endif
+
 #  ifndef __cpp_lib_variant
 #    error "__cpp_lib_variant should be defined in c++20"
 #  endif
@@ -5258,6 +5308,13 @@
 #    error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++23"
 #  endif
 
+#  ifndef __cpp_lib_initializer_list
+#    error "__cpp_lib_initializer_list should be defined in c++23"
+#  endif
+#  if __cpp_lib_initializer_list != 202511L
+#    error "__cpp_lib_initializer_list should have the value 202511L in c++23"
+#  endif
+
 #  ifdef __cpp_lib_inplace_vector
 #    error "__cpp_lib_inplace_vector should not be defined before c++26"
 #  endif
@@ -6209,6 +6266,13 @@
 #    error "__cpp_lib_unwrap_ref should have the value 201811L in c++23"
 #  endif
 
+#  ifndef __cpp_lib_valarray
+#    error "__cpp_lib_valarray should be defined in c++23"
+#  endif
+#  if __cpp_lib_valarray != 202511L
+#    error "__cpp_lib_valarray should have the value 202511L in c++23"
+#  endif
+
 #  ifndef __cpp_lib_variant
 #    error "__cpp_lib_variant should be defined in c++23"
 #  endif
@@ -7126,6 +7190,13 @@
 #    error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++26"
 #  endif
 
+#  ifndef __cpp_lib_initializer_list
+#    error "__cpp_lib_initializer_list should be defined in c++26"
+#  endif
+#  if __cpp_lib_initializer_list != 202511L
+#    error "__cpp_lib_initializer_list should have the value 202511L in c++26"
+#  endif
+
 #  if !defined(_LIBCPP_VERSION)
 #    ifndef __cpp_lib_inplace_vector
 #      error "__cpp_lib_inplace_vector should be defined in c++26"
@@ -8215,6 +8286,13 @@
 #    error "__cpp_lib_unwrap_ref should have the value 201811L in c++26"
 #  endif
 
+#  ifndef __cpp_lib_valarray
+#    error "__cpp_lib_valarray should be defined in c++26"
+#  endif
+#  if __cpp_lib_valarray != 202511L
+#    error "__cpp_lib_valarray should have the value 202511L in c++26"
+#  endif
+
 #  ifndef __cpp_lib_variant
 #    error "__cpp_lib_variant should be defined in c++26"
 #  endif
diff --git a/libcxx/test/std/numerics/numarray/template.valarray/types.compile.pass.cpp b/libcxx/test/std/numerics/numarray/template.valarray/types.compile.pass.cpp
new file mode 100644
index 0000000000000..d6ce1679f262f
--- /dev/null
+++ b/libcxx/test/std/numerics/numarray/template.valarray/types.compile.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <valarray>
+
+// template<class T>
+// class valarray
+// {
+// public:
+//     using value_type     = T;
+//     using iterator       = unspecified;
+//     using const_iterator = unspecified;
+//     ...
+
+#include <valarray>
+#include <iterator>
+#include <type_traits>
+
+#include "test_macros.h"
+
+template <class T>
+void test() {
+  using It  = typename std::valarray<T>::iterator;
+  using CIt = typename std::valarray<T>::const_iterator;
+
+  ASSERT_SAME_TYPE(typename std::valarray<T>::value_type, T);
+  static_assert(
+      std::is_base_of<std::random_access_iterator_tag, std::iterator_traits<It>::iterator_category>::value, "");
+  static_assert(
+      std::is_base_of<std::random_access_iterator_tag, std::iterator_traits<CIt>::iterator_category>::value, "");
+
+  ASSERT_SAME_TYPE(decltype(*It()), T&);
+  ASSERT_SAME_TYPE(decltype(*CIt()), const T&);
+
+#if TEST_STD_VER >= 20
+  static_assert(std::contiguous_iterator<It>);
+  static_assert(std::contiguous_iterator<CIt>);
+#endif
+}
+
+void test() {
+  test<int>();
+  test<double>();
+}
diff --git a/libcxx/test/std/numerics/numarray/template.valarray/types.pass.cpp b/libcxx/test/std/numerics/numarray/template.valarray/types.pass.cpp
deleted file mode 100644
index 3d7e04ab87dd0..0000000000000
--- a/libcxx/test/std/numerics/numarray/template.valarray/types.pass.cpp
+++ /dev/null
@@ -1,29 +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
-//
-//===----------------------------------------------------------------------===//
-
-// <valarray>
-
-// template<class T>
-// class valarray
-// {
-// public:
-//     typedef T value_type;
-//     ...
-
-#include <valarray>
-#include <type_traits>
-
-#include "test_macros.h"
-
-int main(int, char**)
-{
-    static_assert((std::is_same<std::valarray<int>::value_type, int>::value), "");
-    static_assert((std::is_same<std::valarray<double>::value_type, double>::value), "");
-
-  return 0;
-}
diff --git a/libcxx/test/std/numerics/numarray/template.valarray/valarray.members/begin-end.pass.cpp b/libcxx/test/std/numerics/numarray/template.valarray/valarray.members/begin-end.pass.cpp
new file mode 100644
index 0000000000000..33617b66b0033
--- /dev/null
+++ b/libcxx/test/std/numerics/numarray/template.valarray/valarray.members/begin-end.pass.cpp
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <valarray>
+
+// template<class T> class valarray;
+
+// iterator       begin();
+// const_iterator begin() const;
+// iterator       end();
+// const_iterator end() const;
+
+#include <valarray>
+#include <cassert>
+#include <iterator>
+#include <type_traits>
+
+#include "test_macros.h"
+
+template <class T>
+void test_return_types() {
+  typedef typename std::valarray<T>::iterator It;
+  typedef typename std::valarray<T>::const_iterator CIt;
+
+  ASSERT_SAME_TYPE(decltype(std::declval<std::valarray<T>>().begin()), It);
+  ASSERT_SAME_TYPE(decltype(std::declval<std::valarray<T>&>().begin()), It);
+  ASSERT_SAME_TYPE(decltype(std::declval<std::valarray<T>>().end()), It);
+  ASSERT_SAME_TYPE(decltype(std::declval<std::valarray<T>&>().end()), It);
+
+  ASSERT_SAME_TYPE(decltype(std::declval<const std::valarray<T>>().begin()), CIt);
+  ASSERT_SAME_TYPE(decltype(std::declval<const std::valarray<T>&>().begin()), CIt);
+  ASSERT_SAME_TYPE(decltype(std::declval<const std::valarray<T>>().end()), CIt);
+  ASSERT_SAME_TYPE(decltype(std::declval<const std::valarray<T>&>().end()), CIt);
+}
+
+int main(int, char**) {
+  {
+    typedef std::valarray<int>::iterator It;
+    typedef std::valarray<int>::const_iterator Cit;
+
+    int a[] = {1, 2, 3, 4, 5};
+    std::valarray<int> v(a, 5);
+    const std::valarray<int>& cv = v;
+
+    assert(&*v.begin() == &v[0]);
+    assert(&*v.end() == &cv[0]);
+    *v.begin() = 10;
+    assert(v[0] == 10);
+
+    assert(&*std::prev(v.end()) == &v[4]);
+    assert(&*std::prev(cv.end()) == &cv[4]);
+  }
+#if TEST_STD_VER >= 11
+  {
+    int a[] = {1, 2, 3, 4, 5};
+    std::valarray<int> v(a, 5);
+    int sum = 0;
+    for (int& i : v) {
+      sum += i;
+    }
+    assert(sum == 15);
+  }
+  {
+    int a[] = {1, 2, 3, 4, 5};
+    const std::valarray<int> cv(a, 5);
+    int sum = 0;
+    for (const int& i : cv) {
+      sum += i;
+    }
+    assert(sum == 15);
+  }
+#endif
+  test_return_types<int>();
+  test_return_types<double>();
+
+  return 0;
+}
diff --git a/libcxx/test/std/numerics/numarray/valarray.range/begin-end.pass.cpp b/libcxx/test/std/numerics/numarray/valarray.range/begin-end.pass.cpp
deleted file mode 100644
index d5ec017e04a86..0000000000000
--- a/libcxx/test/std/numerics/numarray/valarray.range/begin-end.pass.cpp
+++ /dev/null
@@ -1,69 +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
-//
-//===----------------------------------------------------------------------===//
-
-// <valarray>
-
-// template<class T> class valarray;
-
-// template <class T> unspecified begin(valarray<T>& v);
-// template <class T> unspecified begin(const valarray<T>& v);
-// template <class T> unspecified end(valarray<T>& v);
-// template <class T> unspecified end(const valarray<T>& v);
-
-#include <valarray>
-#include <cassert>
-#include <iterator>
-#include <type_traits>
-
-#include "test_macros.h"
-
-int main(int, char**)
-{
-  {
-    int a[] = {1, 2, 3, 4, 5};
-    std::valarray<int> v(a, 5);
-    const std::valarray<int>& cv = v;
-    using It = decltype(std::begin(v));
-    using CIt = decltype(std::begin(cv));
-    static_assert(std::is_base_of<std::random_access_iterator_tag, std::iterator_traits<It>::iterator_category>::value, "");
-    static_assert(std::is_base_of<std::random_access_iterator_tag, std::iterator_traits<CIt>::iterator_category>::value, "");
-    ASSERT_SAME_TYPE(decltype(*std::begin(v)), int&);
-    ASSERT_SAME_TYPE(decltype(*std::begin(cv)), const int&);
-    assert(&*std::begin(v) == &v[0]);
-    assert(&*std::begin(cv) == &cv[0]);
-    *std::begin(v) = 10;
-    assert(v[0] == 10);
-
-    ASSERT_SAME_TYPE(decltype(std::end(v)), It);
-    ASSERT_SAME_TYPE(decltype(std::end(cv)), CIt);
-    assert(&*std::prev(std::end(v)) == &v[4]);
-    assert(&*std::prev(std::end(cv)) == &cv[4]);
-  }
-#if TEST_STD_VER >= 11
-  {
-    int a[] = {1, 2, 3, 4, 5};
-    std::valarray<int> v(a, 5);
-    int sum = 0;
-    for (int& i : v) {
-      sum += i;
-    }
-    assert(sum == 15);
-  }
-  {
-    int a[] = {1, 2, 3, 4, 5};
-    const std::valarray<int> cv(a, 5);
-    int sum = 0;
-    for (const int& i : cv) {
-      sum += i;
-    }
-    assert(sum == 15);
-  }
-#endif
-
-  return 0;
-}
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index f61d6f991cb15..83fa411c5b2ce 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -746,6 +746,11 @@ def add_version_header(tc):
             "values": {"c++17": 201505},
             "headers": ["forward_list", "list", "vector"],
         },
+        {
+            "name": "__cpp_lib_initializer_list",
+            "values": {"c++14": 202511},
+            "headers": ["initializer_list"],
+        },
         {
             "name": "__cpp_lib_inplace_vector",
             "values": {"c++26": 202406},  # P0843R14 inplace_vector
@@ -1492,6 +1497,11 @@ def add_version_header(tc):
             "values": {"c++20": 201811},
             "headers": ["functional"],
         },
+        {
+            "name": "__cpp_lib_valarray",
+            "values": {"c++14": 202511},
+            "headers": ["valarray"],
+        },
         {
             "name": "__cpp_lib_variant",
             "values": {
diff --git a/libcxx/utils/libcxx/header_information.py b/libcxx/utils/libcxx/header_information.py
index d06271a7908cc..f53d07295d6f1 100644
--- a/libcxx/utils/libcxx/header_information.py
+++ b/libcxx/utils/libcxx/header_information.py
@@ -220,6 +220,7 @@ def __hash__(self) -> int:
 # For example, [algorithm.syn] contains "#include <initializer_list>".
 mandatory_inclusions = {
     "algorithm": ["initializer_list"],
+    "any": ["initializer_list", "typeinfo"],
     "array": ["compare", "initializer_list"],
     "bitset": ["iosfwd", "string"],
     "chrono": ["compare"],
@@ -230,10 +231,11 @@ def __hash__(self) -> int:
     "filesystem": ["compare"],
     "flat_map": ["compare", "initializer_list"],
     "flat_set": ["compare", "initializer_list"],
+    "functional": ["initializer_list", "typeinfo"],
     "forward_list": ["compare", "initializer_list"],
     "ios": ["iosfwd"],
     "iostream": ["ios", "istream", "ostream", "streambuf"],
-    "iterator": ["compare", "concepts"],
+    "iterator": ["compare", "concepts", "initializer_list"],
     "list": ["compare", "initializer_list"],
     "map": ["compare", "initializer_list"],
     "memory": ["compare"],
@@ -251,7 +253,7 @@ def __hash__(self) -> int:
     "tgmath.h": ["cmath", "complex"],
     "thread": ["compare"],
     "tuple": ["compare"],
-    "typeindex": ["compare"],
+    "typeindex": ["compare", "typeinfo"],
     "unordered_map": ["compare", "initializer_list"],
     "unordered_set": ["compare", "initializer_list"],
     "utility": ["compare", "initializer_list"],



More information about the libcxx-commits mailing list