15#include <commons/color.hpp>
16#include <commons/icon.hpp>
35template <UnitLike U, NumericValue T =
double>
50 [[nodiscard]]
static std::shared_ptr<UnitValue>
of(T value) {
51 return std::make_shared<UnitValue>(value);
55 [[nodiscard]]
static std::unique_ptr<UnitValue>
unique(T value) {
56 return std::make_unique<UnitValue>(value);
62 [[nodiscard]]
static std::expected<UnitValue, ParseError>
parse(
const std::string_view input) {
63 auto split = detail::split_number_and_tail(input);
65 return std::unexpected{split.error()};
66 auto num = detail::parse_number<T>(split->number, input);
68 return std::unexpected{num.error()};
69 constexpr auto d = U::descriptor();
70 const std::string_view tail = split->tail;
71 if (tail.empty() && d.symbol.empty())
73 if (tail == d.id || tail == d.symbol || tail == d.short_name)
75 return std::unexpected{
ParseError{ParseErrorCode::UnitMismatch,
78 std::string{
"expected '"} + std::string{d.symbol} +
79 "', got '" + std::string{tail} +
"'"}};
86 [[nodiscard]]
static constexpr std::string_view id() noexcept {
89 [[nodiscard]]
static constexpr std::string_view symbol() noexcept {
92 [[nodiscard]]
static constexpr std::string_view short_name() noexcept {
95 [[nodiscard]]
static constexpr std::string_view kind() noexcept {
98 [[nodiscard]]
static constexpr std::string_view long_name() noexcept {
101 [[nodiscard]]
static constexpr std::optional<comms::Icon> icon() noexcept {
104 [[nodiscard]]
static constexpr std::optional<comms::Color> color() noexcept {
113 return U::descriptor();
116 return static_cast<double>(v);
120 [[nodiscard]] std::string
to_string()
const override;
123 [[nodiscard]] std::unique_ptr<IUnitValue>
clone()
const override {
124 return std::make_unique<UnitValue>(*
this);
128 [[nodiscard]]
friend constexpr bool operator==(
const UnitValue& a,
132 [[nodiscard]]
friend constexpr auto operator<=>(
const UnitValue& a,
133 const UnitValue& b)
noexcept {
137 constexpr UnitValue& operator+=(
const UnitValue& rhs)
noexcept {
141 constexpr UnitValue& operator-=(
const UnitValue& rhs)
noexcept {
145 constexpr UnitValue& operator*=(T s)
noexcept {
149 constexpr UnitValue& operator/=(T s)
noexcept {
155template <UnitLike U, NumericValue T>
156[[nodiscard]]
constexpr UnitValue<U, T> operator+(
const UnitValue<U, T>& a,
157 const UnitValue<U, T>& b)
noexcept {
158 return UnitValue<U, T>{
static_cast<T
>(a.v + b.v)};
161template <UnitLike U, NumericValue T>
162[[nodiscard]]
constexpr UnitValue<U, T> operator-(
const UnitValue<U, T>& a,
163 const UnitValue<U, T>& b)
noexcept {
164 return UnitValue<U, T>{
static_cast<T
>(a.v - b.v)};
167template <UnitLike U, NumericValue T>
168[[nodiscard]]
constexpr UnitValue<U, T> operator-(
const UnitValue<U, T>& a)
noexcept {
169 return UnitValue<U, T>{
static_cast<T
>(-a.v)};
172template <UnitLike U, NumericValue T>
173[[nodiscard]]
constexpr UnitValue<U, T> operator+(
const UnitValue<U, T>& a)
noexcept {
177template <UnitLike U, NumericValue T>
178[[nodiscard]]
constexpr UnitValue<U, T> operator*(
const UnitValue<U, T>& a, T s)
noexcept {
179 return UnitValue<U, T>{
static_cast<T
>(a.v * s)};
182template <UnitLike U, NumericValue T>
183[[nodiscard]]
constexpr UnitValue<U, T> operator*(T s,
const UnitValue<U, T>& a)
noexcept {
184 return UnitValue<U, T>{
static_cast<T
>(a.v * s)};
187template <UnitLike U, NumericValue T>
188[[nodiscard]]
constexpr UnitValue<U, T> operator/(
const UnitValue<U, T>& a, T s)
noexcept {
189 return UnitValue<U, T>{
static_cast<T
>(a.v / s)};
193template <UnitLike U, NumericValue T>
195 return static_cast<T
>(a.v / b.v);
200template <UnitLike To, UnitLike From, NumericValue T>
202 static_assert(units_compatible<From, To>(),
203 "dimval::convert: source and destination units have different kinds");
204 constexpr auto from_d = From::descriptor();
205 constexpr auto to_d = To::descriptor();
206 if constexpr (std::is_same_v<From, To>) {
210 const auto canonical =
static_cast<double>(v.v) * from_d.factor + from_d.offset;
211 const auto out = (canonical - to_d.offset) / to_d.factor;
217template <UnitLike U, NumericValue T =
double>
Polymorphic interface implemented by every UnitValue<U,T>.
Definition interface.hpp:27
Common concepts, error types, and small utilities used across dimval.
Abstract interfaces for runtime polymorphic handling of dimensional values.
Low-level parsing primitives shared by parse.hpp and the inline UnitValue::parse / MeasureValue::pars...
Detailed error report from a parse_*_value call.
Definition core.hpp:30
Runtime metadata for a unit.
Definition descriptor.hpp:29
A value paired at the type level with a unit tag.
Definition unit.hpp:36
static std::expected< UnitValue, ParseError > parse(const std::string_view input)
Parse "42.5 m" → UnitValue<U,T>.
Definition unit.hpp:62
double numeric_as_double() const noexcept override
Numeric value as a double (lossy for >double types).
Definition unit.hpp:115
static std::shared_ptr< UnitValue > of(T value)
Heap-allocated shared-owned factory: auto p = MeterValue::of(1.78); For a stack value,...
Definition unit.hpp:50
std::unique_ptr< IUnitValue > clone() const override
Deep copy as the interface type — the moral equivalent of a virtual copy ctor.
Definition unit.hpp:123
std::string to_string() const override
Render <value> <symbol> (or whatever the descriptor's formatter dictates).
Definition format.hpp:340
static std::unique_ptr< UnitValue > unique(T value)
Heap-allocated unique-owned factory: auto p = MeterValue::unique(1.78);
Definition unit.hpp:55
std::string to_formatted_string() const override
Render with the descriptor's default precision applied.
Definition format.hpp:345
UnitDescriptor descriptor() const noexcept override
Full descriptor — read individual fields (descriptor().id, ...) from here.
Definition unit.hpp:112
constexpr UnitValue(T value) noexcept
Implicit conversion from the numeric type — enables MeterValue distance = 1.78; style construction.
Definition unit.hpp:46
Concepts and helper accessors that drive the static side of dimval.
constexpr UnitValue< To, T > convert(const UnitValue< From, T > &v) noexcept
Convert a UnitValue between units of the same kind.
Definition unit.hpp:201
constexpr UnitValue< U, T > unit_value(T v) noexcept
Sugar: produce a UnitValue from a scalar literal.
Definition unit.hpp:218