| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#include "from_chars.h" |
|
2
|
|
|
|
|
|
|
#include // isspace |
|
3
|
|
|
|
|
|
|
#include // memcpy |
|
4
|
|
|
|
|
|
|
#include |
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
namespace panda { |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
static unsigned _index[256]; |
|
9
|
|
|
|
|
|
|
static char _rindex[36]; |
|
10
|
|
|
|
|
|
|
|
|
11
|
18
|
|
|
|
|
|
static bool _init () { |
|
12
|
4626
|
100
|
|
|
|
|
for (auto& val : _index) val = 255; |
|
13
|
198
|
100
|
|
|
|
|
for (int i = 0; i <= 9; ++i) _index['0' + i] = i; |
|
14
|
486
|
100
|
|
|
|
|
for (int i = 0; i <= 25; ++i) _index['a' + i] = i+10; |
|
15
|
486
|
100
|
|
|
|
|
for (int i = 0; i <= 25; ++i) _index['A' + i] = i+10; |
|
16
|
198
|
100
|
|
|
|
|
for (int i = 0; i <= 9; ++i) _rindex[i] = '0' + i; |
|
17
|
486
|
100
|
|
|
|
|
for (int i = 0; i <= 25; ++i) _rindex[i + 10] = 'a' + i; |
|
18
|
18
|
|
|
|
|
|
return true; |
|
19
|
|
|
|
|
|
|
} |
|
20
|
18
|
|
|
|
|
|
static const bool _inited = _init(); |
|
21
|
|
|
|
|
|
|
|
|
22
|
1158
|
|
|
|
|
|
static inline bool _is_space (unsigned char ch) { return std::isspace(ch); } |
|
23
|
|
|
|
|
|
|
//static inline bool _is_space (unsigned wchar_t ch) { return std::iswspace(ch); } |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
template |
|
26
|
|
|
|
|
|
|
static inline bool _find_sign (const C*& ptr, const C* const end) { |
|
27
|
|
|
|
|
|
|
if (ptr == end) return false; |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
bool minus = false; |
|
30
|
|
|
|
|
|
|
if (*ptr == '-') { ++ptr; minus = true; } |
|
31
|
|
|
|
|
|
|
else if (*ptr == '+') ++ptr; |
|
32
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
return minus; |
|
34
|
|
|
|
|
|
|
} |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
template |
|
37
|
423
|
|
|
|
|
|
static inline UT _parse (const UC*& ptr, const UC* const end, unsigned base, UT max, bool& overflow) { |
|
38
|
423
|
|
|
|
|
|
UT res = 0; |
|
39
|
423
|
|
|
|
|
|
UT maxmp = max / base; |
|
40
|
423
|
|
|
|
|
|
overflow = false; |
|
41
|
|
|
|
|
|
|
|
|
42
|
2509
|
0
|
|
|
|
|
for (; ptr != end; ++ptr) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
if (sizeof(UC) > 1 && *ptr > 255) break; |
|
44
|
2192
|
|
|
|
|
|
auto val = _index[*ptr]; |
|
45
|
2192
|
0
|
|
|
|
|
if (val >= base) break; |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
46
|
2118
|
0
|
|
|
|
|
if (res > maxmp) { overflow = true; res = max; break; } |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
47
|
2102
|
|
|
|
|
|
res *= base; |
|
48
|
2102
|
0
|
|
|
|
|
if (val > (UT)(max - res)) { overflow = true; res = max; break; } |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
49
|
2086
|
|
|
|
|
|
res += val; |
|
50
|
|
|
|
|
|
|
} |
|
51
|
|
|
|
|
|
|
|
|
52
|
1250
|
0
|
|
|
|
|
if (overflow) for (; ptr != end; ++ptr) if ((sizeof(UC) > 1 && *ptr > 255) || _index[*ptr] >= base) break; // move to the end of the number |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
|
|
54
|
423
|
|
|
|
|
|
return res; |
|
55
|
|
|
|
|
|
|
} |
|
56
|
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
template |
|
58
|
299
|
|
|
|
|
|
static inline typename std::enable_if::value, from_chars_result>::type _from_chars (const C* s, const C* send, UT& value, unsigned base) { |
|
59
|
|
|
|
|
|
|
using UC = typename std::make_unsigned::type; |
|
60
|
299
|
|
|
|
|
|
const UC* ptr = (const UC*)s; |
|
61
|
299
|
|
|
|
|
|
const UC* const end = (const UC*)send; |
|
62
|
299
|
0
|
|
|
|
|
if (base < 2 || base > 36) base = 10; |
|
|
|
0
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
|
|
64
|
355
|
0
|
|
|
|
|
while (ptr != end && _is_space(*ptr)) ++ptr; // skip whitespaces in the beginning |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
bool overflow; |
|
67
|
299
|
|
|
|
|
|
auto tmp = ptr; |
|
68
|
299
|
|
|
|
|
|
value = _parse(ptr, end, base, std::numeric_limits::max(), overflow); |
|
69
|
|
|
|
|
|
|
|
|
70
|
299
|
0
|
|
|
|
|
if (ptr - tmp == 0) return {s, make_error_code(std::errc::invalid_argument)}; |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
71
|
274
|
0
|
|
|
|
|
if (overflow) return {(const C*)ptr, make_error_code(std::errc::result_out_of_range)}; |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
72
|
299
|
|
|
|
|
|
return {(const C*)ptr, std::error_code()}; |
|
73
|
|
|
|
|
|
|
} |
|
74
|
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
template |
|
76
|
124
|
|
|
|
|
|
static inline typename std::enable_if::value, from_chars_result>::type _from_chars (const C* s, const C* send, T& value, unsigned base) { |
|
77
|
|
|
|
|
|
|
using UC = typename std::make_unsigned::type; |
|
78
|
|
|
|
|
|
|
using UT = typename std::make_unsigned::type; |
|
79
|
124
|
|
|
|
|
|
const UC* ptr = (const UC*)s; |
|
80
|
124
|
|
|
|
|
|
const UC* const end = (const UC*)send; |
|
81
|
124
|
0
|
|
|
|
|
if (base < 2 || base > 36) base = 10; |
|
|
|
0
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
|
|
83
|
232
|
0
|
|
|
|
|
while (ptr != end && _is_space(*ptr)) ++ptr; // skip whitespaces in the beginning |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
|
|
85
|
124
|
|
|
|
|
|
bool minus = false; |
|
86
|
124
|
0
|
|
|
|
|
if (ptr != end && *ptr == '-') { ++ptr; minus = true; } |
|
|
|
0
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
bool overflow; |
|
88
|
124
|
|
|
|
|
|
auto tmp = ptr; |
|
89
|
|
|
|
|
|
|
|
|
90
|
124
|
0
|
|
|
|
|
if (minus) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
91
|
48
|
|
|
|
|
|
UT max = (UT)std::numeric_limits::max() - (T)(std::numeric_limits::max() + std::numeric_limits::min()); |
|
92
|
48
|
|
|
|
|
|
UT tmp = _parse(ptr, end, base, max, overflow); |
|
93
|
48
|
|
|
|
|
|
value = (T)0 - tmp; |
|
94
|
|
|
|
|
|
|
} else { |
|
95
|
76
|
|
|
|
|
|
value = _parse(ptr, end, base, (UT)std::numeric_limits::max(), overflow); |
|
96
|
|
|
|
|
|
|
} |
|
97
|
|
|
|
|
|
|
|
|
98
|
124
|
0
|
|
|
|
|
if (ptr - tmp == 0) return {s, make_error_code(std::errc::invalid_argument)}; |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
99
|
108
|
0
|
|
|
|
|
if (overflow) return {(const C*)ptr, make_error_code(std::errc::result_out_of_range)}; |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
100
|
124
|
|
|
|
|
|
return {(const C*)ptr, std::error_code()}; |
|
101
|
|
|
|
|
|
|
} |
|
102
|
|
|
|
|
|
|
|
|
103
|
62
|
|
|
|
|
|
from_chars_result from_chars (const char* first, const char* last, int8_t& value, int base) { return _from_chars (first, last, value, base); } |
|
104
|
62
|
|
|
|
|
|
from_chars_result from_chars (const char* first, const char* last, int16_t& value, int base) { return _from_chars (first, last, value, base); } |
|
105
|
62
|
|
|
|
|
|
from_chars_result from_chars (const char* first, const char* last, int& value, int base) { return _from_chars (first, last, value, base); } |
|
106
|
62
|
|
|
|
|
|
from_chars_result from_chars (const char* first, const char* last, long& value, int base) { return _from_chars (first, last, value, base); } |
|
107
|
0
|
|
|
|
|
|
from_chars_result from_chars (const char* first, const char* last, long long& value, int base) { return _from_chars (first, last, value, base); } |
|
108
|
46
|
|
|
|
|
|
from_chars_result from_chars (const char* first, const char* last, uint8_t& value, int base) { return _from_chars (first, last, value, base); } |
|
109
|
46
|
|
|
|
|
|
from_chars_result from_chars (const char* first, const char* last, uint16_t& value, int base) { return _from_chars (first, last, value, base); } |
|
110
|
46
|
|
|
|
|
|
from_chars_result from_chars (const char* first, const char* last, unsigned& value, int base) { return _from_chars (first, last, value, base); } |
|
111
|
460
|
|
|
|
|
|
from_chars_result from_chars (const char* first, const char* last, unsigned long& value, int base) { return _from_chars (first, last, value, base); } |
|
112
|
0
|
|
|
|
|
|
from_chars_result from_chars (const char* first, const char* last, unsigned long long& value, int base) { return _from_chars(first, last, value, base); } |
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
template |
|
115
|
51
|
|
|
|
|
|
static inline C* _compile (C* ptr, UT value, int base) { |
|
116
|
152
|
0
|
|
|
|
|
do { |
|
|
|
0
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
117
|
152
|
|
|
|
|
|
*--ptr = _rindex[value % base]; |
|
118
|
152
|
|
|
|
|
|
value /= base; |
|
119
|
|
|
|
|
|
|
} while (value != 0); |
|
120
|
51
|
|
|
|
|
|
return ptr; |
|
121
|
|
|
|
|
|
|
} |
|
122
|
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
template |
|
124
|
24
|
|
|
|
|
|
static inline typename std::enable_if::value, to_chars_result>::type _to_chars (C* d, C* dend, UT value, int base) { |
|
125
|
24
|
0
|
|
|
|
|
if (base < 2 || base > 36) base = 10; |
|
|
|
0
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
126
|
24
|
|
|
|
|
|
int maxsize = std::ceil(std::numeric_limits::digits * std::log(2) / std::log(base)); /* enough for UT-bit integer represented in given base */ |
|
127
|
24
|
|
|
|
|
|
char strval[maxsize]; |
|
128
|
24
|
|
|
|
|
|
char* end = strval + maxsize; |
|
129
|
24
|
|
|
|
|
|
char* begin = _compile(end, value, base); |
|
130
|
24
|
|
|
|
|
|
auto len = end - begin; |
|
131
|
24
|
0
|
|
|
|
|
if (dend - d < len) return {dend, make_error_code(std::errc::value_too_large)}; |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
132
|
20
|
|
|
|
|
|
std::memcpy(d, begin, len); |
|
133
|
24
|
|
|
|
|
|
return {d + len, std::error_code()}; |
|
134
|
|
|
|
|
|
|
} |
|
135
|
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
template |
|
137
|
27
|
|
|
|
|
|
static inline typename std::enable_if::value, to_chars_result>::type _to_chars (C* d, C* dend, T value, int base) { |
|
138
|
|
|
|
|
|
|
using UT = typename std::make_unsigned::type; |
|
139
|
27
|
0
|
|
|
|
|
if (base < 2 || base > 36) base = 10; |
|
|
|
0
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
140
|
27
|
|
|
|
|
|
int maxsize = std::ceil(std::numeric_limits::digits * std::log(2) / std::log(base) + 1); |
|
141
|
27
|
|
|
|
|
|
char strval[maxsize]; |
|
142
|
27
|
|
|
|
|
|
char* end = strval + maxsize; |
|
143
|
|
|
|
|
|
|
char* begin; |
|
144
|
|
|
|
|
|
|
|
|
145
|
27
|
0
|
|
|
|
|
if (value >= 0) begin = _compile(end, value, base); |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
else { |
|
147
|
0
|
|
|
|
|
|
UT positive_value = (UT)std::numeric_limits::max() - (T)(std::numeric_limits::max() + value); |
|
148
|
0
|
|
|
|
|
|
begin = _compile(end, positive_value, base); |
|
149
|
0
|
|
|
|
|
|
*--begin = '-'; |
|
150
|
|
|
|
|
|
|
} |
|
151
|
|
|
|
|
|
|
|
|
152
|
27
|
|
|
|
|
|
auto len = end - begin; |
|
153
|
27
|
0
|
|
|
|
|
if (dend - d < len) return {dend, make_error_code(std::errc::value_too_large)}; |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
154
|
23
|
|
|
|
|
|
std::memcpy(d, begin, len); |
|
155
|
27
|
|
|
|
|
|
return {d + len, std::error_code()}; |
|
156
|
|
|
|
|
|
|
} |
|
157
|
|
|
|
|
|
|
|
|
158
|
12
|
|
|
|
|
|
to_chars_result to_chars (char* first, char* last, int8_t value, int base) { return _to_chars (first, last, value, base); } |
|
159
|
12
|
|
|
|
|
|
to_chars_result to_chars (char* first, char* last, int16_t value, int base) { return _to_chars (first, last, value, base); } |
|
160
|
18
|
|
|
|
|
|
to_chars_result to_chars (char* first, char* last, int value, int base) { return _to_chars (first, last, value, base); } |
|
161
|
12
|
|
|
|
|
|
to_chars_result to_chars (char* first, char* last, long value, int base) { return _to_chars (first, last, value, base); } |
|
162
|
0
|
|
|
|
|
|
to_chars_result to_chars (char* first, char* last, long long value, int base) { return _to_chars (first, last, value, base); } |
|
163
|
12
|
|
|
|
|
|
to_chars_result to_chars (char* first, char* last, uint8_t value, int base) { return _to_chars (first, last, value, base); } |
|
164
|
12
|
|
|
|
|
|
to_chars_result to_chars (char* first, char* last, uint16_t value, int base) { return _to_chars(first, last, value, base); } |
|
165
|
12
|
|
|
|
|
|
to_chars_result to_chars (char* first, char* last, unsigned value, int base) { return _to_chars(first, last, value, base); } |
|
166
|
12
|
|
|
|
|
|
to_chars_result to_chars (char* first, char* last, unsigned long value, int base) { return _to_chars(first, last, value, base); } |
|
167
|
0
|
|
|
|
|
|
to_chars_result to_chars (char* first, char* last, unsigned long long value, int base) { return _to_chars(first, last, value, base); } |
|
168
|
|
|
|
|
|
|
|
|
169
|
72
|
50
|
|
|
|
|
} |
|
|
|
50
|
|
|
|
|
|