twelve_bit 0.1.1

A Rust library for representing 12-bit unsigned values. This is primarily useful for implementing Chip-8 assemblers and interpreters safely. The type implements the bulk of the standard Rust literal semantics and operators, and much of the documentation is adapted from the u16 intrinsic type.
Documentation
//
// Copyright 2016 The u12 Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>.
// All files in the project carrying such notice may not be copied, modified, or 
// distributed except according to those terms.
//

use std::cmp;
use std::marker;
use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Not, Rem, Shl, Shr, Sub};

#[derive(Debug,Clone,Copy,PartialEq,Eq,PartialOrd,Ord)]
pub struct U12(u16);

// MARK: - Literal Macro

/// Creates a 12-bit value via unchecked-into conversion.
/// This is meant to simplify describing U12 literal values, as the
/// `$x` parameter is first bound to a 16-bit value. This allows the compiler to
/// elide the type of the literal, and does compile-time validation that no
/// literal greater than `0xFFFF` is specified; this will panic for values
/// in the range `0x1000...0xFFFF`.
///
/// # Examples
/// Basic usage:
///
/// ```rust
/// # #[macro_use] extern crate twelve_bit;
/// use twelve_bit::u12::*;
/// # fn main() {
/// assert_eq!(u12![0], U12::min_value());
/// assert_eq!(u12![4095], U12::max_value());
/// # }
/// ```
#[macro_export]
macro_rules! u12 {
  ( $x:expr ) => {{
    let x: u16 = $x;
    let value: U12 = x.unchecked_into();
    value
  }}
}

// MARK: - Public Constants

/// The largest value representable by the `U12` type.
pub const MAX: U12 = U12(0xFFF);

/// The smallest value representable by the `U12` type.
pub const MIN: U12 = U12(0x000);

// MARK: - Implementation

impl U12 {

  /// Returns the smallest value that can be represented by this integer type.
  pub fn min_value() -> Self {
    MIN
  }

  /// Returns the largest value that can be represented by this integer type.
  pub fn max_value() -> Self {
    MAX
  }

