Home > Mobile >  How to create a `span<std::byte>` from a single generic object?
How to create a `span<std::byte>` from a single generic object?

Time:05-06

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) };
}
  • Related