Unit Conversion and Dimensional Analysis Library 3.6.1
A compile-time, header-only C++23 dimensional-analysis library
Loading...
Searching...
No Matches
serialization.h File Reference

self-describing binary serialization of quantities More...

#include <array>
#include <cmath>
#include <compare>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <expected>
#include <functional>
#include <istream>
#include <iterator>
#include <limits>
#include <memory>
#include <ostream>
#include <span>
#include <stdexcept>
#include <string>
#include <string_view>
#include <tuple>
#include <units/core.h>
#include <utility>
#include <vector>
Include dependency graph for serialization.h:

Go to the source code of this file.

Classes

struct  units::dimension_term
 one base-dimension term of a signature: which base dimension (by name-hash), and its rational exponent More...
struct  units::unit_identity
 the runtime identity of a quantity's dimension — the set of nonzero base-dimension terms More...
struct  units::detail::signature< Unit >
 the compile-time signature of a unit as a fixed-size, sorted array of terms More...
class  units::any_unit
struct  std::hash< units::any_unit >
 hashes an erased quantity by its dimension signature and SI-base magnitude, so any_unit is usable as an unordered-container key. More...

Namespaces

namespace  units
 Unit Conversion Library namespace.

Typedefs

using units::detail::builtin_dimensions
 The library's known dimensions, offered to visit as the default candidate set so a stream of any built-in dimension resolves without the caller naming it.
template<class Dim>
using units::detail::canonical_unit_t = unit<conversion_factor<std::ratio<1>, Dim>, double>
 the canonical SI base unit of a dimension (ratio 1, no pi, no translation)

Enumerations

enum class  units::deserialize_error {
  units::truncated , units::bad_version , units::dimension_mismatch , units::unknown_base_dimension ,
  units::lossy_target
}
 the reasons a deserialize can fail More...
enum class  units::detail::value_kind : std::uint8_t { ivarint = 0 , f32 = 1 , f64 = 2 }
 header byte layout: [ valueKind:2 | fracExp:1 | reserved:5 ] More...

Functions

constexpr std::uint64_t units::detail::name_hash (std::string_view name) noexcept
 FNV-1a 64-bit hash of a base dimension's name.
void units::detail::put_uvarint (std::vector< std::byte > &out, std::uint64_t value)
 appends an unsigned integer to a byte buffer as an LEB128 varint
void units::detail::put_svarint (std::vector< std::byte > &out, std::int64_t value)
 appends a signed integer to a byte buffer as a zig-zag LEB128 varint
bool units::detail::get_uvarint (const std::byte *&cursor, const std::byte *end, std::uint64_t &value)
 reads an LEB128 unsigned varint from a byte cursor
bool units::detail::get_svarint (const std::byte *&cursor, const std::byte *end, std::int64_t &value)
 reads a zig-zag LEB128 signed varint from a byte cursor
template<class DimensionList>
consteval std::size_t units::detail::dimension_arity ()
 the number of base-dimension terms in a dimension_t<...> list
template<class DimensionList, std::size_t N>
consteval void units::detail::fill_terms (std::array< dimension_term, N > &out, std::size_t at)
 writes a term per base dimension of a dimension_t<...> list into a fixed span
template<UnitType Unit>
unit_identity units::detail::identity_of ()
 the dimension signature of a unit type, as the runtime (vector-backed) identity
std::vector< std::byte > units::detail::encode (const unit_identity &identity, double base)
 encodes a dimension identity and SI-base magnitude to the self-describing byte stream
std::ostream & units::operator<< (std::ostream &os, const any_unit &value)
 writes an erased quantity's self-describing BINARY bytes to a stream
template<class Target>
Target units::unit_cast (const any_unit &value)
 explicit cast from an erased any_unit to a concrete unit, throwing on a dimension mismatch
template<class Unit>
any_unit units::serialize (const Unit &quantity)
 serializes a quantity to a self-describing, erased any_unit
std::expected< any_unit, deserialize_errorunits::deserialize (std::span< const std::byte > bytes)
 decodes a self-describing byte stream into an erased quantity
template<class Unit>
std::expected< Unit, deserialize_errorunits::deserialize (std::span< const std::byte > bytes)
 decodes a self-describing byte stream directly into a known unit type (fully static)
std::expected< any_unit, deserialize_errorunits::deserialize (std::istream &is)
 reads and decodes one self-describing erased quantity from a binary stream, in a single expression
std::istream & units::operator>> (std::istream &is, any_unit &value)
 reads one self-describing erased quantity from a binary stream (classic stream-extraction form)
template<class Unit>
std::expected< Unit, deserialize_errorunits::deserialize (std::istream &is)
 reads and decodes one record from a binary stream directly into a known unit type

Variables

constexpr std::uint8_t units::detail::serialization_version = 1

Detailed Description

self-describing binary serialization of quantities

Typedef Documentation

◆ builtin_dimensions

