OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libstdc++-v3/] [include/] [bits/] [locale_facets.tcc] - Blame information for rev 17

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 17 jlechner
// Locale support -*- C++ -*-
2
 
3
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
4
// Free Software Foundation, Inc.
5
//
6
// This file is part of the GNU ISO C++ Library.  This library is free
7
// software; you can redistribute it and/or modify it under the
8
// terms of the GNU General Public License as published by the
9
// Free Software Foundation; either version 2, or (at your option)
10
// any later version.
11
 
12
// This library is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
// GNU General Public License for more details.
16
 
17
// You should have received a copy of the GNU General Public License along
18
// with this library; see the file COPYING.  If not, write to the Free
19
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20
// USA.
21
 
22
// As a special exception, you may use this file as part of a free software
23
// library without restriction.  Specifically, if other files instantiate
24
// templates or use macros or inline functions from this file, or you compile
25
// this file and link it with other files to produce an executable, this
26
// file does not by itself cause the resulting executable to be covered by
27
// the GNU General Public License.  This exception does not however
28
// invalidate any other reasons why the executable file might be covered by
29
// the GNU General Public License.
30
 
31
/** @file locale_facets.tcc
32
 *  This is an internal header file, included by other library headers.
33
 *  You should not attempt to use it directly.
34
 */
35
 
36
#ifndef _LOCALE_FACETS_TCC
37
#define _LOCALE_FACETS_TCC 1
38
 
39
#pragma GCC system_header
40
 
41
#include                // For numeric_limits
42
#include                // For bad_cast.
43
#include 
44
 
45
namespace std
46
{
47
  template
48
    locale
49
    locale::combine(const locale& __other) const
50
    {
51
      _Impl* __tmp = new _Impl(*_M_impl, 1);
52
      try
53
        {
54
          __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
55
        }
56
      catch(...)
57
        {
58
          __tmp->_M_remove_reference();
59
          __throw_exception_again;
60
        }
61
      return locale(__tmp);
62
    }
63
 
64
  template
65
    bool
66
    locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
67
                       const basic_string<_CharT, _Traits, _Alloc>& __s2) const
68
    {
69
      typedef std::collate<_CharT> __collate_type;
70
      const __collate_type& __collate = use_facet<__collate_type>(*this);
71
      return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
72
                                __s2.data(), __s2.data() + __s2.length()) < 0);
73
    }
74
 
75
  /**
76
   *  @brief  Test for the presence of a facet.
77
   *
78
   *  has_facet tests the locale argument for the presence of the facet type
79
   *  provided as the template parameter.  Facets derived from the facet
80
   *  parameter will also return true.
81
   *
82
   *  @param  Facet  The facet type to test the presence of.
83
   *  @param  locale  The locale to test.
84
   *  @return  true if locale contains a facet of type Facet, else false.
85
  */
86
  template
87
    inline bool
88
    has_facet(const locale& __loc) throw()
89
    {
90
      const size_t __i = _Facet::id._M_id();
91
      const locale::facet** __facets = __loc._M_impl->_M_facets;
92
      return (__i < __loc._M_impl->_M_facets_size && __facets[__i]);
93
    }
94
 
95
  /**
96
   *  @brief  Return a facet.
97
   *
98
   *  use_facet looks for and returns a reference to a facet of type Facet
99
   *  where Facet is the template parameter.  If has_facet(locale) is true,
100
   *  there is a suitable facet to return.  It throws std::bad_cast if the
101
   *  locale doesn't contain a facet of type Facet.
102
   *
103
   *  @param  Facet  The facet type to access.
104
   *  @param  locale  The locale to use.
105
   *  @return  Reference to facet of type Facet.
106
   *  @throw  std::bad_cast if locale doesn't contain a facet of type Facet.
107
  */
108
  template
109
    inline const _Facet&
110
    use_facet(const locale& __loc)
111
    {
112
      const size_t __i = _Facet::id._M_id();
113
      const locale::facet** __facets = __loc._M_impl->_M_facets;
114
      if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i]))
115
        __throw_bad_cast();
116
      return static_cast(*__facets[__i]);
117
    }
118
 
119
  // Routine to access a cache for the facet.  If the cache didn't
120
  // exist before, it gets constructed on the fly.
121
  template
122
    struct __use_cache
123
    {
124
      const _Facet*
125
      operator() (const locale& __loc) const;
126
    };
127
 
128
  // Specializations.
129
  template
130
    struct __use_cache<__numpunct_cache<_CharT> >
131
    {
132
      const __numpunct_cache<_CharT>*
133
      operator() (const locale& __loc) const
134
      {
135
        const size_t __i = numpunct<_CharT>::id._M_id();
136
        const locale::facet** __caches = __loc._M_impl->_M_caches;
137
        if (!__caches[__i])
138
          {
139
            __numpunct_cache<_CharT>* __tmp = NULL;
140
            try
141
              {
142
                __tmp = new __numpunct_cache<_CharT>;
143
                __tmp->_M_cache(__loc);
144
              }
145
            catch(...)
146
              {
147
                delete __tmp;
148
                __throw_exception_again;
149
              }
150
            __loc._M_impl->_M_install_cache(__tmp, __i);
151
          }
152
        return static_cast*>(__caches[__i]);
153
      }
154
    };
155
 
156
  template
157
    struct __use_cache<__moneypunct_cache<_CharT, _Intl> >
158
    {
159
      const __moneypunct_cache<_CharT, _Intl>*
160
      operator() (const locale& __loc) const
161
      {
162
        const size_t __i = moneypunct<_CharT, _Intl>::id._M_id();
163
        const locale::facet** __caches = __loc._M_impl->_M_caches;
164
        if (!__caches[__i])
165
          {
166
            __moneypunct_cache<_CharT, _Intl>* __tmp = NULL;
167
            try
168
              {
169
                __tmp = new __moneypunct_cache<_CharT, _Intl>;
170
                __tmp->_M_cache(__loc);
171
              }
172
            catch(...)
173
              {
174
                delete __tmp;
175
                __throw_exception_again;
176
              }
177
            __loc._M_impl->_M_install_cache(__tmp, __i);
178
          }
179
        return static_cast<
180
          const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]);
181
      }
182
    };
183
 
184
  template
185
    void
186
    __numpunct_cache<_CharT>::_M_cache(const locale& __loc)
187
    {
188
      _M_allocated = true;
189
 
190
      const numpunct<_CharT>& __np = use_facet >(__loc);
191
 
192
      _M_grouping_size = __np.grouping().size();
193
      char* __grouping = new char[_M_grouping_size];
194
      __np.grouping().copy(__grouping, _M_grouping_size);
195
      _M_grouping = __grouping;
196
      _M_use_grouping = (_M_grouping_size
197
                         && static_cast(__np.grouping()[0]) > 0);
198
 
199
      _M_truename_size = __np.truename().size();
200
      _CharT* __truename = new _CharT[_M_truename_size];
201
      __np.truename().copy(__truename, _M_truename_size);
202
      _M_truename = __truename;
203
 
204
      _M_falsename_size = __np.falsename().size();
205
      _CharT* __falsename = new _CharT[_M_falsename_size];
206
      __np.falsename().copy(__falsename, _M_falsename_size);
207
      _M_falsename = __falsename;
208
 
209
      _M_decimal_point = __np.decimal_point();
210
      _M_thousands_sep = __np.thousands_sep();
211
 
212
      const ctype<_CharT>& __ct = use_facet >(__loc);
213
      __ct.widen(__num_base::_S_atoms_out,
214
                 __num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out);
215
      __ct.widen(__num_base::_S_atoms_in,
216
                 __num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in);
217
    }
218
 
219
  template
220
    void
221
    __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc)
222
    {
223
      _M_allocated = true;
224
 
225
      const moneypunct<_CharT, _Intl>& __mp =
226
        use_facet >(__loc);
227
 
228
      _M_grouping_size = __mp.grouping().size();
229
      char* __grouping = new char[_M_grouping_size];
230
      __mp.grouping().copy(__grouping, _M_grouping_size);
231
      _M_grouping = __grouping;
232
      _M_use_grouping = (_M_grouping_size
233
                         && static_cast(__mp.grouping()[0]) > 0);
234
 
235
      _M_decimal_point = __mp.decimal_point();
236
      _M_thousands_sep = __mp.thousands_sep();
237
      _M_frac_digits = __mp.frac_digits();
238
 
239
      _M_curr_symbol_size = __mp.curr_symbol().size();
240
      _CharT* __curr_symbol = new _CharT[_M_curr_symbol_size];
241
      __mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size);
242
      _M_curr_symbol = __curr_symbol;
243
 
244
      _M_positive_sign_size = __mp.positive_sign().size();
245
      _CharT* __positive_sign = new _CharT[_M_positive_sign_size];
246
      __mp.positive_sign().copy(__positive_sign, _M_positive_sign_size);
247
      _M_positive_sign = __positive_sign;
248
 
249
      _M_negative_sign_size = __mp.negative_sign().size();
250
      _CharT* __negative_sign = new _CharT[_M_negative_sign_size];
251
      __mp.negative_sign().copy(__negative_sign, _M_negative_sign_size);
252
      _M_negative_sign = __negative_sign;
253
 
254
      _M_pos_format = __mp.pos_format();
255
      _M_neg_format = __mp.neg_format();
256
 
257
      const ctype<_CharT>& __ct = use_facet >(__loc);
258
      __ct.widen(money_base::_S_atoms,
259
                 money_base::_S_atoms + money_base::_S_end, _M_atoms);
260
    }
261
 
262
 
263
  // Used by both numeric and monetary facets.
264
  // Check to make sure that the __grouping_tmp string constructed in
265
  // money_get or num_get matches the canonical grouping for a given
266
  // locale.
267
  // __grouping_tmp is parsed L to R
268
  // 1,222,444 == __grouping_tmp of "\1\3\3"
269
  // __grouping is parsed R to L
270
  // 1,222,444 == __grouping of "\3" == "\3\3\3"
271
  static bool
272
  __verify_grouping(const char* __grouping, size_t __grouping_size,
273
                    const string& __grouping_tmp);
274
 
275
  template
276
    _InIter
277
    num_get<_CharT, _InIter>::
278
    _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
279
                     ios_base::iostate& __err, string& __xtrc) const
280
    {
281
      typedef char_traits<_CharT>                       __traits_type;
282
      typedef __numpunct_cache<_CharT>                  __cache_type;
283
      __use_cache<__cache_type> __uc;
284
      const locale& __loc = __io._M_getloc();
285
      const __cache_type* __lc = __uc(__loc);
286
      const _CharT* __lit = __lc->_M_atoms_in;
287
      char_type __c = char_type();
288
 
289
      // True if __beg becomes equal to __end.
290
      bool __testeof = __beg == __end;
291
 
292
      // First check for sign.
293
      if (!__testeof)
294
        {
295
          __c = *__beg;
296
          const bool __plus = __c == __lit[__num_base::_S_iplus];
297
          if ((__plus || __c == __lit[__num_base::_S_iminus])
298
              && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
299
              && !(__c == __lc->_M_decimal_point))
300
            {
301
              __xtrc += __plus ? '+' : '-';
302
              if (++__beg != __end)
303
                __c = *__beg;
304
              else
305
                __testeof = true;
306
            }
307
        }
308
 
309
      // Next, look for leading zeros.
310
      bool __found_mantissa = false;
311
      int __sep_pos = 0;
312
      while (!__testeof)
313
        {
314
          if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep
315
              || __c == __lc->_M_decimal_point)
316
            break;
317
          else if (__c == __lit[__num_base::_S_izero])
318
            {
319
              if (!__found_mantissa)
320
                {
321
                  __xtrc += '0';
322
                  __found_mantissa = true;
323
                }
324
              ++__sep_pos;
325
 
326
              if (++__beg != __end)
327
                __c = *__beg;
328
              else
329
                __testeof = true;
330
            }
331
          else
332
            break;
333
        }
334
 
335
      // Only need acceptable digits for floating point numbers.
336
      bool __found_dec = false;
337
      bool __found_sci = false;
338
      string __found_grouping;
339
      if (__lc->_M_use_grouping)
340
        __found_grouping.reserve(32);
341
      const char_type* __q;
342
      const char_type* __lit_zero = __lit + __num_base::_S_izero;
343
      while (!__testeof)
