[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