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