344
        {
345
          // According to 22.2.2.1.2, p8-9, first look for thousands_sep
346
          // and decimal_point.
347
          if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
348
            {
349
              if (!__found_dec && !__found_sci)
350
                {
351
                  // NB: Thousands separator at the beginning of a string
352
                  // is a no-no, as is two consecutive thousands separators.
353
                  if (__sep_pos)
354
                    {
355
                      __found_grouping += static_cast(__sep_pos);
356
                      __sep_pos = 0;
357
                    }
358
                  else
359
                    {
360
                      // NB: __convert_to_v will not assign __v and will
361
                      // set the failbit.
362
                      __xtrc.clear();
363
                      break;
364
                    }
365
                }
366
              else
367
                break;
368
            }
369
          else if (__c == __lc->_M_decimal_point)
370
            {
371
              if (!__found_dec && !__found_sci)
372
                {
373
                  // If no grouping chars are seen, no grouping check
374
                  // is applied. Therefore __found_grouping is adjusted
375
                  // only if decimal_point comes after some thousands_sep.
376
                  if (__found_grouping.size())
377
                    __found_grouping += static_cast(__sep_pos);
378
                  __xtrc += '.';
379
                  __found_dec = true;
380
                }
381
              else
382
                break;
383
            }
384
          else if ((__q = __traits_type::find(__lit_zero, 10, __c)))
385
            {
386
              __xtrc += __num_base::_S_atoms_in[__q - __lit];
387
              __found_mantissa = true;
388
              ++__sep_pos;
389
            }
390
          else if ((__c == __lit[__num_base::_S_ie]
391
                    || __c == __lit[__num_base::_S_iE])
392
                   && !__found_sci && __found_mantissa)
393
            {
394
              // Scientific notation.
395
              if (__found_grouping.size() && !__found_dec)
396
                __found_grouping += static_cast(__sep_pos);
397
              __xtrc += 'e';
398
              __found_sci = true;
399
 
400
              // Remove optional plus or minus sign, if they exist.
401
              if (++__beg != __end)
402
                {
403
                  __c = *__beg;
404
                  const bool __plus = __c == __lit[__num_base::_S_iplus];
405
                  if ((__plus || __c == __lit[__num_base::_S_iminus])
406
                      && !(__lc->_M_use_grouping
407
                           && __c == __lc->_M_thousands_sep)
408
                      && !(__c == __lc->_M_decimal_point))
409
                    __xtrc += __plus ? '+' : '-';
410
                  else
411
                    continue;
412
                }
413
              else
414
                {
415
                  __testeof = true;
416
                  break;
417
                }
418
            }
419
          else
420
            // Not a valid input item.
421
            break;
422
 
423
          if (++__beg != __end)
424
            __c = *__beg;
425
          else
426
            __testeof = true;
427
        }
428
 
429
      // Digit grouping is checked. If grouping and found_grouping don't
430
      // match, then get very very upset, and set failbit.
431
      if (__found_grouping.size())
432
        {
433
          // Add the ending grouping if a decimal or 'e'/'E' wasn't found.
434
          if (!__found_dec && !__found_sci)
435
            __found_grouping += static_cast(__sep_pos);
436
 
437
          if (!std::__verify_grouping(__lc->_M_grouping,
438
                                      __lc->_M_grouping_size,
439
                                      __found_grouping))
440
            __err |= ios_base::failbit;
441
        }
442
 
443
      // Finish up.
444
      if (__testeof)
445
        __err |= ios_base::eofbit;
446
      return __beg;
447
    }
448
 
449
  template
450
    struct __to_unsigned_type
451
    { typedef _ValueT __type; };
452
 
453
  template<>
454
    struct __to_unsigned_type
455
    { typedef unsigned long __type; };
456
 
457
#ifdef _GLIBCXX_USE_LONG_LONG
458
  template<>
459
    struct __to_unsigned_type
460
    { typedef unsigned long long __type; };
461
#endif
462
 
463
  template
464
    template
465
      _InIter
466
      num_get<_CharT, _InIter>::
467
      _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
468
                     ios_base::iostate& __err, _ValueT& __v) const
469
      {
470
        typedef char_traits<_CharT>                          __traits_type;
471
        typedef typename __to_unsigned_type<_ValueT>::__type __unsigned_type;
472
        typedef __numpunct_cache<_CharT>                     __cache_type;
473
        __use_cache<__cache_type> __uc;
474
        const locale& __loc = __io._M_getloc();
475
        const __cache_type* __lc = __uc(__loc);
476
        const _CharT* __lit = __lc->_M_atoms_in;
477
        char_type __c = char_type();
478
 
479
        // NB: Iff __basefield == 0, __base can change based on contents.
480
        const ios_base::fmtflags __basefield = __io.flags()
481
                                               & ios_base::basefield;
482
        const bool __oct = __basefield == ios_base::oct;
483
        int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10);
484
 
485
        // True if __beg becomes equal to __end.
486
        bool __testeof = __beg == __end;
487
 
488
        // First check for sign.
489
        bool __negative = false;
490
        if (!__testeof)
491
          {
492
            __c = *__beg;
493
            if (numeric_limits<_ValueT>::is_signed)
494
              __negative = __c == __lit[__num_base::_S_iminus];
495
            if ((__negative || __c == __lit[__num_base::_S_iplus])
496
                && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
497
                && !(__c == __lc->_M_decimal_point))
498
              {
499
                if (++__beg != __end)
500
                  __c = *__beg;
501
                else
502
                  __testeof = true;
503
              }
504
          }
505
 
506
        // Next, look for leading zeros and check required digits
507
        // for base formats.
508
        bool __found_zero = false;
509
        int __sep_pos = 0;
510
        while (!__testeof)
511
          {
512
            if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep
513
                || __c == __lc->_M_decimal_point)
514
              break;
515
            else if (__c == __lit[__num_base::_S_izero]
516
                     && (!__found_zero || __base == 10))
517
              {
518
                __found_zero = true;
519
                ++__sep_pos;
520
                if (__basefield == 0)
521
                  __base = 8;
522
                if (__base == 8)
523
                  __sep_pos = 0;
524
              }
525
            else if (__found_zero
526
                     && (__c == __lit[__num_base::_S_ix]
527
                         || __c == __lit[__num_base::_S_iX]))
528
              {
529
                if (__basefield == 0)
530
                  __base = 16;
531
                if (__base == 16)
532
                  {
533
                    __found_zero = false;
534
                    __sep_pos = 0;
535
                  }
536
                else
537
                  break;
538
              }
539
            else
540
              break;
541
 
542
            if (++__beg != __end)
543
              {
544
                __c = *__beg;
545
                if (!__found_zero)
546
                  break;
547
              }
548
            else
549
              __testeof = true;
550
          }
551
 
552
        // At this point, base is determined. If not hex, only allow
553
        // base digits as valid input.
554
        const size_t __len = (__base == 16 ? __num_base::_S_iend
555
                              - __num_base::_S_izero : __base);
556
 
557
        // Extract.
558
        string __found_grouping;
559
        if (__lc->_M_use_grouping)
560
          __found_grouping.reserve(32);
561
        bool __testfail = false;
562
        const __unsigned_type __max = __negative ?
563
          -numeric_limits<_ValueT>::min() : numeric_limits<_ValueT>::max();
564
        const __unsigned_type __smax = __max / __base;
565
        __unsigned_type __result = 0;
566
        const char_type* __q;
567
        const char_type* __lit_zero = __lit + __num_base::_S_izero;
568
        while (!__testeof)
569
          {
570
            // According to 22.2.2.1.2, p8-9, first look for thousands_sep
571
            // and decimal_point.
572
            if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
573
              {
574
                // NB: Thousands separator at the beginning of a string
575
                // is a no-no, as is two consecutive thousands separators.
576
                if (__sep_pos)
577
                  {
578
                    __found_grouping += static_cast(__sep_pos);
579
                    __sep_pos = 0;
580
                  }
581
                else
582
                  {
583
                    __testfail = true;
584
                    break;
585
                  }
586
              }
587
            else if (__c == __lc->_M_decimal_point)
588
              break;
589
            else if ((__q = __traits_type::find(__lit_zero, __len, __c)))
590
              {
591
                int __digit = __q - __lit_zero;
592
                if (__digit > 15)
593
                  __digit -= 6;
594
                if (__result > __smax)
595
                  __testfail = true;
596
                else
597
                  {
598
                    __result *= __base;
599
                    __testfail |= __result > __max - __digit;
600
                    __result += __digit;
601
                    ++__sep_pos;
602
                  }
603
              }
604
            else
605
              // Not a valid input item.
606
              break;
607
 
608
            if (++__beg != __end)
609
              __c = *__beg;
610
            else
611
              __testeof = true;
612
          }
613
 
614
        // Digit grouping is checked. If grouping and found_grouping don't
615
        // match, then get very very upset, and set failbit.
616
        if (__found_grouping.size())
617
          {
618
            // Add the ending grouping.
619
            __found_grouping += static_cast(__sep_pos);
620
 
621
            if (!std::__verify_grouping(__lc->_M_grouping,
622
                                        __lc->_M_grouping_size,
623
                                        __found_grouping))
624
              __err |= ios_base::failbit;
625
          }
626
 
627
        if (!__testfail && (__sep_pos || __found_zero
628
                            || __found_grouping.size()))
629
          __v = __negative ? -__result : __result;
630
        else
631
          __err |= ios_base::failbit;
632
 
633
        if (__testeof)
634
          __err |= ios_base::eofbit;
635
        return __beg;
636
      }
637
 
638
  // _GLIBCXX_RESOLVE_LIB_DEFECTS
639
  // 17.  Bad bool parsing
640
  template
641
    _InIter
642
    num_get<_CharT, _InIter>::
643
    do_get(iter_type __beg, iter_type __end, ios_base& __io,
644
           ios_base::iostate& __err, bool& __v) const
645
    {
646
      if (!(__io.flags() & ios_base::boolalpha))
647
        {
648
          // Parse bool values as long.
649
          // NB: We can't just call do_get(long) here, as it might
650
          // refer to a derived class.
651
          long __l = -1;
652
          __beg = _M_extract_int(__beg, __end, __io, __err, __l);
653
          if (__l == 0 || __l == 1)
654
            __v = __l;
655
          else
656
            __err |= ios_base::failbit;
657
        }
658
      else
659
        {
660
          // Parse bool values as alphanumeric.
661
          typedef __numpunct_cache<_CharT>              __cache_type;
662
          __use_cache<__cache_type> __uc;
663
          const locale& __loc = __io._M_getloc();
664
          const __cache_type* __lc = __uc(__loc);
665
 
666
          bool __testf = true;
667
          bool __testt = true;
668
          size_t __n;
669
          bool __testeof = __beg == __end;
670
          for (__n = 0; !__testeof; ++__n)
671
            {
672
              const char_type __c = *__beg;
673
 
674
              if (__testf)
675
                if (__n < __lc->_M_falsename_size)
676
                  __testf = __c == __lc->_M_falsename[__n];
677
                else
678
                  break;
679
 
680
              if (__testt)
681
                if (__n < __lc->_M_truename_size)
682
                  __testt = __c == __lc->_M_truename[__n];
683
                else
684
                  break;
685
 
686
              if (!__testf && !__testt)
687
                break;
688
 
689
              if (++__beg == __end)
690
                __testeof = true;
691
            }
692
          if (__testf && __n == __lc->_M_falsename_size)
693
            __v = 0;
694
          else if (__testt && __n == __lc->_M_truename_size)
695
            __v = 1;
696
          else
697
            __err |= ios_base::failbit;
698
 
699
          if (__testeof)
700
            __err |= ios_base::eofbit;
701
        }
702
      return __beg;
703
    }
704
 
705
  template
706
    _InIter
707
    num_get<_CharT, _InIter>::
708
    do_get(iter_type __beg, iter_type __end, ios_base& __io,
709
           ios_base::iostate& __err, long& __v) const
710
    { return _M_extract_int(__beg, __end, __io, __err, __v); }
711
 
712
  template
713
    _InIter
714
    num_get<_CharT, _InIter>::
715
    do_get(iter_type __beg, iter_type __end, ios_base& __io,
716
           ios_base::iostate& __err, unsigned short& __v) const
717
    { return _M_extract_int(__beg, __end, __io, __err, __v); }
718
 
719
  template
720
    _InIter
721
    num_get<_CharT, _InIter>::
722
    do_get(iter_type __beg, iter_type __end, ios_base& __io,
723
           ios_base::iostate& __err, unsigned int& __v) const
724
    { return _M_extract_int(__beg, __end, __io, __err, __v); }
725
 
726
  template
727
    _InIter
728
    num_get<_CharT, _InIter>::
729
    do_get(iter_type __beg, iter_type __end, ios_base& __io,
730
           ios_base::iostate& __err, unsigned long& __v) const
