85 typename traits::conversion_factor_traits<typename traits::unit_traits<U>::conversion_factor>::dimension_type,
86 typename traits::conversion_factor_traits<typename traits::unit_traits<U>::conversion_factor>::pi_exponent_ratio, std::ratio<0>>>,
87 typename traits::unit_traits<U>::underlying_type,
typename traits::unit_traits<U>::numerical_scale_type>;
107 template<UnitType From, UnitType To>
109 is_losslessly_convertible_unit<From, To> &&
110 (std::is_floating_point_v<typename traits::unit_traits<To>::underlying_type> ||
111 std::ratio_equal_v<typename traits::conversion_factor_traits<typename traits::unit_traits<From>::conversion_factor>::translation_ratio,
112 typename traits::conversion_factor_traits<typename traits::unit_traits<To>::conversion_factor>::translation_ratio>);
116 template<UnitType U, UnitType V>
117 using absolute_result_unit_t = std::conditional_t<is_losslessly_point_convertible_unit<V, U>, U, traits::replace_underlying_t<U, floating_point_promotion_t<typename traits::unit_traits<U>::underlying_type>>>;
123 template<UnitType U, UnitType V>
125 traits::replace_underlying_t<U, floating_point_promotion_t<typename traits::unit_traits<U>::underlying_type>>>;
128 inline namespace affine
134 template<std::
size_t N>
136 template<fixed_
string Tag, UnitType U>
140 namespace wrap_detail
147 inline constexpr bool is_wrapper =
false;
149 inline constexpr bool is_wrapper<absolute<U>> =
true;
151 inline constexpr bool is_wrapper<delta<U>> =
true;
152 template<fixed_
string Tag, UnitType U>
153 inline constexpr bool is_wrapper<basic_kind<Tag, U>> =
true;
156 template<
class Wrapper>
157 using wrapper_unit_t =
typename Wrapper::unit_type;
163 template<
class Wrapper>
164 constexpr auto unwrap(
const Wrapper& w)
noexcept
166 return w.template to<typename Wrapper::unit_type>();
172 inline constexpr bool dependent_false =
false;
174 inline constexpr bool dependent_false_t =
false;
179 template<
class LhsUnit,
class RhsUnit>
180 constexpr std::partial_ordering order(
const LhsUnit& lhs,
const RhsUnit& rhs)
noexcept
183 return std::partial_ordering::less;
185 return std::partial_ordering::greater;
187 return std::partial_ordering::equivalent;
188 return std::partial_ordering::unordered;
202 struct is_absolute_impl : std::false_type
206 struct is_absolute_impl<units::affine::absolute<U>> : std::true_type
211 struct is_delta_impl : std::false_type
215 struct is_delta_impl<units::
affine::delta<U>> : std::true_type
220 struct is_kind_impl : std::false_type
223 template<units::affine::fixed_
string Tag, UnitType U>
236 struct is_absolute : detail::is_absolute_impl<std::remove_cv_t<T>>
249 struct is_delta : detail::is_delta_impl<std::remove_cv_t<T>>
262 struct is_kind : detail::is_kind_impl<std::remove_cv_t<T>>
291 inline namespace affine
307 constexpr explicit
absolute(const U& point) noexcept : m_point(point) {}
313 constexpr auto value() const noexcept {
return m_point.value(); }
315 constexpr auto raw() const noexcept {
return m_point.raw(); }
317 constexpr auto to_linearized() const noexcept {
return m_point.to_linearized(); }
319 [[nodiscard]]
constexpr const char*
name() const noexcept {
return m_point.name(); }
320 [[nodiscard]]
constexpr const char* abbreviation() const noexcept {
return m_point.abbreviation(); }
324 template<ArithmeticType Arithmetic>
325 constexpr Arithmetic
to() const noexcept
333 template<UnitType PlainTarget>
334 requires traits::is_same_dimension_unit_v<U, PlainTarget>
335 constexpr PlainTarget
to() const noexcept
337 return PlainTarget(m_point);
343 template<AbsoluteType WrapperTarget>
344 requires traits::is_same_dimension_unit_v<U, typename WrapperTarget::unit_type>
345 constexpr WrapperTarget
to() const noexcept
347 return WrapperTarget(
typename WrapperTarget::unit_type(m_point));
367 constexpr delta() noexcept = default;
368 constexpr explicit
delta(const U& amount) noexcept : m_amount(amount) {}
374 constexpr auto value() const noexcept {
return m_amount.value(); }
376 constexpr auto raw() const noexcept {
return m_amount.raw(); }
378 constexpr auto to_linearized() const noexcept {
return m_amount.to_linearized(); }
380 [[nodiscard]]
constexpr const char*
name() const noexcept {
return m_amount.name(); }
381 [[nodiscard]]
constexpr const char* abbreviation() const noexcept {
return m_amount.abbreviation(); }
385 template<ArithmeticType Arithmetic>
386 constexpr Arithmetic
to() const noexcept
396 template<UnitType PlainTarget>
397 requires traits::is_same_dimension_unit_v<U, PlainTarget>
398 constexpr PlainTarget
to() const noexcept
401 "units::delta::to<PlainTarget>(): converting this delta into PlainTarget would truncate an "
402 "integer value; convert to a floating-point delta first (e.g. delta<meters<double>>) if intended.");
403 return PlainTarget(scaled_to<PlainTarget>());
409 template<DeltaType WrapperTarget>
410 requires traits::is_same_dimension_unit_v<U, typename WrapperTarget::unit_type>
411 constexpr WrapperTarget
to() const noexcept
413 using V =
typename WrapperTarget::unit_type;
415 "units::delta::to<delta<V>>(): converting this delta into V would truncate an integer value; "
416 "convert to a floating-point delta first (e.g. delta<meters<double>>) if intended.");
417 return WrapperTarget(scaled_to<V>());
425 constexpr V scaled_to() const noexcept
429 return V(there.raw());
443 template<std::
size_t N>
448 constexpr fixed_string(
const char (&str)[N])
noexcept { std::copy_n(str, N,
value); }
451 template<std::
size_t M>
452 constexpr bool operator==(
const fixed_string<M>& rhs)
const noexcept
454 if constexpr (N != M)
457 return std::equal(
value,
value + N, rhs.value);
460 template<std::
size_t N>
476 template<fixed_
string Tag, UnitType U>
503 static constexpr auto tag() noexcept {
return Tag; }
505 constexpr auto value() const noexcept {
return m_value.value(); }
507 constexpr auto raw() const noexcept {
return m_value.raw(); }
509 constexpr auto to_linearized() const noexcept {
return m_value.to_linearized(); }
512 [[nodiscard]]
constexpr const char*
abbreviation() const noexcept {
return m_value.abbreviation(); }
514 [[nodiscard]] std::string
name()
const {
return std::string(Tag.value).append(
" ").append(m_value.name()); }
518 template<ArithmeticType Arithmetic>
519 constexpr Arithmetic
to() const noexcept
526 template<UnitType PlainTarget>
527 requires traits::is_same_dimension_unit_v<U, PlainTarget>
528 constexpr PlainTarget
to() const noexcept
530 return PlainTarget(m_value);
536 template<KindType WrapperTarget>
537 requires(WrapperTarget::tag() == Tag && traits::is_same_dimension_unit_v<U, typename WrapperTarget::unit_type>)
538 constexpr WrapperTarget
to()
const noexcept
540 return WrapperTarget(
typename WrapperTarget::unit_type(m_value));
561 template<UnitType U, UnitType V>
562 requires traits::is_same_dimension_unit_v<U, V>
569 return delta<R>(
R(
R(wrap_detail::unwrap(lhs)).raw() -
R(wrap_detail::unwrap(rhs)).raw()));
575 template<UnitType U, UnitType V>
576 requires traits::is_same_dimension_unit_v<U, V>
580 return absolute<R>(
R(
R(wrap_detail::unwrap(lhs)).raw() + rhs.template to<R>().raw()));
585 template<UnitType U, UnitType V>
586 requires traits::is_same_dimension_unit_v<V, U>
593 template<UnitType U, UnitType V>
594 requires traits::is_same_dimension_unit_v<U, V>
598 return absolute<R>(
R(
R(wrap_detail::unwrap(lhs)).raw() - rhs.template to<R>().raw()));
602 template<UnitType U, UnitType V>
603 requires traits::is_same_dimension_unit_v<U, V>
607 return delta<R>(
R(lhs.template to<R>().raw() + rhs.template to<R>().raw()));
611 template<UnitType U, UnitType V>
612 requires traits::is_same_dimension_unit_v<U, V>
616 return delta<R>(
R(lhs.template to<R>().raw() - rhs.template to<R>().raw()));
623 return delta<U>(U(-wrap_detail::unwrap(d).raw()));
629 template<UnitType U, ArithmeticType T>
632 using ScaledUnit =
decltype(wrap_detail::unwrap(lhs) * rhs);
635 template<UnitType U, ArithmeticType T>
642 template<UnitType U, ArithmeticType T>
645 using ScaledUnit =
decltype(wrap_detail::unwrap(lhs) / rhs);
652 template<UnitType U, UnitType V>
653 requires traits::is_same_dimension_unit_v<U, V>
656 lhs =
absolute<U>(U(wrap_detail::unwrap(lhs).raw() + rhs.template to<U>().raw()));
659 template<UnitType U, UnitType V>
660 requires traits::is_same_dimension_unit_v<U, V>
663 lhs =
absolute<U>(U(wrap_detail::unwrap(lhs).raw() - rhs.template to<U>().raw()));
668 template<UnitType U, UnitType V>
669 requires traits::is_same_dimension_unit_v<U, V>
672 lhs =
delta<U>(U(wrap_detail::unwrap(lhs).raw() + rhs.template to<U>().raw()));
675 template<UnitType U, UnitType V>
676 requires traits::is_same_dimension_unit_v<U, V>
679 lhs =
delta<U>(U(wrap_detail::unwrap(lhs).raw() - rhs.template to<U>().raw()));
686 template<UnitType U, ArithmeticType T>
689 lhs =
delta<U>(U(wrap_detail::unwrap(lhs).raw() * rhs));
692 template<UnitType U, ArithmeticType T>
695 lhs =
delta<U>(U(wrap_detail::unwrap(lhs).raw() / rhs));
713 template<UnitType U, UnitType V>
714 requires traits::is_same_dimension_unit_v<U, V>
717 return wrap_detail::unwrap(lhs) == wrap_detail::unwrap(rhs);
719 template<UnitType U, UnitType V>
720 requires traits::is_same_dimension_unit_v<U, V>
723 return wrap_detail::order(wrap_detail::unwrap(lhs), wrap_detail::unwrap(rhs));
730 template<UnitType U, UnitType V>
731 requires traits::is_same_dimension_unit_v<U, V>
734 using C = std::common_type_t<U, V>;
735 using CLhs = traits::replace_underlying_t<C, typename traits::unit_traits<U>::underlying_type>;
736 using CRhs = traits::replace_underlying_t<C, typename traits::unit_traits<V>::underlying_type>;
737 return lhs.template to<CLhs>() == rhs.template to<CRhs>();
739 template<UnitType U, UnitType V>
740 requires traits::is_same_dimension_unit_v<U, V>
741 constexpr std::partial_ordering operator<=>(
const delta<U>& lhs,
const delta<V>& rhs)
noexcept
743 using C = std::common_type_t<U, V>;
744 using CLhs = traits::replace_underlying_t<C, typename traits::unit_traits<U>::underlying_type>;
745 using CRhs = traits::replace_underlying_t<C, typename traits::unit_traits<V>::underlying_type>;
746 return wrap_detail::order(lhs.template to<CLhs>(), rhs.template to<CRhs>());
762 return os << wrap_detail::unwrap(obj);
769 return os <<
"delta " << wrap_detail::unwrap(obj);
776 return units::to_string(wrap_detail::unwrap(obj));
783 return std::string(
"delta ").append(units::to_string(wrap_detail::unwrap(obj)));
798 using R = detail::floating_point_promotion_t<U>;
799 return delta<R>(units::abs(
R(wrap_detail::unwrap(d))));
803 template<UnitType U, UnitType V>
804 requires traits::is_same_dimension_unit_v<U, V>
808 const delta<R> a = lhs.template to<delta<R>>();
809 const delta<R> b = rhs.template to<delta<R>>();
810 return a < b ? a : b;
814 template<UnitType U, UnitType V>
815 requires traits::is_same_dimension_unit_v<U, V>
819 const delta<R> a = lhs.template to<delta<R>>();
820 const delta<R> b = rhs.template to<delta<R>>();
821 return a > b ? a : b;
825 template<UnitType U, UnitType V, UnitType W>
826 requires(traits::is_same_dimension_unit_v<U, V> && traits::is_same_dimension_unit_v<U, W>)
833 template<UnitType U, UnitType V>
834 requires traits::is_same_dimension_unit_v<U, V>
838 const absolute<R> a = lhs.template to<absolute<R>>();
839 const absolute<R> b = rhs.template to<absolute<R>>();
840 return a < b ? a : b;
844 template<UnitType U, UnitType V>
845 requires traits::is_same_dimension_unit_v<U, V>
849 const absolute<R> a = lhs.template to<absolute<R>>();
850 const absolute<R> b = rhs.template to<absolute<R>>();
851 return a > b ? a : b;
855 template<UnitType U, UnitType V, UnitType W>
856 requires(traits::is_same_dimension_unit_v<U, V> && traits::is_same_dimension_unit_v<U, W>)
869 template<UnitType U, ArithmeticType T>
872 static_assert(wrap_detail::dependent_false_t<U>,
873 "units::absolute: a point cannot be scaled (a point has no magnitude). Take the difference of two "
874 "points for a delta, or scale a delta.");
877 template<UnitType U, ArithmeticType T>
880 static_assert(wrap_detail::dependent_false_t<U>,
881 "units::absolute: a point cannot be scaled (a point has no magnitude). Scale a delta instead.");
884 template<UnitType U, ArithmeticType T>
885 constexpr auto operator/(
const absolute<U>& lhs, T)
noexcept
887 static_assert(wrap_detail::dependent_false_t<U>,
888 "units::absolute: a point cannot be divided by a number (a point has no magnitude). Divide a delta.");
892 template<UnitType U, UnitType V>
893 requires traits::is_same_dimension_unit_v<U, V>
896 static_assert(wrap_detail::dependent_false_t<U>,
897 "units::absolute: a point cannot be divided by a point (there is no ratio of two positions). "
898 "Take the difference of two points for a delta.");
904 template<UnitType U, UnitType V>
905 requires traits::is_same_dimension_unit_v<U, V>
908 static_assert(wrap_detail::dependent_false_t<U>,
909 "units::absolute: cannot add two points (the sum of two positions has no meaning). Subtract them "
910 "for a delta, or add a delta to move a point.");
916 template<UnitType U, ArithmeticType T>
919 static_assert(wrap_detail::dependent_false_t<U>,
920 "units::delta: cannot add a bare number to a delta. Wrap the number in a delta of the same unit "
921 "(e.g. delta<meters<double>>(3)).");
924 template<UnitType U, ArithmeticType T>
925 constexpr auto operator-(
const delta<U>& lhs, T)
noexcept
927 static_assert(wrap_detail::dependent_false_t<U>,
928 "units::delta: cannot subtract a bare number from a delta. Wrap the number in a delta of the same "
932 template<UnitType U, ArithmeticType T>
933 constexpr auto operator+(
const absolute<U>& lhs, T)
noexcept
935 static_assert(wrap_detail::dependent_false_t<U>,
936 "units::absolute: cannot add a bare number to a point. Add a delta of the same unit to move the "
937 "point (e.g. point + delta<meters<double>>(3)).");
951 template<fixed_
string Tag, UnitType U, UnitType V>
952 requires traits::is_same_dimension_unit_v<U, V>
960 template<fixed_
string Tag, UnitType U, UnitType V>
961 requires traits::is_same_dimension_unit_v<U, V>
969 template<fixed_
string Tag, UnitType U>
976 template<fixed_
string Tag, UnitType U, ArithmeticType T>
979 using ScaledUnit =
decltype(wrap_detail::unwrap(lhs) * rhs);
982 template<fixed_
string Tag, UnitType U, ArithmeticType T>
989 template<fixed_
string Tag, UnitType U, ArithmeticType T>
992 using ScaledUnit =
decltype(wrap_detail::unwrap(lhs) / rhs);
998 template<fixed_
string Tag, UnitType U, UnitType V>
999 requires traits::is_same_dimension_unit_v<U, V>
1002 return wrap_detail::unwrap(lhs) / wrap_detail::unwrap(rhs);
1006 template<fixed_
string Tag, UnitType U, ArithmeticType T>
1012 template<fixed_
string Tag, UnitType U, ArithmeticType T>
1020 template<fixed_
string Tag, UnitType U, UnitType V>
1021 requires traits::is_same_dimension_unit_v<U, V>
1024 lhs =
basic_kind<Tag, U>(U(wrap_detail::unwrap(lhs).raw() + U(wrap_detail::unwrap(rhs)).raw()));
1027 template<fixed_
string Tag, UnitType U, UnitType V>
1028 requires traits::is_same_dimension_unit_v<U, V>
1031 lhs =
basic_kind<Tag, U>(U(wrap_detail::unwrap(lhs).raw() - U(wrap_detail::unwrap(rhs)).raw()));
1037 template<fixed_
string Tag, UnitType U, UnitType V>
1038 requires traits::is_same_dimension_unit_v<U, V>
1041 return wrap_detail::unwrap(lhs) == wrap_detail::unwrap(rhs);
1043 template<fixed_
string Tag, UnitType U, UnitType V>
1044 requires traits::is_same_dimension_unit_v<U, V>
1047 return wrap_detail::order(wrap_detail::unwrap(lhs), wrap_detail::unwrap(rhs));
1062 template<fixed_
string TagL, fixed_
string TagR, UnitType U, UnitType V>
1063 requires(!(TagL == TagR))
1064 constexpr auto operator+(
const basic_kind<TagL, U>&,
const basic_kind<TagR, V>&)
noexcept
1066 static_assert(wrap_detail::dependent_false<TagL, TagR>,
1067 "units::kind: cannot add two DIFFERENT kinds (their tags differ, e.g. \"radial\" vs \"straight\"). "
1068 "They share a unit and a dimension but are semantically distinct; unwrap one side with "
1069 "to<PlainUnit>() to operate on the plain unit if that is truly intended.");
1070 return basic_kind<TagL, U>{};
1072 template<fixed_
string TagL, fixed_
string TagR, UnitType U, UnitType V>
1073 requires(!(TagL == TagR))
1076 static_assert(wrap_detail::dependent_false<TagL, TagR>,
1077 "units::kind: cannot subtract two DIFFERENT kinds (their tags differ, e.g. \"radial\" vs "
1078 "\"straight\"). Unwrap one side with to<PlainUnit>() to operate on the plain unit if intended.");
1081 template<fixed_
string TagL, fixed_
string TagR, UnitType U, UnitType V>
1082 requires(!(TagL == TagR))
1085 static_assert(wrap_detail::dependent_false<TagL, TagR>,
1086 "units::kind: cannot compare two DIFFERENT kinds (their tags differ, e.g. \"radial\" vs "
1087 "\"straight\"). Unwrap one side with to<PlainUnit>() to compare the plain units if intended.");
1094 template<fixed_
string Tag, UnitType U, UnitType Plain>
1097 static_assert(wrap_detail::dependent_false_t<Plain>,
1098 "units::kind: cannot add a plain unit to a kind - a plain unit carries no kind, so mixing them in "
1099 "arithmetic is disallowed. Wrap the plain unit in the same kind first, or unwrap the kind with "
1100 "to<PlainUnit>() to work in plain units.");
1103 template<fixed_
string Tag, UnitType U, UnitType Plain>
1106 static_assert(wrap_detail::dependent_false_t<Plain>,
1107 "units::kind: cannot add a plain unit to a kind - a plain unit carries no kind. Wrap the plain unit "
1108 "in the same kind first, or unwrap the kind with to<PlainUnit>() to work in plain units.");
1111 template<fixed_
string Tag, UnitType U, UnitType Plain>
1114 static_assert(wrap_detail::dependent_false_t<Plain>,
1115 "units::kind: cannot subtract a plain unit from a kind - a plain unit carries no kind. Wrap it in the "
1116 "same kind first, or unwrap the kind with to<PlainUnit>().");
1122 template<fixed_
string Tag, UnitType U, ArithmeticType T>
1125 static_assert(wrap_detail::dependent_false<Tag>,
1126 "units::kind: cannot add a bare number to a kind. Wrap the number in the same kind, or unwrap the "
1127 "kind with to<PlainUnit>() to work in plain units.");
1130 template<fixed_
string Tag, UnitType U, ArithmeticType T>
1133 static_assert(wrap_detail::dependent_false<Tag>,
1134 "units::kind: cannot add a bare number to a kind. Wrap the number in the same kind first.");
1137 template<fixed_
string Tag, UnitType U, ArithmeticType T>
1140 static_assert(wrap_detail::dependent_false<Tag>,
1141 "units::kind: cannot subtract a bare number from a kind. Wrap the number in the same kind first.");
1150 template<fixed_
string Tag, UnitType U>
1153 return os <<
'[' << Tag.value <<
"] " << wrap_detail::unwrap(obj);
1157 template<fixed_
string Tag, UnitType U>
1160 return std::string(
"[").append(Tag.value).append(
"] ").append(units::to_string(wrap_detail::unwrap(obj)));
1169 template<fixed_
string Tag, UnitType U>
1172 using R = detail::floating_point_promotion_t<U>;
1177 template<fixed_
string Tag, UnitType U, UnitType V>
1178 requires traits::is_same_dimension_unit_v<U, V>
1184 return a < b ? a : b;
1188 template<fixed_
string Tag, UnitType U, UnitType V>
1189 requires traits::is_same_dimension_unit_v<U, V>
1195 return a > b ? a : b;
1199 template<fixed_
string Tag, UnitType U, UnitType V, UnitType W>
1200 requires(traits::is_same_dimension_unit_v<U, V> && traits::is_same_dimension_unit_v<U, W>)
1213 template<affine::fixed_
string Tag, UnitType U>
1228template<units::UnitType U>
1229struct std::hash<
units::affine::absolute<U>>
1231 constexpr std::size_t operator()(
const units::affine::absolute<U>& x)
const noexcept {
return std::hash<U>()(x.template to<U>()); }
1235template<units::UnitType U>
1236struct std::hash<
units::affine::delta<U>>
1238 constexpr std::size_t operator()(
const units::affine::delta<U>& x)
const noexcept {
return std::hash<U>()(x.template to<U>()); }
1242template<units::affine::fixed_
string Tag, units::UnitType U>
1243struct std::hash<
units::affine::basic_kind<Tag, U>>
1255 template<units::UnitType U>
1256 struct numeric_limits<
units::affine::absolute<U>>
1258 static constexpr bool is_specialized =
true;
1265 template<units::UnitType U>
1266 struct numeric_limits<
units::affine::delta<U>>
1268 static constexpr bool is_specialized =
true;
1275 template<units::affine::fixed_
string Tag, units::UnitType U>
1276 struct numeric_limits<
units::affine::basic_kind<Tag, U>>
1278 static constexpr bool is_specialized =
true;
A point on a (possibly affine) scale — carries the unit's datum.
Definition kind.h:301
constexpr Arithmetic to() const noexcept
Express this point's value as a plain arithmetic type — the numeric value in its own unit (absolute<c...
Definition kind.h:325
constexpr auto to_linearized() const noexcept
The point's linearized value (as the wrapped unit's to_linearized()).
Definition kind.h:317
constexpr absolute() noexcept=default
< the wrapped unit's numeric type
constexpr PlainTarget to() const noexcept
Express this point as a PLAIN unit of the same dimension — unwraps, applying the datum offset (absolu...
Definition kind.h:335
constexpr const char * name() const noexcept
The wrapped unit's name/abbreviation (a point does not rename the unit).
Definition kind.h:319
constexpr WrapperTarget to() const noexcept
Express this point as another absolute<V> — stays a point (the datum is applied as it re-wraps).
Definition kind.h:345
constexpr absolute(underlying_type value) noexcept
Construct a point directly from its underlying numeric value (in U's own unit).
Definition kind.h:310
constexpr auto raw() const noexcept
The point's raw (linearized) value.
Definition kind.h:315
constexpr auto value() const noexcept
The point's numeric value in its own unit.
Definition kind.h:313
typename traits::unit_traits< U >::underlying_type underlying_type
< the wrapped unit type
Definition kind.h:304
A quantity distinguished by a string TAG — a "kind of quantity" that shares a unit and a dimension wi...
Definition kind.h:478
constexpr auto value() const noexcept
The numeric value in its own unit.
Definition kind.h:505
static constexpr auto tag() noexcept
The tag of this kind.
Definition kind.h:503
constexpr basic_kind(underlying_type value) noexcept
Construct from the underlying numeric value (in U's own unit) — explicit, since a bare number carries...
Definition kind.h:493
constexpr const char * abbreviation() const noexcept
The abbreviation is the wrapped unit's (a kind does not change the abbreviation — "m" for a kind<"rad...
Definition kind.h:512
constexpr basic_kind() noexcept=default
< the wrapped unit's numeric type
constexpr PlainTarget to() const noexcept
Express this kind as a PLAIN unit of the same dimension — unwraps (dropping the tag),...
Definition kind.h:528
constexpr WrapperTarget to() const noexcept
Express this kind as another kind<Tag, V> — the tag is KEPT (radial metres → radial feet).
Definition kind.h:538
constexpr auto raw() const noexcept
The raw (linearized) value.
Definition kind.h:507
constexpr auto to_linearized() const noexcept
The linearized value (as the wrapped unit's to_linearized()).
Definition kind.h:509
typename traits::unit_traits< U >::underlying_type underlying_type
< the wrapped unit type
Definition kind.h:481
constexpr basic_kind & operator=(const U &value) noexcept
Assign a plain unit into this kind (same clear-intent conversion as copy-initialization).
Definition kind.h:496
std::string name() const
The name is the tag followed by the wrapped unit's name — e.g. "radial meters".
Definition kind.h:514
constexpr Arithmetic to() const noexcept
Express this kind's value as a plain arithmetic type — the numeric value in its own unit,...
Definition kind.h:519
An amount of a quantity — offset-free (no datum).
Definition kind.h:362
constexpr PlainTarget to() const noexcept
Express this amount as a PLAIN unit of the same dimension — unwraps, SCALE ONLY (the datum is never a...
Definition kind.h:398
constexpr const char * name() const noexcept
The wrapped unit's name/abbreviation (an amount does not rename the unit).
Definition kind.h:380
constexpr WrapperTarget to() const noexcept
Express this amount as another delta<V> — stays an amount (scale-only).
Definition kind.h:411
constexpr Arithmetic to() const noexcept
Express this amount's value as a plain arithmetic type — the numeric value in its own unit,...
Definition kind.h:386
constexpr auto to_linearized() const noexcept
The amount's linearized value (as the wrapped unit's to_linearized()).
Definition kind.h:378
typename traits::unit_traits< U >::underlying_type underlying_type
< the wrapped unit type
Definition kind.h:365
constexpr auto raw() const noexcept
The amount's raw (linearized) value.
Definition kind.h:376
constexpr delta(underlying_type value) noexcept
Construct an amount directly from its underlying numeric value (in U's own unit).
Definition kind.h:371
constexpr auto value() const noexcept
The amount's numeric value in its own unit.
Definition kind.h:374
constexpr delta() noexcept=default
< the wrapped unit's numeric type
Concept satisfied by any absolute<U> point wrapper.
Definition kind.h:275
Concept satisfied by any delta<U> amount wrapper.
Definition kind.h:282
Concept satisfied by any string-tagged kind<Tag, U>.
Definition kind.h:289
unit, dimensional analysis, generic cmath functions, traits (not dimension-specific),...
unit< traits::strong_t< conversion_factor< typename traits::conversion_factor_traits< typename traits::unit_traits< U >::conversion_factor >::conversion_ratio, typename traits::conversion_factor_traits< typename traits::unit_traits< U >::conversion_factor >::dimension_type, typename traits::conversion_factor_traits< typename traits::unit_traits< U >::conversion_factor >::pi_exponent_ratio, std::ratio< 0 > > >, typename traits::unit_traits< U >::underlying_type, typename traits::unit_traits< U >::numerical_scale_type > delta_unit_t
The offset-free counterpart of a unit: same dimension, scale, and pi factor, but translation stripped...
Definition kind.h:84
constexpr bool is_losslessly_point_convertible_unit
The result unit of a wrapper operator that keeps the LHS UNIT (the "LHS-unit tie-break"): the value s...
Definition kind.h:108
std::conditional_t< is_losslessly_point_convertible_unit< V, U >, U, traits::replace_underlying_t< U, floating_point_promotion_t< typename traits::unit_traits< U >::underlying_type > > > absolute_result_unit_t
The result unit of an absolute (point) operator: keep the LHS unit, promote the underlying only when ...
Definition kind.h:117
std::conditional_t< is_losslessly_convertible_unit< delta_unit_t< V >, delta_unit_t< U > >, U, traits::replace_underlying_t< U, floating_point_promotion_t< typename traits::unit_traits< U >::underlying_type > > > delta_result_unit_t
The result unit of a delta (amount) operator: keep the LHS unit, promote the underlying only when the...
Definition kind.h:124
constexpr unit< compound_conversion_factor< joules_, inverse< kelvin_ >, inverse< mols_ > > > R(8.314462618)
Gas constant.
namespace representing type traits which can access the properties of types provided by the units lib...
Definition core.h:197
Unit Conversion Library namespace.
Definition units.h:106
constexpr auto operator-(const absolute< U > &lhs, const absolute< V > &rhs) noexcept
point - point -> delta, kept in the LHS unit (the datum offsets cancel).
Definition kind.h:563
constexpr auto abs(const delta< U > &d) noexcept
Absolute magnitude of a delta (|amount|), promoting like the wrapped unit's units::abs.
Definition kind.h:796
constexpr absolute< U > & operator+=(absolute< U > &lhs, const delta< V > &rhs) noexcept
Compound move of a point by a delta.
Definition kind.h:654
constexpr delta< U > & operator*=(delta< U > &lhs, T rhs) noexcept
Compound scale of a delta by a bare number, in place (the underlying stays the lhs type,...
Definition kind.h:687
constexpr auto operator*(const delta< U > &lhs, T rhs) noexcept
delta scaled by a bare number -> delta.
Definition kind.h:630
constexpr auto operator*(const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept -> detail::rewrap_to_named_t< unit< traits::strong_t< squared< typename traits::unit_traits< std::common_type_t< UnitTypeLhs, UnitTypeRhs > >::conversion_factor > >, typename std::common_type_t< UnitTypeLhs, UnitTypeRhs >::underlying_type > >
Multiplication type for convertible unit types with a linear scale.
Definition core.h:4501
constexpr bool operator==(const absolute< U > &lhs, const absolute< V > &rhs) noexcept
Compare two points (the datum is applied on each side as it unwraps to the plain unit).
Definition kind.h:715
std::string to_string(const absolute< U > &obj)
String form of a point: its wrapped quantity, unmarked.
Definition kind.h:774
constexpr auto operator/(const delta< U > &lhs, T rhs) noexcept
delta divided by a bare number -> delta (promotes like the wrapped unit's own operator/).
Definition kind.h:643
constexpr auto max(const delta< U > &lhs, const delta< V > &rhs) noexcept
The larger of two deltas, kept in the LHS unit (scale-only reconciliation of the rhs).
Definition kind.h:816
constexpr auto min(const delta< U > &lhs, const delta< V > &rhs) noexcept
The smaller of two deltas, kept in the LHS unit (scale-only reconciliation of the rhs).
Definition kind.h:805
constexpr auto clamp(const delta< U > &value, const delta< V > &lo, const delta< W > &hi) noexcept
Clamp a delta into [lo, hi], kept in the value's LHS unit.
Definition kind.h:827
constexpr auto operator+(const absolute< U > &lhs, const delta< V > &rhs) noexcept
point + delta -> point (move the point up by a relative amount), kept in the LHS point's unit.
Definition kind.h:577
std::ostream & operator<<(std::ostream &os, const absolute< U > &obj)
Stream a point: its wrapped quantity, unmarked.
Definition kind.h:760
affine::basic_kind< Tag, U > kind
The preferred user-facing spelling of a string-tagged quantity kind: units::kind<"radial",...
Definition kind.h:1214
A compile-time string usable as a non-type template parameter (the tag of a kind/of).
Definition kind.h:445
char value[N]
the stored characters (including the terminating null)
Definition kind.h:446
constexpr bool operator==(const fixed_string< M > &rhs) const noexcept
Compare two tags of possibly-different length: unequal if the lengths differ, else element-wise.
Definition kind.h:452
Trait which tests whether T is an absolute<U> point wrapper.
Definition kind.h:237
Trait which tests whether T is a delta<U> amount wrapper.
Definition kind.h:250
Trait which tests whether T is a string-tagged kind<Tag, U>.
Definition kind.h:263