18#include <system_error>
56template<
typename Rep,
typename Precision = std::ratio<1>>
66template<
typename Rep,
typename Precision>
71concept not_delta = !_is_specialization_of_v<Rep, delta>;
76 static constexpr Rep zero() noexcept {
return Rep(0); }
79 static constexpr Rep max() noexcept {
return std::numeric_limits<Rep>::max(); }
82 static constexpr Rep min() noexcept {
return std::numeric_limits<Rep>::lowest(); }
97template<
typename Rep,
typename Precision>
100 static_assert(_is_ratio<Precision>::value,
"precision must be a specialization of std::ratio");
101 static_assert(Precision::num > 0,
"precision must be positive");
122 template<
typename Rep2>
123 requires std::convertible_to<const Rep2&, rep> && (treat_as_inexact_v<rep> || !treat_as_inexact_v<Rep2>)
124 constexpr explicit delta(
const Rep2& r)
125 : _r(
static_cast<rep>(r)) {}
140 template<
typename Rep2,
typename Precision2>
141 requires std::convertible_to<const Rep2&, rep> &&
142 detail::_lossless_conversion<Rep2, Precision2, rep, precision> &&
143 detail::_quantity_castable<delta<Rep2, Precision2>,
delta>
163 template<
typename Rep2,
typename Precision2>
164 requires(!detail::_lossless_conversion<Rep2, Precision2, rep, precision> ||
165 !std::convertible_to<const Rep2&, rep>) &&
168 : _r(delta_cast<delta>(d).
count()) {}
219 requires(!treat_as_inexact_v<rep>)
226 requires(!treat_as_inexact_v<rep>)
233 static constexpr delta zero() noexcept {
return delta(delta_values<rep>::zero()); }
236 static constexpr delta min() noexcept {
return delta(delta_values<rep>::min()); }
239 static constexpr delta max() noexcept {
return delta(delta_values<rep>::max()); }
259template<
typename ToDelta,
typename Rep,
typename Precision>
260 requires detail::_quantity_cast_requirements<delta<Rep, Precision>, ToDelta>
262 return detail::_quantity_cast<ToDelta>(d);
281template<
typename ToDelta,
typename Rep,
typename Precision>
283 return detail::_ceil_cast(delta_cast<ToDelta>(d), d);
302template<
typename ToDelta,
typename Rep,
typename Precision>
304 return detail::_floor_cast(delta_cast<ToDelta>(d), d);
319template<
typename ToDelta,
typename Rep,
typename Precision>
321 return delta_cast<ToDelta>(d);
339template<
typename ToDelta,
typename Rep,
typename Precision>
341 return detail::_round_cast<ToDelta>(d, [&d] {
return floor<ToDelta>(d); });
358template<
typename Rep,
typename Precision>
360 return detail::_abs(d);
364template<
typename Rep1,
typename Precision1,
typename Rep2,
typename Precision2>
368 return cd(cd(lhs).count() + cd(rhs).count());
372template<
typename Rep1,
typename Precision1,
typename Rep2,
typename Precision2>
376 return cd(cd(lhs).count() - cd(rhs).count());
380template<
typename Rep1,
typename Precision,
typename Rep2>
381 requires not_delta<Rep2> && std::convertible_to<const Rep2&, std::common_type_t<Rep1, Rep2>>
385 return cd(cd(d).count() * r);
389template<
typename Rep1,
typename Rep2,
typename Precision>
390 requires not_delta<Rep1> && std::convertible_to<const Rep1&, std::common_type_t<Rep1, Rep2>>
397template<
typename Rep1,
typename Precision,
typename Rep2>
398 requires not_delta<Rep2> && std::convertible_to<const Rep2&, std::common_type_t<Rep1, Rep2>>
402 return cd(cd(d).count() / s);
406template<
typename Rep1,
typename Precision1,
typename Rep2,
typename Precision2>
408 -> std::common_type_t<Rep1, Rep2> {
410 return cd(lhs).
count() / cd(rhs).count();
414template<
typename Rep1,
typename Precision,
typename Rep2>
415 requires not_delta<Rep2> && std::convertible_to<const Rep2&, std::common_type_t<Rep1, Rep2>> &&
416 (!treat_as_inexact_v<Rep1> && !treat_as_inexact_v<Rep2>)
420 return cd(cd(d).count() % s);
424template<
typename Rep1,
typename Precision1,
typename Rep2,
typename Precision2>
425 requires(!treat_as_inexact_v<Rep1> && !treat_as_inexact_v<Rep2>)
429 return cd(cd(lhs).count() % cd(rhs).count());
432template<
typename Rep1,
typename Precision1,
typename Rep2,
typename Precision2>
435 return ct(lhs).
count() == ct(rhs).count();
438template<
typename Rep1,
typename Precision1,
typename Rep2,
typename Precision2>
439 requires std::three_way_comparable<std::common_type_t<Rep1, Rep2>>
442 return ct(lhs).
count() <=> ct(rhs).count();
466template<
typename Ratio>
468 static constexpr const char* value =
nullptr;
471struct _si_prefix<
std::ratio<1>> {
472 static constexpr const char* value =
"";
475struct _si_prefix<
std::ratio<1, 10>> {
476 static constexpr const char* value =
"d";
479struct _si_prefix<
std::ratio<1, 1000>> {
480 static constexpr const char* value =
"m";
482template<
typename Ratio>
483inline constexpr const char* _si_prefix_v = _si_prefix<typename Ratio::type>::value;
488template<
typename Precision>
490struct _celsius_delta_unit {
491 using degree = std::ratio<1>;
492 static constexpr const char* suffix =
"°C";
494struct _fahrenheit_delta_unit {
495 using degree = std::ratio<5, 9>;
496 static constexpr const char* suffix =
"°F";
499struct _delta_unit<
std::ratio<1>> : _celsius_delta_unit {};
501struct _delta_unit<
std::ratio<1, 10>> : _celsius_delta_unit {};
503struct _delta_unit<
std::ratio<1, 1000>> : _celsius_delta_unit {};
505struct _delta_unit<
std::ratio<5, 9>> : _fahrenheit_delta_unit {};
507struct _delta_unit<
std::ratio<1, 18>> : _fahrenheit_delta_unit {};
509struct _delta_unit<
std::ratio<1, 1800>> : _fahrenheit_delta_unit {};
515struct _display_traits;
517template<
typename Rep,
typename Precision>
518struct _display_traits<delta<Rep, Precision>> {
520 using _precision =
typename delta<Rep, Precision>::precision;
521 using _unit = _delta_unit<_precision>;
524 using dpc =
typename std::ratio_divide<_precision, typename _unit::degree>::type;
525 static constexpr const char* mark =
"Δ";
526 static constexpr const char* unit = _unit::suffix;
527 static constexpr const char* prefix = _si_prefix_v<dpc>;
537template<
typename Traits,
typename Rep>
538constexpr _display _base_unit_display(
const Rep& count) {
539 return {detail::_ratio_value<typename Traits::dpc>(count),
""};
545template<
typename Traits,
typename Rep>
546constexpr _display _scaled_display(
const Rep& count) {
547 if constexpr (Traits::prefix !=
nullptr) {
548 return {
static_cast<double>(count), Traits::prefix};
550 return _base_unit_display<Traits>(count);
555template<
typename Traits>
556std::string _display_string(
const _display& d) {
557 return _fixed_string(d.value) + Traits::mark + d.prefix + Traits::unit;
561template<
typename Traits,
typename Rep>
562std::string _own_unit_string(
const Rep& count) {
563 static_assert(Traits::prefix !=
nullptr,
"thermo: precision has no SI prefix");
564 return _count_string(count) + Traits::mark + Traits::prefix + Traits::unit;
567#if CONFIG_QUANTA_STD_FORMAT
570template<
typename Traits>
571struct _format_traits {
572 static constexpr const char* markers =
"bs";
573 static constexpr bool has_own_unit = Traits::prefix !=
nullptr;
578 static constexpr void no_own_unit_error(
bool fail =
true) {
580 _format_error(
"thermo: precision has no SI prefix; use an explicit format spec");
585 static constexpr bool own_unit(
bool power) {
return power; }
587 template<
typename OutputIt>
588 static OutputIt append_own_unit(OutputIt out,
bool) {
589 out = _format_append(out, Traits::mark);
590 out = _format_append(out, Traits::prefix);
591 return _format_append(out, Traits::unit);
595 static _display base_display(
const T& t) {
596 return _base_unit_display<Traits>(t.count());
600 static _display scaled_display(
const T& t) {
601 return _scaled_display<Traits>(t.count());
604 template<
typename OutputIt>
605 static OutputIt append_label(OutputIt out,
const _display& d) {
606 out = _format_append(out, Traits::mark);
607 out = _format_append(out, d.prefix);
608 return _format_append(out, Traits::unit);
614template<
typename Traits>
615using _formatter = detail::_unit_formatter<_format_traits<Traits>>;
663template<
typename Rep,
typename Precision>
665 return _own_unit_string<_display_traits<delta<Rep, Precision>>>(d.
count());
672template<
typename Rep,
typename Precision>
674 using traits = _display_traits<delta<Rep, Precision>>;
675 return _display_string<traits>(_base_unit_display<traits>(d.
count()));
682template<
typename Rep,
typename Precision>
684 using traits = _display_traits<delta<Rep, Precision>>;
685 return _display_string<traits>(_scaled_display<traits>(d.
count()));
698struct celsius_scale {
699 using offset = std::ratio<27315, 100>;
700 using degree = std::ratio<1>;
701 static constexpr const char* suffix =
"°C";
710 using offset = std::ratio<0>;
711 using degree = std::ratio<1>;
712 static constexpr const char* suffix =
"K";
720struct fahrenheit_scale {
721 using offset = std::ratio<45967, 180>;
722 using degree = std::ratio<5, 9>;
723 static constexpr const char* suffix =
"°F";
734template<
typename Scale>
735inline constexpr bool _is_relative_scale = std::ratio_not_equal_v<typename Scale::offset, std::ratio<0>>;
738template<
typename Scale,
typename Delta = delta<
int64_t>>
747template<
typename Scale1,
typename Delta1,
typename Scale2,
typename Delta2>
748struct _temperature_ratios {
749 static constexpr _ratio_quotient offset_diff =
750 _safe_ratio_subtract<typename Scale1::offset, typename Scale2::offset>;
752 static constexpr _ratio_quotient prec = _safe_ratio_divide<typename Delta1::precision, typename Delta2::precision>;
753 static constexpr _ratio_quotient offset =
754 _safe_ratio_divide<std::ratio<offset_diff.num, offset_diff.den>,
typename Delta2::precision>;
755 static constexpr bool fits = offset_diff.fits && prec.fits && offset.fits &&
756 _product_fits(prec.den / _gcd(prec.den, offset.den), offset.den);
759template<
typename Scale1,
typename Delta1,
typename Scale2,
typename Delta2>
760struct _lossless_temperature_conversion_impl {
761 using ratios = _temperature_ratios<Scale1, Delta1, Scale2, Delta2>;
763 static constexpr bool value = ratios::offset_diff.fits && ratios::prec.fits && ratios::offset.fits &&
764 ratios::prec.den == 1 && ratios::offset.den == 1;
775template<
typename Source,
typename ToRep,
typename W
ide>
776concept _temperature_integer_steps =
requires(Source& from_val, Wide& w,
const intmax_t& k) {
778 static_cast<Wide
>(from_val) *
static_cast<Wide
>(k) *
static_cast<Wide
>(k) +
779 static_cast<Wide
>(k) *
static_cast<Wide
>(k)
780 } -> std::convertible_to<Wide>;
781 { w /
static_cast<Wide
>(k) } -> std::convertible_to<Wide>;
782 static_cast<ToRep
>(w);
785template<
typename FromRep,
typename ToRep>
786inline constexpr bool _integral_temperature_reps = std::is_integral_v<FromRep> && std::is_integral_v<ToRep>;
788template<
typename FromRep,
typename ToRep,
typename Common>
789using _temperature_source = std::conditional_t<_integral_temperature_reps<FromRep, ToRep>, FromRep, Common>;
791template<
typename FromRep,
typename ToRep,
typename Common>
792using _temperature_wide =
793 std::conditional_t<_integral_temperature_reps<FromRep, ToRep>, detail::_wide_integer<intmax_t>, Common>;
795template<
typename FromRep,
typename ToRep,
typename Common>
796concept _temperature_cast_steps =
797 (treat_as_inexact_v<Common> &&
requires(FromRep (&count)()) {
static_cast<Common
>(count()); } &&
798 requires(Common& from_val,
const double& k, Common& result) {
799 { from_val * k + k } -> std::convertible_to<Common>;
800 static_cast<ToRep
>(result);
802 (!treat_as_inexact_v<Common> &&
803 requires(FromRep (&count)()) {
static_cast<_temperature_source<FromRep, ToRep, Common>
>(count()); } &&
804 _temperature_integer_steps<
805 _temperature_source<FromRep, ToRep, Common>,
807 _temperature_wide<FromRep, ToRep, Common>>);
816template<
typename Scale1,
typename Delta1,
typename Scale2,
typename Delta2>
817concept _implicit_temperature_conversion = std::convertible_to<const typename Delta1::rep&, typename Delta2::rep> &&
818 ((std::is_same_v<Scale1, Scale2> &&
819 detail::_lossless_conversion<
820 typename Delta1::rep,
821 typename Delta1::precision,
822 typename Delta2::rep,
823 typename Delta2::precision>) ||
824 (!std::is_same_v<Scale1, Scale2> && _lossless_temperature_conversion_impl<Scale1, Delta1, Scale2, Delta2>::value &&
825 (treat_as_inexact_v<typename Delta2::rep> || !treat_as_inexact_v<typename Delta1::rep>)));
834template<
typename Scale1,
typename Delta1,
typename Scale2,
typename Delta2>
835concept _temperature_cast_requirements = (std::is_same_v<Scale1, Scale2> && std::is_same_v<Delta1, Delta2>) ||
836 (std::is_same_v<Scale1, Scale2> && detail::_quantity_cast_requirements<Delta1, Delta2>) ||
837 (!std::is_same_v<Scale1, Scale2> && _temperature_ratios<Scale1, Delta1, Scale2, Delta2>::fits &&
838 requires {
typename std::common_type<typename Delta1::rep, typename Delta2::rep, intmax_t>::type; } &&
839 _temperature_cast_steps<
840 typename Delta1::rep,
841 typename Delta2::rep,
842 std::common_type_t<typename Delta1::rep, typename Delta2::rep, intmax_t>>);
846template<
typename ToTemp,
typename Scale,
typename Delta>
847 requires _temperature_cast_requirements<Scale, Delta, typename ToTemp::scale, typename ToTemp::delta_type>
848constexpr ToTemp _temperature_cast(
const temperature<Scale, Delta>& t) {
849 using ToScale =
typename ToTemp::scale;
850 using ToDelta =
typename ToTemp::delta_type;
851 using to_rep =
typename ToDelta::rep;
853 if constexpr (std::is_same_v<Scale, ToScale> && std::is_same_v<Delta, ToDelta>) {
855 }
else if constexpr (std::is_same_v<Scale, ToScale>) {
856 return ToTemp(delta_cast<ToDelta>(Delta(t.count())));
858 using from_prec =
typename Delta::precision;
859 using from_off =
typename Scale::offset;
860 using to_prec =
typename ToDelta::precision;
861 using to_off =
typename ToScale::offset;
863 using offset_diff = std::ratio_subtract<from_off, to_off>;
864 using common_rep = std::common_type_t<typename Delta::rep, to_rep, intmax_t>;
866 using prec_ratio = std::ratio_divide<from_prec, to_prec>;
867 using offset_ratio = std::ratio_divide<offset_diff, to_prec>;
869 if constexpr (treat_as_inexact_v<common_rep>) {
870 common_rep from_val =
static_cast<common_rep
>(t.count());
871 constexpr double pr =
static_cast<double>(prec_ratio::num) / prec_ratio::den;
872 constexpr double or_ =
static_cast<double>(offset_ratio::num) / offset_ratio::den;
873 common_rep result = from_val * pr + or_;
874 return ToTemp(ToDelta(
static_cast<to_rep
>(result)));
878 using source_t = _temperature_source<typename Delta::rep, to_rep, common_rep>;
879 using wider_t = _temperature_wide<typename Delta::rep, to_rep, common_rep>;
880 source_t from_val =
static_cast<source_t
>(t.count());
883 constexpr intmax_t lcd = prec_ratio::den / _gcd(prec_ratio::den, offset_ratio::den) * offset_ratio::den;
884 wider_t numerator =
static_cast<wider_t
>(from_val) *
static_cast<wider_t
>(prec_ratio::num) *
885 static_cast<wider_t
>(lcd / prec_ratio::den) +
886 static_cast<wider_t
>(offset_ratio::num) *
static_cast<wider_t
>(lcd / offset_ratio::den);
887 wider_t result = numerator /
static_cast<wider_t
>(lcd);
888 return ToTemp(ToDelta(
static_cast<to_rep
>(result)));
896template<
typename From,
typename To>
897concept _temperature_castable =
requires(
const From& t) { _temperature_cast<To>(t); };
904struct is_temperature : std::false_type {};
906template<
typename Scale,
typename Delta>
907struct is_temperature<temperature<Scale, Delta>> : std::true_type {};
910inline constexpr bool is_temperature_v = is_temperature<T>::value;
932template<
typename ToTemp,
typename Scale,
typename Delta>
933 requires _temperature_cast_requirements<Scale, Delta, typename ToTemp::scale, typename ToTemp::delta_type>
935 return _temperature_cast<ToTemp>(t);
958template<
typename Scale,
typename Delta>
968 using rep =
typename Delta::rep;
979 template<
typename Rep2>
980 requires std::convertible_to<const Rep2&, rep> && (treat_as_inexact_v<rep> || !treat_as_inexact_v<Rep2>)
982 : _d(
static_cast<rep>(r)) {}
996 template<
typename Delta2>
998 _implicit_temperature_conversion<Scale, Delta2, Scale, Delta>
1000 : _d(delta_cast<Delta>(Delta2(t.
count()))) {}
1003 template<
typename Delta2>
1005 (!_implicit_temperature_conversion<Scale, Delta2, Scale, Delta>)
1010 template<
typename Scale2,
typename Delta2>
1011 requires(!std::is_same_v<temperature, temperature<Scale2, Delta2>>) &&
1013 _implicit_temperature_conversion<Scale2, Delta2, Scale, Delta>
1015 :
temperature(temperature_cast<temperature>(t)) {}
1018 template<
typename Scale2,
typename Delta2>
1019 requires(!std::is_same_v<temperature, temperature<Scale2, Delta2>>) &&
1021 (!_implicit_temperature_conversion<Scale2, Delta2, Scale, Delta>)
1053 requires _is_relative_scale<Scale>
1058 template<
typename Rep2,
typename Precision2>
1064 template<
typename Rep2,
typename Precision2>
1090template<
typename Scale,
typename Delta1,
typename Delta2>
1092 -> std::common_type_t<Delta1, Delta2> {
1093 return Delta1(lhs.
count()) - Delta2(rhs.
count());
1104template<
typename Scale,
typename Delta1,
typename Delta2>
1106 -> std::common_type_t<Delta1, Delta2> {
1115template<
typename Scale,
typename Delta1,
typename Delta2>
1119template<
typename Scale,
typename Delta1,
typename Rep2,
typename Precision2>
1122 using result_delta = std::common_type_t<Delta1, delta<Rep2, Precision2>>;
1127template<
typename Rep1,
typename Precision1,
typename Scale,
typename Delta2>
1134template<
typename Scale,
typename Delta1,
typename Rep2,
typename Precision2>
1137 using result_delta = std::common_type_t<Delta1, delta<Rep2, Precision2>>;
1141template<
typename Scale,
typename Delta1,
typename Delta2>
1143 return Delta1(lhs.
count()) == Delta2(rhs.
count());
1146template<
typename Scale,
typename Delta1,
typename Delta2>
1147 requires std::three_way_comparable<std::common_type_t<typename Delta1::rep, typename Delta2::rep>>
1149 return Delta1(lhs.
count()) <=> Delta2(rhs.
count());
1172template<
typename Scale,
typename Rep,
typename Precision>
1174 using dpc =
typename std::ratio_divide<typename delta<Rep, Precision>::precision,
typename Scale::degree>::type;
1175 static constexpr const char* mark =
"";
1176 static constexpr const char* unit = Scale::suffix;
1177 static constexpr const char* prefix = _si_prefix_v<dpc>;
1188template<
typename Scale,
typename Rep,
typename Precision>
1190 return _own_unit_string<_display_traits<temperature<Scale, delta<Rep, Precision>>>>(t.
count());
1198template<
typename Scale,
typename Rep,
typename Precision>
1200 using traits = _display_traits<temperature<Scale, delta<Rep, Precision>>>;
1201 return _display_string<traits>(_base_unit_display<traits>(t.
count()));
1208template<
typename Scale,
typename Rep,
typename Precision>
1210 using traits = _display_traits<temperature<Scale, delta<Rep, Precision>>>;
1211 return _display_string<traits>(_scaled_display<traits>(t.
count()));
1218template<
typename Rep1,
typename Precision1,
typename Rep2,
typename Precision2>
1221 using common_precision = quanta::detail::_common_precision<Precision1, Precision2>;
1227template<
typename Scale,
typename Delta1,
typename Delta2>
1232#if CONFIG_QUANTA_STD_FORMAT
1259template<
typename Scale,
typename Rep,
typename Precision>
1260struct formatter<
quanta::thermo::temperature<Scale, quanta::thermo::delta<Rep, Precision>>>
1261 :
private quanta::thermo::_formatter<
1262 quanta::thermo::_display_traits<quanta::thermo::temperature<Scale, quanta::thermo::delta<Rep, Precision>>>> {
1263 using quanta::thermo::_formatter<quanta::thermo::_display_traits<
1266 template<
typename FormatContext>
1271 return this->format_quantity(t, ctx);
1280template<
typename Rep,
typename Precision>
1281struct formatter<
quanta::thermo::delta<Rep, Precision>>
1282 :
private quanta::thermo::_formatter<quanta::thermo::_display_traits<quanta::thermo::delta<Rep, Precision>>> {
1283 using quanta::thermo::_formatter<quanta::thermo::_display_traits<quanta::thermo::delta<Rep, Precision>>>::parse;
1285 template<
typename FormatContext>
1287 return this->format_quantity(d, ctx);
1298inline namespace literals {
1299inline namespace thermo_literals {
1390#if QUANTA_HAS_UTF8_LITERALS
1438using namespace literals::thermo_literals;
A temperature difference with a representation and precision.
constexpr delta & operator++()
constexpr delta< typename std::common_type< rep >::type, precision > operator+() const
Rep rep
The representation type.
constexpr delta & operator--()
delta & operator=(const delta &)=default
static constexpr delta zero() noexcept
Returns a zero-length delta.
constexpr delta(const Rep2 &r)
Constructs from a tick count.
constexpr delta & operator%=(const delta &d)
static constexpr delta min() noexcept
Returns the minimum (most negative) representable delta.
constexpr delta & operator*=(const rep &r)
constexpr delta operator++(int)
typename Precision::type precision
The precision as a std::ratio.
constexpr delta(const delta< Rep2, Precision2 > &temp)
Constructs from another delta with different representation or precision.
constexpr delta operator--(int)
constexpr rep count() const
Returns the tick count.
constexpr delta()=default
Constructs a zero delta.
constexpr delta< typename std::common_type< rep >::type, precision > operator-() const
constexpr delta & operator+=(const delta &d)
static constexpr delta max() noexcept
Returns the maximum representable delta.
constexpr delta & operator/=(const rep &r)
constexpr delta & operator-=(const delta &d)
delta(const delta &)=default
constexpr delta & operator%=(const rep &r)
constexpr delta(const delta< Rep2, Precision2 > &d)
Explicit constructor for lossy conversions.
An absolute temperature on a given scale.
temperature & operator=(const temperature &)=default
constexpr temperature()=default
Constructs a temperature at the scale's zero point.
constexpr temperature(const temperature< Scale, Delta2 > &t)
constexpr temperature(const temperature< Scale, Delta2 > &t)
constexpr temperature operator++(int)
constexpr temperature & operator--()
Scale scale
The temperature scale.
constexpr temperature(const temperature< Scale2, Delta2 > &t)
constexpr temperature & operator++()
constexpr temperature(const Rep2 &r)
Constructs from a tick count.
typename Delta::rep rep
The representation type.
constexpr rep count() const
Returns the tick count.
constexpr temperature operator--(int)
temperature(const temperature &)=default
static constexpr temperature max() noexcept
Returns the maximum representable temperature.
static constexpr temperature min() noexcept
Returns the minimum representable temperature.
constexpr temperature(const temperature< Scale2, Delta2 > &t)
constexpr temperature operator-() const
Negates the temperature (e.g.
Delta delta_type
The delta type.
constexpr temperature & operator-=(const delta< Rep2, Precision2 > &d)
constexpr temperature(const Delta &d)
Constructs from a delta.
constexpr temperature & operator+=(const delta< Rep2, Precision2 > &d)
Configuration, traits and internals shared by every quanta domain.
quantity< watt_unit, Rep, Precision > power
Power quantity with configurable representation and precision.
Temperature types and utilities.
temperature< celsius_scale, delta< int64_t, std::milli > > millicelsius
Celsius with 0.001 degree precision.
constexpr ToDelta delta_cast(const delta< Rep, Precision > &d)
Converts a delta to a different precision or representation.
temperature< fahrenheit_scale, delta< int64_t, std::ratio< 5, 90 > > > decifahrenheit
Fahrenheit with 0.1 degree precision.
temperature< celsius_scale, delta< int64_t, std::deci > > decicelsius
Celsius with 0.1 degree precision.
delta< int64_t, std::ratio< 5, 9 > > delta_fahrenheit
Delta with 1°F precision.
delta< int64_t, std::milli > delta_millikelvin
Delta with 0.001 degree precision (Celsius/Kelvin).
constexpr auto difference(const temperature< Scale, Delta1 > &lhs, const temperature< Scale, Delta2 > &rhs) -> std::common_type_t< Delta1, Delta2 >
Returns the difference between two temperatures as a delta.
constexpr ToDelta round(const delta< Rep, Precision > &d)
Rounds a delta to the nearest representable value in the target precision.
delta< int64_t, std::ratio< 5, 9000 > > delta_millifahrenheit
Delta with 0.001°F precision.
delta< int64_t, std::deci > delta_decicelsius
Delta with 0.1 degree precision (Celsius/Kelvin).
delta< int64_t, std::milli > delta_millicelsius
Delta with 0.001 degree precision (Celsius/Kelvin).
constexpr ToDelta trunc(const delta< Rep, Precision > &d)
Rounds a delta toward zero to the nearest representable value in the target precision.
delta< int64_t > delta_celsius
Delta with 1 degree precision (Celsius/Kelvin).
temperature< kelvin_scale > kelvin
Kelvin with 1 degree precision.
constexpr auto operator*(const delta< Rep1, Precision > &d, const Rep2 &r) -> delta< std::common_type_t< Rep1, Rep2 >, Precision >
Multiplies a delta by a scalar.
delta< int64_t, std::deci > delta_decikelvin
Delta with 0.1 degree precision (Celsius/Kelvin).
constexpr auto operator<=>(const delta< Rep1, Precision1 > &lhs, const delta< Rep2, Precision2 > &rhs)
temperature< fahrenheit_scale, delta< int64_t, std::ratio< 5, 9000 > > > millifahrenheit
Fahrenheit with 0.001 degree precision.
temperature< fahrenheit_scale, delta< int64_t, std::ratio< 5, 9 > > > fahrenheit
Fahrenheit with 1 degree precision.
temperature< celsius_scale > celsius
Celsius with 1 degree precision.
constexpr delta< Rep, Precision > abs(const delta< Rep, Precision > &d)
Returns the absolute value of a delta.
constexpr ToTemp temperature_cast(const temperature< Scale, Delta > &t)
Converts a temperature to a different scale or precision.
delta< int64_t > delta_kelvin
Delta with 1 degree precision (Celsius/Kelvin).
constexpr auto operator/(const delta< Rep1, Precision > &d, const Rep2 &s) -> delta< std::common_type_t< Rep1, Rep2 >, Precision >
Divides a delta by a scalar.
constexpr ToDelta ceil(const delta< Rep, Precision > &d)
Rounds a delta up to the nearest representable value in the target precision.
delta< int64_t, std::ratio< 5, 90 > > delta_decifahrenheit
Delta with 0.1°F precision.
temperature< kelvin_scale, delta< int64_t, std::deci > > decikelvin
Kelvin with 0.1 degree precision.
constexpr ToDelta floor(const delta< Rep, Precision > &d)
Rounds a delta down to the nearest representable value in the target precision.
temperature< kelvin_scale, delta< int64_t, std::milli > > millikelvin
Kelvin with 0.001 degree precision.
constexpr bool operator==(const delta< Rep1, Precision1 > &lhs, const delta< Rep2, Precision2 > &rhs)
std::string to_string(const delta< Rep, Precision > &d)
Renders a delta as its exact count with a precision-qualified unit, e.g.
constexpr auto operator+(const delta< Rep1, Precision1 > &lhs, const delta< Rep2, Precision2 > &rhs) -> std::common_type_t< delta< Rep1, Precision1 >, delta< Rep2, Precision2 > >
Returns the sum of two deltas.
constexpr auto operator-(const delta< Rep1, Precision1 > &lhs, const delta< Rep2, Precision2 > &rhs) -> std::common_type_t< delta< Rep1, Precision1 >, delta< Rep2, Precision2 > >
Returns the difference of two deltas.
Type-safe units modeled after std::chrono.
constexpr scaled_t scaled
Selects the scaled form in to_string().
constexpr base_unit_t base_unit
Selects the base-unit form in to_string().
constexpr bool treat_as_inexact_v
Tag type selecting the base-unit form, see base_unit.
Tag type selecting the scaled form, see scaled.
Trait to detect delta specializations.
Trait to indicate floating-point-like behavior.