731
    { return _M_extract_int(__beg, __end, __io, __err, __v); }
732
 
733
#ifdef _GLIBCXX_USE_LONG_LONG
734
  template
735
    _InIter
736
    num_get<_CharT, _InIter>::
737
    do_get(iter_type __beg, iter_type __end, ios_base& __io,
738
           ios_base::iostate& __err, long long& __v) const
739
    { return _M_extract_int(__beg, __end, __io, __err, __v); }
740
 
741
  template
742
    _InIter
743
    num_get<_CharT, _InIter>::
744
    do_get(iter_type __beg, iter_type __end, ios_base& __io,
745
           ios_base::iostate& __err, unsigned long long& __v) const
746
    { return _M_extract_int(__beg, __end, __io, __err, __v); }
747
#endif
748
 
749
  template
750
    _InIter
751
    num_get<_CharT, _InIter>::
752
    do_get(iter_type __beg, iter_type __end, ios_base& __io,
753
           ios_base::iostate& __err, float& __v) const
754
    {
755
      string __xtrc;
756
      __xtrc.reserve(32);
757
      __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
758
      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
759
      return __beg;
760
    }
761
 
762
  template
763
    _InIter
764
    num_get<_CharT, _InIter>::
765
    do_get(iter_type __beg, iter_type __end, ios_base& __io,
766
           ios_base::iostate& __err, double& __v) const
767
    {
768
      string __xtrc;
769
      __xtrc.reserve(32);
770
      __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
771
      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
772
      return __beg;
773
    }
774
 
775
  template
776
    _InIter
777
    num_get<_CharT, _InIter>::
778
    do_get(iter_type __beg, iter_type __end, ios_base& __io,
779
           ios_base::iostate& __err, long double& __v) const
780
    {
781
      string __xtrc;
782
      __xtrc.reserve(32);
783
      __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
784
      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
785
      return __beg;
786
    }
787
 
788
  template
789
    _InIter
790
    num_get<_CharT, _InIter>::
791
    do_get(iter_type __beg, iter_type __end, ios_base& __io,
792
           ios_base::iostate& __err, void*& __v) const
793
    {
794
      // Prepare for hex formatted input.
795
      typedef ios_base::fmtflags        fmtflags;
796
      const fmtflags __fmt = __io.flags();
797
      __io.flags(__fmt & ~ios_base::basefield | ios_base::hex);
798
 
799
      unsigned long __ul;
800
      __beg = _M_extract_int(__beg, __end, __io, __err, __ul);
801
 
802
      // Reset from hex formatted input.
803
      __io.flags(__fmt);
804
 
805
      if (!(__err & ios_base::failbit))
806
        __v = reinterpret_cast(__ul);
807
      return __beg;
808
    }
809
 
810
  // For use by integer and floating-point types after they have been
811
  // converted into a char_type string.
812
  template
813
    void
814
    num_put<_CharT, _OutIter>::
815
    _M_pad(_CharT __fill, streamsize __w, ios_base& __io,
816
           _CharT* __new, const _CharT* __cs, int& __len) const
817
    {
818
      // [22.2.2.2.2] Stage 3.
819
      // If necessary, pad.
820
      __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new, __cs,
821
                                                  __w, __len, true);
822
      __len = static_cast(__w);
823
    }
824
 
825
  // Forwarding functions to peel signed from unsigned integer types and
826
  // either cast or compute the absolute value for the former, depending
827
  // on __basefield.
828
  template
829
    inline int
830
    __int_to_char(_CharT* __bufend, long __v, const _CharT* __lit,
831
                  ios_base::fmtflags __flags)
832
    {
833
      unsigned long __ul = __v;
834
      const ios_base::fmtflags __basefield = __flags & ios_base::basefield;
835
      if (__builtin_expect(__basefield != ios_base::oct
836
                           && __basefield != ios_base::hex, true))
837
        __ul = __v < 0 ? -__v : __ul;
838
      return __int_to_char(__bufend, __ul, __lit, __flags, false);
839
    }
840
 
841
  template
842
    inline int
843
    __int_to_char(_CharT* __bufend, unsigned long __v, const _CharT* __lit,
844
                  ios_base::fmtflags __flags)
845
    { return __int_to_char(__bufend, __v, __lit, __flags, false); }
846
 
847
#ifdef _GLIBCXX_USE_LONG_LONG
848
  template
849
    inline int
850
    __int_to_char(_CharT* __bufend, long long __v, const _CharT* __lit,
851
                  ios_base::fmtflags __flags)
852
    {
853
      unsigned long long __ull = __v;
854
      const ios_base::fmtflags __basefield = __flags & ios_base::basefield;
855
      if (__builtin_expect(__basefield != ios_base::oct
856
                           && __basefield != ios_base::hex, true))
857
        __ull = __v < 0 ? -__v : __ull;
858
      return __int_to_char(__bufend, __ull, __lit, __flags, false);
859
    }
860
 
861
  template
862
    inline int
863
    __int_to_char(_CharT* __bufend, unsigned long long __v,
864
                  const _CharT* __lit, ios_base::fmtflags __flags)
865
    { return __int_to_char(__bufend, __v, __lit, __flags, false); }
866
#endif
867
 
868
  // N.B. The last argument is currently unused (see libstdc++/20914).
869
  template
870
    int
871
    __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit,
872
                  ios_base::fmtflags __flags, bool)
873
    {
874
      const ios_base::fmtflags __basefield = __flags & ios_base::basefield;
875
      _CharT* __buf = __bufend;
876
 
877
      if (__builtin_expect(__basefield != ios_base::oct
878
                           && __basefield != ios_base::hex, true))
879
        {
880
          // Decimal.
881
          do
882
            {
883
              *--__buf = __lit[(__v % 10) + __num_base::_S_odigits];
884
              __v /= 10;
885
            }
886
          while (__v != 0);
887
        }
888
      else if (__basefield == ios_base::oct)
889
        {
890
          // Octal.
891
          do
892
            {
893
              *--__buf = __lit[(__v & 0x7) + __num_base::_S_odigits];
894
              __v >>= 3;
895
            }
896
          while (__v != 0);
897
        }
898
      else
899
        {
900
          // Hex.
901
          const bool __uppercase = __flags & ios_base::uppercase;
902
          const int __case_offset = __uppercase ? __num_base::_S_oudigits
903
                                                : __num_base::_S_odigits;
904
          do
905
            {
906
              *--__buf = __lit[(__v & 0xf) + __case_offset];
907
              __v >>= 4;
908
            }
909
          while (__v != 0);
910
        }
911
      return __bufend - __buf;
912
    }
913
 
914
  template
915
    void
916
    num_put<_CharT, _OutIter>::
917
    _M_group_int(const char* __grouping, size_t __grouping_size, _CharT __sep,
918
                 ios_base&, _CharT* __new, _CharT* __cs, int& __len) const
919
    {
920
      _CharT* __p = std::__add_grouping(__new, __sep, __grouping,
921
                                        __grouping_size, __cs, __cs + __len);
922
      __len = __p - __new;
923
    }
924
 
925
  template
926
    template
927
      _OutIter
928
      num_put<_CharT, _OutIter>::
929
      _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill,
930
                    _ValueT __v) const
931
      {
932
        typedef __numpunct_cache<_CharT>                __cache_type;
933
        __use_cache<__cache_type> __uc;
934
        const locale& __loc = __io._M_getloc();
935
        const __cache_type* __lc = __uc(__loc);
936
        const _CharT* __lit = __lc->_M_atoms_out;
937
        const ios_base::fmtflags __flags = __io.flags();
938
 
939
        // Long enough to hold hex, dec, and octal representations.
940
        const int __ilen = 5 * sizeof(_ValueT);
941
        _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
942
                                                             * __ilen));
943
 
944
        // [22.2.2.2.2] Stage 1, numeric conversion to character.
945
        // Result is returned right-justified in the buffer.
946
        int __len = __int_to_char(__cs + __ilen, __v, __lit, __flags);
947
        __cs += __ilen - __len;
948
 
949
        // Add grouping, if necessary.
950
        if (__lc->_M_use_grouping)
951
          {
952
            // Grouping can add (almost) as many separators as the number
953
            // of digits + space is reserved for numeric base or sign.
954
            _CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
955
                                                                  * (__len + 1)
956
                                                                  * 2));
957
            _M_group_int(__lc->_M_grouping, __lc->_M_grouping_size,
958
                         __lc->_M_thousands_sep, __io, __cs2 + 2, __cs, __len);
959
            __cs = __cs2 + 2;
960
          }
961
 
962
        // Complete Stage 1, prepend numeric base or sign.
963
        const ios_base::fmtflags __basefield = __flags & ios_base::basefield;
964
        if (__builtin_expect(__basefield != ios_base::oct
965
                             && __basefield != ios_base::hex, true))
966
          {
967
            // Decimal.
968
            if (__v > 0)
969
              {
970
                if (__flags & ios_base::showpos
971
                    && numeric_limits<_ValueT>::is_signed)
972
                  *--__cs = __lit[__num_base::_S_oplus], ++__len;
973
              }
974
            else if (__v)
975
              *--__cs = __lit[__num_base::_S_ominus], ++__len;
976
          }
977
        else if (__flags & ios_base::showbase && __v)
978
          {
979
            if (__basefield == ios_base::oct)
980
              *--__cs = __lit[__num_base::_S_odigits], ++__len;
981
            else
982
              {
983
                // 'x' or 'X'
984
                const bool __uppercase = __flags & ios_base::uppercase;
985
                *--__cs = __lit[__num_base::_S_ox + __uppercase];
986
                // '0'
987
                *--__cs = __lit[__num_base::_S_odigits];
988
                __len += 2;
989
              }
990
          }
991
 
992
        // Pad.
993
        const streamsize __w = __io.width();
994
        if (__w > static_cast(__len))
995
          {
996
            _CharT* __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
997
                                                                  * __w));
998
            _M_pad(__fill, __w, __io, __cs3, __cs, __len);
999
            __cs = __cs3;
1000
          }
1001
        __io.width(0);
1002
 
1003
        // [22.2.2.2.2] Stage 4.
1004
        // Write resulting, fully-formatted string to output iterator.
1005
        return std::__write(__s, __cs, __len);
1006
      }
1007
 
1008
  template
1009
    void
1010
    num_put<_CharT, _OutIter>::
1011
    _M_group_float(const char* __grouping, size_t __grouping_size,
1012
                   _CharT __sep, const _CharT* __p, _CharT* __new,
1013
                   _CharT* __cs, int& __len) const
1014
    {
1015
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
1016
      // 282. What types does numpunct grouping refer to?
1017
      // Add grouping, if necessary.
1018
      const int __declen = __p ? __p - __cs : __len;
1019
      _CharT* __p2 = std::__add_grouping(__new, __sep, __grouping,
1020
                                         __grouping_size,
1021
                                         __cs, __cs + __declen);
1022
 
1023
      // Tack on decimal part.
1024
      int __newlen = __p2 - __new;
1025
      if (__p)
1026
        {
1027
          char_traits<_CharT>::copy(__p2, __p, __len - __declen);
1028
          __newlen += __len - __declen;
1029
        }
1030
      __len = __newlen;
1031
    }
1032
 
1033
  // The following code uses snprintf (or sprintf(), when
1034
  // _GLIBCXX_USE_C99 is not defined) to convert floating point values
1035
  // for insertion into a stream.  An optimization would be to replace
1036
  // them with code that works directly on a wide buffer and then use
1037
  // __pad to do the padding.  It would be good to replace them anyway
1038
  // to gain back the efficiency that C++ provides by knowing up front
1039
  // the type of the values to insert.  Also, sprintf is dangerous
1040
  // since may lead to accidental buffer overruns.  This
1041
  // implementation follows the C++ standard fairly directly as
1042
  // outlined in 22.2.2.2 [lib.locale.num.put]
1043
  template
1044
    template
1045
      _OutIter
1046
      num_put<_CharT, _OutIter>::
1047
      _M_insert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
1048
                       _ValueT __v) const
