• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/toolchains/hndtools-armeabi-2011.09/arm-none-eabi/include/c++/4.6.1/bits/
1// Locale support -*- C++ -*-
2
3// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4// 2006, 2007, 2008, 2009, 2010, 2011
5// Free Software Foundation, Inc.
6//
7// This file is part of the GNU ISO C++ Library.  This library is free
8// software; you can redistribute it and/or modify it under the
9// terms of the GNU General Public License as published by the
10// Free Software Foundation; either version 3, or (at your option)
11// any later version.
12
13// This library is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16// GNU General Public License for more details.
17
18// Under Section 7 of GPL version 3, you are granted additional
19// permissions described in the GCC Runtime Library Exception, version
20// 3.1, as published by the Free Software Foundation.
21
22// You should have received a copy of the GNU General Public License and
23// a copy of the GCC Runtime Library Exception along with this program;
24// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
25// <http://www.gnu.org/licenses/>.
26
27/** @file bits/locale_facets.tcc
28 *  This is an internal header file, included by other library headers.
29 *  Do not attempt to use it directly. @headername{locale}
30 */
31
32#ifndef _LOCALE_FACETS_TCC
33#define _LOCALE_FACETS_TCC 1
34
35#pragma GCC system_header
36
37namespace std _GLIBCXX_VISIBILITY(default)
38{
39_GLIBCXX_BEGIN_NAMESPACE_VERSION
40
41  // Routine to access a cache for the facet.  If the cache didn't
42  // exist before, it gets constructed on the fly.
43  template<typename _Facet>
44    struct __use_cache
45    {
46      const _Facet*
47      operator() (const locale& __loc) const;
48    };
49
50  // Specializations.
51  template<typename _CharT>
52    struct __use_cache<__numpunct_cache<_CharT> >
53    {
54      const __numpunct_cache<_CharT>*
55      operator() (const locale& __loc) const
56      {
57	const size_t __i = numpunct<_CharT>::id._M_id();
58	const locale::facet** __caches = __loc._M_impl->_M_caches;
59	if (!__caches[__i])
60	  {
61	    __numpunct_cache<_CharT>* __tmp = 0;
62	    __try
63	      {
64		__tmp = new __numpunct_cache<_CharT>;
65		__tmp->_M_cache(__loc);
66	      }
67	    __catch(...)
68	      {
69		delete __tmp;
70		__throw_exception_again;
71	      }
72	    __loc._M_impl->_M_install_cache(__tmp, __i);
73	  }
74	return static_cast<const __numpunct_cache<_CharT>*>(__caches[__i]);
75      }
76    };
77
78  template<typename _CharT>
79    void
80    __numpunct_cache<_CharT>::_M_cache(const locale& __loc)
81    {
82      _M_allocated = true;
83
84      const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
85
86      char* __grouping = 0;
87      _CharT* __truename = 0;
88      _CharT* __falsename = 0;
89      __try
90	{
91	  _M_grouping_size = __np.grouping().size();
92	  __grouping = new char[_M_grouping_size];
93	  __np.grouping().copy(__grouping, _M_grouping_size);
94	  _M_grouping = __grouping;
95	  _M_use_grouping = (_M_grouping_size
96			     && static_cast<signed char>(_M_grouping[0]) > 0
97			     && (_M_grouping[0]
98				 != __gnu_cxx::__numeric_traits<char>::__max));
99
100	  _M_truename_size = __np.truename().size();
101	  __truename = new _CharT[_M_truename_size];
102	  __np.truename().copy(__truename, _M_truename_size);
103	  _M_truename = __truename;
104
105	  _M_falsename_size = __np.falsename().size();
106	  __falsename = new _CharT[_M_falsename_size];
107	  __np.falsename().copy(__falsename, _M_falsename_size);
108	  _M_falsename = __falsename;
109
110	  _M_decimal_point = __np.decimal_point();
111	  _M_thousands_sep = __np.thousands_sep();
112
113	  const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
114	  __ct.widen(__num_base::_S_atoms_out,
115		     __num_base::_S_atoms_out
116		     + __num_base::_S_oend, _M_atoms_out);
117	  __ct.widen(__num_base::_S_atoms_in,
118		     __num_base::_S_atoms_in
119		     + __num_base::_S_iend, _M_atoms_in);
120	}
121      __catch(...)
122	{
123	  delete [] __grouping;
124	  delete [] __truename;
125	  delete [] __falsename;
126	  __throw_exception_again;
127	}
128    }
129
130  // Used by both numeric and monetary facets.
131  // Check to make sure that the __grouping_tmp string constructed in
132  // money_get or num_get matches the canonical grouping for a given
133  // locale.
134  // __grouping_tmp is parsed L to R
135  // 1,222,444 == __grouping_tmp of "\1\3\3"
136  // __grouping is parsed R to L
137  // 1,222,444 == __grouping of "\3" == "\3\3\3"
138  _GLIBCXX_PURE bool
139  __verify_grouping(const char* __grouping, size_t __grouping_size,
140		    const string& __grouping_tmp) throw ();
141
142_GLIBCXX_BEGIN_NAMESPACE_LDBL
143
144  template<typename _CharT, typename _InIter>
145    _InIter
146    num_get<_CharT, _InIter>::
147    _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
148		     ios_base::iostate& __err, string& __xtrc) const
149    {
150      typedef char_traits<_CharT>			__traits_type;
151      typedef __numpunct_cache<_CharT>                  __cache_type;
152      __use_cache<__cache_type> __uc;
153      const locale& __loc = __io._M_getloc();
154      const __cache_type* __lc = __uc(__loc);
155      const _CharT* __lit = __lc->_M_atoms_in;
156      char_type __c = char_type();
157
158      // True if __beg becomes equal to __end.
159      bool __testeof = __beg == __end;
160
161      // First check for sign.
162      if (!__testeof)
163	{
164	  __c = *__beg;
165	  const bool __plus = __c == __lit[__num_base::_S_iplus];
166	  if ((__plus || __c == __lit[__num_base::_S_iminus])
167	      && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
168	      && !(__c == __lc->_M_decimal_point))
169	    {
170	      __xtrc += __plus ? '+' : '-';
171	      if (++__beg != __end)
172		__c = *__beg;
173	      else
174		__testeof = true;
175	    }
176	}
177
178      // Next, look for leading zeros.
179      bool __found_mantissa = false;
180      int __sep_pos = 0;
181      while (!__testeof)
182	{
183	  if ((__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
184	      || __c == __lc->_M_decimal_point)
185	    break;
186	  else if (__c == __lit[__num_base::_S_izero])
187	    {
188	      if (!__found_mantissa)
189		{
190		  __xtrc += '0';
191		  __found_mantissa = true;
192		}
193	      ++__sep_pos;
194
195	      if (++__beg != __end)
196		__c = *__beg;
197	      else
198		__testeof = true;
199	    }
200	  else
201	    break;
202	}
203
204      // Only need acceptable digits for floating point numbers.
205      bool __found_dec = false;
206      bool __found_sci = false;
207      string __found_grouping;
208      if (__lc->_M_use_grouping)
209	__found_grouping.reserve(32);
210      const char_type* __lit_zero = __lit + __num_base::_S_izero;
211
212      if (!__lc->_M_allocated)
213	// "C" locale
214	while (!__testeof)
215	  {
216	    const int __digit = _M_find(__lit_zero, 10, __c);
217	    if (__digit != -1)
218	      {
219		__xtrc += '0' + __digit;
220		__found_mantissa = true;
221	      }
222	    else if (__c == __lc->_M_decimal_point
223		     && !__found_dec && !__found_sci)
224	      {
225		__xtrc += '.';
226		__found_dec = true;
227	      }
228	    else if ((__c == __lit[__num_base::_S_ie] 
229		      || __c == __lit[__num_base::_S_iE])
230		     && !__found_sci && __found_mantissa)
231	      {
232		// Scientific notation.
233		__xtrc += 'e';
234		__found_sci = true;
235		
236		// Remove optional plus or minus sign, if they exist.
237		if (++__beg != __end)
238		  {
239		    __c = *__beg;
240		    const bool __plus = __c == __lit[__num_base::_S_iplus];
241		    if (__plus || __c == __lit[__num_base::_S_iminus])
242		      __xtrc += __plus ? '+' : '-';
243		    else
244		      continue;
245		  }
246		else
247		  {
248		    __testeof = true;
249		    break;
250		  }
251	      }
252	    else
253	      break;
254
255	    if (++__beg != __end)
256	      __c = *__beg;
257	    else
258	      __testeof = true;
259	  }
260      else
261	while (!__testeof)
262	  {
263	    // According to 22.2.2.1.2, p8-9, first look for thousands_sep
264	    // and decimal_point.
265	    if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
266	      {
267		if (!__found_dec && !__found_sci)
268		  {
269		    // NB: Thousands separator at the beginning of a string
270		    // is a no-no, as is two consecutive thousands separators.
271		    if (__sep_pos)
272		      {
273			__found_grouping += static_cast<char>(__sep_pos);
274			__sep_pos = 0;
275		      }
276		    else
277		      {
278			// NB: __convert_to_v will not assign __v and will
279			// set the failbit.
280			__xtrc.clear();
281			break;
282		      }
283		  }
284		else
285		  break;
286	      }
287	    else if (__c == __lc->_M_decimal_point)
288	      {
289		if (!__found_dec && !__found_sci)
290		  {
291		    // If no grouping chars are seen, no grouping check
292		    // is applied. Therefore __found_grouping is adjusted
293		    // only if decimal_point comes after some thousands_sep.
294		    if (__found_grouping.size())
295		      __found_grouping += static_cast<char>(__sep_pos);
296		    __xtrc += '.';
297		    __found_dec = true;
298		  }
299		else
300		  break;
301	      }
302	    else
303	      {
304		const char_type* __q =
305		  __traits_type::find(__lit_zero, 10, __c);
306		if (__q)
307		  {
308		    __xtrc += '0' + (__q - __lit_zero);
309		    __found_mantissa = true;
310		    ++__sep_pos;
311		  }
312		else if ((__c == __lit[__num_base::_S_ie] 
313			  || __c == __lit[__num_base::_S_iE])
314			 && !__found_sci && __found_mantissa)
315		  {
316		    // Scientific notation.
317		    if (__found_grouping.size() && !__found_dec)
318		      __found_grouping += static_cast<char>(__sep_pos);
319		    __xtrc += 'e';
320		    __found_sci = true;
321		    
322		    // Remove optional plus or minus sign, if they exist.
323		    if (++__beg != __end)
324		      {
325			__c = *__beg;
326			const bool __plus = __c == __lit[__num_base::_S_iplus];
327			if ((__plus || __c == __lit[__num_base::_S_iminus])
328			    && !(__lc->_M_use_grouping
329				 && __c == __lc->_M_thousands_sep)
330			    && !(__c == __lc->_M_decimal_point))
331		      __xtrc += __plus ? '+' : '-';
332			else
333			  continue;
334		      }
335		    else
336		      {
337			__testeof = true;
338			break;
339		      }
340		  }
341		else
342		  break;
343	      }
344	    
345	    if (++__beg != __end)
346	      __c = *__beg;
347	    else
348	      __testeof = true;
349	  }
350
351      // Digit grouping is checked. If grouping and found_grouping don't
352      // match, then get very very upset, and set failbit.
353      if (__found_grouping.size())
354        {
355          // Add the ending grouping if a decimal or 'e'/'E' wasn't found.
356	  if (!__found_dec && !__found_sci)
357	    __found_grouping += static_cast<char>(__sep_pos);
358
359          if (!std::__verify_grouping(__lc->_M_grouping, 
360				      __lc->_M_grouping_size,
361				      __found_grouping))
362	    __err = ios_base::failbit;
363        }
364
365      return __beg;
366    }
367
368  template<typename _CharT, typename _InIter>
369    template<typename _ValueT>
370      _InIter
371      num_get<_CharT, _InIter>::
372      _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
373		     ios_base::iostate& __err, _ValueT& __v) const
374      {
375        typedef char_traits<_CharT>			     __traits_type;
376	using __gnu_cxx::__add_unsigned;
377	typedef typename __add_unsigned<_ValueT>::__type __unsigned_type;
378	typedef __numpunct_cache<_CharT>                     __cache_type;
379	__use_cache<__cache_type> __uc;
380	const locale& __loc = __io._M_getloc();
381	const __cache_type* __lc = __uc(__loc);
382	const _CharT* __lit = __lc->_M_atoms_in;
383	char_type __c = char_type();
384
385	// NB: Iff __basefield == 0, __base can change based on contents.
386	const ios_base::fmtflags __basefield = __io.flags()
387	                                       & ios_base::basefield;
388	const bool __oct = __basefield == ios_base::oct;
389	int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10);
390
391	// True if __beg becomes equal to __end.
392	bool __testeof = __beg == __end;
393
394	// First check for sign.
395	bool __negative = false;
396	if (!__testeof)
397	  {
398	    __c = *__beg;
399	    __negative = __c == __lit[__num_base::_S_iminus];
400	    if ((__negative || __c == __lit[__num_base::_S_iplus])
401		&& !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
402		&& !(__c == __lc->_M_decimal_point))
403	      {
404		if (++__beg != __end)
405		  __c = *__beg;
406		else
407		  __testeof = true;
408	      }
409	  }
410
411	// Next, look for leading zeros and check required digits
412	// for base formats.
413	bool __found_zero = false;
414	int __sep_pos = 0;
415	while (!__testeof)
416	  {
417	    if ((__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
418		|| __c == __lc->_M_decimal_point)
419	      break;
420	    else if (__c == __lit[__num_base::_S_izero] 
421		     && (!__found_zero || __base == 10))
422	      {
423		__found_zero = true;
424		++__sep_pos;
425		if (__basefield == 0)
426		  __base = 8;
427		if (__base == 8)
428		  __sep_pos = 0;
429	      }
430	    else if (__found_zero
431		     && (__c == __lit[__num_base::_S_ix]
432			 || __c == __lit[__num_base::_S_iX]))
433	      {
434		if (__basefield == 0)
435		  __base = 16;
436		if (__base == 16)
437		  {
438		    __found_zero = false;
439		    __sep_pos = 0;
440		  }
441		else
442		  break;
443	      }
444	    else
445	      break;
446
447	    if (++__beg != __end)
448	      {
449		__c = *__beg;
450		if (!__found_zero)
451		  break;
452	      }
453	    else
454	      __testeof = true;
455	  }
456	
457	// At this point, base is determined. If not hex, only allow
458	// base digits as valid input.
459	const size_t __len = (__base == 16 ? __num_base::_S_iend
460			      - __num_base::_S_izero : __base);
461
462	// Extract.
463	string __found_grouping;
464	if (__lc->_M_use_grouping)
465	  __found_grouping.reserve(32);
466	bool __testfail = false;
467	bool __testoverflow = false;
468	const __unsigned_type __max =
469	  (__negative && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
470	  ? -__gnu_cxx::__numeric_traits<_ValueT>::__min
471	  : __gnu_cxx::__numeric_traits<_ValueT>::__max;
472	const __unsigned_type __smax = __max / __base;
473	__unsigned_type __result = 0;
474	int __digit = 0;
475	const char_type* __lit_zero = __lit + __num_base::_S_izero;
476
477	if (!__lc->_M_allocated)
478	  // "C" locale
479	  while (!__testeof)
480	    {
481	      __digit = _M_find(__lit_zero, __len, __c);
482	      if (__digit == -1)
483		break;
484	      
485	      if (__result > __smax)
486		__testoverflow = true;
487	      else
488		{
489		  __result *= __base;
490		  __testoverflow |= __result > __max - __digit;
491		  __result += __digit;
492		  ++__sep_pos;
493		}
494	      
495	      if (++__beg != __end)
496		__c = *__beg;
497	      else
498		__testeof = true;
499	    }
500	else
501	  while (!__testeof)
502	    {
503	      // According to 22.2.2.1.2, p8-9, first look for thousands_sep
504	      // and decimal_point.
505	      if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
506		{
507		  // NB: Thousands separator at the beginning of a string
508		  // is a no-no, as is two consecutive thousands separators.
509		  if (__sep_pos)
510		    {
511		      __found_grouping += static_cast<char>(__sep_pos);
512		      __sep_pos = 0;
513		    }
514		  else
515		    {
516		      __testfail = true;
517		      break;
518		    }
519		}
520	      else if (__c == __lc->_M_decimal_point)
521		break;
522	      else
523		{
524		  const char_type* __q =
525		    __traits_type::find(__lit_zero, __len, __c);
526		  if (!__q)
527		    break;
528		  
529		  __digit = __q - __lit_zero;
530		  if (__digit > 15)
531		    __digit -= 6;
532		  if (__result > __smax)
533		    __testoverflow = true;
534		  else
535		    {
536		      __result *= __base;
537		      __testoverflow |= __result > __max - __digit;
538		      __result += __digit;
539		      ++__sep_pos;
540		    }
541		}
542	      
543	      if (++__beg != __end)
544		__c = *__beg;
545	      else
546		__testeof = true;
547	    }
548	
549	// Digit grouping is checked. If grouping and found_grouping don't
550	// match, then get very very upset, and set failbit.
551	if (__found_grouping.size())
552	  {
553	    // Add the ending grouping.
554	    __found_grouping += static_cast<char>(__sep_pos);
555
556	    if (!std::__verify_grouping(__lc->_M_grouping,
557					__lc->_M_grouping_size,
558					__found_grouping))
559	      __err = ios_base::failbit;
560	  }
561
562	// _GLIBCXX_RESOLVE_LIB_DEFECTS
563	// 23. Num_get overflow result.
564	if ((!__sep_pos && !__found_zero && !__found_grouping.size())
565	    || __testfail)
566	  {
567	    __v = 0;
568	    __err = ios_base::failbit;
569	  }
570	else if (__testoverflow)
571	  {
572	    if (__negative
573		&& __gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
574	      __v = __gnu_cxx::__numeric_traits<_ValueT>::__min;
575	    else
576	      __v = __gnu_cxx::__numeric_traits<_ValueT>::__max;
577	    __err = ios_base::failbit;
578	  }
579	else
580	  __v = __negative ? -__result : __result;
581
582	if (__testeof)
583	  __err |= ios_base::eofbit;
584	return __beg;
585      }
586
587  // _GLIBCXX_RESOLVE_LIB_DEFECTS
588  // 17.  Bad bool parsing
589  template<typename _CharT, typename _InIter>
590    _InIter
591    num_get<_CharT, _InIter>::
592    do_get(iter_type __beg, iter_type __end, ios_base& __io,
593           ios_base::iostate& __err, bool& __v) const
594    {
595      if (!(__io.flags() & ios_base::boolalpha))
596        {
597	  // Parse bool values as long.
598          // NB: We can't just call do_get(long) here, as it might
599          // refer to a derived class.
600	  long __l = -1;
601          __beg = _M_extract_int(__beg, __end, __io, __err, __l);
602	  if (__l == 0 || __l == 1)
603	    __v = bool(__l);
604	  else
605	    {
606	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
607	      // 23. Num_get overflow result.
608	      __v = true;
609	      __err = ios_base::failbit;
610	      if (__beg == __end)
611		__err |= ios_base::eofbit;
612	    }
613        }
614      else
615        {
616	  // Parse bool values as alphanumeric.
617	  typedef __numpunct_cache<_CharT>  __cache_type;
618	  __use_cache<__cache_type> __uc;
619	  const locale& __loc = __io._M_getloc();
620	  const __cache_type* __lc = __uc(__loc);
621
622	  bool __testf = true;
623	  bool __testt = true;
624	  bool __donef = __lc->_M_falsename_size == 0;
625	  bool __donet = __lc->_M_truename_size == 0;
626	  bool __testeof = false;
627	  size_t __n = 0;
628	  while (!__donef || !__donet)
629	    {
630	      if (__beg == __end)
631		{
632		  __testeof = true;
633		  break;
634		}
635
636	      const char_type __c = *__beg;
637
638	      if (!__donef)
639		__testf = __c == __lc->_M_falsename[__n];
640
641	      if (!__testf && __donet)
642		break;
643
644	      if (!__donet)
645		__testt = __c == __lc->_M_truename[__n];
646
647	      if (!__testt && __donef)
648		break;
649
650	      if (!__testt && !__testf)
651		break;
652
653	      ++__n;
654	      ++__beg;
655
656	      __donef = !__testf || __n >= __lc->_M_falsename_size;
657	      __donet = !__testt || __n >= __lc->_M_truename_size;
658	    }
659	  if (__testf && __n == __lc->_M_falsename_size && __n)
660	    {
661	      __v = false;
662	      if (__testt && __n == __lc->_M_truename_size)
663		__err = ios_base::failbit;
664	      else
665		__err = __testeof ? ios_base::eofbit : ios_base::goodbit;
666	    }
667	  else if (__testt && __n == __lc->_M_truename_size && __n)
668	    {
669	      __v = true;
670	      __err = __testeof ? ios_base::eofbit : ios_base::goodbit;
671	    }
672	  else
673	    {
674	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
675	      // 23. Num_get overflow result.
676	      __v = false;
677	      __err = ios_base::failbit;
678	      if (__testeof)
679		__err |= ios_base::eofbit;
680	    }
681	}
682      return __beg;
683    }
684
685  template<typename _CharT, typename _InIter>
686    _InIter
687    num_get<_CharT, _InIter>::
688    do_get(iter_type __beg, iter_type __end, ios_base& __io,
689	   ios_base::iostate& __err, float& __v) const
690    {
691      string __xtrc;
692      __xtrc.reserve(32);
693      __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
694      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
695      if (__beg == __end)
696	__err |= ios_base::eofbit;
697      return __beg;
698    }
699
700  template<typename _CharT, typename _InIter>
701    _InIter
702    num_get<_CharT, _InIter>::
703    do_get(iter_type __beg, iter_type __end, ios_base& __io,
704           ios_base::iostate& __err, double& __v) const
705    {
706      string __xtrc;
707      __xtrc.reserve(32);
708      __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
709      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
710      if (__beg == __end)
711	__err |= ios_base::eofbit;
712      return __beg;
713    }
714
715#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
716  template<typename _CharT, typename _InIter>
717    _InIter
718    num_get<_CharT, _InIter>::
719    __do_get(iter_type __beg, iter_type __end, ios_base& __io,
720	     ios_base::iostate& __err, double& __v) const
721    {
722      string __xtrc;
723      __xtrc.reserve(32);
724      __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
725      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
726      if (__beg == __end)
727	__err |= ios_base::eofbit;
728      return __beg;
729    }
730#endif
731
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,
736           ios_base::iostate& __err, long double& __v) const
737    {
738      string __xtrc;
739      __xtrc.reserve(32);
740      __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
741      std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
742      if (__beg == __end)
743	__err |= ios_base::eofbit;
744      return __beg;
745    }
746
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, void*& __v) const
752    {
753      // Prepare for hex formatted input.
754      typedef ios_base::fmtflags        fmtflags;
755      const fmtflags __fmt = __io.flags();
756      __io.flags((__fmt & ~ios_base::basefield) | ios_base::hex);
757
758      typedef __gnu_cxx::__conditional_type<(sizeof(void*)
759					     <= sizeof(unsigned long)),
760	unsigned long, unsigned long long>::__type _UIntPtrType;       
761
762      _UIntPtrType __ul;
763      __beg = _M_extract_int(__beg, __end, __io, __err, __ul);
764
765      // Reset from hex formatted input.
766      __io.flags(__fmt);
767
768      __v = reinterpret_cast<void*>(__ul);
769      return __beg;
770    }
771
772  // For use by integer and floating-point types after they have been
773  // converted into a char_type string.
774  template<typename _CharT, typename _OutIter>
775    void
776    num_put<_CharT, _OutIter>::
777    _M_pad(_CharT __fill, streamsize __w, ios_base& __io,
778	   _CharT* __new, const _CharT* __cs, int& __len) const
779    {
780      // [22.2.2.2.2] Stage 3.
781      // If necessary, pad.
782      __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new,
783						  __cs, __w, __len);
784      __len = static_cast<int>(__w);
785    }
786
787_GLIBCXX_END_NAMESPACE_LDBL
788
789  template<typename _CharT, typename _ValueT>
790    int
791    __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit,
792		  ios_base::fmtflags __flags, bool __dec)
793    {
794      _CharT* __buf = __bufend;
795      if (__builtin_expect(__dec, true))
796	{
797	  // Decimal.
798	  do
799	    {
800	      *--__buf = __lit[(__v % 10) + __num_base::_S_odigits];
801	      __v /= 10;
802	    }
803	  while (__v != 0);
804	}
805      else if ((__flags & ios_base::basefield) == ios_base::oct)
806	{
807	  // Octal.
808	  do
809	    {
810	      *--__buf = __lit[(__v & 0x7) + __num_base::_S_odigits];
811	      __v >>= 3;
812	    }
813	  while (__v != 0);
814	}
815      else
816	{
817	  // Hex.
818	  const bool __uppercase = __flags & ios_base::uppercase;
819	  const int __case_offset = __uppercase ? __num_base::_S_oudigits
820	                                        : __num_base::_S_odigits;
821	  do
822	    {
823	      *--__buf = __lit[(__v & 0xf) + __case_offset];
824	      __v >>= 4;
825	    }
826	  while (__v != 0);
827	}
828      return __bufend - __buf;
829    }
830
831_GLIBCXX_BEGIN_NAMESPACE_LDBL
832
833  template<typename _CharT, typename _OutIter>
834    void
835    num_put<_CharT, _OutIter>::
836    _M_group_int(const char* __grouping, size_t __grouping_size, _CharT __sep,
837		 ios_base&, _CharT* __new, _CharT* __cs, int& __len) const
838    {
839      _CharT* __p = std::__add_grouping(__new, __sep, __grouping,
840					__grouping_size, __cs, __cs + __len);
841      __len = __p - __new;
842    }
843  
844  template<typename _CharT, typename _OutIter>
845    template<typename _ValueT>
846      _OutIter
847      num_put<_CharT, _OutIter>::
848      _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill,
849		    _ValueT __v) const
850      {
851	using __gnu_cxx::__add_unsigned;
852	typedef typename __add_unsigned<_ValueT>::__type __unsigned_type;
853	typedef __numpunct_cache<_CharT>	             __cache_type;
854	__use_cache<__cache_type> __uc;
855	const locale& __loc = __io._M_getloc();
856	const __cache_type* __lc = __uc(__loc);
857	const _CharT* __lit = __lc->_M_atoms_out;
858	const ios_base::fmtflags __flags = __io.flags();
859
860	// Long enough to hold hex, dec, and octal representations.
861	const int __ilen = 5 * sizeof(_ValueT);
862	_CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
863							     * __ilen));
864
865	// [22.2.2.2.2] Stage 1, numeric conversion to character.
866	// Result is returned right-justified in the buffer.
867	const ios_base::fmtflags __basefield = __flags & ios_base::basefield;
868	const bool __dec = (__basefield != ios_base::oct
869			    && __basefield != ios_base::hex);
870	const __unsigned_type __u = ((__v > 0 || !__dec)
871				     ? __unsigned_type(__v)
872				     : -__unsigned_type(__v));
873 	int __len = __int_to_char(__cs + __ilen, __u, __lit, __flags, __dec);
874	__cs += __ilen - __len;
875
876	// Add grouping, if necessary.
877	if (__lc->_M_use_grouping)
878	  {
879	    // Grouping can add (almost) as many separators as the number
880	    // of digits + space is reserved for numeric base or sign.
881	    _CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
882								  * (__len + 1)
883								  * 2));
884	    _M_group_int(__lc->_M_grouping, __lc->_M_grouping_size,
885			 __lc->_M_thousands_sep, __io, __cs2 + 2, __cs, __len);
886	    __cs = __cs2 + 2;
887	  }
888
889	// Complete Stage 1, prepend numeric base or sign.
890	if (__builtin_expect(__dec, true))
891	  {
892	    // Decimal.
893	    if (__v >= 0)
894	      {
895		if (bool(__flags & ios_base::showpos)
896		    && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed)
897		  *--__cs = __lit[__num_base::_S_oplus], ++__len;
898	      }
899	    else
900	      *--__cs = __lit[__num_base::_S_ominus], ++__len;
901	  }
902	else if (bool(__flags & ios_base::showbase) && __v)
903	  {
904	    if (__basefield == ios_base::oct)
905	      *--__cs = __lit[__num_base::_S_odigits], ++__len;
906	    else
907	      {
908		// 'x' or 'X'
909		const bool __uppercase = __flags & ios_base::uppercase;
910		*--__cs = __lit[__num_base::_S_ox + __uppercase];
911		// '0'
912		*--__cs = __lit[__num_base::_S_odigits];
913		__len += 2;
914	      }
915	  }
916
917	// Pad.
918	const streamsize __w = __io.width();
919	if (__w > static_cast<streamsize>(__len))
920	  {
921	    _CharT* __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
922								  * __w));
923	    _M_pad(__fill, __w, __io, __cs3, __cs, __len);
924	    __cs = __cs3;
925	  }
926	__io.width(0);
927
928	// [22.2.2.2.2] Stage 4.
929	// Write resulting, fully-formatted string to output iterator.
930	return std::__write(__s, __cs, __len);
931      }
932
933  template<typename _CharT, typename _OutIter>
934    void
935    num_put<_CharT, _OutIter>::
936    _M_group_float(const char* __grouping, size_t __grouping_size,
937		   _CharT __sep, const _CharT* __p, _CharT* __new,
938		   _CharT* __cs, int& __len) const
939    {
940      // _GLIBCXX_RESOLVE_LIB_DEFECTS
941      // 282. What types does numpunct grouping refer to?
942      // Add grouping, if necessary.
943      const int __declen = __p ? __p - __cs : __len;
944      _CharT* __p2 = std::__add_grouping(__new, __sep, __grouping,
945					 __grouping_size,
946					 __cs, __cs + __declen);
947
948      // Tack on decimal part.
949      int __newlen = __p2 - __new;
950      if (__p)
951	{
952	  char_traits<_CharT>::copy(__p2, __p, __len - __declen);
953	  __newlen += __len - __declen;
954	}
955      __len = __newlen;
956    }
957
958  // The following code uses vsnprintf (or vsprintf(), when
959  // _GLIBCXX_USE_C99 is not defined) to convert floating point values
960  // for insertion into a stream.  An optimization would be to replace
961  // them with code that works directly on a wide buffer and then use
962  // __pad to do the padding.  It would be good to replace them anyway
963  // to gain back the efficiency that C++ provides by knowing up front
964  // the type of the values to insert.  Also, sprintf is dangerous
965  // since may lead to accidental buffer overruns.  This
966  // implementation follows the C++ standard fairly directly as
967  // outlined in 22.2.2.2 [lib.locale.num.put]
968  template<typename _CharT, typename _OutIter>
969    template<typename _ValueT>
970      _OutIter
971      num_put<_CharT, _OutIter>::
972      _M_insert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
973		       _ValueT __v) const
974      {
975	typedef __numpunct_cache<_CharT>                __cache_type;
976	__use_cache<__cache_type> __uc;
977	const locale& __loc = __io._M_getloc();
978	const __cache_type* __lc = __uc(__loc);
979
980	// Use default precision if out of range.
981	const streamsize __prec = __io.precision() < 0 ? 6 : __io.precision();
982
983	const int __max_digits =
984	  __gnu_cxx::__numeric_traits<_ValueT>::__digits10;
985
986	// [22.2.2.2.2] Stage 1, numeric conversion to character.
987	int __len;
988	// Long enough for the max format spec.
989	char __fbuf[16];
990	__num_base::_S_format_float(__io, __fbuf, __mod);
991
992#ifdef _GLIBCXX_USE_C99
993	// First try a buffer perhaps big enough (most probably sufficient
994	// for non-ios_base::fixed outputs)
995	int __cs_size = __max_digits * 3;
996	char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
997	__len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
998				      __fbuf, __prec, __v);
999
1000	// If the buffer was not large enough, try again with the correct size.
1001	if (__len >= __cs_size)
1002	  {
1003	    __cs_size = __len + 1;
1004	    __cs = static_cast<char*>(__builtin_alloca(__cs_size));
1005	    __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
1006					  __fbuf, __prec, __v);
1007	  }
1008#else
1009	// Consider the possibility of long ios_base::fixed outputs
1010	const bool __fixed = __io.flags() & ios_base::fixed;
1011	const int __max_exp =
1012	  __gnu_cxx::__numeric_traits<_ValueT>::__max_exponent10;
1013
1014	// The size of the output string is computed as follows.
1015	// ios_base::fixed outputs may need up to __max_exp + 1 chars
1016	// for the integer part + __prec chars for the fractional part
1017	// + 3 chars for sign, decimal point, '\0'. On the other hand,
1018	// for non-fixed outputs __max_digits * 2 + __prec chars are
1019	// largely sufficient.
1020	const int __cs_size = __fixed ? __max_exp + __prec + 4
1021	                              : __max_digits * 2 + __prec;
1022	char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
1023	__len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, __fbuf, 
1024				      __prec, __v);
1025#endif
1026
1027	// [22.2.2.2.2] Stage 2, convert to char_type, using correct
1028	// numpunct.decimal_point() values for '.' and adding grouping.
1029	const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1030	
1031	_CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1032							     * __len));
1033	__ctype.widen(__cs, __cs + __len, __ws);
1034	
1035	// Replace decimal point.
1036	_CharT* __wp = 0;
1037	const char* __p = char_traits<char>::find(__cs, __len, '.');
1038	if (__p)
1039	  {
1040	    __wp = __ws + (__p - __cs);
1041	    *__wp = __lc->_M_decimal_point;
1042	  }
1043	
1044	// Add grouping, if necessary.
1045	// N.B. Make sure to not group things like 2e20, i.e., no decimal
1046	// point, scientific notation.
1047	if (__lc->_M_use_grouping
1048	    && (__wp || __len < 3 || (__cs[1] <= '9' && __cs[2] <= '9'
1049				      && __cs[1] >= '0' && __cs[2] >= '0')))
1050	  {
1051	    // Grouping can add (almost) as many separators as the
1052	    // number of digits, but no more.
1053	    _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1054								  * __len * 2));
1055	    
1056	    streamsize __off = 0;
1057	    if (__cs[0] == '-' || __cs[0] == '+')
1058	      {
1059		__off = 1;
1060		__ws2[0] = __ws[0];
1061		__len -= 1;
1062	      }
1063	    
1064	    _M_group_float(__lc->_M_grouping, __lc->_M_grouping_size,
1065			   __lc->_M_thousands_sep, __wp, __ws2 + __off,
1066			   __ws + __off, __len);
1067	    __len += __off;
1068	    
1069	    __ws = __ws2;
1070	  }
1071
1072	// Pad.
1073	const streamsize __w = __io.width();
1074	if (__w > static_cast<streamsize>(__len))
1075	  {
1076	    _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1077								  * __w));
1078	    _M_pad(__fill, __w, __io, __ws3, __ws, __len);
1079	    __ws = __ws3;
1080	  }
1081	__io.width(0);
1082	
1083	// [22.2.2.2.2] Stage 4.
1084	// Write resulting, fully-formatted string to output iterator.
1085	return std::__write(__s, __ws, __len);
1086      }
1087  
1088  template<typename _CharT, typename _OutIter>
1089    _OutIter
1090    num_put<_CharT, _OutIter>::
1091    do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
1092    {
1093      const ios_base::fmtflags __flags = __io.flags();
1094      if ((__flags & ios_base::boolalpha) == 0)
1095        {
1096          const long __l = __v;
1097          __s = _M_insert_int(__s, __io, __fill, __l);
1098        }
1099      else
1100        {
1101	  typedef __numpunct_cache<_CharT>              __cache_type;
1102	  __use_cache<__cache_type> __uc;
1103	  const locale& __loc = __io._M_getloc();
1104	  const __cache_type* __lc = __uc(__loc);
1105
1106	  const _CharT* __name = __v ? __lc->_M_truename
1107	                             : __lc->_M_falsename;
1108	  int __len = __v ? __lc->_M_truename_size
1109	                  : __lc->_M_falsename_size;
1110
1111	  const streamsize __w = __io.width();
1112	  if (__w > static_cast<streamsize>(__len))
1113	    {
1114	      const streamsize __plen = __w - __len;
1115	      _CharT* __ps
1116		= static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
1117							* __plen));
1118
1119	      char_traits<_CharT>::assign(__ps, __plen, __fill);
1120	      __io.width(0);
1121
1122	      if ((__flags & ios_base::adjustfield) == ios_base::left)
1123		{
1124		  __s = std::__write(__s, __name, __len);
1125		  __s = std::__write(__s, __ps, __plen);
1126		}
1127	      else
1128		{
1129		  __s = std::__write(__s, __ps, __plen);
1130		  __s = std::__write(__s, __name, __len);
1131		}
1132	      return __s;
1133	    }
1134	  __io.width(0);
1135	  __s = std::__write(__s, __name, __len);
1136	}
1137      return __s;
1138    }
1139
1140  template<typename _CharT, typename _OutIter>
1141    _OutIter
1142    num_put<_CharT, _OutIter>::
1143    do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
1144    { return _M_insert_float(__s, __io, __fill, char(), __v); }
1145
1146#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
1147  template<typename _CharT, typename _OutIter>
1148    _OutIter
1149    num_put<_CharT, _OutIter>::
1150    __do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
1151    { return _M_insert_float(__s, __io, __fill, char(), __v); }
1152#endif
1153
1154  template<typename _CharT, typename _OutIter>
1155    _OutIter
1156    num_put<_CharT, _OutIter>::
1157    do_put(iter_type __s, ios_base& __io, char_type __fill,
1158	   long double __v) const
1159    { return _M_insert_float(__s, __io, __fill, 'L', __v); }
1160
1161  template<typename _CharT, typename _OutIter>
1162    _OutIter
1163    num_put<_CharT, _OutIter>::
1164    do_put(iter_type __s, ios_base& __io, char_type __fill,
1165           const void* __v) const
1166    {
1167      const ios_base::fmtflags __flags = __io.flags();
1168      const ios_base::fmtflags __fmt = ~(ios_base::basefield
1169					 | ios_base::uppercase);
1170      __io.flags((__flags & __fmt) | (ios_base::hex | ios_base::showbase));
1171
1172      typedef __gnu_cxx::__conditional_type<(sizeof(const void*)
1173					     <= sizeof(unsigned long)),
1174	unsigned long, unsigned long long>::__type _UIntPtrType;       
1175
1176      __s = _M_insert_int(__s, __io, __fill,
1177			  reinterpret_cast<_UIntPtrType>(__v));
1178      __io.flags(__flags);
1179      return __s;
1180    }
1181
1182_GLIBCXX_END_NAMESPACE_LDBL
1183
1184  // Construct correctly padded string, as per 22.2.2.2.2
1185  // Assumes
1186  // __newlen > __oldlen
1187  // __news is allocated for __newlen size
1188
1189  // NB: Of the two parameters, _CharT can be deduced from the
1190  // function arguments. The other (_Traits) has to be explicitly specified.
1191  template<typename _CharT, typename _Traits>
1192    void
1193    __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill,
1194				   _CharT* __news, const _CharT* __olds,
1195				   streamsize __newlen, streamsize __oldlen)
1196    {
1197      const size_t __plen = static_cast<size_t>(__newlen - __oldlen);
1198      const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
1199
1200      // Padding last.
1201      if (__adjust == ios_base::left)
1202	{
1203	  _Traits::copy(__news, __olds, __oldlen);
1204	  _Traits::assign(__news + __oldlen, __plen, __fill);
1205	  return;
1206	}
1207
1208      size_t __mod = 0;
1209      if (__adjust == ios_base::internal)
1210	{
1211	  // Pad after the sign, if there is one.
1212	  // Pad after 0[xX], if there is one.
1213	  // Who came up with these rules, anyway? Jeeze.
1214          const locale& __loc = __io._M_getloc();
1215	  const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
1216
1217	  if (__ctype.widen('-') == __olds[0]
1218	      || __ctype.widen('+') == __olds[0])
1219	    {
1220	      __news[0] = __olds[0];
1221	      __mod = 1;
1222	      ++__news;
1223	    }
1224	  else if (__ctype.widen('0') == __olds[0]
1225		   && __oldlen > 1
1226		   && (__ctype.widen('x') == __olds[1]
1227		       || __ctype.widen('X') == __olds[1]))
1228	    {
1229	      __news[0] = __olds[0];
1230	      __news[1] = __olds[1];
1231	      __mod = 2;
1232	      __news += 2;
1233	    }
1234	  // else Padding first.
1235	}
1236      _Traits::assign(__news, __plen, __fill);
1237      _Traits::copy(__news + __plen, __olds + __mod, __oldlen - __mod);
1238    }
1239
1240  template<typename _CharT>
1241    _CharT*
1242    __add_grouping(_CharT* __s, _CharT __sep,
1243		   const char* __gbeg, size_t __gsize,
1244		   const _CharT* __first, const _CharT* __last)
1245    {
1246      size_t __idx = 0;
1247      size_t __ctr = 0;
1248
1249      while (__last - __first > __gbeg[__idx]
1250	     && static_cast<signed char>(__gbeg[__idx]) > 0
1251	     && __gbeg[__idx] != __gnu_cxx::__numeric_traits<char>::__max)
1252	{
1253	  __last -= __gbeg[__idx];
1254	  __idx < __gsize - 1 ? ++__idx : ++__ctr;
1255	}
1256
1257      while (__first != __last)
1258	*__s++ = *__first++;
1259
1260      while (__ctr--)
1261	{
1262	  *__s++ = __sep;	  
1263	  for (char __i = __gbeg[__idx]; __i > 0; --__i)
1264	    *__s++ = *__first++;
1265	}
1266
1267      while (__idx--)
1268	{
1269	  *__s++ = __sep;	  
1270	  for (char __i = __gbeg[__idx]; __i > 0; --__i)
1271	    *__s++ = *__first++;
1272	}
1273
1274      return __s;
1275    }
1276
1277  // Inhibit implicit instantiations for required instantiations,
1278  // which are defined via explicit instantiations elsewhere.
1279#if _GLIBCXX_EXTERN_TEMPLATE
1280  extern template class numpunct<char>;
1281  extern template class numpunct_byname<char>;
1282  extern template class _GLIBCXX_NAMESPACE_LDBL num_get<char>;
1283  extern template class _GLIBCXX_NAMESPACE_LDBL num_put<char>;
1284  extern template class ctype_byname<char>;
1285
1286  extern template
1287    const ctype<char>&
1288    use_facet<ctype<char> >(const locale&);
1289
1290  extern template
1291    const numpunct<char>&
1292    use_facet<numpunct<char> >(const locale&);
1293
1294  extern template
1295    const num_put<char>&
1296    use_facet<num_put<char> >(const locale&);
1297
1298  extern template
1299    const num_get<char>&
1300    use_facet<num_get<char> >(const locale&);
1301
1302  extern template
1303    bool
1304    has_facet<ctype<char> >(const locale&);
1305
1306  extern template
1307    bool
1308    has_facet<numpunct<char> >(const locale&);
1309
1310  extern template
1311    bool
1312    has_facet<num_put<char> >(const locale&);
1313
1314  extern template
1315    bool
1316    has_facet<num_get<char> >(const locale&);
1317
1318#ifdef _GLIBCXX_USE_WCHAR_T
1319  extern template class numpunct<wchar_t>;
1320  extern template class numpunct_byname<wchar_t>;
1321  extern template class _GLIBCXX_NAMESPACE_LDBL num_get<wchar_t>;
1322  extern template class _GLIBCXX_NAMESPACE_LDBL num_put<wchar_t>;
1323  extern template class ctype_byname<wchar_t>;
1324
1325  extern template
1326    const ctype<wchar_t>&
1327    use_facet<ctype<wchar_t> >(const locale&);
1328
1329  extern template
1330    const numpunct<wchar_t>&
1331    use_facet<numpunct<wchar_t> >(const locale&);
1332
1333  extern template
1334    const num_put<wchar_t>&
1335    use_facet<num_put<wchar_t> >(const locale&);
1336
1337  extern template
1338    const num_get<wchar_t>&
1339    use_facet<num_get<wchar_t> >(const locale&);
1340
1341 extern template
1342    bool
1343    has_facet<ctype<wchar_t> >(const locale&);
1344
1345  extern template
1346    bool
1347    has_facet<numpunct<wchar_t> >(const locale&);
1348
1349  extern template
1350    bool
1351    has_facet<num_put<wchar_t> >(const locale&);
1352
1353  extern template
1354    bool
1355    has_facet<num_get<wchar_t> >(const locale&);
1356#endif
1357#endif
1358
1359_GLIBCXX_END_NAMESPACE_VERSION
1360} // namespace
1361
1362#endif
1363