1use crate::consts;
17use crate::traits::Fixed;
18use crate::types::extra::{
19 IsLessOrEqual, LeEqU8, LeEqU16, LeEqU32, LeEqU64, LeEqU128, True, U6, U7, U14, U15, U30, U31,
20 U62, U63, U126, U127,
21};
22use crate::{
23 FixedI8, FixedI16, FixedI32, FixedI64, FixedI128, FixedU8, FixedU16, FixedU32, FixedU64,
24 FixedU128, ParseFixedError,
25};
26use core::fmt::{Display, Formatter, Result as FmtResult};
27use num_traits::bounds::Bounded;
28use num_traits::cast::{FromPrimitive, ToPrimitive};
29use num_traits::float::FloatConst;
30use num_traits::identities::{ConstOne, ConstZero, One, Zero};
31use num_traits::ops::euclid::{CheckedEuclid, Euclid};
32
33use core::error::Error;
34use num_traits::Num;
35use num_traits::ops::bytes::{FromBytes, ToBytes};
36use num_traits::ops::checked::{
37 CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub,
38};
39use num_traits::ops::inv::Inv;
40use num_traits::ops::mul_add::{MulAdd, MulAddAssign};
41use num_traits::ops::overflowing::{OverflowingAdd, OverflowingMul, OverflowingSub};
42use num_traits::ops::saturating::{SaturatingAdd, SaturatingMul, SaturatingSub};
43use num_traits::ops::wrapping::{
44 WrappingAdd, WrappingMul, WrappingNeg, WrappingShl, WrappingShr, WrappingSub,
45};
46use num_traits::sign::{Signed, Unsigned};
47
48#[derive(Clone, Copy, Debug, PartialEq, Eq)]
51pub enum RadixParseFixedError {
52 UnsupportedRadix,
54 ParseFixedError(ParseFixedError),
56}
57
58impl RadixParseFixedError {
59 fn message(&self) -> &str {
60 match self {
61 RadixParseFixedError::UnsupportedRadix => "unsupported radix",
62 RadixParseFixedError::ParseFixedError(e) => e.message(),
63 }
64 }
65}
66
67impl Display for RadixParseFixedError {
68 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
69 Display::fmt(self.message(), f)
70 }
71}
72
73impl Error for RadixParseFixedError {
74 fn description(&self) -> &str {
75 self.message()
76 }
77}
78
79macro_rules! impl_traits {
80 ($Fixed:ident, $LeEqU:ident, $OneMaxFrac:ident, $Signedness:ident) => {
81 impl<Frac> Bounded for $Fixed<Frac> {
82 #[inline]
83 fn min_value() -> Self {
84 Self::MIN
85 }
86 #[inline]
87 fn max_value() -> Self {
88 Self::MAX
89 }
90 }
91
92 impl<Frac> Zero for $Fixed<Frac> {
93 #[inline]
94 fn zero() -> Self {
95 Self::ZERO
96 }
97 #[inline]
98 fn is_zero(&self) -> bool {
99 (*self).is_zero()
100 }
101 }
102
103 impl<Frac> ConstZero for $Fixed<Frac> {
104 const ZERO: Self = Self::ZERO;
105 }
106
107 impl<Frac: $LeEqU> One for $Fixed<Frac>
108 where
109 Frac: IsLessOrEqual<$OneMaxFrac, Output = True>,
110 {
111 #[inline]
112 fn one() -> Self {
113 Self::ONE
114 }
115 }
116
117 impl<Frac: $LeEqU> ConstOne for $Fixed<Frac>
118 where
119 Frac: IsLessOrEqual<$OneMaxFrac, Output = True>,
120 {
121 const ONE: Self = Self::ONE;
122 }
123
124 impl<Frac: $LeEqU> Num for $Fixed<Frac>
125 where
126 Frac: IsLessOrEqual<$OneMaxFrac, Output = True>,
127 {
128 type FromStrRadixErr = RadixParseFixedError;
129
130 #[inline]
131 fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
132 match radix {
133 2 => Self::from_str_binary(str),
134 8 => Self::from_str_octal(str),
135 10 => str.parse(),
136 16 => Self::from_str_hex(str),
137 _ => return Err(RadixParseFixedError::UnsupportedRadix),
138 }
139 .map_err(RadixParseFixedError::ParseFixedError)
140 }
141 }
142
143 impl<Frac: $LeEqU> Inv for $Fixed<Frac> {
144 type Output = Self;
145 #[inline]
146 fn inv(self) -> Self::Output {
147 self.recip()
148 }
149 }
150
151 if_signed! {
152 $Signedness;
153 impl<Frac: $LeEqU> Signed for $Fixed<Frac>
154 where
155 Frac: IsLessOrEqual<$OneMaxFrac, Output = True>,
156 {
157 #[inline]
158 fn abs(&self) -> Self {
159 (*self).abs()
160 }
161 #[inline]
162 fn abs_sub(&self, other: &Self) -> Self {
163 if *self < *other {
164 Self::ZERO
165 } else {
166 *self - *other
167 }
168 }
169 #[inline]
170 fn signum(&self) -> Self {
171 (*self).signum()
172 }
173 #[inline]
174 fn is_positive(&self) -> bool {
175 (*self).is_positive()
176 }
177 #[inline]
178 fn is_negative(&self) -> bool {
179 (*self).is_negative()
180 }
181 }
182 }
183
184 if_unsigned! {
185 $Signedness;
186 impl<Frac: $LeEqU> Unsigned for $Fixed<Frac>
187 where
188 Frac: IsLessOrEqual<$OneMaxFrac, Output = True>,
189 {
190 }
191 }
192
193 impl<Frac: $LeEqU> Euclid for $Fixed<Frac> {
194 #[inline]
195 fn div_euclid(&self, v: &Self) -> Self {
196 (*self).div_euclid(*v)
197 }
198
199 #[inline]
200 fn rem_euclid(&self, v: &Self) -> Self {
201 (*self).rem_euclid(*v)
202 }
203 }
204
205 impl<Frac> CheckedAdd for $Fixed<Frac> {
206 #[inline]
207 fn checked_add(&self, v: &Self) -> Option<Self> {
208 (*self).checked_add(*v)
209 }
210 }
211
212 impl<Frac> CheckedSub for $Fixed<Frac> {
213 #[inline]
214 fn checked_sub(&self, v: &Self) -> Option<Self> {
215 (*self).checked_sub(*v)
216 }
217 }
218
219 impl<Frac> CheckedNeg for $Fixed<Frac> {
220 #[inline]
221 fn checked_neg(&self) -> Option<Self> {
222 (*self).checked_neg()
223 }
224 }
225
226 impl<Frac: $LeEqU> CheckedMul for $Fixed<Frac> {
227 #[inline]
228 fn checked_mul(&self, v: &Self) -> Option<Self> {
229 (*self).checked_mul(*v)
230 }
231 }
232
233 impl<Frac: $LeEqU> CheckedDiv for $Fixed<Frac> {
234 #[inline]
235 fn checked_div(&self, v: &Self) -> Option<Self> {
236 (*self).checked_div(*v)
237 }
238 }
239
240 impl<Frac> CheckedRem for $Fixed<Frac> {
241 #[inline]
242 fn checked_rem(&self, v: &Self) -> Option<Self> {
243 (*self).checked_rem(*v)
244 }
245 }
246
247 impl<Frac> CheckedShl for $Fixed<Frac> {
248 #[inline]
249 fn checked_shl(&self, rhs: u32) -> Option<Self> {
250 (*self).checked_shl(rhs)
251 }
252 }
253
254 impl<Frac> CheckedShr for $Fixed<Frac> {
255 #[inline]
256 fn checked_shr(&self, rhs: u32) -> Option<Self> {
257 (*self).checked_shr(rhs)
258 }
259 }
260
261 impl<Frac: $LeEqU> CheckedEuclid for $Fixed<Frac> {
262 #[inline]
263 fn checked_div_euclid(&self, v: &Self) -> Option<Self> {
264 (*self).checked_div_euclid(*v)
265 }
266
267 #[inline]
268 fn checked_rem_euclid(&self, v: &Self) -> Option<Self> {
269 (*self).checked_rem_euclid(*v)
270 }
271 }
272
273 impl<Frac> SaturatingAdd for $Fixed<Frac> {
274 #[inline]
275 fn saturating_add(&self, v: &Self) -> Self {
276 (*self).saturating_add(*v)
277 }
278 }
279
280 impl<Frac> SaturatingSub for $Fixed<Frac> {
281 #[inline]
282 fn saturating_sub(&self, v: &Self) -> Self {
283 (*self).saturating_sub(*v)
284 }
285 }
286
287 impl<Frac: $LeEqU> SaturatingMul for $Fixed<Frac> {
288 #[inline]
289 fn saturating_mul(&self, v: &Self) -> Self {
290 (*self).saturating_mul(*v)
291 }
292 }
293
294 impl<Frac> WrappingAdd for $Fixed<Frac> {
295 #[inline]
296 fn wrapping_add(&self, v: &Self) -> Self {
297 (*self).wrapping_add(*v)
298 }
299 }
300
301 impl<Frac> WrappingSub for $Fixed<Frac> {
302 #[inline]
303 fn wrapping_sub(&self, v: &Self) -> Self {
304 (*self).wrapping_sub(*v)
305 }
306 }
307
308 impl<Frac> WrappingNeg for $Fixed<Frac> {
309 #[inline]
310 fn wrapping_neg(&self) -> Self {
311 (*self).wrapping_neg()
312 }
313 }
314
315 impl<Frac: $LeEqU> WrappingMul for $Fixed<Frac> {
316 #[inline]
317 fn wrapping_mul(&self, v: &Self) -> Self {
318 (*self).wrapping_mul(*v)
319 }
320 }
321
322 impl<Frac> WrappingShl for $Fixed<Frac> {
323 #[inline]
324 fn wrapping_shl(&self, rhs: u32) -> Self {
325 (*self).wrapping_shl(rhs)
326 }
327 }
328
329 impl<Frac> WrappingShr for $Fixed<Frac> {
330 #[inline]
331 fn wrapping_shr(&self, rhs: u32) -> Self {
332 (*self).wrapping_shr(rhs)
333 }
334 }
335
336 impl<Frac> OverflowingAdd for $Fixed<Frac> {
337 #[inline]
338 fn overflowing_add(&self, v: &Self) -> (Self, bool) {
339 (*self).overflowing_add(*v)
340 }
341 }
342
343 impl<Frac> OverflowingSub for $Fixed<Frac> {
344 #[inline]
345 fn overflowing_sub(&self, v: &Self) -> (Self, bool) {
346 (*self).overflowing_sub(*v)
347 }
348 }
349
350 impl<Frac: $LeEqU> OverflowingMul for $Fixed<Frac> {
351 #[inline]
352 fn overflowing_mul(&self, v: &Self) -> (Self, bool) {
353 (*self).overflowing_mul(*v)
354 }
355 }
356
357 impl<Frac, MulFrac: $LeEqU> MulAdd<$Fixed<MulFrac>> for $Fixed<Frac> {
358 type Output = $Fixed<Frac>;
359 #[inline]
360 fn mul_add(self, a: $Fixed<MulFrac>, b: $Fixed<Frac>) -> $Fixed<Frac> {
361 self.mul_add(a, b)
362 }
363 }
364
365 impl<Frac, MulFrac: $LeEqU> MulAddAssign<$Fixed<MulFrac>> for $Fixed<Frac> {
366 #[inline]
367 fn mul_add_assign(&mut self, a: $Fixed<MulFrac>, b: $Fixed<Frac>) {
368 *self = self.mul_add(a, b)
369 }
370 }
371
372 impl<Frac: $LeEqU> FloatConst for $Fixed<Frac> {
373 #[inline]
374 fn E() -> Self {
375 consts::E.to_num()
376 }
377 #[inline]
378 fn FRAC_1_PI() -> Self {
379 consts::FRAC_1_PI.to_num()
380 }
381 #[inline]
382 fn FRAC_1_SQRT_2() -> Self {
383 consts::FRAC_1_SQRT_2.to_num()
384 }
385 #[inline]
386 fn FRAC_2_PI() -> Self {
387 consts::FRAC_2_PI.to_num()
388 }
389 #[inline]
390 fn FRAC_2_SQRT_PI() -> Self {
391 consts::FRAC_2_SQRT_PI.to_num()
392 }
393 #[inline]
394 fn FRAC_PI_2() -> Self {
395 consts::FRAC_PI_2.to_num()
396 }
397 #[inline]
398 fn FRAC_PI_3() -> Self {
399 consts::FRAC_PI_3.to_num()
400 }
401 #[inline]
402 fn FRAC_PI_4() -> Self {
403 consts::FRAC_PI_4.to_num()
404 }
405 #[inline]
406 fn FRAC_PI_6() -> Self {
407 consts::FRAC_PI_6.to_num()
408 }
409 #[inline]
410 fn FRAC_PI_8() -> Self {
411 consts::FRAC_PI_8.to_num()
412 }
413 #[inline]
414 fn LN_10() -> Self {
415 consts::LN_10.to_num()
416 }
417 #[inline]
418 fn LN_2() -> Self {
419 consts::LN_2.to_num()
420 }
421 #[inline]
422 fn LOG10_E() -> Self {
423 consts::LOG10_E.to_num()
424 }
425 #[inline]
426 fn LOG2_E() -> Self {
427 consts::LOG2_E.to_num()
428 }
429 #[inline]
430 fn PI() -> Self {
431 consts::PI.to_num()
432 }
433 #[inline]
434 fn SQRT_2() -> Self {
435 consts::SQRT_2.to_num()
436 }
437 #[inline]
438 fn TAU() -> Self {
439 consts::TAU.to_num()
440 }
441 #[inline]
442 fn LOG10_2() -> Self {
443 consts::LOG10_2.to_num()
444 }
445 #[inline]
446 fn LOG2_10() -> Self {
447 consts::LOG2_10.to_num()
448 }
449 }
450
451 impl<Frac: $LeEqU> ToPrimitive for $Fixed<Frac> {
452 #[inline]
453 fn to_i64(&self) -> Option<i64> {
454 self.checked_to_num()
455 }
456 #[inline]
457 fn to_u64(&self) -> Option<u64> {
458 self.checked_to_num()
459 }
460 #[inline]
461 fn to_isize(&self) -> Option<isize> {
462 self.checked_to_num()
463 }
464 #[inline]
465 fn to_i8(&self) -> Option<i8> {
466 self.checked_to_num()
467 }
468 #[inline]
469 fn to_i16(&self) -> Option<i16> {
470 self.checked_to_num()
471 }
472 #[inline]
473 fn to_i32(&self) -> Option<i32> {
474 self.checked_to_num()
475 }
476 #[inline]
477 fn to_i128(&self) -> Option<i128> {
478 self.checked_to_num()
479 }
480 #[inline]
481 fn to_usize(&self) -> Option<usize> {
482 self.checked_to_num()
483 }
484 #[inline]
485 fn to_u8(&self) -> Option<u8> {
486 self.checked_to_num()
487 }
488 #[inline]
489 fn to_u16(&self) -> Option<u16> {
490 self.checked_to_num()
491 }
492 #[inline]
493 fn to_u32(&self) -> Option<u32> {
494 self.checked_to_num()
495 }
496 #[inline]
497 fn to_u128(&self) -> Option<u128> {
498 self.checked_to_num()
499 }
500 #[inline]
501 fn to_f32(&self) -> Option<f32> {
502 self.checked_to_num()
503 }
504 #[inline]
505 fn to_f64(&self) -> Option<f64> {
506 self.checked_to_num()
507 }
508 }
509
510 impl<Frac: $LeEqU> FromPrimitive for $Fixed<Frac> {
511 #[inline]
512 fn from_i64(n: i64) -> Option<Self> {
513 Self::checked_from_num(n)
514 }
515 #[inline]
516 fn from_u64(n: u64) -> Option<Self> {
517 Self::checked_from_num(n)
518 }
519 #[inline]
520 fn from_isize(n: isize) -> Option<Self> {
521 Self::checked_from_num(n)
522 }
523 #[inline]
524 fn from_i8(n: i8) -> Option<Self> {
525 Self::checked_from_num(n)
526 }
527 #[inline]
528 fn from_i16(n: i16) -> Option<Self> {
529 Self::checked_from_num(n)
530 }
531 #[inline]
532 fn from_i32(n: i32) -> Option<Self> {
533 Self::checked_from_num(n)
534 }
535 #[inline]
536 fn from_i128(n: i128) -> Option<Self> {
537 Self::checked_from_num(n)
538 }
539 #[inline]
540 fn from_usize(n: usize) -> Option<Self> {
541 Self::checked_from_num(n)
542 }
543 #[inline]
544 fn from_u8(n: u8) -> Option<Self> {
545 Self::checked_from_num(n)
546 }
547 #[inline]
548 fn from_u16(n: u16) -> Option<Self> {
549 Self::checked_from_num(n)
550 }
551 #[inline]
552 fn from_u32(n: u32) -> Option<Self> {
553 Self::checked_from_num(n)
554 }
555 #[inline]
556 fn from_u128(n: u128) -> Option<Self> {
557 Self::checked_from_num(n)
558 }
559 #[inline]
560 fn from_f32(n: f32) -> Option<Self> {
561 Self::checked_from_num(n)
562 }
563 #[inline]
564 fn from_f64(n: f64) -> Option<Self> {
565 Self::checked_from_num(n)
566 }
567 }
568
569 impl<Frac: $LeEqU> ToBytes for $Fixed<Frac> {
570 type Bytes = <Self as Fixed>::Bytes;
571
572 fn to_be_bytes(&self) -> Self::Bytes {
573 (*self).to_be_bytes()
574 }
575
576 fn to_le_bytes(&self) -> Self::Bytes {
577 (*self).to_le_bytes()
578 }
579
580 fn to_ne_bytes(&self) -> Self::Bytes {
581 (*self).to_ne_bytes()
582 }
583 }
584
585 impl<Frac: $LeEqU> FromBytes for $Fixed<Frac> {
586 type Bytes = <Self as Fixed>::Bytes;
587
588 fn from_be_bytes(bytes: &Self::Bytes) -> Self {
589 Self::from_be_bytes(*bytes)
590 }
591
592 fn from_le_bytes(bytes: &Self::Bytes) -> Self {
593 Self::from_le_bytes(*bytes)
594 }
595
596 fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
597 Self::from_ne_bytes(*bytes)
598 }
599 }
600 };
601}
602
603impl_traits! { FixedI8, LeEqU8, U6, Signed }
604impl_traits! { FixedI16, LeEqU16, U14, Signed }
605impl_traits! { FixedI32, LeEqU32, U30, Signed }
606impl_traits! { FixedI64, LeEqU64, U62, Signed }
607impl_traits! { FixedI128, LeEqU128, U126, Signed }
608impl_traits! { FixedU8, LeEqU8, U7, Unsigned }
609impl_traits! { FixedU16, LeEqU16, U15, Unsigned }
610impl_traits! { FixedU32, LeEqU32, U31, Unsigned }
611impl_traits! { FixedU64, LeEqU64, U63, Unsigned }
612impl_traits! { FixedU128, LeEqU128, U127, Unsigned }