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
use super::BUint;
use crate::digit::{self, Digit};
use crate::errors::{TryFromErrorReason::*, TryFromIntError};
use crate::nightly::impl_const;
use crate::cast::CastFrom;
impl_const! {
impl<const N: usize> const From<bool> for BUint<N> {
#[inline]
fn from(small: bool) -> Self {
Self::cast_from(small)
}
}
}
impl_const! {
impl<const N: usize> const From<char> for BUint<N> {
#[inline]
fn from(c: char) -> Self {
Self::cast_from(c)
}
}
}
macro_rules! from_uint {
($($uint: tt),*) => {
$(impl_const! {
impl<const N: usize> const From<$uint> for BUint<N> {
#[inline]
fn from(int: $uint) -> Self {
const UINT_BITS: usize = $uint::BITS as usize;
let mut out = Self::ZERO;
let mut i = 0;
while i << digit::BIT_SHIFT < UINT_BITS {
let d = (int >> (i << digit::BIT_SHIFT)) as Digit;
if d != 0 {
out.digits[i] = d;
}
i += 1;
}
out
}
}
})*
}
}
from_uint!(u8, u16, u32, usize, u64, u128);
macro_rules! try_from_iint {
($($int: tt -> $uint: tt),*) => {
$(impl_const! {
impl<const N: usize> const TryFrom<$int> for BUint<N> {
type Error = TryFromIntError;
#[inline]
fn try_from(int: $int) -> Result<Self, Self::Error> {
if int.is_negative() {
return Err(TryFromIntError {
from: stringify!($int),
to: "BUint",
reason: Negative,
});
}
let bits = int as $uint;
Ok(Self::from(bits))
}
}
})*
}
}
try_from_iint!(i8 -> u8, i16 -> u16, i32 -> u32, isize -> usize, i64 -> u64, i128 -> u128);
crate::int::convert::all_try_int_impls!(BUint);
impl_const! {
impl<const N: usize> const From<[Digit; N]> for BUint<N> {
#[inline]
fn from(digits: [Digit; N]) -> Self {
Self::from_digits(digits)
}
}
}
impl_const! {
impl<const N: usize> const From<BUint<N>> for [Digit; N] {
#[inline]
fn from(uint: BUint<N>) -> Self {
uint.digits
}
}
}
#[cfg(test)]
mod tests {
use crate::test;
test::test_from! {
function: <u128 as From>::from,
from_types: (u8, u16, u32, u64, u128, bool, char)
}
test::test_from! {
function: <u128 as TryFrom>::try_from,
from_types: (i8, i16, i32, i64, i128, isize, usize)
}
test::test_into! {
function: <u128 as TryInto>::try_into,
into_types: (u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize)
}
}