Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
22.locale.money.put.cpp
Go to the documentation of this file.
1
29#include <ios>
30#include <locale>
31#include <cstdio> // for sprintf()
32
33#include <rw_cmdopt.h> // for rw_enabled()
34#include <rw_driver.h> // for rw_assert(), rw_test(), ...
35#include <rw_valcmp.h> // for rw_strncmp()
36
37
39// set to non-zero value when grouping shouldn't be exercised
40static int no_grouping;
41
42// set to non-zero value when the basic_string overloads
43// of moneY-put::put() shouldn't be exercised
44static int no_basic_string;
45
46
48template <class charT, bool Intl>
49struct Punct: std::moneypunct<charT, Intl>
50{
51 typedef typename std::moneypunct<charT>::char_type char_type;
52 typedef typename std::moneypunct<charT>::string_type string_type;
53
56 static const char *grouping_;
57 static const char_type *curr_symbol_;
60 static std::money_base::pattern pos_format_;
61 static std::money_base::pattern neg_format_;
62 static int frac_digits_;
63
64 static int n_thousands_sep_; // number of calls to do_thousands_sep()
65
66 Punct (): std::moneypunct<charT>(1) { }
67
69 return decimal_point_;
70 }
71
72 int do_frac_digits () const {
73 return frac_digits_;
74 }
75
76 virtual string_type do_curr_symbol () const {
78 }
79
80 virtual std::string do_grouping () const {
81 return grouping_;
82 }
83
84 virtual char_type do_thousands_sep () const {
86 return thousands_sep_;
87 }
88
89 virtual string_type do_positive_sign () const {
91 }
92
93 virtual string_type do_negative_sign () const {
95 }
96
97 virtual std::money_base::pattern do_pos_format () const {
98 return pos_format_;
99 }
100
101 virtual std::money_base::pattern do_neg_format () const {
102 return neg_format_;
103 }
104};
105
106template <class charT, bool Intl>
107const char*
109
110template <class charT, bool Intl>
113
114template <class charT, bool Intl>
117
118template <class charT, bool Intl>
119const typename Punct<charT, Intl>::char_type*
121
122template <class charT, bool Intl>
123const typename Punct<charT, Intl>::char_type*
125
126template <class charT, bool Intl>
127const typename Punct<charT, Intl>::char_type*
129
130template <class charT, bool Intl>
131std::money_base::pattern
133 std::money_base::symbol,
134 std::money_base::sign,
135 std::money_base::none,
136 std::money_base::value
137} };
138
139template <class charT, bool Intl>
140std::money_base::pattern
142 std::money_base::symbol,
143 std::money_base::sign,
144 std::money_base::none,
145 std::money_base::value
146} };
147
148template <class charT, bool Intl>
149int
151
152template <class charT, bool Intl>
153int
155
156
158template <class charT>
159struct Ios: std::basic_ios<charT>
160{
161 Ios () { this->init (0); }
162};
163
164template <class charT>
165struct MoneyPut: std::money_put<charT, charT*>
166{
167 // default ctor defined in order to make it possible
168 // to define const objects of the type w/o explictly
169 // initializing them
170 typedef std::money_put<charT, charT*> Base;
171 MoneyPut (): Base () { /* no-op */ }
172};
173
174
177
178
180std::money_base::pattern
181set_pattern (const char *format)
182{
183 std::money_base::pattern pat;
184
185 for (unsigned i = 0; i != sizeof pat.field / sizeof *pat.field; ++i) {
186 switch (format [i]) {
187 case '\0': case '@': pat.field [i] = std::money_base::none; break;
188 case '\1': case ' ': pat.field [i] = std::money_base::space; break;
189 case '\2': case '$': pat.field [i] = std::money_base::symbol; break;
190 case '\3': case '-': pat.field [i] = std::money_base::sign; break;
191 case '\4': case '1': pat.field [i] = std::money_base::value; break;
192 default:
193 _RWSTD_ASSERT (!!"bad format specifier");
194 }
195 }
196
197 return pat;
198}
199
200
201template <class charT>
203 charT /* unused */,
204 long double val /* value to format */,
205 const char *str /* expected result */,
206 char fill = ' ',
207 int flags = 0,
208 int frac_digits = 0,
209 int width = 0,
210 const char *format = 0 /* pattern or printf() format */,
211 const char *grouping = 0)
212{
213 if (!rw_enabled (lineno)) {
214 rw_note (0, __FILE__, __LINE__, "test on line %d disabled", lineno);
215 return 0;
216 }
217
218 static const char* const cname = 1 < sizeof (charT) ? "wchar_t" : "char";
219
220 static int i = 0; // assertion number per specialization of type_test()
221
222 if (!i) {
223 rw_info (0, 0, 0, "std::money_put<%s>::put(ostreambuf_iterator"
224 "<%s>, bool, ios_base, %s, long double)",
225 cname, cname, cname);
226
227 rw_info (0, 0, 0, "std::money_put<%s>::put(ostreambuf_iterator"
228 "<%s>, bool, ios_base, %s, "
229 "const basic_string<%s>&))",
230 cname, cname, cname, cname);
231 }
232
234 // exercise put (..., long double) overload
235
236 int nfail = 0; // number of failed assertions
237
238 // unless 0, or unless it starts with '%', the `format' argument
239 // is treated as a money_base::pattern string; otherwise the
240 // default pattern is used
241
242 // default format as in locale ("C")
243 const char *fmt_pat = !format || *format == '%' ? "\2\3\4\0" : format;
244
245 if (!grouping) {
246 // default grouping as in locale ("C")
247 grouping = "";
248 }
249
250 const Punct<charT, false> pun;
251
252 // take care to initialize Punct static data before installing
253 // the facet in case locale or the base facet calls the overridden
254 // virtuals early to cache the results
255 pun.grouping_ = grouping;
256 pun.frac_digits_ = frac_digits;
257
258 if (val < 0.0) {
259 pun.neg_format_ = set_pattern (fmt_pat);
260 pun.pos_format_ = std::money_base::pattern ();
261 }
262 else if (val > 0.0) {
263 pun.neg_format_ = std::money_base::pattern ();
264 pun.pos_format_ = set_pattern (fmt_pat);
265 }
266 else {
267 // 0.0 and -0.0
268 pun.neg_format_ = set_pattern (fmt_pat);
269 pun.pos_format_ = pun.neg_format_;
270 }
271
272 // ios-derived object to pass to the facet
273 Ios<charT> ios;
274
275 // money_put-derived object
276 const MoneyPut<charT> mp;
277
278 // install the moneypunct facet in a locale and imbue the latter
279 // in the ios-derived object used by money_put
280 std::locale loc (ios.getloc (), (const std::moneypunct<charT>*)&pun);
281 ios.imbue (loc);
282
283 // set the formatting flags and the width
284 ios.flags (std::ios_base::fmtflags (flags));
285 ios.width (std::streamsize (width));
286
287 bool success;
288
289 charT buf [256] = { 0 };
290
291 if (rw_enabled ("long double")) {
292
293 // exercise 22.2.6.2.1, long double overload
294 *mp.put (buf, false, ios, charT (fill), val) = charT ();
295
296 rw_assert (0 == ios.width (), __FILE__, lineno,
297 "money_put<%s>::put (%#p, false, const ios_base&, "
298 "%{#c}, %LfL) reset width from %d",
299 cname, buf, fill, val, width);
300
301 success = 0 == rw_strncmp (buf, str);
302
303 if (!success)
304 ++nfail;
305
306 rw_assert (success, __FILE__, lineno,
307 "money_put<%s>::put (%#p, false, "
308 "const ios_base&, %{#c}, %LfL) == %{#s} got %{#s}; "
309 "flags = %{If}, grouping = %{#s}",
310 cname, buf,
311 fill, val, str, buf,
312 flags, grouping);
313 }
314 else {
315 static int msg_issued;
316
317 rw_note (msg_issued++, __FILE__, 0, "long double test disabled");
318 }
319
321 // exercise put (..., const basic_string&) overload
322
323 if (frac_digits < 0) {
324 // do not perform string test(s) for negative values of frac_digits
325 // (extension implemented only for the long double overload of put())
326 ++i;
327 return nfail;
328 }
329
330 if (no_basic_string) {
331 rw_note (0, __FILE__, __LINE__,
332 "basic_string<%s> test on line %d disabled", lineno, cname);
333 return nfail;
334 }
335
336 // zero out buffer
337 std::char_traits<charT>::assign (buf, sizeof buf / sizeof *buf, charT ());
338
339 // if the format string starts with a '%',
340 // use it to format the floating point value
341 if (!format || *format != '%')
342 format = "%.0" _RWSTD_LDBL_PRINTF_PREFIX "f";
343
344 char valbuf [256] = "";
345 const int valbuflen = std::sprintf (valbuf, format, val);
346
347 RW_ASSERT (0 < valbuflen && valbuflen < int (sizeof valbuf));
348
349 typedef std::char_traits<charT> Traits;
350 typedef std::allocator<charT> Allocator;
351
352 const std::basic_string<charT, Traits, Allocator>
353 valstr (valbuf, valbuf + valbuflen);
354
355 // set width (reset by a previous call)
356 ios.width (std::streamsize (width));
357
358 // exercise 22.2.6.2.1, basic_string overload
359 *mp.put (buf, false, ios, charT (fill), valstr) = charT ();
360
361 success = 0 == rw_strncmp (buf, str);
362
363 if (!success)
364 ++nfail;
365
366 rw_assert (success, __FILE__, lineno,
367 "money_put<%s>::put (%#p, false, "
368 "const ios_base&, %{#S}) == %{#s} got %{#s}; "
369 "flags = %{If}, grouping = %{#s}",
370 cname, fill, &valstr, buf, str,
371 flags, grouping);
372
373 ++i;
374
375 return nfail;
376}
377
378
380// for convenience
381#define Boolalpha std::ios_base::boolalpha
382#define Dec std::ios_base::dec
383#define Fixed std::ios_base::fixed
384#define Hex std::ios_base::hex
385#define Internal std::ios_base::internal
386#define Left std::ios_base::left
387#define Oct std::ios_base::oct
388#define Right std::ios_base::right
389#define Scientific std::ios_base::scientific
390#define Showbase std::ios_base::showbase
391#define Showpoint std::ios_base::showpoint
392#define Showpos std::ios_base::showpos
393#define Skipws std::ios_base::skipws
394#define Unitbuf std::ios_base::unitbuf
395#define Uppercase std::ios_base::uppercase
396#define Bin std::ios_base::bin
397#define Adjustfield std::ios_base::adjustfield
398#define Basefield std::ios_base::basefield
399#define Floatfield std::ios_base::floatfield
400#define Nolock std::ios_base::nolock
401#define Nolockbuf std::ios_base::nolockbuf
402
403#define Eofbit std::ios_base::eofbit
404#define Failbit std::ios_base::failbit
405#define Goodbit std::ios_base::goodbit
406
407
408template <class charT>
410{
411 static const charT curr_symbol1 [8] = { '$', '\0' };
413
416
417 static const charT signs1[][4] = {
418 // negative positive
419 { '~', '\0' }, { '\0', },
420 };
421
424
425 int ntried = 0;
426 int nfailed = 0;
427
428#define T __LINE__, charT ()
429#define TEST ++ntried, nfailed += type_test
430
431 // enum part { none, space, symbol, sign, value };
432
433 // no symbol, empty sign, default format
434 TEST (T, 0., "0", ' ');
435 TEST (T, 1., "1", ' ');
436 TEST (T, 12., "12", ' ');
437 TEST (T, 123., "123", ' ');
438 TEST (T, 1234., "1234", ' ');
439 TEST (T, 12345., "12345", ' ');
440 TEST (T, 123456., "123456", ' ');
441 TEST (T, 1234567., "1234567", ' ');
442 TEST (T, 12345678., "12345678", ' ');
443 TEST (T, 123456789., "123456789", ' ');
444
445 TEST (T, 12345678.9, "12345679", ' ');
446 TEST (T, 1234567.89, "1234568", ' ');
447 TEST (T, 123456.789, "123457", ' ');
448 TEST (T, 12345.6789, "12346", ' ');
449 TEST (T, 1234.56789, "1235", ' ');
450 TEST (T, 123.456789, "123", ' ');
451 TEST (T, 12.3456789, "12", ' ');
452 TEST (T, 1.23456789, "1", ' ');
453 TEST (T, .123456789, "0", ' ');
454
455 // exercise correct handling of frac_digits
456 TEST (T, 9876543210., "987654321:0", ' ', 0, 1);
457 TEST (T, 876543210., "8765432:10", ' ', 0, 2);
458 TEST (T, 76543210., "76543:210", ' ', 0, 3);
459 TEST (T, 6543210., "654:3210", ' ', 0, 4);
460 TEST (T, 543210., "5:43210", ' ', 0, 5);
461 TEST (T, 43210., "0:043210", ' ', 0, 6);
462 TEST (T, 3210., "0:0003210", ' ', 0, 7);
463 TEST (T, 210., "0:00000210", ' ', 0, 8);
464 TEST (T, 10., "0:000000010", ' ', 0, 9);
465 TEST (T, 1., "0:000000001", ' ', 0, 9);
466 TEST (T, 0., "0:000000000", ' ', 0, 9);
467 TEST (T, 200., "0:000000200", ' ', 0, 9);
468 TEST (T, 3000., "0:000003000", ' ', 0, 9);
469 TEST (T, 40000., "0:000040000", ' ', 0, 9);
470 TEST (T, 500000., "0:000500000", ' ', 0, 9);
471 TEST (T, 6000000., "0:006000000", ' ', 0, 9);
472 TEST (T, 70000000., "0:070000000", ' ', 0, 9);
473 TEST (T, 800000000., "0:800000000", ' ', 0, 9);
474 TEST (T, -900000000., "~0:900000000", ' ', 0, 9);
475 TEST (T, -80000000., "~0:080000000", ' ', 0, 9);
476 TEST (T, -7000000., "~0:007000000", ' ', 0, 9);
477 TEST (T, -600000., "~0:000600000", ' ', 0, 9);
478 TEST (T, -50000., "~0:000050000", ' ', 0, 9);
479 TEST (T, -4000., "~0:000004000", ' ', 0, 9);
480 TEST (T, -300., "~0:000000300", ' ', 0, 9);
481 TEST (T, -20., "~0:000000020", ' ', 0, 9);
482 TEST (T, -1., "~0:000000001", ' ', 0, 9);
483
484 if (test_neg_zero)
485 TEST (T, -0., "~0:000000000", ' ', 0, 9);
486
487 // extension: fixed and negative frac_digits
488 TEST (T, 1.0, "1:0", ' ', Fixed, -1);
489 TEST (T, 2.0, "2:00", ' ', Fixed, -2);
490 TEST (T, 3.0, "3:000", ' ', Fixed, -3);
491 TEST (T, 4.1, "4:1000", ' ', Fixed, -4);
492 TEST (T, 52.34, "52:34000", ' ', Fixed, -5);
493 TEST (T, 634.56789, "634:5679", ' ', Fixed, -4);
494
495
496 // exhaustively exercise valid permutations of format patterns
497 // (`none' allowed in all but the first position by 22.2.6.3, p1)
498 TEST (T, 12, "12", '\0', 0, 0, 0, "\3\0\4\2", "");
499 TEST (T, 123, "123", '\0', 0, 0, 0, "\3\0\2\4", "");
500 TEST (T, 1234, "1234", '\0', 0, 0, 0, "\3\2\4\0", "");
501 TEST (T, 2345, "2345", '\0', 0, 0, 0, "\3\4\2\0", "");
502 TEST (T, 3456, "3456", '\0', 0, 0, 0, "\3\4\0\2", "");
503 TEST (T, 4567, "4567", '\0', 0, 0, 0, "\4\0\2\3", "");
504 TEST (T, 5678, "5678", '\0', 0, 0, 0, "\4\2\0\3", "");
505 TEST (T, 6789, "6789", '\0', 0, 0, 0, "\4\2\3\0", "");
506 TEST (T, 7890, "7890", '\0', 0, 0, 0, "\4\0\3\2", "");
507 TEST (T, 8901, "8901", '\0', 0, 0, 0, "\2\4\0\3", "");
508 TEST (T, 9012, "9012", '\0', 0, 0, 0, "\2\0\4\3", "");
509 TEST (T, 123, "123", '\0', 0, 0, 0, "\2\0\3\4", "");
510
511 // format using `space' in valid positions (all but
512 // the first and last as specified by 22.2.6.3, p1)
513 // the actual space character (not the fill char)
514 // is required
515 TEST (T, 9, " 9", '*', 0, 0, 0, "\3\1\4\2", "");
516 TEST (T, 98, " 98", '*', 0, 0, 0, "\3\1\2\4", "");
517 TEST (T, 987, "987 ", '*', 0, 0, 0, "\3\4\1\2", "");
518 TEST (T, 876, "876 ", '*', 0, 0, 0, "\4\1\2\3", "");
519 TEST (T, 765, "765 ", '*', 0, 0, 0, "\4\2\1\3", "");
520 TEST (T, 654, "654 ", '*', 0, 0, 0, "\4\1\3\2", "");
521 TEST (T, 543, "543 ", '*', 0, 0, 0, "\2\4\1\3", "");
522 TEST (T, 432, " 432", '*', 0, 0, 0, "\2\1\4\3", "");
523 TEST (T, 321, " 321", '*', 0, 0, 0, "\2\1\3\4", "");
524
525 TEST (T, 0, "$0", '\0', Showbase, 0, 0, "\2\3\4\0", "");
526 TEST (T, 1, "$1", '\0', Showbase, 0, 0, "\2\3\4\0", "");
527 TEST (T, 12, "$12", '\0', Showbase, 0, 0, "\2\3\4\0", "");
528 TEST (T, 123, "$123", '\0', Showbase, 0, 0, "\2\3\4\0", "");
529 TEST (T, 1234, "$1234", '\0', Showbase, 0, 0, "\2\3\4\0", "");
530 TEST (T, 12345, "$12345", '\0', Showbase, 0, 0, "\2\3\4\0", "");
531 TEST (T, 123456, "$123456", '\0', Showbase, 0, 0, "\2\3\4\0", "");
532 TEST (T, 1234567, "$1234567", '\0', Showbase, 0, 0, "\2\3\4\0", "");
533 TEST (T, 12345678, "$12345678", '\0', Showbase, 0, 0, "\2\3\4\0", "");
534
535 TEST (T, 0, "$0", '\0', Showbase, 0, 0, 0, "\2");
536 TEST (T, 1, "$1", '\0', Showbase, 0, 0, 0, "\2\2");
537 TEST (T, 12, "$12", '\0', Showbase, 0, 0, 0, "\2");
538 TEST (T, 123, "$1;23", '\0', Showbase, 0, 0, 0, "\2\2");
539 TEST (T, 1234, "$12;34", '\0', Showbase, 0, 0, 0, "\2");
540 TEST (T, 12345, "$1;23;45", '\0', Showbase, 0, 0, 0, "\2\2");
541 TEST (T, 123456, "$12;34;56", '\0', Showbase, 0, 0, 0, "\2");
542 TEST (T, 1234567, "$1;23;45;67", '\0', Showbase, 0, 0, 0, "\2\2");
543 TEST (T, 12345678, "$12;34;56;78", '\0', Showbase, 0, 0, 0, "\2");
544 TEST (T, 123456789, "$1;23;45;67;89", '\0', Showbase, 0, 0, 0, "\2\2");
545
546 if (test_neg_zero)
547 TEST (T, -0.0, "$~0", '\0', Showbase, 0, 0, 0, "\3\3");
548
549 TEST (T, -1, "$~1", '\0', Showbase, 0, 0, 0, "\3");
550 TEST (T, -12, "$~12", '\0', Showbase, 0, 0, 0, "\3\3");
551 TEST (T, -123, "$~123", '\0', Showbase, 0, 0, 0, "\3");
552 TEST (T, -1234, "$~1;234", '\0', Showbase, 0, 0, 0, "\3\3");
553 TEST (T, -12345, "$~12;345", '\0', Showbase, 0, 0, 0, "\3");
554 TEST (T, -123456, "$~123;456", '\0', Showbase, 0, 0, 0, "\3\3");
555 TEST (T, -1234567, "$~1;234;567", '\0', Showbase, 0, 0, 0, "\3");
556 TEST (T, -12345678, "$~12;345;678", '\0', Showbase, 0, 0, 0, "\3\3");
557 TEST (T, -123456789, "$~123;456;789", '\0', Showbase, 0, 0, 0, "\3");
558
559 // for convenience
560 const char *f = "\3\2\4\0"; // { sign, symbol, value, none }
561
562 TEST (T, -321, "~$32;1", '\0', Showbase, 0, 0, f, "\1\2");
563 TEST (T, -4322, "~$432;2", '\0', Showbase, 0, 0, f, "\1\3");
564 TEST (T, -54323, "~$5;4;3;2;3", '\0', Showbase, 0, 0, f, "\1\1");
565 TEST (T, -654324, "~$6;5;4;3;2;4", '\0', Showbase, 0, 0, f, "\1\1");
566 TEST (T, -7654325, "~$765;432;5", '\0', Showbase, 0, 0, f, "\1\3");
567 TEST (T, -87654326, "~$8;7;6;5;4;3;26", '\0', Showbase, 0, 0, f, "\2\1");
568 TEST (T, -987654327, "~$98;76;54;32;7", '\0', Showbase, 0, 0, f, "\1\2");
569
570 static const charT curr_symbol2 [8] = { 'X', 'Y', '\0' };
572
573 static const charT signs2[][8] = {
574 // negative positive
575 { '(', ')', '\0' }, { '{', '}', '\0' }
576 };
577
582
583 f = "\3\4\1\2"; // { sign, value, space, symbol }
584
585 TEST (T, -1357911, "(1.3.5.7.9.1.1 XY)", '*', Showbase, 0, 0, f, "\1");
586 TEST (T, -2468012, "(2.46.80.12 XY)", '-', Showbase, 0, 0, f, "\2");
587 TEST (T, -3692513, "(3.692.513 XY)", ' ', Showbase, 0, 0, f, "\3");
588 TEST (T, -9999914, "(999.9914 XY)", '@', Showbase, 0, 0, f, "\4");
589 TEST (T, -1000015, "(10.00015 XY)", '#', Showbase, 0, 0, f, "\5");
590 TEST (T, -16, "(16 XY)", ')', Showbase, 0, 0, f, "\6");
591
592 TEST (T, +1357917, "{1.3.5.7.9.1.7 XY}", ',', Showbase, 0, 0, f, "\1");
593 TEST (T, +2468018, "{2.46.80.18 XY}", '+', Showbase, 0, 0, f, "\2");
594 TEST (T, +3692519, "{3.692.519 XY}", '0', Showbase, 0, 0, f, "\3");
595 TEST (T, +9999920, "{999.9920 XY}", '1', Showbase, 0, 0, f, "\4");
596 TEST (T, +1000021, "{10.00021 XY}", '\0', Showbase, 0, 0, f, "\5");
597 TEST (T, +22, "{22 XY}", '{', Showbase, 0, 0, f, "\6");
598 TEST (T, +123, "{123 }", '_', 0, 0, 0, f, "\6");
599 TEST (T, -224, "(224 )", '_', 0, 0, 0, f, "\7");
600
601 TEST (T, +325, "{ XY325}", ' ', Showbase, 0, 0, "\3\1\2\4", "\xa");
602 TEST (T, -426, "( XY426)", ' ', Showbase, 0, 0, "\3\1\2\4", "\xb");
603 TEST (T, +527, "{XY 527}", ' ', Showbase, 0, 0, "\3\2\1\4", "\xc");
604 TEST (T, -628, "(XY 628)", ' ', Showbase, 0, 0, "\3\2\1\4", "\xd");
605 TEST (T, +729, "{XY729}", ' ', Showbase, 0, 0, "\3\2\0\4", "\xe");
606 TEST (T, -830, "(XY830)", ' ', Showbase, 0, 0, "\3\2\0\4", "\xf");
607 TEST (T, +931, "{XY931}", ' ', Showbase, 0, 0, "\3\0\2\4", "\x10");
608 TEST (T, -1032, "(XY1032)", ' ', Showbase, 0, 0, "\3\0\2\4");
609 TEST (T, +1133, "1133{XY}", ' ', Showbase, 0, 0, "\4\3\2\0");
610 TEST (T, -1234, "1234XY()", ' ', Showbase, 0, 0, "\4\2\3\0");
611 TEST (T, +1335, "1335XY{}", ' ', Showbase, 0, 0, "\4\2\0\3");
612 TEST (T, -1436, "1436XY ()", ' ', Showbase, 0, 0, "\4\2\1\3");
613 TEST (T, +1537, "1537XY{}", ' ', Showbase, 0, 0, "\4\0\2\3");
614 TEST (T, -1638, "1638 XY()", ' ', Showbase, 0, 0, "\4\1\2\3");
615 TEST (T, +1739, "XY1739{}", ' ', Showbase, 0, 0, "\2\4\0\3");
616 TEST (T, -1840, "XY1840 ()", ' ', Showbase, 0, 0, "\2\4\1\3");
617 TEST (T, +1941, "XY1941{}", ' ', Showbase, 0, 0, "\2\0\4\3");
618 TEST (T, -2042, "XY 2042()", ' ', Showbase, 0, 0, "\2\1\4\3");
619 TEST (T, +2143, "XY{2143}", ' ', Showbase, 0, 0, "\2\3\4\0");
620 TEST (T, -2244, "XY(2244)", ' ', Showbase, 0, 0, "\2\3\0\4");
621 TEST (T, +2345, "XY{ 2345}", ' ', Showbase, 0, 0, "\2\3\1\4");
622
623 // 22.2.6.2, p2:
624 // ...copies of `fill' are inserted as necessary to pad to the
625 // specified width. For the value `af' equal to (str.flags()
626 // & str.adjustfield), if (af == str.internal) is true, the fill
627 // characters are placed where `none' or `space' appears in the
628 // formatting pattern; otherwise if (af == str.left) is true, they
629 // are placed after the other characters; otherwise, they are
630 // placed before the other characters.
631
632 TEST (T, -2446, "___XY( 2446)", '_', Showbase, 0, 12, "\2\3\1\4");
633 TEST (T, +2547, "____XY{2547}", '_', Showbase, 0, 12, "\2\3\0\4");
634
635 TEST (T, -2648, "___XY( 2648)", '_', Showbase | Right, 0, 12, "\2\3\1\4");
636 TEST (T, +2749, "____XY{2749}", '_', Showbase | Right, 0, 12, "\2\3\0\4");
637
638 TEST (T, -2850, "XY( 2850)___", '_', Showbase | Left, 0, 12, "\2\3\1\4");
639 TEST (T, +2951, "XY{2951}____", '_', Showbase | Left, 0, 12, "\2\3\0\4");
640
641 TEST (T, -3052, "___XY( 3052)", '_',
642 Showbase | Left | Right, 0, 12, "\2\3\1\4");
643
644 TEST (T, +3153, "____XY{3153}", '_',
645 Showbase | Left | Right, 0, 12, "\2\3\0\4");
646
647 TEST (T, -3254, "___XY( 3254)", '_',
648 Showbase | Left | Right | Internal, 0, 12, "\2\3\1\4");
649
650 TEST (T, +3355, "____XY{3355}", '_',
651 Showbase | Left | Right | Internal, 0, 12, "\2\3\0\4");
652
653 TEST (T, -3456, "XY( ___3456)", '_',
654 Showbase | Internal, 0, 12, "\2\3\1\4");
655
656 TEST (T, +3557, "XY{____3557}", '_',
657 Showbase | Internal, 0, 12, "\2\3\0\4");
658
659 TEST (T, -3658, "XY____(3658)", '_',
660 Showbase | Internal, 0, 12, "\2\0\3\4");
661
662 TEST (T, +3759, "XY{3759____}", '_',
663 Showbase | Internal, 0, 12, "\2\3\4\0");
664
665 TEST (T, 3759, "XY{37.59}", '_',
666 Showbase | Internal, 0, 8, "\2\3\4\0", "\2");
667
668 TEST (T, 3760, "XY{ 37.60}", '_',
669 Showbase | Internal, 0, 8, "\2\3\1\4", "\2");
670
671 TEST (T, 12345678900000000000.0, "XY{ ........1.23.45678.9000.00.000.0.00}",
672 '.', Showbase | Internal, 0, 40, "\2\3\1\4", "\2\1\3\2\4\5\2");
673
674 TEST (T, 1234567890000000000.0, "{ ...........1234.56789.0000.000.00.0XY}",
675 '.', Showbase | Internal, 0, 40, "\3\1\4\2", "\1\2\3\4\5\6");
676
677 // exercise justification with non-zero frac_digits
678 TEST (T, 1, "_____{0.1}", '_', 0, 1, 10, "-@1$");
679 TEST (T, 12, "_____{1.2}", '_', 0, 1, 10, "-@1$");
680 TEST (T, 123, "____{1.23}", '_', 0, 2, 10, "-@1$");
681 TEST (T, 1234, "_{12.34XY}", '_', Showbase, 2, 10, "-@1$");
682 TEST (T, 1235, "_{ 12.35XY}", '_', Showbase, 2, 11, "- 1$");
683
684 TEST (T, 2, "******{0.2}", '*', Right, 1, 11, "-@1$");
685 TEST (T, 23, "******{2.3}", '*', Right, 1, 11, "-@1$");
686 TEST (T, 234, "*****{2.34}", '*', Right, 2, 11, "-@1$");
687 TEST (T, 2345, "**{23.45XY}", '*', Right | Showbase, 2, 11, "-@1$");
688 TEST (T, 2346, "**{ 23.46XY}", '*', Right | Showbase, 2, 12, "- 1$");
689
690 TEST (T, 3, "{0.3}#######", '#', Left, 1, 12, "-@1$");
691 TEST (T, 34, "{3.4}#######", '#', Left, 1, 12, "-@1$");
692 TEST (T, 345, "{3.45}######", '#', Left, 2, 12, "-@1$");
693 TEST (T, 3456, "{34.56XY}###", '#', Left | Showbase, 2, 12, "-@1$");
694 TEST (T, 3457, "{ 34.57XY}###", '#', Left | Showbase, 2, 13, "- 1$");
695
696 TEST (T, 4, "{=====0.4}", '=', Internal, 1, 10, "-@1$");
697 TEST (T, 45, "{=====4.5}", '=', Internal, 1, 10, "-@1$");
698 TEST (T, 456, "{====4.56}", '=', Internal, 2, 10, "-@1$");
699 TEST (T, 4567, "{=45.67XY}", '=', Internal | Showbase, 2, 10, "-@1$");
700 TEST (T, 4568, "{ =45.68XY}", '=', Internal | Showbase, 2, 11, "- 1$");
701
704
705 // justification with grouping
706 TEST (T, 105, "====={1,0.5}", '=', 0, 1, 12, "-@1$", "\1");
707 TEST (T, 1056, "===={1,05.6}", '=', 0, 1, 12, "-@1$", "\2");
708 TEST (T, 10567, "==={1,05.67}", '=', 0, 2, 12, "-@1$", "\2");
709 TEST (T, 105678, "=={10,56.78XY}", '=', Showbase, 2, 14, "-@1$", "\2");
710 TEST (T, 105679, "={ 10,56.79XY}", '=', Showbase, 2, 14, "- 1$", "\2");
711 TEST (T, 105680, "={ 1,056,80XY}", '=', Showbase, 0, 14, "- 1$", "\2\3");
712
713 int flags = Right | Showbase;
714 TEST (T, 106, ">>>>>{1,0.6}", '>', Right, 1, 12, "-@1$", "\1");
715 TEST (T, 1057, ">>>>{1,05.7}", '>', Right, 1, 12, "-@1$", "\2");
716 TEST (T, 10568, ">>>{1,05.68}", '>', Right, 2, 12, "-@1$", "\2");
717 TEST (T, 105679, ">>{10,56.79XY}", '>', flags, 2, 14, "-@1$", "\2");
718 TEST (T, 105680, ">{ 10,56.80XY}", '>', flags, 2, 14, "- 1$", "\2");
719 TEST (T, 105681, ">{ 1,056,81XY}", '>', flags, 0, 14, "- 1$", "\2\3");
720
721 flags = Left | Showbase;
722 TEST (T, 107, "{1,0.7}<<<<<", '<', Left, 1, 12, "-@1$", "\1");
723 TEST (T, 1058, "{1,05.8}<<<<", '<', Left, 1, 12, "-@1$", "\2");
724 TEST (T, 10569, "{1,05.69}<<<", '<', Left, 2, 12, "-@1$", "\2");
725 TEST (T, 105680, "{10,56.80XY}<<", '<', flags, 2, 14, "-@1$", "\2");
726 TEST (T, 105681, "{ 10,56.81XY}<", '<', flags, 2, 14, "- 1$", "\2");
727 TEST (T, 105682, "{ 1,056,82XY}<", '<', flags, 0, 14, "- 1$", "\2\3");
728
730 TEST (T, 108, "{^^^^^1,0.8}", '^', Internal, 1, 12, "-@1$", "\1");
731 TEST (T, 1059, "{^^^^1,05.9}", '^', Internal, 1, 12, "-@1$", "\2");
732 TEST (T, 10570, "{^^^1,05.70}", '^', Internal, 2, 12, "-@1$", "\2");
733 TEST (T, 105681, "{^^10,56.81XY}", '^', flags, 2, 14, "-@1$", "\2");
734 TEST (T, 105682, "{ ^10,56.82XY}", '^', flags, 2, 14, "- 1$", "\2");
735 TEST (T, 105683, "{ ^1,056,83XY}", '^', flags, 0, 14, "- 1$", "\2\3");
736
737 flags = Left | Right | Showbase;
738 TEST (T, 109, "#####{1,0.9}", '#', Left | Right, 1, 12, "-@1$", "\1");
739 TEST (T, 1060, "####{1,06.0}", '#', Left | Right, 1, 12, "-@1$", "\2");
740 TEST (T, 10571, "###{1,05.71}", '#', Left | Right, 2, 12, "-@1$", "\2");
741 TEST (T, 105682, "##{10,56.82XY}", '#', flags, 2, 14, "-@1$", "\2");
742 TEST (T, 105683, "#{ 10,56.83XY}", '#', flags, 2, 14, "- 1$", "\2");
743 TEST (T, 105684, "#{ 10,56,84XY}", '#', flags, 0, 14, "- 1$", "\2");
744
745
746 // verify that mon_put (..., const basic_string&) ignores the part
747 // of the string starting with the first non-numeric character
748#undef FMT
749#define FMT(fmt) "%.0" _RWSTD_LDBL_PRINTF_PREFIX "f" fmt
750
751 // using default format "\2\3\4\0": {symbol, sign, value, none}
752 TEST (T, 10, "{1.0}", ' ', 0, 1, -1, FMT (" "));
753 TEST (T, 10, "{1.0}", ' ', 0, 1, -1, FMT ("."));
754
755 TEST (T, -11, "(1.1)", ' ', 0, 1, -1, FMT (" "));
756 TEST (T, -11, "(1.1)", ' ', 0, 1, -1, FMT ("."));
757
758 TEST (T, 101, "{1.01}", ' ', 0, 2, -1, FMT (" "));
759 TEST (T, 101, "{1.01}", ' ', 0, 2, -1, FMT ("."));
760
763
764 TEST (T, 1012, "1,0.12", ' ', 0, 2, -1, FMT (" 0"), "\1");
765 TEST (T, 1013, "1,0.13", ' ', 0, 2, -1, FMT (".1"), "\1");
766
767 TEST (T, -1014, "~1,01.4", ' ', 0, 1, -1, FMT ("~2"), "\2");
768 TEST (T, -1015, "~1,01.5", ' ', 0, 1, -1, FMT (",3"), "\2");
769}
770
771
774{
775 if (!rw_enabled ("char")) {
776 rw_note (0, __FILE__, __LINE__, "char test disabled");
777 return;
778 }
779
780 rw_info (0, 0, 0, "std::money_put<%s>::put(ostreambuf_iterator"
781 "<%s>, bool, ios_base, %s, long double); correct use of "
782 "moneypunct<%s, false>::grouping() and thousands_sep()",
783 "char", "char", "char", "char");
784
785 typedef Punct<char, false> PunctT;
786
787 // construct a "replacement" moneypunct-derived facet
788 const PunctT pun;
789
790 // group after every digit
791 PunctT::grouping_ = "\1";
792
793 // reset the do_thousands_sep()-call counter
794 PunctT::thousands_sep_ = ';';
795 PunctT::decimal_point_ = ':';
796 PunctT::n_thousands_sep_ = 0;
797
798 // construct and initialize a basic_ios-derived object
799 struct Ios: std::basic_ios<char> { Ios () { this->init (0); } } ios;
800
801 // construct a money_put-derived facet to exercise
802 struct MoneyPut: std::money_put<char, char*> { } mp;
803
804 // imbue a stream object with a custom locale
805 // containing the replacement punctuation facet
806 std::locale l;
807 std::locale loc (l, (const std::moneypunct<char>*)&pun);
808 ios.imbue (loc);
809
810 // decimal output, no special formatting
811 ios.setf (std::ios::fmtflags ());
812
813 char buf [40] = "";
814
815 *mp.put (buf, false, ios, '\0', 123456789.0L) = '\0';
816
817 // verify that the number was formatted correctly
818 rw_assert (0 == rw_strncmp (buf, "1;2;3;4;5;6;7;8;9"), __FILE__, __LINE__,
819 "money_put<char, char*>::do_put(..., 123456789.0L) "
820 "== %#s, got %#s", "1;2;3;4;5;6;7;8;9", buf);
821
822 // verify that do_thousands_sep() was called at least once
823 // (but not necessarily for each thousands separator inserted
824 // into the output, since the value is allowed to be cached)
825 rw_assert (0 != PunctT::n_thousands_sep_, __FILE__, __LINE__,
826 "money_put<char, char*>::do_put(..., 123456789.0L) "
827 "called moneypunct<char>::do_thousands_sep()");
828}
829
830
832static int
833run_test (int, char*[])
834{
835 // check to see if we can test -0.0
836 static volatile double d = -0.0;
837 test_neg_zero = 1.0 / d < d;
838
839 if (no_grouping)
840 rw_note (0, __FILE__, __LINE__, "grouping test disabled");
841 else
842 grouping_test ();
843
844 if (rw_enabled ("char"))
845 ldbl_test (char ());
846 else
847 rw_note (0, __FILE__, __LINE__, "char test disabled");
848
849#ifndef _RWSTD_NO_WCHAR_T
850
851 if (rw_enabled ("wchar_t"))
852 ldbl_test (wchar_t ());
853 else
854 rw_note (0, __FILE__, __LINE__, "wchar_t test disabled");
855
856#endif // _RWSTD_NO_WCHAR_T
857
858 return 0;
859}
860
861
863int main (int argc, char *argv[])
864{
865 return rw_test (argc, argv, __FILE__,
866 "lib.locale.money.put",
867 0 /* no comment */, run_test,
868 "|-no-grouping# |-no-basic_string#",
869 &no_grouping, &no_basic_string);
870}
#define i
Definition 17.names.cpp:126
#define d
Definition 17.names.cpp:115
#define loc
Definition 17.names.cpp:492
#define f
Definition 17.names.cpp:119
#define Allocator
Definition 17.names.cpp:440
#define Traits
Definition 17.names.cpp:556
#define lineno
Definition 17.names.cpp:491
#define buf
Definition 17.names.cpp:452
#define charT
Definition 17.names.cpp:456
#define val
Definition 17.names.cpp:570
#define T
bool test_neg_zero
#define Left
void grouping_test()
#define Showbase
#define Internal
#define FMT(fmt)
std::money_base::pattern set_pattern(const char *format)
#define Right
#define TEST
#define Fixed
void ldbl_test(charT)
int type_test(int lineno, charT, long double val, const char *str, char fill=' ', int flags=0, int frac_digits=0, int width=0, const char *format=0, const char *grouping=0)
#define flags
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
#define main
#define _RWSTD_LDBL_PRINTF_PREFIX
Definition _config.h:381
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108
std::mbstate_t init
Definition codecvt1.cpp:80
const char * str
Definition exec.cpp:170
Definition json.h:5363
_TEST_EXPORT int rw_enabled(const char *name)
_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
#define RW_ASSERT(expr)
_TEST_EXPORT int rw_strncmp(const char *, const char *, _RWSTD_SIZE_T=_RWSTD_SIZE_MAX, int=CMP_NULTERM)
std::money_put< charT, charT * > Base
virtual string_type do_negative_sign() const
static char_type decimal_point_
static const char_type * negative_sign_
std::moneypunct< charT >::char_type char_type
virtual std::money_base::pattern do_pos_format() const
static const char_type * positive_sign_
int do_frac_digits() const
static int n_thousands_sep_
static const char * grouping_
std::moneypunct< charT >::string_type string_type
static const char_type * curr_symbol_
static char_type thousands_sep_
virtual string_type do_curr_symbol() const
static std::money_base::pattern neg_format_
char_type do_decimal_point() const
static std::money_base::pattern pos_format_
virtual string_type do_positive_sign() const
static int frac_digits_
virtual std::string do_grouping() const
virtual char_type do_thousands_sep() const
Base::char_type char_type
Base::string_type string_type
virtual std::money_base::pattern do_neg_format() const