Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
27.istream.fmat.arith.cpp
Go to the documentation of this file.
1
28#include <cstddef>
29#include <istream>
30
31#include <rw_char.h>
32#include <rw_ctype.h>
33#include <rw_exception.h>
34#include <rw_printf.h>
35#include <rw_streambuf.h>
36#include <rw_driver.h>
37
38
40struct LocaleData {
41 const char *whitespace;
44 const char *grouping;
45 const char *truename;
46 const char *falsename;
47};
48
49
50template <class CharT>
51const std::locale
53{
54#if 255U == _RWSTD_UCHAR_MAX
55
56 // work around a bogus gcc error: ISO C++ forbids variable-size
57 // array (see https://issues.apache.org/jira/browse/STDCXX-351)
58 static const std::size_t N = 256;
59
60#else // if UCHAR_MAX != 255
61
62 // determine the number of classic characters
63 static const std::size_t N = std::ctype<char>::table_size;
64
65#endif
66
67 // derive a class so we can call the protected classic_table()
68 struct ClassicTable: std::ctype<char> {
69 static const std::ctype_base::mask* get () {
70 return classic_table ();
71 }
72 };
73
74 // get the classic C table of masks
75 const std::ctype_base::mask* const classic = ClassicTable::get ();
76
77 static int chars [N + 1];
78 static int masks [N + 1];
79
80 // -1 denotes end of characters (can't use 0 since it's a valid value)
81 chars [N] = -1;
82
83 // copy the classic table clearing the space bit of each mask
84 for (std::size_t i = 0; i != N; ++i) {
85 chars [i] = int (i);
86 masks [i] = classic [i] & ~std::ctype_base::space;
87 }
88
89 typedef unsigned char UChar;
90
91 // set the space bit for all characters in whitespace
92 for (const char *ws = data.whitespace; *ws; ++ws)
93 masks [UChar (*ws)] |= std::ctype_base::space;
94
95 // create a user-defined ctype-derived facet and initialize
96 // it with the character set and the specified masks
97 const std::ctype<CharT>* const ctp =
98 new UserCtype<CharT>(chars, masks);
99
100 struct NumPunct: std::numpunct<CharT> {
101
102 // CharType typedef works around a Sun C++ bug stdcxx-345
103 typedef CharT CharType;
104 typedef std::numpunct<CharType> Base;
105 typedef std::char_traits<CharType> Traits;
106 typedef std::allocator<CharType> Allocator;
107 typedef std::basic_string<CharType, Traits, Allocator> String;
108
109 int dp_;
110 int ts_;
111 const char *grp_;
112 const CharType *fn_;
113 const CharType *tn_;
114
115 NumPunct (int dp, int ts, const char *grp,
116 const CharType *fn, const CharType *tn)
117 : Base (), dp_ (dp), ts_ (ts), grp_ (grp ? grp : ""),
118 fn_ (fn), tn_ (tn) { /* empty */ }
119
120 CharType do_decimal_point () const {
121 return -1 == dp_ ? Base::do_decimal_point ()
122 : make_char (char (dp_), (CharType*)0);
123 }
124
125 CharType do_thousands_sep () const {
126 return -1 == ts_ ? Base::do_thousands_sep ()
127 : make_char (char (ts_), (CharType*)0);
128 }
129
130 std::string do_grouping () const {
131 return 0 == grp_ ? Base::do_grouping ()
132 : std::string (grp_);
133 }
134
135 String do_truename () const {
136 return 0 == tn_ ? Base::do_truename () : String (tn_);
137 }
138
139 String do_falsename () const {
140 return 0 == fn_ ? Base::do_falsename () : String (fn_);
141 }
142 };
143
144 static CharT names [2][64];
145
146 names [false][0] = CharT ();
147 names [true][0] = CharT ();
148
149 if (data.falsename) {
150 for (std::size_t i = 0; data.falsename [i]; ++i) {
151 names [false][i] = data.falsename [i];
152 names [false][i + 1] = CharT ();
153 }
154 }
155
156 if (data.truename) {
157 for (std::size_t i = 0; data.truename [i]; ++i) {
158 names [true][i] = data.truename [i];
159 names [true][i + 1] = CharT ();
160 }
161 }
162
163 // create a user-defined numpunct-derived facet and initialize
164 // its members with the specified parameters
165 const std::numpunct<CharT>* const np =
166 new NumPunct (data.decimal_point,
167 data.thousands_sep,
168 data.grouping,
169 data.falsename ? names [false] : 0,
170 data.truename ? names [true] : 0);
171
172 // install the new nupunct facet in a temporary locale,
173 // replacing the original (if CharT=char or CharT=wchar_t)
174 const std::locale tmp (std::locale::classic (), np);
175
176 // install the new ctype facet in a locale, replacing
177 // the original (if CharT=char or CharT=wchar_t)
178 return std::locale (tmp, ctp);
179}
180
181
183template <class CharT, class Traits>
184const std::locale
185make_locale (const CharT*, const Traits*, const LocaleData &data)
186{
187 // construct a locale with the appropriate ctype and numpunct
188 // facets installed
189 const std::locale tmp (make_locale ((CharT*)0, data));
190
191 typedef std::istreambuf_iterator<CharT, Traits> Iterator;
192 typedef std::num_get<CharT, Iterator> NumGet;
193
194 // check to see if num_get for this charater type and traits
195 // is installed and install it if it isn't (i.e., when Traits
196 // is other than std::char_traits<CharT>)
197 if (std::has_facet<NumGet>(tmp))
198 return tmp;
199
200 return std::locale (tmp, new NumGet);
201}
202
203
205/* extern */ int opt_no_gcount;
206
207
208template <class CharT, class Traits, class ArithmeticType>
209void
210test_extractor (CharT*, Traits*, ArithmeticType*,
211 const char *cname,
212 const char *tname,
213 const char *aname,
214 int line,
215 // printf formatting directive for ArithmeticType
216 const char *valfmt,
217 // character buffer (input sequence)
218 const char *cbuf,
219 // number of characters in buffer:
220 std::size_t cbuf_size,
221 // ctype and numpunct data
222 const LocaleData &locale_data,
223 // stream flags():
224 int flags,
225 // initial stream rdstate():
226 int init_state,
227 // unmasked exceptions:
228 int exceptions,
229 // expected exception:
230 int expect_exception,
231 // expected stream state after extraction:
232 int expect_state,
233 // expected number of extracted characters:
234 int expect_extract,
235 // have streambuf fail (or throw) after so many calls
236 // to underflow() (each call extracts a single chracter):
237 int fail_when,
238 // initial value of the argument to extractor:
239 ArithmeticType init_value,
240 // expected value of the argument after extraction:
241 ArithmeticType expect_value)
242{
243 _RWSTD_UNUSED (cname);
244 _RWSTD_UNUSED (tname);
245
246 typedef std::basic_istream<CharT, Traits> Istream;
248
249 const char *fail_desc = 0;
250
251 int fail_how = 0;
252
253 if (fail_when < 0) {
254 // have the stream buffer object's underflow() fail (by throwing
255 // an exception if possible) after `fail_when' characters have
256 // been extracted (this object calls underflow() for every char)
257 fail_how = Underflow | Throw;
258 fail_when = -fail_when;
259 fail_desc = "threw";
260 }
261 else if (0 < fail_when) {
262 // have the stream buffer object's underflow() fail by returning
263 // eof after `fail_when' characters have been extracted (this
264 // object calls underflow() for every char)
265 fail_how = Underflow;
266 fail_desc = "returned EOF";
267 }
268
269 // construct a stream buffer object and initialize its read sequence
270 // with the character buffer
271 Streambuf sb (cbuf, cbuf_size, fail_how, fail_when);
272
273 // construct an istream object and initialize it with the user
274 // defined streambuf object
275 Istream is (&sb);
276
277 if (-1 == flags) {
278 // get the initial stream object's format control flags
279 flags = is.flags ();
280 }
281 else {
282 // set the stream object's format control flags
283 is.flags (std::ios::fmtflags (flags));
284 }
285
286 if (-1 == exceptions) {
287 // get the initial stream object's exceptions
288 exceptions = is.exceptions ();
289 }
290 else {
291 // unmask the stream objects exceptions (must be done
292 // before calling setstate() to prevent the latter from
293 // throwing ios::failure)
294 is.exceptions (std::ios::iostate (exceptions));
295 }
296
297 if (-1 == init_state) {
298 // get the initial stream object's state
299 init_state = is.rdstate ();
300 }
301 else {
302 // set the stream object's initial state
303
304#ifndef _RWSTD_NO_EXCEPTIONS
305 try {
306 is.setstate (std::ios::iostate (init_state));
307 }
308 catch (...) {
309 // ignore exceptions
310 }
311#else // if defined ( _RWSTD_NO_EXCEPTIONS)
312 is.setstate (std::ios::iostate (init_state));
313#endif // _RWSTD_NO_EXCEPTIONS
314 }
315
316 // construct a locale object that treats only the specified `white'
317 // characters as whitespace (all others are treated normally)
318 const std::locale loc =
319 is.imbue (make_locale ((CharT*)0, (Traits*)0, locale_data));
320
321 // imbue the previous locale into the stream buffer to verify that
322 // the ws manipulator uses the locale imbued in the stream object
323 // and not the one in the stream buffer
324 sb.pubimbue (loc);
325
326 // initialize the variable to the initial value to detect
327 // the extractor setting it when it's not supposed to
328 ArithmeticType value = init_value;
329
330 // format the FUNCALL environment variable w/o writing out any output
331 rw_fprintf (0,
332 "%{$FUNCALL!:@}",
333 "%{$CLASS}(%{*Ac}).operator>>(%s& = %{@}): "
334 "initial flags() = %{If}, rdstate() = %{Is}, "
335 "exceptions() = %{Is}, whitespace = %{#s}, numpunct = { "
336 ".dp=%{#c}, .ts=%{#c}, .grp=%{#s}, .fn=%{#s}, .tn=%{#s} }",
337 int (sizeof *cbuf), cbuf, aname, valfmt, init_value,
338 flags, init_state,
339 exceptions, locale_data.whitespace,
340 locale_data.decimal_point, locale_data.thousands_sep,
341 locale_data.grouping, locale_data.falsename,
342 locale_data.truename);
343
344#ifndef _RWSTD_NO_EXCEPTIONS
345
346 int caught = 0;
347
348 try {
349 is >> value;
350 }
351 catch (Exception&) {
352 caught = 1;
353 }
354 catch (std::ios_base::failure &ex) {
355 caught = 2;
356 rw_assert (caught == expect_exception, 0, line,
357 "line %d. %{$FUNCALL}: unexpectedly threw "
358 "ios_base::failure(%{#s})", __LINE__, ex.what ());
359 }
360 catch (...) {
361 caught = -1;
362 rw_assert (false, 0, line,
363 "line %d. %{$FUNCALL}: unexpectely threw an exception "
364 "of unknown type", __LINE__);
365 }
366
368 // verify that the function propagates exceptions thrown from the
369 // streambuf object only when badbit is set in the stream object's
370 // exceptions()
371
372 rw_assert (caught == expect_exception, 0, line,
373 "line %d. %{$FUNCALL}: "
374 "%{?}failed to throw"
375 "%{:}unexpectedly propagated"
376 "%{;} exception",
377 __LINE__, expect_exception);
378
379#else // if defined (_RWSTD_NO_EXCEPTIONS)
380
381 is >> value;
382
383#endif // _RWSTD_NO_EXCEPTIONS
384
385 // clear the text describing the type of failure when streambuf
386 // didn't actually fail (or throw)
387 if (sb.failed_ == None && sb.threw_ == None)
388 fail_desc = 0;
389
391 // verify that the expected number of characters have been
392 // extracted from the stream
393
394 const int extracted = int (sb.pubgptr () - sb.pubeback ());
395
396 rw_assert (expect_extract == extracted, 0, line,
397 "%d. %{$FUNCALL}: expected to extract %d characters, "
398 "got %d%{?} (underflow() %s at extraction %u)%{;}",
399 __LINE__, expect_extract,
400 extracted, 0 != fail_desc, fail_desc, fail_when);
401
403 // verify that gcount() is not affected
404
405 if (0 == opt_no_gcount)
406 rw_assert (0 == is.gcount (), 0, line,
407 "%d. %{$FUNCALL}: gcount() == 0, got %d "
408 "%{?} (underflow() %s at extraction %u)%{;}",
409 __LINE__, is.gcount (),
410 0 != fail_desc, fail_desc, fail_when);
411
413 // verify the state of the stream object after the function call
414
415 rw_assert (is.rdstate () == expect_state, 0, line,
416 "line %d. %{$FUNCALL}: rdstate() == %{Is}, got %{Is}"
417 "%{?} (underflow() %s at extraction %u)%{;}",
418 __LINE__, expect_state, is.rdstate(),
419 0 != fail_desc, fail_desc, fail_when);
420
422 // verify the extracted value matches the expected value
423
424 rw_assert (expect_value == value, 0, line,
425 "line %d. %{$FUNCALL}: expected value %{@}, got %{@}",
426 __LINE__, valfmt, expect_value, valfmt, value);
427}
428
429
431// state abbreviations for brevity
432const int ___ = 0;
433const int __f = 0 | 0 | std::ios::failbit;
434const int _e_ = 0 | std::ios::eofbit | 0;
435const int _ef = 0 | std::ios::eofbit | std::ios::failbit;
436const int b__ = std::ios::badbit | 0 | 0;
437const int b_f = std::ios::badbit | 0 | std::ios::failbit;
438const int be_ = std::ios::badbit | std::ios::eofbit | 0;
439const int bef = std::ios::badbit | std::ios::eofbit | std::ios::failbit;
440
441const int DEC = std::ios::dec;
442const int OCT = std::ios::oct;
443const int HEX = std::ios::hex;
444
445
446template <class CharT, class Traits, class ArithmeticType>
447void
448test_extractor (CharT*, Traits*, ArithmeticType*,
449 const char *cname,
450 const char *tname,
451 const char *aname,
452 const char *fmt)
453{
454 typedef ArithmeticType T;
455
456 LocaleData locale_data = {
457 0, -1, -1, 0, 0, 0
458 };
459
460 static const volatile T zero = T ();
461 static const volatile T negative_one = T (-1);
462
463 const bool is_signed = negative_one < zero;
464 const bool is_floating = zero > negative_one / 2;
465
466 // avoid test cases designed to exercise the extraction of negative
467 // values when ArithmeticType is an unsigned type
468#undef TEST
469#define TEST(str, fl, is, ex, ee, es, ne, fw, iv, ev) \
470 if (is_signed || 0 <= ev) \
471 test_extractor ((CharT*)0, (Traits*)0, (T*)0, cname, tname, aname, \
472 __LINE__, fmt, str, sizeof str - 1, locale_data, \
473 fl, is, ex, ee, es, ne, fw, (T)(iv), (T)ev)
474
475 locale_data.whitespace = "";
476
477 // +-- subject sequence
478 // | +-- initial flags (-1 for default)
479 // | | +-- initial state (-1 for default)
480 // | | | +-- exceptions (-1 for default)
481 // | | | | +-- expected exception
482 // | | | | | +-- expected rdstate()
483 // | | | | | | +-- extracted characters
484 // | | | | | | | +-- fail when? (0 to not)
485 // | | | | | | | | +-- initial value
486 // | | | | | | | | | +-- expected value
487 // | | | | | | | | | |
488 // V V V V V V V V V V
489 TEST ("", -1, -1, -1, 0, _ef, 0, 0, 1, 1);
490 TEST (" ", -1, -1, -1, 0, __f, 0, 0, 2, 2);
491 TEST (" ", -1, -1, -1, 0, _ef, 0, 1, 3, 3); // fail
492 TEST (" ", -1, -1, -1, 0, b__, 0, -1, 4, 4); // throw
493
494 // exercise behavior when the initial state is other than good
495 TEST (" ", -1, __f, -1, 0, __f, 0, -1, 5, 5);
496 TEST (" ", -1, _e_, -1, 0, _ef, 0, -1, 6, 6);
497 TEST (" ", -1, _ef, -1, 0, _ef, 0, -1, 7, 7);
498 TEST (" ", -1, b__, -1, 0, b_f, 0, -1, 8, 8);
499 TEST (" ", -1, b_f, -1, 0, b_f, 0, -1, 9, 9);
500 TEST (" ", -1, be_, -1, 0, bef, 0, -1, 10, 10);
501 TEST (" ", -1, bef, -1, 0, bef, 0, -1, 11, 11);
502
503 // verify that when the initial state isn't good the extractors
504 // do not attempt to obtain the requested input but call setstate()
505 // to set failbit (which causes failure to be thrown when failbit
506 // or any other bit is set in exceptions) (see LWG issue 419)
507 TEST (" ", -1, __f, __f, 2, __f, 0, -1, 9, 9);
508 TEST (" ", -1, _e_, __f, 2, _ef, 0, -1, 9, 9);
509 TEST (" ", -1, _e_, _e_, 2, _ef, 0, -1, 9, 9);
510 TEST (" ", -1, _ef, _e_, 2, _ef, 0, -1, 9, 9);
511 TEST (" ", -1, b__, __f, 2, b_f, 0, -1, 9, 9);
512 TEST (" ", -1, b_f, __f, 2, b_f, 0, -1, 9, 9);
513 TEST (" ", -1, b_f, b__, 2, b_f, 0, -1, 9, 9);
514
515 locale_data.whitespace = " ";
516 TEST (" ", -1, -1, -1, 0, _ef, 1, 0, 9, 9);
517 TEST (" ", -1, -1, -1, 0, _ef, 0, 1, 9, 9); // fail
518 TEST (" ", -1, -1, -1, 0, b__, 0, -1, 9, 9); // throw
519 TEST (" ", -1, -1, -1, 0, _ef, 1, 2, 9, 9); // fail
520 TEST (" ", -1, -1, -1, 0, b__, 1, -2, 9, 9); // throw
521 TEST ("_", -1, -1, -1, 0, __f, 0, 0, 9, 9);
522
523 TEST (" ", 0, -1, -1, 0, __f, 0, 0, 9, 9);
524
525 locale_data.whitespace = "_";
526 TEST (" ", -1, -1, -1, 0, __f, 0, 0, 9, 9);
527 TEST ("_", -1, -1, -1, 0, _ef, 1, 0, 9, 9);
528
529 locale_data.whitespace = "";
530 TEST ("0", -1, -1, -1, 0, _e_, 1, 0, 9, 0);
531 TEST ("1", -1, -1, -1, 0, _e_, 1, 0, 9, 1);
532 TEST ("+0", -1, -1, -1, 0, _e_, 2, 0, 9, 0);
533 TEST ("-0", -1, -1, -1, 0, _e_, 2, 0, 9, 0);
534 TEST ("+1", -1, -1, -1, 0, _e_, 2, 0, 9, 1);
535 TEST ("-1", -1, -1, -1, 0, _e_, 2, 0, 1, -1);
536 TEST ("+2 ", -1, -1, -1, 0, ___, 2, 0, 9, 2);
537 TEST ("-2 ", -1, -1, -1, 0, ___, 2, 0, 9, -2);
538
539 if (is_floating) {
540 TEST ("3.", -1, -1, -1, 0, _e_, 2, 0, 9, 3);
541 TEST ("+3.", -1, -1, -1, 0, _e_, 3, 0, 9, 3);
542 TEST ("-3.", -1, -1, -1, 0, _e_, 3, 0, 9, -3);
543 }
544 else {
545 TEST ("3.", -1, -1, -1, 0, ___, 1, 0, 9, 3);
546 TEST ("+3.", -1, -1, -1, 0, ___, 2, 0, 9, 3);
547 TEST ("-3.", -1, -1, -1, 0, ___, 2, 0, 9, -3);
548 }
549
550 // set '#' as the only whitespace character
551 locale_data.whitespace = "#";
552 TEST ("#+3", -1, -1, -1, 0, _e_, 3, 0, 9, 3);
553 TEST ("#-4", -1, -1, -1, 0, _e_, 3, 0, 9, -4);
554 TEST ("#+5", -1, -1, -1, 0, _e_, 3, 0, 9, 5);
555 TEST ("#-6", -1, -1, -1, 0, _e_, 3, 0, 9, -6);
556 TEST ("#+7#", -1, -1, -1, 0, ___, 3, 0, 9, 7);
557 TEST ("#-8#", -1, -1, -1, 0, ___, 3, 0, 9, -8);
558 TEST (" -9", -1, -1, -1, 0, __f, 0, 0, -9, -9);
559
560 // set 'X', 'Y', and 'Z' as the only whitespace characters
561 locale_data.whitespace = "XYZ";
562 TEST ("X10", -1, -1, -1, 0, _e_, 3, 0, 9, 10);
563 TEST ("XY11", -1, -1, -1, 0, _e_, 4, 0, 9, 11);
564 TEST ("XYZ12", -1, -1, -1, 0, _e_, 5, 0, 9, 12);
565
566 // set '9' as the whitespace character
567 locale_data.whitespace = "9";
568 TEST ("9", -1, -1, -1, 0, _ef, 1, 0, 8, 8);
569 TEST ("99", -1, -1, -1, 0, _ef, 2, 0, 8, 8);
570 TEST ("999", -1, -1, -1, 0, _ef, 3, 0, 8, 8);
571 TEST ("9991", -1, -1, -1, 0, _e_, 4, 0, 8, 1);
572
573 // exercise grouping
574 locale_data.whitespace = "_";
575 locale_data.thousands_sep = ';';
576 locale_data.grouping = "\1";
577
578 TEST ("0;0", -1, -1, -1, 0, _e_, 3, 0, 9, 0);
579 TEST ("+0;0", -1, -1, -1, 0, _e_, 4, 0, 9, 0);
580 TEST ("-0;0", -1, -1, -1, 0, _e_, 4, 0, 9, 0);
581 TEST ("+0;1", -1, -1, -1, 0, _e_, 4, 0, 9, 1);
582 TEST ("-0;1", -1, -1, -1, 0, _e_, 4, 0, 9, -1);
583 TEST ("0;1", -1, -1, -1, 0, _e_, 3, 0, 9, 1);
584 TEST ("1;0", -1, -1, -1, 0, _e_, 3, 0, 9, 10);
585 TEST ("1;2", -1, -1, -1, 0, _e_, 3, 0, 9, 12);
586 TEST ("_1;2", -1, -1, -1, 0, _e_, 4, 0, 9, 12);
587 TEST ("_1;2_", -1, -1, -1, 0, ___, 4, 0, 9, 12);
588 TEST ("_1_;2", -1, -1, -1, 0, ___, 2, 0, 9, 1);
589 TEST ("12345", -1, -1, -1, 0, _e_, 5, 0, 9, 12345);
590 TEST ("1;2;3;4;5", -1, -1, -1, 0, _e_, 9, 0, 9, 12345);
591 TEST ("12;3;4;5", -1, -1, -1, 0, _ef, 8, 0, 9, 12345);
592
593 // exercise thousands_sep that's a space
594 locale_data.whitespace = " ";
595 locale_data.thousands_sep = ' ';
596 locale_data.grouping = "\2";
597 TEST (" 0", -1, -1, -1, 0, _e_, 2, 0, 9, 0);
598 TEST (" 0", -1, -1, -1, 0, _e_, 3, 0, 9, 0);
599 TEST (" 0", -1, -1, -1, 0, _e_, 4, 0, 9, 0);
600 TEST (" 0 00", -1, -1, -1, 0, _e_, 5, 0, 9, 0);
601 TEST ("+0 00", -1, -1, -1, 0, _e_, 5, 0, 9, 0);
602 TEST ("-0 00", -1, -1, -1, 0, _e_, 5, 0, 9, 0);
603 TEST (" +0 00", -1, -1, -1, 0, _e_, 6, 0, 9, 0);
604 TEST (" -0 00", -1, -1, -1, 0, _e_, 6, 0, 9, 0);
605 TEST (" +0 00", -1, -1, -1, 0, _e_, 7, 0, 9, 0);
606 TEST (" -0 00", -1, -1, -1, 0, _e_, 7, 0, 9, 0);
607 TEST (" +00 00", -1, -1, -1, 0, _e_, 7, 0, 9, 0);
608 TEST (" -00 00", -1, -1, -1, 0, _e_, 7, 0, 9, 0);
609 TEST (" 00 01", -1, -1, -1, 0, _e_, 7, 0, 9, 1);
610 TEST (" +00 01", -1, -1, -1, 0, _e_, 7, 0, 9, 1);
611 TEST (" -00 01", -1, -1, -1, 0, _e_, 7, 0, 1, -1);
612 TEST ("0 01 02", -1, -1, -1, 0, _e_, 7, 0, 9, 102);
613 TEST ("1 02 03", -1, -1, -1, 0, _e_, 7, 0, 9, 10203);
614 TEST ("2 03 04", -1, -1, -1, 0, _e_, 7, 0, 9, 20304);
615 TEST ("304 05", -1, -1, -1, 0, _ef, 6, 0, 9, 30405);
616 TEST ("4 0 5 0", -1, -1, -1, 0, _ef, 7, 0, 9, 4050);
617
618 // according to the grammar in locale.numpunct, a valid number
619 // cannot start or end with a thousands separator (and all pairs
620 // of thousands separator must be separated by at least one
621 // digit)
622 locale_data.whitespace = "_";
623 locale_data.thousands_sep = ';';
624 locale_data.grouping = "\1";
625 TEST (";", -1, -1, -1, 0, __f, 0, 0, 9, 9);
626 TEST (";;", -1, -1, -1, 0, __f, 0, 0, 9, 9);
627 TEST ("_;", -1, -1, -1, 0, __f, 1, 0, 9, 9);
628 TEST ("+;", -1, -1, -1, 0, __f, 1, 0, 9, 9);
629 TEST ("-;", -1, -1, -1, 0, __f, 1, 0, 9, 9);
630 TEST ("0;", -1, -1, -1, 0, _ef, 2, 0, 9, 9);
631 TEST ("+0;", -1, -1, -1, 0, _ef, 3, 0, 9, 9);
632 TEST ("-0;", -1, -1, -1, 0, _ef, 3, 0, 9, 9);
633 TEST ("+1;", -1, -1, -1, 0, _ef, 3, 0, 9, 9);
634 TEST ("-1;", -1, -1, -1, 0, _ef, 3, 0, 9, 9);
635 TEST ("1;", -1, -1, -1, 0, _ef, 2, 0, 9, 9);
636 TEST ("0;_", -1, -1, -1, 0, __f, 2, 0, 9, 9);
637 TEST ("1;_", -1, -1, -1, 0, __f, 2, 0, 9, 9);
638 TEST ("_0;", -1, -1, -1, 0, _ef, 3, 0, 9, 9);
639 TEST ("_1;", -1, -1, -1, 0, _ef, 3, 0, 9, 9);
640 TEST ("0;;", -1, -1, -1, 0, __f, 2, 0, 9, 9);
641 TEST ("1;;", -1, -1, -1, 0, __f, 2, 0, 9, 9);
642 TEST (";0", -1, -1, -1, 0, __f, 0, 0, 9, 9);
643 TEST (";1", -1, -1, -1, 0, __f, 0, 0, 9, 9);
644 TEST ("_;0", -1, -1, -1, 0, __f, 1, 0, 9, 9);
645 TEST ("_;1", -1, -1, -1, 0, __f, 1, 0, 9, 9);
646
647 // exercise errors when thousands_sep that's a space
648 locale_data.whitespace = " ";
649 locale_data.thousands_sep = ' ';
650 locale_data.grouping = "\2";
651 TEST (" ", -1, -1, -1, 0, _ef, 1, 0, 9, 9);
652 TEST (" +", -1, -1, -1, 0, _ef, 2, 0, 9, 9);
653 TEST (" -", -1, -1, -1, 0, _ef, 2, 0, 9, 9);
654 TEST (" + ", -1, -1, -1, 0, __f, 2, 0, 9, 9);
655 TEST (" - ", -1, -1, -1, 0, __f, 2, 0, 9, 9);
656 TEST (" 0 ", -1, -1, -1, 0, _ef, 3, 0, 9, 9);
657 TEST (" +0 ", -1, -1, -1, 0, _ef, 4, 0, 9, 9);
658 TEST (" -0 ", -1, -1, -1, 0, _ef, 4, 0, 9, 9);
659 TEST (" 123 ", -1, -1, -1, 0, _ef, 5, 0, 9, 9);
660 TEST (" +123 ", -1, -1, -1, 0, _ef, 6, 0, 9, 9);
661 TEST (" -123 ", -1, -1, -1, 0, _ef, 6, 0, 9, 9);
662}
663
664
666void info (const char *cname, const char *tname, const char *type)
667{
668 // format the CLASS environment variable w/o writing out any output
669 rw_fprintf (0,
670 "%{$CLASS!:@}",
671 "%{?}istream%{:}%{?}wistream"
672 "%{:}basic_istream<%s, %s>%{;}%{;}",
673 'c' == *cname && 's' == *tname,
674 'w' == *cname && 's' == *tname,
675 cname, tname);
676
677 rw_info (0, 0, __LINE__, "std::%{$CLASS}::operator>>(%s&)", type);
678}
679
680
682#undef TEST
683#define TEST(T, fmt, str, fl, is, ex, ee, es, ne, fw, iv, ev) \
684 test_extractor ((CharT*)0, (Traits*)0, (T*)0, cname, tname, #T, \
685 __LINE__, fmt, str, sizeof str - 1, locale_data, \
686 fl, is, ex, ee, es, ne, fw, (T)(iv), (T)ev)
687
688
690template <class CharT, class Traits>
691void
693 const char *cname,
694 const char *tname)
695{
696 info (cname, tname, "bool");
697
698#define TEST_BOOL(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \
699 TEST (bool, "%b", ss, fl, is, ex, ee, es, ne, fw, iv, ev)
700
701 const int ba = std::ios::boolalpha;
702 const int ba_ws = ba | std::ios::skipws;
703
704 LocaleData locale_data = { 0, -1, -1, 0, 0, 0 };
705 locale_data.whitespace = "_";
706 locale_data.falsename = "NO";
707 locale_data.truename = "YES";
708
709 TEST_BOOL ("", -1, -1, -1, 0, _ef, 0, 0, false, false);
710 TEST_BOOL ("", -1, -1, -1, 0, _ef, 0, 0, true, true);
711 TEST_BOOL ("0", -1, -1, -1, 0, _e_, 1, 0, true, false);
712 TEST_BOOL ("1", -1, -1, -1, 0, _e_, 1, 0, false, true);
713 TEST_BOOL ("+0", -1, -1, -1, 0, _e_, 2, 0, true, false);
714 TEST_BOOL ("-0", -1, -1, -1, 0, _e_, 2, 0, true, false);
715 TEST_BOOL ("+1", -1, -1, -1, 0, _e_, 2, 0, false, true);
716 TEST_BOOL ("00", -1, -1, -1, 0, _e_, 2, 0, true, false);
717 TEST_BOOL ("01", -1, -1, -1, 0, _e_, 2, 0, false, true);
718 TEST_BOOL ("_000", -1, -1, -1, 0, _e_, 4, 0, true, false);
719 TEST_BOOL ("_001", -1, -1, -1, 0, _e_, 4, 0, false, true);
720
721 TEST_BOOL ("NO", -1, -1, -1, 0, __f, 0, 0, true, true);
722 TEST_BOOL ("YES", -1, -1, -1, 0, __f, 0, 0, false, false);
723 TEST_BOOL ("_NO", -1, -1, -1, 0, __f, 1, 0, true, true);
724 TEST_BOOL ("_YES", -1, -1, -1, 0, __f, 1, 0, false, false);
725
726 TEST_BOOL ("NO", ba, -1, -1, 0, ___, 2, 0, false, false);
727 TEST_BOOL ("YES", ba, -1, -1, 0, ___, 3, 0, true, true);
728 TEST_BOOL ("_NO", ba_ws, -1, -1, 0, ___, 3, 0, false, false);
729 TEST_BOOL ("_YES", ba_ws, -1, -1, 0, ___, 4, 0, true, true);
730 TEST_BOOL ("_NO_", ba_ws, -1, -1, 0, ___, 3, 0, false, false);
731 TEST_BOOL ("_YES_", ba_ws, -1, -1, 0, ___, 4, 0, true, true);
732
733 locale_data.falsename = "bool:0";
734 locale_data.truename = "bool:1";
735
736 TEST_BOOL ("bool:0", ba, -1, -1, 0, ___, 6, 0, false, false);
737 TEST_BOOL ("bool:1", ba, -1, -1, 0, ___, 6, 0, true, true);
738 TEST_BOOL ("bool:2", ba, -1, -1, 0, __f, 5, 0, true, true);
739}
740
741
743template <class CharT, class Traits>
744void
746 const char *cname,
747 const char *tname)
748{
749 info (cname, tname, "short");
750
751 test_extractor ((CharT*)0, (Traits*)0, (short*)0,
752 cname, tname, "short", "%hi");
753
754#define TEST_SHRT(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \
755 TEST (short, "%hi", ss, fl, is, ex, ee, es, ne, fw, iv, ev)
756
757 LocaleData locale_data = { 0, -1, -1, 0, 0, 0 };
758 locale_data.whitespace = "";
759
760#if 2 == _RWSTD_SHRT_SIZE
761 const short smax = +32767;
762 const short smin = -smax - 1;
763
764 TEST_SHRT ("-32768", -1, -1, -1, 0, _e_, 6, 0, -1, smin);
765 TEST_SHRT ("-32769", -1, -1, -1, 0, _ef, 6, 0, -1, smin);
766 TEST_SHRT ("-99999", -1, -1, -1, 0, _ef, 6, 0, -1, smin);
767
768 TEST_SHRT ("+32767", -1, -1, -1, 0, _e_, 6, 0, -1, smax);
769 TEST_SHRT ("+32768", -1, -1, -1, 0, _ef, 6, 0, -1, smax);
770 TEST_SHRT ("+99999", -1, -1, -1, 0, _ef, 6, 0, -1, smax);
771 TEST_SHRT ("999999", -1, -1, -1, 0, _ef, 6, 0, -1, smax);
772
773#elif 4 == _RWSTD_SHRT_SIZE
774 const short smax = +2147483647;
775 const short smin = -smax - 1;
776
777 TEST_SHRT ("-2147483648", -1, -1, -1, 0, _e_, 11, 0, -1, smin);
778 TEST_SHRT ("-2147483649", -1, -1, -1, 0, _ef, 11, 0, -1, smin);
779 TEST_SHRT ("-9999999999", -1, -1, -1, 0, _ef, 11, 0, -1, smin);
780
781 TEST_SHRT ("+2147483647", -1, -1, -1, 0, _e_, 11, 0, -1, smax);
782 TEST_SHRT ("+2147483648", -1, -1, -1, 0, _ef, 11, 0, -1, smax);
783 TEST_SHRT ("+9999999999", -1, -1, -1, 0, _ef, 11, 0, -1, smax);
784 TEST_SHRT ("99999999999", -1, -1, -1, 0, _ef, 11, 0, -1, smax);
785#endif // _RWSTD_SHRT_SIZE
786
787}
788
789
791template <class CharT, class Traits>
792void
794 const char *cname,
795 const char *tname)
796{
797 info (cname, tname, "unsigned short");
798
799 test_extractor ((CharT*)0, (Traits*)0, (unsigned short*)0,
800 cname, tname, "unsigned short", "%hu");
801
802#define TEST_USHRT(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \
803 TEST (unsigned short, "%hu", ss, fl, is, ex, ee, es, ne, fw, iv, ev)
804
805 LocaleData locale_data = { 0, -1, -1, 0, 0, 0 };
806 locale_data.whitespace = "";
807
808#if 2 == _RWSTD_USHRT_SIZE
809 const unsigned short usmax = 65535U;
810
811 TEST_SHRT ("65535", -1, -1, -1, 0, _e_, 5, 0, 1, usmax);
812 TEST_SHRT ("65536", -1, -1, -1, 0, _ef, 5, 0, 1, usmax);
813 TEST_SHRT ("99999", -1, -1, -1, 0, _ef, 5, 0, 1, usmax);
814#elif 4 == _RWSTD_USHRT_SIZE
815 const unsigned short usmax = 4294967295U;
816
817 TEST_SHRT ("4294967295", -1, -1, -1, 0, _e_, 10, 0, -1, usmax);
818 TEST_SHRT ("4294967296", -1, -1, -1, 0, _ef, 10, 0, -1, usmax);
819 TEST_SHRT ("9999999999", -1, -1, -1, 0, _ef, 10, 0, -1, usmax);
820#endif // _RWSTD_USHRT_SIZE
821
822}
823
824
826template <class CharT, class Traits>
827void
829 const char *cname,
830 const char *tname)
831{
832 info (cname, tname, "int");
833
834 test_extractor ((CharT*)0, (Traits*)0, (int*)0,
835 cname, tname, "int", "%i");
836
837#define TEST_INT(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \
838 TEST (int, "%i", ss, fl, is, ex, ee, es, ne, fw, iv, ev)
839
840 LocaleData locale_data = { 0, -1, -1, 0, 0, 0 };
841 locale_data.whitespace = "";
842
843#if 2 == _RWSTD_INT_SIZE
844 const int imax = +32767;
845 const int imin = -imax - 1;
846
847 TEST_INT ("-32768", -1, -1, -1, 0, _e_, 6, 0, 1, imin);
848 TEST_INT ("-32769", -1, -1, -1, 0, _ef, 6, 0, 1, imin);
849 TEST_INT ("-99999", -1, -1, -1, 0, _ef, 6, 0, 1, imin);
850
851 TEST_INT ("+32767", -1, -1, -1, 0, _e_, 6, 0, 1, imax);
852 TEST_INT ("+32768", -1, -1, -1, 0, _ef, 6, 0, 1, imax);
853 TEST_INT ("+99999", -1, -1, -1, 0, _ef, 6, 0, 1, imax);
854#elif 4 == _RWSTD_INT_SIZE
855 const int imax = +2147483647;
856 const int imin = -imax - 1;
857
858 TEST_INT ("-2147483648", -1, -1, -1, 0, _e_, 11, 0, -1, imin);
859 TEST_INT ("-2147483649", -1, -1, -1, 0, _ef, 11, 0, -1, imin);
860 TEST_INT ("-9999999999", -1, -1, -1, 0, _ef, 11, 0, -1, imin);
861
862 TEST_INT ("+2147483647", -1, -1, -1, 0, _e_, 11, 0, -1, imax);
863 TEST_INT ("+2147483648", -1, -1, -1, 0, _ef, 11, 0, -1, imax);
864 TEST_INT ("99999999999", -1, -1, -1, 0, _ef, 11, 0, -1, imax);
865#elif 8 == _RWSTD_INT_SIZE
866 const int imax = +9223372036854775807;
867 const int imin = -imax - 1;
868
869 TEST_INT ("-9223372036854775808", -1, -1, -1, 0, _e_, 20, 0, -1, imin);
870 TEST_INT ("-9223372036854775809", -1, -1, -1, 0, _ef, 20, 0, -1, imin);
871 TEST_INT ("-9999999999999999999", -1, -1, -1, 0, _ef, 20, 0, -1, imin);
872
873 TEST_INT ("+9223372036854775807", -1, -1, -1, 0, _e_, 20, 0, -1, imax);
874 TEST_INT ("+9223372036854775808", -1, -1, -1, 0, _ef, 20, 0, -1, imax);
875 TEST_INT ("99999999999999999999", -1, -1, -1, 0, _ef, 20, 0, -1, imax);
876#endif // _RWSTD_INT_SIZE
877
878}
879
880
882template <class CharT, class Traits>
883void
885 const char *cname,
886 const char *tname)
887{
888 info (cname, tname, "unsigned int");
889
890 test_extractor ((CharT*)0, (Traits*)0, (unsigned int*)0,
891 cname, tname, "unsigned int", "%u");
892
893#define TEST_UINT(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \
894 TEST (int, "%u", ss, fl, is, ex, ee, es, ne, fw, iv, ev)
895
896 LocaleData locale_data = { 0, -1, -1, 0, 0, 0 };
897 locale_data.whitespace = "";
898
899#if 2 == _RWSTD_UINT_SIZE
900 const unsigned uimax = 65535U;
901
902 TEST_INT ("65535", -1, -1, -1, 0, _e_, 5, 0, 1, uimax);
903 TEST_INT ("65536", -1, -1, -1, 0, _ef, 5, 0, 1, uimax);
904 TEST_INT ("99999", -1, -1, -1, 0, _ef, 5, 0, 1, uimax);
905#elif 4 == _RWSTD_UINT_SIZE
906 const unsigned uimax = 4294967295U;
907
908 TEST_INT ("4294967295", -1, -1, -1, 0, _e_, 10, 0, -1, uimax);
909 TEST_INT ("4294967296", -1, -1, -1, 0, _ef, 10, 0, -1, uimax);
910 TEST_INT ("9999999999", -1, -1, -1, 0, _ef, 10, 0, -1, uimax);
911#elif 8 == _RWSTD_UINT_SIZE
912 const unsigned uimax = 9223372036854775807U;
913
914 TEST_INT ("9223372036854775807", -1, -1, -1, 0, _e_, 10, 0, -1, uimax);
915 TEST_INT ("9223372036854775808", -1, -1, -1, 0, _ef, 10, 0, -1, uimax);
916 TEST_INT ("9999999999999999999", -1, -1, -1, 0, _ef, 10, 0, -1, uimax);
917#endif // _RWSTD_UINT_SIZE
918
919}
920
921
923template <class CharT, class Traits>
924void
926 const char *cname,
927 const char *tname)
928{
929 info (cname, tname, "long");
930
931 test_extractor ((CharT*)0, (Traits*)0, (long*)0,
932 cname, tname, "long", "%li");
933
934#define TEST_LONG(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \
935 TEST (long, "%li", ss, fl, is, ex, ee, es, ne, fw, iv, ev)
936
937 LocaleData locale_data = { 0, -1, -1, 0, 0, 0 };
938 locale_data.whitespace = "";
939
940#if 2 == _RWSTD_LONG_SIZE
941 const long lmax = +32767L;
942 const long lmin = -lmax - 1;
943
944 TEST_LONG ("-32768", -1, -1, -1, 0, _e_, 6, 0, 1, lmin);
945 TEST_LONG ("-32769", -1, -1, -1, 0, _ef, 6, 0, 1, lmin);
946 TEST_LONG ("-99999", -1, -1, -1, 0, _ef, 6, 0, 1, lmin);
947
948 TEST_LONG ("+32767", -1, -1, -1, 0, _e_, 6, 0, 1, lmax);
949 TEST_LONG ("+32768", -1, -1, -1, 0, _ef, 6, 0, 1, lmax);
950 TEST_LONG ("+99999", -1, -1, -1, 0, _ef, 6, 0, 1, lmax);
951#elif 4 == _RWSTD_LONG_SIZE
952 const long lmax = +2147483647L;
953 const long lmin = -lmax - 1;
954
955 TEST_LONG ("-2147483648", -1, -1, -1, 0, _e_, 11, 0, -1, lmin);
956 TEST_LONG ("-2147483649", -1, -1, -1, 0, _ef, 11, 0, -1, lmin);
957 TEST_LONG ("-9999999999", -1, -1, -1, 0, _ef, 11, 0, -1, lmin);
958
959 TEST_LONG ("+2147483647", -1, -1, -1, 0, _e_, 11, 0, -1, lmax);
960 TEST_LONG ("+2147483648", -1, -1, -1, 0, _ef, 11, 0, -1, lmax);
961 TEST_LONG ("99999999999", -1, -1, -1, 0, _ef, 11, 0, -1, lmax);
962#elif 8 == _RWSTD_LONG_SIZE
963 const long lmax = +9223372036854775807L;
964 const long lmin = -lmax - 1;
965
966 TEST_LONG ("-9223372036854775808", -1, -1, -1, 0, _e_, 20, 0, -1, lmin);
967 TEST_LONG ("-9223372036854775809", -1, -1, -1, 0, _ef, 20, 0, -1, lmin);
968 TEST_LONG ("-9999999999999999999", -1, -1, -1, 0, _ef, 20, 0, -1, lmin);
969
970 TEST_LONG ("+9223372036854775807", -1, -1, -1, 0, _e_, 20, 0, -1, lmax);
971 TEST_LONG ("+9223372036854775808", -1, -1, -1, 0, _ef, 20, 0, -1, lmax);
972 TEST_LONG ("99999999999999999999", -1, -1, -1, 0, _ef, 20, 0, -1, lmax);
973#endif // _RWSTD_LONG_SIZE
974
975}
976
977
979template <class CharT, class Traits>
980void
982 const char *cname,
983 const char *tname)
984{
985 info (cname, tname, "unsigned long");
986
987 test_extractor ((CharT*)0, (Traits*)0, (unsigned long*)0,
988 cname, tname, "unsigned long", "%lu");
989
990#define TEST_ULONG(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \
991 TEST (unsigned long, "%lu", ss, fl, is, ex, ee, es, ne, fw, iv, ev)
992
993 LocaleData locale_data = { 0, -1, -1, 0, 0, 0 };
994 locale_data.whitespace = "";
995
996#if 2 == _RWSTD_ULONG_SIZE
997 const unsigned ulmax = 65535UL;
998
999 TEST_ULONG ("65535", -1, -1, -1, 0, _e_, 5, 0, 1, ulmax);
1000 TEST_ULONG ("65536", -1, -1, -1, 0, _ef, 5, 0, 1, ulmax);
1001 TEST_ULONG ("99999", -1, -1, -1, 0, _ef, 5, 0, 1, ulmax);
1002#elif 4 == _RWSTD_ULONG_SIZE
1003 const unsigned ulmax = 4294967295UL;
1004
1005 TEST_ULONG ("4294967295", -1, -1, -1, 0, _e_, 10, 0, -1, ulmax);
1006 TEST_ULONG ("4294967296", -1, -1, -1, 0, _ef, 10, 0, -1, ulmax);
1007 TEST_ULONG ("9999999999", -1, -1, -1, 0, _ef, 10, 0, -1, ulmax);
1008#elif 8 == _RWSTD_ULONG_SIZE
1009 const unsigned ulmax = 9223372036854775807UL;
1010
1011 TEST_ULONG ("9223372036854775807", -1, -1, -1, 0, _e_, 10, 0, -1, ulmax);
1012 TEST_ULONG ("9223372036854775808", -1, -1, -1, 0, _ef, 10, 0, -1, ulmax);
1013 TEST_ULONG ("9999999999999999999", -1, -1, -1, 0, _ef, 10, 0, -1, ulmax);
1014#endif // _RWSTD_ULONG_SIZE
1015
1016}
1017
1018
1020template <class CharT, class Traits>
1021void
1023 const char *cname,
1024 const char *tname)
1025{
1026 info (cname, tname, "long long");
1027
1028 test_extractor ((CharT*)0, (Traits*)0, (long long*)0,
1029 cname, tname, "long long", "%lli");
1030
1031#define TEST_LLONG(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \
1032 TEST (long long, "%lli", ss, fl, is, ex, ee, es, ne, fw, iv, ev)
1033
1034 LocaleData locale_data = { 0, -1, -1, 0, 0, 0 };
1035 locale_data.whitespace = "";
1036
1037#if 2 == _RWSTD_LLONG_SIZE
1038 const long long llmax = +32767LL;
1039 const long long llmin = -llmax - 1;
1040
1041 TEST_LLONG ("-32768", -1, -1, -1, 0, _e_, 6, 0, 1, llmin);
1042 TEST_LLONG ("-32769", -1, -1, -1, 0, _ef, 6, 0, 1, llmin);
1043 TEST_LLONG ("-99999", -1, -1, -1, 0, _ef, 6, 0, 1, llmin);
1044
1045 TEST_LLONG ("+32767", -1, -1, -1, 0, _e_, 6, 0, 1, llmax);
1046 TEST_LLONG ("+32768", -1, -1, -1, 0, _ef, 6, 0, 1, llmax);
1047 TEST_LLONG ("+99999", -1, -1, -1, 0, _ef, 6, 0, 1, llmax);
1048#elif 4 == _RWSTD_LLONG_SIZE
1049 const long long llmax = +2147483647LL;
1050 const long long llmin = -llmax - 1;
1051
1052 TEST_LLONG ("-2147483648", -1, -1, -1, 0, _e_, 11, 0, -1, llmin);
1053 TEST_LLONG ("-2147483649", -1, -1, -1, 0, _ef, 11, 0, -1, llmin);
1054 TEST_LLONG ("-9999999999", -1, -1, -1, 0, _ef, 11, 0, -1, llmin);
1055
1056 TEST_LLONG ("+2147483647", -1, -1, -1, 0, _e_, 11, 0, -1, llmax);
1057 TEST_LLONG ("+2147483648", -1, -1, -1, 0, _ef, 11, 0, -1, llmax);
1058 TEST_LLONG ("99999999999", -1, -1, -1, 0, _ef, 11, 0, -1, llmax);
1059#elif 8 == _RWSTD_LLONG_SIZE
1060 const long long llmax = +9223372036854775807LL;
1061 const long long llmin = -llmax - 1;
1062
1063 TEST_LLONG ("-9223372036854775808", -1, -1, -1, 0, _e_, 20, 0, -1, llmin);
1064 TEST_LLONG ("-9223372036854775809", -1, -1, -1, 0, _ef, 20, 0, -1, llmin);
1065 TEST_LLONG ("-9999999999999999999", -1, -1, -1, 0, _ef, 20, 0, -1, llmin);
1066
1067 TEST_LLONG ("+9223372036854775807", -1, -1, -1, 0, _e_, 20, 0, -1, llmax);
1068 TEST_LLONG ("+9223372036854775808", -1, -1, -1, 0, _ef, 20, 0, -1, llmax);
1069 TEST_LLONG ("99999999999999999999", -1, -1, -1, 0, _ef, 20, 0, -1, llmax);
1070#endif // _RWSTD_LLONG_SIZE
1071
1072}
1073
1074
1076template <class CharT, class Traits>
1077void
1079 const char *cname,
1080 const char *tname)
1081{
1082 info (cname, tname, "unsigned long long");
1083
1084 test_extractor ((CharT*)0, (Traits*)0, (unsigned long long*)0,
1085 cname, tname, "unsigned long long", "%llu");
1086
1087#define TEST_ULLONG(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \
1088 TEST (unsigned long long, "%llu", ss, fl, is, ex, ee, es, ne, fw, iv, ev)
1089
1090 LocaleData locale_data = { 0, -1, -1, 0, 0, 0 };
1091 locale_data.whitespace = "";
1092
1093#if 2 == _RWSTD_ULLONG_SIZE
1094 const unsigned long long ullmax = 65535ULL;
1095
1096 TEST_ULLONG ("65535", -1, -1, -1, 0, _e_, 5, 0, 1, ullmax);
1097 TEST_ULLONG ("65536", -1, -1, -1, 0, _ef, 5, 0, 1, ullmax);
1098 TEST_ULLONG ("99999", -1, -1, -1, 0, _ef, 5, 0, 1, ullmax);
1099#elif 4 == _RWSTD_ULLONG_SIZE
1100 const unsigned long long ullmax = 4294967295ULL;
1101
1102 TEST_ULLONG ("4294967295", -1, -1, -1, 0, _e_, 10, 0, -1, ullmax);
1103 TEST_ULLONG ("4294967296", -1, -1, -1, 0, _ef, 10, 0, -1, ullmax);
1104 TEST_ULLONG ("9999999999", -1, -1, -1, 0, _ef, 10, 0, -1, ullmax);
1105#elif 8 == _RWSTD_ULLONG_SIZE
1106 const unsigned long long ullmax = 9223372036854775807ULL;
1107
1108 TEST_ULLONG ("9223372036854775807", -1, -1, -1, 0, _e_, 10, 0, -1, ullmax);
1109 TEST_ULLONG ("9223372036854775808", -1, -1, -1, 0, _ef, 10, 0, -1, ullmax);
1110 TEST_ULLONG ("9999999999999999999", -1, -1, -1, 0, _ef, 10, 0, -1, ullmax);
1111#endif // _RWSTD_ULLONG_SIZE
1112
1113}
1114
1115
1117template <class CharT, class Traits, class FloatingType>
1118void
1119test_floating (CharT*, Traits*, FloatingType*,
1120 const char *cname,
1121 const char *tname,
1122 const char *fname,
1123 const char *fmt)
1124{
1125 typedef FloatingType T;
1126
1127 test_extractor ((CharT*)0, (Traits*)0, (FloatingType*)0,
1128 cname, tname, fname, fmt);
1129
1130#define TEST_FLOATING(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \
1131 TEST (T, fmt, ss, fl, is, ex, ee, es, ne, fw, T (iv), T (ev))
1132
1133 LocaleData locale_data = { 0, -1, -1, 0, 0, 0 };
1134 locale_data.whitespace = "";
1135
1136 TEST_FLOATING ("", -1, -1, -1, 0, _ef, 0, 0, 1.0, 1.0);
1137}
1138
1139
1141template <class CharT, class Traits>
1142void
1144 const char *cname,
1145 const char *tname)
1146{
1147 const char fmt[] = "%g";
1148 const char fname[] = "float";
1149
1150 info (cname, tname, fname);
1151
1152 test_floating ((CharT*)0, (Traits*)0, (float*)0,
1153 cname, tname, fname, fmt);
1154
1155#define TEST_FLT(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \
1156 TEST (float, fmt, ss, fl, is, ex, ee, es, ne, fw, iv, ev)
1157
1158 LocaleData locale_data = { 0, -1, -1, 0, 0, 0 };
1159 locale_data.whitespace = "";
1160
1161 TEST_FLT ("", -1, -1, -1, 0, _ef, 0, 0, 1.0f, 1.0f);
1162
1163 rw_warn (0, 0, __LINE__,
1164 "%{$CLASS}::operator>>(%s&) insufficiently exercised", fname);
1165}
1166
1167
1169template <class CharT, class Traits>
1170void
1172 const char *cname,
1173 const char *tname)
1174{
1175 const char fmt[] = "%g";
1176 const char fname[] = "double";
1177
1178 info (cname, tname, fname);
1179
1180 test_floating ((CharT*)0, (Traits*)0, (double*)0,
1181 cname, tname, fname, fmt);
1182
1183#define TEST_DBL(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \
1184 TEST (double, fmt, ss, fl, is, ex, ee, es, ne, fw, iv, ev)
1185
1186 LocaleData locale_data = { 0, -1, -1, 0, 0, 0 };
1187 locale_data.whitespace = "";
1188
1189 TEST_DBL ("", -1, -1, -1, 0, _ef, 0, 0, 1.0, 1.0);
1190
1191 rw_warn (0, 0, __LINE__,
1192 "%{$CLASS}::operator>>(%s&) insufficiently exercised", fname);
1193}
1194
1195
1197template <class CharT, class Traits>
1198void
1200 const char *cname,
1201 const char *tname)
1202{
1203 const char fmt[] = "%Lg";
1204 const char fname[] = "long double";
1205
1206 info (cname, tname, fname);
1207
1208 test_floating ((CharT*)0, (Traits*)0, (long double*)0,
1209 cname, tname, fname, fmt);
1210
1211#define TEST_LDBL(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \
1212 TEST (long double, fmt, ss, fl, is, ex, ee, es, ne, fw, iv, ev)
1213
1214 LocaleData locale_data = { 0, -1, -1, 0, 0, 0 };
1215 locale_data.whitespace = "";
1216
1217 TEST_LDBL ("", -1, -1, -1, 0, _ef, 0, 0, 1.0L, 1.0L);
1218
1219 rw_warn (0, 0, __LINE__,
1220 "%{$CLASS}::operator>>(%s&) insufficiently exercised", fname);
1221}
1222
1223
1237
1238
1239template <class CharT, class Traits>
1240void
1242 const char *cname,
1243 const char *tname)
1244{
1245 // silence unused variable warnings
1246 (void)(___+__f+_e_+_ef+b__+b_f+be_+bef+DEC+OCT+HEX);
1247
1248#undef TEST
1249#define TEST(T) \
1250 if (rw_note (0 == opt_ ## T, 0, __LINE__, "%s tests disabled", #T)) \
1251 test_ ## T ((CharT*)0, (Traits*)0, cname, tname)
1252
1254 // basic_istream::operator>>(bool&)
1255 TEST (bool);
1256
1258 // basic_istream::operator>>(short&)
1259 TEST (shrt);
1260
1262 // basic_istream::operator>>(unsigned short&)
1263 TEST (ushrt);
1264
1266 // basic_istream::operator>>(int&)
1267 TEST (int);
1268
1270 // basic_istream::operator>>(unsigned int&)
1271 TEST (uint);
1272
1274 // basic_istream::operator>>(long&)
1275 TEST (long);
1276
1278 // basic_istream::operator>>(unsigned long&)
1279 TEST (ulong);
1280
1282 // basic_istream::operator>>(long long&)
1283 TEST (llong);
1284
1286 // basic_istream::operator>>(unsigned long long&)
1287 TEST (ullong);
1288
1290 // basic_istream::operator>>(float&)
1291 TEST (flt);
1292
1294 // basic_istream::operator>>(double&)
1295 TEST (dbl);
1296
1298 // basic_istream::operator>>(long double&)
1299 TEST (ldbl);
1300}
1301
1302
1304static int opt_char;
1305static int opt_wchar;
1306static int opt_char_traits;
1307static int opt_user_traits;
1308
1309
1310static int
1311run_test (int, char**)
1312{
1313#undef TEST
1314#define TEST(CharT, Traits) \
1315 test_extractor ((CharT*)0, (Traits*)0, #CharT, #Traits)
1316
1317 if (rw_note (0 <= opt_char && 0 <= opt_char_traits, 0, __LINE__,
1318 "basic_istream<char, char_traits<char>>::operator>>() "
1319 "tests disabled"))
1320 TEST (char, std::char_traits<char>);
1321
1322 if (rw_note (0 <= opt_char && 0 <= opt_user_traits, 0, __LINE__,
1323 "basic_istream<char, UserTraits<char>>::operator>>() "
1324 "tests disabled"))
1325 TEST (char, UserTraits<char>);
1326
1327#ifndef _RWSTD_NO_WCHAR_T
1328
1329 if (rw_note (0 <= opt_wchar && 0 <= opt_char_traits, 0, __LINE__,
1330 "basic_istream<wchar_t, char_traits<wchar_t>>::operator>>() "
1331 "tests disabled"))
1332 TEST (wchar_t, std::char_traits<wchar_t>);
1333
1334 if (rw_note (0 <= opt_wchar && 0 <= opt_user_traits, 0, __LINE__,
1335 "basic_istream<wchar_t, UserTraits<wchar_t>>::operator>>() "
1336 "tests disabled"))
1337 TEST (wchar_t, UserTraits<wchar_t>);
1338
1339#endif // _RWSTD_NO_WCHAR_T
1340
1341 return 0;
1342}
1343
1344
1346int main (int argc, char *argv[])
1347{
1348 return rw_test (argc, argv, __FILE__,
1349 "istream.formatted.arithmetic",
1350 0 /* no comment */,
1351 run_test,
1352 "|-char~ "
1353 "|-wchar_t~ "
1354 "|-char_traits~ "
1355 "|-UserTraits~ "
1356 "|-bool~ "
1357 "|-short~ "
1358 "|-unsigned-short~ "
1359 "|-int~ "
1360 "|-unsigned-int~ "
1361 "|-long~ "
1362 "|-unsigned-long~ "
1363 "|-long-long~ "
1364 "|-unsigned-long-long~ "
1365 "|-float~ "
1366 "|-double~ "
1367 "|-long-double~ "
1368 "|-no-gcount# ",
1369 &opt_char,
1370 &opt_wchar,
1371 &opt_char_traits,
1372 &opt_user_traits,
1373 &opt_bool,
1374 &opt_shrt,
1375 &opt_ushrt,
1376 &opt_int,
1377 &opt_uint,
1378 &opt_long,
1379 &opt_ulong,
1380 &opt_llong,
1381 &opt_ullong,
1382 &opt_flt,
1383 &opt_dbl,
1384 &opt_ldbl,
1386 (void*)0 /* sentinel */);
1387}
InputIter< UserClass > Iterator
#define N
Definition 17.names.cpp:157
#define i
Definition 17.names.cpp:126
#define T
Definition 17.names.cpp:163
#define line
Definition 17.names.cpp:490
#define loc
Definition 17.names.cpp:492
#define sb
Definition 17.names.cpp:542
#define Allocator
Definition 17.names.cpp:440
#define Traits
Definition 17.names.cpp:556
#define CharT
Definition 17.names.cpp:457
#define tmp
Definition 17.names.cpp:553
const char *const data[]
#define flags
int opt_wchar
int opt_char
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
T value(const T &val)
std::char_traits< S > Traits
void test_ulong(CharT *, Traits *, const char *cname, const char *tname)
#define TEST_LLONG(ss, fl, is, ex, ee, es, ne, fw, iv, ev)
const int DEC
const int HEX
const int b__
#define TEST_SHRT(ss, fl, is, ex, ee, es, ne, fw, iv, ev)
const int ___
void test_ullong(CharT *, Traits *, const char *cname, const char *tname)
#define TEST_ULONG(ss, fl, is, ex, ee, es, ne, fw, iv, ev)
void test_ushrt(CharT *, Traits *, const char *cname, const char *tname)
void test_floating(CharT *, Traits *, FloatingType *, const char *cname, const char *tname, const char *fname, const char *fmt)
void test_shrt(CharT *, Traits *, const char *cname, const char *tname)
void test_extractor(CharT *, Traits *, ArithmeticType *, const char *cname, const char *tname, const char *aname, int line, const char *valfmt, const char *cbuf, std::size_t cbuf_size, const LocaleData &locale_data, int flags, int init_state, int exceptions, int expect_exception, int expect_state, int expect_extract, int fail_when, ArithmeticType init_value, ArithmeticType expect_value)
void test_uint(CharT *, Traits *, const char *cname, const char *tname)
const int __f
void test_dbl(CharT *, Traits *, const char *cname, const char *tname)
#define TEST_DBL(ss, fl, is, ex, ee, es, ne, fw, iv, ev)
void test_long(CharT *, Traits *, const char *cname, const char *tname)
const int b_f
const int OCT
#define TEST(str, fl, is, ex, ee, es, ne, fw, iv, ev)
const int bef
#define TEST_INT(ss, fl, is, ex, ee, es, ne, fw, iv, ev)
const int _ef
#define TEST_LDBL(ss, fl, is, ex, ee, es, ne, fw, iv, ev)
#define TEST_ULLONG(ss, fl, is, ex, ee, es, ne, fw, iv, ev)
#define TEST_BOOL(ss, fl, is, ex, ee, es, ne, fw, iv, ev)
void test_flt(CharT *, Traits *, const char *cname, const char *tname)
int opt_no_gcount
#define TEST_FLT(ss, fl, is, ex, ee, es, ne, fw, iv, ev)
const int _e_
void test_llong(CharT *, Traits *, const char *cname, const char *tname)
void test_ldbl(CharT *, Traits *, const char *cname, const char *tname)
#define TEST_LONG(ss, fl, is, ex, ee, es, ne, fw, iv, ev)
#define TEST_FLOATING(ss, fl, is, ex, ee, es, ne, fw, iv, ev)
const std::locale make_locale(const CharT *, const LocaleData &data)
const int be_
void test_int(CharT *, Traits *, const char *cname, const char *tname)
void test_bool(CharT *, Traits *, const char *cname, const char *tname)
#define main
int caught
volatile int zero
Definition LIMITS.cpp:60
#define _RWSTD_UNUSED(arg)
Definition _defs.h:972
Definition json.h:5363
UserChar make_char(char c, UserChar *)
Definition rw_char.h:74
_TEST_EXPORT int rw_test(int argc, char *argv[], const char *filename, const char *clause, const char *comment, int(*testfun)(int, char **), const char *optspec,...)
_TEST_EXPORT int rw_info(int, const char *, int, const char *,...)
Definition driver.cpp:1681
_TEST_EXPORT int rw_note(int, const char *, int, const char *,...)
Definition driver.cpp:1664
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
Definition driver.cpp:1630
_TEST_EXPORT int rw_warn(int, const char *, int, const char *,...)
Definition driver.cpp:1647
_TEST_EXPORT int rw_fprintf(rw_file *, const char *,...)
Definition printf.cpp:3397
@ Throw
@ None
@ Underflow
unsigned char UChar
Definition collate.cpp:122
const char * falsename
const char * whitespace
const char * grouping
const char * truename