Merge lp:~paul-lucas/zorba/pjl-misc into lp:zorba
- pjl-misc
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Matthias Brantner |
Approved revision: | 11180 |
Merged at revision: | 11376 |
Proposed branch: | lp:~paul-lucas/zorba/pjl-misc |
Merge into: | lp:zorba |
Diff against target: |
770 lines (+469/-143) 6 files modified
src/unit_tests/CMakeLists.txt (+1/-0) src/unit_tests/test_ato_.cpp (+106/-0) src/unit_tests/unit_test_list.h (+1/-0) src/unit_tests/unit_tests.cpp (+1/-0) src/util/string_util.cpp (+55/-9) src/util/string_util.h (+305/-134) |
To merge this branch: | bzr merge lp:~paul-lucas/zorba/pjl-misc |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Matthias Brantner | Approve | ||
Paul J. Lucas | Approve | ||
Review via email: mp+159064@code.launchpad.net |
Commit message
1. Added atoll( char const *buf, char const *end, char const **last );
2. Added more aton() functions.
3. Fixed handling of integer overflow.
Description of the change
1. Added atoll( char const *buf, char const *end, char const **last );
2. Added more aton() functions.
3. Fixed handling of integer overflow.
Paul J. Lucas (paul-lucas) : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~paul-lucas/zorba/pjl-misc into lp:zorba failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job pjl-misc-
final status was:
4 tests did not succeed - changes not commited.
Error in read script: /home/ceej/
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue job pjl-misc-
All tests succeeded!
Zorba Build Bot (zorba-buildbot) wrote : | # |
Voting does not meet specified criteria. Required: Approve > 1, Disapprove < 1, Needs Fixing < 1, Pending < 1, Needs Information < 1, Resubmit < 1. Got: 1 Approve.
- 11178. By Paul J. Lucas
-
Added test.
- 11179. By Paul J. Lucas
-
Merge from trunk.
- 11180. By Paul J. Lucas
-
Removed unnecessary #include.
Matthias Brantner (matthias-brantner) : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue job pjl-misc-
All tests succeeded!
Preview Diff
1 | === modified file 'src/unit_tests/CMakeLists.txt' |
2 | --- src/unit_tests/CMakeLists.txt 2013-03-21 00:54:36 +0000 |
3 | +++ src/unit_tests/CMakeLists.txt 2013-04-16 18:41:25 +0000 |
4 | @@ -14,6 +14,7 @@ |
5 | |
6 | SET(UNIT_TEST_SRCS |
7 | instantiate_string.cpp |
8 | + test_ato_.cpp |
9 | test_base64.cpp |
10 | test_base64_streambuf.cpp |
11 | test_hashmaps.cpp |
12 | |
13 | === added file 'src/unit_tests/test_ato_.cpp' |
14 | --- src/unit_tests/test_ato_.cpp 1970-01-01 00:00:00 +0000 |
15 | +++ src/unit_tests/test_ato_.cpp 2013-04-16 18:41:25 +0000 |
16 | @@ -0,0 +1,106 @@ |
17 | +/* |
18 | + * Copyright 2006-2008 The FLWOR Foundation. |
19 | + * |
20 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
21 | + * you may not use this file except in compliance with the License. |
22 | + * You may obtain a copy of the License at |
23 | + * |
24 | + * http://www.apache.org/licenses/LICENSE-2.0 |
25 | + * |
26 | + * Unless required by applicable law or agreed to in writing, software |
27 | + * distributed under the License is distributed on an "AS IS" BASIS, |
28 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
29 | + * See the License for the specific language governing permissions and |
30 | + * limitations under the License. |
31 | + */ |
32 | + |
33 | +#include "stdafx.h" |
34 | +#include <iostream> |
35 | +#include <stdexcept> |
36 | +#include <string> |
37 | + |
38 | +#include "util/cxx_util.h" |
39 | +#include "util/string_util.h" |
40 | + |
41 | +using namespace std; |
42 | +using namespace zorba; |
43 | + |
44 | +/////////////////////////////////////////////////////////////////////////////// |
45 | + |
46 | +static int failures; |
47 | + |
48 | +static bool assert_true( int no, char const *expr, int line, bool result ) { |
49 | + if ( !result ) { |
50 | + cout << '#' << no << " FAILED, line " << line << ": " << expr << endl; |
51 | + ++failures; |
52 | + } |
53 | + return result; |
54 | +} |
55 | + |
56 | +static void print_exception( int no, char const *expr, int line, |
57 | + std::exception const &e ) { |
58 | + assert_true( no, expr, line, false ); |
59 | + cout << "+ exception: " << e.what() << endl; |
60 | +} |
61 | + |
62 | +#define ASSERT_TRUE( NO, EXPR ) assert_true( NO, #EXPR, __LINE__, !!(EXPR) ) |
63 | + |
64 | +#define ASSERT_NO_EXCEPTION( NO, EXPR ) \ |
65 | + try { EXPR; } \ |
66 | + catch ( exception const &e ) { print_exception( NO, #EXPR, __LINE__, e ); } \ |
67 | + catch ( ... ) { assert_true( NO, #EXPR, __LINE__, false ); } |
68 | + |
69 | +#define ASSERT_EXCEPTION( NO, EXPR, EXCEPTION ) \ |
70 | + try { EXPR; assert_true( NO, #EXPR, __LINE__, false ); } \ |
71 | + catch ( EXCEPTION const& ) { } \ |
72 | + catch ( ... ) { assert_true( NO, #EXPR, __LINE__, false ); } |
73 | + |
74 | +///////////////////////////////////////////////////////////////////////////////} |
75 | + |
76 | +static void test_atoll( int no, string const &s ) { |
77 | + char const *last; |
78 | + ASSERT_EXCEPTION( |
79 | + no, ztd::atoll( s.data(), s.data() + s.size(), &last ), range_error |
80 | + ); |
81 | +} |
82 | + |
83 | +static void test_atoull( int no, string const &s ) { |
84 | + char const *last; |
85 | + ASSERT_EXCEPTION( |
86 | + no, ztd::atoull( s.data(), s.data() + s.size(), &last ), range_error |
87 | + ); |
88 | +} |
89 | + |
90 | +/////////////////////////////////////////////////////////////////////////////// |
91 | + |
92 | +namespace zorba { |
93 | +namespace UnitTests { |
94 | + |
95 | +int test_ato_( int, char*[] ) { |
96 | + ascii::itoa_buf_type buf; |
97 | + string s; |
98 | + int test_no = 0; |
99 | + |
100 | + // test overflow |
101 | + s = ascii::itoa( numeric_limits<long long>::max(), buf ); |
102 | + s += '0'; |
103 | + test_atoll( test_no++, s ); |
104 | + |
105 | + // test underflow |
106 | + s = ascii::itoa( numeric_limits<long long>::min(), buf ); |
107 | + s += '0'; |
108 | + test_atoll( test_no++, s ); |
109 | + |
110 | + // test overflow |
111 | + s = ascii::itoa( numeric_limits<unsigned long long>::max(), buf ); |
112 | + s += '0'; |
113 | + test_atoull( test_no++, s ); |
114 | + |
115 | + cout << failures << " test(s) failed\n"; |
116 | + return failures ? 1 : 0; |
117 | +} |
118 | + |
119 | +} // namespace UnitTests |
120 | +} // namespace zorba |
121 | + |
122 | +/* vim:set et sw=2 ts=2: */ |
123 | |
124 | === modified file 'src/unit_tests/unit_test_list.h' |
125 | --- src/unit_tests/unit_test_list.h 2013-03-21 00:54:36 +0000 |
126 | +++ src/unit_tests/unit_test_list.h 2013-04-16 18:41:25 +0000 |
127 | @@ -28,6 +28,7 @@ |
128 | |
129 | int runDebuggerProtocolTest(int argc, char* argv[]); |
130 | |
131 | + int test_ato_( int, char*[] ); |
132 | int test_base64( int, char*[] ); |
133 | int test_base64_streambuf( int, char*[] ); |
134 | int test_hashmaps( int argc, char* argv[] ); |
135 | |
136 | === modified file 'src/unit_tests/unit_tests.cpp' |
137 | --- src/unit_tests/unit_tests.cpp 2013-03-21 00:54:36 +0000 |
138 | +++ src/unit_tests/unit_tests.cpp 2013-04-16 18:41:25 +0000 |
139 | @@ -37,6 +37,7 @@ |
140 | */ |
141 | void initializeTestList() |
142 | { |
143 | + libunittests["ato"] = test_ato_; |
144 | libunittests["base64"] = test_base64; |
145 | libunittests["base64_streambuf"] = test_base64_streambuf; |
146 | |
147 | |
148 | === modified file 'src/util/string_util.cpp' |
149 | --- src/util/string_util.cpp 2013-03-31 15:53:11 +0000 |
150 | +++ src/util/string_util.cpp 2013-04-16 18:41:25 +0000 |
151 | @@ -56,14 +56,15 @@ |
152 | |
153 | /////////////////////////////////////////////////////////////////////////////// |
154 | |
155 | -static void too_big_or_small( char const *buf, char const *last ) { |
156 | +static void throw_range_error( char const *buf, char const *last ) { |
157 | + errno = ERANGE; |
158 | zstring const s( buf, last ); |
159 | throw std::range_error( BUILD_STRING( '"', s, "\": number too big/small" ) ); |
160 | } |
161 | |
162 | inline void check_errno( char const *buf, char const *last ) { |
163 | if ( errno == ERANGE ) |
164 | - too_big_or_small( buf, last ); |
165 | + throw_range_error( buf, last ); |
166 | } |
167 | |
168 | static void check_trailing_chars_impl( char const *last ) { |
169 | @@ -149,20 +150,65 @@ |
170 | return result; |
171 | } |
172 | |
173 | +long long atoll( char const *buf, char const *end, char const **last ) { |
174 | + aton_context const ctx( last ); |
175 | + long long n = 0; |
176 | + char const *s0 = ascii::trim_start_whitespace( buf, end - buf ); |
177 | + char const *s = s0; |
178 | + |
179 | + if ( s < end ) { |
180 | + bool minus = false; |
181 | + switch ( *s ) { |
182 | + case '-': |
183 | + minus = true; |
184 | + // no break; |
185 | + case '+': |
186 | + s0 = ++s; |
187 | + break; |
188 | + } |
189 | + for ( ; s < end && ascii::is_digit( *s ); ++s ) { |
190 | + long long const n_prev = n; |
191 | + n *= 10; |
192 | + if ( n / 10 != n_prev ) // see <http://stackoverflow.com/q/199333/99089> |
193 | + throw_range_error( buf, end ); |
194 | + n += *s - '0'; |
195 | + if ( n < n_prev ) |
196 | + throw_range_error( buf, end ); |
197 | + } |
198 | + if ( s == s0 ) |
199 | + s = buf; |
200 | + else if ( minus ) |
201 | + n = -n; |
202 | + } |
203 | + |
204 | + *last = s; |
205 | + check_parse_number( buf, *last, ctx.check_trailing_chars() ); |
206 | + return n; |
207 | +} |
208 | + |
209 | unsigned long long atoull( char const *buf, char const *end, |
210 | char const **last ) { |
211 | aton_context const ctx( last ); |
212 | unsigned long long n = 0; |
213 | - char const *s = ascii::trim_start_whitespace( buf, end - buf ); |
214 | + char const *s0 = ascii::trim_start_whitespace( buf, end - buf ); |
215 | + char const *s = s0; |
216 | |
217 | - for ( ; s < end && ascii::is_digit( *s ); ++s ) { |
218 | - unsigned long long const n_prev = n; |
219 | - n = n * 10 + *s - '0'; |
220 | - if ( n < n_prev ) { |
221 | - errno = ERANGE; |
222 | - too_big_or_small( buf, end ); |
223 | + if ( s < end ) { |
224 | + if ( *s == '+' ) |
225 | + s0 = ++s; |
226 | + for ( ; s < end && ascii::is_digit( *s ); ++s ) { |
227 | + unsigned long long const n_prev = n; |
228 | + n *= 10; |
229 | + if ( n / 10 != n_prev ) // see <http://stackoverflow.com/q/199333/99089> |
230 | + throw_range_error( buf, end ); |
231 | + n += *s - '0'; |
232 | + if ( n < n_prev ) |
233 | + throw_range_error( buf, end ); |
234 | } |
235 | + if ( s == s0 ) |
236 | + s = buf; |
237 | } |
238 | + |
239 | *last = s; |
240 | check_parse_number( buf, *last, ctx.check_trailing_chars() ); |
241 | return n; |
242 | |
243 | === modified file 'src/util/string_util.h' |
244 | --- src/util/string_util.h 2013-03-26 00:25:41 +0000 |
245 | +++ src/util/string_util.h 2013-04-16 18:41:25 +0000 |
246 | @@ -414,13 +414,17 @@ |
247 | * Parses the given string for a \c double. |
248 | * |
249 | * @param buf The null-terminated C string to parse. Leading and trailing |
250 | - * whitespace is ignored. |
251 | + * whitespace is ignored. After any leading whitespace, there may be a \c + or |
252 | + * \c - sign, followed by a sequence of decimal digits optionally containing a |
253 | + * single single \c . (decimal-point), optionally followed by an exponent |
254 | + * consisting of an \c e or \c E followed by an optional \c + or \c - sign |
255 | + * followed by a sequence of decimal digits. |
256 | * @param last If not \c null, this is set to point to the character after the |
257 | * last numeric character parsed; if \c null, characters past the last numeric |
258 | * character may only be whitespace. |
259 | * @return Returns the \c double value. |
260 | - * @throws invalid_argument if \a buf contains characters other than digits or |
261 | - * leading/trailing whitespace, or contains no digits at all. |
262 | + * @throws invalid_argument if \a buf contains characters other than as |
263 | + * described or contains no digits at all. |
264 | * @throws range_error if the number overflows/underflows. |
265 | */ |
266 | double atod( char const *buf, char const **last = nullptr ); |
267 | @@ -429,13 +433,17 @@ |
268 | * Parses the given string for a \c float. |
269 | * |
270 | * @param buf The null-terminated C string to parse. Leading and trailing |
271 | - * whitespace is ignored. |
272 | + * whitespace is ignored. After any leading whitespace, there may be a \c + or |
273 | + * \c - sign, followed by a sequence of decimal digits optionally containing a |
274 | + * single single \c . (decimal-point), optionally followed by an exponent |
275 | + * consisting of an \c e or \c E followed by an optional \c + or \c - sign |
276 | + * followed by a sequence of decimal digits. |
277 | * @param last If not \c null, this is set to point to the character after the |
278 | * last numeric character parsed; if \c null, characters past the last numeric |
279 | * character may only be whitespace. |
280 | * @return Returns the \c float value. |
281 | - * @throws invalid_argument if \a buf contains characters other than digits or |
282 | - * leading/trailing whitespace, or contains no digits at all. |
283 | + * @throws invalid_argument if \a buf contains characters other than as |
284 | + * described or contains no digits at all. |
285 | * @throws range_error if the number overflows/underflows. |
286 | */ |
287 | float atof( char const *buf, char const **last = nullptr ); |
288 | @@ -444,28 +452,47 @@ |
289 | * Parses the given string for a <code>long long</code>. |
290 | * |
291 | * @param buf The null-terminated C string to parse. Leading and trailing |
292 | - * whitespace is ignored. |
293 | + * whitespace is ignored. After any leading whitespace, there may be a \c + or |
294 | + * \c - sign, followed by a sequence of decimal digits. |
295 | * @param last If not \c null, this is set to point to the character after the |
296 | * last numeric character parsed; if \c null, characters past the last numeric |
297 | * character may only be whitespace. |
298 | * @return Returns the <code>long long</code> value. |
299 | - * @throws invalid_argument if \a buf contains characters other than digits or |
300 | - * leading/trailing whitespace, or contains no digits at all. |
301 | + * @throws invalid_argument if \a buf contains characters other than as |
302 | + * described or contains no digits at all. |
303 | * @throws range_error if the number overflows/underflows. |
304 | */ |
305 | long long atoll( char const *buf, char const **last = nullptr ); |
306 | |
307 | /** |
308 | + * Parses the given string for a <code>long long</code>. |
309 | + * |
310 | + * @param buf The C string to parse; it need not be null-terminated. Leading |
311 | + * and trailing whitespace is ignored. After any leading whitespace, there may |
312 | + * be a \c + or \c - sign, followed by a sequence of decimal digits. |
313 | + * @param end A pointer to one past the last character to parse. |
314 | + * @param last If not \c null, this is set to point to the character after the |
315 | + * last numeric character parsed; if \c null, characters past the last numeric |
316 | + * character may only be whitespace. |
317 | + * @return Returns the <code>long long</code> value. |
318 | + * @throws invalid_argument if \a buf contains characters other than as |
319 | + * described or contains no digits at all. |
320 | + * @throws range_error if the number overflows. |
321 | + */ |
322 | +long long atoll( char const *buf, char const *end, char const **last ); |
323 | + |
324 | +/** |
325 | * Parses the given string for an <code>unsigned long long</code>. |
326 | * |
327 | * @param buf The null-terminated C string to parse. Leading and trailing |
328 | - * whitespace is ignored. |
329 | + * whitespace is ignored. After any leading whitespace, there may be a \c + |
330 | + * sign, followed by a sequence of decimal digits. |
331 | * @param last If not \c null, this is set to point to the character after the |
332 | * last numeric character parsed; if \c null, characters past the last numeric |
333 | * character may only be whitespace. |
334 | * @return Returns the <code>unsigned long long</code> value. |
335 | - * @throws invalid_argument if \a buf contains characters other than digits or |
336 | - * leading/trailing whitespace, or contains no digits at all. |
337 | + * @throws invalid_argument if \a buf contains characters other than as |
338 | + * described or contains no digits at all. |
339 | * @throws range_error if the number overflows. |
340 | */ |
341 | unsigned long long atoull( char const *buf, char const **last = nullptr ); |
342 | @@ -474,14 +501,15 @@ |
343 | * Parses the given string for an <code>unsigned long long</code>. |
344 | * |
345 | * @param buf The C string to parse; it need not be null-terminated. Leading |
346 | - * and trailing whitespace is ignored. |
347 | + * and trailing whitespace is ignored. After any leading whitespace, there may |
348 | + * be a \c + sign, followed by a sequence of decimal digits. |
349 | * @param end A pointer to one past the last character to parse. |
350 | * @param last If not \c null, this is set to point to the character after the |
351 | * last numeric character parsed; if \c null, characters past the last numeric |
352 | * character may only be whitespace. |
353 | * @return Returns the <code>unsigned long long</code> value. |
354 | - * @throws invalid_argument if \a buf contains characters other than digits or |
355 | - * leading/trailing whitespace, or contains no digits at all. |
356 | + * @throws invalid_argument if \a buf contains characters other than as |
357 | + * described or contains no digits at all. |
358 | * @throws range_error if the number overflows. |
359 | */ |
360 | unsigned long long atoull( char const *buf, char const *end, |
361 | @@ -492,117 +520,254 @@ |
362 | * |
363 | * @tparam IntegralType The C++ signed integral type to parse for. |
364 | * @param buf The null-terminated C string to parse. Leading and trailing |
365 | - * whitespace is ignored. |
366 | - * @param last If not \c null, this is set to point to the character after the |
367 | - * last numeric character parsed; if \c null, characters past the last numeric |
368 | - * character may only be whitespace. |
369 | - * @return Returns the \c IntegralType value. |
370 | - * @throws invalid_argument if \a buf contains characters other than digits, a |
371 | - * sign, or leading/trailing whitespace, or contains no digits at all. |
372 | - * @throws range_error if the number is either too small or too big. |
373 | - */ |
374 | -template<typename IntegralType> inline |
375 | -// |
376 | -// Note that the is_integral shouldn't be needed since is_signed means "is a |
377 | -// signed integral type", but Microsoft's implementation is broken and returns |
378 | -// true for floating point types as well. |
379 | -// |
380 | -typename std::enable_if<ZORBA_TR1_NS::is_integral<IntegralType>::value |
381 | - && ZORBA_TR1_NS::is_signed<IntegralType>::value, |
382 | - IntegralType>::type |
383 | -aton( char const *buf, char const **last = nullptr ) { |
384 | - long long const result = atoll( buf, last ); |
385 | - if ( result < std::numeric_limits<IntegralType>::min() || |
386 | - result > std::numeric_limits<IntegralType>::max() ) |
387 | - throw std::range_error( |
388 | - BUILD_STRING( '"', result, "\": number too big/small" ) |
389 | - ); |
390 | - return static_cast<IntegralType>( result ); |
391 | -} |
392 | - |
393 | -/** |
394 | - * Parses the given string for a C++ signed integral type. |
395 | - * |
396 | - * @tparam IntegralType The C++ signed integral type to parse for. |
397 | - * @param buf The null-terminated C string to parse. Leading and trailing |
398 | - * whitespace is ignored. |
399 | - * @param low The lower acceptable bound. |
400 | - * @param high the higher acceptable bound. |
401 | - * @param last If not \c null, this is set to point to the character after the |
402 | - * last numeric character parsed; if \c null, characters past the last numeric |
403 | - * character may only be whitespace. |
404 | - * @return Returns the \c IntegralType value. |
405 | - * @throws invalid_argument if \a buf contains characters other than digits, a |
406 | - * sign, or leading/trailing whitespace, or contains no digits at all. |
407 | - * @throws range_error if the number is either too small or too big. |
408 | - */ |
409 | -template<typename IntegralType> inline |
410 | -// |
411 | -// Note that the is_integral shouldn't be needed since is_signed means "is a |
412 | -// signed integral type", but Microsoft's implementation is broken and returns |
413 | -// true for floating point types as well. |
414 | -// |
415 | -typename std::enable_if<ZORBA_TR1_NS::is_integral<IntegralType>::value |
416 | - && ZORBA_TR1_NS::is_signed<IntegralType>::value, |
417 | - IntegralType>::type |
418 | -aton( char const *buf, IntegralType low, IntegralType high, |
419 | - char const **last = nullptr ) { |
420 | - long long const result = atoll( buf, last ); |
421 | - if ( result < low || result > high ) |
422 | - throw std::range_error( |
423 | - BUILD_STRING( |
424 | - '"', result, "\": number not in range ", low, '-', high |
425 | - ) |
426 | - ); |
427 | - return static_cast<IntegralType>( result ); |
428 | -} |
429 | - |
430 | -/** |
431 | - * Parses the given string for a C++ unsigned integral types. |
432 | - * |
433 | - * @tparam IntegralType The C++ unsigned integral type to parse for. |
434 | - * @param buf The null-terminated C string to parse. Leading and trailing |
435 | - * whitespace is ignored. |
436 | - * @param last If not \c null, this is set to point to the character after the |
437 | - * last numeric character parsed; if \c null, characters past the last numeric |
438 | - * character may only be whitespace. |
439 | - * @return Returns the \c IntegralType value. |
440 | - * @throws invalid_argument if \a buf contains characters other than digits, a |
441 | - * sign, or leading/trailing whitespace, or contains no digits at all. |
442 | - * @throws range_error if the number is either too small or too big. |
443 | - */ |
444 | -template<typename IntegralType> inline |
445 | -typename std::enable_if<ZORBA_TR1_NS::is_unsigned<IntegralType>::value, |
446 | - IntegralType>::type |
447 | -aton( char const *buf, char const **last = nullptr ) { |
448 | - unsigned long long const result = atoull( buf, last ); |
449 | - if ( result > std::numeric_limits<IntegralType>::max() ) |
450 | - throw std::range_error( BUILD_STRING( '"', result, "\": number too big" ) ); |
451 | - return static_cast<IntegralType>( result ); |
452 | -} |
453 | - |
454 | -/** |
455 | - * Parses the given string for a C++ unsigned integral types. |
456 | - * |
457 | - * @tparam IntegralType The C++ unsigned integral type to parse for. |
458 | - * @param buf The null-terminated C string to parse. Leading and trailing |
459 | - * whitespace is ignored. |
460 | - * @param low The lower acceptable bound. |
461 | - * @param high the higher acceptable bound. |
462 | - * @param last If not \c null, this is set to point to the character after the |
463 | - * last numeric character parsed; if \c null, characters past the last numeric |
464 | - * character may only be whitespace. |
465 | - * @return Returns the \c IntegralType value. |
466 | - * @throws invalid_argument if \a buf contains characters other than digits or |
467 | - * leading/trailing whitespace, or contains no digits at all. |
468 | - * @throws range_error if the number is either too small or too big. |
469 | - */ |
470 | -template<typename IntegralType> inline |
471 | -typename std::enable_if<ZORBA_TR1_NS::is_unsigned<IntegralType>::value, |
472 | - IntegralType>::type |
473 | -aton( char const *buf, IntegralType low, IntegralType high, |
474 | - char const **last = nullptr ) { |
475 | - unsigned long long const result = atoull( buf, last ); |
476 | + * whitespace is ignored. After any leading whitespace, there may be a \c + or |
477 | + * \c - sign, followed by a sequence of decimal digits. |
478 | + * @param last If not \c null, this is set to point to the character after the |
479 | + * last numeric character parsed; if \c null, characters past the last numeric |
480 | + * character may only be whitespace. |
481 | + * @return Returns the \c IntegralType value. |
482 | + * @throws invalid_argument if \a buf contains characters other than as |
483 | + * described or contains no digits at all. |
484 | + * @throws range_error if the number is either too small or too big. |
485 | + */ |
486 | +template<typename IntegralType> inline |
487 | +// |
488 | +// Note that the is_integral shouldn't be needed since is_signed means "is a |
489 | +// signed integral type", but Microsoft's implementation is broken and returns |
490 | +// true for floating point types as well. |
491 | +// |
492 | +typename std::enable_if<ZORBA_TR1_NS::is_integral<IntegralType>::value |
493 | + && ZORBA_TR1_NS::is_signed<IntegralType>::value, |
494 | + IntegralType>::type |
495 | +aton( char const *buf, char const **last = nullptr ) { |
496 | + long long const result = atoll( buf, last ); |
497 | + if ( result < std::numeric_limits<IntegralType>::min() || |
498 | + result > std::numeric_limits<IntegralType>::max() ) |
499 | + throw std::range_error( |
500 | + BUILD_STRING( '"', result, "\": number too big/small" ) |
501 | + ); |
502 | + return static_cast<IntegralType>( result ); |
503 | +} |
504 | + |
505 | +/** |
506 | + * Parses the given string for a C++ signed integral type. |
507 | + * |
508 | + * @tparam IntegralType The C++ signed integral type to parse for. |
509 | + * @param buf The null-terminated C string to parse. Leading and trailing |
510 | + * whitespace is ignored. After any leading whitespace, there may be a \c + or |
511 | + * \c - sign, followed by a sequence of decimal digits. |
512 | + * @param low The lower acceptable bound. |
513 | + * @param high the higher acceptable bound. |
514 | + * @param last If not \c null, this is set to point to the character after the |
515 | + * last numeric character parsed; if \c null, characters past the last numeric |
516 | + * character may only be whitespace. |
517 | + * @return Returns the \c IntegralType value. |
518 | + * @throws invalid_argument if \a buf contains characters other than as |
519 | + * described or contains no digits at all. |
520 | + * @throws range_error if the number is either too small or too big. |
521 | + */ |
522 | +template<typename IntegralType> inline |
523 | +// |
524 | +// Note that the is_integral shouldn't be needed since is_signed means "is a |
525 | +// signed integral type", but Microsoft's implementation is broken and returns |
526 | +// true for floating point types as well. |
527 | +// |
528 | +typename std::enable_if<ZORBA_TR1_NS::is_integral<IntegralType>::value |
529 | + && ZORBA_TR1_NS::is_signed<IntegralType>::value, |
530 | + IntegralType>::type |
531 | +aton( char const *buf, IntegralType low, IntegralType high, |
532 | + char const **last = nullptr ) { |
533 | + long long const result = atoll( buf, last ); |
534 | + if ( result < low || result > high ) |
535 | + throw std::range_error( |
536 | + BUILD_STRING( |
537 | + '"', result, "\": number not in range ", low, '-', high |
538 | + ) |
539 | + ); |
540 | + return static_cast<IntegralType>( result ); |
541 | +} |
542 | + |
543 | +/** |
544 | + * Parses the given string for a C++ signed integral type. |
545 | + * |
546 | + * @tparam IntegralType The C++ signed integral type to parse for. |
547 | + * @param buf The C string to parse; it need not be null-terminated. Leading |
548 | + * and trailing whitespace is ignored. After any leading whitespace, there may |
549 | + * be a \c + or \c - sign, followed by a sequence of decimal digits. |
550 | + * @param end A pointer to one past the last character to parse. |
551 | + * @param last If not \c null, this is set to point to the character after the |
552 | + * last numeric character parsed; if \c null, characters past the last numeric |
553 | + * character may only be whitespace. |
554 | + * @return Returns the \c IntegralType value. |
555 | + * @throws invalid_argument if \a buf contains characters other than as |
556 | + * described or contains no digits at all. |
557 | + * @throws range_error if the number is either too small or too big. |
558 | + */ |
559 | +template<typename IntegralType> inline |
560 | +// |
561 | +// Note that the is_integral shouldn't be needed since is_signed means "is a |
562 | +// signed integral type", but Microsoft's implementation is broken and returns |
563 | +// true for floating point types as well. |
564 | +// |
565 | +typename std::enable_if<ZORBA_TR1_NS::is_integral<IntegralType>::value |
566 | + && ZORBA_TR1_NS::is_signed<IntegralType>::value, |
567 | + IntegralType>::type |
568 | +aton( char const *buf, char const *end, char const **last = nullptr ) { |
569 | + long long const result = atoll( buf, end, last ); |
570 | + if ( result < std::numeric_limits<IntegralType>::min() || |
571 | + result > std::numeric_limits<IntegralType>::max() ) |
572 | + throw std::range_error( |
573 | + BUILD_STRING( '"', result, "\": number too big/small" ) |
574 | + ); |
575 | + return static_cast<IntegralType>( result ); |
576 | +} |
577 | + |
578 | +/** |
579 | + * Parses the given string for a C++ signed integral type. |
580 | + * |
581 | + * @tparam IntegralType The C++ signed integral type to parse for. |
582 | + * @param buf The null-terminated C string to parse. Leading and trailing |
583 | + * whitespace is ignored. After any leading whitespace, there may be a \c + or |
584 | + * \c - sign, followed by a sequence of decimal digits. |
585 | + * @param end A pointer to one past the last character to parse. |
586 | + * @param low The lower acceptable bound. |
587 | + * @param high the higher acceptable bound. |
588 | + * @param last If not \c null, this is set to point to the character after the |
589 | + * last numeric character parsed; if \c null, characters past the last numeric |
590 | + * character may only be whitespace. |
591 | + * @return Returns the \c IntegralType value. |
592 | + * @throws invalid_argument if \a buf contains characters other than as |
593 | + * described or contains no digits at all. |
594 | + * @throws range_error if the number is either too small or too big. |
595 | + */ |
596 | +template<typename IntegralType> inline |
597 | +// |
598 | +// Note that the is_integral shouldn't be needed since is_signed means "is a |
599 | +// signed integral type", but Microsoft's implementation is broken and returns |
600 | +// true for floating point types as well. |
601 | +// |
602 | +typename std::enable_if<ZORBA_TR1_NS::is_integral<IntegralType>::value |
603 | + && ZORBA_TR1_NS::is_signed<IntegralType>::value, |
604 | + IntegralType>::type |
605 | +aton( char const *buf, char const *end, IntegralType low, IntegralType high, |
606 | + char const **last = nullptr ) { |
607 | + long long const result = atoll( buf, end, last ); |
608 | + if ( result < low || result > high ) |
609 | + throw std::range_error( |
610 | + BUILD_STRING( |
611 | + '"', result, "\": number not in range ", low, '-', high |
612 | + ) |
613 | + ); |
614 | + return static_cast<IntegralType>( result ); |
615 | +} |
616 | + |
617 | +/** |
618 | + * Parses the given string for a C++ unsigned integral types. |
619 | + * |
620 | + * @tparam IntegralType The C++ unsigned integral type to parse for. |
621 | + * @param buf The null-terminated C string to parse. Leading and trailing |
622 | + * whitespace is ignored. After any leading whitespace, there may be a \c + |
623 | + * sign, followed by a sequence of decimal digits. |
624 | + * @param last If not \c null, this is set to point to the character after the |
625 | + * last numeric character parsed; if \c null, characters past the last numeric |
626 | + * character may only be whitespace. |
627 | + * @return Returns the \c IntegralType value. |
628 | + * @throws invalid_argument if \a buf contains characters other than as |
629 | + * described or contains no digits at all. |
630 | + * @throws range_error if the number is either too small or too big. |
631 | + */ |
632 | +template<typename IntegralType> inline |
633 | +typename std::enable_if<ZORBA_TR1_NS::is_unsigned<IntegralType>::value, |
634 | + IntegralType>::type |
635 | +aton( char const *buf, char const **last = nullptr ) { |
636 | + unsigned long long const result = atoull( buf, last ); |
637 | + if ( result > std::numeric_limits<IntegralType>::max() ) |
638 | + throw std::range_error( BUILD_STRING( '"', result, "\": number too big" ) ); |
639 | + return static_cast<IntegralType>( result ); |
640 | +} |
641 | + |
642 | +/** |
643 | + * Parses the given string for a C++ unsigned integral types. |
644 | + * |
645 | + * @tparam IntegralType The C++ unsigned integral type to parse for. |
646 | + * @param buf The null-terminated C string to parse. Leading and trailing |
647 | + * whitespace is ignored. After any leading whitespace, there may be a \c + |
648 | + * sign, followed by a sequence of decimal digits. |
649 | + * @param low The lower acceptable bound. |
650 | + * @param high the higher acceptable bound. |
651 | + * @param last If not \c null, this is set to point to the character after the |
652 | + * last numeric character parsed; if \c null, characters past the last numeric |
653 | + * character may only be whitespace. |
654 | + * @return Returns the \c IntegralType value. |
655 | + * @throws invalid_argument if \a buf contains characters other than as |
656 | + * described or contains no digits at all. |
657 | + * @throws range_error if the number is either too small or too big. |
658 | + */ |
659 | +template<typename IntegralType> inline |
660 | +typename std::enable_if<ZORBA_TR1_NS::is_unsigned<IntegralType>::value, |
661 | + IntegralType>::type |
662 | +aton( char const *buf, IntegralType low, IntegralType high, |
663 | + char const **last = nullptr ) { |
664 | + unsigned long long const result = atoull( buf, last ); |
665 | + if ( result < low || result > high ) |
666 | + throw std::range_error( |
667 | + BUILD_STRING( |
668 | + '"', result, "\": number not in range ", low, '-', high |
669 | + ) |
670 | + ); |
671 | + return static_cast<IntegralType>( result ); |
672 | +} |
673 | + |
674 | +/** |
675 | + * Parses the given string for a C++ unsigned integral types. |
676 | + * |
677 | + * @tparam IntegralType The C++ unsigned integral type to parse for. |
678 | + * @param buf The C string to parse; it need not be null-terminated. Leading |
679 | + * and trailing whitespace is ignored. After any leading whitespace, there may |
680 | + * be a \c + sign, followed by a sequence of decimal digits. |
681 | + * @param end A pointer to one past the last character to parse. |
682 | + * @param last If not \c null, this is set to point to the character after the |
683 | + * last numeric character parsed; if \c null, characters past the last numeric |
684 | + * character may only be whitespace. |
685 | + * @return Returns the \c IntegralType value. |
686 | + * @throws invalid_argument if \a buf contains characters other than as |
687 | + * described or contains no digits at all. |
688 | + * @throws range_error if the number is either too small or too big. |
689 | + */ |
690 | +template<typename IntegralType> inline |
691 | +typename std::enable_if<ZORBA_TR1_NS::is_unsigned<IntegralType>::value, |
692 | + IntegralType>::type |
693 | +aton( char const *buf, char const *end, char const **last = nullptr ) { |
694 | + unsigned long long const result = atoull( buf, end, last ); |
695 | + if ( result > std::numeric_limits<IntegralType>::max() ) |
696 | + throw std::range_error( BUILD_STRING( '"', result, "\": number too big" ) ); |
697 | + return static_cast<IntegralType>( result ); |
698 | +} |
699 | + |
700 | +/** |
701 | + * Parses the given string for a C++ unsigned integral types. |
702 | + * |
703 | + * @tparam IntegralType The C++ unsigned integral type to parse for. |
704 | + * @param buf The C string to parse; it need not be null-terminated. Leading |
705 | + * and trailing whitespace is ignored. After any leading whitespace, there may |
706 | + * be a \c + sign, followed by a sequence of decimal digits. |
707 | + * @param end A pointer to one past the last character to parse. |
708 | + * @param low The lower acceptable bound. |
709 | + * @param high the higher acceptable bound. |
710 | + * @param last If not \c null, this is set to point to the character after the |
711 | + * last numeric character parsed; if \c null, characters past the last numeric |
712 | + * character may only be whitespace. |
713 | + * @return Returns the \c IntegralType value. |
714 | + * @throws invalid_argument if \a buf contains characters other than as |
715 | + * described or contains no digits at all. |
716 | + * @throws range_error if the number is either too small or too big. |
717 | + */ |
718 | +template<typename IntegralType> inline |
719 | +typename std::enable_if<ZORBA_TR1_NS::is_unsigned<IntegralType>::value, |
720 | + IntegralType>::type |
721 | +aton( char const *buf, char const *end, IntegralType low, IntegralType high, |
722 | + char const **last = nullptr ) { |
723 | + unsigned long long const result = atoull( buf, end, last ); |
724 | if ( result < low || result > high ) |
725 | throw std::range_error( |
726 | BUILD_STRING( |
727 | @@ -616,14 +781,17 @@ |
728 | * Parses the given string for a C++ \c double type. |
729 | * |
730 | * @param buf The null-terminated C string to parse. Leading and trailing |
731 | - * whitespace is ignored. |
732 | + * whitespace is ignored. After any leading whitespace, there may be a \c + or |
733 | + * \c - sign, followed by a sequence of decimal digits optionally containing a |
734 | + * single single \c . (decimal-point), optionally followed by an exponent |
735 | + * consisting of an \c e or \c E followed by an optional \c + or \c - sign |
736 | + * followed by a sequence of decimal digits. |
737 | * @param last If not \c null, this is set to point to the character after the |
738 | * last numeric character parsed; if \c null, characters past the last numeric |
739 | * character may only be whitespace. |
740 | * @return Returns the \c double value. |
741 | - * @throws invalid_argument if \a buf contains characters other than those for |
742 | - * a valid \c double value or leading/trailing whitespace, or contains no |
743 | - * digits at all. |
744 | + * @throws invalid_argument if \a buf contains characters other than as |
745 | + * described or contains no digits at all. |
746 | * @throws range_error if the number overflows/underflows. |
747 | */ |
748 | template<typename NumericType> inline |
749 | @@ -637,14 +805,17 @@ |
750 | * Parses the given string for a C++ \c float type. |
751 | * |
752 | * @param buf The null-terminated C string to parse. Leading and trailing |
753 | - * whitespace is ignored. |
754 | + * whitespace is ignored. After any leading whitespace, there may be a \c + or |
755 | + * \c - sign, followed by a sequence of decimal digits optionally containing a |
756 | + * single single \c . (decimal-point), optionally followed by an exponent |
757 | + * consisting of an \c e or \c E followed by an optional \c + or \c - sign |
758 | + * followed by a sequence of decimal digits. |
759 | * @param last If not \c null, this is set to point to the character after the |
760 | * last numeric character parsed; if \c null, characters past the last numeric |
761 | * character may only be whitespace. |
762 | * @return Returns the \c float value. |
763 | - * @throws invalid_argument if \a buf contains characters other than those for |
764 | - * a valid \c float value or leading/trailing whitespace, or contains no digits |
765 | - * at all. |
766 | + * @throws invalid_argument if \a buf contains characters other than as |
767 | + * described or contains no digits at all. |
768 | * @throws range_error if the number overflows/underflows. |
769 | */ |
770 | template<typename NumericType> inline |
Validation queue starting for merge proposal. zorbatest. lambda. nu:8080/ remotequeue/ pjl-misc- 2013-04- 16T02-57- 42.841Z/ log.html
Log at: http://