  /// Returns the number of ones in the binary representation of `self`.
  /// # Examples
  /// Basic usage:
  ///
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![0b000000000000].count_ones(), 0);
  /// assert_eq!(u12![0b001011111100].count_ones(), 7);
  /// assert_eq!(u12![0b111111111111].count_ones(), 12)
  /// # }
  /// ```
  pub fn count_ones(self) -> u32 {
    self.0.count_ones()
  }

  /// Returns the number of zeros in the binary representation of `self`.
  /// # Examples
  /// Basic usage:
  ///
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![0b000000000000].count_zeros(), 12);
  /// assert_eq!(u12![0b001011111000].count_zeros(), 6);
  /// assert_eq!(u12![0b111111111111].count_zeros(), 0)
  /// # }
  /// ```
  pub fn count_zeros(self) -> u32 {
    self.0.count_zeros() - 4
  }

  /// Returns the number of leading zeros in the binary representation of `self`.
  /// # Examples
  /// Basic usage:
  ///
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![0b111111111111].leading_zeros(), 0);
  /// assert_eq!(u12![0b001011111000].leading_zeros(), 2);
  /// assert_eq!(u12![0b000011111000].leading_zeros(), 4);
  /// assert_eq!(u12![0b000000000000].leading_zeros(), 12);
  /// # }
  /// ```
  pub fn leading_zeros(self) -> u32 {
    self.0.leading_zeros() - 4
  }

  /// Returns the number of trailing zeros in the binary representation of `self`.
  /// # Examples
  /// Basic usage:
  ///
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![0b111111111111].trailing_zeros(), 0);
  /// assert_eq!(u12![0b001011111000].trailing_zeros(), 3);
  /// assert_eq!(u12![0b001011110000].trailing_zeros(), 4);
  /// assert_eq!(u12![0b000000000000].trailing_zeros(), 12);
  /// # }
  /// ```
  pub fn trailing_zeros(self) -> u32 {
    cmp::min(self.0.trailing_zeros(), 12)
  }

  /// Checked integer addition. 
  /// Computes `self + other`, returning `None` if overflow occurred.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![1].checked_add(u12![1]), Some(u12![2]));
  /// assert_eq!(U12::max_value().checked_add(u12![1]), None);
  /// # }
  /// ```
  pub fn checked_add(self, other: Self) -> Option<Self> {
    match self.0 + other.0 {
      result @ 0...4095 => Some(U12(result)),
      _ => None
    }
  }

  /// Saturating integer addition. 
  /// Computes `self + other`, saturating at the numeric bounds instead of overflowing.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```
  /// use twelve_bit::u12::U12;
  ///
  /// assert_eq!(U12::from(1u8).saturating_add(1u8.into()), U12::from(2u8));
  /// assert_eq!(U12::max_value().saturating_add(1u8.into()), U12::max_value());
  /// ```
  pub fn saturating_add(self, other: Self) -> Self {
    match self.0 + other.0 {
      result @ 0...4095 => U12(result),
      _ => Self::max_value()
    }
  }

  /// Wrapping (modular) addition. 
  /// Computes `self + other`, wrapping around at the boundary of the type.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```
  /// use twelve_bit::u12::U12;
  ///
  /// assert_eq!(U12::from(1u8).wrapping_add(1u8.into()), U12::from(2u8));
  /// assert_eq!(U12::max_value().wrapping_add(3u8.into()), U12::from(2u8));
  /// ```
  pub fn wrapping_add(self, other: Self) -> Self {
    U12((self.0 + other.0) & 0xFFF)
  }

  /// Overflowing addition.
  /// Computes `self + other`, returning a tuple of the addition along with a 
  /// boolean indicating whether an arithmetic overflow would occur. 
  /// If an overflow would have occurred then the wrapped value is returned.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```
  /// use twelve_bit::u12::U12;
  ///
  /// assert_eq!(U12::from(1u8).overflowing_add(1u8.into()), (U12::from(2u8), false));
  /// assert_eq!(U12::max_value().overflowing_add(3u8.into()), (U12::from(2u8), true));
  /// ```
  pub fn overflowing_add(self, other: Self) -> (Self, bool) {
    match self.checked_add(other) {
      Some(result) => (result, false),
              None => (self.wrapping_add(other), true)
    }
  }

  /// Checked integer subtraction. 
  /// Computes `self - other`, returning `None` if underflow occurred.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```
  /// use twelve_bit::u12::U12;
  ///
  /// assert_eq!(U12::from(1u8).checked_sub(1u8.into()), Some(U12::from(0u8)));
  /// assert_eq!(U12::min_value().checked_sub(1u8.into()), None);
  /// ```
  pub fn checked_sub(self, other: Self) -> Option<Self> {
    self.0
      .checked_sub(other.0)
      .map(|value| U12(value))
  }

  /// Saturating integer subtraction. 
  /// Computes `self - other`, saturating at the numeric bounds instead of overflowing.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```
  /// use twelve_bit::u12::U12;
  ///
  /// assert_eq!(U12::from(1u8).saturating_sub(1u8.into()), U12::min_value());
  /// assert_eq!(U12::min_value().saturating_sub(5u8.into()), U12::min_value());
  /// ```
  pub fn saturating_sub(self, other: Self) -> Self {
    U12(self.0.saturating_sub(other.0))
  }
  
  /// Wrapping (modular) subtraction. 
  /// Computes `self - other`, wrapping around at the boundary of the type.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```
  /// use twelve_bit::u12::*;
  ///
  /// assert_eq!(U12::from(1u8).wrapping_sub(1u8.into()), U12::min_value());
  /// assert_eq!(U12::min_value().wrapping_sub(5u8.into()), (0xFFB as u16).unchecked_into());
  /// ```
  pub fn wrapping_sub(self, other: Self) -> Self {
    U12(self.0.wrapping_sub(other.0) & 0xFFF)
  }

  /// Overflowing subtraction.
  /// Computes `self - other`, returning a tuple of the subtraction result along with a 
  /// boolean indicating whether an arithmetic underflow would occur.
  /// If an underflow would have occurred then the wrapped value is returned.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```
  /// use twelve_bit::u12::*;
  ///
  /// assert_eq!(U12::from(1u8).overflowing_sub(1u8.into()), (U12::from(0u8), false));
  /// assert_eq!(U12::min_value().overflowing_sub(1u8.into()), (0xFFFu16.unchecked_into(), true));
  /// ```
  pub fn overflowing_sub(self, other: Self) -> (Self, bool) {
    match self.checked_sub(other) {
      Some(result) => (result, false),
              None => (self.wrapping_sub(other), true)
    }
  }

  /// Checked integer multiplication. 
  /// Computes `self * other`, returning `None` if overflow occurred.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```
  /// use twelve_bit::u12::*;
  ///
  /// assert_eq!(U12::from(2u8).checked_mul(255u8.into()), Some((510 as u16).unchecked_into()));
  /// assert_eq!(U12::from(2u8).checked_mul((2048u16).unchecked_into()), None);
  /// assert_eq!(U12::from(2u8).checked_mul((4095u16).unchecked_into()), None);
  /// ```
  pub fn checked_mul(self, other: Self) -> Option<Self> {
    match self.0.checked_mul(other.0) {
      Some(small) if small < 4096 => Some(U12(small)),
      _ => None
    }
  }

  /// Saturating integer multiplication. 
  /// Computes `self * other`, saturating at the numeric bounds instead of overflowing.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```
  /// use twelve_bit::u12::*;
  ///
  /// assert_eq!(U12::from(2u8).saturating_mul(1u8.into()), 2u8.into());
  /// assert_eq!(U12::from(2u8).saturating_mul((2048u16).unchecked_into()), U12::max_value());
  /// assert_eq!(U12::from(2u8).saturating_mul((4095u16).unchecked_into()), U12::max_value());
  /// ```
  pub fn saturating_mul(self, other: Self) -> Self {
    match self.0.checked_mul(other.0) {
      Some(small) if small < 4096 => U12(small),
      _ => Self::max_value()
    }
  }

  /// Wrapping (modular) multiplication. 
  /// Computes `self * other`, wrapping around at the boundary of the type.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```
  /// use twelve_bit::u12::*;
  ///
  /// assert_eq!(U12::from(2u8).wrapping_mul(1u8.into()), 2u8.into());
  /// assert_eq!(U12::from(2u8).wrapping_mul((2048u16).unchecked_into()), 0u8.into());
  /// assert_eq!(U12::from(2u8).wrapping_mul((4095u16).unchecked_into()), (0xFFE as u16).unchecked_into());
  /// ```
  pub fn wrapping_mul(self, other: Self) -> Self {
    U12(self.0.wrapping_mul(other.0) & 0xFFF)
  }

  /// Overflowing multiplication.
  /// Returns a tuple of the multiplication along with a boolean indicating whether an arithmetic 
  /// overflow would occur. If an overflow would have occurred then the wrapped value is returned.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![2].overflowing_mul(u12![1]), (u12![2], false));
  /// assert_eq!(u12![2].overflowing_mul(u12![2048]), (u12![0], true));
  /// assert_eq!(u12![2].overflowing_mul(u12![4095]), (u12![0xFFE], true));
  /// # }
  /// ```
  pub fn overflowing_mul(self, other: Self) -> (Self, bool) {
    match self.checked_mul(other) {
      Some(result) => (result, false),
              None => (self.wrapping_mul(other), true)
    }
  }

  /// Checked integer division.
  /// Computes `self / other`,  returning None if other == 0 or the operation results in 
  /// underflow or overflow.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```
  /// use twelve_bit::u12::*;
  ///
  /// assert_eq!(U12::from(2u8).checked_div(0u8.into()), None);
  /// assert_eq!(U12::from(2u8).checked_div((2048u16).unchecked_into()), Some(U12::min_value()));
  /// assert_eq!(U12::from(2u8).checked_div(2u8.into()), Some(U12::from(1u8)));
  /// ```
  pub fn checked_div(self, other: Self) -> Option<Self> {
    self.0
      .checked_div(other.0)
      .map(|small| U12(small))
  }

  /// Wrapping (modular) division. 
  /// Computes self / other. Wrapped division on unsigned types is just normal division. 
  /// There's no way wrapping could ever happen. This function exists, so that all operations 
  /// are accounted for in the wrapping operations.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```
  /// use twelve_bit::u12::*;
  ///
  /// assert_eq!(U12::from(2u8).wrapping_div((2048u16).unchecked_into()), U12::min_value());
  /// assert_eq!(U12::from(2u8).wrapping_div(2u8.into()), U12::from(1u8));
  /// ```
  pub fn wrapping_div(self, other: Self) -> Self {
    U12(self.0.wrapping_div(other.0))
  }

  /// Calculates the divisor when the receiver is divided by `rhs`.
  /// Returns a tuple of the divisor along with a boolean indicating whether an arithmetic 
  /// overflow would occur. Note that for unsigned integers overflow never occurs, 
  /// so the second value is always false.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![2].overflowing_div(u12![1]), (u12![2], false));
  /// assert_eq!(u12![2048].overflowing_div(u12![2]), (u12![1024], false));
  /// assert_eq!(u12![4095].overflowing_div(u12![2]), (u12![2047], false));
  /// # }
  /// ```
  pub fn overflowing_div(self, other: Self) -> (Self, bool) {
    (self.wrapping_div(other), false)
  }

  /// Checked integer negation.
  /// Computes `-self`, returning `None` unless `self == 0`.
  /// Note that negating any positive integer will overflow.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```
  /// use twelve_bit::u12::*;
  ///
  /// assert_eq!(U12::from(0u8).checked_neg(), Some(0u8.into()));
  /// assert_eq!(U12::from(2u8).checked_neg(), None);
  /// ```
  pub fn checked_neg(self) -> Option<Self> {
    match self.0 {
      0 => Some(self),
      _ => None
    }
  }

  /// Wrapping (modular) negation.
  /// Computes `-self`, wrapping around at the boundary of the type.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```
  /// use twelve_bit::u12::*;
  ///
  /// assert_eq!(U12::from(2u8).wrapping_neg(), 0xFFEu16.unchecked_into());
  /// assert_eq!(U12::from(255u8).wrapping_neg(), 0xF01u16.unchecked_into());
  /// ```
  pub fn wrapping_neg(self) -> Self {
    U12(self.0.wrapping_neg() & 0xFFF)
  }

  /// Negates self in an overflowing fashion.
  /// Returns `!self + 1` using wrapping operations to return the value that 
  /// represents the negation of this unsigned value. Note that for positive 
  /// unsigned values overflow always occurs, but negating `0` does not overflow.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```
  /// use twelve_bit::u12::*;
  ///
  /// assert_eq!(U12::from(0u8).overflowing_neg(), (0u8.into(), false));
  /// assert_eq!(U12::from(2u8).overflowing_neg(), (0xFFEu16.unchecked_into(), true));
  /// ```
  pub fn overflowing_neg(self) -> (U12, bool) {
    match self.0 {
      0 => (self, false),
      _ => (self.wrapping_neg(), true)
    }
  }

  /// Checked integer remainder. 
  /// Computes `self % other`, returning `None` if `other == 0` or the 
  /// operation results in underflow or overflow.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![5].checked_rem(u12![2]), Some(u12![1]));
  /// assert_eq!(u12![5].checked_rem(u12![0]), None);
  /// # }
  /// ```
  pub fn checked_rem(self, other: Self) -> Option<Self> {
    self.0
      .checked_rem(other.0)
      .map(|value| U12(value))
  }

  /// Wrapping (modular) integer remainder.
  /// Computes `self % other`. Wrapped remainder calculation on unsigned types 
  /// is just the regular remainder calculation. There's no way wrapping could ever 
  /// happen. This function exists, so that all operations are accounted for in the 
  /// wrapping operations.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![100].wrapping_rem(u12![10]), u12![0]);
  /// # }
  /// ```
  pub fn wrapping_rem(self, other: Self) -> Self {
    U12(self.0.wrapping_rem(other.0))
  }

  /// Calculates the remainder when `self` is divided by `other`.
  /// Returns a tuple of the remainder after dividing along with a boolean indicating 
  /// whether an arithmetic overflow would occur. Note that for unsigned integers 
  /// overflow never occurs, so the second value is always false.
  ///
  /// # Panics
  /// This function will panic if `other` is `0`.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![5].overflowing_rem(u12![2]), (u12![1], false));
  /// # }
  /// ```
  pub fn overflowing_rem(self, other: Self) -> (Self, bool) {
    let (result, overflow) = self.0.overflowing_rem(other.0);
    (U12(result), overflow)
  }

  /// Checked shift left. 
  /// Computes `self << rhs`, returning `None` if `rhs` is larger than or equal to 
  /// the number of bits in the receiver.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![0b000000000001].checked_shl(12), None);
  /// assert_eq!(u12![0b000000000001].checked_shl(1), Some(u12![0b000000000010]));
  /// assert_eq!(u12![0b000000000001].checked_shl(11), Some(u12![0b100000000000]));
  /// # }
  /// ```
  pub fn checked_shl(self, rhs: u32) -> Option<Self> {
    if rhs >= 12 {
      None
    } else {
      self.0
        .checked_shl(rhs)
        .map(|value| U12(value))
    }
  }

  /// Panic-free bitwise shift-left; yields `self << mask(rhs)`, where mask removes any 
  /// high-order bits of rhs that would cause the shift to exceed the bitwidth of the type.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![0b000000000001].wrapping_shl(12), u12![0b000000000001]);
  /// assert_eq!(u12![0b000000000001].wrapping_shl( 1), u12![0b000000000010]);
  /// assert_eq!(u12![0b000000000001].wrapping_shl(11), u12![0b100000000000]);
  /// # }
  /// ```
  pub fn wrapping_shl(self, rhs: u32) -> Self {
    self.checked_shl(rhs % 12).unwrap()
  }

  /// Shifts self left by rhs bits.
  /// Returns a tuple of the shifted version of the receiver along with a boolean
  /// indicating whether the shift value was larger than or equal to the number of
  /// bits. If the shift value is too large, then value is masked `(N-1)` where N
  /// is the number of bits, and this value is then used to perform the shift.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![0b000000000001].overflowing_shl(12), (u12![0b000000000001], true));
  /// assert_eq!(u12![0b000000000001].overflowing_shl( 1), (u12![0b000000000010], false));
  /// assert_eq!(u12![0b000000000001].overflowing_shl(11), (u12![0b100000000000], false));
  /// # }
  /// ```
  pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
    (self.wrapping_shl(rhs), rhs >= 12)
  }

  /// Checked shift right. 
  /// Computes `self >> rhs`, returning `None` if `rhs` is larger than or 
  /// equal to the number of bits in the receiver.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![0b100000000000].checked_shr(12), None);
  /// assert_eq!(u12![0b100000000000].checked_shr( 1), Some(u12![0b010000000000]));
  /// assert_eq!(u12![0b100000000000].checked_shr(11), Some(u12![0b000000000001]));
  /// # }
  /// ```
  pub fn checked_shr(self, rhs: u32) -> Option<Self> {
    if rhs >= 12 {
      None
    } else {
      self.0
        .checked_shr(rhs)
        .map(|value| U12(value))
    }
  }

  /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`, where mask removes any 
  /// high-order bits of rhs that would cause the shift to exceed the bitwidth of the type.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![0b100000000000].wrapping_shr(12), u12![0b100000000000]);
  /// assert_eq!(u12![0b100000000000].wrapping_shr( 1), u12![0b010000000000]);
  /// assert_eq!(u12![0b100000000000].wrapping_shr(11), u12![0b000000000001]);
  /// # }
  /// ```
  pub fn wrapping_shr(self, rhs: u32) -> Self {
    self.checked_shr(rhs % 12).unwrap()
  }

  /// Shifts the receiver right by `rhs` bits.
  /// Returns a tuple of the shifted version of self along with a boolean indicating 
  /// whether the shift value was larger than or equal to the number of bits. 
  /// If the shift value is too large, then value is masked `(N-1)` where `N` is the 
  /// number of bits, and this value is then used to perform the shift.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![0b100000000000].overflowing_shr(12), (u12![0b100000000000], true));
  /// assert_eq!(u12![0b100000000000].overflowing_shr( 1), (u12![0b010000000000], false));
  /// assert_eq!(u12![0b100000000000].overflowing_shr(11), (u12![0b000000000001], false));
  /// # }
  /// ```
  pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
    (self.wrapping_shr(rhs), rhs >= 12)
  }

  /// Checked bitwise-and of the receiver with `rhs`.
  /// Computes `self & rhs`. This method cannot fail.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![0b111100001111].checked_bitand(u12![0b111100000000]), Some(u12![0b111100000000]));
  /// # }
  /// ```
  pub fn checked_bitand(self, rhs: Self) -> Option<Self> {
    Some(U12(self.0.bitand(rhs.0)))
  }

  /// Checked bitwise-or of the receiver with `rhs`.
  /// Computes `self | rhs`. This method cannot fail.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![0b111100001111].checked_bitor(u12![0b111100000000]), Some(u12![0b111100001111]));
  /// # }
  /// ```
  pub fn checked_bitor(self, rhs: Self) -> Option<Self> {
    Some(U12(self.0.bitor(rhs.0)))
  }

  /// Checked bitwise-xor of the receiver with `rhs`.
  /// Computes `self ^ rhs`. This method cannot fail.
  ///
  /// # Examples
  /// Basic usage:
  /// 
  /// ```rust
  /// # #[macro_use] extern crate twelve_bit;
  /// use twelve_bit::u12::*;
  /// # fn main() {
  /// assert_eq!(u12![0b111100001111].checked_bitxor(u12![0b111100000000]), Some(u12![0b000000001111]));
  /// # }
  /// ```
  pub fn checked_bitxor(self, rhs: Self) -> Option<Self> {
    Some(U12(self.0.bitxor(rhs.0)))
  }

}

