bitint 0.1.1

Integer types that have a logical size measured in bits.
Documentation
# bitint

[![crates.io][crates-badge]][crates-url]
[![docs.rs][docs-badge]][docs-url]
[![CI Status][ci-badge]][ci-url]

[crates-badge]: https://img.shields.io/crates/v/bitint
[crates-url]: https://crates.io/crates/bitint
[docs-badge]: https://img.shields.io/docsrs/bitint
[docs-url]: https://docs.rs/bitint
[ci-badge]: https://img.shields.io/github/actions/workflow/status/mvanbem/bitint/ci.yml?branch=main&label=CI&logo=github
[ci-url]: https://github.com/mvanbem/bitint/actions?query=workflow%3ACI+branch%3Amain

A bit-integer library for Rust. `bitint`s are like primitive integer types, but
their logical width is measured in bits.

This crate provides the `UBitint` trait and 128 types named `U1` through `U128`
that implement it. Each type wraps the smallest primitive unsigned integer type
that can contain it. The types that are not the same width as their primitive
type impose a validity constraint---the value is represented in the least
significant bits and the upper bits are always clear.

## Demo

```rust
// Recommended, but not required.
use bitint::prelude::*;

// Use the bitint! macro to write a bitint literal. Underscores are permitted
// anywhere in a Rust literal and are encouraged for readability.
let seven = bitint!(7_U12);

// Use the #[bitint_literals] attribute macro to write bitint literals anywhere
// inside an item. Here the item is a function, but it can also be useful on an
// impl block or inline module.
# demo();
#[bitint_literals]
fn demo() {
    let five = 5_U12;

    // Arithmetic ops accept Self or the primitive type and panic or wrap just
    // like primitive arithmetic ops.
    assert_eq!(five + five, 10_U12);
    assert_eq!(five - 1_U12, 4_U12);
    assert_eq!(five * 2_U12, 10_U12);
    assert_eq!(five / 3_U12, 1_U12);
    assert_eq!(five % 3_U12, 2_U12);
    // If built with overflow-checks = true, this would panic.
    // If built with overflow-checks = false, this would wrap.
    // five + U12::MAX

    // Checked arithmetic ops.
    assert_eq!(five.checked_add(10_U12), Some(15_U12));
    assert_eq!(five.checked_add(4095_U12), None);

    // Wrapping arithmetic ops.
    assert_eq!(five.wrapping_add(10_U12), 15_U12);
    assert_eq!(five.wrapping_add(4095_U12), 4_U12);

    // Zero-(extra)-cost unchecked arithmetic ops.
    #[cfg(feature = "unchecked_math")]
    {
        // SAFETY: 15 is in range for U12.
        assert_eq!(unsafe { five.unchecked_add(10_U12) }, 15_U12);
        // This would violate the safety condition and cause undefined behavior.
        // unsafe { five.unchecked_add(4095_U12) }
    }

    // Zero-cost conversion to a primitive type.
    assert_eq!(five.to_primitive(), 5);

    // Checked constructor.
    assert_eq!(U12::new(5), Some(five));
    assert_eq!(U12::new(4096), None);

    // Masking constructor.
    assert_eq!(U12::new_masked(5), five);
    assert_eq!(U12::new_masked(13 * 4096 + 5), five);

    // Zero-cost unsafe constructor.
    // SAFETY: 5 is in range for U12.
    assert_eq!(unsafe { U12::new_unchecked(5) }, five);
    // This would violate the safety condition and cause undefined behavior.
    // unsafe { U12::new_unchecked(65536) }

    // Zero-cost safe constructor, only for bitints that are the same width as a
    // primitive type.
    assert_eq!(U16::from_primitive(1234), 1234_U16);

    // String conversions.
    assert_eq!(format!("{five}"), "5");
    assert_eq!(five.to_string(), "5");
    assert_eq!("5".parse::<U12>().unwrap(), 5_U12);
};
```

## Crate features

* **unchecked_math** - Enables the `unchecked_*` methods on unsigned `bitint`
  types. Requires a nightly Rust compiler.