libstdc++: span's deduction-guide for built-in arrays doesn't work (LWG 3369)

The 23_containers/span/deduction.cc test was already passing, but only
because I had previously implemented the original proposed resolution of
3255. As pointed out in 3255 that original P/R was incorrect because it
broke construction from array xvalues. This reverts the incorrect part
of 3255 (and adds tests for the case it broke), and implements the
resolution of 3369 instead.

	* include/std/span (span(T (&)[N])): Use non-deduced context to
	prevent first parameter from interfering with class template argument
	deduction (LWG 3369).
	* testsuite/23_containers/span/deduction.cc: Add missing 'const'.
	* testsuite/23_containers/span/lwg3255.cc: Check for construction from
	rvalues.
This commit is contained in:
Jonathan Wakely 2020-02-19 14:41:46 +00:00
parent 247f410b83
commit 66ae31eb30
4 changed files with 15 additions and 4 deletions

View file

@ -1,5 +1,12 @@
2020-02-19 Jonathan Wakely <jwakely@redhat.com>
* include/std/span (span(T (&)[N])): Use non-deduced context to
prevent first parameter from interfering with class template argument
deduction (LWG 3369).
* testsuite/23_containers/span/deduction.cc: Add missing 'const'.
* testsuite/23_containers/span/lwg3255.cc: Check for construction from
rvalues.
* include/std/span (span::const_iterator, span::const_reverse_iterator)
(span::cbegin(), span::cend(), span::crbegin(), span::crend()):
Remove (LWG 3320).

View file

@ -182,10 +182,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
template<typename _Tp, size_t _ArrayExtent>
requires __is_compatible_array<_Tp, _ArrayExtent>::value
template<size_t _ArrayExtent>
requires (_Extent == dynamic_extent || _ArrayExtent == _Extent)
constexpr
span(_Tp (&__arr)[_ArrayExtent]) noexcept
span(type_identity_t<element_type> (&__arr)[_ArrayExtent]) noexcept
: span(static_cast<pointer>(__arr), _ArrayExtent)
{ }

View file

@ -73,7 +73,7 @@ test01()
std::span s9(s2);
static_assert( is_static_span<int, 2>(s9) );
std::span s10(const_cast<std::span<int, 2>&>(s2));
std::span s10(const_cast<const std::span<int, 2>&>(s2));
static_assert( is_static_span<int, 2>(s10) );
std::span s11(s5);

View file

@ -57,10 +57,14 @@ static_assert( !is_constructible_v<span<const int, 1>, const array<const int, 2>
static_assert( is_constructible_v<span<int>, int(&)[2]> );
static_assert( is_constructible_v<span<const int>, int(&)[2]> );
static_assert( is_constructible_v<span<const int>, const int(&)[2]> );
static_assert( is_constructible_v<span<const int>, int[2]> );
static_assert( is_constructible_v<span<const int>, const int[2]> );
static_assert( is_constructible_v<span<int>, array<int, 2>&> );
static_assert( is_constructible_v<span<const int>, array<int, 2>&> );
static_assert( is_constructible_v<span<const int>, array<const int, 2>&> );
static_assert( is_constructible_v<span<const int>, array<int, 2>> );
static_assert( is_constructible_v<span<const int>, array<const int, 2>> );
static_assert( is_constructible_v<span<const int>, const array<int, 2>&> );
static_assert( is_constructible_v<span<const int>, const array<const int, 2>&> );