// MARK: - Non-Failable Conversions - From Smaller Types

impl From<u8> for U12 {
  fn from(small: u8) -> Self {
    U12(small as u16)
  }
}

// MARK: - Non-Failable Conversions - Into Larger Types

/// Implements From<U12> for the specified type.
macro_rules! impl_from_u12 {
  ($result:path) => {
    impl From<U12> for $result {
      fn from(small: U12) -> Self {
        small.0 as Self
      }
    }
  }
}

impl_from_u12!(u16);
impl_from_u12!(u32);
impl_from_u12!(u64);
impl_from_u12!(usize);

// MARK: - Failable Conversions - From Larger Types

/// Trait for implementing failable conversions in a generic way.
pub trait FailableInto<T> where Self: marker::Sized, T: marker::Sized {

  /// Returns the receiver as `Some(T)` if non-truncating, or `None`.
  fn failable_into(self) -> Option<T>;

  /// Returns the receiver as `T` by using `failable_into()` and unwrapping the result.
  ///
  /// # Panics
  /// This method will panic if `failable_into` fails.
  fn unchecked_into(self) -> T {
    match self.failable_into() {
      Some(value) => value,
      None => panic!("unchecked conversion failed")
    }
  }

}

/// Implements a failable conversion into u8 from U12.
impl FailableInto<u8> for U12 {
  fn failable_into(self) -> Option<u8> {
    if self.0 > 0xFF {
      None
    } else {
      Some((self.0 & 0xFF) as u8)
    }
  }
}

