musli_json/parser/
integer.rs

1use crate::error::IntegerError;
2
3use musli::Context;
4
5use crate::parser::Parser;
6
7use self::traits::FromUnsigned;
8pub(crate) use self::traits::{Float, Signed, Unsigned};
9
10/// Fully deconstructed parts of a signed number.
11#[non_exhaustive]
12#[derive(Clone, Copy)]
13pub(crate) struct SignedPartsBase<T>
14where
15    T: Signed,
16{
17    /// If the number is negative.
18    pub(crate) is_negative: bool,
19    /// The unsigned component of the number.
20    pub(crate) unsigned: T::Unsigned,
21}
22
23impl<T> SignedPartsBase<T>
24where
25    T: Signed,
26{
27    pub(crate) fn compute(self) -> Result<T, IntegerError> {
28        let Self {
29            is_negative,
30            unsigned,
31        } = self;
32
33        match if is_negative {
34            unsigned.negate()
35        } else {
36            unsigned.signed()
37        } {
38            Some(value) => Ok(value),
39            None => Err(IntegerError::IntegerOverflow),
40        }
41    }
42}
43
44/// Fully deconstructed parts of a signed number.
45#[non_exhaustive]
46#[derive(Clone, Copy)]
47pub(crate) struct SignedPartsFull<T>
48where
49    T: Signed,
50{
51    /// If the number is negative.
52    pub(crate) is_negative: bool,
53    /// The unsigned component of the number.
54    pub(crate) unsigned: Parts<T::Unsigned>,
55}
56
57impl<T> SignedPartsFull<T>
58where
59    T: Signed,
60{
61    #[inline(always)]
62    pub(crate) fn compute(self) -> Result<T, IntegerError> {
63        let Self {
64            is_negative,
65            unsigned: parts,
66        } = self;
67
68        let value = parts.compute()?;
69
70        match if is_negative {
71            value.negate()
72        } else {
73            value.signed()
74        } {
75            Some(value) => Ok(value),
76            None => Err(IntegerError::IntegerOverflow),
77        }
78    }
79
80    #[inline(always)]
81    pub(crate) fn compute_float<F>(self) -> F
82    where
83        F: Float,
84        F: FromUnsigned<T::Unsigned>,
85    {
86        let Self {
87            is_negative,
88            unsigned: parts,
89        } = self;
90        let value = parts.compute_float::<F>();
91
92        if is_negative {
93            value.negate()
94        } else {
95            value
96        }
97    }
98}
99
100/// The mantissa, or anything after a decimal point.
101#[derive(Clone, Copy)]
102pub(crate) struct Mantissa<T> {
103    /// The value of the mantissa.
104    value: T,
105    /// The exponent of the mantissa.
106    exp: i32,
107}
108
109impl<T> Mantissa<T>
110where
111    T: Unsigned,
112{
113    fn into_float<F>(self) -> Mantissa<F>
114    where
115        F: FromUnsigned<T>,
116    {
117        Mantissa {
118            value: self.value.into_float::<F>(),
119            exp: self.exp,
120        }
121    }
122}
123
124impl<F> Mantissa<F>
125where
126    F: Float,
127{
128    /// Compute as float with a negative exponent.
129    #[inline]
130    fn compute_float(self, e: i32) -> F {
131        self.value.pow10(e - self.exp)
132    }
133}
134
135impl<T> Default for Mantissa<T>
136where
137    T: Unsigned,
138{
139    fn default() -> Self {
140        Self {
141            value: T::ZERO,
142            exp: 0i32,
143        }
144    }
145}
146
147/// Fully deconstructed parts of an unsigned number.
148#[non_exhaustive]
149#[derive(Clone, Copy)]
150pub(crate) struct Parts<T> {
151    /// The base, or everything before a decimal point.
152    pub(crate) base: T,
153    /// The mantissa, or anything after a decimal point.
154    pub(crate) m: Mantissa<T>,
155    /// The exponent of the number.
156    pub(crate) e: i32,
157}
158
159impl<T> Parts<T>
160where
161    T: Unsigned,
162{
163    #[inline(always)]
164    pub(crate) fn compute(self) -> Result<T, IntegerError> {
165        macro_rules! check {
166            ($expr:expr, $kind:ident) => {
167                match $expr {
168                    Some(value) => value,
169                    None => return Err(IntegerError::$kind),
170                }
171            };
172        }
173
174        let Self { mut base, m, e } = self;
175
176        if e == 0 {
177            if !m.value.is_zero() {
178                return Err(IntegerError::Decimal);
179            }
180
181            return Ok(base);
182        }
183
184        if e >= 0 {
185            // Decoding the specified mantissa would result in a fractional number.
186            let mantissa_exp = check!(e.checked_sub(m.exp).filter(|n| *n >= 0), Decimal) as u32;
187
188            if !base.is_zero() {
189                base = check!(base.checked_pow10(e as u32), IntegerOverflow);
190            }
191
192            let base = check! {
193                m.value
194                    .checked_pow10(mantissa_exp)
195                    .and_then(|m| base.checked_add(m)),
196                IntegerOverflow
197            };
198
199            Ok(base)
200        } else if !m.value.is_zero() {
201            Err(IntegerError::Decimal)
202        } else {
203            Ok(check!(base.checked_neg_pow10(-e as u32), Decimal))
204        }
205    }
206
207    #[inline(always)]
208    pub(crate) fn compute_float<F>(self) -> F
209    where
210        F: Float,
211        F: FromUnsigned<T>,
212    {
213        let Self { base, m, e } = self;
214        base.into_float::<F>().pow10(e) + m.into_float::<F>().compute_float(e)
215    }
216}
217
218/// Implementation to skip over a well-formed JSON number.
219pub(crate) fn skip_number<'de, P, C>(cx: &C, mut p: P) -> Result<(), C::Error>
220where
221    P: Parser<'de>,
222    C: ?Sized + Context,
223{
224    p.skip_whitespace(cx)?;
225
226    let start = cx.mark();
227
228    if p.peek_byte(cx)? == Some(b'-') {
229        p.skip(cx, 1)?;
230    }
231
232    match p.read_byte(cx)? {
233        b'0' => (),
234        b if is_digit_nonzero(b) => {
235            p.consume_while(cx, is_digit)?;
236        }
237        _ => {
238            return Err(cx.marked_message(start, IntegerError::InvalidNumeric));
239        }
240    }
241
242    if p.peek_byte(cx)? == Some(b'.') {
243        p.skip(cx, 1)?;
244        p.consume_while(cx, is_digit)?;
245    }
246
247    if matches!(p.peek_byte(cx)?, Some(b'e') | Some(b'E')) {
248        p.skip(cx, 1)?;
249
250        match p.peek_byte(cx)? {
251            Some(b'-') => {
252                p.skip(cx, 1)?;
253            }
254            Some(b'+') => {
255                p.skip(cx, 1)?;
256            }
257            _ => (),
258        };
259
260        p.consume_while(cx, is_digit)?;
261    }
262
263    Ok(())
264}
265
266/// Partially parse an unsigned value.
267#[cfg_attr(feature = "parse-full", allow(unused))]
268#[inline(never)]
269pub(crate) fn parse_unsigned_base<'de, T, C, P>(cx: &C, mut p: P) -> Result<T, C::Error>
270where
271    T: Unsigned,
272    P: Parser<'de>,
273    C: ?Sized + Context,
274{
275    p.skip_whitespace(cx)?;
276
277    let start = cx.mark();
278    decode_unsigned_base::<T, _, _>(cx, p, start)
279}
280
281/// Fully parse an unsigned value.
282#[cfg_attr(not(feature = "parse-full"), allow(unused))]
283#[inline(never)]
284pub(crate) fn parse_unsigned_full<'de, T, C, P>(cx: &C, mut p: P) -> Result<T, C::Error>
285where
286    T: Unsigned,
287    P: Parser<'de>,
288    C: ?Sized + Context,
289{
290    p.skip_whitespace(cx)?;
291
292    let start = cx.mark();
293
294    match decode_unsigned_full(cx, p, start)?.compute() {
295        Ok(value) => Ok(value),
296        Err(error) => Err(cx.marked_message(start, error)),
297    }
298}
299
300/// Decode a signed integer.
301#[inline(always)]
302fn decode_signed_base<'de, T, C, P>(cx: &C, mut p: P) -> Result<SignedPartsBase<T>, C::Error>
303where
304    C: ?Sized + Context,
305    T: Signed,
306    P: Parser<'de>,
307{
308    let start = cx.mark();
309
310    let is_negative = if p.peek_byte(cx)? == Some(b'-') {
311        p.skip(cx, 1)?;
312        true
313    } else {
314        false
315    };
316
317    let unsigned = decode_unsigned_base::<T::Unsigned, _, _>(cx, p, start)?;
318
319    Ok(SignedPartsBase {
320        is_negative,
321        unsigned,
322    })
323}
324
325/// Decode a full signed integer.
326pub(crate) fn decode_signed_full<'de, T, C, P>(
327    cx: &C,
328    p: &mut P,
329) -> Result<SignedPartsFull<T>, C::Error>
330where
331    C: ?Sized + Context,
332    T: Signed,
333    P: ?Sized + Parser<'de>,
334{
335    p.skip_whitespace(cx)?;
336
337    decode_signed_full_inner(cx, p)
338}
339
340/// Decode a full signed integer.
341#[inline(always)]
342fn decode_signed_full_inner<'de, T, C, P>(cx: &C, mut p: P) -> Result<SignedPartsFull<T>, C::Error>
343where
344    C: ?Sized + Context,
345    T: Signed,
346    P: Parser<'de>,
347{
348    let start = cx.mark();
349
350    let is_negative = if p.peek_byte(cx)? == Some(b'-') {
351        p.skip(cx, 1)?;
352        true
353    } else {
354        false
355    };
356
357    let parts = decode_unsigned_full::<T::Unsigned, _, _>(cx, p, start)?;
358
359    Ok(SignedPartsFull {
360        is_negative,
361        unsigned: parts,
362    })
363}
364
365/// Fully parse a signed value.
366#[cfg_attr(feature = "parse-full", allow(unused))]
367#[inline(never)]
368pub(crate) fn parse_signed_base<'de, T, C, P>(cx: &C, mut p: P) -> Result<T, C::Error>
369where
370    T: Signed,
371    P: Parser<'de>,
372    C: ?Sized + Context,
373{
374    p.skip_whitespace(cx)?;
375
376    let start = cx.mark();
377
378    match decode_signed_base(cx, p)?.compute() {
379        Ok(value) => Ok(value),
380        Err(error) => Err(cx.marked_message(start, error)),
381    }
382}
383
384/// Fully parse a signed value.
385#[cfg_attr(not(feature = "parse-full"), allow(unused))]
386#[inline(never)]
387pub(crate) fn parse_signed_full<'de, T, C, P>(cx: &C, mut p: P) -> Result<T, C::Error>
388where
389    T: Signed,
390    P: Parser<'de>,
391    C: ?Sized + Context,
392{
393    p.skip_whitespace(cx)?;
394
395    let start = cx.mark();
396
397    match decode_signed_full_inner(cx, p)?.compute() {
398        Ok(value) => Ok(value),
399        Err(error) => Err(cx.marked_message(start, error)),
400    }
401}
402
403/// Generically decode a single (whole) integer from a stream of bytes abiding
404/// by JSON convention for format.
405#[inline(always)]
406fn decode_unsigned_base<'de, T, C, P>(cx: &C, mut p: P, start: C::Mark) -> Result<T, C::Error>
407where
408    T: Unsigned,
409    P: Parser<'de>,
410    C: ?Sized + Context,
411{
412    let base = match p.read_byte(cx)? {
413        b'0' => T::ZERO,
414        b if is_digit_nonzero(b) => {
415            let mut base = T::from_byte(b - b'0');
416
417            while let Some(true) = p.peek_byte(cx)?.map(is_digit) {
418                base = digit(cx, base, p.borrow_mut(), start)?;
419            }
420
421            base
422        }
423        _ => {
424            return Err(cx.marked_message(start, IntegerError::InvalidNumeric));
425        }
426    };
427
428    Ok(base)
429}
430
431/// Generically decode a single (whole) integer from a stream of bytes abiding
432/// by JSON convention for format.
433#[inline(always)]
434fn decode_unsigned_full<'de, T, C, P>(
435    cx: &C,
436    mut p: P,
437    start: C::Mark,
438) -> Result<Parts<T>, C::Error>
439where
440    T: Unsigned,
441    P: Parser<'de>,
442    C: ?Sized + Context,
443{
444    let base = decode_unsigned_base(cx, p.borrow_mut(), start)?;
445
446    let mut m = Mantissa::<T>::default();
447
448    if let Some(b'.') = p.peek_byte(cx)? {
449        p.skip(cx, 1)?;
450
451        // NB: we use unchecked operations over mantissa_exp since the mantissa
452        // for any supported type would overflow long before this.
453        m.exp = m.exp.wrapping_add(decode_zeros(cx, p.borrow_mut())?);
454
455        // Stored zeros so that the last segment of zeros can be ignored since
456        // they have no bearing on the value of the integer.
457        let mut zeros = 0;
458
459        while let Some(true) = p.peek_byte(cx)?.map(is_digit) {
460            // Accrue accumulated zeros.
461            if zeros > 0 {
462                m.exp += zeros;
463                m.value = match m.value.checked_pow10(zeros as u32) {
464                    Some(mantissa) => mantissa,
465                    None => {
466                        return Err(cx.marked_message(start, IntegerError::IntegerOverflow));
467                    }
468                };
469            }
470
471            m.exp += 1;
472            m.value = digit(cx, m.value, p.borrow_mut(), start)?;
473            zeros = decode_zeros(cx, p.borrow_mut())?;
474        }
475    }
476
477    let e = if matches!(p.peek_byte(cx)?, Some(b'e' | b'E')) {
478        p.skip(cx, 1)?;
479        decode_exponent(cx, p, start)?
480    } else {
481        0
482    };
483
484    Ok(Parts { base, m, e })
485}
486
487/// Decode an exponent.
488#[inline(always)]
489fn decode_exponent<'de, P, C>(cx: &C, mut p: P, start: C::Mark) -> Result<i32, C::Error>
490where
491    P: Parser<'de>,
492    C: ?Sized + Context,
493{
494    let mut is_negative = false;
495    let mut e = 0u32;
496
497    match p.peek_byte(cx)? {
498        Some(b'-') => {
499            p.skip(cx, 1)?;
500            is_negative = true
501        }
502        Some(b'+') => {
503            p.skip(cx, 1)?;
504        }
505        _ => (),
506    };
507
508    while let Some(true) = p.peek_byte(cx)?.map(is_digit) {
509        e = digit(cx, e, p.borrow_mut(), start)?;
510    }
511
512    match if is_negative { e.negate() } else { e.signed() } {
513        Some(value) => Ok(value),
514        None => Err(cx.marked_message(start, IntegerError::IntegerOverflow)),
515    }
516}
517
518/// Decode a single digit into `out`.
519#[inline(always)]
520fn digit<'de, T, C, P>(cx: &C, out: T, mut p: P, start: C::Mark) -> Result<T, C::Error>
521where
522    T: Unsigned,
523    P: Parser<'de>,
524    C: ?Sized + Context,
525{
526    let Some(out) = out.checked_mul10() else {
527        return Err(cx.marked_message(start, IntegerError::IntegerOverflow));
528    };
529
530    Ok(out + T::from_byte(p.read_byte(cx)? - b'0'))
531}
532
533/// Decode sequence of zeros.
534#[inline(always)]
535fn decode_zeros<'de, P, C>(cx: &C, mut p: P) -> Result<i32, C::Error>
536where
537    P: Parser<'de>,
538    C: ?Sized + Context,
539{
540    let mut count = 0i32;
541
542    while let Some(b'0') = p.peek_byte(cx)? {
543        count = count.wrapping_add(1);
544        p.skip(cx, 1)?;
545    }
546
547    Ok(count)
548}
549
550// Test if b is numeric.
551#[inline]
552fn is_digit(b: u8) -> bool {
553    b.is_ascii_digit()
554}
555
556// Test if b is numeric.
557#[inline(always)]
558fn is_digit_nonzero(b: u8) -> bool {
559    (b'1'..=b'9').contains(&b)
560}
561
562mod traits {
563    use core::fmt;
564    use core::ops::{Add, Not};
565
566    pub(crate) trait Unsigned: Sized + fmt::Debug + Add<Self, Output = Self> {
567        type Signed: Signed<Unsigned = Self>;
568
569        const ZERO: Self;
570
571        fn from_byte(b: u8) -> Self;
572
573        fn is_zero(&self) -> bool;
574
575        /// Calculate `self * 10 ** e`.
576        fn checked_pow10(self, exp: u32) -> Option<Self>;
577
578        /// Calculate `self / 10 ** e`.
579        fn checked_neg_pow10(self, e: u32) -> Option<Self>;
580
581        fn checked_mul10(self) -> Option<Self>;
582
583        fn checked_add(self, other: Self) -> Option<Self>;
584
585        fn checked_pow(self, exp: u32) -> Option<Self>;
586
587        fn negate(self) -> Option<Self::Signed>;
588
589        fn signed(self) -> Option<Self::Signed>;
590
591        fn into_float<F>(self) -> F
592        where
593            F: FromUnsigned<Self>;
594    }
595
596    pub(crate) trait Signed: Sized + fmt::Debug {
597        type Unsigned: Unsigned<Signed = Self>;
598    }
599
600    pub(crate) trait FromUnsigned<T> {
601        fn from_unsigned(value: T) -> Self;
602    }
603
604    pub(crate) trait Float: Sized + Add<Self, Output = Self> {
605        fn negate(self) -> Self;
606
607        fn pow10(self, e: i32) -> Self;
608    }
609
610    macro_rules! count {
611        (()) => { 0 };
612        ((_)) => { 1 };
613        ((_ _)) => { 2 };
614        ((_ _ _)) => { 3 };
615        ((_ _ _ _)) => { 4 };
616        ((_ _ _ _ _)) => { 5 };
617        ((_ _ _ _ _ _)) => { 6 };
618        ((_ _ _ _ _ _ _)) => { 7 };
619        ((_ _ _ _ _ _ _ _)) => { 8 };
620        ((_ _ _ _ _ _ _ _ _)) => { 9 };
621        ((_ _ _ _ _ _ _ _ _ _)) => { 10 };
622        ((_ _ _ _ _ _ _ _ _ _ _)) => { 11 };
623        ((_ _ _ _ _ _ _ _ _ _ _ _)) => { 12 };
624        ((_ _ _ _ _ _ _ _ _ _ _ _ _)) => { 13 };
625        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 14 };
626        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 15 };
627        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 16 };
628        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 17 };
629        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 18 };
630        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 19 };
631        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 20 };
632        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 21 };
633        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 22 };
634        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 23 };
635        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 24 };
636        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 25 };
637        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 26 };
638        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 27 };
639        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 28 };
640        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 29 };
641        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 30 };
642        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 31 };
643        ((_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)) => { 32 };
644
645        (($($s:tt)*) $first:tt $($tt:tt)*) => {
646            count!(($($s)* _) $($tt)*)
647        };
648    }
649
650    macro_rules! unsigned {
651        ($unsigned:ty, $signed:ty, [$($pows:literal),* $(,)?]) => {
652            impl Unsigned for $unsigned {
653                type Signed = $signed;
654
655                const ZERO: Self = 0;
656
657                #[inline(always)]
658                fn from_byte(b: u8) -> Self {
659                    b as $unsigned
660                }
661
662                #[inline(always)]
663                fn is_zero(&self) -> bool {
664                    *self == 0
665                }
666
667                #[inline(always)]
668                fn checked_pow10(self, e: u32) -> Option<Self> {
669                    static POWS: [$unsigned; count!(() $($pows)*)] = [
670                        $($pows),*
671                    ];
672
673                    let n = if let Some(e) = POWS.get(e as usize) {
674                        *e
675                    } else {
676                        10.checked_pow(e)?
677                    };
678
679                    self.checked_mul(n)
680                }
681
682                #[inline(always)]
683                fn checked_neg_pow10(self, e: u32) -> Option<Self> {
684                    const ONE: $unsigned = 1;
685                    let div = ONE.checked_pow10(e)?;
686
687                    if self % div != 0 {
688                        None
689                    } else {
690                        Some(self / div)
691                    }
692                }
693
694                #[inline(always)]
695                fn checked_mul10(self) -> Option<Self> {
696                    self.checked_mul(10)
697                }
698
699                #[inline(always)]
700                fn checked_add(self, other: Self) -> Option<Self> {
701                    <$unsigned>::checked_add(self, other)
702                }
703
704                #[inline(always)]
705                fn checked_pow(self, exp: u32) -> Option<Self> {
706                    <$unsigned>::checked_pow(self, exp)
707                }
708
709                #[inline(always)]
710                fn negate(self) -> Option<Self::Signed> {
711                    if self > (<$unsigned>::MAX >> 1) + 1 {
712                        None
713                    } else {
714                        Some(self.not().wrapping_add(1) as $signed)
715                    }
716                }
717
718                #[inline(always)]
719                fn signed(self) -> Option<Self::Signed> {
720                    if self > <$unsigned>::MAX >> 1 {
721                        None
722                    } else {
723                        Some(self as $signed)
724                    }
725                }
726
727                #[inline(always)]
728                fn into_float<F>(self) -> F where F: FromUnsigned<Self> {
729                    F::from_unsigned(self)
730                }
731            }
732
733            impl Signed for $signed {
734                type Unsigned = $unsigned;
735            }
736        };
737    }
738
739    unsigned!(u8, i8, [1, 10, 100,]);
740
741    unsigned!(u16, i16, [1, 10, 100, 1000, 10000,]);
742
743    unsigned!(
744        u32,
745        i32,
746        [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000,]
747    );
748
749    unsigned!(
750        u64,
751        i64,
752        [
753            1,
754            10,
755            100,
756            1000,
757            10000,
758            100000,
759            1000000,
760            10000000,
761            100000000,
762            1000000000,
763            10000000000,
764            100000000000,
765            1000000000000,
766            10000000000000,
767            100000000000000,
768            1000000000000000,
769            10000000000000000,
770            100000000000000000,
771            1000000000000000000,
772            10000000000000000000,
773        ]
774    );
775
776    unsigned!(
777        u128,
778        i128,
779        [
780            1,
781            10,
782            100,
783            1000,
784            10000,
785            100000,
786            1000000,
787            10000000,
788            100000000,
789            1000000000,
790            10000000000,
791            100000000000,
792            1000000000000,
793            10000000000000,
794            100000000000000,
795            1000000000000000,
796            10000000000000000,
797            100000000000000000,
798            1000000000000000000,
799            10000000000000000000,
800            100000000000000000000,
801            1000000000000000000000,
802            10000000000000000000000,
803            100000000000000000000000,
804            1000000000000000000000000,
805            10000000000000000000000000,
806            100000000000000000000000000,
807            1000000000000000000000000000,
808            10000000000000000000000000000,
809            100000000000000000000000000000,
810            1000000000000000000000000000000,
811            10000000000000000000000000000000,
812        ]
813    );
814
815    #[cfg(target_pointer_width = "32")]
816    unsigned!(
817        usize,
818        isize,
819        [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000,]
820    );
821
822    #[cfg(target_pointer_width = "64")]
823    unsigned!(
824        usize,
825        isize,
826        [
827            1,
828            10,
829            100,
830            1000,
831            10000,
832            100000,
833            1000000,
834            10000000,
835            100000000,
836            1000000000,
837            10000000000,
838            100000000000,
839            1000000000000,
840            10000000000000,
841            100000000000000,
842            1000000000000000,
843            10000000000000000,
844            100000000000000000,
845            1000000000000000000,
846            10000000000000000000,
847        ]
848    );
849
850    macro_rules! float {
851        ($float:ty, $fallback:path) => {
852            impl Float for $float {
853                #[inline]
854                fn negate(self) -> Self {
855                    -self
856                }
857
858                #[inline]
859                #[cfg(feature = "std")]
860                fn pow10(self, e: i32) -> Self {
861                    self * <$float>::powi(10.0, e)
862                }
863
864                #[inline]
865                #[cfg(not(feature = "std"))]
866                fn pow10(self, e: i32) -> Self {
867                    self * $fallback(10.0, e)
868                }
869            }
870
871            impl FromUnsigned<u8> for $float {
872                fn from_unsigned(value: u8) -> Self {
873                    value as $float
874                }
875            }
876
877            impl FromUnsigned<u16> for $float {
878                fn from_unsigned(value: u16) -> Self {
879                    value as $float
880                }
881            }
882
883            impl FromUnsigned<u32> for $float {
884                fn from_unsigned(value: u32) -> Self {
885                    value as $float
886                }
887            }
888
889            impl FromUnsigned<u64> for $float {
890                fn from_unsigned(value: u64) -> Self {
891                    value as $float
892                }
893            }
894
895            impl FromUnsigned<u128> for $float {
896                fn from_unsigned(value: u128) -> Self {
897                    value as $float
898                }
899            }
900        };
901    }
902
903    float!(f32, self::no_std::powf32);
904    float!(f64, self::no_std::powf64);
905
906    #[cfg(not(feature = "std"))]
907    mod no_std {
908        macro_rules! powf {
909            ($ty:ty, $name:ident) => {
910                #[inline(never)]
911                pub(crate) fn $name(mut base: $ty, mut exp: i32) -> $ty {
912                    if exp == 0 {
913                        return 1.0;
914                    }
915
916                    while exp & 1 == 0 {
917                        base = base * base;
918                        exp >>= 1;
919                    }
920
921                    if exp == 1 {
922                        return base;
923                    }
924
925                    let mut acc = base;
926
927                    while exp > 1 {
928                        exp >>= 1;
929                        base = base * base;
930
931                        if exp & 1 == 1 {
932                            acc = acc * base;
933                        }
934                    }
935
936                    acc
937                }
938            };
939        }
940
941        powf!(f32, powf32);
942        powf!(f64, powf64);
943    }
944}