1
2use apint::{ApInt, ApIntData};
3use bitwidth::{BitWidth};
4use errors::{Error, Result};
5use storage::{Storage};
6use digit::{Bit, Digit};
7use digit;
8
9use smallvec::SmallVec;
10
11use std::ptr::NonNull;
12
13impl ApInt {
14 pub(in apint) unsafe fn drop_digits(&mut self) {
26 if self.len.storage() == Storage::Ext {
27 let len = self.len_digits();
28 drop(Vec::from_raw_parts(
29 self.data.ext.as_ptr(), len, len))
30 }
31 }
32}
33
34impl Drop for ApInt {
35 fn drop(&mut self) {
36 unsafe{self.drop_digits()}
37 }
38}
39
40impl ApInt {
42
43 #[inline]
51 pub(in apint) fn new_inl(width: BitWidth, digit: Digit) -> ApInt {
52 assert_eq!(width.storage(), Storage::Inl);
53 ApInt{
54 len: width,
55 data: ApIntData{ inl: digit }}
56 }
57
58 pub(in apint) unsafe fn new_ext(width: BitWidth, ext_ptr: *mut Digit) -> ApInt {
70 assert_eq!(width.storage(), Storage::Ext);
71 ApInt{
72 len: width,
73 data: ApIntData{ ext: NonNull::new_unchecked(ext_ptr) }
74 }
75 }
76
77 pub fn from_bit<B>(bit: B) -> ApInt
81 where B: Into<Bit>
82 {
83 ApInt::new_inl(BitWidth::w1(), Digit(bit.into().to_bool() as u64))
84 }
85
86 #[inline]
88 pub fn from_i8(val: i8) -> ApInt {
89 ApInt::from_u8(val as u8)
90 }
91
92 #[inline]
94 pub fn from_u8(val: u8) -> ApInt {
95 ApInt::new_inl(BitWidth::w8(), Digit(u64::from(val)))
96 }
97
98 #[inline]
100 pub fn from_i16(val: i16) -> ApInt {
101 ApInt::from_u16(val as u16)
102 }
103
104 #[inline]
106 pub fn from_u16(val: u16) -> ApInt {
107 ApInt::new_inl(BitWidth::w16(), Digit(u64::from(val)))
108 }
109
110 #[inline]
112 pub fn from_i32(val: i32) -> ApInt {
113 ApInt::from_u32(val as u32)
114 }
115
116 #[inline]
118 pub fn from_u32(val: u32) -> ApInt {
119 ApInt::new_inl(BitWidth::w32(), Digit(u64::from(val)))
120 }
121
122 #[inline]
124 pub fn from_i64(val: i64) -> ApInt {
125 ApInt::from_u64(val as u64)
126 }
127
128 #[inline]
130 pub fn from_u64(val: u64) -> ApInt {
131 ApInt::new_inl(BitWidth::w64(), Digit(val))
132 }
133
134 #[inline]
136 pub fn from_i128(val: i128) -> ApInt {
137 ApInt::from_u128(val as u128)
138 }
139
140 pub fn from_u128(val: u128) -> ApInt {
142 let hi = (val >> digit::BITS) as u64;
143 let lo = (val & ((1u128 << 64) - 1)) as u64;
144 ApInt::from([hi, lo])
145 }
146
147 pub(in apint) fn from_iter<I>(digits: I) -> Result<ApInt>
163 where I: IntoIterator<Item=Digit>,
164 {
165 let mut buffer = digits.into_iter().collect::<SmallVec<[Digit; 1]>>();
166 match buffer.len() {
167 0 => {
168 Err(Error::expected_non_empty_digits())
169 }
170 1 => {
171 let first_and_only = *buffer
172 .first()
173 .expect("We have already asserted that `digits.len()` must be at exactly `1`.");
174 Ok(ApInt::new_inl(BitWidth::w64(), first_and_only))
175 }
176 n => {
177 use std::mem;
178 let bitwidth = BitWidth::new(n * digit::BITS)
179 .expect("We have already asserted that the number of items the given Iterator \
180 iterates over is greater than `1` and thus non-zero and thus a valid `BitWidth`.");
181 let req_digits = bitwidth.required_digits();
182 buffer.shrink_to_fit();
183 assert_eq!(buffer.capacity(), req_digits);
184 assert_eq!(buffer.len() , req_digits);
185 let ptr_buffer = buffer.as_ptr() as *mut Digit;
186 mem::forget(buffer);
187 Ok(unsafe{ ApInt::new_ext(bitwidth, ptr_buffer) })
188 }
189 }
190 }
191
192 pub(in apint) fn repeat_digit<D>(target_width: BitWidth, digit: D) -> ApInt
198 where D: Into<Digit>
199 {
200 use std::iter;
201 let digit = digit.into();
202 let req_digits = target_width.required_digits();
203 ApInt::from_iter(iter::repeat(digit).take(req_digits))
204 .expect("Since `required_digits` always returns `1` or more \
205 required digits we can safely assume that this operation \
206 never fails.")
207 .into_truncate(target_width)
208 .expect("Since `BitWidth::required_digits` always returns the upper bound \
209 for the number of digits required to represent the given `BitWidth` \
210 and `ApInt::from_iter` will use exactly this upper bound \
211 we can safely assume that `target_width` is always equal or \
212 less than what `ApInt::from_iter` returns and thus truncation will \
213 never fail.")
214 }
215
216 pub fn zero(width: BitWidth) -> ApInt {
218 ApInt::repeat_digit(width, digit::ZERO)
219 }
220
221 pub fn one(width: BitWidth) -> ApInt {
223 ApInt::from_u64(1).into_zero_resize(width)
224 }
225
226 pub fn all_unset(width: BitWidth) -> ApInt {
230 ApInt::zero(width)
231 }
232
233 pub fn all_set(width: BitWidth) -> ApInt {
235 ApInt::repeat_digit(width, digit::ONES)
236 }
237
238 pub fn unsigned_min_value(width: BitWidth) -> ApInt {
240 ApInt::zero(width)
241 }
242
243 pub fn unsigned_max_value(width: BitWidth) -> ApInt {
245 ApInt::all_set(width)
246 }
247
248 pub fn signed_min_value(width: BitWidth) -> ApInt {
250 let mut result = ApInt::zero(width);
251 result.set_sign_bit();
252 result
253 }
254
255 pub fn signed_max_value(width: BitWidth) -> ApInt {
257 let mut result = ApInt::all_set(width);
258 result.unset_sign_bit();
259 result
260 }
261}
262
263impl<B> From<B> for ApInt
264 where B: Into<Bit>
265{
266 #[inline]
267 fn from(bit: B) -> ApInt {
268 ApInt::from_bit(bit)
269 }
270}
271
272impl From<u8> for ApInt {
273 #[inline]
274 fn from(val: u8) -> ApInt {
275 ApInt::from_u8(val)
276 }
277}
278
279impl From<i8> for ApInt {
280 #[inline]
281 fn from(val: i8) -> ApInt {
282 ApInt::from_i8(val)
283 }
284}
285
286impl From<u16> for ApInt {
287 #[inline]
288 fn from(val: u16) -> ApInt {
289 ApInt::from_u16(val)
290 }
291}
292
293impl From<i16> for ApInt {
294 #[inline]
295 fn from(val: i16) -> ApInt {
296 ApInt::from_i16(val)
297 }
298}
299
300impl From<u32> for ApInt {
301 #[inline]
302 fn from(val: u32) -> ApInt {
303 ApInt::from_u32(val)
304 }
305}
306
307impl From<i32> for ApInt {
308 #[inline]
309 fn from(val: i32) -> ApInt {
310 ApInt::from_i32(val)
311 }
312}
313
314impl From<u64> for ApInt {
315 #[inline]
316 fn from(val: u64) -> ApInt {
317 ApInt::from_u64(val)
318 }
319}
320
321impl From<i64> for ApInt {
322 #[inline]
323 fn from(val: i64) -> ApInt {
324 ApInt::from_i64(val)
325 }
326}
327
328impl From<u128> for ApInt {
329 #[inline]
330 fn from(val: u128) -> ApInt {
331 ApInt::from_u128(val)
332 }
333}
334
335impl From<i128> for ApInt {
336 #[inline]
337 fn from(val: i128) -> ApInt {
338 ApInt::from_i128(val)
339 }
340}
341
342macro_rules! impl_from_array_for_apint {
343 ($n:expr) => {
344 impl From<[i64; $n]> for ApInt {
345 fn from(val: [i64; $n]) -> ApInt {
346 <Self as From<[u64; $n]>>::from(
347 unsafe{ ::std::mem::transmute::<[i64; $n], [u64; $n]>(val) })
348 }
349 }
350
351 impl From<[u64; $n]> for ApInt {
352 fn from(val: [u64; $n]) -> ApInt {
353 let buffer = val.into_iter()
354 .rev()
355 .cloned()
356 .map(Digit)
357 .collect::<Vec<Digit>>();
358 assert_eq!(buffer.len(), $n);
359 ApInt::from_iter(buffer)
360 .expect("We asserted that `buffer.len()` is exactly `$n` \
361 so we can expect `ApInt::from_iter` to be successful.")
362 }
363 }
364 }
365}
366
367impl_from_array_for_apint!(2); impl_from_array_for_apint!(3); impl_from_array_for_apint!(4); impl_from_array_for_apint!(5); impl_from_array_for_apint!(6); impl_from_array_for_apint!(7); impl_from_array_for_apint!(8); impl_from_array_for_apint!(16); impl_from_array_for_apint!(32); #[cfg(test)]
378mod tests {
379 use super::*;
380
381 use std::ops::Range;
382
383 fn powers() -> impl Iterator<Item=u128> {
384 (0..128).map(|p| 1 << p)
385 }
386
387 fn powers_from_to(range: Range<usize>) -> impl Iterator<Item=u128> {
388 powers().skip(range.start).take(range.end - range.start)
389 }
390
391 mod tests {
392 use super::{powers, powers_from_to};
393
394 #[test]
395 fn test_powers() {
396 let mut pows = powers();
397 assert_eq!(pows.next(), Some(1 << 0));
398 assert_eq!(pows.next(), Some(1 << 1));
399 assert_eq!(pows.next(), Some(1 << 2));
400 assert_eq!(pows.next(), Some(1 << 3));
401 assert_eq!(pows.next(), Some(1 << 4));
402 assert_eq!(pows.next(), Some(1 << 5));
403 assert_eq!(pows.last(), Some(1 << 127));
404 }
405
406 #[test]
407 fn test_powers_from_to() {
408 {
409 let mut powsft = powers_from_to(0..4);
410 assert_eq!(powsft.next(), Some(1 << 0));
411 assert_eq!(powsft.next(), Some(1 << 1));
412 assert_eq!(powsft.next(), Some(1 << 2));
413 assert_eq!(powsft.next(), Some(1 << 3));
414 assert_eq!(powsft.next(), None);
415 }
416 {
417 let mut powsft = powers_from_to(4..7);
418 assert_eq!(powsft.next(), Some(1 << 4));
419 assert_eq!(powsft.next(), Some(1 << 5));
420 assert_eq!(powsft.next(), Some(1 << 6));
421 assert_eq!(powsft.next(), None);
422 }
423 }
424 }
425
426 fn test_values_u8() -> impl Iterator<Item=u8> {
427 powers_from_to(0..8)
428 .map(|v| v as u8)
429 .chain([
430 u8::max_value(),
431 10,
432 42,
433 99,
434 123
435 ].into_iter()
436 .map(|v| *v))
437 }
438
439 #[test]
440 fn from_bit() {
441 {
442 let explicit = ApInt::from_bit(Bit::Set);
443 let implicit = ApInt::from(Bit::Set);
444 let expected = ApInt::new_inl(BitWidth::w1(), Digit::one());
445 assert_eq!(explicit, implicit);
446 assert_eq!(explicit, expected);
447 }
448 {
449 let explicit = ApInt::from_bit(Bit::Unset);
450 let implicit = ApInt::from(Bit::Unset);
451 let expected = ApInt::new_inl(BitWidth::w1(), Digit::zero());
452 assert_eq!(explicit, implicit);
453 assert_eq!(explicit, expected);
454 }
455 }
456
457 #[test]
458 fn from_w8() {
459 for val in test_values_u8() {
460 let explicit_u8 = ApInt::from_u8(val);
461 let explicit_i8 = ApInt::from_i8(val as i8);
462 let implicit_u8 = ApInt::from(val);
463 let implicit_i8 = ApInt::from(val as i8);
464 let expected = ApInt{
465 len : BitWidth::w8(),
466 data: ApIntData{inl: Digit(u64::from(val))}
467 };
468 assert_eq!(explicit_u8, explicit_i8);
469 assert_eq!(explicit_u8, implicit_i8);
470 assert_eq!(explicit_u8, implicit_u8);
471 assert_eq!(explicit_u8, expected);
472 }
473 }
474
475 fn test_values_u16() -> impl Iterator<Item=u16> {
476 test_values_u8()
477 .map(u16::from)
478 .chain(powers_from_to(8..16)
479 .map(|v| v as u16))
480 .chain([
481 u16::max_value(),
482 500,
483 1000,
484 1337,
485 7777,
486 42_000
487 ].into_iter().map(|v| *v))
488 }
489
490 #[test]
491 fn from_w16() {
492 for val in test_values_u16() {
493 let explicit_u16 = ApInt::from_u16(val);
494 let explicit_i16 = ApInt::from_i16(val as i16);
495 let implicit_u16 = ApInt::from(val);
496 let implicit_i16 = ApInt::from(val as i16);
497 let expected = ApInt{
498 len : BitWidth::w16(),
499 data: ApIntData{inl: Digit(u64::from(val))}
500 };
501 assert_eq!(explicit_u16, explicit_i16);
502 assert_eq!(explicit_u16, implicit_i16);
503 assert_eq!(explicit_u16, implicit_u16);
504 assert_eq!(explicit_u16, expected);
505 }
506 }
507
508 fn test_values_u32() -> impl Iterator<Item=u32> {
509 test_values_u16()
510 .map(u32::from)
511 .chain(powers_from_to(16..32)
512 .map(|v| v as u32))
513 .chain([
514 u32::max_value(),
515 1_000_000,
516 999_999_999,
517 1_234_567_890
518 ].into_iter().map(|v| *v))
519 }
520
521 #[test]
522 fn from_w32() {
523 for val in test_values_u32() {
524 let explicit_u32 = ApInt::from_u32(val);
525 let explicit_i32 = ApInt::from_i32(val as i32);
526 let implicit_u32 = ApInt::from(val);
527 let implicit_i32 = ApInt::from(val as i32);
528 let expected = ApInt{
529 len : BitWidth::w32(),
530 data: ApIntData{inl: Digit(u64::from(val))}
531 };
532 assert_eq!(explicit_u32, explicit_i32);
533 assert_eq!(explicit_u32, implicit_i32);
534 assert_eq!(explicit_u32, implicit_u32);
535 assert_eq!(explicit_u32, expected);
536 }
537 }
538
539 fn test_values_u64() -> impl Iterator<Item=u64> {
540 test_values_u32()
541 .map(u64::from)
542 .chain(powers_from_to(32..64)
543 .map(|v| v as u64))
544 .chain([
545 u64::max_value(),
546 1_000_000_000_000,
547 999_999_999_999_999_999,
548 0x0123_4567_89AB_CDEF
549 ].into_iter().map(|v| *v))
550 }
551
552 #[test]
553 fn from_w64() {
554 for val in test_values_u64() {
555 let explicit_u64 = ApInt::from_u64(val);
556 let explicit_i64 = ApInt::from_i64(val as i64);
557 let implicit_u64 = ApInt::from(val);
558 let implicit_i64 = ApInt::from(val as i64);
559 let expected = ApInt{
560 len : BitWidth::w64(),
561 data: ApIntData{inl: Digit(u64::from(val))}
562 };
563 assert_eq!(explicit_u64, explicit_i64);
564 assert_eq!(explicit_u64, implicit_i64);
565 assert_eq!(explicit_u64, implicit_u64);
566 assert_eq!(explicit_u64, expected);
567 }
568 }
569
570 fn test_values_u128() -> impl Iterator<Item=u128> {
571 test_values_u64()
572 .map(u128::from)
573 .chain(powers_from_to(64..128)
574 .map(|v| v as u128))
575 .chain([
576 u128::max_value(),
577 1_000_000_000_000_000_000_000_000,
578 999_999_999_999_999_999_999_999_999,
579 0x0123_4567_89AB_CDEF_FEDC_BA98_7654_3210
580 ].into_iter().map(|v| *v))
581 }
582
583 #[test]
584 fn from_w128() {
585 use digit::{Digit, DigitRepr};
586 for val in test_values_u128() {
587 let explicit_u128 = ApInt::from_u128(val);
588 let explicit_i128 = ApInt::from_i128(val as i128);
589 let implicit_u128 = ApInt::from(val);
590 let implicit_i128 = ApInt::from(val as i128);
591 let expected = ApInt::from_iter(
592 vec![
593 Digit((val & u128::from(u64::max_value())) as DigitRepr),
594 Digit((val >> 64) as DigitRepr)
595 ]).unwrap();
596 assert_eq!(explicit_u128, explicit_i128);
597 assert_eq!(explicit_u128, implicit_i128);
598 assert_eq!(explicit_u128, implicit_u128);
599 assert_eq!(explicit_u128, expected);
600 }
601 }
602
603 #[test]
604 fn zero() {
605 assert_eq!(ApInt::zero(BitWidth::w1()), ApInt::from_bit(false));
606 assert_eq!(ApInt::zero(BitWidth::w8()), ApInt::from_u8(0));
607 assert_eq!(ApInt::zero(BitWidth::w16()), ApInt::from_u16(0));
608 assert_eq!(ApInt::zero(BitWidth::w32()), ApInt::from_u32(0));
609 assert_eq!(ApInt::zero(BitWidth::w64()), ApInt::from_u64(0));
610 assert_eq!(ApInt::zero(BitWidth::w128()), ApInt::from_u128(0));
611 assert_eq!(ApInt::zero(BitWidth::new(192).unwrap()), ApInt::from([0_u64; 3]));
612 assert_eq!(ApInt::zero(BitWidth::new(256).unwrap()), ApInt::from([0_u64; 4]));
613 }
614
615 #[test]
616 fn one() {
617 assert_eq!(ApInt::one(BitWidth::w1()), ApInt::from_bit(true));
618 assert_eq!(ApInt::one(BitWidth::w8()), ApInt::from_u8(1));
619 assert_eq!(ApInt::one(BitWidth::w16()), ApInt::from_u16(1));
620 assert_eq!(ApInt::one(BitWidth::w32()), ApInt::from_u32(1));
621 assert_eq!(ApInt::one(BitWidth::w64()), ApInt::from_u64(1));
622 assert_eq!(ApInt::one(BitWidth::w128()), ApInt::from_u128(1));
623 assert_eq!(ApInt::one(BitWidth::new(192).unwrap()), ApInt::from([0_u64, 0, 1]));
624 assert_eq!(ApInt::one(BitWidth::new(256).unwrap()), ApInt::from([0_u64, 0, 0, 1]));
625 }
626
627 #[test]
628 fn all_unset_eq_zero() {
629 let test_widths =
630 [
631 1_usize, 2, 4, 8, 10, 16, 32, 50, 64,
632 100, 128, 150, 200, 250, 255, 256
633 ]
634 .into_iter()
635 .map(|&w| BitWidth::new(w).unwrap());
636 for width in test_widths {
637 assert_eq!(ApInt::zero(width), ApInt::all_unset(width));
638 }
639 }
640
641 #[test]
642 fn same_signed_unsigned() {
643 assert_eq!(ApInt::from_i8(-1), ApInt::from_u8(0xFF));
644 assert_eq!(ApInt::from_i16(-1), ApInt::from_u16(0xFFFF));
645 assert_eq!(ApInt::from_i32(-1), ApInt::from_u32(0xFFFF_FFFF));
646 assert_eq!(ApInt::from_i64(-1), ApInt::from_u64(0xFFFF_FFFF_FFFF_FFFF));
647 assert_eq!(ApInt::from_i128(-1), ApInt::from_u128(0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF));
648 }
649
650 #[test]
651 fn all_set() {
652 assert_eq!(ApInt::all_set(BitWidth::w1()), ApInt::from_bit(true));
653 assert_eq!(ApInt::all_set(BitWidth::w8()), ApInt::from_i8(-1));
654 assert_eq!(ApInt::all_set(BitWidth::w16()), ApInt::from_i16(-1));
655 assert_eq!(ApInt::all_set(BitWidth::w32()), ApInt::from_i32(-1));
656 assert_eq!(ApInt::all_set(BitWidth::w64()), ApInt::from_i64(-1));
657 assert_eq!(ApInt::all_set(BitWidth::w128()), ApInt::from_i128(-1));
658 assert_eq!(
659 ApInt::all_set(BitWidth::new(192).unwrap()),
660 ApInt::from([-1_i64 as u64, -1_i64 as u64, -1_i64 as u64])
661 );
662 assert_eq!(
663 ApInt::all_set(BitWidth::new(256).unwrap()),
664 ApInt::from([-1_i64 as u64, -1_i64 as u64, -1_i64 as u64, -1_i64 as u64])
665 );
666 }
667
668 #[test]
669 fn unsiged_min_value_eq_zero() {
670 let test_widths =
671 [
672 1_usize, 2, 4, 8, 10, 16, 32, 50, 64,
673 100, 128, 150, 200, 250, 255, 256
674 ]
675 .into_iter()
676 .map(|&w| BitWidth::new(w).unwrap());
677 for width in test_widths {
678 assert_eq!(ApInt::zero(width), ApInt::unsigned_min_value(width));
679 }
680 }
681
682 #[test]
683 fn unsiged_max_value_eq_all_set() {
684 let test_widths =
685 [
686 1_usize, 2, 4, 8, 10, 16, 32, 50, 64,
687 100, 128, 150, 200, 250, 255, 256
688 ]
689 .into_iter()
690 .map(|&w| BitWidth::new(w).unwrap());
691 for width in test_widths {
692 assert_eq!(ApInt::all_set(width), ApInt::unsigned_max_value(width));
693 }
694 }
695
696 #[test]
697 fn signed_min_value() {
698 assert_eq!(ApInt::signed_min_value(BitWidth::w1()), ApInt::from_bit(true));
699 assert_eq!(ApInt::signed_min_value(BitWidth::w8()), ApInt::from_i8(i8::min_value()));
700 assert_eq!(ApInt::signed_min_value(BitWidth::w16()), ApInt::from_i16(i16::min_value()));
701 assert_eq!(ApInt::signed_min_value(BitWidth::w32()), ApInt::from_i32(i32::min_value()));
702 assert_eq!(ApInt::signed_min_value(BitWidth::w64()), ApInt::from_i64(i64::min_value()));
703 assert_eq!(ApInt::signed_min_value(BitWidth::w128()), ApInt::from_i128(i128::min_value()));
704
705 {
706 let w10 = BitWidth::new(10).unwrap();
707 assert_eq!(
708 ApInt::signed_min_value(w10), ApInt::new_inl(w10, Digit(0x0000_0000_0000_0200))
709 )
710 }
711 {
712 use std::i128;
713 assert_eq!(
714 ApInt::signed_min_value(BitWidth::w128()), ApInt::from(i128::MIN)
715 );
716 assert_eq!(
717 ApInt::signed_min_value(BitWidth::w128()), ApInt::from([0x8000_0000_0000_0000_u64, 0_u64])
718 );
719 let w256 = BitWidth::new(256).unwrap();
720 assert_eq!(
721 ApInt::signed_min_value(w256), ApInt::from([0x8000_0000_0000_0000_u64, 0_u64, 0_u64, 0_u64])
722 )
723 }
724 }
725
726 #[test]
727 fn signed_max_value() {
728 assert_eq!(ApInt::signed_max_value(BitWidth::w1()), ApInt::from_bit(false));
729 assert_eq!(ApInt::signed_max_value(BitWidth::w8()), ApInt::from_i8(i8::max_value()));
730 assert_eq!(ApInt::signed_max_value(BitWidth::w16()), ApInt::from_i16(i16::max_value()));
731 assert_eq!(ApInt::signed_max_value(BitWidth::w32()), ApInt::from_i32(i32::max_value()));
732 assert_eq!(ApInt::signed_max_value(BitWidth::w64()), ApInt::from_i64(i64::max_value()));
733 assert_eq!(ApInt::signed_max_value(BitWidth::w128()), ApInt::from_i128(i128::max_value()));
734
735 {
736 let w10 = BitWidth::new(10).unwrap();
737 assert_eq!(
738 ApInt::signed_max_value(w10), ApInt::new_inl(w10, Digit(0x0000_0000_0000_01FF))
739 )
740 }
741 }
742}