Skip to main content

num_t/
lib.rs

1#![warn(
2    clippy::unwrap_used,
3    clippy::cast_lossless,
4    clippy::unimplemented,
5    clippy::indexing_slicing,
6    clippy::expect_used
7)]
8
9use std::iter::Sum;
10use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign};
11use std::str::FromStr;
12
13#[derive(Debug)]
14#[repr(transparent)]
15pub struct Num<Number, Type>(pub Number, std::marker::PhantomData<Type>);
16
17impl<Scalar: Clone, Type> Clone for Num<Scalar, Type> {
18    fn clone(&self) -> Self {
19        Num(self.0.clone(), self.1)
20    }
21}
22
23impl<Scalar: Copy, Type> Copy for Num<Scalar, Type> {}
24
25impl<Scalar: Default, Type> Default for Num<Scalar, Type> {
26    fn default() -> Self {
27        Num(Scalar::default(), std::marker::PhantomData::<Type>)
28    }
29}
30
31impl<Scalar, Type> From<Scalar> for Num<Scalar, Type> {
32    fn from(number: Scalar) -> Self {
33        Num(number, std::marker::PhantomData::<Type>)
34    }
35}
36
37impl<Scalar, Type> Num<Scalar, Type> {
38    #[inline]
39    pub fn new(number: Scalar) -> Num<Scalar, Type> {
40        Num(number, std::marker::PhantomData::<Type>)
41    }
42}
43
44impl<Scalar: PartialOrd, Type> PartialOrd for Num<Scalar, Type> {
45    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
46        self.0.partial_cmp(&other.0)
47    }
48}
49
50impl<Scalar: PartialEq, Type> PartialEq for Num<Scalar, Type> {
51    fn eq(&self, other: &Self) -> bool {
52        self.0 == other.0
53    }
54}
55
56impl<Scalar: std::cmp::Eq, Type> std::cmp::Eq for Num<Scalar, Type> {}
57
58impl<Scalar: Add<Output = Scalar>, Type> Add for Num<Scalar, Type> {
59    type Output = Self;
60
61    fn add(self, other: Self) -> Self::Output {
62        Num::new(self.0 + other.0)
63    }
64}
65
66impl<Scalar: Sub<Output = Scalar>, Type> Sub for Num<Scalar, Type> {
67    type Output = Self;
68
69    fn sub(self, other: Self) -> Self::Output {
70        Num::new(self.0 - other.0)
71    }
72}
73
74impl<Scalar: Mul<Output = Scalar>, Type> Mul for Num<Scalar, Type> {
75    type Output = Self;
76
77    fn mul(self, other: Self) -> Self::Output {
78        Num::new(self.0 * other.0)
79    }
80}
81
82impl<Scalar: Div<Output = Scalar>, Type> Div for Num<Scalar, Type> {
83    type Output = Self;
84
85    fn div(self, other: Self) -> Self::Output {
86        Num::new(self.0 / other.0)
87    }
88}
89
90impl<Scalar: Rem<Output = Scalar>, Type> Rem for Num<Scalar, Type> {
91    type Output = Self;
92
93    fn rem(self, other: Self) -> Self::Output {
94        Num::new(self.0 % other.0)
95    }
96}
97
98impl<Scalar: AddAssign, Type> AddAssign for Num<Scalar, Type> {
99    fn add_assign(&mut self, other: Self) {
100        self.0 += other.0;
101    }
102}
103
104impl<Scalar: SubAssign, Type> SubAssign for Num<Scalar, Type> {
105    fn sub_assign(&mut self, other: Self) {
106        self.0 -= other.0;
107    }
108}
109
110impl<Scalar: MulAssign, Type> MulAssign for Num<Scalar, Type> {
111    fn mul_assign(&mut self, other: Self) {
112        self.0 *= other.0;
113    }
114}
115
116impl<Scalar: DivAssign, Type> DivAssign for Num<Scalar, Type> {
117    fn div_assign(&mut self, other: Self) {
118        self.0 /= other.0;
119    }
120}
121
122impl<Scalar: RemAssign, Type> RemAssign for Num<Scalar, Type> {
123    fn rem_assign(&mut self, other: Self) {
124        self.0 %= other.0;
125    }
126}
127
128impl<Scalar: num_traits::ToPrimitive, Type> num_traits::ToPrimitive for Num<Scalar, Type> {
129    fn to_i64(&self) -> Option<i64> {
130        self.0.to_i64()
131    }
132
133    fn to_u64(&self) -> Option<u64> {
134        self.0.to_u64()
135    }
136
137    fn to_f32(&self) -> Option<f32> {
138        self.0.to_f32()
139    }
140
141    fn to_f64(&self) -> Option<f64> {
142        self.0.to_f64()
143    }
144
145    fn to_i128(&self) -> Option<i128> {
146        self.0.to_i128()
147    }
148
149    fn to_u128(&self) -> Option<u128> {
150        self.0.to_u128()
151    }
152
153    fn to_i16(&self) -> Option<i16> {
154        self.0.to_i16()
155    }
156
157    fn to_u16(&self) -> Option<u16> {
158        self.0.to_u16()
159    }
160
161    fn to_i32(&self) -> Option<i32> {
162        self.0.to_i32()
163    }
164
165    fn to_u32(&self) -> Option<u32> {
166        self.0.to_u32()
167    }
168
169    fn to_i8(&self) -> Option<i8> {
170        self.0.to_i8()
171    }
172
173    fn to_isize(&self) -> Option<isize> {
174        self.0.to_isize()
175    }
176
177    fn to_u8(&self) -> Option<u8> {
178        self.0.to_u8()
179    }
180
181    fn to_usize(&self) -> Option<usize> {
182        self.0.to_usize()
183    }
184}
185
186impl<Scalar: num_traits::NumCast, Type> num_traits::NumCast for Num<Scalar, Type> {
187    fn from<T: num_traits::ToPrimitive>(n: T) -> Option<Self> {
188        Scalar::from(n).map(Num::new)
189    }
190}
191
192impl<Scalar: num_traits::Num, Type> num_traits::Num for Num<Scalar, Type> {
193    type FromStrRadixErr = Scalar::FromStrRadixErr;
194
195    fn from_str_radix(
196        str: &str,
197        radix: u32,
198    ) -> Result<Self, <Self as num_traits::Num>::FromStrRadixErr> {
199        Ok(Num::new(Scalar::from_str_radix(str, radix)?))
200    }
201}
202
203impl<Scalar: num_traits::One, Type> num_traits::One for Num<Scalar, Type> {
204    fn one() -> Self {
205        Num::new(Scalar::one())
206    }
207}
208
209impl<Scalar: num_traits::Zero, Type> num_traits::Zero for Num<Scalar, Type> {
210    fn zero() -> Self {
211        Num::new(Scalar::zero())
212    }
213
214    fn is_zero(&self) -> bool {
215        self.0.is_zero()
216    }
217}
218
219impl<Scalar: num_traits::Float, Type> num_traits::Float for Num<Scalar, Type>
220where
221    Self: std::ops::Neg<Output = Self> + std::fmt::Debug,
222{
223    fn nan() -> Self {
224        Num::new(Scalar::nan())
225    }
226
227    fn infinity() -> Self {
228        Num::new(Scalar::infinity())
229    }
230
231    fn neg_infinity() -> Self {
232        Num::new(Scalar::neg_infinity())
233    }
234
235    fn neg_zero() -> Self {
236        Num::new(Scalar::neg_zero())
237    }
238
239    fn min_value() -> Self {
240        Num::new(Scalar::min_value())
241    }
242
243    fn min_positive_value() -> Self {
244        Num::new(Scalar::min_positive_value())
245    }
246
247    fn max_value() -> Self {
248        Num::new(Scalar::max_value())
249    }
250
251    fn is_nan(self) -> bool {
252        self.0.is_nan()
253    }
254
255    fn is_infinite(self) -> bool {
256        self.0.is_infinite()
257    }
258
259    fn is_finite(self) -> bool {
260        self.0.is_finite()
261    }
262
263    fn is_normal(self) -> bool {
264        self.0.is_normal()
265    }
266
267    fn classify(self) -> std::num::FpCategory {
268        self.0.classify()
269    }
270
271    fn floor(self) -> Self {
272        Num::new(self.0.floor())
273    }
274
275    fn ceil(self) -> Self {
276        Num::new(self.0.ceil())
277    }
278
279    fn round(self) -> Self {
280        Num::new(self.0.round())
281    }
282
283    fn trunc(self) -> Self {
284        Num::new(self.0.trunc())
285    }
286
287    fn fract(self) -> Self {
288        Num::new(self.0.fract())
289    }
290
291    fn abs(self) -> Self {
292        Num::new(self.0.abs())
293    }
294
295    fn signum(self) -> Self {
296        Num::new(self.0.signum())
297    }
298
299    fn is_sign_positive(self) -> bool {
300        self.0.is_sign_positive()
301    }
302
303    fn is_sign_negative(self) -> bool {
304        self.0.is_sign_negative()
305    }
306
307    fn mul_add(self, a: Self, b: Self) -> Self {
308        Num::new(self.0.mul_add(a.0, b.0))
309    }
310
311    fn recip(self) -> Self {
312        Num::new(self.0.recip())
313    }
314
315    fn powi(self, n: i32) -> Self {
316        Num::new(self.0.powi(n))
317    }
318
319    fn powf(self, n: Self) -> Self {
320        Num::new(self.0.powf(n.0))
321    }
322
323    fn sqrt(self) -> Self {
324        Num::new(self.0.sqrt())
325    }
326
327    fn exp(self) -> Self {
328        Num::new(self.0.exp())
329    }
330
331    fn exp2(self) -> Self {
332        Num::new(self.0.exp2())
333    }
334
335    fn ln(self) -> Self {
336        Num::new(self.0.ln())
337    }
338
339    fn log(self, base: Self) -> Self {
340        Num::new(self.0.log(base.0))
341    }
342
343    fn log2(self) -> Self {
344        Num::new(self.0.log2())
345    }
346
347    fn log10(self) -> Self {
348        Num::new(self.0.log10())
349    }
350
351    fn max(self, other: Self) -> Self {
352        Num::new(self.0.max(other.0))
353    }
354
355    fn min(self, other: Self) -> Self {
356        Num::new(self.0.min(other.0))
357    }
358
359    fn abs_sub(self, other: Self) -> Self {
360        Num::new(self.0.abs_sub(other.0))
361    }
362
363    fn cbrt(self) -> Self {
364        Num::new(self.0.cbrt())
365    }
366
367    fn hypot(self, other: Self) -> Self {
368        Num::new(self.0.hypot(other.0))
369    }
370
371    fn sin(self) -> Self {
372        Num::new(self.0.sin())
373    }
374
375    fn cos(self) -> Self {
376        Num::new(self.0.cos())
377    }
378
379    fn tan(self) -> Self {
380        Num::new(self.0.tan())
381    }
382
383    fn asin(self) -> Self {
384        Num::new(self.0.asin())
385    }
386
387    fn acos(self) -> Self {
388        Num::new(self.0.acos())
389    }
390
391    fn atan(self) -> Self {
392        Num::new(self.0.atan())
393    }
394
395    fn atan2(self, other: Self) -> Self {
396        Num::new(self.0.atan2(other.0))
397    }
398
399    fn sin_cos(self) -> (Self, Self) {
400        let (sin, cos) = self.0.sin_cos();
401        (Num::new(sin), Num::new(cos))
402    }
403
404    fn exp_m1(self) -> Self {
405        Num::new(self.0.exp_m1())
406    }
407
408    fn ln_1p(self) -> Self {
409        Num::new(self.0.ln_1p())
410    }
411
412    fn sinh(self) -> Self {
413        Num::new(self.0.sinh())
414    }
415
416    fn cosh(self) -> Self {
417        Num::new(self.0.cosh())
418    }
419
420    fn tanh(self) -> Self {
421        Num::new(self.0.tanh())
422    }
423
424    fn asinh(self) -> Self {
425        Num::new(self.0.asinh())
426    }
427
428    fn acosh(self) -> Self {
429        Num::new(self.0.acosh())
430    }
431
432    fn atanh(self) -> Self {
433        Num::new(self.0.atanh())
434    }
435
436    fn integer_decode(self) -> (u64, i16, i8) {
437        self.0.integer_decode()
438    }
439}
440
441#[cfg(feature = "float_next_after")]
442impl<Scalar: float_next_after::NextAfter, Type> float_next_after::NextAfter for Num<Scalar, Type> {
443    fn next_after(self, other: Self) -> Self {
444        Num::new(self.0.next_after(other.0))
445    }
446}
447
448impl<Scalar: num_traits::Bounded, Type> num_traits::Bounded for Num<Scalar, Type> {
449    fn min_value() -> Self {
450        Num::new(Scalar::min_value())
451    }
452
453    fn max_value() -> Self {
454        Num::new(Scalar::max_value())
455    }
456}
457
458impl<Scalar: std::ops::Neg<Output = Scalar>, Type> std::ops::Neg for Num<Scalar, Type> {
459    type Output = Self;
460
461    fn neg(self) -> Self::Output {
462        Num::new(-self.0)
463    }
464}
465
466impl<Scalar: num_traits::Signed + std::ops::Neg<Output = Scalar> + num_traits::Num, Type>
467    num_traits::Signed for Num<Scalar, Type>
468where
469    Self: std::ops::Neg<Output = Self>,
470{
471    fn abs(&self) -> Self {
472        Num::new(self.0.abs())
473    }
474
475    fn abs_sub(&self, other: &Self) -> Self {
476        Num::new(self.0.abs_sub(&other.0))
477    }
478
479    fn signum(&self) -> Self {
480        Num::new(self.0.signum())
481    }
482
483    fn is_positive(&self) -> bool {
484        self.0.is_positive()
485    }
486
487    fn is_negative(&self) -> bool {
488        self.0.is_negative()
489    }
490}
491
492#[cfg(feature = "geo")]
493impl<Scalar: geo::GeoNum, Type: std::fmt::Debug> geo::GeoNum for Num<Scalar, Type>
494where
495    Self: std::ops::Neg<Output = Self>,
496    <Scalar as geo::GeoNum>::Ker: geo::Kernel<Num<Scalar, Type>>,
497{
498    type Ker = <Scalar as geo::GeoNum>::Ker;
499
500    fn total_cmp(&self, other: &Self) -> std::cmp::Ordering {
501        self.0.total_cmp(&other.0)
502    }
503}
504
505impl<Scalar: FromStr, Type> FromStr for Num<Scalar, Type> {
506    type Err = Scalar::Err;
507
508    fn from_str(s: &str) -> Result<Self, Self::Err> {
509        Ok(Num::new(Scalar::from_str(s)?))
510    }
511}
512
513impl<Scalar: num_traits::FromPrimitive, Type> num_traits::FromPrimitive for Num<Scalar, Type> {
514    fn from_i64(n: i64) -> Option<Self> {
515        Scalar::from_i64(n).map(Num::new)
516    }
517
518    fn from_u64(n: u64) -> Option<Self> {
519        Scalar::from_u64(n).map(Num::new)
520    }
521}
522
523impl<Scalar: std::cmp::Ord, Type> std::cmp::Ord for Num<Scalar, Type> {
524    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
525        self.0.cmp(&other.0)
526    }
527}
528
529impl<Scalar: std::fmt::Display, Type> std::fmt::Display for Num<Scalar, Type> {
530    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
531        self.0.fmt(f)
532    }
533}
534
535impl<Scalar: Sum, Type> Sum for Num<Scalar, Type> {
536    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
537        Num::new(iter.map(|n| n.0).sum())
538    }
539}