fugue_bv/
core_mixed.rs

1use std::borrow::Cow;
2use std::cmp::Ordering;
3use std::fmt;
4use std::ops::{
5    Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
6    Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
7};
8use std::str::FromStr;
9
10use fugue_bytes::Order;
11use rug::Integer as BigInt;
12
13use crate::error::{ParseError, TryFromBitVecError};
14use crate::{core_bigint, core_u64};
15
16pub const MAX_BITS: Option<u32> = core_bigint::MAX_BITS;
17
18#[derive(Debug, Clone, Hash, serde::Deserialize, serde::Serialize)]
19pub enum BitVec {
20    N(core_u64::BitVec),
21    U(core_bigint::BitVec),
22}
23
24#[inline(always)]
25fn apply1<F, T, O>(f: F, t: T) -> O
26where
27    F: FnOnce(T) -> O,
28{
29    f(t)
30}
31
32fn apply2<F, T, O>(f: F, u: T, v: T) -> O
33where
34    F: FnOnce(T, T) -> O,
35{
36    f(u, v)
37}
38
39fn apply2_mut<F, T>(f: F, u: &mut T, v: &T)
40where
41    F: FnOnce(&mut T, &T),
42{
43    f(u, v)
44}
45
46macro_rules! bind {
47    ($self:ident, $f:expr) => {{
48        match $self {
49            BitVec::N(m) => BitVec::N(apply1($f, m)),
50            BitVec::U(m) => BitVec::U(apply1($f, m)),
51        }
52    }};
53    (ref $self:ident, $f:expr) => {{
54        match $self {
55            BitVec::N(ref m) => Self::N(apply1($f, m)),
56            BitVec::U(ref m) => Self::U(apply1($f, m)),
57        }
58    }};
59    (ref mut $self:ident, $f:expr) => {{
60        match $self {
61            BitVec::N(ref mut m) => Self::N(apply1($f, m)),
62            BitVec::U(ref mut m) => Self::U(apply1($f, m)),
63        }
64    }};
65}
66
67macro_rules! fold_map {
68    ($self:ident, $f:expr) => {{
69        match $self {
70            BitVec::N(m) => apply1($f, m),
71            BitVec::U(m) => apply1($f, m),
72        }
73    }};
74    (ref $self:ident, $f:expr) => {{
75        match $self {
76            BitVec::N(ref m) => apply1($f, m),
77            BitVec::U(ref m) => apply1($f, m),
78        }
79    }};
80    (ref mut $self:ident, $f:expr) => {{
81        match $self {
82            BitVec::N(ref mut m) => apply1($f, m),
83            BitVec::U(ref mut m) => apply1($f, m),
84        }
85    }};
86}
87
88macro_rules! bind2 {
89    ($self:ident, $other:ident, $f:expr) => {{
90        match ($self, $other) {
91            (BitVec::N(m), BitVec::N(n)) => BitVec::N(apply2($f, m, n)),
92            (BitVec::U(m), BitVec::U(n)) => BitVec::U(apply2($f, m, n)),
93            _ => panic!("cannot apply operation to operands with different bit sizes"),
94        }
95    }};
96    (ref $self:ident, $other:ident, $f:expr) => {{
97        match ($self, $other) {
98            (BitVec::N(ref m), BitVec::N(ref n)) => BitVec::N(apply2($f, m, n)),
99            (BitVec::U(ref m), BitVec::U(ref n)) => BitVec::U(apply2($f, m, n)),
100            _ => panic!("cannot apply operation to operands with different bit sizes"),
101        }
102    }};
103    (ref mut $self:ident, $other:ident, $f:expr) => {{
104        match ($self, $other) {
105            (BitVec::N(ref mut m), BitVec::N(ref mut n)) => BitVec::N(apply2($f, m, n)),
106            (BitVec::U(ref mut m), BitVec::U(ref mut n)) => BitVec::U(apply2($f, m, n)),
107            _ => panic!("cannot apply operation to operands with different bit sizes"),
108        }
109    }};
110}
111
112macro_rules! fold_map2 {
113    ($self:ident, $other:ident, $f:expr) => {{
114        match ($self, $other) {
115            (BitVec::N(m), BitVec::N(n)) => apply2($f, m, n),
116            (BitVec::U(m), BitVec::U(n)) => apply2($f, m, n),
117            _ => panic!("cannot apply operation to operands with different bit sizes"),
118        }
119    }};
120    (ref $self:ident, $other:ident, $f:expr) => {{
121        match ($self, $other) {
122            (BitVec::N(ref m), BitVec::N(ref n)) => apply2($f, m, n),
123            (BitVec::U(ref m), BitVec::U(ref n)) => apply2($f, m, n),
124            _ => panic!("cannot apply operation to operands with different bit sizes"),
125        }
126    }};
127    (ref mut $self:ident, ref $other:ident, $f:expr) => {{
128        match ($self, $other) {
129            (BitVec::N(ref mut m), BitVec::N(ref n)) => apply2_mut($f, m, n),
130            (BitVec::U(ref mut m), BitVec::U(ref n)) => apply2_mut($f, m, n),
131            _ => panic!("cannot apply operation to operands with different bit sizes"),
132        }
133    }};
134    (ref mut $self:ident, ref mut $other:ident, $f:expr) => {{
135        match ($self, $other) {
136            (BitVec::N(ref mut m), BitVec::N(ref mut n)) => apply2($f, m, n),
137            (BitVec::U(ref mut m), BitVec::U(ref mut n)) => apply2($f, m, n),
138            _ => panic!("cannot apply operation to operands with different bit sizes"),
139        }
140    }};
141}
142
143impl From<core_u64::BitVec> for BitVec {
144    fn from(bv: core_u64::BitVec) -> Self {
145        Self::N(bv)
146    }
147}
148
149impl From<core_bigint::BitVec> for BitVec {
150    fn from(bv: core_bigint::BitVec) -> Self {
151        Self::U(bv)
152    }
153}
154
155impl fmt::Display for BitVec {
156    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157        fold_map!(self, |slf| fmt::Display::fmt(slf, f))
158    }
159}
160
161impl fmt::LowerHex for BitVec {
162    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163        fold_map!(self, |slf| fmt::LowerHex::fmt(slf, f))
164    }
165}
166
167impl fmt::UpperHex for BitVec {
168    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
169        fold_map!(self, |slf| fmt::UpperHex::fmt(slf, f))
170    }
171}
172
173impl fmt::Binary for BitVec {
174    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
175        fold_map!(self, |slf| fmt::Binary::fmt(slf, f))
176    }
177}
178
179impl FromStr for BitVec {
180    type Err = ParseError;
181
182    fn from_str(s: &str) -> Result<Self, Self::Err> {
183        let (cst, sz) = s.rsplit_once(':').ok_or(ParseError::InvalidFormat)?;
184
185        let val = if let Some(cstv) = cst.strip_prefix("0x") {
186            BigInt::from_str_radix(cstv, 16)
187        } else {
188            BigInt::from_str_radix(cst, 10)
189        }
190        .map_err(|_| ParseError::InvalidConst)?;
191
192        let bits = usize::from_str(sz).map_err(|_| ParseError::InvalidSize)?;
193
194        Ok(Self::from_bigint(val, bits))
195    }
196}
197
198impl BitVec {
199    pub fn from_str_radix(s: &str, radix: u32) -> Result<Self, ParseError> {
200        let (cst, sz) = s.rsplit_once(':').ok_or(ParseError::InvalidFormat)?;
201        let val =
202            BigInt::from_str_radix(cst, radix as i32).map_err(|_| ParseError::InvalidConst)?;
203
204        let bits = usize::from_str(sz).map_err(|_| ParseError::InvalidSize)?;
205        Ok(Self::from_bigint(val, bits))
206    }
207}
208
209impl BitVec {
210    pub fn from_bigint(v: BigInt, bits: usize) -> Self {
211        if bits <= 64 {
212            let v = core_bigint::BitVec::from_bigint(v, bits).to_u64().unwrap();
213            Self::N(core_u64::BitVec::from_uint(v, bits))
214        } else {
215            Self::U(core_bigint::BitVec::from_bigint(v, bits))
216        }
217    }
218
219    #[allow(unused)]
220    pub(crate) fn from_bigint_with(v: BigInt, mask: &'static BigInt) -> Self {
221        let bits = mask.count_ones().unwrap() as usize;
222        if bits <= 64 {
223            let v = core_bigint::BitVec::from_bigint_with(v, mask)
224                .to_u64()
225                .unwrap();
226            Self::N(core_u64::BitVec::from_uint(v, bits))
227        } else {
228            Self::U(core_bigint::BitVec::from_bigint_with(v, mask))
229        }
230    }
231
232    pub fn as_bigint(&self) -> Cow<BigInt> {
233        match self {
234            Self::N(ref bv) => Cow::Owned(BigInt::from(bv.0)),
235            Self::U(ref bv) => Cow::Borrowed(bv.as_raw()),
236        }
237    }
238
239    #[inline(always)]
240    pub fn as_raw(&self) -> Cow<BigInt> {
241        self.as_bigint()
242    }
243
244    pub fn zero(bits: usize) -> Self {
245        if bits <= 64 {
246            Self::N(core_u64::BitVec::zero(bits))
247        } else {
248            Self::U(core_bigint::BitVec::zero(bits))
249        }
250    }
251
252    pub fn one(bits: usize) -> Self {
253        if bits <= 64 {
254            Self::N(core_u64::BitVec::one(bits))
255        } else {
256            Self::U(core_bigint::BitVec::one(bits))
257        }
258    }
259
260    pub fn count_ones(&self) -> u32 {
261        fold_map!(self, |slf| slf.count_ones())
262    }
263
264    pub fn count_zeros(&self) -> u32 {
265        fold_map!(self, |slf| slf.count_zeros())
266    }
267
268    pub fn leading_ones(&self) -> u32 {
269        fold_map!(self, |slf| slf.leading_ones())
270    }
271
272    pub fn leading_zeros(&self) -> u32 {
273        fold_map!(self, |slf| slf.leading_zeros())
274    }
275
276    pub fn bits(&self) -> usize {
277        fold_map!(self, |slf| slf.bits())
278    }
279
280    pub fn signed(self) -> Self {
281        bind!(self, |slf| slf.signed())
282    }
283
284    pub fn signed_assign(&mut self) {
285        fold_map!(ref mut self, |slf| slf.signed_assign());
286    }
287
288    pub fn is_zero(&self) -> bool {
289        fold_map!(self, |slf| slf.is_zero())
290    }
291
292    pub fn is_one(&self) -> bool {
293        fold_map!(self, |slf| slf.is_one())
294    }
295
296    pub fn is_signed(&self) -> bool {
297        fold_map!(self, |slf| slf.is_signed())
298    }
299
300    pub fn is_negative(&self) -> bool {
301        fold_map!(self, |slf| slf.is_negative())
302    }
303
304    pub fn unsigned(self) -> Self {
305        bind!(self, |slf| slf.unsigned())
306    }
307
308    pub fn unsigned_assign(&mut self) {
309        fold_map!(ref mut self, |slf| slf.unsigned_assign());
310    }
311
312    pub fn is_unsigned(&self) -> bool {
313        fold_map!(self, |slf| slf.is_unsigned())
314    }
315
316    pub fn bit(&self, index: u32) -> bool {
317        fold_map!(self, |slf| slf.bit(index))
318    }
319
320    pub fn set_bit(&mut self, index: u32) {
321        fold_map!(self, |slf| slf.set_bit(index))
322    }
323
324    pub fn leading_one(&self) -> Option<u32> {
325        fold_map!(self, |slf| slf.leading_one())
326    }
327
328    pub fn msb(&self) -> bool {
329        fold_map!(self, |slf| slf.msb())
330    }
331
332    pub fn lsb(&self) -> bool {
333        fold_map!(self, |slf| slf.lsb())
334    }
335
336    pub fn from_be_bytes(buf: &[u8]) -> Self {
337        if buf.len() <= 8 {
338            Self::N(core_u64::BitVec::from_be_bytes(buf))
339        } else {
340            Self::U(core_bigint::BitVec::from_be_bytes(buf))
341        }
342    }
343
344    pub fn from_le_bytes(buf: &[u8]) -> Self {
345        if buf.len() <= 8 {
346            Self::N(core_u64::BitVec::from_le_bytes(buf))
347        } else {
348            Self::U(core_bigint::BitVec::from_le_bytes(buf))
349        }
350    }
351
352    #[inline(always)]
353    pub fn from_ne_bytes(buf: &[u8]) -> Self {
354        if cfg!(target_endian = "big") {
355            Self::from_be_bytes(buf)
356        } else {
357            Self::from_le_bytes(buf)
358        }
359    }
360
361    pub fn to_be_bytes(&self, buf: &mut [u8]) {
362        fold_map!(self, |slf| slf.to_be_bytes(buf))
363    }
364
365    pub fn to_le_bytes(&self, buf: &mut [u8]) {
366        fold_map!(self, |slf| slf.to_le_bytes(buf))
367    }
368
369    #[inline(always)]
370    pub fn to_ne_bytes(&self, buf: &mut [u8]) {
371        if cfg!(target_endian = "big") {
372            self.to_be_bytes(buf)
373        } else {
374            self.to_le_bytes(buf)
375        }
376    }
377
378    pub fn from_bytes<O: Order>(bytes: &[u8], signed: bool) -> BitVec {
379        let v = if O::ENDIAN.is_big() {
380            Self::from_be_bytes(bytes)
381        } else {
382            Self::from_le_bytes(bytes)
383        };
384
385        if signed {
386            v.signed()
387        } else {
388            v
389        }
390    }
391
392    pub fn into_bytes<O: Order>(self, bytes: &mut [u8]) {
393        if O::ENDIAN.is_big() {
394            self.to_be_bytes(bytes)
395        } else {
396            self.to_le_bytes(bytes)
397        }
398    }
399
400    pub fn incr(&self, value: u64) -> Self {
401        self + &BitVec::from_u64(value, self.bits())
402    }
403
404    pub fn succ(&self) -> Self {
405        self.incr(1)
406    }
407
408    pub fn decr(&self, value: u64) -> Self {
409        self - &BitVec::from_u64(value, self.bits())
410    }
411
412    pub fn pred(&self) -> Self {
413        self.decr(1)
414    }
415
416    pub fn abs(&self) -> BitVec {
417        if self.is_negative() {
418            -self
419        } else {
420            self.clone()
421        }
422    }
423
424    pub fn lcm(&self, rhs: &Self) -> Self {
425        bind2!(self, rhs, |slf, rhs| slf.lcm(rhs))
426    }
427
428    pub fn gcd(&self, rhs: &Self) -> Self {
429        bind2!(self, rhs, |slf, rhs| slf.gcd(rhs))
430    }
431
432    pub fn gcd_ext(&self, rhs: &Self) -> (Self, Self, Self) {
433        fold_map2!(self, rhs, |slf, rhs| {
434            let (g, a, b) = slf.gcd_ext(rhs);
435            (g.into(), a.into(), b.into())
436        })
437    }
438
439    pub fn signed_borrow(&self, rhs: &Self) -> bool {
440        fold_map2!(self, rhs, |slf, rhs| slf.signed_borrow(rhs))
441    }
442
443    pub fn carry(&self, rhs: &Self) -> bool {
444        fold_map2!(self, rhs, |slf, rhs| slf.carry(rhs))
445    }
446
447    pub fn signed_carry(&self, rhs: &Self) -> bool {
448        fold_map2!(self, rhs, |slf, rhs| slf.signed_carry(rhs))
449    }
450
451    pub fn rem_euclid(&self, rhs: &Self) -> Self {
452        bind2!(self, rhs, |slf, rhs| slf.rem_euclid(rhs))
453    }
454
455    pub fn max_value_with(bits: usize, signed: bool) -> Self {
456        if bits <= 64 {
457            Self::N(core_u64::BitVec::max_value_with(bits, signed))
458        } else {
459            Self::U(core_bigint::BitVec::max_value_with(bits, signed))
460        }
461    }
462
463    pub fn max_value(&self) -> Self {
464        bind!(self, |slf| slf.max_value())
465    }
466
467    pub fn min_value_with(bits: usize, signed: bool) -> Self {
468        if bits <= 64 {
469            Self::N(core_u64::BitVec::min_value_with(bits, signed))
470        } else {
471            Self::U(core_bigint::BitVec::min_value_with(bits, signed))
472        }
473    }
474
475    pub fn min_value(&self) -> Self {
476        bind!(self, |slf| slf.min_value())
477    }
478
479    pub fn signed_cast(&self, size: usize) -> Self {
480        self.clone().signed().cast(size)
481    }
482
483    pub fn unsigned_cast(&self, size: usize) -> Self {
484        self.clone().unsigned().cast(size)
485    }
486
487    pub fn signed_cast_assign(&mut self, bits: usize) {
488        self.cast_assign_with(true, bits)
489    }
490
491    pub fn unsigned_cast_assign(&mut self, bits: usize) {
492        self.cast_assign_with(false, bits)
493    }
494
495    pub fn cast(self, size: usize) -> Self {
496        let signed = self.is_signed();
497        self.cast_with(signed, size)
498    }
499
500    fn cast_with(self, signed: bool, size: usize) -> Self {
501        match self {
502            Self::N(bv) => {
503                if size <= 64 {
504                    if signed {
505                        Self::N(bv.signed().cast(size).signed())
506                    } else {
507                        Self::N(bv.unsigned().cast(size))
508                    }
509                } else {
510                    let v = core_bigint::BitVec::from_u64(bv.0, bv.bits());
511                    Self::U(if signed {
512                        v.signed().cast(size).signed()
513                    } else {
514                        v.unsigned().cast(size)
515                    })
516                }
517            }
518            Self::U(bv) => {
519                if size <= 64 {
520                    let v = core_u64::BitVec::from_u64(bv.cast(64).to_u64().unwrap(), 64);
521                    Self::N(if signed {
522                        v.signed().cast(size).signed()
523                    } else {
524                        v.unsigned().cast(size)
525                    })
526                } else {
527                    if signed {
528                        Self::U(bv.signed().cast(size).signed())
529                    } else {
530                        Self::U(bv.unsigned().cast(size))
531                    }
532                }
533            }
534        }
535    }
536
537    pub fn cast_assign(&mut self, size: usize) {
538        let signed = self.is_signed();
539        self.cast_assign_with(signed, size)
540    }
541
542    fn cast_assign_with(&mut self, signed: bool, size: usize) {
543        match self {
544            Self::N(ref mut bv) => {
545                if size <= 64 {
546                    if signed {
547                        bv.signed_cast_assign(size);
548                    } else {
549                        bv.unsigned_cast_assign(size);
550                    }
551                } else {
552                    let mut v = core_bigint::BitVec::from_u64(bv.0, bv.bits());
553                    if signed {
554                        v.signed_cast_assign(size);
555                    } else {
556                        v.unsigned_cast_assign(size);
557                    }
558                    *self = Self::U(v);
559                }
560            }
561            Self::U(ref mut bv) => {
562                if size <= 64 {
563                    if signed {
564                        bv.signed_cast_assign(64);
565                    } else {
566                        bv.unsigned_cast_assign(64);
567                    }
568                    let mut v = core_u64::BitVec::from_u64(bv.to_u64().unwrap(), 64);
569                    if signed {
570                        v.signed_cast_assign(size);
571                    } else {
572                        v.unsigned_cast_assign(size);
573                    }
574                    *self = Self::N(v);
575                } else {
576                    if signed {
577                        bv.signed_cast_assign(size);
578                    } else {
579                        bv.unsigned_cast_assign(size);
580                    }
581                }
582            }
583        }
584    }
585}
586
587impl PartialEq<Self> for BitVec {
588    fn eq(&self, other: &Self) -> bool {
589        self.bits() == other.bits() && fold_map2!(self, other, |slf, other| slf.eq(other))
590    }
591}
592impl Eq for BitVec {}
593
594impl PartialOrd for BitVec {
595    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
596        Some(self.cmp(other))
597    }
598}
599impl Ord for BitVec {
600    fn cmp(&self, other: &Self) -> Ordering {
601        fold_map2!(self, other, |slf, other| slf.cmp(other))
602    }
603}
604
605impl BitVec {
606    pub fn signed_cmp(&self, other: &Self) -> Ordering {
607        fold_map2!(self, other, |slf, other| slf.signed_cmp(other))
608    }
609}
610
611impl Neg for BitVec {
612    type Output = Self;
613
614    fn neg(self) -> Self::Output {
615        bind!(self, |slf| slf.neg())
616    }
617}
618
619impl BitVec {
620    pub fn neg_assign(&mut self) {
621        fold_map!(ref mut self, |slf| slf.neg_assign())
622    }
623}
624
625impl<'a> Neg for &'a BitVec {
626    type Output = BitVec;
627
628    fn neg(self) -> Self::Output {
629        bind!(self, |slf| slf.neg())
630    }
631}
632
633impl Not for BitVec {
634    type Output = Self;
635
636    fn not(self) -> Self::Output {
637        bind!(self, |slf| slf.not())
638    }
639}
640
641impl<'a> Not for &'a BitVec {
642    type Output = BitVec;
643
644    fn not(self) -> Self::Output {
645        bind!(self, |slf| slf.not())
646    }
647}
648
649impl BitVec {
650    pub fn not_assign(&mut self) {
651        fold_map!(ref mut self, |slf| slf.not_assign())
652    }
653}
654
655impl Add for BitVec {
656    type Output = Self;
657
658    fn add(self, rhs: Self) -> Self::Output {
659        bind2!(self, rhs, |slf, rhs| slf.add(rhs))
660    }
661}
662
663impl<'a> Add for &'a BitVec {
664    type Output = BitVec;
665
666    fn add(self, rhs: Self) -> Self::Output {
667        bind2!(self, rhs, |slf, rhs| slf.add(rhs))
668    }
669}
670
671impl AddAssign for BitVec {
672    fn add_assign(&mut self, rhs: Self) {
673        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.add_assign(rhs))
674    }
675}
676
677impl AddAssign<&'_ BitVec> for BitVec {
678    fn add_assign(&mut self, rhs: &BitVec) {
679        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.add_assign(rhs))
680    }
681}
682
683impl Div for BitVec {
684    type Output = Self;
685
686    fn div(self, rhs: Self) -> Self::Output {
687        bind2!(self, rhs, |slf, rhs| slf.div(rhs))
688    }
689}
690
691impl<'a> Div for &'a BitVec {
692    type Output = BitVec;
693
694    fn div(self, rhs: Self) -> Self::Output {
695        bind2!(self, rhs, |slf, rhs| slf.div(rhs))
696    }
697}
698
699impl DivAssign for BitVec {
700    fn div_assign(&mut self, rhs: Self) {
701        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.div_assign(rhs))
702    }
703}
704
705impl DivAssign<&'_ BitVec> for BitVec {
706    fn div_assign(&mut self, rhs: &BitVec) {
707        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.div_assign(rhs))
708    }
709}
710
711impl BitVec {
712    pub fn signed_div(&self, rhs: &Self) -> BitVec {
713        bind2!(self, rhs, |slf, rhs| slf.signed_div(rhs))
714    }
715
716    pub fn signed_div_assign(&mut self, rhs: &Self) {
717        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.signed_div_assign(rhs))
718    }
719}
720
721impl Mul for BitVec {
722    type Output = Self;
723
724    fn mul(self, rhs: Self) -> Self::Output {
725        bind2!(self, rhs, |slf, rhs| slf.mul(rhs))
726    }
727}
728
729impl<'a> Mul for &'a BitVec {
730    type Output = BitVec;
731
732    fn mul(self, rhs: Self) -> Self::Output {
733        bind2!(self, rhs, |slf, rhs| slf.mul(rhs))
734    }
735}
736
737impl MulAssign for BitVec {
738    fn mul_assign(&mut self, rhs: Self) {
739        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.mul_assign(rhs))
740    }
741}
742
743impl MulAssign<&'_ BitVec> for BitVec {
744    fn mul_assign(&mut self, rhs: &BitVec) {
745        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.mul_assign(rhs))
746    }
747}
748
749impl Rem for BitVec {
750    type Output = Self;
751
752    fn rem(self, rhs: Self) -> Self::Output {
753        bind2!(self, rhs, |slf, rhs| slf.rem(rhs))
754    }
755}
756
757impl<'a> Rem for &'a BitVec {
758    type Output = BitVec;
759
760    fn rem(self, rhs: Self) -> Self::Output {
761        bind2!(self, rhs, |slf, rhs| slf.rem(rhs))
762    }
763}
764
765impl RemAssign for BitVec {
766    fn rem_assign(&mut self, rhs: Self) {
767        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.rem_assign(rhs))
768    }
769}
770
771impl RemAssign<&'_ BitVec> for BitVec {
772    fn rem_assign(&mut self, rhs: &BitVec) {
773        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.rem_assign(rhs))
774    }
775}
776
777impl BitVec {
778    pub fn signed_rem(&self, rhs: &Self) -> BitVec {
779        bind2!(self, rhs, |slf, rhs| slf.signed_rem(rhs))
780    }
781
782    pub fn signed_rem_assign(&mut self, rhs: &Self) {
783        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.signed_rem_assign(rhs))
784    }
785}
786
787impl Sub for BitVec {
788    type Output = Self;
789
790    fn sub(self, rhs: Self) -> Self::Output {
791        bind2!(self, rhs, |slf, rhs| slf.sub(rhs))
792    }
793}
794
795impl<'a> Sub for &'a BitVec {
796    type Output = BitVec;
797
798    fn sub(self, rhs: Self) -> Self::Output {
799        bind2!(self, rhs, |slf, rhs| slf.sub(rhs))
800    }
801}
802
803impl SubAssign for BitVec {
804    fn sub_assign(&mut self, rhs: Self) {
805        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.sub_assign(rhs))
806    }
807}
808
809impl SubAssign<&'_ BitVec> for BitVec {
810    fn sub_assign(&mut self, rhs: &BitVec) {
811        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.sub_assign(rhs))
812    }
813}
814
815impl BitAnd for BitVec {
816    type Output = Self;
817
818    fn bitand(self, rhs: Self) -> Self::Output {
819        bind2!(self, rhs, |slf, rhs| slf.bitand(rhs))
820    }
821}
822
823impl<'a> BitAnd for &'a BitVec {
824    type Output = BitVec;
825
826    fn bitand(self, rhs: Self) -> Self::Output {
827        bind2!(self, rhs, |slf, rhs| slf.bitand(rhs))
828    }
829}
830
831impl BitAndAssign for BitVec {
832    fn bitand_assign(&mut self, rhs: Self) {
833        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.bitand_assign(rhs))
834    }
835}
836
837impl BitAndAssign<&'_ BitVec> for BitVec {
838    fn bitand_assign(&mut self, rhs: &BitVec) {
839        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.bitand_assign(rhs))
840    }
841}
842
843impl BitOr for BitVec {
844    type Output = Self;
845
846    fn bitor(self, rhs: Self) -> Self::Output {
847        bind2!(self, rhs, |slf, rhs| slf.bitor(rhs))
848    }
849}
850
851impl<'a> BitOr for &'a BitVec {
852    type Output = BitVec;
853
854    fn bitor(self, rhs: Self) -> Self::Output {
855        bind2!(self, rhs, |slf, rhs| slf.bitor(rhs))
856    }
857}
858
859impl BitOrAssign for BitVec {
860    fn bitor_assign(&mut self, rhs: Self) {
861        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.bitor_assign(rhs))
862    }
863}
864
865impl BitOrAssign<&'_ BitVec> for BitVec {
866    fn bitor_assign(&mut self, rhs: &BitVec) {
867        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.bitor_assign(rhs))
868    }
869}
870
871impl BitXor for BitVec {
872    type Output = Self;
873
874    fn bitxor(self, rhs: Self) -> Self::Output {
875        bind2!(self, rhs, |slf, rhs| slf.bitxor(rhs))
876    }
877}
878
879impl<'a> BitXor for &'a BitVec {
880    type Output = BitVec;
881
882    fn bitxor(self, rhs: Self) -> Self::Output {
883        bind2!(self, rhs, |slf, rhs| slf.bitxor(rhs))
884    }
885}
886
887impl BitXorAssign for BitVec {
888    fn bitxor_assign(&mut self, rhs: Self) {
889        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.bitxor_assign(rhs))
890    }
891}
892
893impl BitXorAssign<&'_ BitVec> for BitVec {
894    fn bitxor_assign(&mut self, rhs: &BitVec) {
895        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.bitxor_assign(rhs))
896    }
897}
898
899impl Shl<u32> for BitVec {
900    type Output = Self;
901
902    fn shl(self, rhs: u32) -> Self::Output {
903        bind!(self, |slf| slf.shl(rhs))
904    }
905}
906
907impl<'a> Shl<u32> for &'a BitVec {
908    type Output = BitVec;
909
910    fn shl(self, rhs: u32) -> Self::Output {
911        bind!(self, |slf| slf.shl(rhs))
912    }
913}
914
915impl ShlAssign<u32> for BitVec {
916    fn shl_assign(&mut self, rhs: u32) {
917        fold_map!(ref mut self, |slf| slf.shl_assign(rhs))
918    }
919}
920
921impl Shl for BitVec {
922    type Output = Self;
923
924    fn shl(self, rhs: Self) -> Self::Output {
925        bind2!(self, rhs, |slf, rhs| slf.shl(rhs))
926    }
927}
928
929impl<'a> Shl for &'a BitVec {
930    type Output = BitVec;
931
932    fn shl(self, rhs: Self) -> Self::Output {
933        bind2!(self, rhs, |slf, rhs| slf.shl(rhs))
934    }
935}
936
937impl ShlAssign for BitVec {
938    fn shl_assign(&mut self, rhs: Self) {
939        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.shl_assign(rhs))
940    }
941}
942
943impl ShlAssign<&'_ BitVec> for BitVec {
944    fn shl_assign(&mut self, rhs: &BitVec) {
945        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.shl_assign(rhs))
946    }
947}
948
949impl Shr<u32> for BitVec {
950    type Output = Self;
951
952    fn shr(self, rhs: u32) -> Self::Output {
953        bind!(self, |slf| slf.shr(rhs))
954    }
955}
956
957impl<'a> Shr<u32> for &'a BitVec {
958    type Output = BitVec;
959
960    fn shr(self, rhs: u32) -> Self::Output {
961        bind!(self, |slf| slf.shr(rhs))
962    }
963}
964
965impl ShrAssign<u32> for BitVec {
966    fn shr_assign(&mut self, rhs: u32) {
967        fold_map!(ref mut self, |slf| slf.shr_assign(rhs))
968    }
969}
970
971impl Shr for BitVec {
972    type Output = Self;
973
974    fn shr(self, rhs: Self) -> Self::Output {
975        bind2!(self, rhs, |slf, rhs| slf.shr(rhs))
976    }
977}
978
979impl<'a> Shr for &'a BitVec {
980    type Output = BitVec;
981
982    fn shr(self, rhs: Self) -> Self::Output {
983        bind2!(self, rhs, |slf, rhs| slf.shr(rhs))
984    }
985}
986
987impl ShrAssign for BitVec {
988    fn shr_assign(&mut self, rhs: Self) {
989        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.shr_assign(rhs))
990    }
991}
992
993impl ShrAssign<&'_ BitVec> for BitVec {
994    fn shr_assign(&mut self, rhs: &BitVec) {
995        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.shr_assign(rhs))
996    }
997}
998
999impl BitVec {
1000    pub fn signed_shr(&self, rhs: &Self) -> BitVec {
1001        bind2!(self, rhs, |slf, rhs| slf.signed_shr(rhs))
1002    }
1003
1004    pub fn signed_shr_assign(&mut self, rhs: &Self) {
1005        fold_map2!(ref mut self, ref rhs, |slf, rhs| slf.signed_shr_assign(rhs))
1006    }
1007}
1008
1009macro_rules! impl_from_for {
1010    ($t:ident) => {
1011        impl From<$t> for BitVec {
1012            fn from(t: $t) -> Self {
1013                let bits = ::std::mem::size_of::<$t>() * 8;
1014                if bits <= 64 {
1015                    Self::N(core_u64::BitVec::from(t))
1016                } else {
1017                    Self::U(core_bigint::BitVec::from(t))
1018                }
1019            }
1020        }
1021    };
1022}
1023
1024macro_rules! impls_from_for {
1025    ($($tname:ident),*) => {
1026        $(
1027            impl_from_for!($tname);
1028        )*
1029    };
1030}
1031
1032macro_rules! impl_to_u_for {
1033    ($t:tt) => {
1034        impl BitVec {
1035            ::paste::paste! {
1036                pub fn [< to_u $t >](&self) -> Option<[< u $t >]> {
1037                    fold_map!(self, |slf| slf.[< to_u $t >]())
1038                }
1039            }
1040        }
1041
1042        ::paste::paste! {
1043            impl ::std::convert::TryFrom<&'_ BitVec> for [< u $t >] {
1044                type Error = TryFromBitVecError;
1045
1046                fn try_from(bv: &BitVec) -> Result<[< u $t >], TryFromBitVecError> {
1047                    bv.[< to_u $t >]().ok_or(TryFromBitVecError)
1048                }
1049            }
1050        }
1051
1052        ::paste::paste! {
1053            impl ::std::convert::TryFrom<BitVec> for [< u $t >] {
1054                type Error = TryFromBitVecError;
1055
1056                fn try_from(bv: BitVec) -> Result<[< u $t >], TryFromBitVecError> {
1057                    bv.[< to_u $t >]().ok_or(TryFromBitVecError)
1058                }
1059            }
1060        }
1061    };
1062}
1063
1064macro_rules! impl_to_i_for {
1065    ($t:tt) => {
1066        impl BitVec {
1067            ::paste::paste! {
1068                pub fn [< to_i $t >](&self) -> Option<[< i $t >]> {
1069                    fold_map!(self, |slf| slf.[< to_i $t >]())
1070                }
1071            }
1072        }
1073
1074        ::paste::paste! {
1075            impl ::std::convert::TryFrom<&'_ BitVec> for [< i $t >] {
1076                type Error = TryFromBitVecError;
1077
1078                fn try_from(bv: &BitVec) -> Result<[< i $t >], TryFromBitVecError> {
1079                    bv.[< to_i $t >]().ok_or(TryFromBitVecError)
1080                }
1081            }
1082        }
1083
1084        ::paste::paste! {
1085            impl ::std::convert::TryFrom<BitVec> for [< i $t >] {
1086                type Error = TryFromBitVecError;
1087
1088                fn try_from(bv: BitVec) -> Result<[< i $t >], TryFromBitVecError> {
1089                    bv.[< to_i $t >]().ok_or(TryFromBitVecError)
1090                }
1091            }
1092        }
1093    };
1094}
1095
1096macro_rules! impl_from_t_for {
1097    ($t:ident) => {
1098        impl BitVec {
1099            ::paste::paste! {
1100                pub fn [< from_ $t >](t: $t, bits: usize) -> Self {
1101                    if bits <= 64 {
1102                        Self::N(core_u64::BitVec::[< from_ $t >](t, bits))
1103                    } else {
1104                        Self::U(core_bigint::BitVec::[< from_ $t >](t, bits))
1105                    }
1106                }
1107            }
1108        }
1109    };
1110}
1111
1112macro_rules! impls_to_u_for {
1113    ($($tname:tt),*) => {
1114        $(
1115            impl_to_u_for!($tname);
1116        )*
1117    };
1118}
1119
1120macro_rules! impls_to_i_for {
1121    ($($tname:tt),*) => {
1122        $(
1123            impl_to_i_for!($tname);
1124        )*
1125    };
1126}
1127
1128macro_rules! impls_from_t_for {
1129    ($($tname:ident),*) => {
1130        $(
1131            impl_from_t_for!($tname);
1132        )*
1133    };
1134}
1135
1136impls_from_for! { i8, i16, i32, i64, i128, isize }
1137impls_from_for! { u8, u16, u32, u64, u128, usize }
1138impls_from_t_for! { i8, i16, i32, i64, i128, isize }
1139impls_from_t_for! { u8, u16, u32, u64, u128, usize }
1140
1141impls_to_i_for! { 8, 16, 32, 64, 128, size }
1142impls_to_u_for! { 8, 16, 32, 64, 128, size }
1143
1144#[cfg(test)]
1145mod test {
1146    use super::*;
1147
1148    #[test]
1149    fn test_wrapped_add() {
1150        let v1 = BitVec::from(0xff00u16);
1151        let v2 = BitVec::from(0x0100u16);
1152
1153        assert_eq!(v1 + v2, BitVec::zero(16));
1154
1155        let v3 = BitVec::from_u32(0xffff00, 24);
1156        let v4 = BitVec::from_u32(0x000100, 24);
1157
1158        assert_eq!(v3 + v4, BitVec::zero(24));
1159
1160        let v5 = BitVec::from_i32(-1, 24);
1161        let v6 = BitVec::from_i32(1, 24);
1162
1163        assert_eq!(v5 + v6, BitVec::zero(24));
1164    }
1165
1166    #[test]
1167    fn test_wrapped_sub() {
1168        let v1 = BitVec::from(0xfffeu16);
1169        let v2 = BitVec::from(0xffffu16);
1170
1171        assert_eq!(v1 - v2, BitVec::from(0xffffu16));
1172
1173        let v3 = BitVec::from_u32(0xfffffe, 24);
1174        let v4 = BitVec::from_u32(0xffffff, 24);
1175
1176        assert_eq!(v3 - v4, BitVec::from_u32(0xffffff, 24));
1177
1178        let v5 = BitVec::from_u32(0x0, 120);
1179        let v6 = BitVec::from_u32(0x1, 120);
1180
1181        assert_eq!(v5 - v6, -BitVec::from_i32(0x1, 120))
1182    }
1183
1184    #[test]
1185    fn test_signed_shift_right() {
1186        let v1 = BitVec::from(0xffffu16);
1187        assert_eq!(v1 >> 4, BitVec::from(0x0fffu16));
1188
1189        let v2 = BitVec::from(0xffffu16);
1190        assert_eq!(v2.signed() >> 4, BitVec::from(0xffffu16));
1191
1192        let v3 = BitVec::from(0x8000u16);
1193        assert_eq!(v3.signed() >> 4, BitVec::from(0xf800u16));
1194
1195        let v4 = BitVec::from(0x05deu16);
1196        assert_eq!(v4.signed() >> 1u32, BitVec::from(0x2efu16));
1197    }
1198
1199    #[test]
1200    fn test_signed_rem() {
1201        let v1 = BitVec::from(-100i64);
1202        let v2 = BitVec::from(-27i64);
1203
1204        assert_eq!(v1.signed().rem(v2.signed()), BitVec::from(-19i64));
1205
1206        let v3 = BitVec::from(-100i64);
1207        let v4 = BitVec::from(27i64);
1208
1209        assert_eq!(v3.signed().rem(v4), BitVec::from(-19i64));
1210
1211        let v5 = BitVec::from(100i64);
1212        let v6 = BitVec::from(-27i64);
1213
1214        assert_eq!(v5.rem(v6.signed()), BitVec::from(19i64));
1215
1216        let v7 = BitVec::from(100i64);
1217        let v8 = BitVec::from(27i64);
1218
1219        assert_eq!(v7.signed().rem(v8), BitVec::from(19i64));
1220    }
1221
1222    #[test]
1223    fn test_signed_rem_euclid() {
1224        let v1 = BitVec::from(-100i64);
1225        let v2 = BitVec::from(-27i64);
1226
1227        assert_eq!(v1.signed().rem_euclid(&v2.signed()), BitVec::from(8i64));
1228
1229        let v3 = BitVec::from(-100i64);
1230        let v4 = BitVec::from(27i64);
1231
1232        assert_eq!(v3.signed().rem_euclid(&v4), BitVec::from(8i64));
1233
1234        let v5 = BitVec::from(100i64);
1235        let v6 = BitVec::from(-27i64);
1236
1237        assert_eq!(v5.rem_euclid(&v6.signed()), BitVec::from(19i64));
1238
1239        let v7 = BitVec::from(100i64);
1240        let v8 = BitVec::from(27i64);
1241
1242        assert_eq!(v7.signed().rem_euclid(&v8), BitVec::from(19i64));
1243
1244        let v1 = BitVec::from(7i64);
1245        let v2 = BitVec::from(4i64);
1246
1247        assert_eq!(v1.signed().rem_euclid(&v2.signed()), BitVec::from(3i64));
1248
1249        let v3 = BitVec::from(-7i64);
1250        let v4 = BitVec::from(4i64);
1251
1252        assert_eq!(v3.signed().rem_euclid(&v4), BitVec::from(1i64));
1253
1254        let v5 = BitVec::from(7i64);
1255        let v6 = BitVec::from(-4i64);
1256
1257        assert_eq!(v5.rem_euclid(&v6.signed()), BitVec::from(3i64));
1258
1259        let v7 = BitVec::from(-7i64);
1260        let v8 = BitVec::from(-4i64);
1261
1262        assert_eq!(v7.signed().rem_euclid(&v8.signed()), BitVec::from(1i64));
1263    }
1264
1265    #[test]
1266    fn test_abs() {
1267        let v1 = BitVec::from(0x8000_0000u32).signed();
1268        assert_eq!(v1.abs(), BitVec::from(0x8000_0000u32));
1269
1270        let v2 = BitVec::from(0x8000_0001u32).signed();
1271        assert_eq!(v2.abs(), BitVec::from(0x7fff_ffffu32));
1272    }
1273
1274    #[test]
1275    fn test_compare() {
1276        let v1 = BitVec::from(0x8000_0000u32);
1277        let v2 = BitVec::from(0x8000_0001u32);
1278        let v3 = BitVec::from(0xffff_ffffu32).signed();
1279
1280        assert_eq!(v1 < v2, true);
1281        assert_eq!(v1 < v3, false);
1282        assert_eq!(v3 < v1, true);
1283        assert_eq!(v3 < v2, true);
1284        assert_eq!(v1.clone().signed() == v1, true);
1285    }
1286
1287    #[test]
1288    fn test_byte_convert() {
1289        let v1 = BitVec::from_be_bytes(&[0xff, 0xff]);
1290        let v2 = BitVec::from_be_bytes(&[0x80, 0x00]);
1291        let v3 = BitVec::from_be_bytes(&[0x7f, 0xff]);
1292
1293        assert_eq!(v1, BitVec::from(0xffffu16));
1294        assert_eq!(v2, BitVec::from(0x8000u16));
1295        assert_eq!(v3, BitVec::from(0x7fffu16));
1296
1297        let mut buf = [0u8; 2];
1298
1299        v1.to_be_bytes(&mut buf);
1300        assert_eq!(&buf, &[0xff, 0xff]);
1301
1302        v2.to_be_bytes(&mut buf);
1303        assert_eq!(&buf, &[0x80, 0x00]);
1304
1305        v3.to_be_bytes(&mut buf);
1306        assert_eq!(&buf, &[0x7f, 0xff]);
1307
1308        v1.to_le_bytes(&mut buf);
1309        assert_eq!(&buf, &[0xff, 0xff]);
1310
1311        v2.to_le_bytes(&mut buf);
1312        assert_eq!(&buf, &[0x00, 0x80]);
1313
1314        v3.to_le_bytes(&mut buf);
1315        assert_eq!(&buf, &[0xff, 0x7f]);
1316    }
1317
1318    #[test]
1319    fn test_signed_borrow() {
1320        let v1 = BitVec::from(0x8000u16);
1321        let v2 = BitVec::from(0x1u16);
1322
1323        assert_eq!(v1.signed_borrow(&v2), true);
1324
1325        let v3 = BitVec::from(0x8001u16);
1326        let v4 = BitVec::from(0x1u16);
1327
1328        assert_eq!(v3.signed_borrow(&v4), false);
1329    }
1330
1331    #[test]
1332    fn test_1bit() {
1333        let v0 = BitVec::zero(1);
1334        assert_eq!(v0.bits(), 1);
1335
1336        let v1 = v0.max_value();
1337        assert_eq!(v1, BitVec::from_u64(0b1, 1));
1338
1339        let v2 = BitVec::one(1);
1340        assert_eq!(v2, BitVec::from_u64(0b1, 1));
1341
1342        assert_eq!(v1.sub(v2.clone()), BitVec::from_u64(0b0, 1));
1343        assert_eq!(v0.sub(v2), BitVec::from_u64(0b1, 1));
1344    }
1345
1346    #[test]
1347    fn test_3bit() {
1348        let v0 = BitVec::zero(3);
1349        assert_eq!(v0.bits(), 3);
1350
1351        let v1 = v0.max_value();
1352        assert_eq!(v1, BitVec::from_u64(0b111, 3));
1353
1354        let v2 = BitVec::one(3);
1355        assert_eq!(v2, BitVec::from_u64(0b1, 3));
1356
1357        assert_eq!(v1.sub(v2.clone()), BitVec::from_u64(0b110, 3));
1358        assert_eq!(v0.sub(v2), BitVec::from_u64(0b111, 3));
1359
1360        assert_eq!(
1361            BitVec::from_u64(5, 3).mul(BitVec::from_u64(3, 3).neg()),
1362            BitVec::from_u64(1, 3)
1363        );
1364    }
1365
1366    #[test]
1367    fn test_parse() -> Result<(), ParseError> {
1368        assert_eq!("0x100:129".parse::<BitVec>()?.bits(), 129);
1369        assert_eq!("0x100:0".parse::<BitVec>()?.bits(), 0);
1370        Ok(())
1371    }
1372}