1049
      {
1050
        typedef __numpunct_cache<_CharT>                __cache_type;
1051
        __use_cache<__cache_type> __uc;
1052
        const locale& __loc = __io._M_getloc();
1053
        const __cache_type* __lc = __uc(__loc);
1054
 
1055
        // Use default precision if out of range.
1056
        streamsize __prec = __io.precision();
1057
        if (__prec < static_cast(0))
1058
          __prec = static_cast(6);
1059
 
1060
        const int __max_digits = numeric_limits<_ValueT>::digits10;
1061
 
1062
        // [22.2.2.2.2] Stage 1, numeric conversion to character.
1063
        int __len;
1064
        // Long enough for the max format spec.
1065
        char __fbuf[16];
1066
 
1067
#ifdef _GLIBCXX_USE_C99
1068
        // First try a buffer perhaps big enough (most probably sufficient
1069
        // for non-ios_base::fixed outputs)
1070
        int __cs_size = __max_digits * 3;
1071
        char* __cs = static_cast(__builtin_alloca(__cs_size));
1072
 
1073
        __num_base::_S_format_float(__io, __fbuf, __mod);
1074
        __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v,
1075
                                      _S_get_c_locale(), __prec);
1076
 
1077
        // If the buffer was not large enough, try again with the correct size.
1078
        if (__len >= __cs_size)
1079
          {
1080
            __cs_size = __len + 1;
1081
            __cs = static_cast(__builtin_alloca(__cs_size));
1082
            __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v,
1083
                                          _S_get_c_locale(), __prec);
1084
          }
1085
#else
1086
        // Consider the possibility of long ios_base::fixed outputs
1087
        const bool __fixed = __io.flags() & ios_base::fixed;
1088
        const int __max_exp = numeric_limits<_ValueT>::max_exponent10;
1089
 
1090
        // The size of the output string is computed as follows.
1091
        // ios_base::fixed outputs may need up to __max_exp + 1 chars
1092
        // for the integer part + __prec chars for the fractional part
1093
        // + 3 chars for sign, decimal point, '\0'. On the other hand,
1094
        // for non-fixed outputs __max_digits * 2 + __prec chars are
1095
        // largely sufficient.
1096
        const int __cs_size = __fixed ? __max_exp + __prec + 4
1097
                                      : __max_digits * 2 + __prec;
1098
        char* __cs = static_cast(__builtin_alloca(__cs_size));
1099
 
1100
        __num_base::_S_format_float(__io, __fbuf, __mod);
1101
        __len = std::__convert_from_v(__cs, 0, __fbuf, __v,
1102
                                      _S_get_c_locale(), __prec);
1103
#endif
1104
 
1105
        // [22.2.2.2.2] Stage 2, convert to char_type, using correct
1106
        // numpunct.decimal_point() values for '.' and adding grouping.
1107
        const ctype<_CharT>& __ctype = use_facet >(__loc);
1108
 
1109
        _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1110
                                                             * __len));
1111
        __ctype.widen(__cs, __cs + __len, __ws);
1112
 
1113
        // Replace decimal point.
1114
        const _CharT __cdec = __ctype.widen('.');
1115
        const _CharT __dec = __lc->_M_decimal_point;
1116
        const _CharT* __p = char_traits<_CharT>::find(__ws, __len, __cdec);
1117
        if (__p)
1118
          __ws[__p - __ws] = __dec;
1119
 
1120
        // Add grouping, if necessary.
1121
        // N.B. Make sure to not group things like 2e20, i.e., no decimal
1122
        // point, scientific notation.
1123
        if (__lc->_M_use_grouping
1124
            && (__p || __len < 3 || (__cs[1] <= '9' && __cs[2] <= '9'
1125
                                     && __cs[1] >= '0' && __cs[2] >= '0')))
1126
          {
1127
            // Grouping can add (almost) as many separators as the
1128
            // number of digits, but no more.
1129
            _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1130
                                                                  * __len * 2));
1131
 
1132
            streamsize __off = 0;
1133
            if (__cs[0] == '-' || __cs[0] == '+')
1134
              {
1135
                __off = 1;
1136
                __ws2[0] = __ws[0];
1137
                __len -= 1;
1138
              }
1139
 
1140
            _M_group_float(__lc->_M_grouping, __lc->_M_grouping_size,
1141
                           __lc->_M_thousands_sep, __p, __ws2 + __off,
1142
                           __ws + __off, __len);
1143
            __len += __off;
1144
 
1145
            __ws = __ws2;
1146
          }
1147
 
1148
        // Pad.
1149
        const streamsize __w = __io.width();
1150
        if (__w > static_cast(__len))
1151
          {
1152
            _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1153
                                                                  * __w));
1154
            _M_pad(__fill, __w, __io, __ws3, __ws, __len);
1155
            __ws = __ws3;
1156
          }
1157
        __io.width(0);
1158
 
1159
        // [22.2.2.2.2] Stage 4.
1160
        // Write resulting, fully-formatted string to output iterator.
1161
        return std::__write(__s, __ws, __len);
1162
      }
1163
 
1164
  template
1165
    _OutIter
1166
    num_put<_CharT, _OutIter>::
1167
    do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
1168
    {
1169
      const ios_base::fmtflags __flags = __io.flags();
1170
      if ((__flags & ios_base::boolalpha) == 0)
1171
        {
1172
          const long __l = __v;
1173
          __s = _M_insert_int(__s, __io, __fill, __l);
1174
        }
1175
      else
1176
        {
1177
          typedef __numpunct_cache<_CharT>              __cache_type;
1178
          __use_cache<__cache_type> __uc;
1179
          const locale& __loc = __io._M_getloc();
1180
          const __cache_type* __lc = __uc(__loc);
1181
 
1182
          const _CharT* __name = __v ? __lc->_M_truename
1183
                                     : __lc->_M_falsename;
1184
          int __len = __v ? __lc->_M_truename_size
1185
                          : __lc->_M_falsename_size;
1186
 
1187
          const streamsize __w = __io.width();
1188
          if (__w > static_cast(__len))
1189
            {
1190
              _CharT* __cs
1191
                = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1192
                                                        * __w));
1193
              _M_pad(__fill, __w, __io, __cs, __name, __len);
1194
              __name = __cs;
1195
            }
1196
          __io.width(0);
1197
          __s = std::__write(__s, __name, __len);
1198
        }
1199
      return __s;
1200
    }
1201
 
1202
  template
1203
    _OutIter
1204
    num_put<_CharT, _OutIter>::
1205
    do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const
1206
    { return _M_insert_int(__s, __io, __fill, __v); }
1207
 
1208
  template
1209
    _OutIter
1210
    num_put<_CharT, _OutIter>::
1211
    do_put(iter_type __s, ios_base& __io, char_type __fill,
1212
           unsigned long __v) const
1213
    { return _M_insert_int(__s, __io, __fill, __v); }
1214
 
1215
#ifdef _GLIBCXX_USE_LONG_LONG
1216
  template
1217
    _OutIter
1218
    num_put<_CharT, _OutIter>::
1219
    do_put(iter_type __s, ios_base& __io, char_type __fill, long long __v) const
1220
    { return _M_insert_int(__s, __io, __fill, __v); }
1221
 
1222
  template
1223
    _OutIter
1224
    num_put<_CharT, _OutIter>::
1225
    do_put(iter_type __s, ios_base& __io, char_type __fill,
1226
           unsigned long long __v) const
1227
    { return _M_insert_int(__s, __io, __fill, __v); }
1228
#endif
1229
 
1230
  template
1231
    _OutIter
1232
    num_put<_CharT, _OutIter>::
1233
    do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
1234
    { return _M_insert_float(__s, __io, __fill, char(), __v); }
1235
 
1236
  template
1237
    _OutIter
1238
    num_put<_CharT, _OutIter>::
1239
    do_put(iter_type __s, ios_base& __io, char_type __fill,
1240
           long double __v) const
1241
    { return _M_insert_float(__s, __io, __fill, 'L', __v); }
1242
 
1243
  template
1244
    _OutIter
1245
    num_put<_CharT, _OutIter>::
1246
    do_put(iter_type __s, ios_base& __io, char_type __fill,
1247
           const void* __v) const
1248
    {
1249
      const ios_base::fmtflags __flags = __io.flags();
1250
      const ios_base::fmtflags __fmt = ~(ios_base::basefield
1251
                                         | ios_base::uppercase
1252
                                         | ios_base::internal);
1253
      __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase));
1254
 
1255
      __s = _M_insert_int(__s, __io, __fill,
1256
                          reinterpret_cast(__v));
1257
      __io.flags(__flags);
1258
      return __s;
1259
    }
1260
 
1261
  template
1262
    template
1263
      _InIter
1264
      money_get<_CharT, _InIter>::
1265
      _M_extract(iter_type __beg, iter_type __end, ios_base& __io,
1266
                 ios_base::iostate& __err, string& __units) const
1267
      {
1268
        typedef char_traits<_CharT>                       __traits_type;
1269
        typedef typename string_type::size_type           size_type;
1270
        typedef money_base::part                          part;
1271
        typedef __moneypunct_cache<_CharT, _Intl>         __cache_type;
1272
 
1273
        const locale& __loc = __io._M_getloc();
1274
        const ctype<_CharT>& __ctype = use_facet >(__loc);
1275
 
1276
        __use_cache<__cache_type> __uc;
1277
        const __cache_type* __lc = __uc(__loc);
1278
        const char_type* __lit = __lc->_M_atoms;
1279
 
1280
        // Deduced sign.
1281
        bool __negative = false;
1282
        // Sign size.
1283
        size_type __sign_size = 0;
1284
        // True if sign is mandatory.
1285
        const bool __mandatory_sign = (__lc->_M_positive_sign_size
1286
                                       && __lc->_M_negative_sign_size);
1287
        // String of grouping info from thousands_sep plucked from __units.
1288
        string __grouping_tmp;
1289
        if (__lc->_M_use_grouping)
1290
          __grouping_tmp.reserve(32);
1291
        // Last position before the decimal point.
1292
        int __last_pos = 0;
1293
        // Separator positions, then, possibly, fractional digits.
1294
        int __n = 0;
1295
        // If input iterator is in a valid state.
1296
        bool __testvalid = true;
1297
        // Flag marking when a decimal point is found.
1298
        bool __testdecfound = false;
1299
 
1300
        // The tentative returned string is stored here.
1301
        string __res;
1302
        __res.reserve(32);
1303
 
1304
        const char_type* __lit_zero = __lit + money_base::_S_zero;
1305
        const money_base::pattern __p = __lc->_M_neg_format;
1306
        for (int __i = 0; __i < 4 && __testvalid; ++__i)
1307
          {
1308
            const part __which = static_cast(__p.field[__i]);
1309
            switch (__which)
1310
              {
1311
              case money_base::symbol:
1312
                // According to 22.2.6.1.2, p2, symbol is required
1313
                // if (__io.flags() & ios_base::showbase), otherwise
1314
                // is optional and consumed only if other characters
1315
                // are needed to complete the format.
1316
                if (__io.flags() & ios_base::showbase || __sign_size > 1
1317
                    || __i == 0
1318
                    || (__i == 1 && (__mandatory_sign
1319
                                     || (static_cast(__p.field[0])
1320
                                         == money_base::sign)
1321
                                     || (static_cast(__p.field[2])
1322
                                         == money_base::space)))
1323
                    || (__i == 2 && ((static_cast(__p.field[3])
1324
                                      == money_base::value)
1325
                                     || __mandatory_sign
1326
                                     && (static_cast(__p.field[3])
1327
                                         == money_base::sign))))
1328
                  {
1329
                    const size_type __len = __lc->_M_curr_symbol_size;
1330
                    size_type __j = 0;
1331
                    for (; __beg != __end && __j < __len
1332
                           && *__beg == __lc->_M_curr_symbol[__j];
1333
                         ++__beg, ++__j);
1334
                    if (__j != __len
1335
                        && (__j || __io.flags() & ios_base::showbase))
1336
                      __testvalid = false;
1337
                  }
1338
                break;
1339
              case money_base::sign:
1340
                // Sign might not exist, or be more than one character long.
1341
                if (__lc->_M_positive_sign_size && __beg != __end
1342
                    && *__beg == __lc->_M_positive_sign[0])
1343
                  {
1344
                    __sign_size = __lc->_M_positive_sign_size;
1345
                    ++__beg;
1346
                  }
1347
                else if (__lc->_M_negative_sign_size && __beg != __end
1348
                         && *__beg == __lc->_M_negative_sign[0])
1349
                  {
1350
                    __negative = true;
1351
                    __sign_size = __lc->_M_negative_sign_size;
1352
                    ++__beg;
1353
                  }
1354
                else if (__lc->_M_positive_sign_size
1355
                         && !__lc->_M_negative_sign_size)
1356
                  // "... if no sign is detected, the result is given the sign
1357
                  // that corresponds to the source of the empty string"
1358
                  __negative = true;
1359
                else if (__mandatory_sign)
1360
                  __testvalid = false;
1361
                break;
1362
              case money_base::value:
1363
                // Extract digits, remove and stash away the
1364
                // grouping of found thousands separators.
1365
                for (; __beg != __end; ++__beg)
1366
                  {
1367
                    const char_type __c = *__beg;
1368
                    const char_type* __q = __traits_type::find(__lit_zero,
1369
                                                               10, __c);
1370
                    if (__q != 0)
1371
                      {
1372
                        __res += money_base::_S_atoms[__q - __lit];
1373
                        ++__n;
1374
                      }
1375
                    else if (__c == __lc->_M_decimal_point
1376
                             && !__testdecfound)
1377
                      {
1378
                        __last_pos = __n;
1379
                        __n = 0;
1380
                        __testdecfound = true;
1381
                      }
1382
                    else if (__lc->_M_use_grouping
1383
                             && __c == __lc->_M_thousands_sep
1384
                             && !__testdecfound)
1385
                      {
1386
                        if (__n)
1387
                          {
1388
                            // Mark position for later analysis.
1389
                            __grouping_tmp += static_cast(__n);
1390
                            __n = 0;
1391
                          }
1392
                        else
1393
                          {
1394
                            __testvalid = false;
1395
                            break;
1396
                          }
1397
                      }
1398
                    else
1399
                      break;
1400
                  }
1401
                if (__res.empty())
1402
                  __testvalid = false;
1403
                break;
1404
              case money_base::space:
1405
                // At least one space is required.
1406
                if (__beg != __end && __ctype.is(ctype_base::space, *__beg))
1407
                  ++__beg;
1408
                else
1409
                  __testvalid = false;
1410
              case money_base::none:
1411
                // Only if not at the end of the pattern.
1412
                if (__i != 3)
1413
                  for (; __beg != __end
1414
                         && __ctype.is(ctype_base::space, *__beg); ++__beg);
1415
                break;
1416
              }
1417
          }
1418
 
1419
        // Need to get the rest of the sign characters, if they exist.
1420
        if (__sign_size > 1 && __testvalid)
1421
          {
1422
            const char_type* __sign = __negative ? __lc->_M_negative_sign
1423
                                                 : __lc->_M_positive_sign;
1424
            size_type __i = 1;
1425
            for (; __beg != __end && __i < __sign_size
1426
                   && *__beg == __sign[__i]; ++__beg, ++__i);
1427
 
1428
            if (__i != __sign_size)
1429
              __testvalid = false;
1430
          }
1431
 
1432
        if (__testvalid)
1433
          {
1434
            // Strip leading zeros.
1435
            if (__res.size() > 1)
1436
              {
1437
                const size_type __first = __res.find_first_not_of('0');
1438
                const bool __only_zeros = __first == string::npos;
1439
                if (__first)
1440
                  __res.erase(0, __only_zeros ? __res.size() - 1 : __first);
1441
              }
1442
 
1443
            // 22.2.6.1.2, p4
1444
            if (__negative && __res[0] != '0')
1445
              __res.insert(__res.begin(), '-');
1446
 
1447
            // Test for grouping fidelity.
1448
            if (__grouping_tmp.size())
1449
              {
1450
                // Add the ending grouping.
1451
                __grouping_tmp += static_cast(__testdecfound ? __last_pos
1452
                                                                   : __n);
1453
                if (!std::__verify_grouping(__lc->_M_grouping,
1454
                                            __lc->_M_grouping_size,
1455
                                            __grouping_tmp))
1456
                  __err |= ios_base::failbit;
1457
              }
1458
 
1459
            // Iff not enough digits were supplied after the decimal-point.
1460
            if (__testdecfound && __lc->_M_frac_digits > 0
1461
                && __n != __lc->_M_frac_digits)
1462
              __testvalid = false;
1463
          }
1464
 
1465
        // Iff valid sequence is not recognized.
1466
        if (!__testvalid)
1467
          __err |= ios_base::failbit;
1468
        else
1469
          __units.swap(__res);
1470
 
1471
        // Iff no more characters are available.
1472
        if (__beg == __end)
1473
          __err |= ios_base::eofbit;
1474
        return __beg;
1475
      }