/// Implements FailableAs<U12> for the specified type.
macro_rules! impl_failable_into_u12 {
  ($source_type:path) => {
    impl FailableInto<U12> for $source_type {
      fn failable_into(self) -> Option<U12> {
        if self > 0xFFF {
          None
        } else {
          Some(U12(self as u16))
        }
      }
    }
  }
}

impl_failable_into_u12!(u16);
impl_failable_into_u12!(u32);
impl_failable_into_u12!(u64);
impl_failable_into_u12!(usize);

// MARK: - Default

impl Default for U12 {
  fn default() -> Self {
    U12::min_value()
  }
}

// MARK: - Arithmetic Operator Traits (Add, Sub, Mul, Div)

///
/// Implements an arithmetic trait family for `U12`. This macro generates
/// implementations for an arithmetic trait `$trait_name` such that the
/// it is possible to invoke `$trait_method` on all of `U12.op(U12)`, `(&'a U12).op(U12)`,
/// `U12.op(&'a U12)` and `(&'a U12).op(&'b U12)`. The implementation calls through to
/// `$checked_method` on U12. If the `$checked_method` returns `None`, the
/// trait panics with the message specified as `$message`.
///
macro_rules! impl_arithmetic_trait_family_for_u12 {
  ($trait_name:ident, $trait_method:ident, $checked_method:ident, $message:expr) => {

    // Implementation of U12.op(U12) -> U12.
    impl $trait_name<U12> for U12 {
      type Output = U12;
      fn $trait_method(self, other: U12) -> Self::Output {
        match self.$checked_method(other) {
          Some(result) => result,
          None => {
            panic!($message)
          }
        }
      }
    }

    // Implementation of (&'a U12).op(U12) -> U12.
    impl<'a> $trait_name<U12> for &'a U12 {
      type Output = U12;
      fn $trait_method(self, other: U12) -> Self::Output {
        (*self).$trait_method(other)
      }
    }

    // Implementation of U12.op(&'a U12) -> U12.
    impl<'a> $trait_name<&'a U12> for U12 {
      type Output = U12;
      fn $trait_method(self, other: &'a U12) -> Self::Output {
        self.$trait_method(*other)
      }
    }

    // Implementation of (&'a U12).op(&'b U12) -> U12.
    impl<'a,'b> $trait_name<&'a U12> for &'b U12 {
      type Output = U12;
      fn $trait_method(self, other: &'a U12) -> Self::Output {
        (*self).$trait_method(*other)
      }
    }

  }
}

