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
24impl ApInt {
26 pub fn into_bitnot(self) -> Self {
28 forward_mut_impl(self, ApInt::bitnot)
29 }
30
31 pub fn bitnot(&mut self) {
33 self.modify_digits(|digit| digit.not_inplace());
34 self.clear_unused_bits();
35 }
36
37 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 pub fn checked_bitand_assign(&mut self, rhs: &ApInt) -> Result<()> {
58 self.modify_zipped_digits(rhs, |l, r| *l &= r)
59 }
60
61 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 pub fn checked_bitor_assign(&mut self, rhs: &ApInt) -> Result<()> {
82 self.modify_zipped_digits(rhs, |l, r| *l |= r)
83 }
84
85 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 pub fn checked_bitxor_assign(&mut self, rhs: &ApInt) -> Result<()> {
106 self.modify_zipped_digits(rhs, |l, r| *l ^= r)
107 }
108}
109
110impl ApInt {
112 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 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 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 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 pub fn set_all(&mut self) {
200 self.modify_digits(|digit| digit.set_all());
201 self.clear_unused_bits();
202 }
203
204 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 pub fn unset_all(&mut self) {
217 self.modify_digits(|digit| digit.unset_all());
218 }
219
220 pub fn is_all_unset(&self) -> bool {
222 self.is_zero()
223 }
224
225 pub fn flip_all(&mut self) {
227 self.modify_digits(|digit| digit.flip_all());
229 self.clear_unused_bits();
230 }
231
232 pub fn sign_bit(&self) -> Bit {
236 self.most_significant_bit()
237 }
238
239 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 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 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
270impl ApInt {
272 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 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 zeros - (digit::BITS - self.width().excess_bits().unwrap_or(digit::BITS))
290 }
291
292 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 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
322impl Not for ApInt {
327 type Output = ApInt;
328
329 fn not(self) -> Self::Output {
330 forward_mut_impl(self, ApInt::bitnot)
331 }
332}
333
334impl<'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
362impl<'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
390impl<'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
418impl<'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}