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