Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion doc/modules/ROOT/pages/api_reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,12 @@ https://www.boost.org/LICENSE_1_0.txt

| xref:byte_conversions.adoc[`from_le_bytes`]
| Reconstructs a safe integer from a little-endian byte array

| xref:byte_conversions.adoc[`to_ne_bytes`]
| Converts a safe integer to a native-endian byte array

| xref:byte_conversions.adoc[`from_ne_bytes`]
| Reconstructs a safe integer from a native-endian byte array
|===

=== Arithmetic
Expand Down Expand Up @@ -296,7 +302,7 @@ This header is not included in the convenience header since it requires external
| Bounded unsigned integer type (`bounded_uint<Min, Max>`)

| `<boost/safe_numbers/byte_conversions.hpp>`
| Byte order conversion functions (`to_be`, `from_be`, `to_le`, `from_le`, `to_be_bytes`, `from_be_bytes`, `to_le_bytes`, `from_le_bytes`)
| Byte order conversion functions (`to_be`, `from_be`, `to_le`, `from_le`, `to_be_bytes`, `from_be_bytes`, `to_le_bytes`, `from_le_bytes`, `to_ne_bytes`, `from_ne_bytes`)

| `<boost/safe_numbers/verified_integers.hpp>`
| Verified integer types (`verified_u8`, `verified_u16`, `verified_u32`, `verified_u64`, `verified_u128`, `verified_bounded_integer<Min, Max>`)
Expand Down
190 changes: 190 additions & 0 deletions doc/modules/ROOT/pages/byte_conversions.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,12 @@ constexpr auto bytes = to_be_bytes(verified_u32{u32{0x01020304}});
Reconstructs a safe integer value from a big-endian byte array.
The bytes are reinterpreted as the underlying type and then converted from big-endian to native byte order using `from_be`.

=== Runtime Overload

[source,c++]
----
template <non_bounded_integral_library_type T, std::size_t N>
requires (!is_verified_type_v<T>)
constexpr auto from_be_bytes(const std::span<const std::byte, N> bytes) -> T;
----