1476
 
1477
  template
1478
    _InIter
1479
    money_get<_CharT, _InIter>::
1480
    do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
1481
           ios_base::iostate& __err, long double& __units) const
1482
    {
1483
      string __str;
1484
      if (__intl)
1485
        __beg = _M_extract(__beg, __end, __io, __err, __str);
1486
      else
1487
        __beg = _M_extract(__beg, __end, __io, __err, __str);
1488
      std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale());
1489
      return __beg;
1490
    }
1491
 
1492
  template
1493
    _InIter
1494
    money_get<_CharT, _InIter>::
1495
    do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io,
1496
           ios_base::iostate& __err, string_type& __units) const
1497
    {
1498
      typedef typename string::size_type                  size_type;
1499
 
1500
      const locale& __loc = __io._M_getloc();
1501
      const ctype<_CharT>& __ctype = use_facet >(__loc);
1502
 
1503
      string __str;
1504
      const iter_type __ret = __intl ? _M_extract(__beg, __end, __io,
1505
                                                        __err, __str)
1506
                                     : _M_extract(__beg, __end, __io,
1507
                                                         __err, __str);
1508
      const size_type __len = __str.size();
1509
      if (__len)
1510
        {
1511
          _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1512
                                                               * __len));
1513
          __ctype.widen(__str.data(), __str.data() + __len, __ws);
1514
          __units.assign(__ws, __len);
1515
        }
1516
 
1517
      return __ret;
1518
    }
1519
 
1520
  template
1521
    template
1522
      _OutIter
1523
      money_put<_CharT, _OutIter>::
1524
      _M_insert(iter_type __s, ios_base& __io, char_type __fill,
1525
                const string_type& __digits) const
1526
      {
1527
        typedef typename string_type::size_type           size_type;
1528
        typedef money_base::part                          part;
1529
        typedef __moneypunct_cache<_CharT, _Intl>         __cache_type;
1530
 
1531
        const locale& __loc = __io._M_getloc();
1532
        const ctype<_CharT>& __ctype = use_facet >(__loc);
1533
 
1534
        __use_cache<__cache_type> __uc;
1535
        const __cache_type* __lc = __uc(__loc);
1536
        const char_type* __lit = __lc->_M_atoms;
1537
 
1538
        // Determine if negative or positive formats are to be used, and
1539
        // discard leading negative_sign if it is present.
1540
        const char_type* __beg = __digits.data();
1541
 
1542
        money_base::pattern __p;
1543
        const char_type* __sign;
1544
        size_type __sign_size;
1545
        if (!(*__beg == __lit[money_base::_S_minus]))
1546
          {
1547
            __p = __lc->_M_pos_format;
1548
            __sign = __lc->_M_positive_sign;
1549
            __sign_size = __lc->_M_positive_sign_size;
1550
          }
1551
        else
1552
          {
1553
            __p = __lc->_M_neg_format;
1554
            __sign = __lc->_M_negative_sign;
1555
            __sign_size = __lc->_M_negative_sign_size;
1556
            if (__digits.size())
1557
              ++__beg;
1558
          }
1559
 
1560
        // Look for valid numbers in the ctype facet within input digits.
1561
        size_type __len = __ctype.scan_not(ctype_base::digit, __beg,
1562
                                           __beg + __digits.size()) - __beg;
1563
        if (__len)
1564
          {
1565
            // Assume valid input, and attempt to format.
1566
            // Break down input numbers into base components, as follows:
1567
            //   final_value = grouped units + (decimal point) + (digits)
1568
            string_type __value;
1569
            __value.reserve(2 * __len);
1570
 
1571
            // Add thousands separators to non-decimal digits, per
1572
            // grouping rules.
1573
            int __paddec = __len - __lc->_M_frac_digits;
1574
            if (__paddec > 0)
1575
              {
1576
                if (__lc->_M_frac_digits < 0)
1577
                  __paddec = __len;
1578
                if (__lc->_M_grouping_size)
1579
                  {
1580
                    _CharT* __ws =
1581
                      static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1582
                                                            * 2 * __len));
1583
                    _CharT* __ws_end =
1584
                      std::__add_grouping(__ws, __lc->_M_thousands_sep,
1585
                                          __lc->_M_grouping,
1586
                                          __lc->_M_grouping_size,
1587
                                          __beg, __beg + __paddec);
1588
                    __value.assign(__ws, __ws_end - __ws);
1589
                  }
1590
                else
1591
                  __value.assign(__beg, __paddec);
1592
              }
1593
 
1594
            // Deal with decimal point, decimal digits.
1595
            if (__lc->_M_frac_digits > 0)
1596
              {
1597
                __value += __lc->_M_decimal_point;
1598
                if (__paddec >= 0)
1599
                  __value.append(__beg + __paddec, __lc->_M_frac_digits);
1600
                else
1601
                  {
1602
                    // Have to pad zeros in the decimal position.
1603
                    __value.append(-__paddec, __lit[money_base::_S_zero]);
1604
                    __value.append(__beg, __len);
1605
                  }
1606
              }
1607
 
1608
            // Calculate length of resulting string.
1609
            const ios_base::fmtflags __f = __io.flags()
1610
                                           & ios_base::adjustfield;
1611
            __len = __value.size() + __sign_size;
1612
            __len += ((__io.flags() & ios_base::showbase)
1613
                      ? __lc->_M_curr_symbol_size : 0);
1614
 
1615
            string_type __res;
1616
            __res.reserve(2 * __len);
1617
 
1618
            const size_type __width = static_cast(__io.width());
1619
            const bool __testipad = (__f == ios_base::internal
1620
                                     && __len < __width);
1621
            // Fit formatted digits into the required pattern.
1622
            for (int __i = 0; __i < 4; ++__i)
1623
              {
1624
                const part __which = static_cast(__p.field[__i]);
1625
                switch (__which)
1626
                  {
1627
                  case money_base::symbol:
1628
                    if (__io.flags() & ios_base::showbase)
1629
                      __res.append(__lc->_M_curr_symbol,
1630
                                   __lc->_M_curr_symbol_size);
1631
                    break;
1632
                  case money_base::sign:
1633
                    // Sign might not exist, or be more than one
1634
                    // charater long. In that case, add in the rest
1635
                    // below.
1636
                    if (__sign_size)
1637
                      __res += __sign[0];
1638
                    break;
1639
                  case money_base::value:
1640
                    __res += __value;
1641
                    break;
1642
                  case money_base::space:
1643
                    // At least one space is required, but if internal
1644
                    // formatting is required, an arbitrary number of
1645
                    // fill spaces will be necessary.
1646
                    if (__testipad)
1647
                      __res.append(__width - __len, __fill);
1648
                    else
1649
                      __res += __fill;
1650
                    break;
1651
                  case money_base::none:
1652
                    if (__testipad)
1653
                      __res.append(__width - __len, __fill);
1654
                    break;
1655
                  }
1656
              }
1657
 
1658
            // Special case of multi-part sign parts.
1659
            if (__sign_size > 1)
1660
              __res.append(__sign + 1, __sign_size - 1);
1661
 
1662
            // Pad, if still necessary.
1663
            __len = __res.size();
1664
            if (__width > __len)
1665
              {
1666
                if (__f == ios_base::left)
1667
                  // After.
1668
                  __res.append(__width - __len, __fill);
1669
                else
1670
                  // Before.
1671
                  __res.insert(0, __width - __len, __fill);
1672
                __len = __width;
1673
              }
1674
 
1675
            // Write resulting, fully-formatted string to output iterator.
1676
            __s = std::__write(__s, __res.data(), __len);
1677
          }
1678
        __io.width(0);
1679
        return __s;
1680
      }
1681
 
1682
  template
1683
    _OutIter
1684
    money_put<_CharT, _OutIter>::
1685
    do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
1686
           long double __units) const
1687
    {
1688
      const locale __loc = __io.getloc();
1689
      const ctype<_CharT>& __ctype = use_facet >(__loc);
1690
#ifdef _GLIBCXX_USE_C99
1691
      // First try a buffer perhaps big enough.
1692
      int __cs_size = 64;
1693
      char* __cs = static_cast(__builtin_alloca(__cs_size));
1694
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
1695
      // 328. Bad sprintf format modifier in money_put<>::do_put()
1696
      int __len = std::__convert_from_v(__cs, __cs_size, "%.*Lf", __units,
1697
                                        _S_get_c_locale(), 0);
1698
      // If the buffer was not large enough, try again with the correct size.
1699
      if (__len >= __cs_size)
1700
        {
1701
          __cs_size = __len + 1;
1702
          __cs = static_cast(__builtin_alloca(__cs_size));
1703
          __len = std::__convert_from_v(__cs, __cs_size, "%.*Lf", __units,
1704
                                        _S_get_c_locale(), 0);
1705
        }
1706
#else
1707
      // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'.
1708
      const int __cs_size = numeric_limits::max_exponent10 + 3;
1709
      char* __cs = static_cast(__builtin_alloca(__cs_size));
1710
      int __len = std::__convert_from_v(__cs, 0, "%.*Lf", __units,
1711
                                        _S_get_c_locale(), 0);
1712
#endif
1713
      _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1714
                                                           * __cs_size));