Initial value:
std::tuple<dimension::length, dimension::mass, dimension::time, dimension::current, dimension::temperature, dimension::substance, dimension::luminous_intensity,
make_dimension< length, std::ratio< 2 >, time, std::ratio<-2 > > radioactivity
< Represents an SI derived unit of luminance
Definition core.h:1359
dimension_multiply< pressure, time > dynamic_viscosity
< Represents an SI derived unit of density
Definition core.h:1375
dimension_divide< mass, volume > density
< Represents an SI derived unit of torque
Definition core.h:1374
make_dimension< luminous_intensity, std::ratio< 1 >, length, std::ratio<-2 > > luminance
< Represents an SI derived unit of illuminance
Definition core.h:1358
dimension_pow< angle, std::ratio< 2 > > solid_angle
< Represents a quantity of angle
Definition core.h:1337
dimension_divide< current, voltage > conductance
< Represents an SI derived unit of impedance
Definition core.h:1353
make_dimension< power, std::ratio< 1 >, length, std::ratio<-1 > > spectral_flux
< Represents an SI derived unit of spectral intensity
Definition core.h:1367
dimension_divide< mass, substance > substance_mass
< Represents an SI derived unit of radioactivity
Definition core.h:1360
make_dimension< radiant_intensity, std::ratio< 1 >, area, std::ratio<-1 > > radiance
< Represents an SI derived unit of radiant intensity
Definition core.h:1364
dimension_divide< voltage, current > impedance
< Represents an SI derived unit of capacitance
Definition core.h:1352
dimension_divide< substance, mass > substance_concentration
< Represents an SI derived unit of substance mass
Definition core.h:1361
dimension_divide< energy, time > power
< Represents an SI derived unit of energy
Definition core.h:1349
dimension_multiply< impedance, time > inductance
< Represents an SI derived unit of magnetic flux
Definition core.h:1355
dimension_pow< length, std::ratio< 3 > > volume
< Represents an SI derived unit of area
Definition core.h:1344
dimension_divide< area, time > kinematic_viscosity
< Represents an SI derived unit of dynamic (absolute) viscosity
Definition core.h:1376
make_dimension< angle_tag > angle
< Represents a quantity with no dimension.
Definition core.h:1334
dimension_divide< velocity, time > acceleration
< Represents an SI derived unit of angular velocity
Definition core.h:1341
dimension_multiply< mass, acceleration > force
< Represents an SI derived unit of acceleration
Definition core.h:1342
make_dimension< power, std::ratio< 1 >, solid_angle, std::ratio<-1 > > radiant_intensity
< Represents an SI derived unit of magnetic field strength
Definition core.h:1363
dimension_divide< force, area > pressure
< Represents an SI derived unit of volumetric flow rate
Definition core.h:1346
make_dimension< radiant_intensity, std::ratio< 1 >, length, std::ratio<-1 > > spectral_intensity
< Represents an SI derived unit of irradiance
Definition core.h:1366
dimension_divide< power, current > voltage
< Represents an SI derived unit of power
Definition core.h:1350
dimension_divide< charge, voltage > capacitance
< Represents an SI derived unit of voltage
Definition core.h:1351
dimension_multiply< time, current > charge
< Represents an SI derived unit of pressure
Definition core.h:1347
make_dimension< mass, std::ratio< 1 >, time, std::ratio<-2 >, current, std::ratio<-1 > > magnetic_field_strength
< Represents an SI derived unit of substance concentration
Definition core.h:1362
dimension_divide< energy, current > magnetic_flux
< Represents an SI derived unit of conductance
Definition core.h:1354
dimension_multiply< force, length > energy
< Represents an SI derived unit of charge
Definition core.h:1348
make_dimension< power, std::ratio< 1 >, volume, std::ratio<-1 > > spectral_irradiance
< Represents an SI derived unit of spectral intensity
Definition core.h:1369
make_dimension< volume, std::ratio<-1 > > concentration
< Represents an SI derived unit of energy density
Definition core.h:1378
make_dimension< data_tag > data
< Represents a unit of concentration
Definition core.h:1379
dimension_multiply< solid_angle, luminous_intensity > luminous_flux
< Represents an SI derived unit of inductance
Definition core.h:1356
dimension_divide< length, time > velocity
< Represents an SI derived unit of frequency
Definition core.h:1339
dimension_divide< data, time > data_transfer_rate
< Represents a unit of data size
Definition core.h:1380
dimension_pow< length, std::ratio< 2 > > area
< Represents an SI derived unit of force
Definition core.h:1343
make_dimension< radiant_intensity, std::ratio< 1 >, volume, std::ratio<-1 > > spectral_radiance
< Represents an SI derived unit of spectral flux
Definition core.h:1368
make_dimension< luminous_flux, std::ratio< 1 >, length, std::ratio<-2 > > illuminance
< Represents an SI derived unit of luminous flux
Definition core.h:1357
make_dimension< time, std::ratio<-1 > > frequency
< Represents an SI derived unit of solid angle
Definition core.h:1338
make_dimension< power, std::ratio< 1 >, area, std::ratio<-1 > > irradiance
< Represents an SI derived unit of radiance
Definition core.h:1365
dimension_divide< angle, time > angular_velocity
< Represents an SI derived unit of velocity
Definition core.h:1340
make_dimension< energy, std::ratio< 1 >, volume, std::ratio<-1 > > energy_density
< Represents an SI derived unit of kinematic viscosity
Definition core.h:1377
make_dimension< length, std::ratio< 1 >, time, std::ratio<-3 > > jerk
< Represents an SI derived unit of spectral irradiance
Definition core.h:1372
dimension_divide< volume, time > volume_flow_rate
< Represents an SI derived unit of volume
Definition core.h:1345
dimension_multiply< force, length > torque
< Represents an SI derived unit of jerk
Definition core.h:1373