impl_arithmetic_trait_family_for_u12!(Add, add, checked_add, "arithmetic overflow" );
impl_arithmetic_trait_family_for_u12!(Sub, sub, checked_sub, "arithmetic underflow");
impl_arithmetic_trait_family_for_u12!(Mul, mul, checked_mul, "arithmetic overflow" );
impl_arithmetic_trait_family_for_u12!(Div, div, checked_div, "arithmetic exception");
impl_arithmetic_trait_family_for_u12!(Rem, rem, checked_rem, "arithmetic exception");

// MARK: - Not

impl Not for U12 {
  type Output = U12;
  fn not(self) -> Self::Output {
    U12((!self.0) & 0xFFF)
  }
}

impl<'a> Not for &'a U12 {
  type Output = U12;
  fn not(self) -> Self::Output {
    (*self).not()
  }
}

// MARK: - Bitwise Operations

macro_rules! impl_bitwise_trait_family_for_u12 {
  ($trait_name:ident, $trait_method:ident, $checked_method:ident) => {
    impl_arithmetic_trait_family_for_u12!($trait_name, $trait_method, $checked_method, "<unreachable>");
  }
}

impl_bitwise_trait_family_for_u12!(BitAnd, bitand, checked_bitand);
impl_bitwise_trait_family_for_u12!(BitOr , bitor , checked_bitor );
impl_bitwise_trait_family_for_u12!(BitXor, bitxor, checked_bitxor);

