un_prim/
macros.rs

1// This file is part of the un-prim.
2//
3// Copyright (C) 2022 Ade M Ramdani
4//
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
7// This program is free software: you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation, either version 3 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program.  If not, see <https://www.gnu.org/licenses/>.
19
20#[macro_export]
21macro_rules! bit_size {
22    ($t:ty) => {{
23        use std::mem::size_of;
24        (size_of::<$t>() * 8) as u32
25    }};
26}
27
28#[macro_export]
29macro_rules! doc {
30    ($x:expr, $s:expr, $($t:tt)*) => {
31        #[doc = $x]
32        #[doc = concat!("```", "\nuse un_prim::*;\n\n", "let x: ", stringify!($s), " = 100u8.into();", "\n", "assert_eq!(100u8, x.into());\n\n", "```")]
33        #[derive(Clone, Copy)]
34        $($t)*
35    };
36}
37
38#[macro_export]
39macro_rules! byte_size {
40    ($t:ty) => {{
41        use std::mem::size_of;
42        size_of::<$t>() as usize
43    }};
44}
45
46#[macro_export]
47macro_rules! impl_serde {
48    ($S:ident) => {
49        impl Serialize for $S {
50            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
51            where
52                S: serde::Serializer,
53            {
54                let s = self.to_str_radix(16);
55                serializer.serialize_str(&format!("0x{}", &s))
56            }
57        }
58        impl<'de> Deserialize<'de> for $S {
59            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
60            where
61                D: serde::Deserializer<'de>,
62            {
63                let s = String::deserialize(deserializer)?;
64                <$S>::from_str(&s).map_err(serde::de::Error::custom)
65            }
66        }
67    };
68}
69
70#[macro_export]
71macro_rules! impl_stringr {
72    ($S:ident) => {
73        impl $S {
74            fn to_radix_digits_le(v: &$S, radix: u32) -> Vec<u8> {
75                assert!((2..=36).contains(&radix));
76
77                let mut res = Vec::new();
78                let mut digits = v.clone();
79
80                while digits > Self::zero() {
81                    let q = digits / Self::from(radix);
82                    let r = digits % Self::from(radix);
83                    res.push(r.into());
84                    digits = q;
85                }
86                res
87            }
88
89            fn from_radix_digits_be(digits: &[u8], radix: u32) -> $S {
90                assert!((2..=36).contains(&radix));
91
92                let mut res = <$S>::zero();
93                let mut power = <$S>::one();
94                for digit in digits.iter().rev() {
95                    let digit = *digit as u8;
96                    if digit >= radix as u8 {
97                        return <$S>::zero();
98                    }
99                    res += power * digit.into();
100                    power *= radix.into();
101                }
102                res
103            }
104
105            /// convert this type into radix string.
106            pub fn to_str_radix(&self, radix: u32) -> String {
107                assert!((2..=36).contains(&radix));
108
109                if self.is_zero() {
110                    return "0".to_string();
111                }
112
113                let mut res = Self::to_radix_digits_le(self, radix);
114
115                for r in &mut res {
116                    if *r < 10 {
117                        *r += b'0';
118                    } else {
119                        *r += b'a' - 10;
120                    }
121                }
122
123                res.reverse();
124
125                unsafe { String::from_utf8_unchecked(res) }
126            }
127
128            /// Convert string into this type by given radix.
129            pub fn from_str_radix(s: &str, radix: u32) -> Result<Self, String> {
130                let mut s = s;
131
132                if s.starts_with('+') {
133                    let tail = &s[1..];
134                    if tail.starts_with('+') {
135                        s = tail;
136                    }
137                }
138
139                if s.is_empty() {
140                    return Err("empty string".to_string());
141                }
142
143                if s.starts_with('_') {
144                    return Err("leading underscore".to_string());
145                }
146
147                let mut v = Vec::with_capacity(s.len());
148
149                for b in s.bytes() {
150                    let d = match b {
151                        b'0'..=b'9' => b - b'0',
152                        b'a'..=b'z' => b - b'a' + 10,
153                        b'A'..=b'Z' => b - b'A' + 10,
154                        b'_' => continue,
155                        _ => return Err("invalid character".to_string()),
156                    };
157
158                    if d < radix as u8 {
159                        v.push(d);
160                    } else {
161                        return Err("invalid digit".to_string());
162                    }
163                }
164
165                Ok(Self::from_radix_digits_be(&v, radix))
166            }
167        }
168    };
169}
170
171#[macro_export]
172macro_rules! impl_def_trait {
173    ($S:ident) => {
174        impl Eq for $S {}
175
176        impl PartialEq for $S {
177            fn eq(&self, other: &Self) -> bool {
178                self.data == other.data
179            }
180        }
181
182        impl Ord for $S {
183            fn cmp(&self, other: &Self) -> std::cmp::Ordering {
184                let x = self.clone();
185                let y = other.clone();
186                let (z, c) = x.overflowing_sub(y);
187
188                if c {
189                    std::cmp::Ordering::Less
190                } else if z.is_zero() {
191                    std::cmp::Ordering::Equal
192                } else {
193                    std::cmp::Ordering::Greater
194                }
195            }
196
197            fn clamp(self, min: Self, max: Self) -> Self
198            where
199                Self: Sized,
200            {
201                if self < min {
202                    min
203                } else if self > max {
204                    max
205                } else {
206                    self
207                }
208            }
209        }
210
211        impl PartialOrd for $S {
212            fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
213                Some(self.cmp(other))
214            }
215        }
216
217        impl Default for $S {
218            fn default() -> Self {
219                Self::zero()
220            }
221        }
222
223        impl std::fmt::Display for $S {
224            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
225                f.pad_integral(true, "", &self.to_str_radix(10))
226            }
227        }
228
229        impl std::fmt::Debug for $S {
230            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
231                std::fmt::Display::fmt(self, f)
232            }
233        }
234
235        impl std::fmt::Binary for $S {
236            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
237                f.pad_integral(true, "", &self.to_str_radix(2))
238            }
239        }
240
241        impl std::fmt::Octal for $S {
242            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
243                f.pad_integral(true, "", &self.to_str_radix(8))
244            }
245        }
246
247        impl FromStr for $S {
248            type Err = String;
249
250            fn from_str(s: &str) -> Result<Self, Self::Err> {
251                if s.is_empty() {
252                    return Err("Empty string".to_string());
253                }
254
255                #[allow(unused_mut)]
256                let mut res: Result<Self, String>;
257
258                // check if the string has a leading 0x
259                if s.starts_with("0x") {
260                    res = Self::from_str_radix(s.strip_prefix("0x").unwrap(), 16);
261                } else if s.starts_with("0b") {
262                    res = Self::from_str_radix(s.strip_prefix("0b").unwrap(), 2);
263                } else if s.starts_with("0o") {
264                    res = Self::from_str_radix(s.strip_prefix("0o").unwrap(), 8);
265                } else {
266                    res = Self::from_str_radix(s, 10);
267                }
268
269                match res {
270                    Ok(v) => Ok(v),
271                    Err(e) => Err(e),
272                }
273            }
274        }
275    };
276}
277
278#[macro_export]
279macro_rules! define {
280    ($S:ident, $size:expr, $doc:expr) => {
281        doc!(
282            $doc,
283            $S,
284            pub struct $S {
285                data: [u8; $size],
286            }
287        );
288
289        from_prim!($S, u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
290
291        impl_def_trait!($S);
292
293        impl_stringr!($S);
294
295        impl_serde!($S);
296
297        impl $S {
298            /// Bytes size of this type.
299            pub const SIZE: usize = $size;
300
301            /// Bit size of this type.
302            pub const BITS: u32 = bit_size!($S);
303
304            /// Minimum value of this type.
305            pub const MIN: $S = $S { data: [0; $size] };
306
307            /// Maximum value of this type.
308            pub const MAX: $S = $S { data: [255; $size] };
309
310            /// Return zero representation of this types.
311            pub fn zero() -> Self {
312                let data = [0; Self::SIZE];
313                Self { data }
314            }
315
316            /// Return one representation of this types.
317            pub fn one() -> Self {
318                let mut data = [0; Self::SIZE];
319                data[0] = 1;
320                Self { data }
321            }
322
323            /// Return true if this is zero.
324            pub fn is_zero(&self) -> bool {
325                self.data.iter().all(|&x| x == 0)
326            }
327
328            /// Return true if this is one.
329            pub fn is_one(&self) -> bool {
330                self.data[0] == 1 && self.data.iter().all(|&x| x == 0)
331            }
332
333            /// Create this type from little endian bytes.
334            pub fn from_le_bytes(bytes: [u8; $size]) -> Self {
335                let mut data = [0; Self::SIZE];
336                for i in 0..data.len() {
337                    if i < bytes.len() {
338                        data[i] = bytes[i];
339                    } else {
340                        data[i] = 0;
341                    }
342                }
343                Self { data }
344            }
345
346            /// Create this type from big endian bytes.
347            pub fn from_be_bytes(bytes: [u8; $size]) -> Self {
348                let mut data = [0; Self::SIZE];
349                for i in 0..data.len() {
350                    if i < bytes.len() {
351                        data[i] = bytes[i];
352                    } else {
353                        data[i] = 0;
354                    }
355                }
356                data.reverse();
357                Self { data }
358            }
359
360            /// Return the little endian representation of this type.
361            pub fn to_le_bytes(&self) -> [u8; $size] {
362                self.data
363            }
364
365            /// Return the big endian representation of this type.
366            pub fn to_be_bytes(&self) -> [u8; $size] {
367                let mut data = self.data;
368                data.reverse();
369                data
370            }
371
372            /// Convert this type to little endian.
373            pub fn to_le(&self) -> Self {
374                self.clone()
375            }
376
377            /// Convert this type to big endian.
378            pub fn to_be(&self) -> Self {
379                Self {
380                    data: self.to_be_bytes(),
381                }
382            }
383
384            /// Return count of leading zeros.
385            pub fn leading_zeros(&self) -> u32 {
386                let mut data = self.data;
387                data.reverse();
388                let mut zeros = 0;
389                for i in 0..Self::SIZE {
390                    let z = data[i].leading_zeros();
391                    zeros += z;
392                    if z != 8 {
393                        break;
394                    }
395                }
396                zeros
397            }
398
399            /// Return count of trailing zeros.
400            pub fn trailing_zeros(&self) -> u32 {
401                let data = self.data;
402                let mut zeros = 0;
403                for i in 0..Self::SIZE {
404                    let z = data[i].trailing_zeros();
405                    zeros += z;
406                    if z != 8 {
407                        break;
408                    }
409                }
410                zeros
411            }
412
413            /// Return count of leading ones.
414            pub fn leading_ones(&self) -> u32 {
415                let mut data = self.data;
416                data.reverse();
417                let mut ones = 0;
418                for i in 0..Self::SIZE {
419                    let o = data[i].leading_ones();
420                    ones += o;
421                    if o != 8 {
422                        break;
423                    }
424                }
425                ones
426            }
427
428            /// Return count of trailing ones.
429            pub fn trailing_ones(&self) -> u32 {
430                let data = self.data;
431                let mut ones = 0;
432                for i in 0..Self::SIZE {
433                    let o = data[i].trailing_ones();
434                    ones += o;
435                    if o != 8 {
436                        break;
437                    }
438                }
439                ones
440            }
441
442            impl_maths!($size);
443
444            impl_shift!();
445        }
446
447        impl_math_ops!($S);
448        impl_bit_ops!($S);
449    };
450}
451
452#[macro_export]
453macro_rules! from_prim {
454    ($S:ident, $( $T:ty ),*) => {
455        $(
456            impl From<$T> for $S {
457                fn from(x: $T) -> Self {
458                    let mut data = [0; Self::SIZE];
459                    let bytes = x.to_le_bytes();
460                    for i in 0..data.len() {
461                        if i < bytes.len() {
462                            data[i] = bytes[i];
463                        } else {
464                            break;
465                        }
466                    }
467                    Self { data }
468                }
469            }
470
471            impl From<$S> for $T {
472                fn from(x: $S) -> Self {
473                    let mut bytes = [0; byte_size!($T)];
474                    let data = x.data;
475                    for i in 0..bytes.len() {
476                        if i < data.len() {
477                            bytes[i] = data[i];
478                        } else {
479                            break;
480                        }
481                    }
482                    <$T>::from_le_bytes(bytes)
483                }
484            }
485        )*
486    };
487}
488
489#[macro_export]
490macro_rules! impl_maths {
491    ($size:expr) => {
492        /// Add two number and return the sum along with the carry.
493        pub fn overflowing_add(&self, other: Self) -> (Self, bool) {
494            let x = self.data;
495            let y = other.data;
496
497            let mut carry = 0;
498            let mut sum = [0; Self::SIZE];
499
500            for i in 0..x.len() {
501                let (s, c) = x[i].overflowing_add(y[i]);
502                let (s, c2) = s.overflowing_add(carry);
503                sum[i] = s;
504                carry = c as u8 + c2 as u8;
505            }
506
507            (Self { data: sum }, carry != 0)
508        }
509
510        /// Subtract two number and return the sum along with the borrow.
511        pub fn overflowing_sub(&self, other: Self) -> (Self, bool) {
512            let x = self.data;
513            let y = other.data;
514
515            let mut br = 0;
516            let mut sum = [0; Self::SIZE];
517
518            for i in 0..x.len() {
519                let (s, b) = x[i].overflowing_sub(y[i]);
520                let (s, b2) = s.overflowing_sub(br);
521                sum[i] = s;
522                br = b as u8 + b2 as u8;
523            }
524
525            (Self { data: sum }, br != 0)
526        }
527
528        /// Return product of two number after multiplication and bool indicating overflow.
529        pub fn overflowing_mul(&self, other: Self) -> (Self, bool) {
530            let x = self.data;
531            let y = other.data;
532
533            let mut res = [0; Self::SIZE * 2];
534            let mut resid = 0;
535            let mut temp: Vec<u8> = Vec::new();
536            let mut tempid = 0;
537            let mut carry = 0;
538            let mut c: Vec<u8> = Vec::new();
539
540            if y.len() == 1 && x.len() == 1 {
541                let (c, r) = mul8(x[0], y[0]);
542                let mut data = [0; Self::SIZE];
543                data[0] = r;
544                return (Self { data }, c != 0);
545            }
546
547            for i in 0..y.len() {
548                for j in 0..x.len() {
549                    if i == 0 && j == 0 {
550                        let (cr, r) = mul8(x[j], y[i]);
551                        res[resid] = r;
552                        resid += 1;
553                        carry = cr;
554                        continue;
555                    }
556
557                    if i == 0 {
558                        if j == (x.len() - 1) {
559                            let (cc, rr) = mul_r(carry, x[j], y[i]);
560                            c.push(cc);
561                            temp.push(rr);
562                            carry = 0;
563                            continue;
564                        }
565
566                        let (cr, rr) = mul_r(carry, x[j], y[i]);
567                        carry = cr;
568                        temp.push(rr);
569                        continue;
570                    }
571
572                    if i != y.len() - 1 {
573                        if j == 0 {
574                            let (cr, r) = mul_r(temp[0], x[j], y[i]);
575                            res[resid] = r;
576                            resid += 1;
577                            carry = cr;
578                            temp.remove(0);
579                            continue;
580                        } else if j == x.len() - 1 {
581                            let (cc, rr) = mul_carry(c[0], x[j], y[i], carry);
582                            c[0] = cc;
583                            temp.push(rr);
584                            tempid = 0;
585                            carry = 0;
586                            continue;
587                        } else {
588                            let (cr, rr) = mul_carry(temp[tempid], x[j], y[i], carry);
589                            temp[tempid] = rr;
590                            carry = cr;
591                            tempid += 1;
592                            continue;
593                        }
594                    }
595
596                    if j == 0 {
597                        let (cr, r) = mul_r(temp[0], x[j], y[i]);
598                        res[resid] = r;
599                        carry = cr;
600                        resid += 1;
601                        temp.remove(0);
602                        continue;
603                    } else if j != x.len() - 1 {
604                        let (cr, r) = mul_carry(temp[0], x[j], y[i], carry);
605                        res[resid] = r;
606                        carry = cr;
607                        resid += 1;
608                        temp.remove(0);
609                        continue;
610                    } else {
611                        let (a, b) = mul_carry(c[0], x[j], y[i], carry);
612                        res[resid] = a;
613                        resid += 1;
614                        res[resid] = b;
615                        carry = 0;
616                        continue;
617                    }
618                }
619            }
620
621            let mut data = [0; Self::SIZE];
622            data.copy_from_slice(&res[..Self::SIZE]);
623            let mut ov = [0; Self::SIZE];
624            ov.copy_from_slice(&res[Self::SIZE..]);
625
626            let prod2 = Self { data: ov };
627
628            (Self { data }, !prod2.is_zero())
629        }
630
631        /// Devides u by single normalized word d and produces both quotient and remainder.
632        fn div_rem_by1(u: &[u8], d: u8) -> ([u8; $size], u8) {
633            let reciprocal = reciprocal_2by1(d);
634            let mut q = [0u8; Self::SIZE];
635            let mut r = u[u.len() - 1];
636
637            for i in (0..u.len() - 1).rev() {
638                (q[i], r) = div_rem_2by1(r, u[i], d, reciprocal);
639            }
640
641            (q, r)
642        }
643
644        /// Implement division of u by multiple normalized words d from the Knuth's algorithm.
645        fn div_rem_knuth(u: &[u8], d: &[u8]) -> ([u8; $size], [u8; $size]) {
646            let mut q = [0u8; Self::SIZE];
647            let dh = d[d.len() - 1];
648            let dl = d[d.len() - 2];
649            let reciprocal = reciprocal_2by1(dh);
650            let mut u = u.to_vec();
651
652            for j in (0..u.len() - d.len()).rev() {
653                let u2 = u[j + d.len()];
654                let u1 = u[j + d.len() - 1];
655                let u0 = u[j + d.len() - 2];
656
657                #[allow(unused_mut)]
658                let (mut qhat, mut rhat);
659
660                if u2 >= dh {
661                    qhat = !0u8;
662                } else {
663                    (qhat, rhat) = div_rem_2by1(u2, u1, dh, reciprocal);
664                    let (ph, pl) = mul8(qhat, dl);
665                    if ph > rhat || (ph == rhat && pl > u0) {
666                        qhat -= 1;
667                    }
668                }
669
670                let (nu, borrow) = sub_mul(&u[j..], d, qhat);
671                u[j..].copy_from_slice(&nu);
672                u[j + d.len()] = u2.overflowing_sub(borrow).0;
673
674                if u2 < borrow {
675                    qhat -= 1;
676                    let (nu, carry) = add_slice(&u[j..], d);
677                    u[j..].copy_from_slice(&nu);
678                    u[j + d.len()] = carry;
679                }
680
681                q[j] = qhat;
682            }
683
684            let mut rem = [0u8; Self::SIZE];
685            for i in 0..d.len() {
686                rem[i] = u[i];
687            }
688            (q, rem)
689        }
690
691        /// Divide two numbers and return tuple of the quotient and remainder.
692        pub fn div_rem(&self, rhs: Self) -> (Self, Self) {
693            let mut q = [0u8; Self::SIZE];
694            let mut r = [0u8; Self::SIZE];
695
696            // If the divisor is zero, return the dividend.
697            if rhs.is_zero() {
698                return (self.clone(), Self::zero());
699            }
700
701            let (u, d) = (self.data, rhs.data);
702
703            let mut dlen = 0usize;
704
705            for i in (0..d.len()).rev() {
706                if d[i] != 0 {
707                    dlen = i + 1;
708                    break;
709                }
710            }
711
712            let shift = d[dlen - 1].leading_zeros();
713
714            let dnstorage = [0u8; Self::SIZE];
715            let mut dn = dnstorage[..dlen].to_vec();
716
717            for i in (1..dlen).rev() {
718                dn[i] = ((d[i] as u16) << shift) as u8 | ((d[i - 1] as u16) >> (8 - shift)) as u8;
719            }
720            dn[0] = ((d[0] as u16) << shift) as u8;
721
722            let mut ulen = 0usize;
723
724            for i in (0..u.len()).rev() {
725                if u[i] != 0 {
726                    ulen = i + 1;
727                    break;
728                }
729            }
730
731            if ulen < dlen {
732                r.copy_from_slice(&u);
733                return (Self { data: q }, Self { data: r });
734            }
735
736            let unstorage = [0u8; Self::SIZE + 1];
737            let mut un = unstorage[..ulen + 1].to_vec();
738            un[ulen] = ((u[ulen - 1] as u16) >> (8 - shift)) as u8;
739
740            for i in (1..ulen).rev() {
741                un[i] = ((u[i] as u16) << shift) as u8 | ((u[i - 1] as u16) >> (8 - shift)) as u8;
742            }
743            un[0] = ((u[0] as u16) << shift) as u8;
744
745            if dlen == 1 {
746                let (qt, rt) = Self::div_rem_by1(&un, dn[0]);
747                r[0] = ((rt as u16) >> shift) as u8;
748                q = qt;
749
750                return (Self { data: q }, Self { data: r });
751            }
752
753            let (un, q) = Self::div_rem_knuth(&un, &dn);
754
755            for i in 0..d.len() - 1 {
756                r[i] = ((un[i] as u16) >> shift) as u8
757                    | ((un[i + 1] as u16) << (8 - shift) as u8) as u8;
758            }
759
760            r[dlen - 1] = ((un[dlen - 1] as u16) >> shift) as u8;
761
762            return (Self { data: q }, Self { data: r });
763        }
764    };
765}
766
767#[macro_export]
768macro_rules! impl_shift {
769    () => {
770        /// Shift left and return the result along with boolean indicating overflow.
771        pub fn overflowing_shl(&self, n: u32) -> (Self, bool) {
772            if n == 0 {
773                return (self.clone(), false);
774            }
775
776            if n >= Self::BITS {
777                let mut shift = n;
778                while shift >= Self::BITS {
779                    shift -= Self::BITS;
780                }
781                return (self.overflowing_shl(shift).0, true);
782            }
783
784            let mut x = self.data;
785            x.reverse();
786
787            let mut data = [0u8; Self::SIZE];
788
789            for i in 0..x.len() {
790                if n == 8 {
791                    if i != x.len() - 1 {
792                        data[i] = x[i + 1];
793                    }
794                    continue;
795                }
796
797                if n % 8 == 0 {
798                    let q = (n / 8) as usize;
799                    if i + q <= x.len() - 1 {
800                        data[i] = x[i + q];
801                        continue;
802                    }
803                }
804
805                if n < 8 {
806                    data[i] = x[i] << n;
807                    if i < x.len() - 1 {
808                        data[i] |= x[i + 1] >> (8 - n);
809                    }
810                    continue;
811                }
812
813                if n > 8 {
814                    let q = (n / 8) as usize;
815                    if i + q <= x.len() - 1 {
816                        data[i] = x[i + q] << (n % 8);
817                        if i + 1 + q <= x.len() - 1 {
818                            data[i] |= x[i + 1 + q] >> (8 - (n % 8));
819                        }
820                        continue;
821                    }
822                }
823            }
824
825            data.reverse();
826
827            (Self { data }, false)
828        }
829
830        /// Shift right and return the result along with boolean indicating overflow.
831        pub fn overflowing_shr(&self, n: u32) -> (Self, bool) {
832            if n == 0 {
833                return (self.clone(), false);
834            }
835
836            if n >= Self::BITS {
837                let mut shift = n;
838                while shift >= Self::BITS {
839                    shift -= Self::BITS;
840                }
841                return (self.overflowing_shl(shift).0, true);
842            }
843
844            let x = self.data;
845            let mut data = [0u8; Self::SIZE];
846
847            for i in 0..x.len() {
848                if n == 8 {
849                    if i != x.len() - 1 {
850                        data[i] = x[i + 1];
851                    }
852                    continue;
853                }
854
855                if n % 8 == 0 {
856                    let q = (n / 8) as usize;
857                    if i + q <= x.len() - 1 {
858                        data[i] = x[i + q];
859                        continue;
860                    }
861                }
862
863                if n < 8 {
864                    data[i] = x[i] >> n;
865                    if i < x.len() - 1 {
866                        data[i] |= x[i + 1] << (8 - n);
867                    }
868                    continue;
869                }
870
871                if n > 8 {
872                    let q = (n / 8) as usize;
873                    if i + q <= x.len() - 1 {
874                        data[i] = x[i + q] >> (n % 8);
875                        if i + 1 + q <= x.len() - 1 {
876                            data[i] |= x[i + 1 + q] << (8 - (n % 8));
877                        }
878                        continue;
879                    }
880                }
881            }
882
883            (Self { data }, false)
884        }
885    };
886}
887
888#[macro_export]
889macro_rules! impl_math_ops {
890    ($( $S:ident ),*) => {
891        $(
892            impl Add for $S {
893                type Output = $S;
894
895                fn add(self, other: $S) -> $S {
896                    let (sum, carry) = self.overflowing_add(other);
897                    if carry {
898                        panic!("attempt to add with overflow");
899                    }
900                    sum
901                }
902            }
903
904            impl AddAssign for $S {
905                fn add_assign(&mut self, other: $S) {
906                    *self = *self + other;
907                }
908            }
909
910            impl Sub for $S {
911                type Output = $S;
912
913                fn sub(self, other: $S) -> $S {
914                    let (sum, borrow) = self.overflowing_sub(other);
915                    if borrow {
916                        panic!("attempt to subtract with underflow");
917                    }
918                    sum
919                }
920            }
921
922            impl SubAssign for $S {
923                fn sub_assign(&mut self, other: $S) {
924                    *self = *self - other;
925                }
926            }
927
928            impl Mul for $S {
929                type Output = $S;
930
931                fn mul(self, other: $S) -> $S {
932                    let (prod, carry) = self.overflowing_mul(other);
933
934                    if carry {
935                        panic!("attempt to multiply with upperflow");
936                    }
937                    prod
938                }
939            }
940
941            impl MulAssign for $S {
942                fn mul_assign(&mut self, other: $S) {
943                    *self = *self * other;
944                }
945            }
946
947            impl Div for $S {
948                type Output = $S;
949
950                fn div(self, other: $S) -> $S {
951                    self.div_rem(other).0
952                }
953            }
954
955            impl DivAssign for $S {
956                fn div_assign(&mut self, other: $S) {
957                    *self = *self / other;
958                }
959            }
960
961            impl Rem for $S {
962                type Output = $S;
963
964                fn rem(self, other: $S) -> Self {
965                    self.div_rem(other).1
966                }
967            }
968
969            impl RemAssign for $S {
970                fn rem_assign(&mut self, other: $S) {
971                    *self = *self % other;
972                }
973            }
974        )*
975    };
976}
977
978#[macro_export]
979macro_rules! impl_bit_ops {
980    ($($S:ident),*) => {
981        $(
982            impl BitAnd for $S {
983                type Output = $S;
984
985                fn bitand(self, rhs: Self) -> Self::Output {
986                    let x = self.data;
987                    let y = rhs.data;
988                    let mut data = [0; Self::SIZE];
989
990                    for i in 0..x.len() {
991                        data[i] = x[i] & y[i];
992                    }
993
994                    Self { data }
995                }
996            }
997
998            impl BitAndAssign for $S {
999                fn bitand_assign(&mut self, rhs: Self) {
1000                    *self = *self & rhs;
1001                }
1002            }
1003
1004            impl BitOr for $S {
1005                type Output = $S;
1006
1007                fn bitor(self, rhs: Self) -> Self::Output {
1008                    let x = self.data;
1009                    let y = rhs.data;
1010                    let mut data = [0; Self::SIZE];
1011
1012                    for i in 0..x.len() {
1013                        data[i] = x[i] | y[i];
1014                    }
1015
1016                    Self { data }
1017                }
1018            }
1019
1020            impl BitOrAssign for $S {
1021                fn bitor_assign(&mut self, rhs: Self) {
1022                    *self = *self | rhs;
1023                }
1024            }
1025
1026            impl BitXor for $S {
1027                type Output = $S;
1028
1029                fn bitxor(self, rhs: Self) -> Self::Output {
1030                    let x = self.data;
1031                    let y = rhs.data;
1032                    let mut data = [0; Self::SIZE];
1033
1034                    for i in 0..x.len() {
1035                        data[i] = x[i] ^ y[i];
1036                    }
1037
1038                    Self { data }
1039                }
1040            }
1041
1042            impl BitXorAssign for $S {
1043                fn bitxor_assign(&mut self, rhs: Self) {
1044                    *self = *self ^ rhs;
1045                }
1046            }
1047
1048            impl Not for $S {
1049                type Output = $S;
1050
1051                fn not(self) -> Self::Output {
1052                    let mut data = self.data;
1053                    for i in 0..data.len() {
1054                        data[i] = !data[i];
1055                    }
1056                    Self { data }
1057                }
1058            }
1059
1060            impl Shl<u32> for $S {
1061                type Output = $S;
1062
1063                fn shl(self, n: u32) -> Self::Output {
1064                    let (x, ov) = self.overflowing_shl(n);
1065                    if ov {
1066                        panic!("attemp to shift left with overflow.")
1067                    }
1068                    x
1069                }
1070            }
1071
1072            impl ShlAssign<u32> for $S {
1073                fn shl_assign(&mut self, n: u32) {
1074                    *self = *self << n;
1075                }
1076            }
1077
1078            impl Shr<u32> for $S {
1079                type Output = $S;
1080
1081                fn shr(self, n: u32) -> Self::Output {
1082                    let (x, ov) = self.overflowing_shr(n);
1083                    if ov {
1084                        panic!("attemp to shift right with overflow.")
1085                    }
1086                    x
1087                }
1088            }
1089
1090            impl ShrAssign<u32> for $S {
1091                fn shr_assign(&mut self, n: u32) {
1092                    *self = *self >> n;
1093                }
1094            }
1095        )*
1096    };
1097}