Expand Down Expand Up @@ -366,6 +369,33 @@ auto reconstructed = from_be_bytes<u32>(std::span<const std::byte, 4>{to_be_byte
// reconstructed == original
----

=== Verified Overload

[source,c++]
----
template <verified_type T, std::size_t N>
consteval auto from_be_bytes(const std::span<const std::byte, N> bytes) -> T;
----

Compile-time only overload for verified types.
The span must have a fixed extent matching `sizeof(T)`; a mismatched extent produces a `static_assert` failure.

==== Example

[source,c++]
----
using namespace boost::safe_numbers;

constexpr std::array<std::byte, 4> bytes {std::byte{0x01}, std::byte{0x02}, std::byte{0x03}, std::byte{0x04}};
constexpr auto val = from_be_bytes<verified_u32>(std::span<const std::byte, 4>{bytes});
// val == verified_u32{u32{0x01020304}}

// Round-trip
constexpr auto original = verified_u32{u32{0xDEADBEEF}};
constexpr auto reconstructed = from_be_bytes<verified_u32>(std::span<const std::byte, 4>{to_be_bytes(original)});
static_assert(reconstructed == original);
----

== to_le_bytes

Converts a safe integer value to a little-endian byte array.
Expand Down Expand Up @@ -427,9 +457,12 @@ constexpr auto bytes = to_le_bytes(verified_u32{u32{0x01020304}});
Reconstructs a safe integer value from a little-endian byte array.
The bytes are reinterpreted as the underlying type and then converted from little-endian to native byte order using `from_le`.

=== Runtime Overload

[source,c++]
----
template <non_bounded_integral_library_type T, std::size_t N>
requires (!is_verified_type_v<T>)
constexpr auto from_le_bytes(const std::span<const std::byte, N> bytes) -> T;
----

Expand Down Expand Up @@ -469,3 +502,160 @@ auto original = u32{0xDEADBEEF};
auto reconstructed = from_le_bytes<u32>(std::span<const std::byte, 4>{to_le_bytes(original)});
// reconstructed == original
----

=== Verified Overload

[source,c++]
----
template <verified_type T, std::size_t N>
consteval auto from_le_bytes(const std::span<const std::byte, N> bytes) -> T;
----

Compile-time only overload for verified types.
The span must have a fixed extent matching `sizeof(T)`; a mismatched extent produces a `static_assert` failure.

==== Example

[source,c++]
----
using namespace boost::safe_numbers;

constexpr std::array<std::byte, 4> bytes {std::byte{0x04}, std::byte{0x03}, std::byte{0x02}, std::byte{0x01}};
constexpr auto val = from_le_bytes<verified_u32>(std::span<const std::byte, 4>{bytes});
// val == verified_u32{u32{0x01020304}}

// Round-trip
constexpr auto original = verified_u32{u32{0xDEADBEEF}};
constexpr auto reconstructed = from_le_bytes<verified_u32>(std::span<const std::byte, 4>{to_le_bytes(original)});
static_assert(reconstructed == original);
----

== to_ne_bytes

Converts a safe integer value to a native-endian byte array.
Delegates to `to_le_bytes` on little-endian platforms and `to_be_bytes` on big-endian platforms.

The result is equivalent to `std::bit_cast<std::array<std::byte, sizeof(T)>>(value)` -- i.e., the raw in-memory representation.

=== Runtime Overload

[source,c++]
----
template <non_bounded_integral_library_type T>
requires (!is_verified_type_v<T>)
constexpr auto to_ne_bytes(const T value) noexcept -> std::array<std::byte, sizeof(T)>;
----

==== Parameters

* `value` -- The value to convert.

==== Return Value

A `std::array<std::byte, sizeof(T)>` containing the value's bytes in native byte order.

==== Complexity

O(1).

==== Example

[source,c++]
----
using namespace boost::safe_numbers;

auto bytes = to_ne_bytes(u32{0x01020304});
// On little-endian: bytes == {0x04, 0x03, 0x02, 0x01}
// On big-endian: bytes == {0x01, 0x02, 0x03, 0x04}
----

=== Verified Overload

[source,c++]
----
template <non_bounded_integral_library_type T>
consteval auto to_ne_bytes(const verified_type_basis<T> value) noexcept -> std::array<std::byte, sizeof(T)>;
----

Compile-time only overload for verified types.

==== Example

[source,c++]
----
using namespace boost::safe_numbers;

constexpr auto bytes = to_ne_bytes(verified_u32{u32{0x01020304}});
----

== from_ne_bytes

Reconstructs a safe integer value from a native-endian byte array.
Delegates to `from_le_bytes` on little-endian platforms and `from_be_bytes` on big-endian platforms.

=== Runtime Overload

[source,c++]
----
template <non_bounded_integral_library_type T, std::size_t N>
requires (!is_verified_type_v<T>)
constexpr auto from_ne_bytes(const std::span<const std::byte, N> bytes) -> T;
----

==== Parameters

* `bytes` -- A span of bytes in native byte order. May have a fixed extent or `std::dynamic_extent`.

==== Return Value

The reconstructed safe integer value.

==== Extent Matching

The function validates that the number of input bytes matches `sizeof(T)`:

* **Fixed extent matches `sizeof(T)`**: Compiles and executes normally.
* **Fixed extent does not match `sizeof(T)`**: Produces a `static_assert` failure at compile time.
* **Dynamic extent**: Checks at runtime and throws `std::domain_error` if the sizes do not match.

==== Complexity

O(1).

==== Example

[source,c++]
----
using namespace boost::safe_numbers;

// Round-trip
auto original = u32{0xDEADBEEF};
auto reconstructed = from_ne_bytes<u32>(std::span<const std::byte, 4>{to_ne_bytes(original)});
// reconstructed == original
----

=== Verified Overload

[source,c++]
----
template <verified_type T, std::size_t N>
consteval auto from_ne_bytes(const std::span<const std::byte, N> bytes) -> T;
----

Compile-time only overload for verified types.
The span must have a fixed extent matching `sizeof(T)`; a mismatched extent produces a `static_assert` failure.

==== Example

[source,c++]
----
using namespace boost::safe_numbers;

constexpr auto original = verified_u32{u32{0xDEADBEEF}};
constexpr auto reconstructed = from_ne_bytes<verified_u32>(std::span<const std::byte, 4>{to_ne_bytes(original)});
static_assert(reconstructed == original);
----

== Example

For a complete example demonstrating all byte conversion functions, see xref:examples.adoc#examples_byte_conversions[Byte Conversions].
45 changes: 45 additions & 0 deletions doc/modules/ROOT/pages/examples.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,51 @@ shr<checked>(u32(8), 1) = 4
----
====

[#examples_byte_conversions]
== Byte Conversions

The library provides functions for converting safe integers to and from byte arrays in big-endian, little-endian, or native byte order.
Verified types support the same conversions at compile time via `consteval` overloads.

.This https://github.com/boostorg/safe_numbers/blob/develop/examples/byte_conversions.cpp[example] demonstrates byte conversion functions with all safe integer types.
====
[source, c++]
----
include::example$byte_conversions.cpp[]
----

Output:
----
=== to_be_bytes ===
u32(0x01020304) -> BE bytes: 01 02 03 04
u16(0xABCD) -> BE bytes: ab cd

=== from_be_bytes ===
BE bytes {01,02,03,04} -> u32: 0x1020304

=== to_le_bytes ===
u32(0x01020304) -> LE bytes: 04 03 02 01
u64(0x01..08) -> LE bytes: 08 07 06 05 04 03 02 01

=== from_le_bytes ===
LE bytes {04,03,02,01} -> u32: 0x1020304

=== to_ne_bytes / from_ne_bytes (native endian) ===
u32(0xDEADBEEF) -> NE bytes: ef be ad de
Round-trip: -> u32: 0xdeadbeef

=== u8 round-trip ===
u8(0x42) -> BE: 42
u8(0x42) -> LE: 42

=== Verified types (compile-time) ===
verified_u32 to_be_bytes: 01 02 03 04
verified_u32 BE round-trip: 0xdeadbeef
verified_u64 LE round-trip: 0x123456789abcdef
verified_u32 NE round-trip: 0xcafebabe
----
====

[#examples_verified_construction]
== Verified Types: Construction and Runtime Usage

Expand Down
Loading