// MARK: - Logic Operations

///
/// Implements an logic trait family for `U12`. This macro generates
/// implementations for an arithmetic trait `$trait_name` such that the
/// it is possible to invoke `$trait_method` on all of `U12.op($rhs_type)`, `(&'a U12).op($rhs_type)`,
/// `U12.op(&'a $rhs_type)` and `(&'a U12).op(&'b $rhs_type)`. The implementation calls through to
/// `$checked_method` on U12. If the RHS value represented as a 64-bit number exceeds
/// 12, the implementation panics with the specified `$message`.
///
macro_rules! impl_shift_trait_family_for_u12 {
  ($rhs_type:ident, $trait_name:ident, $trait_method:ident, $checked_method:ident, $message:expr) => {

    // Implementation of U12.op($rhs_type) -> U12.
    impl $trait_name<$rhs_type> for U12 {
      type Output = U12;
      fn $trait_method(self, other: $rhs_type) -> Self::Output {
        if (other as u64) > (u32::max_value() as u64) {
          panic!($message)
        } else {
          match self.$checked_method(other as u32) {
            Some(result) => result,
            None => {
              panic!($message)
            }
          }
        }
      }
    }

    // Implementation of (&'a U12).op($rhs_type) -> U12.
    impl<'a> $trait_name<$rhs_type> for &'a U12 {
      type Output = U12;
      fn $trait_method(self, other: $rhs_type) -> Self::Output {
        (*self).$trait_method(other)
      }
    }

    // Implementation of U12.op(&'a $rhs_type) -> U12.
    impl<'a> $trait_name<&'a $rhs_type> for U12 {
      type Output = U12;
      fn $trait_method(self, other: &'a $rhs_type) -> Self::Output {
        self.$trait_method(*other)
      }
    }

    // Implementation of (&'a U12).op(&'b $rhs_type) -> U12.
    impl<'a,'b> $trait_name<&'a $rhs_type> for &'b U12 {
      type Output = U12;
      fn $trait_method(self, other: &'a $rhs_type) -> Self::Output {
        (*self).$trait_method(*other)
      }
    }

  }
}

