1use std::cmp::Ordering;
2use std::fmt::{Binary, Display, LowerHex, Octal, UpperHex};
3use std::hash::{Hash, Hasher};
4
5use std::ops::{
6 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
7 Mul, MulAssign, Not, Range, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
8};
9
10use crate::dynamic::Bvd;
11#[allow(unused_imports)]
12use crate::fixed::{Bv128, Bv16, Bv32, Bv64, Bv8, Bvf};
13use crate::iter::BitIterator;
14use crate::utils::{IArray, IArrayMut, Integer, StaticCast};
15use crate::Bit;
16use crate::{BitVector, ConvertionError, Endianness};
17
18#[cfg(target_pointer_width = "16")]
20pub(crate) type Bvp = Bv32;
21#[cfg(target_pointer_width = "32")]
22pub(crate) type Bvp = Bv64;
23#[cfg(target_pointer_width = "64")]
24pub(crate) type Bvp = Bv128;
25
26#[derive(Clone, Debug)]
57pub enum Bv {
58 #[doc(hidden)]
59 Fixed(Bvp),
60 #[doc(hidden)]
61 Dynamic(Bvd),
62}
63
64impl Bv {
65 pub fn reserve(&mut self, additional: usize) {
80 match self {
81 &mut Bv::Fixed(ref b) => {
82 if b.len() + additional > Bvp::capacity() {
83 let mut new_b = Bvd::from(b);
84 new_b.reserve(additional);
85 *self = Bv::Dynamic(new_b);
86 }
87 }
88 Bv::Dynamic(b) => b.reserve(additional),
89 }
90 }
91
92 pub fn shrink_to_fit(&mut self) {
107 if let Bv::Dynamic(b) = self {
108 if b.len() <= Bvp::capacity() {
109 let new_b = Bvp::try_from(&*b).unwrap();
110 *self = Bv::Fixed(new_b);
111 } else {
112 b.shrink_to_fit();
113 }
114 }
115 }
116}
117
118impl IArray for Bv {
123 type I = u64;
124
125 fn int_len<J: Integer>(&self) -> usize
126 where
127 u64: StaticCast<J>,
128 {
129 match self {
130 Bv::Fixed(bvf) => IArray::int_len(bvf),
131 Bv::Dynamic(bvd) => IArray::int_len(bvd),
132 }
133 }
134
135 fn get_int<J: Integer>(&self, idx: usize) -> Option<J>
136 where
137 u64: StaticCast<J>,
138 {
139 match self {
140 Bv::Fixed(bvf) => IArray::get_int(bvf, idx),
141 Bv::Dynamic(bvd) => IArray::get_int(bvd, idx),
142 }
143 }
144}
145
146impl IArrayMut for Bv {
147 type I = u64;
148
149 fn set_int<J: Integer>(&mut self, idx: usize, v: J) -> Option<J>
150 where
151 u64: StaticCast<J>,
152 {
153 match self {
154 Bv::Fixed(bvf) => IArrayMut::set_int(bvf, idx, v),
155 Bv::Dynamic(bvd) => IArrayMut::set_int(bvd, idx, v),
156 }
157 }
158}
159
160impl BitVector for Bv {
165 fn with_capacity(capacity: usize) -> Self {
166 if capacity <= Bvp::capacity() {
167 Bv::Fixed(Bvp::with_capacity(capacity))
168 } else {
169 Bv::Dynamic(Bvd::with_capacity(capacity))
170 }
171 }
172
173 fn zeros(length: usize) -> Self {
174 if length <= Bvp::capacity() {
175 Bv::Fixed(Bvp::zeros(length))
176 } else {
177 Bv::Dynamic(Bvd::zeros(length))
178 }
179 }
180
181 fn ones(length: usize) -> Self {
182 if length <= Bvp::capacity() {
183 Bv::Fixed(Bvp::ones(length))
184 } else {
185 Bv::Dynamic(Bvd::ones(length))
186 }
187 }
188
189 fn capacity(&self) -> usize {
190 match self {
191 Bv::Fixed(_) => Bvp::capacity(),
192 Bv::Dynamic(b) => b.capacity(),
193 }
194 }
195
196 fn len(&self) -> usize {
197 match self {
198 Bv::Fixed(b) => b.len(),
199 Bv::Dynamic(b) => b.len(),
200 }
201 }
202
203 fn from_binary<S: AsRef<str>>(string: S) -> Result<Self, ConvertionError> {
204 if string.as_ref().len() <= Bvp::capacity() {
205 Ok(Bv::Fixed(Bvp::from_binary(string)?))
206 } else {
207 Ok(Bv::Dynamic(Bvd::from_binary(string)?))
208 }
209 }
210
211 fn from_hex<S: AsRef<str>>(string: S) -> Result<Self, ConvertionError> {
212 if string.as_ref().len() * 4 <= Bvp::capacity() {
213 Ok(Bv::Fixed(Bvp::from_hex(string)?))
214 } else {
215 Ok(Bv::Dynamic(Bvd::from_hex(string)?))
216 }
217 }
218
219 fn from_bytes<B: AsRef<[u8]>>(
220 bytes: B,
221 endianness: Endianness,
222 ) -> Result<Self, ConvertionError> {
223 if bytes.as_ref().len() * 8 <= Bvp::capacity() {
224 Ok(Bv::Fixed(Bvp::from_bytes(bytes, endianness)?))
225 } else {
226 Ok(Bv::Dynamic(Bvd::from_bytes(bytes, endianness)?))
227 }
228 }
229
230 fn to_vec(&self, endianness: Endianness) -> Vec<u8> {
231 match self {
232 Bv::Fixed(b) => b.to_vec(endianness),
233 Bv::Dynamic(b) => b.to_vec(endianness),
234 }
235 }
236
237 fn read<R: std::io::Read>(
238 reader: &mut R,
239 length: usize,
240 endianness: Endianness,
241 ) -> std::io::Result<Self> {
242 if length <= Bvp::capacity() {
243 Ok(Bv::Fixed(Bvp::read(reader, length, endianness)?))
244 } else {
245 Ok(Bv::Dynamic(Bvd::read(reader, length, endianness)?))
246 }
247 }
248
249 fn write<W: std::io::Write>(
250 &self,
251 writer: &mut W,
252 endianness: Endianness,
253 ) -> std::io::Result<()> {
254 match self {
255 Bv::Fixed(b) => b.write(writer, endianness),
256 Bv::Dynamic(b) => b.write(writer, endianness),
257 }
258 }
259
260 fn get(&self, index: usize) -> Bit {
261 match self {
262 Bv::Fixed(b) => b.get(index),
263 Bv::Dynamic(b) => b.get(index),
264 }
265 }
266
267 fn set(&mut self, index: usize, bit: Bit) {
268 match self {
269 Bv::Fixed(b) => b.set(index, bit),
270 Bv::Dynamic(b) => b.set(index, bit),
271 }
272 }
273
274 fn copy_range(&self, range: Range<usize>) -> Self {
275 match self {
276 Bv::Fixed(b) => Bv::Fixed(b.copy_range(range)),
277 Bv::Dynamic(b) => {
278 let s = b.copy_range(range);
279 if s.len() <= Bvp::capacity() {
280 Bv::Fixed(Bvp::try_from(s).unwrap())
281 } else {
282 Bv::Dynamic(s)
283 }
284 }
285 }
286 }
287
288 fn push(&mut self, bit: Bit) {
289 self.reserve(1);
290 match self {
291 Bv::Fixed(b) => b.push(bit),
292 Bv::Dynamic(b) => b.push(bit),
293 }
294 }
295
296 fn pop(&mut self) -> Option<Bit> {
297 match self {
298 Bv::Fixed(b) => b.pop(),
299 Bv::Dynamic(b) => b.pop(),
300 }
301 }
302
303 fn resize(&mut self, new_length: usize, bit: Bit) {
304 if new_length > self.len() {
305 self.reserve(new_length - self.len());
306 }
307 match self {
308 Bv::Fixed(b) => b.resize(new_length, bit),
309 Bv::Dynamic(b) => b.resize(new_length, bit),
310 }
311 }
312
313 fn append<B: BitVector>(&mut self, suffix: &B) {
314 match self {
315 Bv::Fixed(bvf) => {
316 if bvf.len() + suffix.len() <= Bvp::capacity() {
317 bvf.append(suffix);
318 } else {
319 let mut bvd = Bvd::from(&*bvf);
320 bvd.append(suffix);
321 *self = Bv::Dynamic(bvd);
322 }
323 }
324 Bv::Dynamic(bvd) => {
325 bvd.append(suffix);
326 }
327 }
328 }
329
330 fn prepend<B: BitVector>(&mut self, prefix: &B) {
331 match self {
332 Bv::Fixed(bvf) => {
333 if bvf.len() + prefix.len() <= Bvp::capacity() {
334 bvf.prepend(prefix);
335 } else {
336 let mut bvd = Bvd::from(&*bvf);
337 bvd.prepend(prefix);
338 *self = Bv::Dynamic(bvd);
339 }
340 }
341 Bv::Dynamic(bvd) => {
342 bvd.prepend(prefix);
343 }
344 }
345 }
346
347 fn shl_in(&mut self, bit: Bit) -> Bit {
348 match self {
349 Bv::Fixed(b) => b.shl_in(bit),
350 Bv::Dynamic(b) => b.shl_in(bit),
351 }
352 }
353
354 fn shr_in(&mut self, bit: Bit) -> Bit {
355 match self {
356 Bv::Fixed(b) => b.shr_in(bit),
357 Bv::Dynamic(b) => b.shr_in(bit),
358 }
359 }
360
361 fn rotl(&mut self, rot: usize) {
362 match self {
363 Bv::Fixed(b) => b.rotl(rot),
364 Bv::Dynamic(b) => b.rotl(rot),
365 }
366 }
367
368 fn rotr(&mut self, rot: usize) {
369 match self {
370 Bv::Fixed(b) => b.rotr(rot),
371 Bv::Dynamic(b) => b.rotr(rot),
372 }
373 }
374
375 fn leading_zeros(&self) -> usize {
376 match self {
377 Bv::Fixed(b) => b.leading_zeros(),
378 Bv::Dynamic(b) => b.leading_zeros(),
379 }
380 }
381
382 fn leading_ones(&self) -> usize {
383 match self {
384 Bv::Fixed(b) => b.leading_ones(),
385 Bv::Dynamic(b) => b.leading_ones(),
386 }
387 }
388
389 fn trailing_zeros(&self) -> usize {
390 match self {
391 Bv::Fixed(b) => b.trailing_zeros(),
392 Bv::Dynamic(b) => b.trailing_zeros(),
393 }
394 }
395
396 fn trailing_ones(&self) -> usize {
397 match self {
398 Bv::Fixed(b) => b.trailing_ones(),
399 Bv::Dynamic(b) => b.trailing_ones(),
400 }
401 }
402
403 fn is_zero(&self) -> bool {
404 match self {
405 Bv::Fixed(b) => b.is_zero(),
406 Bv::Dynamic(b) => b.is_zero(),
407 }
408 }
409
410 fn div_rem<B: BitVector>(&self, divisor: &B) -> (Self, Self)
411 where
412 Self: for<'a> TryFrom<&'a B, Error: std::fmt::Debug>,
413 {
414 assert!(!divisor.is_zero(), "Division by zero");
415 let mut quotient = Bv::zeros(self.len());
416 let mut rem = self.clone();
417 if divisor.significant_bits() > self.significant_bits() {
418 return (quotient, rem);
419 }
420
421 let shift = self.significant_bits() - divisor.significant_bits();
422 let mut divisor: Bv = divisor.try_into().expect("should never fail");
423 divisor.resize(self.len(), Bit::Zero);
424 divisor <<= shift;
425
426 for i in (0..shift + 1).rev() {
427 if rem >= divisor {
428 rem -= &divisor;
429 quotient.set(i, Bit::One);
430 }
431 divisor >>= 1u32;
432 }
433
434 (quotient, rem)
435 }
436
437 fn iter(&self) -> BitIterator<'_, Self> {
438 self.into_iter()
439 }
440}
441
442impl Hash for Bv {
443 fn hash<H: Hasher>(&self, state: &mut H) {
444 self.len().hash(state);
445 for i in 0..Self::int_len::<u64>(self) {
446 self.get_int::<u64>(i).unwrap().hash(state);
447 }
448 }
449}
450
451impl<'a> IntoIterator for &'a Bv {
456 type Item = Bit;
457 type IntoIter = BitIterator<'a, Bv>;
458
459 fn into_iter(self) -> Self::IntoIter {
460 BitIterator::new(self)
461 }
462}
463
464impl FromIterator<Bit> for Bv {
465 fn from_iter<T: IntoIterator<Item = Bit>>(iter: T) -> Self {
466 let iter = iter.into_iter();
467 let mut bv = Bv::with_capacity(iter.size_hint().0);
468 iter.for_each(|b| bv.push(b));
469 bv
470 }
471}
472
473impl Extend<Bit> for Bv {
474 fn extend<T: IntoIterator<Item = Bit>>(&mut self, iter: T) {
475 let iter = iter.into_iter();
476 self.reserve(iter.size_hint().0);
477 iter.for_each(|b| self.push(b));
478 }
479}
480
481impl Binary for Bv {
486 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
487 match self {
488 Bv::Fixed(b) => Binary::fmt(b, f),
489 Bv::Dynamic(b) => Binary::fmt(b, f),
490 }
491 }
492}
493
494impl Display for Bv {
495 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
496 match self {
497 Bv::Fixed(b) => Display::fmt(b, f),
498 Bv::Dynamic(b) => Display::fmt(b, f),
499 }
500 }
501}
502
503impl LowerHex for Bv {
504 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
505 match self {
506 Bv::Fixed(b) => LowerHex::fmt(b, f),
507 Bv::Dynamic(b) => LowerHex::fmt(b, f),
508 }
509 }
510}
511
512impl UpperHex for Bv {
513 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
514 match self {
515 Bv::Fixed(b) => UpperHex::fmt(b, f),
516 Bv::Dynamic(b) => UpperHex::fmt(b, f),
517 }
518 }
519}
520
521impl Octal for Bv {
522 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
523 match self {
524 Bv::Fixed(b) => Octal::fmt(b, f),
525 Bv::Dynamic(b) => Octal::fmt(b, f),
526 }
527 }
528}
529
530impl PartialEq for Bv {
535 fn eq(&self, other: &Self) -> bool {
536 match self {
537 Bv::Fixed(b1) => match other {
538 Bv::Fixed(b2) => b1.eq(b2),
539 Bv::Dynamic(b2) => b1.eq(b2),
540 },
541 Bv::Dynamic(b1) => match other {
542 Bv::Fixed(b2) => b1.eq(b2),
543 Bv::Dynamic(b2) => b1.eq(b2),
544 },
545 }
546 }
547}
548
549impl PartialEq<Bvd> for Bv {
550 fn eq(&self, other: &Bvd) -> bool {
551 match self {
552 Bv::Fixed(bvf) => bvf.eq(other),
553 Bv::Dynamic(bvd) => bvd.eq(other),
554 }
555 }
556}
557
558impl<I: Integer, const N: usize> PartialEq<Bvf<I, N>> for Bv
559where
560 u64: StaticCast<I>,
561{
562 fn eq(&self, other: &Bvf<I, N>) -> bool {
563 match self {
564 Bv::Fixed(bvf) => bvf.eq(other),
565 Bv::Dynamic(bvd) => bvd.eq(other),
566 }
567 }
568}
569
570impl Eq for Bv {}
571
572impl PartialOrd for Bv {
573 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
574 Some(self.cmp(other))
575 }
576}
577
578impl<I: Integer, const N: usize> PartialOrd<Bvf<I, N>> for Bv
579where
580 u64: StaticCast<I>,
581{
582 fn partial_cmp(&self, other: &Bvf<I, N>) -> Option<Ordering> {
583 match self {
584 Bv::Fixed(bvf) => bvf.partial_cmp(other),
585 Bv::Dynamic(bvd) => bvd.partial_cmp(other),
586 }
587 }
588}
589
590impl PartialOrd<Bvd> for Bv {
591 fn partial_cmp(&self, other: &Bvd) -> Option<Ordering> {
592 match self {
593 Bv::Fixed(bvf) => bvf.partial_cmp(other),
594 Bv::Dynamic(bvd) => bvd.partial_cmp(other),
595 }
596 }
597}
598
599impl Ord for Bv {
600 fn cmp(&self, other: &Self) -> Ordering {
601 match self {
602 Bv::Fixed(b1) => match other {
603 Bv::Fixed(b2) => b1.cmp(b2),
604 Bv::Dynamic(b2) => b1.partial_cmp(b2).unwrap(),
605 },
606 Bv::Dynamic(b1) => match other {
607 Bv::Fixed(b2) => b1.partial_cmp(b2).unwrap(),
608 Bv::Dynamic(b2) => b1.cmp(b2),
609 },
610 }
611 }
612}
613
614impl From<&Bv> for Bv {
619 fn from(b: &Bv) -> Self {
620 match b {
621 Bv::Fixed(bvf) => Bv::Fixed(*bvf),
622 Bv::Dynamic(bvd) => Bv::Dynamic(bvd.clone()),
623 }
624 }
625}
626
627impl From<Bvd> for Bv {
628 fn from(b: Bvd) -> Self {
629 if let Ok(bvf) = Bvp::try_from(&b) {
630 Bv::Fixed(bvf)
631 } else {
632 Bv::Dynamic(b)
633 }
634 }
635}
636
637impl From<&'_ Bvd> for Bv {
638 fn from(b: &'_ Bvd) -> Self {
639 if let Ok(bvf) = Bvp::try_from(b) {
640 Bv::Fixed(bvf)
641 } else {
642 Bv::Dynamic(b.clone())
643 }
644 }
645}
646
647impl<I: Integer, const N: usize> From<&Bvf<I, N>> for Bv {
648 fn from(b: &Bvf<I, N>) -> Self {
649 if Bvf::<I, N>::capacity() <= Bvp::capacity() {
650 Bv::Fixed(b.try_into().unwrap())
651 } else {
652 Bv::Dynamic(b.into())
653 }
654 }
655}
656
657impl<I: Integer, const N: usize> From<Bvf<I, N>> for Bv {
658 fn from(b: Bvf<I, N>) -> Self {
659 Bv::from(&b)
660 }
661}
662
663macro_rules! impl_tryfrom { ($($type:ty),+) => {
664 $(
665 impl From<$type> for Bv {
666 fn from(int: $type) -> Self {
667 if std::mem::size_of::<$type>() * 8 <= Bvp::capacity() {
669 Bv::Fixed(Bvp::try_from(int).unwrap())
670 }
671 else {
672 Bv::Dynamic(Bvd::from(int))
673 }
674 }
675 }
676
677 impl From<&$type> for Bv {
678 fn from(int: &$type) -> Self {
679 Self::from(*int)
680 }
681 }
682
683 impl TryFrom<&Bv> for $type
684 {
685 type Error = ConvertionError;
686 fn try_from(bv: &Bv) -> Result<Self, Self::Error> {
687 match bv {
688 Bv::Fixed(b) => Ok(b.try_into()?),
689 Bv::Dynamic(b) => Ok(b.try_into()?),
690 }
691 }
692 }
693
694 impl TryFrom<Bv> for $type
695 {
696 type Error = ConvertionError;
697 fn try_from(bv: Bv) -> Result<Self, Self::Error> {
698 Self::try_from(&bv)
699 }
700 }
701 )+
702}}
703
704impl_tryfrom!(u8, u16, u32, u64, u128, usize);
705
706impl<I: Integer> From<&[I]> for Bv
707where
708 u64: StaticCast<I>,
709{
710 fn from(slice: &[I]) -> Self {
711 let mut bv = Bv::zeros(slice.len() * I::BITS);
712 for (i, v) in slice.iter().enumerate() {
713 bv.set_int(i, *v);
714 }
715 bv
716 }
717}
718
719impl Not for Bv {
724 type Output = Bv;
725
726 fn not(self) -> Self::Output {
727 match self {
728 Bv::Fixed(b) => Bv::Fixed(b.not()),
729 Bv::Dynamic(b) => Bv::Dynamic(b.not()),
730 }
731 }
732}
733
734impl Not for &'_ Bv {
735 type Output = Bv;
736
737 fn not(self) -> Self::Output {
738 match self {
739 Bv::Fixed(b) => Bv::Fixed(b.not()),
740 Bv::Dynamic(b) => Bv::Dynamic(b.not()),
741 }
742 }
743}
744
745macro_rules! impl_shift_assign {($trait:ident, $method:ident, {$($rhs:ty),+}) => {
746 $(
747 impl $trait<$rhs> for Bv {
748 fn $method(&mut self, rhs: $rhs) {
749 match self {
750 Bv::Fixed(b) => b.$method(rhs),
751 Bv::Dynamic(b) => b.$method(rhs)
752 }
753 }
754 }
755
756 impl $trait<&'_ $rhs> for Bv {
757 fn $method(&mut self, rhs: &'_ $rhs) {
758 match self {
759 Bv::Fixed(b) => b.$method(rhs),
760 Bv::Dynamic(b) => b.$method(rhs)
761 }
762 }
763 }
764 )+
765}}
766
767impl_shift_assign!(ShlAssign, shl_assign, {u8, u16, u32, u64, u128, usize});
768impl_shift_assign!(ShrAssign, shr_assign, {u8, u16, u32, u64, u128, usize});
769
770macro_rules! impl_shift {($trait:ident, $method:ident, {$($rhs:ty),+}) => {
771 $(
772 impl $trait<$rhs> for Bv {
773 type Output = Bv;
774 fn $method(self, rhs: $rhs) -> Bv {
775 match self {
776 Bv::Fixed(b) => Bv::Fixed(b.$method(rhs)),
777 Bv::Dynamic(b) => Bv::Dynamic(b.$method(rhs))
778 }
779 }
780 }
781
782 impl $trait<&'_ $rhs> for Bv {
783 type Output = Bv;
784 fn $method(self, rhs: &'_ $rhs) -> Bv {
785 match self {
786 Bv::Fixed(b) => Bv::Fixed(b.$method(rhs)),
787 Bv::Dynamic(b) => Bv::Dynamic(b.$method(rhs))
788 }
789 }
790 }
791
792 impl $trait<$rhs> for &'_ Bv {
793 type Output = Bv;
794 fn $method(self, rhs: $rhs) -> Bv {
795 self.clone().$method(rhs)
796 }
797 }
798
799 impl $trait<&'_ $rhs> for &'_ Bv {
800 type Output = Bv;
801 fn $method(self, rhs: &'_ $rhs) -> Bv {
802 self.clone().$method(rhs)
803 }
804 }
805 )+
806}}
807
808impl_shift!(Shl, shl, {u8, u16, u32, u64, u128, usize});
809impl_shift!(Shr, shr, {u8, u16, u32, u64, u128, usize});
810
811macro_rules! impl_op_uint {
816 ($trait:ident, $method:ident, {$($uint:ty),+}) => {
817 $(
818 impl $trait<&$uint> for &Bv
819 {
820 type Output = Bv;
821 fn $method(self, rhs: &$uint) -> Self::Output {
822 match self {
823 Bv::Fixed(bvf) => Bv::Fixed(bvf.$method(rhs)),
824 Bv::Dynamic(bvd) => Bv::Dynamic(bvd.$method(rhs)),
825 }
826 }
827 }
828
829 impl $trait<$uint> for &Bv
830 {
831 type Output = Bv;
832 fn $method(self, rhs: $uint) -> Self::Output {
833 match self {
834 Bv::Fixed(bvf) => Bv::Fixed(bvf.$method(rhs)),
835 Bv::Dynamic(bvd) => Bv::Dynamic(bvd.$method(rhs)),
836 }
837 }
838 }
839
840 impl $trait<&$uint> for Bv
841 {
842 type Output = Bv;
843 fn $method(self, rhs: &$uint) -> Self::Output {
844 match self {
845 Bv::Fixed(bvf) => Bv::Fixed(bvf.$method(rhs)),
846 Bv::Dynamic(bvd) => Bv::Dynamic(bvd.$method(rhs)),
847 }
848 }
849 }
850
851 impl $trait<$uint> for Bv
852 {
853 type Output = Bv;
854 fn $method(self, rhs: $uint) -> Self::Output {
855 match self {
856 Bv::Fixed(bvf) => Bv::Fixed(bvf.$method(rhs)),
857 Bv::Dynamic(bvd) => Bv::Dynamic(bvd.$method(rhs)),
858 }
859 }
860 }
861 )+
862 };
863}
864
865macro_rules! impl_op_assign_uint {
866 ($trait:ident, $method:ident, {$($uint:ty),+}) => {
867 $(
868 impl $trait<$uint> for Bv
869 {
870 fn $method(&mut self, rhs: $uint) {
871 match self {
872 Bv::Fixed(bvf) => bvf.$method(rhs),
873 Bv::Dynamic(bvd) => bvd.$method(rhs),
874 }
875 }
876 }
877
878 impl $trait<&$uint> for Bv
879 {
880 fn $method(&mut self, rhs: &$uint) {
881 match self {
882 Bv::Fixed(bvf) => bvf.$method(rhs),
883 Bv::Dynamic(bvd) => bvd.$method(rhs),
884 }
885 }
886 }
887 )+
888 };
889}
890
891macro_rules! impl_op_assign {
896 ($trait:ident, $method:ident, {$($uint:ty),+}) => {
897 impl $trait<&Bv> for Bv {
898 fn $method(&mut self, bv: &Bv) {
899 match bv {
900 Bv::Fixed(b) => self.$method(b),
901 Bv::Dynamic(b) => self.$method(b),
902 }
903 }
904 }
905
906 impl $trait<Bv> for Bv {
907 fn $method(&mut self, bv: Bv) {
908 match bv {
909 Bv::Fixed(b) => self.$method(b),
910 Bv::Dynamic(b) => self.$method(b),
911 }
912 }
913 }
914
915 impl<I: Integer, const N: usize> $trait<&Bvf<I, N>> for Bv
916 where
917 u64: StaticCast<I>,
918 {
919 fn $method(&mut self, bvf: &Bvf<I, N>) {
920 match self {
921 Bv::Fixed(b) => b.$method(bvf),
922 Bv::Dynamic(b) => b.$method(bvf),
923 }
924 }
925 }
926
927 impl<I: Integer, const N: usize> $trait<Bvf<I, N>> for Bv
928 where
929 u64: StaticCast<I>,
930 {
931 fn $method(&mut self, bvf: Bvf<I, N>) {
932 match self {
933 Bv::Fixed(b) => b.$method(bvf),
934 Bv::Dynamic(b) => b.$method(bvf),
935 }
936 }
937 }
938
939 impl $trait<Bvd> for Bv {
940 fn $method(&mut self, bvd: Bvd) {
941 match self {
942 Bv::Fixed(b) => b.$method(bvd),
943 Bv::Dynamic(b) => b.$method(bvd),
944 }
945 }
946 }
947
948 impl $trait<&Bvd> for Bv {
949 fn $method(&mut self, bvd: &Bvd) {
950 match self {
951 Bv::Fixed(b) => b.$method(bvd),
952 Bv::Dynamic(b) => b.$method(bvd),
953 }
954 }
955 }
956
957 impl_op_assign_uint!($trait, $method, {$($uint),+});
958 };
959}
960
961impl_op_assign!(BitAndAssign, bitand_assign, {u8, u16, u32, u64, usize, u128});
962impl_op_assign!(BitOrAssign, bitor_assign, {u8, u16, u32, u64, usize, u128});
963impl_op_assign!(BitXorAssign, bitxor_assign, {u8, u16, u32, u64, usize, u128});
964impl_op_assign!(AddAssign, add_assign, {u8, u16, u32, u64, usize, u128});
965impl_op_assign!(SubAssign, sub_assign, {u8, u16, u32, u64, usize, u128});
966impl_op_assign!(MulAssign, mul_assign, {u8, u16, u32, u64, usize, u128});
967impl_op_assign!(DivAssign, div_assign, {u8, u16, u32, u64, usize, u128});
968impl_op_assign!(RemAssign, rem_assign, {u8, u16, u32, u64, usize, u128});
969
970macro_rules! impl_op {
971 ($trait:ident, $method:ident, {$($uint:ty),+}) => {
972 impl $trait<&Bv> for &Bv {
973 type Output = Bv;
974 fn $method(self, rhs: &Bv) -> Bv {
975 match self {
976 Bv::Fixed(bvf) => Bv::Fixed(bvf.$method(rhs)),
977 Bv::Dynamic(bvd) => Bv::Dynamic(bvd.$method(rhs)),
978 }
979 }
980 }
981
982 impl $trait<Bv> for &Bv {
983 type Output = Bv;
984 fn $method(self, rhs: Bv) -> Bv {
985 match self {
986 Bv::Fixed(bvf) => Bv::Fixed(bvf.$method(rhs)),
987 Bv::Dynamic(bvd) => Bv::Dynamic(bvd.$method(rhs)),
988 }
989 }
990 }
991
992 impl $trait<&Bv> for Bv {
993 type Output = Bv;
994 fn $method(self, rhs: &Bv) -> Bv {
995 match self {
996 Bv::Fixed(bvf) => Bv::Fixed(bvf.$method(rhs)),
997 Bv::Dynamic(bvd) => Bv::Dynamic(bvd.$method(rhs)),
998 }
999 }
1000 }
1001
1002 impl $trait<Bv> for Bv {
1003 type Output = Bv;
1004 fn $method(self, rhs: Bv) -> Bv {
1005 match self {
1006 Bv::Fixed(bvf) => Bv::Fixed(bvf.$method(rhs)),
1007 Bv::Dynamic(bvd) => Bv::Dynamic(bvd.$method(rhs)),
1008 }
1009 }
1010 }
1011
1012 impl<I: Integer, const N: usize> $trait<&Bvf<I, N>> for &Bv
1013 where
1014 u64: StaticCast<I>
1015 {
1016 type Output = Bv;
1017 fn $method(self, rhs: &Bvf<I, N>) -> Bv {
1018 match self {
1019 Bv::Fixed(bvf) => Bv::Fixed(bvf.$method(rhs)),
1020 Bv::Dynamic(bvd) => Bv::Dynamic(bvd.$method(rhs)),
1021 }
1022 }
1023 }
1024
1025 impl<I: Integer, const N: usize> $trait<Bvf<I, N>> for &Bv
1026 where
1027 u64: StaticCast<I>
1028 {
1029 type Output = Bv;
1030 fn $method(self, rhs: Bvf<I, N>) -> Bv {
1031 match self {
1032 Bv::Fixed(bvf) => Bv::Fixed(bvf.$method(rhs)),
1033 Bv::Dynamic(bvd) => Bv::Dynamic(bvd.$method(rhs)),
1034 }
1035 }
1036 }
1037
1038 impl<I: Integer, const N: usize> $trait<&Bvf<I, N>> for Bv
1039 where
1040 u64: StaticCast<I>
1041 {
1042 type Output = Bv;
1043 fn $method(self, rhs: &Bvf<I, N>) -> Bv {
1044 match self {
1045 Bv::Fixed(bvf) => Bv::Fixed(bvf.$method(rhs)),
1046 Bv::Dynamic(bvd) => Bv::Dynamic(bvd.$method(rhs)),
1047 }
1048 }
1049 }
1050
1051 impl<I: Integer, const N: usize> $trait<Bvf<I, N>> for Bv
1052 where
1053 u64: StaticCast<I>
1054 {
1055 type Output = Bv;
1056 fn $method(self, rhs: Bvf<I, N>) -> Bv {
1057 match self {
1058 Bv::Fixed(bvf) => Bv::Fixed(bvf.$method(rhs)),
1059 Bv::Dynamic(bvd) => Bv::Dynamic(bvd.$method(rhs)),
1060 }
1061 }
1062 }
1063
1064 impl $trait<&Bvd> for &Bv
1065 {
1066 type Output = Bv;
1067 fn $method(self, rhs: &Bvd) -> Bv {
1068 match self {
1069 Bv::Fixed(bvf) => Bv::Fixed(bvf.$method(rhs)),
1070 Bv::Dynamic(bvd) => Bv::Dynamic(bvd.$method(rhs)),
1071 }
1072 }
1073 }
1074
1075 impl $trait<Bvd> for &Bv
1076 {
1077 type Output = Bv;
1078 fn $method(self, rhs: Bvd) -> Bv {
1079 match self {
1080 Bv::Fixed(bvf) => Bv::Fixed(bvf.$method(rhs)),
1081 Bv::Dynamic(bvd) => Bv::Dynamic(bvd.$method(rhs)),
1082 }
1083 }
1084 }
1085
1086 impl $trait<&Bvd> for Bv
1087 {
1088 type Output = Bv;
1089 fn $method(self, rhs: &Bvd) -> Bv {
1090 match self {
1091 Bv::Fixed(bvf) => Bv::Fixed(bvf.$method(rhs)),
1092 Bv::Dynamic(bvd) => Bv::Dynamic(bvd.$method(rhs)),
1093 }
1094 }
1095 }
1096
1097 impl $trait<Bvd> for Bv
1098 {
1099 type Output = Bv;
1100 fn $method(self, rhs: Bvd) -> Bv {
1101 match self {
1102 Bv::Fixed(bvf) => Bv::Fixed(bvf.$method(rhs)),
1103 Bv::Dynamic(bvd) => Bv::Dynamic(bvd.$method(rhs)),
1104 }
1105 }
1106 }
1107
1108 impl_op_uint!($trait, $method, {$($uint),+});
1109 };
1110}
1111
1112impl_op!(BitAnd, bitand, {u8, u16, u32, u64, usize, u128});
1113impl_op!(BitOr, bitor, {u8, u16, u32, u64, usize, u128});
1114impl_op!(BitXor, bitxor, {u8, u16, u32, u64, usize, u128});
1115impl_op!(Add, add, {u8, u16, u32, u64, usize, u128});
1116impl_op!(Sub, sub, {u8, u16, u32, u64, usize, u128});
1117impl_op!(Mul, mul, {u8, u16, u32, u64, usize, u128});
1118impl_op!(Div, div, {u8, u16, u32, u64, usize, u128});
1119impl_op!(Rem, rem, {u8, u16, u32, u64, usize, u128});