std::byteswap(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’… std::byteswap(3) β€” a C++ Standard Library moment

okay bestie, so we're in the C++ Standard Library manual, section 3, and the star of the show is std::byteswap. yes that's literally it, that's the name. iconic. let's get into it ✨


🌸 Synopsis

so this lil guy lives in the header <bit>, and it's been around since C++23:

template< class T >
constexpr T byteswap( T n ) noexcept;

what it does: reverses the bytes in the integer value n. that's the whole vibe. πŸ¦‹

and listen β€” std::byteswap only participates in overload resolution if T satisfies integral, i.e. T is an integer type. and heads up: the program is ill-formed if T has padding bits. no cap, that's a hard no. πŸ’€


πŸŽ€ Parameters

  • n β€” integer value (that's it, that's the parameter)

πŸ’– Return value

an integer value of type T whose object representation comprises the bytes of that of n in reversed order. so like... the same bytes, just walking backwards. main character energy honestly. 🫢


✨ Notes

this function is useful for processing data of different endianness. (endianness discourse, we love to see it 🌈)

feature-test macro time, bestie:

  • __cpp_lib_byteswap β€” value 202110L, std (C++23), feature std::byteswap

🧚 Possible implementation

here's one way it could look β€” not the law, just a vibe:

template<std::integral T>
constexpr T byteswap(T value) noexcept
{
    static_assert(std::has_unique_object_representations_v<T>,
                  "T may not have padding bits");
    auto value_representation = std::bit_cast<std::array<std::byte, sizeof(T)>>(value);
    std::ranges::reverse(value_representation);
    return std::bit_cast<T>(value_representation);
}

πŸ”₯ Example

go ahead and run this, i'll wait πŸ’…

#include <bit>
#include <concepts>
#include <cstdint>
#include <iomanip>
#include <iostream>

template<std::integral T>
void dump(T v, char term = '\n')
{
    std::cout << std::hex << std::uppercase << std::setfill('0')
              << std::setw(sizeof(T) * 2) << v << " : ";
    for (std::size_t i{}; i != sizeof(T); ++i, v >>= 8)
        std::cout << std::setw(2) << static_cast<unsigned>(T(0xFF) & v) << ' ';
    std::cout << std::dec << term;
}

int main()
{
    static_assert(std::byteswap('a') == 'a');

    std::cout << "byteswap for U16:\n";
    constexpr auto x = std::uint16_t(0xCAFE);
    dump(x);
    dump(std::byteswap(x));

    std::cout << "\nbyteswap for U32:\n";
    constexpr auto y = std::uint32_t(0xDEADBEEFu);
    dump(y);
    dump(std::byteswap(y));

    std::cout << "\nbyteswap for U64:\n";
    constexpr auto z = std::uint64_t{0x0123456789ABCDEFull};
    dump(z);
    dump(std::byteswap(z));
}

πŸ“ Possible output

byteswap for U16:
CAFE : FE CA
FECA : CA FE

byteswap for U32:
DEADBEEF : EF BE AD DE
EFBEADDE : DE AD BE EF

byteswap for U64:
0123456789ABCDEF : EF CD AB 89 67 45 23 01
EFCDAB8967452301 : 01 23 45 67 89 AB CD EF

look at those bytes flipping around. she ate and left no crumbs πŸ‘‘


πŸ‘‘ See also

  • endian β€” indicates the endianness of scalar types (C++20) (enum)
  • rotl β€” computes the result of bitwise left-rotation (C++20) (function template)
  • rotr β€” computes the result of bitwise right-rotation (C++20) (function template)

ok that's the whole page, go byte-swap something responsibly πŸ¦‹

πŸ’œ and that's a wrap! brought to you by http://cppreference.com, dated 2024.06.10 β€” this was std::byteswap(3), mwah πŸ’…βœ¨

πŸ“¦ where this page comes from