// TODO: mm: Implement Shl<U12>

impl_shift_trait_family_for_u12!(u8,    Shl, shl, checked_shl, "logic overflow");
impl_shift_trait_family_for_u12!(i8,    Shl, shl, checked_shl, "logic overflow");
impl_shift_trait_family_for_u12!(u16,   Shl, shl, checked_shl, "logic overflow");
impl_shift_trait_family_for_u12!(i16,   Shl, shl, checked_shl, "logic overflow");
impl_shift_trait_family_for_u12!(u32,   Shl, shl, checked_shl, "logic overflow");
impl_shift_trait_family_for_u12!(i32,   Shl, shl, checked_shl, "logic overflow");
impl_shift_trait_family_for_u12!(u64,   Shl, shl, checked_shl, "logic overflow");
impl_shift_trait_family_for_u12!(i64,   Shl, shl, checked_shl, "logic overflow");
impl_shift_trait_family_for_u12!(usize, Shl, shl, checked_shl, "logic overflow");
impl_shift_trait_family_for_u12!(isize, Shl, shl, checked_shl, "logic overflow");

// TODO: mm: Implement Shr<U12>

impl_shift_trait_family_for_u12!(u8,    Shr, shr, checked_shr, "logic underflow");
impl_shift_trait_family_for_u12!(i8,    Shr, shr, checked_shr, "logic underflow");
impl_shift_trait_family_for_u12!(u16,   Shr, shr, checked_shr, "logic underflow");
impl_shift_trait_family_for_u12!(i16,   Shr, shr, checked_shr, "logic underflow");
impl_shift_trait_family_for_u12!(u32,   Shr, shr, checked_shr, "logic underflow");
impl_shift_trait_family_for_u12!(i32,   Shr, shr, checked_shr, "logic underflow");
impl_shift_trait_family_for_u12!(u64,   Shr, shr, checked_shr, "logic underflow");
impl_shift_trait_family_for_u12!(i64,   Shr, shr, checked_shr, "logic underflow");
impl_shift_trait_family_for_u12!(usize, Shr, shr, checked_shr, "logic underflow");
impl_shift_trait_family_for_u12!(isize, Shr, shr, checked_shr, "logic underflow");