apint/apint/
bitwise.rs

1use apint::{ApInt};
2use digit::{Bit};
3use digit;
4use errors::{Result};
5use apint::utils::{
6	DataAccess,
7	DataAccessMut
8};
9use bitpos::{BitPos};
10use traits::{Width};
11use checks;
12use utils::{try_forward_bin_mut_impl, forward_mut_impl};
13
14use std::ops::{
15	Not,
16	BitAnd,
17	BitOr,
18	BitXor,
19	BitAndAssign,
20	BitOrAssign,
21	BitXorAssign
22};
23
24/// # Bitwise Operations
25impl ApInt {
26	/// Flips all bits of `self` and returns the result.
27	pub fn into_bitnot(self) -> Self {
28		forward_mut_impl(self, ApInt::bitnot)
29	}
30
31	/// Flip all bits of this `ApInt` inplace.
32	pub fn bitnot(&mut self) {
33		self.modify_digits(|digit| digit.not_inplace());
34		self.clear_unused_bits();
35	}
36
37	/// Tries to bit-and assign this `ApInt` inplace to `rhs`
38	/// and returns the result.
39	/// 
40	/// **Note:** This forwards to
41	/// [`checked_bitand`](struct.ApInt.html#method.checked_bitand).
42	/// 
43	/// # Errors
44	/// 
45	/// If `self` and `rhs` have unmatching bit widths.
46	pub fn into_checked_bitand(self, rhs: &ApInt) -> Result<ApInt> {
47		try_forward_bin_mut_impl(self, rhs, ApInt::checked_bitand_assign)
48	}
49
50	/// Bit-and assigns all bits of this `ApInt` with the bits of `rhs`.
51	/// 
52	/// **Note:** This operation is inplace of `self` and won't allocate memory.
53	/// 
54	/// # Errors
55	/// 
56	/// If `self` and `rhs` have unmatching bit widths.
57	pub fn checked_bitand_assign(&mut self, rhs: &ApInt) -> Result<()> {
58		self.modify_zipped_digits(rhs, |l, r| *l &= r)
59	}
60
61	/// Tries to bit-and assign this `ApInt` inplace to `rhs`
62	/// and returns the result.
63	/// 
64	/// **Note:** This forwards to
65	/// [`checked_bitor`](struct.ApInt.html#method.checked_bitor).
66	/// 
67	/// # Errors
68	/// 
69	/// If `self` and `rhs` have unmatching bit widths.
70	pub fn into_checked_bitor(self, rhs: &ApInt) -> Result<ApInt> {
71		try_forward_bin_mut_impl(self, rhs, ApInt::checked_bitor_assign)
72	}
73
74	/// Bit-or assigns all bits of this `ApInt` with the bits of `rhs`.
75	/// 
76	/// **Note:** This operation is inplace of `self` and won't allocate memory.
77	/// 
78	/// # Errors
79	/// 
80	/// If `self` and `rhs` have unmatching bit widths.
81	pub fn checked_bitor_assign(&mut self, rhs: &ApInt) -> Result<()> {
82		self.modify_zipped_digits(rhs, |l, r| *l |= r)
83	}
84
85	/// Tries to bit-xor assign this `ApInt` inplace to `rhs`
86	/// and returns the result.
87	/// 
88	/// **Note:** This forwards to
89	/// [`checked_bitxor`](struct.ApInt.html#method.checked_bitxor).
90	/// 
91	/// # Errors
92	/// 
93	/// If `self` and `rhs` have unmatching bit widths.
94	pub fn into_checked_bitxor(self, rhs: &ApInt) -> Result<ApInt> {
95		try_forward_bin_mut_impl(self, rhs, ApInt::checked_bitxor_assign)
96	}
97
98	/// Bit-xor assigns all bits of this `ApInt` with the bits of `rhs`.
99	/// 
100	/// **Note:** This operation is inplace of `self` and won't allocate memory.
101	/// 
102	/// # Errors
103	/// 
104	/// If `self` and `rhs` have unmatching bit widths.
105	pub fn checked_bitxor_assign(&mut self, rhs: &ApInt) -> Result<()> {
106		self.modify_zipped_digits(rhs, |l, r| *l ^= r)
107	}
108}
109
110/// # Bitwise Access
111impl ApInt {
112	/// Returns the bit at the given bit position `pos`.
113	/// 
114	/// This returns
115	/// 
116	/// - `Bit::Set` if the bit at `pos` is `1`
117	/// - `Bit::Unset` otherwise
118	/// 
119	/// # Errors
120	/// 
121	/// - If `pos` is not a valid bit position for the width of this `ApInt`.
122	pub fn get_bit_at<P>(&self, pos: P) -> Result<Bit>
123		where P: Into<BitPos>
124	{
125		let pos = pos.into();
126		checks::verify_bit_access(self, pos)?;
127		match self.access_data() {
128			DataAccess::Inl(digit) => digit.get(pos),
129			DataAccess::Ext(digits) => {
130				let (digit_pos, bit_pos) = pos.to_digit_and_bit_pos();
131				digits[digit_pos].get(bit_pos)
132			}
133		}
134	}
135
136	/// Sets the bit at the given bit position `pos` to one (`1`).
137	/// 
138	/// # Errors
139	/// 
140	/// - If `pos` is not a valid bit position for the width of this `ApInt`.
141	pub fn set_bit_at<P>(&mut self, pos: P) -> Result<()>
142		where P: Into<BitPos>
143	{
144		let pos = pos.into();
145		checks::verify_bit_access(self, pos)?;
146		match self.access_data_mut() {
147			DataAccessMut::Inl(digit) => digit.set(pos),
148			DataAccessMut::Ext(digits) => {
149				let (digit_pos, bit_pos) = pos.to_digit_and_bit_pos();
150				digits[digit_pos].set(bit_pos)
151			}
152		}
153	}
154
155	/// Sets the bit at the given bit position `pos` to zero (`0`).
156	/// 
157	/// # Errors
158	/// 
159	/// - If `pos` is not a valid bit position for the width of this `ApInt`.
160	pub fn unset_bit_at<P>(&mut self, pos: P) -> Result<()>
161		where P: Into<BitPos>
162	{
163		let pos = pos.into();
164		checks::verify_bit_access(self, pos)?;
165		match self.access_data_mut() {
166			DataAccessMut::Inl(digit) => digit.unset(pos),
167			DataAccessMut::Ext(digits) => {
168				let (digit_pos, bit_pos) = pos.to_digit_and_bit_pos();
169				digits[digit_pos].unset(bit_pos)
170			}
171		}
172	}
173
174	/// Flips the bit at the given bit position `pos`.
175	/// 
176	/// # Note
177	/// 
178	/// - If the bit at the given position was `0` it will be `1`
179	///   after this operation and vice versa.
180	/// 
181	/// # Errors
182	/// 
183	/// - If `pos` is not a valid bit position for the width of this `ApInt`.
184	pub fn flip_bit_at<P>(&mut self, pos: P) -> Result<()>
185		where P: Into<BitPos>
186	{
187		let pos = pos.into();
188		checks::verify_bit_access(self, pos)?;
189		match self.access_data_mut() {
190			DataAccessMut::Inl(digit) => digit.flip(pos),
191			DataAccessMut::Ext(digits) => {
192				let (digit_pos, bit_pos) = pos.to_digit_and_bit_pos();
193				digits[digit_pos].flip(bit_pos)
194			}
195		}
196	}
197
198	/// Sets all bits of this `ApInt` to one (`1`).
199	pub fn set_all(&mut self) {
200		self.modify_digits(|digit| digit.set_all());
201		self.clear_unused_bits();
202	}
203
204	/// Returns``true` if all bits in the `ApInt` are set.
205	pub fn is_all_set(&self) -> bool {
206		let (msb, rest) = self.split_most_significant_digit();
207		if let Some(excess_bits) = self.width().excess_bits() {
208			if msb.repr().count_ones() as usize != excess_bits {
209				return false
210			}
211		}
212		rest.iter().all(|d| d.is_all_set())
213	}
214
215	/// Sets all bits of this `ApInt` to zero (`0`).
216	pub fn unset_all(&mut self) {
217		self.modify_digits(|digit| digit.unset_all());
218	}
219
220	/// Returns `true` if all bits in the `ApInt` are unset.
221	pub fn is_all_unset(&self) -> bool {
222		self.is_zero()
223	}
224
225	/// Flips all bits of this `ApInt`.
226	pub fn flip_all(&mut self) {
227		// TODO: remove since equal to ApInt::checked_bitnot_assign
228		self.modify_digits(|digit| digit.flip_all());
229		self.clear_unused_bits();
230	}
231
232	/// Returns the sign bit of this `ApInt`.
233	/// 
234	/// **Note:** This is equal to the most significant bit of this `ApInt`.
235	pub fn sign_bit(&self) -> Bit {
236		self.most_significant_bit()
237	}
238
239	/// Sets the sign bit of this `ApInt` to one (`1`).
240	pub fn set_sign_bit(&mut self) {
241		let sign_bit_pos = self.width().sign_bit_pos();
242		self.set_bit_at(sign_bit_pos)
243		    .expect("`BitWidth::sign_bit_pos` always returns a valid `BitPos`
244			         for usage in the associated `ApInt` for operating on bits.")
245	}
246
247	/// Sets the sign bit of this `ApInt` to zero (`0`).
248	pub fn unset_sign_bit(&mut self) {
249		let sign_bit_pos = self.width().sign_bit_pos();
250		self.unset_bit_at(sign_bit_pos)
251		    .expect("`BitWidth::sign_bit_pos` always returns a valid `BitPos`
252			         for usage in the associated `ApInt` for operating on bits.")
253	}
254
255	/// Flips the sign bit of this `ApInt`.
256	/// 
257	/// # Note
258	/// 
259	/// - If the sign bit was `0` it will be `1` after this operation and vice versa.
260	/// - Depending on the interpretation of the `ApInt` this
261	///   operation changes its signedness.
262	pub fn flip_sign_bit(&mut self) {
263		let sign_bit_pos = self.width().sign_bit_pos();
264		self.flip_bit_at(sign_bit_pos)
265		    .expect("`BitWidth::sign_bit_pos` always returns a valid `BitPos`
266			         for usage in the associated `ApInt` for operating on bits.")
267	}
268}
269
270/// # Bitwise utility methods.
271impl ApInt {
272	/// Returns the number of ones in the binary representation of this `ApInt`.
273	pub fn count_ones(&self) -> usize {
274		self.as_digit_slice()
275		    .into_iter()
276		    .map(|d| d.repr().count_ones() as usize)
277		    .sum::<usize>()
278	}
279
280	/// Returns the number of zeros in the binary representation of this `ApInt`.
281	pub fn count_zeros(&self) -> usize {
282		let zeros = self.as_digit_slice()
283			.into_iter()
284		    .map(|d| d.repr().count_zeros() as usize)
285			.sum::<usize>();
286		// Since `ApInt` instances with width's that are no powers of two
287		// have unused excess bits that are always zero we need to cut them off
288		// for a correct implementation of this operation.
289		zeros - (digit::BITS - self.width().excess_bits().unwrap_or(digit::BITS))
290	}
291
292	/// Returns the number of leading zeros in the binary representation of this `ApInt`.
293	pub fn leading_zeros(&self) -> usize {
294		let mut zeros = 0;
295		for d in self.as_digit_slice().into_iter().rev() {
296			let leading_zeros = d.repr().leading_zeros() as usize;
297			zeros += leading_zeros;
298			if leading_zeros != digit::BITS {
299				break;
300			}
301		}
302		zeros - (digit::BITS - self.width().excess_bits().unwrap_or(digit::BITS))
303	}
304
305	/// Returns the number of trailing zeros in the binary representation of this `ApInt`.
306	pub fn trailing_zeros(&self) -> usize {
307		let mut zeros = 0;
308		for d in self.as_digit_slice() {
309			let trailing_zeros = d.repr().trailing_zeros() as usize;
310			zeros += trailing_zeros;
311			if trailing_zeros != digit::BITS {
312				break;
313			}
314		}
315		if zeros >= self.width().to_usize() {
316			zeros -= digit::BITS - self.width().excess_bits().unwrap_or(digit::BITS);
317		}
318		zeros
319	}
320}
321
322//  ===========================================================================
323//  `Not` (bitwise) impls
324//  ===========================================================================
325
326impl Not for ApInt {
327	type Output = ApInt;
328
329	fn not(self) -> Self::Output {
330		forward_mut_impl(self, ApInt::bitnot)
331	}
332}
333
334//  ===========================================================================
335//  `BitAnd` impls
336//  ===========================================================================
337
338impl<'a> BitAnd<&'a ApInt> for ApInt {
339    type Output = ApInt;
340
341    fn bitand(self, rhs: &'a ApInt) -> Self::Output {
342        self.into_checked_bitand(rhs).unwrap()
343    }
344}
345
346impl<'a, 'b> BitAnd<&'a ApInt> for &'b ApInt {
347    type Output = ApInt;
348
349    fn bitand(self, rhs: &'a ApInt) -> Self::Output {
350        self.clone().into_checked_bitand(rhs).unwrap()
351    }
352}
353
354impl<'a, 'b> BitAnd<&'a ApInt> for &'b mut ApInt {
355    type Output = ApInt;
356
357    fn bitand(self, rhs: &'a ApInt) -> Self::Output {
358        self.clone().into_checked_bitand(rhs).unwrap()
359    }
360}
361
362//  ===========================================================================
363//  `BitOr` impls
364//  ===========================================================================
365
366impl<'a> BitOr<&'a ApInt> for ApInt {
367    type Output = ApInt;
368
369    fn bitor(self, rhs: &'a ApInt) -> Self::Output {
370        self.into_checked_bitor(rhs).unwrap()
371    }
372}
373
374impl<'a, 'b> BitOr<&'a ApInt> for &'b ApInt {
375    type Output = ApInt;
376
377    fn bitor(self, rhs: &'a ApInt) -> Self::Output {
378        self.clone().into_checked_bitor(rhs).unwrap()
379    }
380}
381
382impl<'a, 'b> BitOr<&'a ApInt> for &'b mut ApInt {
383    type Output = ApInt;
384
385    fn bitor(self, rhs: &'a ApInt) -> Self::Output {
386        self.clone().into_checked_bitor(rhs).unwrap()
387    }
388}
389
390//  ===========================================================================
391//  `BitXor` impls
392//  ===========================================================================
393
394impl<'a> BitXor<&'a ApInt> for ApInt {
395    type Output = ApInt;
396
397    fn bitxor(self, rhs: &'a ApInt) -> Self::Output {
398        self.into_checked_bitxor(rhs).unwrap()
399    }
400}
401
402impl<'a, 'b> BitXor<&'a ApInt> for &'b ApInt {
403    type Output = ApInt;
404
405    fn bitxor(self, rhs: &'a ApInt) -> Self::Output {
406        self.clone().into_checked_bitxor(rhs).unwrap()
407    }
408}
409
410impl<'a, 'b> BitXor<&'a ApInt> for &'b mut ApInt {
411    type Output = ApInt;
412
413    fn bitxor(self, rhs: &'a ApInt) -> Self::Output {
414        self.clone().into_checked_bitxor(rhs).unwrap()
415    }
416}
417
418//  ===========================================================================
419//  `BitAndAssign`, `BitOrAssign` and `BitXorAssign` impls
420//  ===========================================================================
421
422impl<'a> BitAndAssign<&'a ApInt> for ApInt {
423    fn bitand_assign(&mut self, rhs: &'a ApInt) {
424        self.checked_bitand_assign(rhs).unwrap();
425    }
426}
427
428impl<'a> BitOrAssign<&'a ApInt> for ApInt {
429    fn bitor_assign(&mut self, rhs: &'a ApInt) {
430        self.checked_bitor_assign(rhs).unwrap();
431    }
432}
433
434impl<'a> BitXorAssign<&'a ApInt> for ApInt {
435    fn bitxor_assign(&mut self, rhs: &'a ApInt) {
436        self.checked_bitxor_assign(rhs).unwrap();
437    }
438}
439
440#[cfg(test)]
441mod tests {
442	use super::*;
443
444	use bitwidth::{BitWidth};
445
446	#[test]
447	fn count_ones() {
448		assert_eq!(ApInt::zero(BitWidth::w1()).count_ones(), 0);
449		assert_eq!(ApInt::zero(BitWidth::w8()).count_ones(), 0);
450		assert_eq!(ApInt::zero(BitWidth::w16()).count_ones(), 0);
451		assert_eq!(ApInt::zero(BitWidth::w32()).count_ones(), 0);
452		assert_eq!(ApInt::zero(BitWidth::w64()).count_ones(), 0);
453		assert_eq!(ApInt::zero(BitWidth::w128()).count_ones(), 0);
454
455		assert_eq!(ApInt::one(BitWidth::w1()).count_ones(), 1);
456		assert_eq!(ApInt::one(BitWidth::w8()).count_ones(), 1);
457		assert_eq!(ApInt::one(BitWidth::w16()).count_ones(), 1);
458		assert_eq!(ApInt::one(BitWidth::w32()).count_ones(), 1);
459		assert_eq!(ApInt::one(BitWidth::w64()).count_ones(), 1);
460		assert_eq!(ApInt::one(BitWidth::w128()).count_ones(), 1);
461
462		assert_eq!(ApInt::signed_min_value(BitWidth::w1()).count_ones(), 1);
463		assert_eq!(ApInt::signed_min_value(BitWidth::w8()).count_ones(), 1);
464		assert_eq!(ApInt::signed_min_value(BitWidth::w16()).count_ones(), 1);
465		assert_eq!(ApInt::signed_min_value(BitWidth::w32()).count_ones(), 1);
466		assert_eq!(ApInt::signed_min_value(BitWidth::w64()).count_ones(), 1);
467		assert_eq!(ApInt::signed_min_value(BitWidth::w128()).count_ones(), 1);
468
469		assert_eq!(ApInt::signed_max_value(BitWidth::w1()).count_ones(), 0);
470		assert_eq!(ApInt::signed_max_value(BitWidth::w8()).count_ones(), 8 - 1);
471		assert_eq!(ApInt::signed_max_value(BitWidth::w16()).count_ones(), 16 - 1);
472		assert_eq!(ApInt::signed_max_value(BitWidth::w32()).count_ones(), 32 - 1);
473		assert_eq!(ApInt::signed_max_value(BitWidth::w64()).count_ones(), 64 - 1);
474		assert_eq!(ApInt::signed_max_value(BitWidth::w128()).count_ones(), 128 - 1);
475	}
476
477	#[test]
478	fn count_zeros() {
479		assert_eq!(ApInt::zero(BitWidth::w1()).count_zeros(), 1);
480		assert_eq!(ApInt::zero(BitWidth::w8()).count_zeros(), 8);
481		assert_eq!(ApInt::zero(BitWidth::w16()).count_zeros(), 16);
482		assert_eq!(ApInt::zero(BitWidth::w32()).count_zeros(), 32);
483		assert_eq!(ApInt::zero(BitWidth::w64()).count_zeros(), 64);
484		assert_eq!(ApInt::zero(BitWidth::w128()).count_zeros(), 128);
485
486		assert_eq!(ApInt::one(BitWidth::w1()).count_zeros(), 0);
487		assert_eq!(ApInt::one(BitWidth::w8()).count_zeros(), 8 - 1);
488		assert_eq!(ApInt::one(BitWidth::w16()).count_zeros(), 16 - 1);
489		assert_eq!(ApInt::one(BitWidth::w32()).count_zeros(), 32 - 1);
490		assert_eq!(ApInt::one(BitWidth::w64()).count_zeros(), 64 - 1);
491		assert_eq!(ApInt::one(BitWidth::w128()).count_zeros(), 128 - 1);
492
493		assert_eq!(ApInt::signed_min_value(BitWidth::w1()).count_zeros(), 0);
494		assert_eq!(ApInt::signed_min_value(BitWidth::w8()).count_zeros(), 8 - 1);
495		assert_eq!(ApInt::signed_min_value(BitWidth::w16()).count_zeros(), 16 - 1);
496		assert_eq!(ApInt::signed_min_value(BitWidth::w32()).count_zeros(), 32 - 1);
497		assert_eq!(ApInt::signed_min_value(BitWidth::w64()).count_zeros(), 64 - 1);
498		assert_eq!(ApInt::signed_min_value(BitWidth::w128()).count_zeros(), 128 - 1);
499
500		assert_eq!(ApInt::signed_max_value(BitWidth::w1()).count_zeros(), 1);
501		assert_eq!(ApInt::signed_max_value(BitWidth::w8()).count_zeros(), 1);
502		assert_eq!(ApInt::signed_max_value(BitWidth::w16()).count_zeros(), 1);
503		assert_eq!(ApInt::signed_max_value(BitWidth::w32()).count_zeros(), 1);
504		assert_eq!(ApInt::signed_max_value(BitWidth::w64()).count_zeros(), 1);
505		assert_eq!(ApInt::signed_max_value(BitWidth::w128()).count_zeros(), 1);
506	}
507
508	#[test]
509	fn leading_zeros() {
510		assert_eq!(ApInt::zero(BitWidth::w1()).leading_zeros(), 1);
511		assert_eq!(ApInt::zero(BitWidth::w8()).leading_zeros(), 8);
512		assert_eq!(ApInt::zero(BitWidth::w16()).leading_zeros(), 16);
513		assert_eq!(ApInt::zero(BitWidth::w32()).leading_zeros(), 32);
514		assert_eq!(ApInt::zero(BitWidth::w64()).leading_zeros(), 64);
515		assert_eq!(ApInt::zero(BitWidth::w128()).leading_zeros(), 128);
516
517		assert_eq!(ApInt::one(BitWidth::w1()).leading_zeros(), 0);
518		assert_eq!(ApInt::one(BitWidth::w8()).leading_zeros(), 8 - 1);
519		assert_eq!(ApInt::one(BitWidth::w16()).leading_zeros(), 16 - 1);
520		assert_eq!(ApInt::one(BitWidth::w32()).leading_zeros(), 32 - 1);
521		assert_eq!(ApInt::one(BitWidth::w64()).leading_zeros(), 64 - 1);
522		assert_eq!(ApInt::one(BitWidth::w128()).leading_zeros(), 128 - 1);
523
524		assert_eq!(ApInt::signed_min_value(BitWidth::w1()).leading_zeros(), 0);
525		assert_eq!(ApInt::signed_min_value(BitWidth::w8()).leading_zeros(), 0);
526		assert_eq!(ApInt::signed_min_value(BitWidth::w16()).leading_zeros(), 0);
527		assert_eq!(ApInt::signed_min_value(BitWidth::w32()).leading_zeros(), 0);
528		assert_eq!(ApInt::signed_min_value(BitWidth::w64()).leading_zeros(), 0);
529		assert_eq!(ApInt::signed_min_value(BitWidth::w128()).leading_zeros(), 0);
530
531		assert_eq!(ApInt::signed_max_value(BitWidth::w1()).leading_zeros(), 1);
532		assert_eq!(ApInt::signed_max_value(BitWidth::w8()).leading_zeros(), 1);
533		assert_eq!(ApInt::signed_max_value(BitWidth::w16()).leading_zeros(), 1);
534		assert_eq!(ApInt::signed_max_value(BitWidth::w32()).leading_zeros(), 1);
535		assert_eq!(ApInt::signed_max_value(BitWidth::w64()).leading_zeros(), 1);
536		assert_eq!(ApInt::signed_max_value(BitWidth::w128()).leading_zeros(), 1);
537	}
538
539	#[test]
540	fn trailing_zeros() {
541		assert_eq!(ApInt::zero(BitWidth::w1()).trailing_zeros(), 1);
542		assert_eq!(ApInt::zero(BitWidth::w8()).trailing_zeros(), 8);
543		assert_eq!(ApInt::zero(BitWidth::w16()).trailing_zeros(), 16);
544		assert_eq!(ApInt::zero(BitWidth::w32()).trailing_zeros(), 32);
545		assert_eq!(ApInt::zero(BitWidth::w64()).trailing_zeros(), 64);
546		assert_eq!(ApInt::zero(BitWidth::w128()).trailing_zeros(), 128);
547
548		assert_eq!(ApInt::one(BitWidth::w1()).trailing_zeros(), 0);
549		assert_eq!(ApInt::one(BitWidth::w8()).trailing_zeros(), 0);
550		assert_eq!(ApInt::one(BitWidth::w16()).trailing_zeros(), 0);
551		assert_eq!(ApInt::one(BitWidth::w32()).trailing_zeros(), 0);
552		assert_eq!(ApInt::one(BitWidth::w64()).trailing_zeros(), 0);
553		assert_eq!(ApInt::one(BitWidth::w128()).trailing_zeros(), 0);
554
555		assert_eq!(ApInt::signed_min_value(BitWidth::w1()).trailing_zeros(), 0);
556		assert_eq!(ApInt::signed_min_value(BitWidth::w8()).trailing_zeros(), 8 - 1);
557		assert_eq!(ApInt::signed_min_value(BitWidth::w16()).trailing_zeros(), 16 - 1);
558		assert_eq!(ApInt::signed_min_value(BitWidth::w32()).trailing_zeros(), 32 - 1);
559		assert_eq!(ApInt::signed_min_value(BitWidth::w64()).trailing_zeros(), 64 - 1);
560		assert_eq!(ApInt::signed_min_value(BitWidth::w128()).trailing_zeros(), 128 - 1);
561
562		assert_eq!(ApInt::signed_max_value(BitWidth::w1()).trailing_zeros(), 1);
563		assert_eq!(ApInt::signed_max_value(BitWidth::w8()).trailing_zeros(), 0);
564		assert_eq!(ApInt::signed_max_value(BitWidth::w16()).trailing_zeros(), 0);
565		assert_eq!(ApInt::signed_max_value(BitWidth::w32()).trailing_zeros(), 0);
566		assert_eq!(ApInt::signed_max_value(BitWidth::w64()).trailing_zeros(), 0);
567		assert_eq!(ApInt::signed_max_value(BitWidth::w128()).trailing_zeros(), 0);
568	}
569
570	mod is_all_set {
571		use super::*;
572
573		#[test]
574		fn simple_false() {
575			let input = ApInt::from(0b0001_1011_0110_0111_u16);
576			assert_eq!(input.width(), BitWidth::w16());
577			assert_eq!(input.count_ones(), 9);
578			assert!(!input.is_all_set());
579		}
580
581		#[test]
582		fn simple_true() {
583			let input = ApInt::all_set(BitWidth::w32());
584			assert_eq!(input.width(), BitWidth::w32());
585			assert_eq!(input.count_ones(), 32);
586			assert!(input.is_all_set());
587		}
588	}
589
590	mod is_all_unset {
591		use super::*;
592
593		#[test]
594		fn simple_false() {
595			let input = ApInt::from(0b0001_1011_0110_0111_u16);
596			assert_eq!(input.width(), BitWidth::w16());
597			assert_eq!(input.count_ones(), 9);
598			assert_eq!(input.is_zero(), input.is_all_unset());
599		}
600
601		#[test]
602		fn simple_true() {
603			let input = ApInt::all_unset(BitWidth::w32());
604			assert_eq!(input.width(), BitWidth::w32());
605			assert_eq!(input.count_ones(), 0);
606			assert_eq!(input.is_zero(), input.is_all_unset());
607		}
608	}
609}