1#![cfg_attr(feature = "f32", doc = " ```rust,compile_fail")]
10#![cfg_attr(not(feature = "f32"), doc = " ```rust,ignore")]
11#![cfg_attr(feature = "f32", doc = " ```rust,compile_fail")]
23#![cfg_attr(not(feature = "f32"), doc = " ```rust,ignore")]
24#![cfg_attr(all(feature = "si", feature = "f32"), doc = " ```rust")]
36#![cfg_attr(not(all(feature = "si", feature = "f32")), doc = " ```rust,ignore")]
37use crate::si::temperature_interval::TemperatureInterval;
49
50quantity! {
51 quantity: ThermodynamicTemperature; "thermodynamic temperature";
53 dimension: ISQ<
55 Z0, Z0, Z0, Z0, P1, Z0, Z0>; kind: dyn crate::si::marker::TemperatureKind;
63 units {
64 @yottakelvin: prefix!(yotta); "YK", "yottakelvin", "yottakelvins";
65 @zettakelvin: prefix!(zetta); "ZK", "zettakelvin", "zettakelvins";
66 @exakelvin: prefix!(exa); "EK", "exakelvin", "exakelvins";
67 @petakelvin: prefix!(peta); "PK", "petakelvin", "petakelvins";
68 @terakelvin: prefix!(tera); "TK", "terakelvin", "terakelvins";
69 @gigakelvin: prefix!(giga); "GK", "gigakelvin", "gigakelvins";
70 @megakelvin: prefix!(mega); "MK", "megakelvin", "megakelvins";
71 @kilokelvin: prefix!(kilo); "kK", "kilokelvin", "kilokelvins";
72 @hectokelvin: prefix!(hecto); "hK", "hectokelvin", "hectokelvins";
73 @decakelvin: prefix!(deca); "daK", "decakelvin", "decakelvins";
74 @kelvin: prefix!(none); "K", "kelvin", "kelvins";
79 @decikelvin: prefix!(deci); "dK", "decikelvin", "decikelvins";
80 @centikelvin: prefix!(centi); "cK", "centikelvin", "centikelvins";
81 @millikelvin: prefix!(milli); "mK", "millikelvin", "millikelvins";
82 @microkelvin: prefix!(micro); "µK", "microkelvin", "microkelvins";
83 @nanokelvin: prefix!(nano); "nK", "nanokelvin", "nanokelvins";
84 @picokelvin: prefix!(pico); "pK", "picokelvin", "picokelvins";
85 @femtokelvin: prefix!(femto); "fK", "femtokelvin", "femtokelvins";
86 @attokelvin: prefix!(atto); "aK", "attokelvin", "attokelvins";
87 @zeptokelvin: prefix!(zepto); "zK", "zeptokelvin", "zeptokelvins";
88 @yoctokelvin: prefix!(yocto); "yK", "yoctokelvin", "yoctokelvins";
89
90 @degree_celsius: 1.0_E0, 273.15_E0; "°C", "degree Celsius", "degrees Celsius";
91 @degree_fahrenheit: 5.0_E0 / 9.0_E0, 459.67_E0; "°F", "degree Fahrenheit",
92 "degrees Fahrenheit";
93 @degree_rankine: 5.0_E0 / 9.0_E0; "°R", "degree Rankine", "degrees Rankine";
94 }
95}
96
97#[doc(hidden)]
98macro_rules! impl_ops {
99 (
100 $AddSubTrait:ident, $addsub_fun:ident, $addsub_op:tt,
101 $AddSubAssignTrait:ident, $addsubassign_fun:ident, $addsubassign_op:tt,
102 $AddSubAlias:ident
103 ) => {
104 #[cfg(feature = "autoconvert")]
105 impl<Ul, Ur, V> $crate::lib::ops::$AddSubTrait<TemperatureInterval<Ur, V>>
106 for ThermodynamicTemperature<Ul, V>
107 where
108 Ul: super::Units<V> + ?Sized,
109 Ur: super::Units<V> + ?Sized,
110 V: $crate::num::Num + $crate::Conversion<V>,
111 {
112 type Output = ThermodynamicTemperature<Ul, V>;
113
114 #[inline(always)]
115 fn $addsub_fun(self, rhs: TemperatureInterval<Ur, V>) -> Self::Output {
116 super::Quantity {
117 dimension: $crate::lib::marker::PhantomData,
118 units: $crate::lib::marker::PhantomData,
119 value: self.value
120 $addsub_op super::change_base::<Dimension, Ul, Ur, V>(&rhs.value),
121 }
122 }
123 }
124
125 #[cfg(not(feature = "autoconvert"))]
126 impl<U, V> $crate::lib::ops::$AddSubTrait<TemperatureInterval<U, V>>
127 for ThermodynamicTemperature<U, V>
128 where
129 U: super::Units<V> + ?Sized,
130 V: $crate::num::Num + $crate::Conversion<V>,
131 {
132 type Output = ThermodynamicTemperature<U, V>;
133
134 #[inline(always)]
135 fn $addsub_fun(self, rhs: TemperatureInterval<U, V>) -> Self::Output {
136 super::Quantity {
137 dimension: $crate::lib::marker::PhantomData,
138 units: $crate::lib::marker::PhantomData,
139 value: self.value $addsub_op rhs.value,
140 }
141 }
142 }
143
144 #[cfg(feature = "autoconvert")]
145 impl<Ul, Ur, V> $crate::lib::ops::$AddSubAssignTrait<TemperatureInterval<Ur, V>>
146 for ThermodynamicTemperature<Ul, V>
147 where
148 Ul: super::Units<V> + ?Sized,
149 Ur: super::Units<V> + ?Sized,
150 V: $crate::num::Num + $crate::Conversion<V> + $crate::lib::ops::$AddSubAssignTrait<V>,
151 {
152 #[inline(always)]
153 fn $addsubassign_fun(&mut self, rhs: TemperatureInterval<Ur, V>) {
154 self.value $addsubassign_op super::change_base::<Dimension, Ul, Ur, V>(&rhs.value);
155 }
156 }
157
158 #[cfg(not(feature = "autoconvert"))]
159 impl<U, V> $crate::lib::ops::$AddSubAssignTrait<TemperatureInterval<U, V>>
160 for ThermodynamicTemperature<U, V>
161 where
162 U: super::Units<V> + ?Sized,
163 V: $crate::num::Num + $crate::Conversion<V> + $crate::lib::ops::$AddSubAssignTrait<V>,
164 {
165 #[inline(always)]
166 fn $addsubassign_fun(&mut self, rhs: TemperatureInterval<U, V>) {
167 self.value $addsubassign_op rhs.value;
168 }
169 }
170 };
171}
172
173impl_ops!(Add, add, +, AddAssign, add_assign, +=, Sum);
174impl_ops!(Sub, sub, -, SubAssign, sub_assign, -=, Diff);
175
176#[cfg(test)]
177mod tests {
178 use crate::si::quantities::*;
179 use crate::si::temperature_interval as ti;
180 use crate::si::thermodynamic_temperature as tt;
181
182 storage_types! {
183 use crate::tests::*;
184 use super::*;
185
186 quickcheck! {
187 #[allow(trivial_casts)]
188 fn add(l: A<V>, r: A<V>) -> bool {
189 Test::eq(&ThermodynamicTemperature::<V>::new::<tt::kelvin>(&*l + &*r),
190 &(ThermodynamicTemperature::<V>::new::<tt::kelvin>((*l).clone())
191 + TemperatureInterval::<V>::new::<ti::kelvin>((*r).clone())))
192 }
193
194 #[allow(trivial_casts)]
195 fn sub(l: A<V>, r: A<V>) -> bool {
196 Test::eq(&ThermodynamicTemperature::<V>::new::<tt::kelvin>(&*l - &*r),
197 &(ThermodynamicTemperature::<V>::new::<tt::kelvin>((*l).clone())
198 - TemperatureInterval::<V>::new::<ti::kelvin>((*r).clone())))
199 }
200 }
201 }
202
203 mod non_big {
204 storage_types! {
205 types: PrimInt, Rational, Rational32, Rational64, Float;
206
207 use crate::tests::*;
208 use super::super::*;
209
210 quickcheck! {
211 #[allow(trivial_casts)]
212 fn add_assign(l: A<V>, r: A<V>) -> bool {
213 let mut f = *l;
214 let mut v = ThermodynamicTemperature::<V>::new::<tt::kelvin>(*l);
215
216 f += *r;
217 v += TemperatureInterval::<V>::new::<ti::kelvin>(*r);
218
219 Test::approx_eq(&ThermodynamicTemperature::<V>::new::<tt::kelvin>(f), &v)
220 }
221
222 #[allow(trivial_casts)]
223 fn sub_assign(l: A<V>, r: A<V>) -> bool {
224 let mut f = *l;
225 let mut v = ThermodynamicTemperature::<V>::new::<tt::kelvin>(*l);
226
227 f -= *r;
228 v -= TemperatureInterval::<V>::new::<ti::kelvin>(*r);
229
230 Test::approx_eq(&ThermodynamicTemperature::<V>::new::<tt::kelvin>(f), &v)
231 }
232 }
233 }
234 }
235}