1715
      __ctype.widen(__cs, __cs + __len, __ws);
1716
      const string_type __digits(__ws, __len);
1717
      return __intl ? _M_insert(__s, __io, __fill, __digits)
1718
                    : _M_insert(__s, __io, __fill, __digits);
1719
    }
1720
 
1721
  template
1722
    _OutIter
1723
    money_put<_CharT, _OutIter>::
1724
    do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,
1725
           const string_type& __digits) const
1726
    { return __intl ? _M_insert(__s, __io, __fill, __digits)
1727
                    : _M_insert(__s, __io, __fill, __digits); }
1728
 
1729
 
1730
  // NB: Not especially useful. Without an ios_base object or some
1731
  // kind of locale reference, we are left clawing at the air where
1732
  // the side of the mountain used to be...
1733
  template
1734
    time_base::dateorder
1735
    time_get<_CharT, _InIter>::do_date_order() const
1736
    { return time_base::no_order; }
1737
 
1738
  // Expand a strftime format string and parse it.  E.g., do_get_date() may
1739
  // pass %m/%d/%Y => extracted characters.
1740
  template
1741
    _InIter
1742
    time_get<_CharT, _InIter>::
1743
    _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io,
1744
                          ios_base::iostate& __err, tm* __tm,
1745
                          const _CharT* __format) const
1746
    {
1747
      const locale& __loc = __io._M_getloc();
1748
      const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
1749
      const ctype<_CharT>& __ctype = use_facet >(__loc);
1750
      const size_t __len = char_traits<_CharT>::length(__format);
1751
 
1752
      for (size_t __i = 0; __beg != __end && __i < __len && !__err; ++__i)
1753
        {
1754
          if (__ctype.narrow(__format[__i], 0) == '%')
1755
            {
1756
              // Verify valid formatting code, attempt to extract.
1757
              char __c = __ctype.narrow(__format[++__i], 0);
1758
              int __mem = 0;
1759
              if (__c == 'E' || __c == 'O')
1760
                __c = __ctype.narrow(__format[++__i], 0);
1761
              switch (__c)
1762
                {
1763
                  const char* __cs;
1764
                  _CharT __wcs[10];
1765
                case 'a':
1766
                  // Abbreviated weekday name [tm_wday]
1767
                  const char_type*  __days1[7];
1768
                  __tp._M_days_abbreviated(__days1);
1769
                  __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days1,
1770
                                          7, __io, __err);
1771
                  break;
1772
                case 'A':
1773
                  // Weekday name [tm_wday].
1774
                  const char_type*  __days2[7];
1775
                  __tp._M_days(__days2);
1776
                  __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days2,
1777
                                          7, __io, __err);
1778
                  break;
1779
                case 'h':
1780
                case 'b':
1781
                  // Abbreviated month name [tm_mon]
1782
                  const char_type*  __months1[12];
1783
                  __tp._M_months_abbreviated(__months1);
1784
                  __beg = _M_extract_name(__beg, __end, __tm->tm_mon,
1785
                                          __months1, 12, __io, __err);
1786
                  break;
1787
                case 'B':
1788
                  // Month name [tm_mon].
1789
                  const char_type*  __months2[12];
1790
                  __tp._M_months(__months2);
1791
                  __beg = _M_extract_name(__beg, __end, __tm->tm_mon,
1792
                                          __months2, 12, __io, __err);
1793
                  break;
1794
                case 'c':
1795
                  // Default time and date representation.
1796
                  const char_type*  __dt[2];
1797
                  __tp._M_date_time_formats(__dt);
1798
                  __beg = _M_extract_via_format(__beg, __end, __io, __err,
1799
                                                __tm, __dt[0]);
1800
                  break;
1801
                case 'd':
1802
                  // Day [01, 31]. [tm_mday]
1803
                  __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2,
1804
                                         __io, __err);
1805
                  break;
1806
                case 'e':
1807
                  // Day [1, 31], with single digits preceded by
1808
                  // space. [tm_mday]
1809
                  if (__ctype.is(ctype_base::space, *__beg))
1810
                    __beg = _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9,
1811
                                           1, __io, __err);
1812
                  else
1813
                    __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31,
1814
                                           2, __io, __err);
1815
                  break;
1816
                case 'D':
1817
                  // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year]
1818
                  __cs = "%m/%d/%y";
1819
                  __ctype.widen(__cs, __cs + 9, __wcs);
1820
                  __beg = _M_extract_via_format(__beg, __end, __io, __err,
1821
                                                __tm, __wcs);
1822
                  break;
1823
                case 'H':
1824
                  // Hour [00, 23]. [tm_hour]
1825
                  __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2,
1826
                                         __io, __err);
1827
                  break;
1828
                case 'I':
1829
                  // Hour [01, 12]. [tm_hour]
1830
                  __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2,
1831
                                         __io, __err);
1832
                  break;
1833
                case 'm':
1834
                  // Month [01, 12]. [tm_mon]
1835
                  __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2,
1836
                                         __io, __err);
1837
                  if (!__err)
1838
                    __tm->tm_mon = __mem - 1;
1839
                  break;
1840
                case 'M':
1841
                  // Minute [00, 59]. [tm_min]
1842
                  __beg = _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2,
1843
                                         __io, __err);
1844
                  break;
1845
                case 'n':
1846
                  if (__ctype.narrow(*__beg, 0) == '\n')
1847
                    ++__beg;
1848
                  else
1849
                    __err |= ios_base::failbit;
1850
                  break;
1851
                case 'R':
1852
                  // Equivalent to (%H:%M).
1853
                  __cs = "%H:%M";
1854
                  __ctype.widen(__cs, __cs + 6, __wcs);
1855
                  __beg = _M_extract_via_format(__beg, __end, __io, __err,
1856
                                                __tm, __wcs);
1857
                  break;
1858
                case 'S':
1859
                  // Seconds. [tm_sec]
1860
                  // [00, 60] in C99 (one leap-second), [00, 61] in C89.
1861
#ifdef _GLIBCXX_USE_C99
1862
                  __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 60, 2,
1863
#else
1864
                  __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 61, 2,
1865
#endif
1866
                                         __io, __err);
1867
                  break;
1868
                case 't':
1869
                  if (__ctype.narrow(*__beg, 0) == '\t')
1870
                    ++__beg;
1871
                  else
1872
                    __err |= ios_base::failbit;
1873
                  break;
1874
                case 'T':
1875
                  // Equivalent to (%H:%M:%S).
1876
                  __cs = "%H:%M:%S";
1877
                  __ctype.widen(__cs, __cs + 9, __wcs);
1878
                  __beg = _M_extract_via_format(__beg, __end, __io, __err,
1879
                                                __tm, __wcs);
1880
                  break;
1881
                case 'x':
1882
                  // Locale's date.
1883
                  const char_type*  __dates[2];
1884
                  __tp._M_date_formats(__dates);
1885
                  __beg = _M_extract_via_format(__beg, __end, __io, __err,
1886
                                                __tm, __dates[0]);
1887
                  break;
1888
                case 'X':
1889
                  // Locale's time.
1890
                  const char_type*  __times[2];
1891
                  __tp._M_time_formats(__times);
1892
                  __beg = _M_extract_via_format(__beg, __end, __io, __err,
1893
                                                __tm, __times[0]);
1894
                  break;
1895
                case 'y':
1896
                case 'C': // C99
1897
                  // Two digit year. [tm_year]
1898
                  __beg = _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2,
1899
                                         __io, __err);
1900
                  break;
1901
                case 'Y':
1902
                  // Year [1900). [tm_year]
1903
                  __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4,
1904
                                         __io, __err);
1905
                  if (!__err)
1906
                    __tm->tm_year = __mem - 1900;
1907
                  break;
1908
                case 'Z':
1909
                  // Timezone info.
1910
                  if (__ctype.is(ctype_base::upper, *__beg))
1911
                    {
1912
                      int __tmp;
1913
                      __beg = _M_extract_name(__beg, __end, __tmp,
1914
                                       __timepunct_cache<_CharT>::_S_timezones,
1915
                                              14, __io, __err);
1916
 
1917
                      // GMT requires special effort.
1918
                      if (__beg != __end && !__err && __tmp == 0
1919
                          && (*__beg == __ctype.widen('-')
1920
                              || *__beg == __ctype.widen('+')))
1921
                        {
1922
                          __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2,
1923
                                                 __io, __err);
1924
                          __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2,
1925
                                                 __io, __err);
1926
                        }
1927
                    }
1928
                  else
1929
                    __err |= ios_base::failbit;
1930
                  break;
1931
                default:
1932
                  // Not recognized.
1933
                  __err |= ios_base::failbit;
1934
                }
1935
            }
1936
          else
1937
            {
1938
              // Verify format and input match, extract and discard.
1939
              if (__format[__i] == *__beg)
1940
                ++__beg;
1941
              else
1942
                __err |= ios_base::failbit;
1943
            }
1944
        }
1945
      return __beg;
1946
    }
1947
 
1948
  template
1949
    _InIter
1950
    time_get<_CharT, _InIter>::
1951
    _M_extract_num(iter_type __beg, iter_type __end, int& __member,
1952
                   int __min, int __max, size_t __len,
1953
                   ios_base& __io, ios_base::iostate& __err) const
1954
    {
1955
      const locale& __loc = __io._M_getloc();
1956
      const ctype<_CharT>& __ctype = use_facet >(__loc);
1957
 
1958
      // As-is works for __len = 1, 2, 4, the values actually used.
1959
      int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1);
1960
 
1961
      ++__min;
1962
      size_t __i = 0;
1963
      int __value = 0;
1964
      for (; __beg != __end && __i < __len; ++__beg, ++__i)
1965
        {
1966
          const char __c = __ctype.narrow(*__beg, '*');
1967
          if (__c >= '0' && __c <= '9')
1968
            {
1969
              __value = __value * 10 + (__c - '0');
1970
              const int __valuec = __value * __mult;
1971
              if (__valuec > __max || __valuec + __mult < __min)
1972
                break;
1973
              __mult /= 10;
1974
            }
1975
          else
1976
            break;
1977
        }
1978
      if (__i == __len)
1979
        __member = __value;
1980
      else
1981
        __err |= ios_base::failbit;
1982
      return __beg;
1983
    }
1984
 
1985
  // Assumptions:
1986
  // All elements in __names are unique.
1987
  template
1988
    _InIter
1989
    time_get<_CharT, _InIter>::
1990
    _M_extract_name(iter_type __beg, iter_type __end, int& __member,
1991
                    const _CharT** __names, size_t __indexlen,
1992
                    ios_base& __io, ios_base::iostate& __err) const
1993
    {
1994
      typedef char_traits<_CharT>               __traits_type;
1995
      const locale& __loc = __io._M_getloc();
1996
      const ctype<_CharT>& __ctype = use_facet >(__loc);
1997
 
1998
      int* __matches = static_cast(__builtin_alloca(sizeof(int)
1999
                                                          * __indexlen));
2000
      size_t __nmatches = 0;
2001
      size_t __pos = 0;
2002
      bool __testvalid = true;
2003
      const char_type* __name;
2004
 
2005
      // Look for initial matches.
2006
      // NB: Some of the locale data is in the form of all lowercase
2007
      // names, and some is in the form of initially-capitalized
2008
      // names. Look for both.
2009
      if (__beg != __end)
2010
        {
2011
          const char_type __c = *__beg;
2012
          for (size_t __i1 = 0; __i1 < __indexlen; ++__i1)
2013
            if (__c == __names[__i1][0]
2014
                || __c == __ctype.toupper(__names[__i1][0]))
2015
              __matches[__nmatches++] = __i1;
2016
        }
2017
 
2018
      while (__nmatches > 1)
2019
        {
2020
          // Find smallest matching string.
2021
          size_t __minlen = __traits_type::length(__names[__matches[0]]);
2022
          for (size_t __i2 = 1; __i2 < __nmatches; ++__i2)
2023
            __minlen = std::min(__minlen,
2024
                              __traits_type::length(__names[__matches[__i2]]));
2025
          ++__beg, ++__pos;
2026
          if (__pos < __minlen && __beg != __end)
2027
            for (size_t __i3 = 0; __i3 < __nmatches;)
2028
              {
2029
                __name = __names[__matches[__i3]];
2030
                if (!(__name[__pos] == *__beg))
2031
                  __matches[__i3] = __matches[--__nmatches];
2032
                else
2033
                  ++__i3;
2034
              }
2035
          else
2036
            break;
2037
        }
2038
 
2039
      if (__nmatches == 1)
2040
        {
2041
          // Make sure found name is completely extracted.
2042
          ++__beg, ++__pos;
2043
          __name = __names[__matches[0]];
2044
          const size_t __len = __traits_type::length(__name);
2045
          while (__pos < __len && __beg != __end && __name[__pos] == *__beg)
2046
            ++__beg, ++__pos;
2047
 
2048
          if (__len == __pos)
2049
            __member = __matches[0];
2050
          else
2051
            __testvalid = false;
2052
        }
2053
      else
2054
        __testvalid = false;
2055
      if (!__testvalid)
2056
        __err |= ios_base::failbit;
2057
      return __beg;
2058
    }
