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
const fn str_eq(a: &str, b: &str) -> bool {
let a = a.as_bytes();
let b = b.as_bytes();
if a.len() != b.len() {
return false;
}
let mut i = 0;
while i < a.len() {
if a[i] != b[i] {
return false;
}
i += 1;
}
true
}
pub(crate) const GLOBAL_OVERFLOW_CHECKS: bool = {
match option_env!("BNUM_OVERFLOW_CHECKS") {
Some(v) if str_eq(v, "true") => true,
Some(v) if str_eq(v, "false") => false,
_ => cfg!(debug_assertions), // if the environment variable is not set, fallback to using whether in release mode or not. this should never happen though as build.rs will always set the variable
}
};
/// An enum that represents the different possible overflow behaviour for [`Integer`](crate::Integer).
///
/// For more details on overflow behaviour, see the [`Integer`](crate::Integer) documentation.
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
#[repr(u8)]
pub enum OverflowMode {
/// Specifies that arithmetic operations should wrap around on overflow.
Wrap = 0,
/// Specifies that arithmetic operations should panic on overflow.
Panic = 1,
/// Specifies that arithmetic operations should saturate to the integer type's maximum or minimum value on overflow.
Saturate = 2,
}
impl OverflowMode {
/// The default overflow mode, which is the mode used for [`Integer`](crate::Integer) types when the const-generic parameter `OM` is not explicitly specified.
///
/// The value of `DEFAULT` is controlled by the [`overflow-checks` flag](https://doc.rust-lang.org/cargo/reference/profiles.html#overflow-checks): if overflow checks are enabled, then `DEFAULT` is `Self::Panic`; if overflow checks are disabled, then `DEFAULT` is `Self::Wrap`.
pub const DEFAULT: Self = if GLOBAL_OVERFLOW_CHECKS {
OverflowMode::Panic
} else {
OverflowMode::Wrap
};
#[inline]
pub(crate) const fn to_u8(self) -> u8 {
self as u8
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_str_eq() {
assert!(str_eq("hello", "hello"));
assert!(!str_eq("hello", "world"));
assert!(str_eq("", ""));
assert!(str_eq("a", "a"));
assert!(str_eq("hi there", "hi there"));
assert!(!str_eq("hello", "helloo"));
assert!(!str_eq("", "a"));
}
#[test]
fn test_overflow_mode_to_u8() {
assert_eq!(OverflowMode::Wrap.to_u8(), 0);
assert_eq!(OverflowMode::Panic.to_u8(), 1);
assert_eq!(OverflowMode::Saturate.to_u8(), 2);
}
}