I have a parameter of type const T&
and want to turn it into std::span<const std::byte>
or whatever the magic type that std::as_bytes()
spits out is.
Ranges have a number of constructors, mostly aimed at containers, arrays, etc. But I can't seem to turn a single object into such a span. I feel like this is not an unreasonable thing to do.
EDIT: As an example, what doesn't compile:
const std::span<const std::byte> my_span(std::ranges::single_view{ object });
CodePudding user response:
Pointer to individual object can be treated the same way as pointer to an array of single object. You can create a span like this:
const T& t = value();
auto s = std::span<const T, 1>{std::addressof(t), 1};
You can then use std::as_bytes
:
auto bytes = std::as_bytes(std::span<const T, 1>{std::addressof(t), 1});
Helper functions would probably be appropriate:
template<class T>
std::span<T, 1>
singular_span(T& t)
{
return std::span<T, 1>{std::addressof(t), 1};
}
template<class T>
auto
singular_bytes(T& t)
{
return std::as_bytes(singular_span(t));
}
CodePudding user response:
You can reinterpret_cast<std::byte *>
a pointer to any object, which gets you the first argument to the span, and the size of your type gives you the second.
template <typename T>
std::span<const std::byte, sizeof(T)> bytes_view(T & t) {
return std::span<const std::byte, sizeof(T)> { reinterpret_cast<const std::byte *>(std::addressof(t)), sizeof(T) };
}
template <typename T>
requires (!std::is_const_v<T>)
std::span<std::byte, sizeof(T)> mutable_bytes_view(T & t) {
return std::span<std::byte, sizeof(T)> { reinterpret_cast<std::byte *>(std::addressof(t)), sizeof(T) };
}