apint/
uint.rs

1use apint::ApInt;
2use traits::Width;
3use digit::Bit;
4use bitwidth::BitWidth;
5use errors::Result;
6use apint::{ShiftAmount};
7use bitpos::{BitPos};
8use int::Int;
9use utils::{try_forward_bin_mut_impl, forward_mut_impl, forward_bin_mut_impl};
10
11#[cfg(feature = "rand_support")]
12use rand;
13
14use std::cmp::Ordering;
15use std::ops::{
16	Not,
17	BitAnd,
18	BitOr,
19	BitXor,
20	BitAndAssign,
21	BitOrAssign,
22	BitXorAssign,
23	Add,
24	Sub,
25	Mul,
26    Div,
27    Rem,
28	AddAssign,
29	SubAssign,
30	MulAssign,
31    DivAssign,
32    RemAssign
33};
34
35/// Unsigned machine integer with arbitrary bitwidths and modulo arithmetics.
36/// 
37/// Thin convenience wrapper around `ApInt` for static unsigned interpretation of the value.
38/// 
39/// This very cheaply transformes to and from `ApInt` and `Int` instances and together with
40/// `Int` offers a more elegant and higher-level abstraction interface to the lower-level `ApInt`.
41#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
42pub struct UInt {
43    value: ApInt,
44}
45
46impl From<ApInt> for UInt {
47    fn from(value: ApInt) -> UInt {
48        UInt { value }
49    }
50}
51
52impl UInt {
53    /// Transforms this `UInt` into an equivalent `ApInt` instance.
54    pub fn into_apint(self) -> ApInt {
55        self.value
56    }
57
58    /// Transforms this `UInt` into an equivalent `Int` instance.
59    pub fn into_signed(self) -> Int {
60        Int::from(self.value)
61    }
62}
63
64/// # Constructors
65impl UInt {
66    /// Creates a new `UInt` from the given `Bit` value with a bit width of `1`.
67    ///
68    /// This function is generic over types that are convertible to `Bit` such as `bool`.
69    pub fn from_bit<B>(bit: B) -> UInt
70    where
71        B: Into<Bit>,
72    {
73        UInt::from(ApInt::from_bit(bit))
74    }
75
76    /// Creates a new `UInt` from a given `u8` value with a bit-width of 8.
77    #[inline]
78    pub fn from_u8(val: u8) -> UInt {
79        UInt::from(ApInt::from_u8(val))
80    }
81
82    /// Creates a new `UInt` from a given `u16` value with a bit-width of 16.
83    #[inline]
84    pub fn from_u16(val: u16) -> UInt {
85        UInt::from(ApInt::from_u16(val))
86    }
87
88    /// Creates a new `UInt` from a given `u32` value with a bit-width of 32.
89    #[inline]
90    pub fn from_u32(val: u32) -> UInt {
91        UInt::from(ApInt::from_u32(val))
92    }
93
94    /// Creates a new `UInt` from a given `u64` value with a bit-width of 64.
95    #[inline]
96    pub fn from_u64(val: u64) -> UInt {
97        UInt::from(ApInt::from_u64(val))
98    }
99
100    /// Creates a new `UInt` from a given `u64` value with a bit-width of 64.
101    pub fn from_u128(val: u128) -> UInt {
102        UInt::from(ApInt::from_u128(val))
103    }
104
105    /// Creates a new `UInt` with the given bit width that represents zero.
106    pub fn zero(width: BitWidth) -> UInt {
107        UInt::from(ApInt::zero(width))
108    }
109
110    /// Creates a new `UInt` with the given bit width that represents one.
111    pub fn one(width: BitWidth) -> UInt {
112        UInt::from(ApInt::one(width))
113    }
114
115    /// Creates a new `UInt` with the given bit width that has all bits unset.
116    ///
117    /// **Note:** This is equal to calling `UInt::zero` with the given `width`.
118    pub fn all_unset(width: BitWidth) -> UInt {
119        UInt::zero(width)
120    }
121
122    /// Creates a new `UInt` with the given bit width that has all bits set.
123    ///
124    /// # Note
125    ///
126    /// - This is equal to minus one on any twos-complement machine.
127    pub fn all_set(width: BitWidth) -> UInt {
128        UInt::from(ApInt::all_set(width))
129    }
130
131    /// Returns the smallest `UInt` that can be represented by the given `BitWidth`.
132    pub fn min_value(width: BitWidth) -> UInt {
133        UInt::from(ApInt::unsigned_min_value(width))
134    }
135
136    /// Returns the largest `UInt` that can be represented by the given `BitWidth`.
137    pub fn max_value(width: BitWidth) -> UInt {
138        UInt::from(ApInt::unsigned_max_value(width))
139    }
140}
141
142impl<B> From<B> for UInt
143	where B: Into<Bit>
144{
145	#[inline]
146	fn from(bit: B) -> UInt {
147        UInt::from_bit(bit)
148	}
149}
150
151impl From<u8> for UInt {
152    fn from(val: u8) -> UInt {
153        UInt::from_u8(val)
154    }
155}
156
157impl From<u16> for UInt {
158    fn from(val: u16) -> UInt {
159        UInt::from_u16(val)
160    }
161}
162
163impl From<u32> for UInt {
164    fn from(val: u32) -> UInt {
165        UInt::from_u32(val)
166    }
167}
168
169impl From<u64> for UInt {
170    fn from(val: u64) -> UInt {
171        UInt::from_u64(val)
172    }
173}
174
175impl From<u128> for UInt {
176    fn from(val: u128) -> UInt {
177        UInt::from_u128(val)
178    }
179}
180
181macro_rules! impl_from_array_for_uint {
182	($n:expr) => {
183		impl From<[u64; $n]> for UInt {
184			fn from(val: [u64; $n]) -> UInt {
185				UInt::from(ApInt::from(val))
186			}
187		}
188	}
189}
190
191impl_from_array_for_uint!(2); // 128 bits
192impl_from_array_for_uint!(3); // 192 bits
193impl_from_array_for_uint!(4); // 256 bits
194impl_from_array_for_uint!(5); // 320 bits
195impl_from_array_for_uint!(6); // 384 bits
196impl_from_array_for_uint!(7); // 448 bits
197impl_from_array_for_uint!(8); // 512 bits
198impl_from_array_for_uint!(16); // 1024 bits
199impl_from_array_for_uint!(32); // 2048 bits
200
201/// # Utilities
202impl UInt {
203    /// Returns `true` if this `UInt` represents the value zero (`0`).
204    ///
205    /// # Note
206    ///
207    /// - Zero (`0`) is also called the additive neutral element.
208    /// - This operation is more efficient than comparing two instances
209    ///   of `UInt` for the same reason.
210    pub fn is_zero(&self) -> bool {
211        self.value.is_zero()
212    }
213
214    /// Returns `true` if this `UInt` represents the value one (`1`).
215    ///
216    /// # Note
217    ///
218    /// - One (`1`) is also called the multiplicative neutral element.
219    /// - This operation is more efficient than comparing two instances
220    ///   of `UInt` for the same reason.
221    pub fn is_one(&self) -> bool {
222        self.value.is_one()
223    }
224
225    /// Returns `true` if this `UInt` represents an even number.
226    pub fn is_even(&self) -> bool {
227        self.value.is_even()
228    }
229
230    /// Returns `true` if this `UInt` represents an odd number.
231    pub fn is_odd(&self) -> bool {
232        self.value.is_odd()
233    }
234}
235
236impl UInt {
237
238	/// Less-than (`lt`) comparison between `self` and `rhs`.
239	/// 
240	/// # Note
241	/// 
242	/// - Returns `Ok(true)` if `self < rhs`.
243	/// - Interprets both `UInt` instances as **unsigned** values.
244	/// 
245	/// # Errors
246	/// 
247	/// - If `self` and `rhs` have unmatching bit widths.
248	pub fn checked_lt(&self, rhs: &UInt) -> Result<bool> {
249		self.value.checked_ult(&rhs.value)
250	}
251
252	/// Less-equals (`le`) comparison between `self` and `rhs`.
253	/// 
254	/// # Note
255	/// 
256	/// - Returns `Ok(true)` if `self <= rhs`.
257	/// - Interprets both `UInt` instances as **unsigned** values.
258	/// 
259	/// # Errors
260	/// 
261	/// - If `self` and `rhs` have unmatching bit widths.
262	#[inline]
263	pub fn checked_le(&self, rhs: &UInt) -> Result<bool> {
264		self.value.checked_ule(&rhs.value)
265	}
266
267	/// Greater-than (`gt`) comparison between `self` and `rhs`.
268	/// 
269	/// # Note
270	/// 
271	/// - Returns `Ok(true)` if `self > rhs`.
272	/// - Interprets both `UInt` instances as **unsigned** values.
273	/// 
274	/// # Errors
275	/// 
276	/// - If `self` and `rhs` have unmatching bit widths.
277	#[inline]
278	pub fn checked_gt(&self, rhs: &UInt) -> Result<bool> {
279		self.value.checked_ugt(&rhs.value)
280	}
281
282	/// Greater-equals (`ge`) comparison between `self` and `rhs`.
283	/// 
284	/// # Note
285	/// 
286	/// - Returns `Ok(true)` if `self >= rhs`.
287	/// - Interprets both `UInt` instances as **unsigned** values.
288	/// 
289	/// # Errors
290	/// 
291	/// - If `self` and `rhs` have unmatching bit widths.
292	#[inline]
293	pub fn checked_ge(&self, rhs: &UInt) -> Result<bool> {
294		self.value.checked_uge(&rhs.value)
295	}
296}
297
298impl PartialOrd for UInt {
299    fn partial_cmp(&self, rhs: &UInt) -> Option<Ordering> {
300        if self.value.width() != rhs.value.width() {
301            return None;
302        }
303        if self.checked_lt(rhs).unwrap() {
304            return Some(Ordering::Less);
305        }
306        if self.value == rhs.value {
307            return Some(Ordering::Equal);
308        }
309        Some(Ordering::Greater)
310    }
311
312    fn lt(&self, rhs: &UInt) -> bool {
313        self.checked_lt(rhs).unwrap_or(false)
314    }
315
316    fn le(&self, rhs: &UInt) -> bool {
317        self.checked_le(rhs).unwrap_or(false)
318    }
319
320    fn gt(&self, rhs: &UInt) -> bool {
321        self.checked_gt(rhs).unwrap_or(false)
322    }
323
324    fn ge(&self, rhs: &UInt) -> bool {
325        self.checked_ge(rhs).unwrap_or(false)
326    }
327}
328
329/// # To Primitive (Resize)
330impl UInt {
331    /// Resizes this `UInt` to a `bool` primitive type.
332    ///
333    /// Bits in this `UInt` that are not within the bounds
334    /// of the `bool` are being ignored.
335    ///
336    /// # Note
337    ///
338    /// - Basically this returns `true` if the least significant
339    ///   bit of this `UInt` is `1` and `false` otherwise.
340    pub fn resize_to_bool(&self) -> bool {
341        self.value.resize_to_bool()
342    }
343
344    /// Resizes this `UInt` to a `u8` primitive type.
345    ///
346    /// # Note
347    ///
348    /// - All bits but the least significant `8` bits are
349    ///   being ignored by this operation to construct the
350    ///   result.
351    pub fn resize_to_u8(&self) -> u8 {
352        self.value.resize_to_u8()
353    }
354
355    /// Resizes this `UInt` to a `u16` primitive type.
356    ///
357    /// # Note
358    ///
359    /// - All bits but the least significant `16` bits are
360    ///   being ignored by this operation to construct the
361    ///   result.
362    pub fn resize_to_u16(&self) -> u16 {
363        self.value.resize_to_u16()
364    }
365
366    /// Resizes this `UInt` to a `u32` primitive type.
367    ///
368    /// # Note
369    ///
370    /// - All bits but the least significant `32` bits are
371    ///   being ignored by this operation to construct the
372    ///   result.
373    pub fn resize_to_u32(&self) -> u32 {
374        self.value.resize_to_u32()
375    }
376
377    /// Resizes this `UInt` to a `u64` primitive type.
378    ///
379    /// # Note
380    ///
381    /// - All bits but the least significant `64` bits are
382    ///   being ignored by this operation to construct the
383    ///   result.
384    pub fn resize_to_u64(&self) -> u64 {
385        self.value.resize_to_u64()
386    }
387
388    /// Resizes this `UInt` to a `u128` primitive type.
389    ///
390    /// # Note
391    ///
392    /// - All bits but the least significant `128` bits are
393    ///   being ignored by this operation to construct the
394    ///   result.
395    pub fn resize_to_u128(&self) -> u128 {
396        self.value.resize_to_u128()
397    }
398}
399
400/// # To Primitive (Try-Cast)
401impl UInt {
402    /// Tries to represent the value of this `UInt` as a `bool`.
403    ///
404    /// # Note
405    ///
406    /// This returns `true` if the value represented by this `UInt`
407    /// is `1`, returns `false` if the value represented by this
408    /// `UInt` is `0` and returns an error otherwise.
409    ///
410    /// # Errors
411    ///
412    /// - If the value represented by this `UInt` can not be
413    ///   represented by a `bool`.
414    pub fn try_to_bool(&self) -> Result<bool> {
415        self.value.try_to_bool()
416    }
417
418    /// Tries to represent the value of this `UInt` as a `u8`.
419    ///
420    /// # Note
421    ///
422    /// - This conversion is possible as long as the value represented
423    ///   by this `UInt` does not exceed the maximum value of `u8`.
424    ///
425    /// # Errors
426    ///
427    /// - If the value represented by this `UInt` can not be
428    ///   represented by a `u8`.
429    pub fn try_to_u8(&self) -> Result<u8> {
430        self.value.try_to_u8()
431    }
432
433    /// Tries to represent the value of this `UInt` as a `u16`.
434    ///
435    /// # Note
436    ///
437    /// - This conversion is possible as long as the value represented
438    ///   by this `UInt` does not exceed the maximum value of `u16`.
439    ///
440    /// # Errors
441    ///
442    /// - If the value represented by this `UInt` can not be
443    ///   represented by a `u16`.
444    pub fn try_to_u16(&self) -> Result<u16> {
445        self.value.try_to_u16()
446    }
447
448    /// Tries to represent the value of this `UInt` as a `u32`.
449    ///
450    /// # Note
451    ///
452    /// - This conversion is possible as long as the value represented
453    ///   by this `UInt` does not exceed the maximum value of `u32`.
454    ///
455    /// # Errors
456    ///
457    /// - If the value represented by this `UInt` can not be
458    ///   represented by a `u32`.
459    pub fn try_to_u32(&self) -> Result<u32> {
460        self.value.try_to_u32()
461    }
462
463    /// Tries to represent the value of this `UInt` as a `u64`.
464    ///
465    /// # Note
466    ///
467    /// - This conversion is possible as long as the value represented
468    ///   by this `UInt` does not exceed the maximum value of `u64`.
469    ///
470    /// # Errors
471    ///
472    /// - If the value represented by this `UInt` can not be
473    ///   represented by a `u64`.
474    pub fn try_to_u64(&self) -> Result<u64> {
475        self.value.try_to_u64()
476    }
477
478    /// Tries to represent the value of this `UInt` as a `u128`.
479    ///
480    /// # Note
481    ///
482    /// - This conversion is possible as long as the value represented
483    ///   by this `UInt` does not exceed the maximum value of `u128`.
484    ///
485    /// # Complexity
486    ///
487    /// - 𝒪(n) where n is the number of digits of this `UInt`.
488    ///
489    /// # Errors
490    ///
491    /// - If the value represented by this `UInt` can not be
492    ///   represented by a `u128`.
493    pub fn try_to_u128(&self) -> Result<u128> {
494        self.value.try_to_u128()
495    }
496}
497
498/// # Shifts
499impl UInt {
500   	/// Shift this `UInt` left by the given `shift_amount` bits.
501	/// 
502	/// This operation is inplace and will **not** allocate memory.
503	/// 
504	/// # Errors
505	/// 
506	/// - If the given `shift_amount` is invalid for the bit width of this `UInt`.
507	pub fn checked_shl_assign<S>(&mut self, shift_amount: S) -> Result<()>
508		where S: Into<ShiftAmount>
509	{
510		self.value.checked_shl_assign(shift_amount)
511	}
512
513	/// Shift this `UInt` left by the given `shift_amount` bits and returns the result.
514	/// 
515	/// This operation is inplace and will **not** allocate memory.
516	/// 
517	/// # Errors
518	/// 
519	/// - If the given `shift_amount` is invalid for the bit width of this `UInt`.
520	pub fn into_checked_shl<S>(self, shift_amount: S) -> Result<UInt>
521		where S: Into<ShiftAmount>
522	{
523		self.value.into_checked_shl(shift_amount).map(UInt::from)
524	}
525
526	/// Right-shifts this `UInt` by the given `shift_amount` bits.
527	/// 
528	/// This operation is inplace and will **not** allocate memory.
529	/// 
530	/// # Errors
531	/// 
532	/// - If the given `shift_amount` is invalid for the bit width of this `UInt`.
533	pub fn checked_shr_assign<S>(&mut self, shift_amount: S) -> Result<()>
534		where S: Into<ShiftAmount>
535	{
536		self.value.checked_lshr_assign(shift_amount)
537	}
538
539	/// Right-shifts this `UInt` by the given `shift_amount` bits
540	/// and returns the result.
541	/// 
542	/// This operation is inplace and will **not** allocate memory.
543	/// 
544	/// # Errors
545	/// 
546	/// - If the given `shift_amount` is invalid for the bit width of this `UInt`.
547	pub fn into_checked_shr<S>(self, shift_amount: S) -> Result<UInt>
548		where S: Into<ShiftAmount>
549	{
550		self.value.into_checked_lshr(shift_amount).map(UInt::from)
551	}
552}
553
554use std::ops::{Shl, ShlAssign, Shr, ShrAssign};
555
556impl<S> Shl<S> for UInt
557    where S: Into<ShiftAmount>
558{
559    type Output = UInt;
560
561    fn shl(self, shift_amount: S) -> Self::Output {
562        self.into_checked_shl(shift_amount).unwrap()
563    }
564}
565
566impl<S> Shr<S> for UInt
567    where S: Into<ShiftAmount>
568{
569    type Output = UInt;
570
571    fn shr(self, shift_amount: S) -> Self::Output {
572        self.into_checked_shr(shift_amount).unwrap()
573    }
574}
575
576impl<S> ShlAssign<S> for UInt
577    where S: Into<ShiftAmount>
578{
579    fn shl_assign(&mut self, shift_amount: S) {
580        self.checked_shl_assign(shift_amount).unwrap()
581    }
582}
583
584impl<S> ShrAssign<S> for UInt
585    where S: Into<ShiftAmount>
586{
587    fn shr_assign(&mut self, shift_amount: S) {
588        self.checked_shr_assign(shift_amount).unwrap()
589    }
590}
591
592/// # Random Utilities using `rand` crate.
593#[cfg(feature = "rand_support")]
594impl UInt {
595	/// Creates a new `UInt` with the given `BitWidth` and random `Digit`s.
596	pub fn random_with_width(width: BitWidth) -> UInt {
597		UInt::from(ApInt::random_with_width(width))
598	}
599
600	/// Creates a new `UInt` with the given `BitWidth` and random `Digit`s
601    /// using the given random number generator.
602    /// 
603    /// **Note:** This is useful for cryptographic or testing purposes.
604    pub fn random_with_width_using<R>(width: BitWidth, rng: &mut R) -> UInt
605        where R: rand::Rng
606    {
607        UInt::from(ApInt::random_with_width_using(width, rng))
608    }
609
610    /// Randomizes the digits of this `UInt` inplace.
611    /// 
612    /// This won't change its `BitWidth`.
613    pub fn randomize(&mut self) {
614        self.value.randomize()
615    }
616
617    /// Randomizes the digits of this `UInt` inplace using the given
618    /// random number generator.
619    /// 
620    /// This won't change its `BitWidth`.
621    pub fn randomize_using<R>(&mut self, rng: &mut R)
622        where R: rand::Rng
623    {
624        self.value.randomize_using(rng)
625    }
626}
627
628impl UInt {
629	/// Assigns `rhs` to this `UInt`.
630	///
631	/// This mutates digits and may affect the bitwidth of `self`
632	/// which **might result in an expensive operations**.
633	///
634	/// After this operation `rhs` and `self` are equal to each other.
635	pub fn assign(&mut self, rhs: &UInt) {
636		self.value.assign(&rhs.value)
637	}
638
639	/// Strictly assigns `rhs` to this `UInt`.
640	/// 
641	/// After this operation `rhs` and `self` are equal to each other.
642	/// 
643	/// **Note:** Strict assigns protect against mutating the bit width
644	/// of `self` and thus return an error instead of executing a probably
645	/// expensive `assign` operation.
646	/// 
647	/// # Errors
648	/// 
649	/// - If `rhs` and `self` have unmatching bit widths.
650	pub fn strict_assign(&mut self, rhs: &UInt) -> Result<()> {
651		self.value.strict_assign(&rhs.value)
652	}
653}
654
655/// # Casting: Truncation & Extension
656impl UInt {
657	/// Tries to truncate this `UInt` inplace to the given `target_width`
658	/// and returns the result.
659	/// 
660	/// # Note
661	/// 
662	/// - This is useful for method chaining.
663	/// - For more details look into
664	///   [`truncate`](struct.UInt.html#method.truncate).
665	/// 
666	/// # Errors
667	/// 
668	/// - If the `target_width` is greater than the current width.
669	pub fn into_truncate<W>(self, target_width: W) -> Result<UInt>
670		where W: Into<BitWidth>
671	{
672		try_forward_bin_mut_impl(self, target_width, UInt::truncate)
673	}
674
675	/// Tries to truncate this `UInt` inplace to the given `target_width`.
676	/// 
677	/// # Note
678	/// 
679	/// - This is a no-op if `self.width()` and `target_width` are equal.
680	/// - This operation is inplace as long as `self.width()` and `target_width`
681	///   require the same amount of digits for their representation.
682	/// 
683	/// # Errors
684	/// 
685	/// - If the `target_width` is greater than the current width.
686	pub fn truncate<W>(&mut self, target_width: W) -> Result<()>
687		where W: Into<BitWidth>
688	{
689		self.value.truncate(target_width)
690	}
691
692	// ========================================================================
693
694	/// Tries to zero-extend this `UInt` inplace to the given `target_width`
695	/// and returns the result.
696	/// 
697	/// # Note
698	/// 
699	/// - This is useful for method chaining.
700	/// - For more details look into
701	///   [`extend`](struct.UInt.html#method.extend).
702	/// 
703	/// # Errors
704	/// 
705	/// - If the `target_width` is less than the current width.
706	pub fn into_extend<W>(self, target_width: W) -> Result<UInt>
707		where W: Into<BitWidth>
708	{
709		try_forward_bin_mut_impl(self, target_width, UInt::extend)
710	}
711
712	/// Tries to extend this `UInt` inplace to the given `target_width`.
713	/// 
714	/// # Note
715	/// 
716	/// - This is a no-op if `self.width()` and `target_width` are equal.
717	/// - This operation is inplace as long as `self.width()` and `target_width`
718	///   require the same amount of digits for their representation.
719	/// 
720	/// # Errors
721	/// 
722	/// - If the `target_width` is less than the current width.
723	pub fn extend<W>(&mut self, target_width: W) -> Result<()>
724		where W: Into<BitWidth>
725	{
726		self.value.zero_extend(target_width)
727	}
728
729	// ========================================================================
730
731	/// Resizes this `UInt` to the given `target_width`
732	/// and returns the result.
733	/// 
734	/// # Note
735	/// 
736	/// - This is useful for method chaining.
737	/// - For more details look into
738	///   [`resize`](struct.UInt.html#method.resize).
739	pub fn into_resize<W>(self, target_width: W) -> UInt
740		where W: Into<BitWidth>
741	{
742		forward_bin_mut_impl(self, target_width, UInt::resize)
743	}
744
745	/// Resizes the given `UInt` inplace.
746	/// 
747	/// # Note
748	/// 
749	/// This operation will forward to
750	/// 
751	/// - [`truncate`](struct.UInt.html#method.truncate)
752	///   if `target_width` is less than or equal to the width of
753	///   the given `UInt`
754	/// - [`extend`](struct.UInt.html#method.extend)
755	///   otherwise
756	pub fn resize<W>(&mut self, target_width: W)
757		where W: Into<BitWidth>
758	{
759		self.value.zero_resize(target_width)
760	}
761}
762
763/// # Bitwise Operations
764impl UInt {
765	/// Flips all bits of `self` and returns the result.
766	pub fn into_bitnot(self) -> Self {
767		forward_mut_impl(self, UInt::bitnot)
768	}
769
770	/// Flip all bits of this `UInt` inplace.
771	pub fn bitnot(&mut self) {
772		self.value.bitnot()
773	}
774
775	/// Tries to bit-and assign this `UInt` inplace to `rhs`
776	/// and returns the result.
777	/// 
778	/// **Note:** This forwards to
779	/// [`checked_bitand`](struct.UInt.html#method.checked_bitand).
780	/// 
781	/// # Errors
782	/// 
783	/// If `self` and `rhs` have unmatching bit widths.
784	pub fn into_checked_bitand(self, rhs: &UInt) -> Result<UInt> {
785		try_forward_bin_mut_impl(self, rhs, UInt::checked_bitand_assign)
786	}
787
788	/// Bit-and assigns all bits of this `UInt` with the bits of `rhs`.
789	/// 
790	/// **Note:** This operation is inplace of `self` and won't allocate memory.
791	/// 
792	/// # Errors
793	/// 
794	/// If `self` and `rhs` have unmatching bit widths.
795	pub fn checked_bitand_assign(&mut self, rhs: &UInt) -> Result<()> {
796		self.value.checked_bitand_assign(&rhs.value)
797	}
798
799	/// Tries to bit-and assign this `UInt` inplace to `rhs`
800	/// and returns the result.
801	/// 
802	/// **Note:** This forwards to
803	/// [`checked_bitor`](struct.UInt.html#method.checked_bitor).
804	/// 
805	/// # Errors
806	/// 
807	/// If `self` and `rhs` have unmatching bit widths.
808	pub fn into_checked_bitor(self, rhs: &UInt) -> Result<UInt> {
809		try_forward_bin_mut_impl(self, rhs, UInt::checked_bitor_assign)
810	}
811
812	/// Bit-or assigns all bits of this `UInt` with the bits of `rhs`.
813	/// 
814	/// **Note:** This operation is inplace of `self` and won't allocate memory.
815	/// 
816	/// # Errors
817	/// 
818	/// If `self` and `rhs` have unmatching bit widths.
819	pub fn checked_bitor_assign(&mut self, rhs: &UInt) -> Result<()> {
820		self.value.checked_bitor_assign(&rhs.value)
821	}
822
823	/// Tries to bit-xor assign this `UInt` inplace to `rhs`
824	/// and returns the result.
825	/// 
826	/// **Note:** This forwards to
827	/// [`checked_bitxor`](struct.UInt.html#method.checked_bitxor).
828	/// 
829	/// # Errors
830	/// 
831	/// If `self` and `rhs` have unmatching bit widths.
832	pub fn into_checked_bitxor(self, rhs: &UInt) -> Result<UInt> {
833		try_forward_bin_mut_impl(self, rhs, UInt::checked_bitxor_assign)
834	}
835
836	/// Bit-xor assigns all bits of this `UInt` with the bits of `rhs`.
837	/// 
838	/// **Note:** This operation is inplace of `self` and won't allocate memory.
839	/// 
840	/// # Errors
841	/// 
842	/// If `self` and `rhs` have unmatching bit widths.
843	pub fn checked_bitxor_assign(&mut self, rhs: &UInt) -> Result<()> {
844		self.value.checked_bitxor_assign(&rhs.value)
845	}
846}
847
848/// # Bitwise Access
849impl UInt {
850	/// Returns the bit at the given bit position `pos`.
851	/// 
852	/// This returns
853	/// 
854	/// - `Bit::Set` if the bit at `pos` is `1`
855	/// - `Bit::Unset` otherwise
856	/// 
857	/// # Errors
858	/// 
859	/// - If `pos` is not a valid bit position for the width of this `UInt`.
860	pub fn get_bit_at<P>(&self, pos: P) -> Result<Bit>
861		where P: Into<BitPos>
862	{
863		self.value.get_bit_at(pos)
864	}
865
866	/// Sets the bit at the given bit position `pos` to one (`1`).
867	/// 
868	/// # Errors
869	/// 
870	/// - If `pos` is not a valid bit position for the width of this `UInt`.
871	pub fn set_bit_at<P>(&mut self, pos: P) -> Result<()>
872		where P: Into<BitPos>
873	{
874		self.value.set_bit_at(pos)
875	}
876
877	/// Sets the bit at the given bit position `pos` to zero (`0`).
878	/// 
879	/// # Errors
880	/// 
881	/// - If `pos` is not a valid bit position for the width of this `UInt`.
882	pub fn unset_bit_at<P>(&mut self, pos: P) -> Result<()>
883		where P: Into<BitPos>
884	{
885		self.value.unset_bit_at(pos)
886	}
887
888	/// Flips the bit at the given bit position `pos`.
889	/// 
890	/// # Note
891	/// 
892	/// - If the bit at the given position was `0` it will be `1`
893	///   after this operation and vice versa.
894	/// 
895	/// # Errors
896	/// 
897	/// - If `pos` is not a valid bit position for the width of this `UInt`.
898	pub fn flip_bit_at<P>(&mut self, pos: P) -> Result<()>
899		where P: Into<BitPos>
900	{
901		self.value.flip_bit_at(pos)
902	}
903
904	/// Sets all bits of this `UInt` to one (`1`).
905	pub fn set_all(&mut self) {
906		self.value.set_all()
907	}
908
909	/// Returns `true` if all bits in this `UInt` are set.
910	pub fn is_all_set(&self) -> bool {
911		self.value.is_all_set()
912	}
913
914	/// Sets all bits of this `UInt` to zero (`0`).
915	pub fn unset_all(&mut self) {
916		self.value.unset_all()
917	}
918
919	/// Returns `true` if all bits in this `UInt` are unset.
920	pub fn is_all_unset(&self) -> bool {
921		self.value.is_all_unset()
922	}
923
924	/// Flips all bits of this `UInt`.
925	pub fn flip_all(&mut self) {
926		self.value.flip_all()
927	}
928}
929
930/// # Bitwise utility methods.
931impl UInt {
932	/// Returns the number of ones in the binary representation of this `UInt`.
933	pub fn count_ones(&self) -> usize {
934		self.value.count_ones()
935	}
936
937	/// Returns the number of zeros in the binary representation of this `UInt`.
938	pub fn count_zeros(&self) -> usize {
939		self.value.count_zeros()
940	}
941
942	/// Returns the number of leading zeros in the binary representation of this `UInt`.
943	pub fn leading_zeros(&self) -> usize {
944		self.value.leading_zeros()
945	}
946
947	/// Returns the number of trailing zeros in the binary representation of this `UInt`.
948	pub fn trailing_zeros(&self) -> usize {
949		self.value.trailing_zeros()
950	}
951}
952
953//  ===========================================================================
954//  `Not` (bitwise) impls
955//  ===========================================================================
956
957impl Not for UInt {
958	type Output = UInt;
959
960	fn not(self) -> Self::Output {
961		forward_mut_impl(self, UInt::bitnot)
962	}
963}
964
965//  ===========================================================================
966//  `BitAnd` impls
967//  ===========================================================================
968
969impl<'a> BitAnd<&'a UInt> for UInt {
970    type Output = UInt;
971
972    fn bitand(self, rhs: &'a UInt) -> Self::Output {
973        self.into_checked_bitand(rhs).unwrap()
974    }
975}
976
977impl<'a, 'b> BitAnd<&'a UInt> for &'b UInt {
978    type Output = UInt;
979
980    fn bitand(self, rhs: &'a UInt) -> Self::Output {
981        self.clone().into_checked_bitand(rhs).unwrap()
982    }
983}
984
985impl<'a, 'b> BitAnd<&'a UInt> for &'b mut UInt {
986    type Output = UInt;
987
988    fn bitand(self, rhs: &'a UInt) -> Self::Output {
989        self.clone().into_checked_bitand(rhs).unwrap()
990    }
991}
992
993//  ===========================================================================
994//  `BitOr` impls
995//  ===========================================================================
996
997impl<'a> BitOr<&'a UInt> for UInt {
998    type Output = UInt;
999
1000    fn bitor(self, rhs: &'a UInt) -> Self::Output {
1001        self.into_checked_bitor(rhs).unwrap()
1002    }
1003}
1004
1005impl<'a, 'b> BitOr<&'a UInt> for &'b UInt {
1006    type Output = UInt;
1007
1008    fn bitor(self, rhs: &'a UInt) -> Self::Output {
1009        self.clone().into_checked_bitor(rhs).unwrap()
1010    }
1011}
1012
1013impl<'a, 'b> BitOr<&'a UInt> for &'b mut UInt {
1014    type Output = UInt;
1015
1016    fn bitor(self, rhs: &'a UInt) -> Self::Output {
1017        self.clone().into_checked_bitor(rhs).unwrap()
1018    }
1019}
1020
1021//  ===========================================================================
1022//  `BitXor` impls
1023//  ===========================================================================
1024
1025impl<'a> BitXor<&'a UInt> for UInt {
1026    type Output = UInt;
1027
1028    fn bitxor(self, rhs: &'a UInt) -> Self::Output {
1029        self.into_checked_bitxor(rhs).unwrap()
1030    }
1031}
1032
1033impl<'a, 'b> BitXor<&'a UInt> for &'b UInt {
1034    type Output = UInt;
1035
1036    fn bitxor(self, rhs: &'a UInt) -> Self::Output {
1037        self.clone().into_checked_bitxor(rhs).unwrap()
1038    }
1039}
1040
1041impl<'a, 'b> BitXor<&'a UInt> for &'b mut UInt {
1042    type Output = UInt;
1043
1044    fn bitxor(self, rhs: &'a UInt) -> Self::Output {
1045        self.clone().into_checked_bitxor(rhs).unwrap()
1046    }
1047}
1048
1049//  ===========================================================================
1050//  `BitAndAssign`, `BitOrAssign` and `BitXorAssign` impls
1051//  ===========================================================================
1052
1053impl<'a> BitAndAssign<&'a UInt> for UInt {
1054    fn bitand_assign(&mut self, rhs: &'a UInt) {
1055        self.checked_bitand_assign(rhs).unwrap();
1056    }
1057}
1058
1059impl<'a> BitOrAssign<&'a UInt> for UInt {
1060    fn bitor_assign(&mut self, rhs: &'a UInt) {
1061        self.checked_bitor_assign(rhs).unwrap();
1062    }
1063}
1064
1065impl<'a> BitXorAssign<&'a UInt> for UInt {
1066    fn bitxor_assign(&mut self, rhs: &'a UInt) {
1067        self.checked_bitxor_assign(rhs).unwrap();
1068    }
1069}
1070
1071/// # Arithmetic Operations
1072impl UInt {
1073	/// Adds `rhs` to `self` and returns the result.
1074	/// 
1075	/// **Note:** This will **not** allocate memory.
1076	/// 
1077	/// # Errors
1078	/// 
1079	/// - If `self` and `rhs` have unmatching bit widths.
1080	pub fn into_checked_add(self, rhs: &UInt) -> Result<UInt> {
1081		try_forward_bin_mut_impl(self, rhs, UInt::checked_add_assign)
1082	}
1083
1084	/// Add-assigns `rhs` to `self` inplace.
1085	/// 
1086	/// **Note:** This will **not** allocate memory.
1087	/// 
1088	/// # Errors
1089	/// 
1090	/// - If `self` and `rhs` have unmatching bit widths.
1091	pub fn checked_add_assign(&mut self, rhs: &UInt) -> Result<()> {
1092		self.value.checked_add_assign(&rhs.value)
1093	}
1094
1095	/// Subtracts `rhs` from `self` and returns the result.
1096	/// 
1097	/// # Note
1098	/// 
1099	/// In the low-level bit-wise representation there is no difference between signed
1100	/// and unsigned subtraction of fixed bit-width integers. (Cite: LLVM)
1101	/// 
1102	/// # Errors
1103	/// 
1104	/// - If `self` and `rhs` have unmatching bit widths.
1105	pub fn into_checked_sub(self, rhs: &UInt) -> Result<UInt> {
1106		try_forward_bin_mut_impl(self, rhs, UInt::checked_sub_assign)
1107	}
1108
1109	/// Subtract-assigns `rhs` from `self` inplace.
1110	/// 
1111	/// # Note
1112	/// 
1113	/// In the low-level bit-wise representation there is no difference between signed
1114	/// and unsigned subtraction of fixed bit-width integers. (Cite: LLVM)
1115	/// 
1116	/// # Errors
1117	/// 
1118	/// - If `self` and `rhs` have unmatching bit widths.
1119	pub fn checked_sub_assign(&mut self, rhs: &UInt) -> Result<()> {
1120		self.value.checked_sub_assign(&rhs.value)
1121	}
1122
1123	/// Subtracts `rhs` from `self` and returns the result.
1124	/// 
1125	/// # Note
1126	/// 
1127	/// In the low-level bit-wise representation there is no difference between signed
1128	/// and unsigned multiplication of fixed bit-width integers. (Cite: LLVM)
1129	/// 
1130	/// # Errors
1131	/// 
1132	/// - If `self` and `rhs` have unmatching bit widths.
1133	pub fn into_checked_mul(self, rhs: &UInt) -> Result<UInt> {
1134		try_forward_bin_mut_impl(self, rhs, UInt::checked_mul_assign)
1135	}
1136
1137	/// Multiply-assigns `rhs` to `self` inplace.
1138	/// 
1139	/// # Note
1140	/// 
1141	/// In the low-level bit-wise representation there is no difference between signed
1142	/// and unsigned multiplication of fixed bit-width integers. (Cite: LLVM)
1143	/// 
1144	/// # Errors
1145	/// 
1146	/// - If `self` and `rhs` have unmatching bit widths.
1147	pub fn checked_mul_assign(&mut self, rhs: &UInt) -> Result<()> {
1148		self.value.checked_mul_assign(&rhs.value)
1149	}
1150
1151	/// Divides `self` by `rhs` and returns the result.
1152	/// 
1153	/// # Note
1154	/// 
1155	/// - This operation will **not** allocate memory and computes inplace of `self`.
1156	/// - In the low-level machine abstraction signed division and unsigned division
1157	///   are two different operations.
1158	/// 
1159	/// # Errors
1160	/// 
1161	/// - If `self` and `rhs` have unmatching bit widths.
1162	pub fn into_checked_div(self, rhs: &UInt) -> Result<UInt> {
1163		try_forward_bin_mut_impl(self, rhs, UInt::checked_div_assign)
1164	}
1165
1166	/// Assignes `self` to the division of `self` by `rhs`.
1167	/// 
1168	/// # Note
1169	/// 
1170	/// - This operation will **not** allocate memory and computes inplace of `self`.
1171	/// - In the low-level machine abstraction signed division and unsigned division
1172	///   are two different operations.
1173	/// 
1174	/// # Errors
1175	/// 
1176	/// - If `self` and `rhs` have unmatching bit widths.
1177	pub fn checked_div_assign(&mut self, rhs: &UInt) -> Result<()> {
1178		self.value.checked_udiv_assign(&rhs.value)
1179	}
1180
1181	/// Calculates the **unsigned** remainder of `self` by `rhs` and returns the result.
1182	/// 
1183	/// # Note
1184	/// 
1185	/// - This operation will **not** allocate memory and computes inplace of `self`.
1186	/// - In the low-level machine abstraction signed division and unsigned division
1187	///   are two different operations.
1188	/// 
1189	/// # Errors
1190	/// 
1191	/// - If `self` and `rhs` have unmatching bit widths.
1192	pub fn into_checked_rem(self, rhs: &UInt) -> Result<UInt> {
1193		try_forward_bin_mut_impl(self, rhs, UInt::checked_rem_assign)
1194	}
1195
1196	/// Assignes `self` to the **unsigned** remainder of `self` by `rhs`.
1197	/// 
1198	/// # Note
1199	/// 
1200	/// - This operation will **not** allocate memory and computes inplace of `self`.
1201	/// - In the low-level machine abstraction signed division and unsigned division
1202	///   are two different operations.
1203	/// 
1204	/// # Errors
1205	/// 
1206	/// - If `self` and `rhs` have unmatching bit widths.
1207	pub fn checked_rem_assign(&mut self, rhs: &UInt) -> Result<()> {
1208		self.value.checked_urem_assign(&rhs.value)
1209	}
1210}
1211
1212// ============================================================================
1213//  Add and Add-Assign: `std::ops::Add` and `std::ops::AddAssign`
1214// ============================================================================
1215
1216impl<'a> Add<&'a UInt> for UInt {
1217	type Output = UInt;
1218
1219	fn add(self, rhs: &'a UInt) -> Self::Output {
1220		self.into_checked_add(rhs).unwrap()
1221	}
1222}
1223
1224impl<'a, 'b> Add<&'a UInt> for &'b UInt {
1225	type Output = UInt;
1226
1227	fn add(self, rhs: &'a UInt) -> Self::Output {
1228		self.clone().into_checked_add(rhs).unwrap()
1229	}
1230}
1231
1232impl<'a> AddAssign<&'a UInt> for UInt {
1233	fn add_assign(&mut self, rhs: &'a UInt) {
1234		self.checked_add_assign(rhs).unwrap()
1235	}
1236}
1237
1238// ============================================================================
1239//  Sub and Sub-Assign: `std::ops::Sub` and `std::ops::SubAssign`
1240// ============================================================================
1241
1242impl<'a> Sub<&'a UInt> for UInt {
1243	type Output = UInt;
1244
1245	fn sub(self, rhs: &'a UInt) -> Self::Output {
1246		self.into_checked_sub(rhs).unwrap()
1247	}
1248}
1249
1250impl<'a, 'b> Sub<&'a UInt> for &'b UInt {
1251	type Output = UInt;
1252
1253	fn sub(self, rhs: &'a UInt) -> Self::Output {
1254		self.clone().into_checked_sub(rhs).unwrap()
1255	}
1256}
1257
1258impl<'a> SubAssign<&'a UInt> for UInt {
1259	fn sub_assign(&mut self, rhs: &'a UInt) {
1260		self.checked_sub_assign(rhs).unwrap()
1261	}
1262}
1263
1264// ============================================================================
1265//  Mul and Mul-Assign: `std::ops::Mul` and `std::ops::MulAssign`
1266// ============================================================================
1267
1268impl<'a> Mul<&'a UInt> for UInt {
1269	type Output = UInt;
1270
1271	fn mul(self, rhs: &'a UInt) -> Self::Output {
1272		self.into_checked_mul(rhs).unwrap()
1273	}
1274}
1275
1276impl<'a, 'b> Mul<&'a UInt> for &'b UInt {
1277	type Output = UInt;
1278
1279	fn mul(self, rhs: &'a UInt) -> Self::Output {
1280		self.clone().into_checked_mul(rhs).unwrap()
1281	}
1282}
1283
1284impl<'a> MulAssign<&'a UInt> for UInt {
1285	fn mul_assign(&mut self, rhs: &'a UInt) {
1286		self.checked_mul_assign(rhs).unwrap();
1287	}
1288}
1289
1290// ============================================================================
1291//  Div and Div-Assign: `std::ops::Div` and `std::ops::DivAssign`
1292// ============================================================================
1293
1294impl<'a> Div<&'a UInt> for UInt {
1295	type Output = UInt;
1296
1297	fn div(self, rhs: &'a UInt) -> Self::Output {
1298		self.into_checked_div(rhs).unwrap()
1299	}
1300}
1301
1302impl<'a, 'b> Div<&'a UInt> for &'b UInt {
1303	type Output = UInt;
1304
1305	fn div(self, rhs: &'a UInt) -> Self::Output {
1306		self.clone().into_checked_div(rhs).unwrap()
1307	}
1308}
1309
1310impl<'a> DivAssign<&'a UInt> for UInt {
1311	fn div_assign(&mut self, rhs: &'a UInt) {
1312		self.checked_div_assign(rhs).unwrap();
1313	}
1314}
1315
1316// ============================================================================
1317//  Rem and Rem-Assign: `std::ops::Rem` and `std::ops::RemAssign`
1318// ============================================================================
1319
1320impl<'a> Rem<&'a UInt> for UInt {
1321	type Output = UInt;
1322
1323	fn rem(self, rhs: &'a UInt) -> Self::Output {
1324		self.into_checked_rem(rhs).unwrap()
1325	}
1326}
1327
1328impl<'a, 'b> Rem<&'a UInt> for &'b UInt {
1329	type Output = UInt;
1330
1331	fn rem(self, rhs: &'a UInt) -> Self::Output {
1332		self.clone().into_checked_rem(rhs).unwrap()
1333	}
1334}
1335
1336impl<'a> RemAssign<&'a UInt> for UInt {
1337	fn rem_assign(&mut self, rhs: &'a UInt) {
1338		self.checked_rem_assign(rhs).unwrap();
1339	}
1340}
1341
1342// ============================================================================
1343//  Binary, Oct, LowerHex and UpperHex implementations
1344// ============================================================================
1345
1346use std::fmt;
1347
1348impl fmt::Binary for UInt {
1349	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1350		self.value.fmt(f)
1351	}
1352}
1353
1354impl fmt::Octal for UInt {
1355	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1356		self.value.fmt(f)
1357	}
1358}
1359
1360impl fmt::LowerHex for UInt {
1361	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1362		self.value.fmt(f)
1363	}
1364}
1365
1366impl fmt::UpperHex for UInt {
1367	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1368		self.value.fmt(f)
1369	}
1370}