mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
libstdc++: Remove span constructor from initializer_list.
Following LWG4520 resolution from paper P4144R1 Remove span’s initializer_list constructor for C++26. libstdc++-v3/ChangeLog: * include/bits/version.def (span_initializer_list): Remove. * include/bits/version.h: Regenerate. * include/std/span (span::span(initializer_list<value_type>)): Remove. * testsuite/23_containers/span/init_list_cons.cc: Removed. * testsuite/23_containers/span/init_list_cons_neg.cc: Removed. * testsuite/23_containers/inplace_vector/copy.cc: Replace span with initializer_list in eq helper. * testsuite/23_containers/inplace_vector/erasure.cc: Likewise. * testsuite/23_containers/inplace_vector/move.cc: Likewise. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
This commit is contained in:
@@ -2171,14 +2171,6 @@ ftms = {
|
||||
};
|
||||
};
|
||||
|
||||
ftms = {
|
||||
name = span_initializer_list;
|
||||
values = {
|
||||
v = 202311;
|
||||
cxxmin = 26;
|
||||
};
|
||||
};
|
||||
|
||||
ftms = {
|
||||
name = text_encoding;
|
||||
values = {
|
||||
|
||||
@@ -2426,16 +2426,6 @@
|
||||
#endif /* !defined(__cpp_lib_saturation_arithmetic) */
|
||||
#undef __glibcxx_want_saturation_arithmetic
|
||||
|
||||
#if !defined(__cpp_lib_span_initializer_list)
|
||||
# if (__cplusplus > 202302L)
|
||||
# define __glibcxx_span_initializer_list 202311L
|
||||
# if defined(__glibcxx_want_all) || defined(__glibcxx_want_span_initializer_list)
|
||||
# define __cpp_lib_span_initializer_list 202311L
|
||||
# endif
|
||||
# endif
|
||||
#endif /* !defined(__cpp_lib_span_initializer_list) */
|
||||
#undef __glibcxx_want_span_initializer_list
|
||||
|
||||
#if !defined(__cpp_lib_text_encoding)
|
||||
# if (__cplusplus > 202302L) && _GLIBCXX_HOSTED && (_GLIBCXX_USE_NL_LANGINFO_L)
|
||||
# define __glibcxx_text_encoding 202306L
|
||||
|
||||
@@ -47,9 +47,7 @@
|
||||
#include <cstddef>
|
||||
#include <bits/stl_iterator.h>
|
||||
#include <bits/ranges_base.h>
|
||||
#ifdef __cpp_lib_span_initializer_list
|
||||
# include <initializer_list>
|
||||
#endif
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
@@ -232,18 +230,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
: _M_ptr(ranges::data(__range)), _M_extent(ranges::size(__range))
|
||||
{ }
|
||||
|
||||
#if __cpp_lib_span_initializer_list >= 202311L // >= C++26
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Winit-list-lifetime"
|
||||
constexpr
|
||||
explicit(extent != dynamic_extent)
|
||||
span(initializer_list<value_type> __il)
|
||||
requires (is_const_v<_Type>)
|
||||
: _M_ptr(__il.begin()), _M_extent(__il.size())
|
||||
{ }
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
constexpr
|
||||
span(const span&) noexcept = default;
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ static_assert(std::is_trivially_copy_assignable_v<std::inplace_vector<Z, 0>>);
|
||||
|
||||
template<typename T, size_t N>
|
||||
constexpr bool
|
||||
eq(const std::inplace_vector<T, N>& s, std::span<const T> o)
|
||||
eq(const std::inplace_vector<T, N>& s, std::initializer_list<std::type_identity_t<T>> o)
|
||||
{ return std::ranges::equal(s, o); }
|
||||
|
||||
constexpr void
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
// { dg-do run { target c++26 } }
|
||||
|
||||
#include <inplace_vector>
|
||||
#include <ranges>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <span>
|
||||
|
||||
template<typename T, size_t N>
|
||||
constexpr bool
|
||||
eq(const std::inplace_vector<T, N>& l, std::span<const T> r) {
|
||||
if (l.size() != r.size())
|
||||
return false;
|
||||
for (auto i = 0u; i < l.size(); ++i)
|
||||
if (l[i] != r[i])
|
||||
return false;
|
||||
return true;
|
||||
eq(const std::inplace_vector<T, N>& l, std::initializer_list<std::type_identity_t<T>> r) {
|
||||
return std::ranges::equal(l, r);
|
||||
};
|
||||
|
||||
constexpr void
|
||||
|
||||
@@ -177,7 +177,7 @@ static_assert(std::is_nothrow_swappable_v<std::inplace_vector<Z, 0>>);
|
||||
|
||||
template<typename T, size_t N>
|
||||
constexpr bool
|
||||
eq(const std::inplace_vector<T, N>& s, std::span<const T> o)
|
||||
eq(const std::inplace_vector<T, N>& s, std::initializer_list<std::type_identity_t<T>> o)
|
||||
{ return std::ranges::equal(s, o); }
|
||||
|
||||
constexpr void
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
// { dg-do compile { target c++26 } }
|
||||
|
||||
#include <span>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(__cpp_lib_span_initializer_list)
|
||||
# error "__cpp_lib_span_initializer_list should be defined"
|
||||
#elif __cpp_lib_span_initializer_list < 202311L
|
||||
# error "Wrong value for __cpp_lib_span_initializer_list (should be >= 202311L)"
|
||||
#endif
|
||||
|
||||
// Check the constraint on the initializer_list constructor
|
||||
static_assert( std::is_const_v<std::span<const int>::element_type>);
|
||||
static_assert(!std::is_const_v<std::span< int>::element_type>);
|
||||
|
||||
static_assert( std::is_constructible_v<std::span<const int >, std::initializer_list< int>>);
|
||||
static_assert( std::is_constructible_v<std::span<const int >, std::initializer_list<const int>>);
|
||||
static_assert( std::is_constructible_v<std::span<const int, 42>, std::initializer_list< int>>);
|
||||
static_assert( std::is_constructible_v<std::span<const int, 42>, std::initializer_list<const int>>);
|
||||
static_assert(!std::is_constructible_v<std::span< int >, std::initializer_list< int>>);
|
||||
static_assert(!std::is_constructible_v<std::span< int >, std::initializer_list<const int>>);
|
||||
static_assert(!std::is_constructible_v<std::span< int, 42>, std::initializer_list< int>>);
|
||||
static_assert(!std::is_constructible_v<std::span< int, 42>, std::initializer_list<const int>>);
|
||||
|
||||
// Check the explicit-ness on the initializer_list constructor
|
||||
static_assert( std::is_convertible_v<std::initializer_list< int>, std::span<const int >>);
|
||||
static_assert( std::is_convertible_v<std::initializer_list<const int>, std::span<const int >>);
|
||||
static_assert(!std::is_convertible_v<std::initializer_list< int>, std::span<const int, 42>>);
|
||||
static_assert(!std::is_convertible_v<std::initializer_list<const int>, std::span<const int, 42>>);
|
||||
static_assert(!std::is_convertible_v<std::initializer_list< int>, std::span< int >>);
|
||||
static_assert(!std::is_convertible_v<std::initializer_list<const int>, std::span< int >>);
|
||||
static_assert(!std::is_convertible_v<std::initializer_list< int>, std::span< int, 42>>);
|
||||
static_assert(!std::is_convertible_v<std::initializer_list<const int>, std::span< int, 42>>);
|
||||
|
||||
constexpr size_t fun1(std::span<const int> s)
|
||||
{
|
||||
return s.size();
|
||||
}
|
||||
|
||||
static_assert(fun1({}) == 0);
|
||||
static_assert(fun1({1, 2, 3}) == 3);
|
||||
static_assert(fun1(std::initializer_list<int>{1, 2, 3}) == 3);
|
||||
|
||||
// Stress-test array->pointer decays
|
||||
struct decayer {
|
||||
constexpr decayer() = default;
|
||||
constexpr decayer(decayer *) {}
|
||||
};
|
||||
|
||||
constexpr size_t fun2(std::span<const decayer> s)
|
||||
{
|
||||
return s.size();
|
||||
}
|
||||
|
||||
void test01()
|
||||
{
|
||||
int intArray[42];
|
||||
static_assert(fun1(intArray) == 42);
|
||||
|
||||
decayer decArray[42];
|
||||
static_assert(fun2(decArray) == 42);
|
||||
static_assert(fun2({decArray}) == 1); // decayer[] -> decayer* -> decayer(decayer*) -> init_list<decayer> of 1 element
|
||||
static_assert(fun2({decArray, decArray + 42}) == 2); // does not select span(iterator, iterator)
|
||||
static_assert(fun2({decArray, decArray, decArray}) == 3);
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
// { dg-do run { target { c++20 && c++23_down } } }
|
||||
// { dg-do compile { target c++26 } }
|
||||
|
||||
#include <span>
|
||||
#include <utility>
|
||||
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
struct Any {
|
||||
constexpr Any() { }
|
||||
template<typename T> constexpr Any(T) { }
|
||||
};
|
||||
|
||||
// Examples from P2447R4
|
||||
void one(std::pair<int, int>) {}
|
||||
void one(std::span<const int>) {}
|
||||
void two(std::span<const int, 2>) {}
|
||||
constexpr std::size_t three(std::span<void * const> v) { return v.size(); }
|
||||
constexpr std::size_t four(std::span<const Any> v) { return v.size(); }
|
||||
|
||||
void *array3[10];
|
||||
Any array4[10];
|
||||
|
||||
int main()
|
||||
{
|
||||
one({1, 2}); // { dg-error "call of overloaded" "should be ambiguous with the one(std::pair) overload" { target c++26 } }
|
||||
two({{1, 2}}); // { dg-error "would use explicit constructor" "should prefer the initializer_list constructor, which is explicit" { target c++26 } }
|
||||
|
||||
#if __cpp_lib_span_initializer_list
|
||||
static_assert(three({array3, 0}) == 2);
|
||||
static_assert(four({array4, array4 + 10}) == 2);
|
||||
#else
|
||||
static_assert(three({array3, 0}) == 0);
|
||||
static_assert(four({array4, array4 + 10}) == 10);
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user