Implement the accepted resolution of LWG 4243.
libstdc++-v3/ChangeLog:
* include/std/span (as_bytes, as_writable_bytes): Add
constraints to disallow volatile elements, as per LWG 4243.
* testsuite/23_containers/span/lwg4243.cc: New test.
---
v2: fix the test - I had the fixes added to the index with 'git add' but
not committed. This is what I actually tested!
Tested x86_64-linux.
libstdc++-v3/include/std/span | 5 ++-
.../testsuite/23_containers/span/lwg4243.cc | 31 +++++++++++++++++++
2 files changed, 35 insertions(+), 1 deletion(-)
create mode 100644 libstdc++-v3/testsuite/23_containers/span/lwg4243.cc
diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span
index 8f525d009ff5..a2f338449c8a 100644
--- a/libstdc++-v3/include/std/span
+++ b/libstdc++-v3/include/std/span
@@ -517,7 +517,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
span(_Range &&)
-> span<remove_reference_t<ranges::range_reference_t<_Range&>>>;
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 4243. as_bytes/as_writable_bytes is broken with span<volatile T>
template<typename _Type, size_t _Extent>
+ requires (!is_volatile_v<_Type>)
[[nodiscard]]
inline
span<const byte, _Extent == dynamic_extent
@@ -532,7 +535,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _Type, size_t _Extent>
- requires (!is_const_v<_Type>)
+ requires (!is_const_v<_Type> && !is_volatile_v<_Type>)
inline
span<byte, _Extent == dynamic_extent
? dynamic_extent : _Extent * sizeof(_Type)>
diff --git a/libstdc++-v3/testsuite/23_containers/span/lwg4243.cc
b/libstdc++-v3/testsuite/23_containers/span/lwg4243.cc
new file mode 100644
index 000000000000..26bb53d8739b
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/lwg4243.cc
@@ -0,0 +1,31 @@
+// { dg-do compile { target c++20 } }
+
+// LWG 4243. as_bytes/as_writable_bytes is broken with span<volatile T>
+
+#include <span>
+
+template<typename ElementType, std::size_t Extent = std::dynamic_extent>
+concept can_call_as_bytes
+ = requires (std::span<ElementType, Extent> s) { std::as_bytes(s); };
+
+static_assert( can_call_as_bytes<int> );
+static_assert( can_call_as_bytes<int, 10> );
+static_assert( can_call_as_bytes<const int> );
+static_assert( can_call_as_bytes<const int, 10> );
+static_assert( ! can_call_as_bytes<volatile int> );
+static_assert( ! can_call_as_bytes<volatile int, 10> );
+static_assert( ! can_call_as_bytes<const volatile int> );
+static_assert( ! can_call_as_bytes<const volatile int, 10> );
+
+template<typename ElementType, std::size_t Extent = std::dynamic_extent>
+concept can_call_as_writable_bytes
+ = requires (std::span<ElementType, Extent> s) { std::as_writable_bytes(s); };
+
+static_assert( can_call_as_writable_bytes<int> );
+static_assert( can_call_as_writable_bytes<int, 10> );
+static_assert( ! can_call_as_writable_bytes<const int> );
+static_assert( ! can_call_as_writable_bytes<const int, 10> );
+static_assert( ! can_call_as_writable_bytes<volatile int> );
+static_assert( ! can_call_as_writable_bytes<volatile int, 10> );
+static_assert( ! can_call_as_writable_bytes<const volatile int> );
+static_assert( ! can_call_as_writable_bytes<const volatile int, 10> );
--
2.53.0