1 //! Test utilities.
2 
3 use super::config::BUFFER_SIZE;
4 
5 cfg_if! {
6 if #[cfg(feature = "correct")] {
7     use arrayvec;
8     use super::sequence::{CloneableVecLike, VecLike};
9 }}  // cfg_if
10 
11 // BASES
12 
13 /// Pow2 bases.
14 #[cfg(all(feature = "correct", feature = "radix"))]
15 pub(crate) const BASE_POW2: [u32; 5] = [2, 4, 8, 16, 32];
16 
17 /// Non-pow2 bases.
18 #[cfg(feature = "radix")]
19 pub(crate) const BASE_POWN: [u32; 30] = [
20     3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21,
21     22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36
22 ];
23 
24 #[cfg(not(feature = "radix"))]
25 pub(crate) const BASE_POWN: [u32; 1] = [10];
26 
27 // BUFFER
28 
29 /// Create new buffer for itoa or ftoa functionality.
30 #[inline]
new_buffer() -> [u8; BUFFER_SIZE]31 pub(crate) fn new_buffer() -> [u8; BUFFER_SIZE] {
32     [b'\0'; BUFFER_SIZE]
33 }
34 
35 // BYTE SLICE
36 
37 /// Use to help type deduction.
38 #[inline]
as_slice<'a, T>(x: &'a [T]) -> &'a [T]39 pub(crate) fn as_slice<'a, T>(x: &'a [T]) -> &'a [T] {
40     x
41 }
42 
43 cfg_if! {
44 if #[cfg(feature = "correct")] {
45 
46 // FROM U32
47 
48 #[cfg(limb_width_32)]
49 pub(crate) type DataType = arrayvec::ArrayVec<[u32; 128]>;
50 
51 #[cfg(limb_width_64)]
52 pub(crate) type DataType = arrayvec::ArrayVec<[u64; 64]>;
53 
54 
55 #[cfg(limb_width_32)]
56 pub(crate) fn from_u32(x: &[u32]) -> DataType {
57     x.iter().cloned().collect()
58 }
59 
60 #[cfg(limb_width_64)]
61 pub(crate) fn from_u32(x: &[u32]) -> DataType {
62     let mut v = DataType::default();
63     v.reserve(x.len() / 2);
64     for xi in x.chunks(2) {
65         match xi.len() {
66             1 => v.push(xi[0] as u64),
67             2 => v.push(((xi[1] as u64) << 32) | (xi[0] as u64)),
68             _ => unreachable!(),
69         }
70     }
71 
72     v
73 }
74 
75 #[cfg(limb_width_32)]
76 pub(crate) fn deduce_from_u32<T: CloneableVecLike<u32>>(x: &[u32]) -> T
77 {
78     from_u32(x).iter().cloned().collect()
79 }
80 
81 #[cfg(limb_width_64)]
82 pub(crate) fn deduce_from_u32<T: CloneableVecLike<u64>>(x: &[u32]) -> T
83 {
84     from_u32(x).iter().cloned().collect()
85 }
86 
87 }}  // cfg_if
88 
89 // LITERAL BYTE SLICES
90 
91 /// Create a literal byte slice.
92 macro_rules! b {
93     ($l:expr) => ($l.as_bytes());
94 }
95 
96 // FLOATING-POINT EQUALITY
97 
98 cfg_if! {
99 if #[cfg(feature = "correct")] {
100     /// Assert two 32-bit floats are equal.
101     macro_rules! assert_f32_eq {
102         ($l:expr, $r:expr $(, $opt:ident = $val:expr)+) => (assert_eq!($l, $r););
103         ($l:expr, $r:expr) => (assert_eq!($l, $r););
104     }
105 
106     /// Assert two 64-bit floats are equal.
107     macro_rules! assert_f64_eq {
108         ($l:expr, $r:expr $(, $opt:ident = $val:expr)+) => (assert_eq!($l, $r););
109         ($l:expr, $r:expr) => (assert_eq!($l, $r););
110     }
111 } else {
112     /// Assert two 32-bit floats are equal.
113     macro_rules! assert_f32_eq {
114         ($l:expr, $r:expr $(, $opt:ident = $val:expr)+) => (approx::assert_relative_eq!($l, $r $(, $opt = $val)*););
115         ($l:expr, $r:expr) => (approx::assert_relative_eq!($l, $r, epsilon=1e-20););
116     }
117 
118     /// Assert two 64-bit floats are equal.
119     macro_rules! assert_f64_eq {
120         ($l:expr, $r:expr $(, $opt:ident = $val:expr)+) => (approx::assert_relative_eq!($l, $r $(, $opt = $val)*););
121         ($l:expr, $r:expr) => (approx::assert_relative_eq!($l, $r, epsilon=1e-20, max_relative=1e-12););
122     }
123 }}  // cfg_if
124