The library's known dimensions, offered to visit as the default candidate set so a stream of any built-in dimension resolves without the caller naming it.

This is NOT the wire vocabulary: the stream keys each base dimension by a hash of its name STRING, so a dimension the library has never seen — including a user-defined make_dimension<my_tag> — still serializes and round-trips. visit cannot resolve a user-defined dimension unless the caller lists it (visit<my_dimension>(f)), because C++ cannot materialize a type from the runtime hash — the runtime→type wall. The set is otherwise open by design.

Enumeration Type Documentation

◆ value_kind

enum class units::detail::value_kind : std::uint8_t
strong

header byte layout: [ valueKind:2 | fracExp:1 | reserved:5 ]

Enumerator
ivarint 

value is an integer in SI base, zig-zag varint

f32 

value is an exact 32-bit float

f64 

value is a 64-bit double

Function Documentation

◆ dimension_arity()

template<class DimensionList>
std::size_t units::detail::dimension_arity ( )
consteval

the number of base-dimension terms in a dimension_t<...> list

Template Parameters
DimensionLista dimension_t<...> specialization
Returns
the term count

◆ encode()

std::vector< std::byte > units::detail::encode ( const unit_identity & identity,
double base )
inline

encodes a dimension identity and SI-base magnitude to the self-describing byte stream

The single source of truth for the wire format, used by both serialize (from a compile-time signature) and any_unit (from its decoded runtime identity), so a value and its round-tripped form encode byte-identically. The value encoding is chosen from base alone (tersest exact: integer varint, else exact 32-bit float, else 64-bit double), so it does not depend on the source unit's underlying type.

Parameters
[in]identitythe ordered base-dimension terms (sorted by hash)
[in]basethe magnitude in SI canonical base
Returns
the encoded bytes

◆ fill_terms()

template<class DimensionList, std::size_t N>
void units::detail::fill_terms ( std::array< dimension_term, N > & out,
std::size_t at )
consteval

writes a term per base dimension of a dimension_t<...> list into a fixed span

Each term is keyed by a hash of the base dimension's name, so ANY base dimension — built-in or user-defined make_dimension<my_tag> — is captured; there is no fixed vocabulary.

Template Parameters
DimensionLista dimension_t<...> specialization
Nthe fixed capacity of the destination array
Parameters
[out]outthe destination array
[in]atthe index to write the front term at

◆ get_svarint()

bool units::detail::get_svarint ( const std::byte *& cursor,
const std::byte * end,
std::int64_t & value )
inline

reads a zig-zag LEB128 signed varint from a byte cursor

Parameters
[in,out]cursorpointer into the buffer; advanced past the value on success
[in]endone-past-the-end of the buffer
[out]valuedecoded value
Returns
true on success, false if the buffer was truncated

◆ get_uvarint()

bool units::detail::get_uvarint ( const std::byte *& cursor,
const std::byte * end,
std::uint64_t & value )
inline

reads an LEB128 unsigned varint from a byte cursor

Parameters
[in,out]cursorpointer into the buffer; advanced past the value on success
[in]endone-past-the-end of the buffer
[out]valuedecoded value
Returns
true on success, false if the buffer was truncated

◆ identity_of()

template<UnitType Unit>
unit_identity units::detail::identity_of ( )

the dimension signature of a unit type, as the runtime (vector-backed) identity

Materializes the compile-time fixed-array signature into a unit_identity for runtime compare.

Template Parameters
Unita UnitType
Returns
the unit_identity (nonzero base-dimension terms, sorted by hash)

◆ name_hash()

std::uint64_t units::detail::name_hash ( std::string_view name)
constexprnoexcept

FNV-1a 64-bit hash of a base dimension's name.

Hashing the library-controlled name string (not a compiler-generated type name) is portable across compilers and versions, is a fixed 8 bytes regardless of name length, and needs no central table — any dimension name, built-in or user-defined, hashes to a stable wire key.

Parameters
[in]namethe dimension name
Returns
the 64-bit hash

◆ put_svarint()

void units::detail::put_svarint ( std::vector< std::byte > & out,
std::int64_t value )
inline

appends a signed integer to a byte buffer as a zig-zag LEB128 varint

Parameters
[out]outbuffer to append to
[in]valuevalue to encode

◆ put_uvarint()

void units::detail::put_uvarint ( std::vector< std::byte > & out,
std::uint64_t value )
inline

appends an unsigned integer to a byte buffer as an LEB128 varint

Parameters
[out]outbuffer to append to
[in]valuevalue to encode