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}