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
use crate::util::*;
use super::exponent::*;
use super::traits::*;
use super::trim::*;
use super::validate::*;
data_interface!(
struct StandardFastDataInterface,
struct StandardSlowDataInterface,
fields => {},
integer_iter => (IteratorNoSeparator, iterate_digits_no_separator),
fraction_iter => (IteratorNoSeparator, iterate_digits_no_separator),
exponent_iter => (IteratorNoSeparator, iterate_digits_no_separator),
format => |_| NumberFormat::default(),
consume_integer_digits => consume_digits_no_separator,
consume_fraction_digits => consume_digits_no_separator,
extract_exponent => extract_exponent_no_separator,
validate_mantissa => validate_permissive_mantissa,
validate_exponent => validate_required_exponent,
validate_exponent_fraction => validate_exponent_optional_fraction,
validate_exponent_sign => validate_optional_exponent_sign,
ltrim_zero => ltrim_zero_no_separator,
ltrim_separator => ltrim_separator_no_separator,
rtrim_zero => rtrim_zero_no_separator,
rtrim_separator => rtrim_separator_no_separator,
new => fn new(format: NumberFormat) -> Self {
Self {
integer: &[],
fraction: None,
exponent: None,
raw_exponent: 0
}
}
);
type DataTuple<'a> = (&'a [u8], Option<&'a [u8]>, Option<&'a [u8]>, i32);
impl<'a> From<DataTuple<'a>> for StandardFastDataInterface<'a> {
perftools_inline!{
fn from(data: DataTuple<'a>) -> Self {
StandardFastDataInterface {
integer: data.0,
fraction: data.1,
exponent: data.2,
raw_exponent: data.3
}
}}
}
#[cfg(test)]
mod tests {
use super::*;
macro_rules! standard {
($integer:expr, $fraction:expr, $exponent:expr, $raw_exponent:expr) => {
StandardFastDataInterface {
integer: $integer,
fraction: $fraction,
exponent: $exponent,
raw_exponent: $raw_exponent
}
};
}
#[test]
fn extract_test() {
StandardFastDataInterface::new(NumberFormat::standard().unwrap()).run_tests([
("1.2345", Ok(standard!(b"1", Some(b!("2345")), None, 0))),
("12.345", Ok(standard!(b"12", Some(b!("345")), None, 0))),
("12345.6789", Ok(standard!(b"12345", Some(b!("6789")), None, 0))),
("1.2345e10", Ok(standard!(b"1", Some(b!("2345")), Some(b!("10")), 10))),
("1.2345e+10", Ok(standard!(b"1", Some(b!("2345")), Some(b!("+10")), 10))),
("1.2345e-10", Ok(standard!(b"1", Some(b!("2345")), Some(b!("-10")), -10))),
("100000000000000000000", Ok(standard!(b"100000000000000000000", None, None, 0))),
("100000000000000000001", Ok(standard!(b"100000000000000000001", None, None, 0))),
("179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791.9999999999999999999999999999999999999999999999999999999999999999999999", Ok(standard!(b"179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791", Some(b!("9999999999999999999999999999999999999999999999999999999999999999999999")), None, 0))),
("1009e-31", Ok(standard!(b"1009", None, Some(b!("-31")), -31))),
("001.0", Ok(standard!(b"1", Some(b!("")), None, 0))),
("1.", Ok(standard!(b"1", Some(b!("")), None, 0))),
("12.", Ok(standard!(b"12", Some(b!("")), None, 0))),
("1234567.", Ok(standard!(b"1234567", Some(b!("")), None, 0))),
(".1", Ok(standard!(b"", Some(b!("1")), None, 0))),
(".12", Ok(standard!(b"", Some(b!("12")), None, 0))),
(".1234567", Ok(standard!(b"", Some(b!("1234567")), None, 0))),
("1.2345e", Err(ErrorCode::EmptyExponent)),
("", Err(ErrorCode::EmptyMantissa)),
("+", Err(ErrorCode::EmptyMantissa)),
("-", Err(ErrorCode::EmptyMantissa)),
(".", Err(ErrorCode::EmptyMantissa)),
("+.", Err(ErrorCode::EmptyMantissa)),
("-.", Err(ErrorCode::EmptyMantissa)),
("e", Err(ErrorCode::EmptyMantissa)),
("E", Err(ErrorCode::EmptyMantissa)),
("e1", Err(ErrorCode::EmptyMantissa)),
("e+1", Err(ErrorCode::EmptyMantissa)),
("e-1", Err(ErrorCode::EmptyMantissa)),
(".e", Err(ErrorCode::EmptyMantissa)),
(".E", Err(ErrorCode::EmptyMantissa)),
(".e1", Err(ErrorCode::EmptyMantissa)),
(".e+1", Err(ErrorCode::EmptyMantissa)),
(".e-1", Err(ErrorCode::EmptyMantissa)),
(".3e", Err(ErrorCode::EmptyExponent))
].iter());
}
#[test]
fn fast_data_interface_test() {
type Data<'a> = StandardFastDataInterface<'a>;
let data = Data {
integer: b"1",
fraction: Some(b!("2345")),
exponent: None,
raw_exponent: 0
};
assert!(data.integer_iter().eq(b"1".iter()));
assert!(data.fraction_iter().eq(b"2345".iter()));
#[cfg(feature = "correct")]
assert_eq!(data.digits_start(), 0);
}
#[cfg(feature = "correct")]
#[test]
fn slow_data_interface_test() {
type Data<'a> = StandardSlowDataInterface<'a>;
let data = Data {
integer: b"1",
fraction: b"2345",
digits_start: 0,
truncated_digits: 0,
raw_exponent: 0
};
assert_eq!(data.integer_digits(), 1);
assert!(data.integer_iter().eq(b"1".iter()));
assert_eq!(data.fraction_digits(), 4);
assert!(data.fraction_iter().eq(b"2345".iter()));
assert_eq!(data.significant_fraction_digits(), 4);
assert!(data.significant_fraction_iter().eq(b"2345".iter()));
assert_eq!(data.mantissa_digits(), 5);
assert_eq!(data.digits_start(), 0);
assert_eq!(data.truncated_digits(), 0);
assert_eq!(data.raw_exponent(), 0);
assert_eq!(data.mantissa_exponent(), -4);
assert_eq!(data.scientific_exponent(), 0);
let data = Data {
integer: b"",
fraction: b"12345",
digits_start: 0,
truncated_digits: 0,
raw_exponent: 0
};
assert_eq!(data.integer_digits(), 0);
assert!(data.integer_iter().eq(b"".iter()));
assert_eq!(data.fraction_digits(), 5);
assert!(data.fraction_iter().eq(b"12345".iter()));
assert_eq!(data.significant_fraction_digits(), 5);
assert!(data.significant_fraction_iter().eq(b"12345".iter()));
assert_eq!(data.mantissa_digits(), 5);
assert_eq!(data.digits_start(), 0);
assert_eq!(data.truncated_digits(), 0);
assert_eq!(data.raw_exponent(), 0);
assert_eq!(data.mantissa_exponent(), -5);
assert_eq!(data.scientific_exponent(), -1);
}
}