[libcxx-commits] [libcxx] a72ab9c - [libc++][span] P2821R5: `span.at()` (#74994)
via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Jan 5 01:41:26 PST 2024
Author: Hristo Hristov
Date: 2024-01-05T11:41:22+02:00
New Revision: a72ab9c14d604ae857acad5ed7d6b5be6914c619
URL: https://github.com/llvm/llvm-project/commit/a72ab9c14d604ae857acad5ed7d6b5be6914c619
DIFF: https://github.com/llvm/llvm-project/commit/a72ab9c14d604ae857acad5ed7d6b5be6914c619.diff
LOG: [libc++][span] P2821R5: `span.at()` (#74994)
- Implements: [P2821R5: span.at()](https://wg21.link/P2821R5)
(https://eel.is/c++draft/views.contiguous#views.span)
- Cleaned up `span.operator[]` test
---------
Co-authored-by: Zingam <zingam at outlook.com>
Added:
libcxx/test/std/containers/views/views.span/span.elem/at.pass.cpp
Modified:
libcxx/docs/FeatureTestMacroTable.rst
libcxx/docs/ReleaseNotes/18.rst
libcxx/docs/Status/Cxx2cPapers.csv
libcxx/include/span
libcxx/include/version
libcxx/test/libcxx/transitive_includes/cxx03.csv
libcxx/test/libcxx/transitive_includes/cxx11.csv
libcxx/test/libcxx/transitive_includes/cxx14.csv
libcxx/test/libcxx/transitive_includes/cxx17.csv
libcxx/test/libcxx/transitive_includes/cxx20.csv
libcxx/test/libcxx/transitive_includes/cxx23.csv
libcxx/test/libcxx/transitive_includes/cxx26.csv
libcxx/test/std/containers/views/views.span/span.elem/op_idx.pass.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/span.version.compile.pass.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
libcxx/utils/generate_feature_test_macro_components.py
Removed:
################################################################################
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index ad12b109023154..8ce5ec9f64ef9a 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -436,6 +436,8 @@ Status
--------------------------------------------------- -----------------
``__cpp_lib_smart_ptr_owner_equality`` *unimplemented*
--------------------------------------------------- -----------------
+ ``__cpp_lib_span_at`` ``202311L``
+ --------------------------------------------------- -----------------
``__cpp_lib_span_initializer_list`` *unimplemented*
--------------------------------------------------- -----------------
``__cpp_lib_sstream_from_string_view`` *unimplemented*
diff --git a/libcxx/docs/ReleaseNotes/18.rst b/libcxx/docs/ReleaseNotes/18.rst
index f5cda9aaa5dcb0..cae2347be5fd61 100644
--- a/libcxx/docs/ReleaseNotes/18.rst
+++ b/libcxx/docs/ReleaseNotes/18.rst
@@ -57,6 +57,7 @@ Implemented Papers
- P2871R3 - Remove Deprecated Unicode Conversion Facets from C++26
- P2870R3 - Remove basic_string::reserve()
- P2909R4 - Fix formatting of code units as integers (Dude, where’s my ``char``?)
+- P2821R5 - span.at()
- P0521R0 - Proposed Resolution for CA 14 (shared_ptr use_count/unique)
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index ff83648aa76830..fa4a112d143673 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -35,7 +35,7 @@
"`P2909R4 <https://wg21.link/P2909R4>`__","LWG","Fix formatting of code units as integers (Dude, where’s my ``char``?)","Kona November 2023","|Complete|","18.0","|format| |DR|"
"`P0952R2 <https://wg21.link/P0952R2>`__","LWG","A new specification for ``std::generate_canonical``","Kona November 2023","","",""
"`P2447R6 <https://wg21.link/P2447R6>`__","LWG","``std::span`` over an initializer list","Kona November 2023","","",""
-"`P2821R5 <https://wg21.link/P2821R5>`__","LWG","``span.at()``","Kona November 2023","","",""
+"`P2821R5 <https://wg21.link/P2821R5>`__","LWG","``span.at()``","Kona November 2023","|Complete|","18.0",""
"`P2868R3 <https://wg21.link/P2868R3>`__","LWG","Remove Deprecated ``std::allocator`` Typedef From C++26","Kona November 2023","","",""
"`P2870R3 <https://wg21.link/P2870R3>`__","LWG","Remove ``basic_string::reserve()`` From C++26","Kona November 2023","|Complete|","18.0",""
"`P2871R3 <https://wg21.link/P2871R3>`__","LWG","Remove Deprecated Unicode Conversion Facets from C++26","Kona November 2023","|Complete|","18.0",""
diff --git a/libcxx/include/span b/libcxx/include/span
index 7dd53110ac2927..007a32597f965b 100644
--- a/libcxx/include/span
+++ b/libcxx/include/span
@@ -92,6 +92,7 @@ public:
// [span.elem], span element access
constexpr reference operator[](size_type idx) const;
+ constexpr reference at(size_type idx) const; // since C++26
constexpr reference front() const;
constexpr reference back() const;
constexpr pointer data() const noexcept;
@@ -146,6 +147,7 @@ template<class R>
#include <__utility/forward.h>
#include <array> // for array
#include <cstddef> // for byte
+#include <stdexcept>
#include <version>
// standard-mandated includes
@@ -321,6 +323,14 @@ public:
return __data_[__idx];
}
+# if _LIBCPP_STD_VER >= 26
+ _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const {
+ if (__index >= size())
+ std::__throw_out_of_range("span");
+ return __data_[__index];
+ }
+# endif
+
_LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::front() on empty span");
return __data_[0];
@@ -469,6 +479,14 @@ public:
return __data_[__idx];
}
+# if _LIBCPP_STD_VER >= 26
+ _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const {
+ if (__index >= size())
+ std::__throw_out_of_range("span");
+ return __data_[__index];
+ }
+# endif
+
_LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::front() on empty span");
return __data_[0];
diff --git a/libcxx/include/version b/libcxx/include/version
index 768710ef5c84aa..d3c2791a7d0b2c 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -201,6 +201,7 @@ __cpp_lib_smart_ptr_for_overwrite 202002L <memory>
__cpp_lib_smart_ptr_owner_equality 202306L <memory>
__cpp_lib_source_location 201907L <source_location>
__cpp_lib_span 202002L <span>
+__cpp_lib_span_at 202311L <span>
__cpp_lib_span_initializer_list 202311L <span>
__cpp_lib_spanstream 202106L <spanstream>
__cpp_lib_ssize 201902L <iterator>
@@ -505,6 +506,7 @@ __cpp_lib_within_lifetime 202306L <type_traits>
// # define __cpp_lib_rcu 202306L
// # define __cpp_lib_saturation_arithmetic 202311L
// # define __cpp_lib_smart_ptr_owner_equality 202306L
+# define __cpp_lib_span_at 202311L
// # define __cpp_lib_span_initializer_list 202311L
// # define __cpp_lib_sstream_from_string_view 202306L
// # define __cpp_lib_submdspan 202306L
diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv
index 3f066342717624..e709628ce2311b 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx03.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv
@@ -742,6 +742,7 @@ span functional
span initializer_list
span iterator
span limits
+span stdexcept
span type_traits
span version
sstream cstddef
diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv
index 7b443e5a0ec0f9..d3ea6ed97367e4 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx11.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv
@@ -748,6 +748,7 @@ span functional
span initializer_list
span iterator
span limits
+span stdexcept
span type_traits
span version
sstream cstddef
diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv
index a5b77ec79bb5c3..3e56017bfb537b 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx14.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv
@@ -750,6 +750,7 @@ span functional
span initializer_list
span iterator
span limits
+span stdexcept
span type_traits
span version
sstream cstddef
diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv
index a5b77ec79bb5c3..3e56017bfb537b 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx17.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv
@@ -750,6 +750,7 @@ span functional
span initializer_list
span iterator
span limits
+span stdexcept
span type_traits
span version
sstream cstddef
diff --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv
index c8c84867fda459..0c5b9721a22551 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx20.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv
@@ -755,6 +755,7 @@ span functional
span initializer_list
span iterator
span limits
+span stdexcept
span type_traits
span version
sstream cstddef
diff --git a/libcxx/test/libcxx/transitive_includes/cxx23.csv b/libcxx/test/libcxx/transitive_includes/cxx23.csv
index a4fa50dc014aba..0d8c3fa21b2f37 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx23.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx23.csv
@@ -519,6 +519,7 @@ span array
span cstddef
span initializer_list
span limits
+span stdexcept
span version
sstream cstddef
sstream istream
diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv
index a4fa50dc014aba..0d8c3fa21b2f37 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx26.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv
@@ -519,6 +519,7 @@ span array
span cstddef
span initializer_list
span limits
+span stdexcept
span version
sstream cstddef
sstream istream
diff --git a/libcxx/test/std/containers/views/views.span/span.elem/at.pass.cpp b/libcxx/test/std/containers/views/views.span/span.elem/at.pass.cpp
new file mode 100644
index 00000000000000..c09571675c0ffa
--- /dev/null
+++ b/libcxx/test/std/containers/views/views.span/span.elem/at.pass.cpp
@@ -0,0 +1,188 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
+
+// <span>
+
+// constexpr reference at(size_type idx) const; // since C++26
+
+#include <array>
+#include <cassert>
+#include <concepts>
+#include <limits>
+#include <span>
+#include <stdexcept>
+#include <string>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+#include "test_macros.h"
+
+template <typename ReferenceT>
+constexpr void testSpanAt(auto&& anySpan, int index, int expectedValue) {
+ // non-const
+ {
+ std::same_as<ReferenceT> decltype(auto) elem = anySpan.at(index);
+ assert(elem == expectedValue);
+ }
+
+ // const
+ {
+ std::same_as<ReferenceT> decltype(auto) elem = std::as_const(anySpan).at(index);
+ assert(elem == expectedValue);
+ }
+}
+
+constexpr bool test() {
+ // With static extent
+ {
+ std::array arr{0, 1, 2, 3, 4, 5, 9084};
+ std::span arrSpan{arr};
+
+ assert(std::dynamic_extent != arrSpan.extent);
+
+ using ReferenceT = typename decltype(arrSpan)::reference;
+
+ testSpanAt<ReferenceT>(arrSpan, 0, 0);
+ testSpanAt<ReferenceT>(arrSpan, 1, 1);
+ testSpanAt<ReferenceT>(arrSpan, 6, 9084);
+ }
+
+ // With dynamic extent
+ {
+ std::vector vec{0, 1, 2, 3, 4, 5, 9084};
+ std::span vecSpan{vec};
+
+ assert(std::dynamic_extent == vecSpan.extent);
+
+ using ReferenceT = typename decltype(vecSpan)::reference;
+
+ testSpanAt<ReferenceT>(vecSpan, 0, 0);
+ testSpanAt<ReferenceT>(vecSpan, 1, 1);
+ testSpanAt<ReferenceT>(vecSpan, 6, 9084);
+ }
+
+ return true;
+}
+
+void test_exceptions() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ using namespace std::string_literals;
+
+ // With static extent
+ {
+ std::array arr{0, 1, 2, 3, 4, 5, 9084, std::numeric_limits<int>::max()};
+ const std::span arrSpan{arr};
+
+ try {
+ using SizeT = typename decltype(arrSpan)::size_type;
+ std::ignore = arrSpan.at(std::numeric_limits<SizeT>::max());
+ assert(false);
+ } catch ([[maybe_unused]] const std::out_of_range& e) {
+ // pass
+ LIBCPP_ASSERT(e.what() == "span"s);
+ } catch (...) {
+ assert(false);
+ }
+
+ try {
+ std::ignore = arrSpan.at(arr.size());
+ assert(false);
+ } catch ([[maybe_unused]] const std::out_of_range& e) {
+ // pass
+ LIBCPP_ASSERT(e.what() == "span"s);
+ } catch (...) {
+ assert(false);
+ }
+
+ try {
+ std::ignore = arrSpan.at(arr.size() - 1);
+ // pass
+ assert(arrSpan.at(arr.size() - 1) == std::numeric_limits<int>::max());
+ } catch (...) {
+ assert(false);
+ }
+ }
+
+ {
+ std::array<int, 0> arr{};
+ const std::span arrSpan{arr};
+
+ try {
+ std::ignore = arrSpan.at(0);
+ assert(false);
+ } catch ([[maybe_unused]] const std::out_of_range& e) {
+ // pass
+ LIBCPP_ASSERT(e.what() == "span"s);
+ } catch (...) {
+ assert(false);
+ }
+ }
+
+ // With dynamic extent
+
+ {
+ std::vector vec{0, 1, 2, 3, 4, 5, 9084, std::numeric_limits<int>::max()};
+ const std::span vecSpan{vec};
+
+ try {
+ using SizeT = typename decltype(vecSpan)::size_type;
+ std::ignore = vecSpan.at(std::numeric_limits<SizeT>::max());
+ assert(false);
+ } catch ([[maybe_unused]] const std::out_of_range& e) {
+ // pass
+ LIBCPP_ASSERT(e.what() == "span"s);
+ } catch (...) {
+ assert(false);
+ }
+
+ try {
+ std::ignore = vecSpan.at(vec.size());
+ assert(false);
+ } catch (const std::out_of_range& e) {
+ // pass
+ LIBCPP_ASSERT(e.what() == "span"s);
+ } catch (...) {
+ assert(false);
+ }
+
+ try {
+ std::ignore = vecSpan.at(vec.size() - 1);
+ assert(vecSpan.at(vec.size() - 1) == std::numeric_limits<int>::max());
+ } catch (...) {
+ assert(false);
+ }
+ }
+
+ {
+ std::vector<int> vec{};
+ const std::span vecSpan{vec};
+
+ try {
+ std::ignore = vecSpan.at(0);
+ assert(false);
+ } catch ([[maybe_unused]] const std::out_of_range& e) {
+ // pass
+ LIBCPP_ASSERT(e.what() == "span"s);
+ } catch (...) {
+ assert(false);
+ }
+ }
+#endif // TEST_HAS_NO_EXCEPTIONS
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ test_exceptions();
+
+ return 0;
+}
diff --git a/libcxx/test/std/containers/views/views.span/span.elem/op_idx.pass.cpp b/libcxx/test/std/containers/views/views.span/span.elem/op_idx.pass.cpp
index e46fd267ef5cc5..b7f36c57585881 100644
--- a/libcxx/test/std/containers/views/views.span/span.elem/op_idx.pass.cpp
+++ b/libcxx/test/std/containers/views/views.span/span.elem/op_idx.pass.cpp
@@ -41,7 +41,6 @@ void testRuntimeSpan(Span sp, std::size_t idx)
assert(r1 == r2);
}
-struct A{};
constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/span.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/span.version.compile.pass.cpp
index 355eb1338d945e..dbbbaf4ec7c228 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/span.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/span.version.compile.pass.cpp
@@ -17,6 +17,7 @@
/* Constant Value
__cpp_lib_span 202002L [C++20]
+ __cpp_lib_span_at 202311L [C++26]
__cpp_lib_span_initializer_list 202311L [C++26]
*/
@@ -29,6 +30,10 @@
# error "__cpp_lib_span should not be defined before c++20"
# endif
+# ifdef __cpp_lib_span_at
+# error "__cpp_lib_span_at should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_span_initializer_list
# error "__cpp_lib_span_initializer_list should not be defined before c++26"
# endif
@@ -39,6 +44,10 @@
# error "__cpp_lib_span should not be defined before c++20"
# endif
+# ifdef __cpp_lib_span_at
+# error "__cpp_lib_span_at should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_span_initializer_list
# error "__cpp_lib_span_initializer_list should not be defined before c++26"
# endif
@@ -49,6 +58,10 @@
# error "__cpp_lib_span should not be defined before c++20"
# endif
+# ifdef __cpp_lib_span_at
+# error "__cpp_lib_span_at should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_span_initializer_list
# error "__cpp_lib_span_initializer_list should not be defined before c++26"
# endif
@@ -62,6 +75,10 @@
# error "__cpp_lib_span should have the value 202002L in c++20"
# endif
+# ifdef __cpp_lib_span_at
+# error "__cpp_lib_span_at should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_span_initializer_list
# error "__cpp_lib_span_initializer_list should not be defined before c++26"
# endif
@@ -75,6 +92,10 @@
# error "__cpp_lib_span should have the value 202002L in c++23"
# endif
+# ifdef __cpp_lib_span_at
+# error "__cpp_lib_span_at should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_span_initializer_list
# error "__cpp_lib_span_initializer_list should not be defined before c++26"
# endif
@@ -88,6 +109,13 @@
# error "__cpp_lib_span should have the value 202002L in c++26"
# endif
+# ifndef __cpp_lib_span_at
+# error "__cpp_lib_span_at should be defined in c++26"
+# endif
+# if __cpp_lib_span_at != 202311L
+# error "__cpp_lib_span_at should have the value 202311L in c++26"
+# endif
+
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_span_initializer_list
# error "__cpp_lib_span_initializer_list should be defined in c++26"
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 650a14b019ed87..3b7f2d26feebd0 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
@@ -186,6 +186,7 @@
__cpp_lib_smart_ptr_owner_equality 202306L [C++26]
__cpp_lib_source_location 201907L [C++20]
__cpp_lib_span 202002L [C++20]
+ __cpp_lib_span_at 202311L [C++26]
__cpp_lib_span_initializer_list 202311L [C++26]
__cpp_lib_spanstream 202106L [C++23]
__cpp_lib_ssize 201902L [C++20]
@@ -879,6 +880,10 @@
# error "__cpp_lib_span should not be defined before c++20"
# endif
+# ifdef __cpp_lib_span_at
+# error "__cpp_lib_span_at should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_span_initializer_list
# error "__cpp_lib_span_initializer_list should not be defined before c++26"
# endif
@@ -1716,6 +1721,10 @@
# error "__cpp_lib_span should not be defined before c++20"
# endif
+# ifdef __cpp_lib_span_at
+# error "__cpp_lib_span_at should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_span_initializer_list
# error "__cpp_lib_span_initializer_list should not be defined before c++26"
# endif
@@ -2733,6 +2742,10 @@
# error "__cpp_lib_span should not be defined before c++20"
# endif
+# ifdef __cpp_lib_span_at
+# error "__cpp_lib_span_at should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_span_initializer_list
# error "__cpp_lib_span_initializer_list should not be defined before c++26"
# endif
@@ -4029,6 +4042,10 @@
# error "__cpp_lib_span should have the value 202002L in c++20"
# endif
+# ifdef __cpp_lib_span_at
+# error "__cpp_lib_span_at should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_span_initializer_list
# error "__cpp_lib_span_initializer_list should not be defined before c++26"
# endif
@@ -5541,6 +5558,10 @@
# error "__cpp_lib_span should have the value 202002L in c++23"
# endif
+# ifdef __cpp_lib_span_at
+# error "__cpp_lib_span_at should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_span_initializer_list
# error "__cpp_lib_span_initializer_list should not be defined before c++26"
# endif
@@ -7272,6 +7293,13 @@
# error "__cpp_lib_span should have the value 202002L in c++26"
# endif
+# ifndef __cpp_lib_span_at
+# error "__cpp_lib_span_at should be defined in c++26"
+# endif
+# if __cpp_lib_span_at != 202311L
+# error "__cpp_lib_span_at should have the value 202311L in c++26"
+# endif
+
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_span_initializer_list
# error "__cpp_lib_span_initializer_list should be defined in c++26"
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 2f506f32f565cb..3ad5170d73ffec 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -1085,6 +1085,11 @@ def add_version_header(tc):
},
"headers": ["span"],
},
+ {
+ "name": "__cpp_lib_span_at",
+ "values": {"c++26": 202311}, # P2821R3 span.at()
+ "headers": ["span"],
+ },
{
"name": "__cpp_lib_span_initializer_list",
"values": {"c++26": 202311}, # P2447R6 std::span over an initializer list
More information about the libcxx-commits
mailing list