2059
 
2060
  template
2061
    _InIter
2062
    time_get<_CharT, _InIter>::
2063
    do_get_time(iter_type __beg, iter_type __end, ios_base& __io,
2064
                ios_base::iostate& __err, tm* __tm) const
2065
    {
2066
      const locale& __loc = __io._M_getloc();
2067
      const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
2068
      const char_type*  __times[2];
2069
      __tp._M_time_formats(__times);
2070
      __beg = _M_extract_via_format(__beg, __end, __io, __err,
2071
                                    __tm, __times[0]);
2072
      if (__beg == __end)
2073
        __err |= ios_base::eofbit;
2074
      return __beg;
2075
    }
2076
 
2077
  template
2078
    _InIter
2079
    time_get<_CharT, _InIter>::
2080
    do_get_date(iter_type __beg, iter_type __end, ios_base& __io,
2081
                ios_base::iostate& __err, tm* __tm) const
2082
    {
2083
      const locale& __loc = __io._M_getloc();
2084
      const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
2085
      const char_type*  __dates[2];
2086
      __tp._M_date_formats(__dates);
2087
      __beg = _M_extract_via_format(__beg, __end, __io, __err,
2088
                                    __tm, __dates[0]);
2089
      if (__beg == __end)
2090
        __err |= ios_base::eofbit;
2091
      return __beg;
2092
    }
2093
 
2094
  template
2095
    _InIter
2096
    time_get<_CharT, _InIter>::
2097
    do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io,
2098
                   ios_base::iostate& __err, tm* __tm) const
2099
    {
2100
      typedef char_traits<_CharT>               __traits_type;
2101
      const locale& __loc = __io._M_getloc();
2102
      const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
2103
      const ctype<_CharT>& __ctype = use_facet >(__loc);
2104
      const char_type*  __days[7];
2105
      __tp._M_days_abbreviated(__days);
2106
      int __tmpwday;
2107
      __beg = _M_extract_name(__beg, __end, __tmpwday, __days, 7, __io, __err);
2108
 
2109
      // Check to see if non-abbreviated name exists, and extract.
2110
      // NB: Assumes both _M_days and _M_days_abbreviated organized in
2111
      // exact same order, first to last, such that the resulting
2112
      // __days array with the same index points to a day, and that
2113
      // day's abbreviated form.
2114
      // NB: Also assumes that an abbreviated name is a subset of the name.
2115
      if (!__err && __beg != __end)
2116
        {
2117
          size_t __pos = __traits_type::length(__days[__tmpwday]);
2118
          __tp._M_days(__days);
2119
          const char_type* __name = __days[__tmpwday];
2120
          if (__name[__pos] == *__beg)
2121
            {
2122
              // Extract the rest of it.
2123
              const size_t __len = __traits_type::length(__name);
2124
              while (__pos < __len && __beg != __end
2125
                     && __name[__pos] == *__beg)
2126
                ++__beg, ++__pos;
2127
              if (__len != __pos)
2128
                __err |= ios_base::failbit;
2129
            }
2130
        }
2131
      if (!__err)
2132
        __tm->tm_wday = __tmpwday;
2133
 
2134
      if (__beg == __end)
2135
        __err |= ios_base::eofbit;
2136
      return __beg;
2137
     }
2138
 
2139
  template
2140
    _InIter
2141
    time_get<_CharT, _InIter>::
2142
    do_get_monthname(iter_type __beg, iter_type __end,
2143
                     ios_base& __io, ios_base::iostate& __err, tm* __tm) const
2144
    {
2145
      typedef char_traits<_CharT>               __traits_type;
2146
      const locale& __loc = __io._M_getloc();
2147
      const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc);
2148
      const ctype<_CharT>& __ctype = use_facet >(__loc);
2149
      const char_type*  __months[12];
2150
      __tp._M_months_abbreviated(__months);
2151
      int __tmpmon;
2152
      __beg = _M_extract_name(__beg, __end, __tmpmon, __months, 12,
2153
                              __io, __err);
2154
 
2155
      // Check to see if non-abbreviated name exists, and extract.
2156
      // NB: Assumes both _M_months and _M_months_abbreviated organized in
2157
      // exact same order, first to last, such that the resulting
2158
      // __months array with the same index points to a month, and that
2159
      // month's abbreviated form.
2160
      // NB: Also assumes that an abbreviated name is a subset of the name.
2161
      if (!__err && __beg != __end)
2162
        {
2163
          size_t __pos = __traits_type::length(__months[__tmpmon]);
2164
          __tp._M_months(__months);
2165
          const char_type* __name = __months[__tmpmon];
2166
          if (__name[__pos] == *__beg)
2167
            {
2168
              // Extract the rest of it.
2169
              const size_t __len = __traits_type::length(__name);
2170
              while (__pos < __len && __beg != __end
2171
                     && __name[__pos] == *__beg)
2172
                ++__beg, ++__pos;
2173
              if (__len != __pos)
2174
                __err |= ios_base::failbit;
2175
            }
2176
        }
2177
      if (!__err)
2178
        __tm->tm_mon = __tmpmon;
2179
 
2180
      if (__beg == __end)
2181
        __err |= ios_base::eofbit;
2182
      return __beg;
2183
    }
2184
 
2185
  template
2186
    _InIter
2187
    time_get<_CharT, _InIter>::
2188
    do_get_year(iter_type __beg, iter_type __end, ios_base& __io,
2189
                ios_base::iostate& __err, tm* __tm) const
2190
    {
2191
      const locale& __loc = __io._M_getloc();
2192
      const ctype<_CharT>& __ctype = use_facet >(__loc);
2193
 
2194
      size_t __i = 0;
2195
      int __value = 0;
2196
      for (; __beg != __end && __i < 4; ++__beg, ++__i)
2197
        {
2198
          const char __c = __ctype.narrow(*__beg, '*');
2199
          if (__c >= '0' && __c <= '9')
2200
            __value = __value * 10 + (__c - '0');
2201
          else
2202
            break;
2203
        }
2204
      if (__i == 2 || __i == 4)
2205
        __tm->tm_year = __i == 2 ? __value : __value - 1900;
2206
      else
2207
        __err |= ios_base::failbit;
2208
      if (__beg == __end)
2209
        __err |= ios_base::eofbit;
2210
      return __beg;
2211
    }
2212
 
2213
  template
2214
    _OutIter
2215
    time_put<_CharT, _OutIter>::
2216
    put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm,
2217
        const _CharT* __beg, const _CharT* __end) const
2218
    {
2219
      const locale& __loc = __io._M_getloc();
2220
      ctype<_CharT> const& __ctype = use_facet >(__loc);
2221
      for (; __beg != __end; ++__beg)
2222
        if (__ctype.narrow(*__beg, 0) != '%')
2223
          {
2224
            *__s = *__beg;
2225
            ++__s;
2226
          }
2227
        else if (++__beg != __end)
2228
          {
2229
            char __format;
2230
            char __mod = 0;
2231
            const char __c = __ctype.narrow(*__beg, 0);
2232
            if (__c != 'E' && __c != 'O')
2233
              __format = __c;
2234
            else if (++__beg != __end)
2235
              {
2236
                __mod = __c;
2237
                __format = __ctype.narrow(*__beg, 0);
2238
              }
2239
            else
2240
              break;
2241
            __s = this->do_put(__s, __io, __fill, __tm, __format, __mod);
2242
          }
2243
        else
2244
          break;
2245
      return __s;
2246
    }
2247
 
2248
  template
2249
    _OutIter
2250
    time_put<_CharT, _OutIter>::
2251
    do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm,
2252
           char __format, char __mod) const
2253
    {
2254
      const locale& __loc = __io._M_getloc();
2255
      ctype<_CharT> const& __ctype = use_facet >(__loc);
2256
      __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc);
2257
 
2258
      // NB: This size is arbitrary. Should this be a data member,
2259
      // initialized at construction?
2260
      const size_t __maxlen = 128;
2261
      char_type* __res =
2262
       static_cast(__builtin_alloca(sizeof(char_type) * __maxlen));
2263
 
2264
      // NB: In IEE 1003.1-200x, and perhaps other locale models, it
2265
      // is possible that the format character will be longer than one
2266
      // character. Possibilities include 'E' or 'O' followed by a
2267
      // format character: if __mod is not the default argument, assume
2268
      // it's a valid modifier.
2269
      char_type __fmt[4];
2270
      __fmt[0] = __ctype.widen('%');
2271
      if (!__mod)
2272
        {
2273
          __fmt[1] = __format;
2274
          __fmt[2] = char_type();
2275
        }
2276
      else
2277
        {
2278
          __fmt[1] = __mod;
2279
          __fmt[2] = __format;
2280
          __fmt[3] = char_type();
2281
        }
2282
 
2283
      __tp._M_put(__res, __maxlen, __fmt, __tm);
2284
 
2285
      // Write resulting, fully-formatted string to output iterator.
2286
      return std::__write(__s, __res, char_traits::length(__res));
2287
    }
2288
 
2289
  // Generic version does nothing.
2290
  template
2291
    int
2292
    collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const
2293
    { return 0; }
2294
 
2295
  // Generic version does nothing.
2296
  template
2297
    size_t
2298
    collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const
2299
    { return 0; }
2300
 
2301
  template
2302
    int
2303
    collate<_CharT>::
2304
    do_compare(const _CharT* __lo1, const _CharT* __hi1,
2305
               const _CharT* __lo2, const _CharT* __hi2) const
2306
    {
2307
      // strcoll assumes zero-terminated strings so we make a copy
2308
      // and then put a zero at the end.
2309
      const string_type __one(__lo1, __hi1);
2310
      const string_type __two(__lo2, __hi2);
2311
 
2312
      const _CharT* __p = __one.c_str();
2313
      const _CharT* __pend = __one.data() + __one.length();
2314
      const _CharT* __q = __two.c_str();
2315
      const _CharT* __qend = __two.data() + __two.length();
2316
 
2317
      // strcoll stops when it sees a nul character so we break
2318
      // the strings into zero-terminated substrings and pass those
2319
      // to strcoll.
2320
      for (;;)
2321
        {
2322
          const int __res = _M_compare(__p, __q);
2323
          if (__res)
2324
            return __res;
2325
 
2326
          __p += char_traits<_CharT>::length(__p);
2327
          __q += char_traits<_CharT>::length(__q);
2328
          if (__p == __pend && __q == __qend)
2329
            return 0;
2330
          else if (__p == __pend)
2331
            return -1;
2332
          else if (__q == __qend)
2333
            return 1;
2334
 
2335
          __p++;
2336
          __q++;
2337
        }
2338
    }
2339
 
2340
  template
2341
    typename collate<_CharT>::string_type
2342
    collate<_CharT>::
2343
    do_transform(const _CharT* __lo, const _CharT* __hi) const
2344
    {
2345
      // strxfrm assumes zero-terminated strings so we make a copy
2346
      string_type __str(__lo, __hi);
2347
 
2348
      const _CharT* __p = __str.c_str();
2349
      const _CharT* __pend = __str.data() + __str.length();
2350
 
2351
      size_t __len = (__hi - __lo) * 2;
2352
 
2353
      string_type __ret;
2354
 
2355
      // strxfrm stops when it sees a nul character so we break
2356
      // the string into zero-terminated substrings and pass those
2357
      // to strxfrm.
2358
      for (;;)
2359
        {
2360
          // First try a buffer perhaps big enough.
2361
          _CharT* __c =
2362
            static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len));
