apint/apint/
constructors.rs

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	/// Deallocates memory that may be allocated by this `ApInt`.
15	/// 
16	/// `ApInt` instances with a bit width larger than `64` bits
17	/// allocate their digits on the heap. With `drop_digits` this
18	/// memory can be freed.
19	/// 
20	/// **Note:** This is extremely unsafe, only use this if the
21	///           `ApInt` no longer needs its digits.
22	/// 
23	/// **Note:** This is `unsafe` since it violates invariants
24	///           of the `ApInt`.
25	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
40/// # Constructors
41impl ApInt {
42
43	/// Creates a new small `ApInt` from the given `BitWidth` and `Digit`.
44	/// 
45	/// Small `ApInt` instances are stored entirely on the stack.
46	/// 
47	/// # Panics
48	/// 
49	/// - If the given `width` represents a `BitWidth` larger than `64` bits.
50	#[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	/// Creates a new large `ApInt` from the given `BitWidth` and `Digit`.
59	/// 
60	/// Large `ApInt` instances allocate their digits on the heap.
61	/// 
62	/// **Note:** This operation is unsafe since the buffer length behind the
63	///           given `ext_ptr` must be trusted.
64	/// 
65	/// # Panics
66	/// 
67	/// - If the given `width` represents a `BitWidth` smaller than
68	///   or equal to `64` bits.
69	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	/// Creates a new `ApInt` from the given `Bit` value with a bit width of `1`.
78	/// 
79	/// This function is generic over types that are convertible to `Bit` such as `bool`.
80	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	/// Creates a new `ApInt` from a given `i8` value with a bit-width of 8.
87	#[inline]
88	pub fn from_i8(val: i8) -> ApInt {
89		ApInt::from_u8(val as u8)
90	}
91
92	/// Creates a new `ApInt` from a given `u8` value with a bit-width of 8.
93	#[inline]
94	pub fn from_u8(val: u8) -> ApInt {
95		ApInt::new_inl(BitWidth::w8(), Digit(u64::from(val)))
96	}
97
98	/// Creates a new `ApInt` from a given `i16` value with a bit-width of 16.
99	#[inline]
100	pub fn from_i16(val: i16) -> ApInt {
101		ApInt::from_u16(val as u16)
102	}
103
104	/// Creates a new `ApInt` from a given `u16` value with a bit-width of 16.
105	#[inline]
106	pub fn from_u16(val: u16) -> ApInt {
107		ApInt::new_inl(BitWidth::w16(), Digit(u64::from(val)))
108	}
109
110	/// Creates a new `ApInt` from a given `i32` value with a bit-width of 32.
111	#[inline]
112	pub fn from_i32(val: i32) -> ApInt {
113		ApInt::from_u32(val as u32)
114	}
115
116	/// Creates a new `ApInt` from a given `u32` value with a bit-width of 32.
117	#[inline]
118	pub fn from_u32(val: u32) -> ApInt {
119		ApInt::new_inl(BitWidth::w32(), Digit(u64::from(val)))
120	}
121
122	/// Creates a new `ApInt` from a given `i64` value with a bit-width of 64.
123	#[inline]
124	pub fn from_i64(val: i64) -> ApInt {
125		ApInt::from_u64(val as u64)
126	}
127
128	/// Creates a new `ApInt` from a given `u64` value with a bit-width of 64.
129	#[inline]
130	pub fn from_u64(val: u64) -> ApInt {
131		ApInt::new_inl(BitWidth::w64(), Digit(val))
132	}
133
134	/// Creates a new `ApInt` from a given `i128` value with a bit-width of 128.
135	#[inline]
136	pub fn from_i128(val: i128) -> ApInt {
137		ApInt::from_u128(val as u128)
138	}
139
140	/// Creates a new `ApInt` from a given `u128` value with a bit-width of 128.
141	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	/// Creates a new `ApInt` from the given iterator over `Digit`s.
148	/// 
149	/// This results in `ApInt` instances with bitwidths that are a multiple
150	/// of a `Digit`s bitwidth (e.g. 64 bit).
151	/// 
152	/// Users of this API may truncate, extend or simply resize the resulting
153	/// `ApInt` afterwards to obtain the desired bitwidth. This may be very cheap
154	/// depending on the difference between the actual and target bitwidths.
155	/// For example, `move_truncate`ing a `128` bitwidth `ApInt` to `100` is
156	/// relatively cheap and won't allocate memory since both `ApInt` instances can use
157	/// the same amount of `Digit`s.
158	/// 
159	/// # Errors
160	/// 
161	/// - If the iterator yields no elements.
162	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	/// Creates a new `ApInt` that represents the repetition of the given digit
193	/// up to the given target bitwidth.
194	/// 
195	/// Note: The last digit in the generated sequence is truncated to make the `ApInt`'s
196	///       value representation fit the given bit-width.
197	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	/// Creates a new `ApInt` with the given bit width that represents zero.
217	pub fn zero(width: BitWidth) -> ApInt {
218		ApInt::repeat_digit(width, digit::ZERO)
219	}
220
221	/// Creates a new `ApInt` with the given bit width that represents one.
222	pub fn one(width: BitWidth) -> ApInt {
223		ApInt::from_u64(1).into_zero_resize(width)
224	}
225
226	/// Creates a new `ApInt` with the given bit width that has all bits unset.
227	/// 
228	/// **Note:** This is equal to calling `ApInt::zero` with the given `width`.
229	pub fn all_unset(width: BitWidth) -> ApInt {
230		ApInt::zero(width)
231	}
232
233	/// Creates a new `ApInt` with the given bit width that has all bits set.
234	pub fn all_set(width: BitWidth) -> ApInt {
235		ApInt::repeat_digit(width, digit::ONES)
236	}
237
238	/// Returns the smallest unsigned `ApInt` that can be represented by the given `BitWidth`.
239	pub fn unsigned_min_value(width: BitWidth) -> ApInt {
240		ApInt::zero(width)
241	}
242
243	/// Returns the largest unsigned `ApInt` that can be represented by the given `BitWidth`.
244	pub fn unsigned_max_value(width: BitWidth) -> ApInt {
245		ApInt::all_set(width)
246	}
247
248	/// Returns the smallest signed `ApInt` that can be represented by the given `BitWidth`.
249	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	/// Returns the largest signed `ApInt` that can be represented by the given `BitWidth`.
256	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);  // 128 bits
368impl_from_array_for_apint!(3);  // 192 bits
369impl_from_array_for_apint!(4);  // 256 bits
370impl_from_array_for_apint!(5);  // 320 bits
371impl_from_array_for_apint!(6);  // 384 bits
372impl_from_array_for_apint!(7);  // 448 bits
373impl_from_array_for_apint!(8);  // 512 bits
374impl_from_array_for_apint!(16); // 1024 bits
375impl_from_array_for_apint!(32); // 2048 bits
376
377#[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}