37#ifndef units_serialization_h_
38#define units_serialization_h_
73 using builtin_dimensions = std::tuple<dimension::length, dimension::mass, dimension::time, dimension::current, dimension::temperature, dimension::substance, dimension::luminous_intensity,
91 constexpr std::uint64_t
name_hash(std::string_view name)
noexcept
93 std::uint64_t
h = 1469598103934665603ULL;
94 for (
const char c :
name)
96 h ^=
static_cast<std::uint8_t
>(
c);
97 h *= 1099511628211ULL;
133 inline void put_uvarint(std::vector<std::byte>& out, std::uint64_t value)
137 std::uint8_t
byte = value & 0x7F;
141 out.push_back(std::byte{
byte});
142 }
while (value != 0);
152 inline void put_svarint(std::vector<std::byte>& out, std::int64_t value)
154 put_uvarint(out, (
static_cast<std::uint64_t
>(value) << 1) ^
static_cast<std::uint64_t
>(value >> 63));
166 inline bool get_uvarint(
const std::byte*& cursor,
const std::byte* end, std::uint64_t& value)
169 unsigned int shift = 0;
170 while (cursor != end)
172 const auto byte = std::to_integer<std::uint8_t>(*cursor++);
173 value |=
static_cast<std::uint64_t
>(
byte & 0x7F) << shift;
174 if ((
byte & 0x80) == 0)
192 inline bool get_svarint(
const std::byte*& cursor,
const std::byte* end, std::int64_t& value)
197 value =
static_cast<std::int64_t
>((raw >> 1) ^ (~(raw & 1) + 1));
221 std::vector<dimension_term> terms;
232 if (terms.size() != other.terms.size())
234 for (std::size_t i = 0; i < terms.size(); ++i)
235 if (terms[i].hash != other.terms[i].hash || terms[i].num != other.terms[i].num || terms[i].den != other.terms[i].den)
250 template<
class DimensionList>
253 if constexpr (DimensionList::empty)
270 template<
class DimensionList, std::
size_t N>
271 consteval void fill_terms(std::array<dimension_term, N>& out, std::size_t at)
273 if constexpr (!DimensionList::empty)
275 using front_dim =
typename DimensionList::front;
276 using tag =
typename front_dim::dimension;
277 using exponent =
typename front_dim::exponent;
285 template<UnitType Unit>
291 static consteval std::array<dimension_term, arity> compute()
293 std::array<dimension_term, arity> terms{};
296 for (std::size_t i = 1; i < arity; ++i)
300 while (j > 0 && terms[j - 1].hash > key.
hash)
302 terms[j] = terms[j - 1];
310 static constexpr std::array<dimension_term, arity> value = compute();
321 template<UnitType Unit>
325 id.terms.assign(signature<Unit>::value.begin(), signature<Unit>::value.end());
340 inline constexpr std::uint8_t serialization_version = 1;
366 if (
base == std::floor(
base) && std::abs(
base) < 9.0e15)
368 else if (
static_cast<double>(
static_cast<float>(
base)) ==
base)
374 bool fracExp =
false;
375 for (
const auto& term : identity.terms)
379 std::vector<std::byte> out;
380 out.push_back(std::byte{serialization_version});
381 const std::uint8_t header =
static_cast<std::uint8_t
>(
static_cast<std::uint8_t
>(
kind) | (fracExp ? 0x04 : 0x00));
382 out.push_back(std::byte{header});
384 for (
const auto& term : identity.terms)
387 for (
unsigned int i = 0; i < 8; ++i)
388 out.push_back(std::byte{static_cast<std::uint8_t>(term.hash >> (8 * i))});
399 const float f =
static_cast<float>(
base);
401 std::memcpy(&bits, &f,
sizeof(bits));
402 for (
unsigned int i = 0; i < 4; ++i)
403 out.push_back(std::byte{static_cast<std::uint8_t>(bits >> (8 * i))});
409 std::memcpy(&bits, &
base,
sizeof(bits));
410 for (
unsigned int i = 0; i < 8; ++i)
411 out.push_back(std::byte{static_cast<std::uint8_t>(bits >> (8 * i))});
437 : m_identity(
std::move(id)),
439 m_bytes(detail::encode(m_identity, base))
453 m_bytes(detail::encode(m_identity, 0.0))
464 template<
class Dimension>
465 [[nodiscard]]
bool is() const noexcept
504 [[nodiscard]] std::span<const std::byte>
bytes() const noexcept
517 [[nodiscard]]
operator std::span<const std::byte>() const noexcept
531 [[nodiscard]]
const char*
data() const noexcept
533 return reinterpret_cast<const char*
>(m_bytes.data());
542 [[nodiscard]] std::size_t
size() const noexcept
544 return m_bytes.size();
566 visit([&named](
const auto& quantity) { named = units::to_string(quantity); });
568 catch (
const std::runtime_error&)
587 std::string out = std::to_string(m_base);
588 if (m_identity.terms.empty())
590 out +=
" [dimensionless]";
594 for (std::size_t i = 0; i < m_identity.terms.size(); ++i)
599 std::snprintf(hex,
sizeof(hex),
"#%llx",
static_cast<unsigned long long>(m_identity.terms[i].hash));
602 out += std::to_string(m_identity.terms[i].num);
603 if (m_identity.terms[i].den != 1)
606 out += std::to_string(m_identity.terms[i].den);
632 if (!(m_identity == other.m_identity))
634 const double diff = std::abs(m_base - other.m_base);
635 return diff < std::numeric_limits<double>::epsilon() * std::abs(m_base + other.m_base) || diff < std::numeric_limits<double>::min();
647 return !(*
this == other);
663 if (!(m_identity == other.m_identity))
664 return std::partial_ordering::unordered;
666 return std::partial_ordering::equivalent;
667 return m_base <=> other.m_base;
678 [[nodiscard]] std::expected<Unit, deserialize_error>
to()
const
680 static_assert(traits::is_unit_v<Unit>,
681 "any_unit::to<T>() collapses into a unit type (e.g. meters<double>), not a bare number. To read a plain value, collapse to a unit first, then call .value() or .to<double>() on that "
684 if constexpr (traits::is_unit_v<Unit>)
689 using ConversionFactor =
typename traits::unit_traits<Unit>::conversion_factor;
691 using UnderlyingTarget =
typename traits::unit_traits<Unit>::underlying_type;
700 if constexpr (!std::is_floating_point_v<UnderlyingTarget>)
702 if (as_double != std::floor(as_double) || std::abs(as_double) >
static_cast<double>(std::numeric_limits<UnderlyingTarget>::max()))
705 return Unit(
static_cast<UnderlyingTarget
>(as_double));
723 static_assert(traits::is_unit_v<Unit>,
"any_unit::try_to<T>() collapses into a unit type (e.g. meters<double>), not a bare number.");
726 throw std::runtime_error(
"units::any_unit: dimension mismatch collapsing to the requested unit");
749 static_assert(traits::is_unit_v<Unit>,
"any_unit::assign_to(out) assigns into a unit variable (e.g. meters<double>), not a bare number. Collapse to a unit, then read its value.");
773 template<
class... Dimensions,
class Visitor>
779 if constexpr (
sizeof...(Dimensions) == 0)
780 matched = dispatch_tuple<detail::builtin_dimensions>(std::forward<Visitor>(visitor));
782 matched = dispatch_list<Dimensions...>(std::forward<Visitor>(visitor));
784 throw std::runtime_error(
"units::any_unit: no candidate dimension matched the stream");
797 template<
class Dimension,
class Visitor>
798 bool try_dispatch_one(Visitor&& visitor)
const
803 std::forward<Visitor>(visitor)(Base(m_base));
812 template<
class... Dimensions,
class Visitor>
813 bool dispatch_list(Visitor&& visitor)
const
815 bool matched =
false;
817 ((matched = matched || try_dispatch_one<Dimensions>(visitor)), ...);
823 template<
class DimTuple, std::
size_t I = 0,
class Visitor>
824 bool dispatch_tuple(Visitor&& visitor)
const
826 if constexpr (I < std::tuple_size_v<DimTuple>)
828 if (try_dispatch_one<std::tuple_element_t<I, DimTuple>>(visitor))
830 return dispatch_tuple<DimTuple, I + 1>(visitor);
835 unit_identity m_identity;
837 std::vector<std::byte> m_bytes;
851 inline std::ostream& operator<<(std::ostream& os,
const any_unit& value)
853 os.write(value.
data(),
static_cast<std::streamsize
>(value.
size()));
871 template<
class Target>
874 static_assert(traits::is_unit_v<Target>,
"units::unit_cast<T>(any_unit) casts to a unit type (e.g. meters<double>), not a bare number. Collapse to a unit, then read its value.");
875 return value.
try_to<Target>();
897 static_assert(traits::is_unit_v<Unit>,
"units::serialize requires a units quantity (e.g. meters<double>). Its argument is not a unit type; wrap the value in a unit before serializing.");
899 if constexpr (!traits::is_unit_v<Unit>)
903 constexpr auto& sig = detail::signature<Unit>::value;
908 const double base = Base(quantity).value();
912 id.terms.assign(sig.begin(), sig.end());
914 return any_unit{std::move(
id), base};
928 [[nodiscard]]
inline std::expected<any_unit, deserialize_error>
deserialize(std::span<const std::byte> bytes)
930 const std::byte* cursor = bytes.data();
931 const std::byte* end = bytes.data() + bytes.size();
935 const std::uint8_t version = std::to_integer<std::uint8_t>(*cursor++);
936 if (version != detail::serialization_version)
941 const std::uint8_t header = std::to_integer<std::uint8_t>(*cursor++);
943 const bool fracExp = (header & 0x04) != 0;
945 std::uint64_t count = 0;
950 id.terms.reserve(count);
951 for (std::uint64_t i = 0; i < count; ++i)
953 if (end - cursor < 8)
955 std::uint64_t hash = 0;
956 for (
unsigned int byteIndex = 0; byteIndex < 8; ++byteIndex)
957 hash |=
static_cast<std::uint64_t
>(std::to_integer<std::uint8_t>(*cursor++)) << (8 * byteIndex);
958 std::int64_t num = 0;
959 std::int64_t den = 1;
975 base =
static_cast<double>(v);
980 if (end - cursor < 4)
982 std::uint32_t bits = 0;
983 for (
unsigned int i = 0; i < 4; ++i)
984 bits |=
static_cast<std::uint32_t
>(std::to_integer<std::uint8_t>(*cursor++)) << (8 * i);
986 std::memcpy(&f, &bits,
sizeof(f));
987 base =
static_cast<double>(f);
992 if (end - cursor < 8)
994 std::uint64_t bits = 0;
995 for (
unsigned int i = 0; i < 8; ++i)
996 bits |=
static_cast<std::uint64_t
>(std::to_integer<std::uint8_t>(*cursor++)) << (8 * i);
997 std::memcpy(&base, &bits,
sizeof(base));
1003 return any_unit(std::move(
id), base);
1014 template<
class Unit>
1015 [[nodiscard]] std::expected<Unit, deserialize_error>
deserialize(std::span<const std::byte> bytes)
1017 static_assert(traits::is_unit_v<Unit>,
1018 "units::deserialize<T>(bytes) decodes into a unit type (e.g. deserialize<meters<double>>). The requested type is not a unit; use deserialize(bytes) for an erased any_unit.");
1021 return std::unexpected(erased.error());
1022 return erased->template to<Unit>();
1038 [[nodiscard]]
inline std::expected<any_unit, deserialize_error>
deserialize(std::istream& is)
1040 const std::istream::pos_type start = is.tellg();
1041 if (start == std::istream::pos_type(-1))
1044 const std::vector<char> buffer{std::istreambuf_iterator<char>(is), std::istreambuf_iterator<char>()};
1047 auto decoded =
deserialize(std::span<const std::byte>(
reinterpret_cast<const std::byte*
>(buffer.data()), buffer.size()));
1049 is.seekg(start +
static_cast<std::istream::off_type
>(decoded->size()));
1068 value = std::move(*decoded);
1070 is.setstate(std::ios::failbit);
1086 template<
class Unit>
1087 [[nodiscard]] std::expected<Unit, deserialize_error>
deserialize(std::istream& is)
1089 static_assert(traits::is_unit_v<Unit>,
1090 "units::deserialize<T>(stream) decodes into a unit type (e.g. deserialize<meters<double>>). The requested type is not a unit; use deserialize(stream) for an erased any_unit.");
1093 return std::unexpected(erased.error());
1094 return erased->template to<Unit>();
1110 std::size_t seed = std::hash<double>()(value.
value_in_base());
1111 const auto mix = [&seed](std::size_t h)
noexcept { seed ^= h + 0x9e3779b97f4a7c15ULL + (seed << 6) + (seed >> 2); };
1112 for (
const auto& term : value.
identity().terms)
1114 mix(std::hash<std::uint64_t>()(term.hash));
1115 mix(std::hash<std::int64_t>()(term.num));
1116 mix(std::hash<std::int64_t>()(term.den));
Definition serialization.h:424
bool assign_to(Unit &out) const
collapses into an existing unit variable, leaving it untouched on a dimension mismatch
Definition serialization.h:747
double value_in_base() const noexcept
the magnitude in SI canonical base units, for logging or routing
Definition serialization.h:476
std::expected< Unit, deserialize_error > to() const
collapses into a concrete unit, checked (the safe default)
Definition serialization.h:678
any_unit()
constructs an empty erased quantity (dimensionless, zero) — the target for stream extraction
Definition serialization.h:450
bool is() const noexcept
whether this erased quantity is of the requested dimension
Definition serialization.h:465
bool operator!=(const any_unit &other) const noexcept
whether two erased quantities differ in dimension or magnitude
Definition serialization.h:645
Unit try_to() const
collapses into a concrete unit, throwing on a dimension mismatch
Definition serialization.h:721
bool operator==(const any_unit &other) const noexcept
whether two erased quantities are the same dimension and magnitude
Definition serialization.h:630
any_unit(unit_identity id, double base)
constructs an erased quantity from a decoded identity and SI-base magnitude
Definition serialization.h:436
std::span< const std::byte > bytes() const noexcept
the serialized byte stream, as a type-safe view
Definition serialization.h:504
std::string to_string_raw() const
the dimension-agnostic text rendering, keyed by name-hash — always available, never resolves a name
Definition serialization.h:585
std::string to_string() const
a human-readable text rendering of the erased quantity, for logging and diagnostics
Definition serialization.h:559
std::partial_ordering operator<=>(const any_unit &other) const noexcept
orders two erased quantities of the same dimension by magnitude
Definition serialization.h:661
const char * data() const noexcept
a pointer to the serialized bytes as const char*, for byte-oriented interfaces
Definition serialization.h:531
const unit_identity & identity() const noexcept
the decoded dimension signature
Definition serialization.h:487
std::size_t size() const noexcept
the number of serialized bytes
Definition serialization.h:542
void visit(Visitor &&visitor) const
invokes a visitor with the canonical quantity for the decoded dimension
Definition serialization.h:774
unit, dimensional analysis, generic cmath functions, traits (not dimension-specific),...
@ base
the SI base-dimension list (" m s^-1"); pairs with a base-converted value.
Definition core.h:3419
@ name
the unit's own full name ("meters", "feet"); base-dimension list if unnamed.
Definition core.h:3418
constexpr T unit_cast(const Unit &value) noexcept
Casts an unit to an arithmetic type.
Definition core.h:3754
constexpr meters_per_second c(299792458.0)
Speed of light in vacuum.
constexpr unit< compound_conversion_factor< joules_, seconds_ > > h(6.62607015e-34)
Planck constant.
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
typename units::detail::dimension_of_impl< U >::type dimension_of_t
Names the dimension_t of a conversion_factor.
Definition core.h:1455
Unit Conversion Library namespace.
Definition units.h:106
std::expected< any_unit, deserialize_error > deserialize(std::span< const std::byte > bytes)
decodes a self-describing byte stream into an erased quantity
Definition serialization.h:928
std::istream & operator>>(std::istream &is, any_unit &value)
reads one self-describing erased quantity from a binary stream (classic stream-extraction form)
Definition serialization.h:1065
any_unit serialize(const Unit &quantity)
serializes a quantity to a self-describing, erased any_unit
Definition serialization.h:895
deserialize_error
the reasons a deserialize can fail
Definition serialization.h:105
@ bad_version
the stream's format version is not understood
Definition serialization.h:107
@ truncated
the byte range ended before a complete quantity was read
Definition serialization.h:106
@ lossy_target
the value cannot be represented in the requested underlying type without loss
Definition serialization.h:110
@ unknown_base_dimension
the stream names a base-dimension code this build does not know
Definition serialization.h:109
@ dimension_mismatch
the stream's dimension does not match the requested target
Definition serialization.h:108
affine::basic_kind< Tag, U > kind
The preferred user-facing spelling of a string-tagged quantity kind: units::kind<"radial",...
Definition kind.h:1214
std::vector< std::byte > encode(const unit_identity &identity, double base)
encodes a dimension identity and SI-base magnitude to the self-describing byte stream
Definition serialization.h:363
void put_uvarint(std::vector< std::byte > &out, std::uint64_t value)
appends an unsigned integer to a byte buffer as an LEB128 varint
Definition serialization.h:133
consteval void 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
Definition serialization.h:271
unit< conversion_factor< std::ratio< 1 >, Dim >, double > canonical_unit_t
the canonical SI base unit of a dimension (ratio 1, no pi, no translation)
Definition serialization.h:331
unit_identity identity_of()
the dimension signature of a unit type, as the runtime (vector-backed) identity
Definition serialization.h:322
void 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
Definition serialization.h:152
constexpr std::uint64_t name_hash(std::string_view name) noexcept
FNV-1a 64-bit hash of a base dimension's name.
Definition serialization.h:91
std::tuple< dimension::length, dimension::mass, dimension::time, dimension::current, dimension::temperature, dimension::substance, dimension::luminous_intensity, dimension::angle, dimension::data, dimension::solid_angle, dimension::frequency, dimension::velocity, dimension::angular_velocity, dimension::acceleration, dimension::force, dimension::area, dimension::volume, dimension::volume_flow_rate, dimension::pressure, dimension::charge, dimension::energy, dimension::power, dimension::voltage, dimension::capacitance, dimension::impedance, dimension::conductance, dimension::magnetic_flux, dimension::inductance, dimension::luminous_flux, dimension::illuminance, dimension::luminance, dimension::radioactivity, dimension::substance_mass, dimension::substance_concentration, dimension::magnetic_field_strength, dimension::radiant_intensity, dimension::radiance, dimension::irradiance, dimension::spectral_intensity, dimension::spectral_flux, dimension::spectral_radiance, dimension::spectral_irradiance, dimension::jerk, dimension::torque, dimension::density, dimension::energy_density, dimension::concentration, dimension::data_transfer_rate, dimension::dynamic_viscosity, dimension::kinematic_viscosity > builtin_dimensions
The library's known dimensions, offered to visit as the default candidate set so a stream of any buil...
Definition serialization.h:73
value_kind
header byte layout: [ valueKind:2 | fracExp:1 | reserved:5 ]
Definition serialization.h:344
@ ivarint
value is an integer in SI base, zig-zag varint
Definition serialization.h:345
@ f32
value is an exact 32-bit float
Definition serialization.h:346
@ f64
value is a 64-bit double
Definition serialization.h:347
bool get_uvarint(const std::byte *&cursor, const std::byte *end, std::uint64_t &value)
reads an LEB128 unsigned varint from a byte cursor
Definition serialization.h:166
bool 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
Definition serialization.h:192
consteval std::size_t dimension_arity()
the number of base-dimension terms in a dimension_t<...> list
Definition serialization.h:251
the compile-time signature of a unit as a fixed-size, sorted array of terms
Definition serialization.h:287
one base-dimension term of a signature: which base dimension (by name-hash), and its rational exponen...
Definition serialization.h:210
std::uint64_t hash
FNV-1a hash of the base dimension's name; the wire identity.
Definition serialization.h:211
std::int64_t den
exponent denominator (1 for the common integer-exponent case)
Definition serialization.h:213
std::int64_t num
exponent numerator
Definition serialization.h:212
the runtime identity of a quantity's dimension — the set of nonzero base-dimension terms
Definition serialization.h:220
bool operator==(const unit_identity &other) const noexcept
dimension-signature equality
Definition serialization.h:230