[libcxx-commits] [libcxx] [libc++] Complete overload removal in P3016R6 (PR #216932)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Aug 18 00:11:18 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: A. Jiang (frederick-vs-ja)
<details>
<summary>Changes</summary>
P3016R6 also removed overloads of `std::data` and `std::empty` for `std::initializer_list`, but 8248eef4bea83086c4487215a465771f79e8759b missed these removals.
Note that the removal of that `std::empty` overload is almost NFC, as the overload for `const` array will be selected instead for `{vals...}`. Perhaps the removal is observable only when used with a user-defined overload.
The removal for `std::data` overload unconditionally makes `std::data({vals...})` ill-formed (which is good). To avoid potential IFNDR-ness, this PR tests unconventional `std::data<T>({vals...})` instead.
Drive-by changes: Sort includes and remove meaningless guards in touched test files.
---
Full diff: https://github.com/llvm/llvm-project/pull/216932.diff
4 Files Affected:
- (modified) libcxx/include/__iterator/data.h (+1-6)
- (modified) libcxx/include/__iterator/empty.h (+1-6)
- (modified) libcxx/test/std/iterators/iterator.container/data.pass.cpp (+19-11)
- (modified) libcxx/test/std/iterators/iterator.container/empty.pass.cpp (+21-12)
``````````diff
diff --git a/libcxx/include/__iterator/data.h b/libcxx/include/__iterator/data.h
index 7efa57e1a22a7..de5bba6ca2b45 100644
--- a/libcxx/include/__iterator/data.h
+++ b/libcxx/include/__iterator/data.h
@@ -11,7 +11,7 @@
#define _LIBCPP___ITERATOR_DATA_H
#include <__config>
-#include <initializer_list>
+#include <__cstddef/size_t.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -38,11 +38,6 @@ template <class _Tp, size_t _Sz>
return __array;
}
-template <class _Ep>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Ep* data(initializer_list<_Ep> __il) noexcept {
- return __il.begin();
-}
-
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER >= 17
diff --git a/libcxx/include/__iterator/empty.h b/libcxx/include/__iterator/empty.h
index b763048f547e5..7b8ffce21f757 100644
--- a/libcxx/include/__iterator/empty.h
+++ b/libcxx/include/__iterator/empty.h
@@ -11,7 +11,7 @@
#define _LIBCPP___ITERATOR_EMPTY_H
#include <__config>
-#include <initializer_list>
+#include <__cstddef/size_t.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -32,11 +32,6 @@ template <class _Tp, size_t _Sz>
return false;
}
-template <class _Ep>
-[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty(initializer_list<_Ep> __il) noexcept {
- return __il.size() == 0;
-}
-
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER >= 17
diff --git a/libcxx/test/std/iterators/iterator.container/data.pass.cpp b/libcxx/test/std/iterators/iterator.container/data.pass.cpp
index b25587163f3c0..2aca37f6e3751 100644
--- a/libcxx/test/std/iterators/iterator.container/data.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.container/data.pass.cpp
@@ -13,18 +13,16 @@
// 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
-#include <iterator>
-#include <cassert>
-#include <vector>
#include <array>
+#include <cassert>
+#include <iterator>
#include <initializer_list>
+#include <string_view>
+#include <type_traits>
+#include <vector>
#include "test_macros.h"
-#if TEST_STD_VER > 14
-#include <string_view>
-#endif
-
template<typename C>
void test_const_container( const C& c )
{
@@ -60,6 +58,18 @@ void test_const_array( const T (&array)[Sz] )
assert ( std::data(array) == &array[0]);
}
+// Verify that the std::data overload for std::initializer_list is removed by P3016R6.
+template <class T, class = void>
+constexpr bool can_std_data_with_int_list = false;
+template <class T>
+constexpr bool can_std_data_with_int_list<T, std::void_t<decltype(std::data<T>({1, 2, 3}))>> = true;
+
+static_assert(!can_std_data_with_int_list<int>);
+// When C is a range type convertible from {1, 2, 3}, the overload for const C& is selected.
+static_assert(can_std_data_with_int_list<std::vector<int>>);
+static_assert(can_std_data_with_int_list<std::array<int, 3>>);
+static_assert(can_std_data_with_int_list<std::initializer_list<int>>);
+
int main(int, char**)
{
std::vector<int> v; v.push_back(1);
@@ -74,11 +84,9 @@ int main(int, char**)
test_const_container ( a );
test_const_container ( il );
-#if TEST_STD_VER > 14
std::string_view sv{"ABC"};
- test_container ( sv );
- test_const_container ( sv );
-#endif
+ test_container(sv);
+ test_const_container(sv);
static constexpr int arrA [] { 1, 2, 3 };
test_const_array ( arrA );
diff --git a/libcxx/test/std/iterators/iterator.container/empty.pass.cpp b/libcxx/test/std/iterators/iterator.container/empty.pass.cpp
index 2593ba3b0e56e..1cf343dafcac4 100644
--- a/libcxx/test/std/iterators/iterator.container/empty.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.container/empty.pass.cpp
@@ -12,19 +12,17 @@
// 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
-#include <iterator>
-#include <cassert>
-#include <vector>
#include <array>
-#include <list>
+#include <cassert>
#include <initializer_list>
+#include <iterator>
+#include <list>
+#include <string_view>
+#include <type_traits>
+#include <vector>
#include "test_macros.h"
-#if TEST_STD_VER > 14
-#include <string_view>
-#endif
-
template<typename C>
void test_const_container( const C& c )
{
@@ -59,6 +57,11 @@ void test_const_array( const T (&array)[Sz] )
assert (!std::empty(array));
}
+namespace p3016r6 {
+template <class T>
+void empty(std::initializer_list<T>);
+}
+
int main(int, char**)
{
std::vector<int> v; v.push_back(1);
@@ -76,14 +79,20 @@ int main(int, char**)
test_const_container ( a );
test_const_container ( il );
-#if TEST_STD_VER > 14
std::string_view sv{"ABC"};
- test_container ( sv );
- test_const_container ( sv );
-#endif
+ test_container(sv);
+ test_const_container(sv);
static constexpr int arrA [] { 1, 2, 3 };
test_const_array ( arrA );
+ {
+ // Verify that the std::empty overload for std::initializer_list is absent (removed by P3016R6).
+ // The behavior of std::empty({vals...}) is unchanged because the overload for const T(&)[N] is used.
+ using p3016r6::empty;
+ using std::empty;
+ static_assert(std::is_same_v<decltype(empty({1, 2, 3})), void>);
+ }
+
return 0;
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/216932
More information about the libcxx-commits
mailing list