1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
//! Integer types that have a logical size measured in bits.
//!
//! This crate provides the [`UBitint`] trait and 128 types named
//! [`U1`](crate::U1) through [`U128`](crate::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
//!
//! ```
//! // 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.
//!
#![cfg_attr(not(test), no_std)]
#![cfg_attr(
    feature = "unchecked_math",
    feature(unchecked_math),
    feature(const_inherent_unchecked_arith)
)]
#![cfg_attr(feature = "_nightly", feature(doc_cfg))]
#![deny(missing_docs)]
#![deny(rustdoc::broken_intra_doc_links)]

use core::fmt::{self, Display, Formatter};
use core::num::ParseIntError;

pub mod prelude;
mod traits;
mod types;

// For macro access via `$crate`.
#[doc(hidden)]
pub mod __private {
    pub use bitint_macros::bitint;
}

mod sealed {
    pub trait Sealed {}
}

pub use types::*;

/// The error type returned when a [`TryFrom`] conversion to a `bitint` fails.
#[derive(Debug)]
pub struct RangeError(pub(crate) ());

impl Display for RangeError {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "value out of range for bitint type")
    }
}

/// The error type returned when parsing a string to a `bitint` fails.
#[derive(Debug)]
#[non_exhaustive]
pub enum ParseBitintError {
    /// Parsing failed because parsing to the primitive type failed.
    Parse(ParseIntError),
    /// Parsing failed because the primitive value was out of range.
    Range(RangeError),
}

impl Display for ParseBitintError {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        match self {
            Self::Parse(e) => write!(f, "{e}"),
            Self::Range(e) => write!(f, "{e}"),
        }
    }
}

impl From<ParseIntError> for ParseBitintError {
    fn from(value: ParseIntError) -> Self {
        Self::Parse(value)
    }
}

impl From<RangeError> for ParseBitintError {
    fn from(value: RangeError) -> Self {
        Self::Range(value)
    }
}

pub use traits::*;

/// Constructs a `bitint` literal.
///
/// A `bitint` literal is an integer literal with a suffix consisting of `'U'`
/// followed by an integer, which must be at least one and at most 128.
///
/// This macro accepts one `bitint` literal which is checked against the
/// corresponding [`UBitint`] type's range and replaced with either a call to a
/// non-panicking const constructor or a compile error.
///
/// # Examples
///
/// ```
/// # use bitint::prelude::*;
/// // The suffix `U3` corresponds to the type `U3`. Underscores are permitted
/// // anywhere in a Rust literal and are encouraged for readability.
/// let x = bitint!(6_U3);
/// assert_eq!(x.to_primitive(), 6);
///```
///
/// ```compile_fail
/// # use bitint::prelude::*;
/// // This value is out of range for `U16`.
/// bitint!(65536_U16);
/// ```
#[macro_export]
macro_rules! bitint {
    ($($tt:tt)*) => {
        $crate::__private::bitint! { ($crate, $($tt)*) }
    };
}

/// Rewrites `bitint` literals in the item it is attached to.
///
/// A `bitint` literal is an integer literal with a suffix consisting of `'U'`
/// followed by an integer, which must be at least one and at most 128.
///
/// `bitint` literals are checked against the corresponding [`UBitint`] type's
/// range and replaced with either a call to a non-panicking const constructor
/// or a compile error. All other tokens are preserved.
///
/// # Examples
///
/// ```
/// # use bitint::prelude::*;
/// #[bitint_literals]
/// fn example() {
///     // The suffix `U3` corresponds to the type `U3`. Underscores are
///     // permitted anywhere in a Rust literal and are encouraged for
///     // readability.
///     let x = 6_U3;
///     assert_eq!(x.to_primitive(), 6);
/// }
/// ```
///
/// ```compile_fail
/// # use bitint::prelude::*;
/// #[bitint_literals]
/// fn example() {
///     // This value is out of range for `U16`.
///     let x = 65536_U16;
/// }
/// ```
pub use bitint_macros::bitint_literals;