Skip to content

Commit a61404c

Browse files
Implement LWG-4243 as_bytes/as_writable_bytes is broken with span<volatile T> (#5867)
1 parent 44c4abc commit a61404c

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

stl/inc/span

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,13 +558,14 @@ span(_Rng&&) -> span<remove_reference_t<_RANGES range_reference_t<_Rng>>>;
558558
#ifdef __cpp_lib_byte
559559
// [span.objectrep] Views of object representation
560560
_EXPORT_STD template <class _Ty, size_t _Extent>
561+
requires (!is_volatile_v<_Ty>)
561562
_NODISCARD auto as_bytes(span<_Ty, _Extent> _Sp) noexcept {
562563
using _ReturnType = span<const byte, _Extent == dynamic_extent ? dynamic_extent : sizeof(_Ty) * _Extent>;
563564
return _ReturnType{reinterpret_cast<const byte*>(_Sp.data()), _Sp.size_bytes()};
564565
}
565566

566567
_EXPORT_STD template <class _Ty, size_t _Extent>
567-
requires (!is_const_v<_Ty>)
568+
requires (!is_const_v<_Ty> && !is_volatile_v<_Ty>)
568569
_NODISCARD auto as_writable_bytes(span<_Ty, _Extent> _Sp) noexcept {
569570
using _ReturnType = span<byte, _Extent == dynamic_extent ? dynamic_extent : sizeof(_Ty) * _Extent>;
570571
return _ReturnType{reinterpret_cast<byte*>(_Sp.data()), _Sp.size_bytes()};

tests/std/tests/P0122R7_span/test.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,11 @@ using BorrowedContiguousSizedRange = BasicRange<int, true>;
153153
template <typename T, size_t Extent = dynamic_extent>
154154
constexpr void FunctionTakingSpan(type_identity_t<span<T, Extent>>) {}
155155

156-
template <typename U, typename = void>
157-
constexpr bool AsWritableBytesCompilesFor = false;
156+
template <typename U>
157+
constexpr bool AsBytesCompilesFor = requires { as_bytes(declval<U>()); };
158158

159159
template <typename U>
160-
constexpr bool AsWritableBytesCompilesFor<U, void_t<decltype(as_writable_bytes(declval<U>()))>> = true;
160+
constexpr bool AsWritableBytesCompilesFor = requires { as_writable_bytes(declval<U>()); };
161161

162162
constexpr bool test() {
163163
{
@@ -1016,10 +1016,23 @@ void test_non_constexpr() {
10161016
static_assert(noexcept(as_writable_bytes(sp_dyn)));
10171017
static_assert(noexcept(as_writable_bytes(sp_nine)));
10181018

1019+
static_assert(AsBytesCompilesFor<span<int>>);
1020+
static_assert(AsBytesCompilesFor<span<int, 5>>);
1021+
static_assert(AsBytesCompilesFor<span<const int>>);
1022+
static_assert(AsBytesCompilesFor<span<const int, 6>>);
1023+
static_assert(!AsBytesCompilesFor<span<volatile int>>);
1024+
static_assert(!AsBytesCompilesFor<span<volatile int, 7>>);
1025+
static_assert(!AsBytesCompilesFor<span<const volatile int>>);
1026+
static_assert(!AsBytesCompilesFor<span<const volatile int, 8>>);
1027+
10191028
static_assert(AsWritableBytesCompilesFor<span<int>>);
10201029
static_assert(AsWritableBytesCompilesFor<span<int, 9>>);
10211030
static_assert(!AsWritableBytesCompilesFor<span<const int>>);
1022-
static_assert(!AsWritableBytesCompilesFor<span<const int, 9>>);
1031+
static_assert(!AsWritableBytesCompilesFor<span<const int, 10>>);
1032+
static_assert(!AsWritableBytesCompilesFor<span<volatile int>>);
1033+
static_assert(!AsWritableBytesCompilesFor<span<volatile int, 11>>);
1034+
static_assert(!AsWritableBytesCompilesFor<span<const volatile int>>);
1035+
static_assert(!AsWritableBytesCompilesFor<span<const volatile int, 12>>);
10231036

10241037
auto sp_1 = as_bytes(sp_dyn);
10251038
auto sp_2 = as_bytes(sp_nine);

0 commit comments

Comments
 (0)