2363
          size_t __res = _M_transform(__c, __p, __len);
2364
          // If the buffer was not large enough, try again with the
2365
          // correct size.
2366
          if (__res >= __len)
2367
            {
2368
              __len = __res + 1;
2369
              __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
2370
                                                          * __len));
2371
              __res = _M_transform(__c, __p, __len);
2372
            }
2373
 
2374
          __ret.append(__c, __res);
2375
          __p += char_traits<_CharT>::length(__p);
2376
          if (__p == __pend)
2377
            return __ret;
2378
 
2379
          __p++;
2380
          __ret.push_back(_CharT());
2381
        }
2382
    }
2383
 
2384
  template
2385
    long
2386
    collate<_CharT>::
2387
    do_hash(const _CharT* __lo, const _CharT* __hi) const
2388
    {
2389
      unsigned long __val = 0;
2390
      for (; __lo < __hi; ++__lo)
2391
        __val = *__lo + ((__val << 7) |
2392
                       (__val >> (numeric_limits::digits - 7)));
2393
      return static_cast(__val);
2394
    }
2395
 
2396
  // Construct correctly padded string, as per 22.2.2.2.2
2397
  // Assumes
2398
  // __newlen > __oldlen
2399
  // __news is allocated for __newlen size
2400
  // Used by both num_put and ostream inserters: if __num,
2401
  // internal-adjusted objects are padded according to the rules below
2402
  // concerning 0[xX] and +-, otherwise, exactly as right-adjusted
2403
  // ones are.
2404
 
2405
  // NB: Of the two parameters, _CharT can be deduced from the
2406
  // function arguments. The other (_Traits) has to be explicitly specified.
2407
  template
2408
    void
2409
    __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill,
2410
                                   _CharT* __news, const _CharT* __olds,
2411
                                   const streamsize __newlen,
2412
                                   const streamsize __oldlen, const bool __num)
2413
    {
2414
      const size_t __plen = static_cast(__newlen - __oldlen);
2415
      const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
2416
 
2417
      // Padding last.
2418
      if (__adjust == ios_base::left)
2419
        {
2420
          _Traits::copy(__news, const_cast<_CharT*>(__olds), __oldlen);
2421
          _Traits::assign(__news + __oldlen, __plen, __fill);
2422
          return;
2423
        }
2424
 
2425
      size_t __mod = 0;
2426
      if (__adjust == ios_base::internal && __num)
2427
        {
2428
          // Pad after the sign, if there is one.
2429
          // Pad after 0[xX], if there is one.
2430
          // Who came up with these rules, anyway? Jeeze.
2431
          const locale& __loc = __io._M_getloc();
2432
          const ctype<_CharT>& __ctype = use_facet >(__loc);
2433
 
2434
          const bool __testsign = (__ctype.widen('-') == __olds[0]
2435
                                   || __ctype.widen('+') == __olds[0]);
2436
          const bool __testhex = (__ctype.widen('0') == __olds[0]
2437
                                  && __oldlen > 1
2438
                                  && (__ctype.widen('x') == __olds[1]
2439
                                      || __ctype.widen('X') == __olds[1]));
2440
          if (__testhex)
2441
            {
2442
              __news[0] = __olds[0];
2443
              __news[1] = __olds[1];
2444
              __mod = 2;
2445
              __news += 2;
2446
            }
2447
          else if (__testsign)
2448
            {
2449
              __news[0] = __olds[0];
2450
              __mod = 1;
2451
              ++__news;
2452
            }
2453
          // else Padding first.
2454
        }
2455
      _Traits::assign(__news, __plen, __fill);
2456
      _Traits::copy(__news + __plen, const_cast<_CharT*>(__olds + __mod),
2457
                    __oldlen - __mod);
2458
    }
2459
 
2460
  bool
2461
  __verify_grouping(const char* __grouping, size_t __grouping_size,
2462
                    const string& __grouping_tmp)
2463
  {
2464
    const size_t __n = __grouping_tmp.size() - 1;
2465
    const size_t __min = std::min(__n, size_t(__grouping_size - 1));
2466
    size_t __i = __n;
2467
    bool __test = true;
2468
 
2469
    // Parsed number groupings have to match the
2470
    // numpunct::grouping string exactly, starting at the
2471
    // right-most point of the parsed sequence of elements ...
2472
    for (size_t __j = 0; __j < __min && __test; --__i, ++__j)
2473
      __test = __grouping_tmp[__i] == __grouping[__j];
2474
    for (; __i && __test; --__i)
2475
      __test = __grouping_tmp[__i] == __grouping[__min];
2476
    // ... but the first parsed grouping can be <= numpunct
2477
    // grouping (only do the check if the numpunct char is > 0
2478
    // because <= 0 means any size is ok).
2479
    if (static_cast(__grouping[__min]) > 0)
2480
      __test &= __grouping_tmp[0] <= __grouping[__min];
2481
    return __test;
2482
  }
2483
 
2484
  template
2485
    _CharT*
2486
    __add_grouping(_CharT* __s, _CharT __sep,
2487
                   const char* __gbeg, size_t __gsize,
2488
                   const _CharT* __first, const _CharT* __last)
2489
    {
2490
      if (__last - __first > *__gbeg
2491
          && static_cast(*__gbeg) > 0)
2492
        {
2493
          const bool __bump = __gsize != 1;
2494
          __s = std::__add_grouping(__s,  __sep, __gbeg + __bump,
2495
                                    __gsize - __bump, __first,
2496
                                    __last - *__gbeg);
2497
          __first = __last - *__gbeg;
2498
          *__s++ = __sep;
2499
        }
2500
      do
2501
        *__s++ = *__first++;
2502
      while (__first != __last);
2503
      return __s;
2504
    }
2505
 
2506
  // Inhibit implicit instantiations for required instantiations,
2507
  // which are defined via explicit instantiations elsewhere.
2508
  // NB: This syntax is a GNU extension.
2509
#if _GLIBCXX_EXTERN_TEMPLATE
2510
  extern template class moneypunct;
2511
  extern template class moneypunct;
2512
  extern template class moneypunct_byname;
2513
  extern template class moneypunct_byname;
2514
  extern template class money_get;
2515
  extern template class money_put;
2516
  extern template class numpunct;
2517
  extern template class numpunct_byname;
2518
  extern template class num_get;
2519
  extern template class num_put;
2520
  extern template class __timepunct;
2521
  extern template class time_put;
2522
  extern template class time_put_byname;
2523
  extern template class time_get;
2524
  extern template class time_get_byname;
2525
  extern template class messages;
2526
  extern template class messages_byname;
2527
  extern template class ctype_byname;
2528
  extern template class codecvt_byname;
2529
  extern template class collate;
2530
  extern template class collate_byname;
2531
 
2532
  extern template
2533
    const codecvt&
2534
    use_facet >(const locale&);
2535
 
2536
  extern template
2537
    const collate&
2538
    use_facet >(const locale&);
2539
 
2540
  extern template
2541
    const numpunct&
2542
    use_facet >(const locale&);
2543
 
2544
  extern template
2545
    const num_put&
2546
    use_facet >(const locale&);
2547
 
2548
  extern template
2549
    const num_get&
2550
    use_facet >(const locale&);
2551
 
2552
  extern template
2553
    const moneypunct&
2554
    use_facet >(const locale&);
2555
 
2556
  extern template
2557
    const moneypunct&
2558
    use_facet >(const locale&);
2559
 
2560
  extern template
2561
    const money_put&
2562
    use_facet >(const locale&);
2563
 
2564
  extern template
2565
    const money_get&
2566
    use_facet >(const locale&);
2567
 
2568
  extern template
2569
    const __timepunct&
2570
    use_facet<__timepunct >(const locale&);
2571
 
2572
  extern template
2573
    const time_put&
2574
    use_facet >(const locale&);
2575
 
2576
  extern template
2577
    const time_get&
2578
    use_facet >(const locale&);
2579
 
2580
  extern template
2581
    const messages&
2582
    use_facet >(const locale&);
2583
 
2584
  extern template
2585
    bool
2586
    has_facet >(const locale&);
2587
 
2588
  extern template
2589
    bool
2590
    has_facet >(const locale&);
2591
 
2592
  extern template
2593
    bool
2594
    has_facet >(const locale&);
2595
 
2596
  extern template
2597
    bool
2598
    has_facet >(const locale&);
2599
 
2600
  extern template
2601
    bool
2602
    has_facet >(const locale&);
2603
 
2604
  extern template
2605
    bool
2606
    has_facet >(const locale&);
2607
 
2608
  extern template
2609
    bool
2610
    has_facet >(const locale&);
2611
 
2612
  extern template
2613
    bool
2614
    has_facet >(const locale&);
2615
 
2616
  extern template
2617
    bool
2618
    has_facet >(const locale&);
2619
 
2620
  extern template
2621
    bool
2622
    has_facet<__timepunct >(const locale&);
2623
 
2624
  extern template
2625
    bool
2626
    has_facet >(const locale&);
2627
 
2628
  extern template
2629
    bool
2630
    has_facet >(const locale&);
2631
 
2632
  extern template
2633
    bool
2634
    has_facet >(const locale&);
2635
 
2636
#ifdef _GLIBCXX_USE_WCHAR_T
2637
  extern template class moneypunct;
2638
  extern template class moneypunct;
2639
  extern template class moneypunct_byname;
2640
  extern template class moneypunct_byname;
2641
  extern template class money_get;
2642
  extern template class money_put;
2643
  extern template class numpunct;
2644
  extern template class numpunct_byname;
2645
  extern template class num_get;
2646
  extern template class num_put;
2647
  extern template class __timepunct;
2648
  extern template class time_put;
2649
  extern template class time_put_byname;
2650
  extern template class time_get;
2651
  extern template class time_get_byname;
2652
  extern template class messages;
2653
  extern template class messages_byname;
2654
  extern template class ctype_byname;
2655
  extern template class codecvt_byname;
2656
  extern template class collate;
2657
  extern template class collate_byname;
2658
 
2659
  extern template
2660
    const codecvt&
2661
    use_facet >(locale const&);
2662
 
2663
  extern template
2664
    const collate&
2665
    use_facet >(const locale&);
2666
 
2667
  extern template
2668
    const numpunct&
2669
    use_facet >(const locale&);
2670
 
2671
  extern template
2672
    const num_put&
2673
    use_facet >(const locale&);
2674
 
2675
  extern template
2676
    const num_get&
2677
    use_facet >(const locale&);
2678
 
2679
  extern template
2680
    const moneypunct&
2681
    use_facet >(const locale&);
2682
 
2683
  extern template
2684
    const moneypunct&
2685
    use_facet >(const locale&);
2686
 
2687
  extern template
2688
    const money_put&
2689
    use_facet >(const locale&);
2690
 
2691
  extern template
2692
    const money_get&
2693
    use_facet >(const locale&);
2694
 
2695
  extern template
2696
    const __timepunct&
2697
    use_facet<__timepunct >(const locale&);
2698
 
2699
  extern template
2700
    const time_put&
2701
    use_facet >(const locale&);
2702
 
2703
  extern template
2704
    const time_get&
2705
    use_facet >(const locale&);
2706
 
2707
  extern template
2708
    const messages&
2709
    use_facet >(const locale&);
2710
 
2711
 extern template
2712
    bool
2713
    has_facet >(const locale&);
2714
 
2715
  extern template
2716
    bool
2717
    has_facet >(const locale&);
2718
 
2719
  extern template
2720
    bool
2721
    has_facet >(const locale&);
2722
 
2723
  extern template
2724
    bool
2725
    has_facet >(const locale&);
2726
 
2727
  extern template
2728
    bool
2729
    has_facet >(const locale&);
2730
 
2731
  extern template
2732
    bool
2733
    has_facet >(const locale&);
2734
 
2735
  extern template
2736
    bool
2737
    has_facet >(const locale&);
2738
 
2739
  extern template
2740
    bool
2741
    has_facet >(const locale&);
2742
 
2743
  extern template
2744
    bool
2745
    has_facet >(const locale&);
2746
 
2747
  extern template
2748
    bool
2749
    has_facet<__timepunct >(const locale&);
2750
 
2751
  extern template
2752
    bool
2753
    has_facet >(const locale&);
2754
 
2755
  extern template
2756
    bool
2757
    has_facet >(const locale&);
2758
 
2759
  extern template
2760
    bool
2761
    has_facet >(const locale&);
2762
#endif
2763
#endif
2764
} // namespace std
2765
 
2766
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.