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