williamr@2: /*
williamr@2:  * © Portions copyright (c) 2006-2007 Nokia Corporation.  All rights reserved.
williamr@2:  * Copyright (c) 1999
williamr@2:  * Silicon Graphics Computer Systems, Inc.
williamr@2:  *
williamr@2:  * Copyright (c) 1999
williamr@2:  * Boris Fomitchev
williamr@2:  *
williamr@2:  * This material is provided "as is", with absolutely no warranty expressed
williamr@2:  * or implied. Any use is at your own risk.
williamr@2:  *
williamr@2:  * Permission to use or copy this software for any purpose is hereby granted
williamr@2:  * without fee, provided the above notices are retained on all copies.
williamr@2:  * Permission to modify the code and to distribute modified code is granted,
williamr@2:  * provided the above notices are retained, and a notice that the code was
williamr@2:  * modified is included with the above copyright notice.
williamr@2:  *
williamr@2:  */
williamr@2: #ifndef _STLP_NUM_GET_C
williamr@2: #define _STLP_NUM_GET_C
williamr@2: 
williamr@2: #ifndef _STLP_INTERNAL_NUM_GET_H
williamr@2: # include <stl/_num_get.h>
williamr@2: #endif
williamr@2: 
williamr@2: # if defined (_STLP_EXPOSE_STREAM_IMPLEMENTATION)
williamr@2: 
williamr@2: #ifndef _STLP_LIMITS_H
williamr@2: # include <stl/_limits.h>
williamr@2: #endif
williamr@2: 
williamr@2: _STLP_DECLSPEC  unsigned char*  __get_digit_val_table(void);
williamr@2: _STLP_DECLSPEC  char*  __get_narrow_atoms(void);
williamr@2: _STLP_BEGIN_NAMESPACE
williamr@2: 
williamr@2: extern const unsigned char __digit_val_table[];
williamr@2: 
williamr@2: template < class _InputIter, class _Integer, class _CharT>
williamr@2: _InputIter _STLP_CALL
williamr@2: _M_do_get_integer(_InputIter&, _InputIter&, ios_base&, ios_base::iostate&, _Integer&, _CharT*);
williamr@2: 
williamr@2: // _M_do_get_integer and its helper functions.
williamr@2: 
williamr@2: #ifdef	__SYMBIAN32__
williamr@2: template<class _CharT>
williamr@2: inline bool _STLP_CALL __get_fdigit(_CharT& c, const _CharT* digits)
williamr@2:   { 
williamr@2: 
williamr@2:   const _CharT* p = find(digits, digits + 10, c);
williamr@2:   if (p != digits + 10) {
williamr@2:     c = (_CharT)( (_CharT)'0' + (p - digits));
williamr@2:     return true;
williamr@2:   }
williamr@2:   else
williamr@2:     return false;
williamr@2: }
williamr@2: 
williamr@2: #endif
williamr@2: inline bool _STLP_CALL __get_fdigit(char& __c, const char*)
williamr@2:   { return __c >= '0' && __c <= '9'; }
williamr@2: 
williamr@2: inline bool _STLP_CALL __get_fdigit_or_sep(char& __c, char __sep, const char *)
williamr@2: {
williamr@2:   if (__c == __sep) {
williamr@2:     __c = ',' ;
williamr@2:     return true ;
williamr@2:   } else
williamr@2:     return  ( __c >= '0' && __c <= '9');
williamr@2: }
williamr@2: 
williamr@2: # ifndef _STLP_NO_WCHAR_T
williamr@2: 
williamr@2: // Similar, except return the character itself instead of the numeric
williamr@2: // value.  Used for floating-point input.
williamr@2: inline bool  _STLP_CALL __get_fdigit(wchar_t& c, const wchar_t* digits)
williamr@2: {
williamr@2:   const wchar_t* p = find(digits, digits + 10, c);
williamr@2:   if (p != digits + 10) {
williamr@2:     c = (char)('0' + (p - digits));
williamr@2:     return true;
williamr@2:   }
williamr@2:   else
williamr@2:     return false;
williamr@2: }
williamr@2: 
williamr@2: inline bool  _STLP_CALL __get_fdigit_or_sep(wchar_t& c, wchar_t sep,
williamr@2:                                      const wchar_t * digits)
williamr@2: {
williamr@2:   if (c == sep) {
williamr@2:     c = (char)',';
williamr@2:     return true;
williamr@2:   }
williamr@2:   else
williamr@2:     return __get_fdigit(c, digits);
williamr@2: }
williamr@2: #ifdef __SYMBIAN32__
williamr@2: template <class _CharT>
williamr@2: inline bool  _STLP_CALL __get_fdigit_or_sep(_CharT& c, _CharT sep,
williamr@2:                                      const _CharT * digits)
williamr@2: {
williamr@2:   if (c == sep) {
williamr@2:     c = (_CharT)',';
williamr@2:     return true;
williamr@2:   }
williamr@2:   else
williamr@2:     return __get_fdigit(c, digits);
williamr@2: }
williamr@2: 
williamr@2: 
williamr@2: 
williamr@2: #endif
williamr@2: #endif
williamr@2: inline int _STLP_CALL
williamr@2: __get_digit_from_table(unsigned __index)
williamr@2: {
williamr@2:   return (__index > 127 ? 0xFF : __get_digit_val_table()[__index]);
williamr@2: }
williamr@2: 
williamr@2: extern const char __narrow_atoms[];
williamr@2: 
williamr@2: template <class _InputIter, class _CharT>
williamr@2: int
williamr@2: _M_get_base_or_zero(_InputIter& __stl_in, _InputIter& __end, ios_base& __str, _CharT*)
williamr@2: {
williamr@2:   _CharT __atoms[5];
williamr@2:   const ctype<_CharT>& __c_type = use_facet< ctype<_CharT> >(__str.getloc());
williamr@2:   // const ctype<_CharT>& __c_type = *(const ctype<_CharT>*)__str._M_ctype_facet();
williamr@2: 
williamr@2:   __c_type.widen(__get_narrow_atoms(), __get_narrow_atoms() + 5, __atoms);
williamr@2: 
williamr@2:   bool __negative = false;
williamr@2:   _CharT __c = *__stl_in;
williamr@2: 
williamr@2:   if (__c == __atoms[1] /* __xminus_char */ ) {
williamr@2:     __negative = true;
williamr@2:     ++__stl_in;
williamr@2:   }
williamr@2:   else if (__c == __atoms[0] /* __xplus_char */ )
williamr@2:     ++__stl_in;
williamr@2: 
williamr@2: 
williamr@2:   int __base;
williamr@2:   int __valid_zero = 0;
williamr@2: 
williamr@2:   ios_base::fmtflags __basefield = __str.flags() & ios_base::basefield;
williamr@2: 
williamr@2:   switch (__basefield) {
williamr@2:   case ios_base::oct:
williamr@2:     __base = 8;
williamr@2:     break;
williamr@2:   case ios_base::dec:
williamr@2:     __base = 10;
williamr@2:     break;
williamr@2:   case ios_base::hex:
williamr@2:     __base = 16;
williamr@2:     if (__stl_in != __end && *__stl_in == __atoms[2] /* __zero_char */ ) {
williamr@2:       ++__stl_in;
williamr@2:       if (__stl_in != __end &&
williamr@2:           (*__stl_in == __atoms[3] /* __x_char */ || *__stl_in == __atoms[4] /* __X_char */ ))
williamr@2:         ++__stl_in;
williamr@2:       else
williamr@2:         __valid_zero = 1; // That zero is valid by itself.
williamr@2:     }
williamr@2:     break;
williamr@2:   default:
williamr@2:     if (__stl_in != __end && *__stl_in == __atoms[2] /* __zero_char */ ) {
williamr@2:       ++__stl_in;
williamr@2:       if (__stl_in != __end &&
williamr@2:           (*__stl_in == __atoms[3] /* __x_char */ || *__stl_in == __atoms[4] /* __X_char */ )) {
williamr@2:         ++__stl_in;
williamr@2:         __base = 16;
williamr@2:       }
williamr@2:       else
williamr@2:         {
williamr@2:           __base = 8;
williamr@2:           __valid_zero = 1; // That zero is still valid by itself.
williamr@2:         }
williamr@2:     }
williamr@2:     else
williamr@2:       __base = 10;
williamr@2:     break;
williamr@2:   }
williamr@2:   return (__base << 2) | ((int)__negative << 1) | __valid_zero;
williamr@2: }
williamr@2: 
williamr@2: 
williamr@2: template <class _InputIter, class _Integer>
williamr@2: bool _STLP_CALL
williamr@2: __get_integer(_InputIter& __first, _InputIter& __last,
williamr@2: 	      int __base, _Integer& __val,
williamr@2: 	      int __got, bool __is_negative, char __separator, const string& __grouping, const __true_type&)
williamr@2: {
williamr@2:   bool __ovflow = false;
williamr@2:   bool __valid_group = true;
williamr@2: 
williamr@2:   _Integer __result = 0;
williamr@2:   bool __is_group = !__grouping.empty();
williamr@2: //  char __group_sizes[64];
williamr@2:   char __group_sizes[256] = {0}; //group sizes can be more
williamr@2: #ifdef	__SYMBIAN32__
williamr@2: int __current_group_size = __got;
williamr@2: #else
williamr@2:   int __current_group_size = 0;
williamr@2: #endif
williamr@2:   char* __group_sizes_end = __group_sizes;
williamr@2:    int prv_got = 0;
williamr@2:    
williamr@2:    
williamr@2:   _Integer __over_base = (numeric_limits<_Integer>::min)() / __STATIC_CAST(_Integer, __base);
williamr@2: 
williamr@2:    for ( ; __first != __last ; ++__first) {
williamr@2: 
williamr@2:      const char __c = *__first;
williamr@2: 
williamr@2:      if (__is_group && __c == __separator) {
williamr@2: 	 if (prv_got == __got) //no successive seperators
williamr@2: 	 	return false;
williamr@2: 	 prv_got = __got;
williamr@2:        *__group_sizes_end++ = __current_group_size;       
williamr@2:        __current_group_size = 0;
williamr@2:        continue;
williamr@2:      }
williamr@2: 
williamr@2:      int __n = __get_digit_from_table(__c);
williamr@2: 
williamr@2:      if (__n >= __base)
williamr@2: 	 	break;
williamr@2: 
williamr@2:      ++__got;
williamr@2:      ++__current_group_size;
williamr@2: 
williamr@2:      if (__result < __over_base)
williamr@2:        __ovflow = true;  // don't need to keep accumulating
williamr@2:      else {
williamr@2:        _Integer __next = __STATIC_CAST(_Integer, __base * __result - __n);
williamr@2:        if (__result != 0)
williamr@2: #ifdef	__SYMBIAN32__
williamr@2: 	if (__is_negative)
williamr@2: 		__ovflow = __ovflow || __next >= __result;
williamr@2: 	else
williamr@2: 		__ovflow = __ovflow || (__next-1) >= __result; //For signed char, the ranges are -128 to 127, 
williamr@2: #else
williamr@2: 	 __ovflow = __ovflow || __next >= __result;
williamr@2: #endif
williamr@2:        __result = __next;
williamr@2:      }
williamr@2:    }
williamr@2: 
williamr@2:    if (__is_group && __group_sizes_end != __group_sizes) {
williamr@2:      *__group_sizes_end++ = __current_group_size;
williamr@2:      
williamr@2:    }
williamr@2: 
williamr@2:    // fbp : added to not modify value if nothing was read
williamr@2:    if (__got > 0) {
williamr@2:        __val = __ovflow
williamr@2: 	 ? __is_negative ? (numeric_limits<_Integer>::min)()
williamr@2: 	 : (numeric_limits<_Integer>::max)()
williamr@2: 	 : (__is_negative ? __result : __STATIC_CAST(_Integer, -__result));
williamr@2:    }
williamr@2:    __valid_group = __valid_grouping(__group_sizes, __group_sizes_end,
williamr@2: 									    __grouping.data(), __grouping.data()+ __grouping.size());
williamr@2: 
williamr@2: 	if (__valid_group == false)
williamr@2: 	__val = 0;
williamr@2: 
williamr@2:   // overflow is being treated as failure
williamr@2:   return ((__got > 0) && !__ovflow) && (__is_group == 0 || __valid_group) ;
williamr@2: }
williamr@2: 
williamr@2: template <class _InputIter, class _Integer>
williamr@2: bool _STLP_CALL
williamr@2: __get_integer(_InputIter& __first, _InputIter& __last,
williamr@2: 	      int __base, _Integer& __val,
williamr@2: 	      int __got, bool __is_negative, char __separator, const string& __grouping, const __false_type&)
williamr@2: {
williamr@2:   bool __ovflow = false;
williamr@2:   bool __valid_group = true;
williamr@2:   _Integer __result = 0;
williamr@2:   bool __is_group = !__grouping.empty();
williamr@2: //  char __group_sizes[64];
williamr@2:   char __group_sizes[256] = {0};//group sizes can be more
williamr@2:   int __current_group_size = 0;
williamr@2:   char* __group_sizes_end = __group_sizes;
williamr@2:      int prv_got = 0;
williamr@2: 
williamr@2:  
williamr@2:   _Integer  __over_base = (numeric_limits<_Integer>::max)() / __STATIC_CAST(_Integer, __base);
williamr@2: 
williamr@2:   for ( ; __first != __last ; ++__first) {
williamr@2: 
williamr@2:     const char __c = *__first;
williamr@2: /*
williamr@2:     //if (__is_group && __c == __separator) { //no seperator at the start of number.
williamr@2:     if (__is_group && __c == __separator && __got) {
williamr@2:       // seperator should come after extracting some digits
williamr@2:       	if (!__current_group_size)
williamr@2:       		break;
williamr@2:      *__group_sizes_end++ = __current_group_size;    
williamr@2:       __current_group_size = 0;
williamr@2:       continue;
williamr@2:     }
williamr@2: */
williamr@2: 	if (__is_group && __c == __separator) {
williamr@2: 	 if (prv_got == __got) //no successive seperators
williamr@2: 	 	return false;
williamr@2: 	 	prv_got = __got;
williamr@2:        *__group_sizes_end++ = __current_group_size;       
williamr@2:        __current_group_size = 0;
williamr@2:        continue;
williamr@2:      }
williamr@2:     int __n = __get_digit_from_table(__c);
williamr@2: 
williamr@2:     if (__n >= __base)
williamr@2:     	break;
williamr@2: 
williamr@2:     ++__got;
williamr@2:     ++__current_group_size;
williamr@2: 
williamr@2:     if (__result > __over_base)
williamr@2:       __ovflow = true;  //don't need to keep accumulating
williamr@2:     else {
williamr@2:       _Integer __next = __STATIC_CAST(_Integer, __base * __result + __n);
williamr@2: 	if (__result != 0)
williamr@2: 	  __ovflow = __ovflow || __next <= __result;
williamr@2: 	__result = __next;
williamr@2:       }
williamr@2:   }
williamr@2: 
williamr@2:   if (__is_group && __group_sizes_end != __group_sizes) {
williamr@2:       *__group_sizes_end++ = __current_group_size;     
williamr@2:   }
williamr@2: 
williamr@2:   // fbp : added to not modify value if nothing was read
williamr@2:   if (__got > 0) {
williamr@2:       __val = __ovflow
williamr@2: 	? (numeric_limits<_Integer>::max)()
williamr@2: 	: (__is_negative ? __STATIC_CAST(_Integer, -__result) : __result);
williamr@2:   }
williamr@2:   __valid_group =  __valid_grouping(__group_sizes, __group_sizes_end,
williamr@2: 					 __grouping.data(), __grouping.data()+ __grouping.size());
williamr@2: 
williamr@2: 	if (__valid_group == false)
williamr@2: 	__val = 0;
williamr@2: 
williamr@2:   // overflow is being treated as failure
williamr@2:   return ((__got > 0) && !__ovflow) &&
williamr@2:     (__is_group == 0 ||__valid_group) ;
williamr@2: }
williamr@2: 
williamr@2: 
williamr@2: template <class _InputIter, class _Integer>
williamr@2: bool _STLP_CALL
williamr@2: __get_decimal_integer(_InputIter& __first, _InputIter& __last, _Integer& __val)
williamr@2: {
williamr@2:   string __grp;
williamr@2:   return __get_integer(__first, __last, 10, __val, 0, false, ' ', __grp, __false_type());
williamr@2: }
williamr@2: 
williamr@2: template <class _InputIter, class _Integer, class _CharT>
williamr@2: _InputIter _STLP_CALL
williamr@2: _M_do_get_integer(_InputIter& __stl_in, _InputIter& __end, ios_base& __str,
williamr@2:                   ios_base::iostate& __err, _Integer& __val, _CharT* __pc)
williamr@2: {
williamr@2: 
williamr@2: #if defined(__HP_aCC) && (__HP_aCC == 1)
williamr@2:   bool _IsSigned = !((_Integer)(-1) > 0);
williamr@2: #else
williamr@2:   typedef typename __bool2type<numeric_limits<_Integer>::is_signed>::_Ret _IsSigned;
williamr@2: #endif
williamr@2: 
williamr@2:   //const numpunct<_CharT>& __numpunct = *(const numpunct<_CharT>*)__str._M_numpunct_facet();
williamr@2:   const numpunct<_CharT>& __numpunct = use_facet< numpunct<_CharT> >(__str.getloc());
williamr@2: //  const string& __grouping = __str._M_grouping(); // cached copy //stdcxx fix - 11/1/06
williamr@2:   const string& __grouping = __numpunct.grouping();
williamr@2: 
williamr@2: 
williamr@2:   const int __base_or_zero = _M_get_base_or_zero(__stl_in, __end, __str, __pc);
williamr@2:   int  __got = __base_or_zero & 1;
williamr@2: 
williamr@2:   bool __result;
williamr@2: 
williamr@2:   if (__stl_in == __end) {      // We may have already read a 0.  If so,
williamr@2: 
williamr@2:     if (__got > 0) {       // the result is 0 even if we're at eof.
williamr@2:       __val = 0;
williamr@2:       __result = true;
williamr@2:     }
williamr@2:     else
williamr@2:       __result = false;
williamr@2:   } else {
williamr@2: 
williamr@2:     const bool __negative = __base_or_zero & 2;
williamr@2:     const int __base = __base_or_zero >> 2;
williamr@2: 
williamr@2: #if defined(__HP_aCC) && (__HP_aCC == 1)
williamr@2:      if (_IsSigned)
williamr@2:        __result = __get_integer(__stl_in, __end, __base,  __val, __got, __negative, __numpunct.thousands_sep(), __grouping, __true_type() );
williamr@2:      else
williamr@2:       __result = __get_integer(__stl_in, __end, __base,  __val, __got, __negative, __numpunct.thousands_sep(), __grouping, __false_type() );
williamr@2: #else
williamr@2: #ifdef __SYMBIAN32__
williamr@2:     _Integer __tval;
williamr@2:     __result = __get_integer(__stl_in, __end, __base,  __tval, __got, __negative, __numpunct.thousands_sep(), __grouping, _IsSigned());
williamr@2:     if(__result)
williamr@2:         __val = __tval;
williamr@2: #else
williamr@2:     __result = __get_integer(__stl_in, __end, __base,  __val, __got, __negative, __numpunct.thousands_sep(), __grouping, _IsSigned());
williamr@2: #endif    
williamr@2: # endif
williamr@2:   }
williamr@2: 
williamr@2:   __err = __STATIC_CAST(ios_base::iostate, __result ? ios_base::goodbit : ios_base::failbit);
williamr@2: 
williamr@2:   if (__stl_in == __end)
williamr@2:     __err |= ios_base::eofbit;
williamr@2:   return __stl_in;
williamr@2: }
williamr@2: 
williamr@2: // _M_read_float and its helper functions.
williamr@2: template <class _InputIter, class _CharT>
williamr@2: _InputIter  _STLP_CALL
williamr@2: __copy_sign(_InputIter __first, _InputIter __last, string& __v,
williamr@2:             _CharT __xplus, _CharT __xminus) {
williamr@2:     if (__first != __last) {
williamr@2:     _CharT __c = *__first;
williamr@2:     if (__c == __xplus)
williamr@2:       ++__first;
williamr@2:     else if (__c == __xminus) {
williamr@2:       __v.push_back('-');
williamr@2:       ++__first;
williamr@2:     }
williamr@2:   }
williamr@2:   return __first;
williamr@2: }
williamr@2: 
williamr@2: 
williamr@2: template <class _InputIter, class _CharT>
williamr@2: bool _STLP_CALL
williamr@2: __copy_digits(_InputIter& __first, _InputIter& __last,
williamr@2:               string& __v, const _CharT* __digits)
williamr@2: {
williamr@2:   bool __ok = false;
williamr@2: 
williamr@2:   for ( ; __first != __last; ++__first) {
williamr@2:     _CharT __c = *__first;
williamr@2:     if (__get_fdigit(__c, __digits)) {
williamr@2:       __v.push_back((char)__c);
williamr@2:       __ok = true;
williamr@2:     }
williamr@2:     else
williamr@2:       break;
williamr@2:   }
williamr@2:   return __ok;
williamr@2: }
williamr@2: 
williamr@2: template <class _InputIter, class _CharT>
williamr@2: bool _STLP_CALL
williamr@2: __copy_grouped_digits(_InputIter& __first, _InputIter& __last,
williamr@2: 		      string& __v, const _CharT * __digits,
williamr@2: 		      _CharT __sep, const string& __grouping,
williamr@2: 		      bool& __grouping_ok)
williamr@2: {
williamr@2:   bool __ok = false;
williamr@2: //  char __group_sizes[64];
williamr@2:   char __group_sizes[256] = {0};//group sizes can be more
williamr@2:   char*__group_sizes_end = __group_sizes;
williamr@2:   char __current_group_size = 0;
williamr@2: 
williamr@2:   for ( ; __first != __last; ++__first) {
williamr@2:     _CharT __c = *__first;
williamr@2:     bool __tmp = __get_fdigit_or_sep(__c, __sep, __digits);
williamr@2:     if (__tmp) {
williamr@2:       if (__c == ',') { 
williamr@2:       	// seperator should come after extracting some digits
williamr@2:       	if (!__current_group_size)
williamr@2:       		break;
williamr@2:       	
williamr@2:         *__group_sizes_end++ = __current_group_size;        
williamr@2:         __current_group_size = 0;
williamr@2:       }
williamr@2:       else {
williamr@2:         __ok = true;
williamr@2:         __v.push_back((char)__c);
williamr@2:         ++__current_group_size;
williamr@2:       }
williamr@2:     }
williamr@2:     else
williamr@2:       break;
williamr@2:   }
williamr@2: 
williamr@2:   if (__group_sizes_end != __group_sizes)
williamr@2:     *__group_sizes_end++ = __current_group_size;    
williamr@2:   __grouping_ok = __valid_grouping(__group_sizes, __group_sizes_end, __grouping.data(), __grouping.data() + __grouping.size());
williamr@2:   __ok = __ok & __grouping_ok; //Added, to check for valid grouping. If not valid grouping should return false.
williamr@2:   return __ok;
williamr@2: }
williamr@2: 
williamr@2: 
williamr@2: template <class _InputIter, class _CharT>
williamr@2: bool _STLP_CALL
williamr@2: _M_read_float(string& __buf, _InputIter& __stl_in, _InputIter& __end, ios_base& __s, _CharT*)
williamr@2: {
williamr@2:   // Create a string, copying characters of the form
williamr@2:   // [+-]? [0-9]* .? [0-9]* ([eE] [+-]? [0-9]+)?
williamr@2: 
williamr@2:   bool __digits_before_dot /* = false */;
williamr@2:   bool __digits_after_dot = false;
williamr@2:   bool __ok;
williamr@2: 
williamr@2:   bool   __grouping_ok = true;
williamr@2: 
williamr@2:   const ctype<_CharT>& __ct = use_facet< ctype<_CharT> >(__s.getloc());
williamr@2:   // const ctype<_CharT>& __ct = *(const ctype<_CharT>*)__s._M_ctype_facet();
williamr@2:   //const numpunct<_CharT>& __numpunct = *(const numpunct<_CharT>*)__s._M_numpunct_facet();
williamr@2:   const numpunct<_CharT>& __numpunct = use_facet< numpunct<_CharT> >(__s.getloc());
williamr@2: //  const string& __grouping = __s._M_grouping(); // cached copy //stdcxx fix - 11/1/06
williamr@2:     const string& __grouping = __numpunct.grouping();
williamr@2: 
williamr@2:   _CharT __dot = __numpunct.decimal_point();
williamr@2:   _CharT __sep = __numpunct.thousands_sep();
williamr@2: 
williamr@2:   _CharT __digits[10];
williamr@2:   _CharT __xplus;
williamr@2:   _CharT __xminus;
williamr@2: 
williamr@2:   _CharT __pow_e;
williamr@2:   _CharT __pow_E;
williamr@2: 
williamr@2:   _Initialize_get_float(__ct, __xplus, __xminus, __pow_e, __pow_E, __digits);
williamr@2: 
williamr@2:   // Get an optional sign
williamr@2:   __stl_in = __copy_sign(__stl_in, __end, __buf, __xplus, __xminus);
williamr@2: 
williamr@2:   // Get an optional string of digits.
williamr@2:   if (__grouping.size() != 0)
williamr@2:     __digits_before_dot = __copy_grouped_digits(__stl_in, __end, __buf, __digits,
williamr@2: 						__sep, __grouping, __grouping_ok);
williamr@2:   else
williamr@2:     __digits_before_dot = __copy_digits(__stl_in, __end, __buf, __digits);
williamr@2: 
williamr@2:   // Get an optional decimal point, and an optional string of digits.
williamr@2:   if (__stl_in != __end && *__stl_in == __dot) {
williamr@2:     __buf.push_back('.');
williamr@2:     ++__stl_in;
williamr@2:     __digits_after_dot = __copy_digits(__stl_in, __end, __buf, __digits);
williamr@2:   }
williamr@2: 
williamr@2:   // There have to be some digits, somewhere.
williamr@2:   __ok = __digits_before_dot || __digits_after_dot;
williamr@2: 
williamr@2:   // Get an optional exponent.
williamr@2:   if (__ok && __stl_in != __end && (*__stl_in == __pow_e || *__stl_in == __pow_E)) {
williamr@2:     __buf.push_back('e');
williamr@2:     ++__stl_in;
williamr@2:     __stl_in = __copy_sign(__stl_in, __end, __buf, __xplus, __xminus);
williamr@2:     __ok = __copy_digits(__stl_in, __end, __buf, __digits);
williamr@2:     // If we have an exponent then the sign
williamr@2:     // is optional but the digits aren't.
williamr@2:   }
williamr@2: 
williamr@2:   return __ok;
williamr@2: }
williamr@2: 
williamr@2: //
williamr@2: // num_get<>, num_put<>
williamr@2: //
williamr@2: 
williamr@2: # if ( _STLP_STATIC_TEMPLATE_DATA > 0 )
williamr@2: # if !defined(__LIBSTD_CPP_SYMBIAN32_WSD__) && !defined(_STLP_LIBSTD_CPP_NO_STATIC_VAR_)
williamr@2: template <class _CharT, class _InputIterator>
williamr@2: locale::id num_get<_CharT, _InputIterator>::id;
williamr@2: #endif
williamr@2: # else
williamr@2: 
williamr@2: typedef num_get<char, const char*> num_get_char;
williamr@2: typedef num_get<char, istreambuf_iterator<char, char_traits<char> > > num_get_char_2;
williamr@2: 
williamr@2: #ifndef __SYMBIAN32__
williamr@2: __DECLARE_INSTANCE(locale::id, num_get_char::id, );
williamr@2: __DECLARE_INSTANCE(locale::id, num_get_char_2::id, );
williamr@2: #endif
williamr@2: 
williamr@2: # ifndef _STLP_NO_WCHAR_T
williamr@2: 
williamr@2: typedef num_get<wchar_t, const wchar_t*> num_get_wchar_t;
williamr@2: typedef num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > > num_get_wchar_t_2;
williamr@2: 
williamr@2: #ifndef __SYMBIAN32__
williamr@2: __DECLARE_INSTANCE(locale::id, num_get_wchar_t::id, );
williamr@2: __DECLARE_INSTANCE(locale::id, num_get_wchar_t_2::id, );
williamr@2: #endif
williamr@2: 
williamr@2: # endif
williamr@2: 
williamr@2: # endif /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */
williamr@2: 
williamr@2: # ifndef _STLP_NO_BOOL
williamr@2: template <class _CharT, class _InputIter>
williamr@2: _InputIter
williamr@2: num_get<_CharT, _InputIter>::do_get(_InputIter __stl_in, _InputIter __end,
williamr@2:                                     ios_base& __s,
williamr@2:                                     ios_base::iostate& __err, bool& __x) const
williamr@2: {
williamr@2:   if (__s.flags() & ios_base::boolalpha) {
williamr@2:     locale __loc = __s.getloc();
williamr@2:     //const _Numpunct& __np = *(const _Numpunct*)__s._M_numpunct_facet();
williamr@2:         const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc) ;
williamr@2: //    const ctype<_CharT>& __ct =    use_facet<ctype<_CharT> >(__loc) ;
williamr@2: 
williamr@2:     const basic_string<_CharT> __truename  = __np.truename();
williamr@2:     const basic_string<_CharT> __falsename = __np.falsename();
williamr@2:     bool __true_ok  = true;
williamr@2:     bool __false_ok = true;
williamr@2: 
williamr@2:     size_t __n = 0;
williamr@2:     for ( ; __stl_in != __end; ++__stl_in) {
williamr@2:       _CharT __c = *__stl_in;
williamr@2:       __true_ok  = __true_ok  && (__c == __truename[__n]);
williamr@2:       __false_ok = __false_ok && (__c == __falsename[__n]);
williamr@2:       ++__n;
williamr@2: 
williamr@2:       if ((!__true_ok && !__false_ok) ||
williamr@2:           (__true_ok  && __n >= __truename.size()) ||
williamr@2:           (__false_ok && __n >= __falsename.size())) {
williamr@2:           
williamr@2:           if (__true_ok || __false_ok)  //if anything OK then increment, else, break
williamr@2: 		++__stl_in;
williamr@2:         break;
williamr@2:       }
williamr@2:     }
williamr@2: 	// stdcxx fix, Changed to check for complete true,false string
williamr@2:     if (__true_ok  && __n < __truename.size()) 
williamr@2:    {
williamr@2: 	for ( ; __stl_in != __end; ++__stl_in) {
williamr@2:       		_CharT __c = *__stl_in;
williamr@2:       		__true_ok  = __true_ok  && (__c == __truename[__n]);
williamr@2: 		++__n;  
williamr@2: 		 if ((!__true_ok) ||(__true_ok  && __n >= __truename.size()) )
williamr@2: 		 {
williamr@2: 		 	if(__true_ok)
williamr@2: 		 		++__stl_in;
williamr@2:           		break;
williamr@2: 		 }
williamr@2: 		 	
williamr@2: 	}
williamr@2: 	 if (__true_ok  && __n < __truename.size()) 
williamr@2: 	   	__true_ok  = false;
williamr@2:     }
williamr@2:     if (__false_ok && __n < __falsename.size())
williamr@2:    {
williamr@2: 
williamr@2:    		for ( ; __stl_in != __end; ++__stl_in) {
williamr@2:       		_CharT __c = *__stl_in;
williamr@2:       		__false_ok  = __false_ok  && (__c == __falsename[__n]);
williamr@2: 		++__n;  
williamr@2: 		 if ((!__false_ok) ||(__false_ok  && __n >= __falsename.size()) )         
williamr@2:           	{
williamr@2: 			if(__false_ok)
williamr@2: 				++__stl_in;
williamr@2:           		break;
williamr@2: 		 }
williamr@2: 		 	
williamr@2: 		}
williamr@2: 		if (__false_ok && __n < __falsename.size())
williamr@2:    			__false_ok = false;
williamr@2:     }
williamr@2: 
williamr@2:     if (__true_ok || __false_ok) {
williamr@2:       __err = ios_base::goodbit;
williamr@2:       __x = __true_ok;
williamr@2:     }
williamr@2:     else
williamr@2:       __err = ios_base::failbit;
williamr@2: 
williamr@2:     if (__stl_in == __end)
williamr@2:       __err |= ios_base::eofbit;
williamr@2: 
williamr@2:     return __stl_in;
williamr@2:   }
williamr@2: 
williamr@2:   else {
williamr@2:     long __lx;
williamr@2:     _InputIter __tmp = this->do_get(__stl_in, __end, __s, __err, __lx);
williamr@2:     if (!(__err & ios_base::failbit)) {
williamr@2:       if (__lx == 0)
williamr@2:         __x = false;
williamr@2:       else if (__lx == 1)
williamr@2:         __x = true;
williamr@2:       else
williamr@2:         __err |= ios_base::failbit;
williamr@2:     }
williamr@2:     return __tmp;
williamr@2:   }
williamr@2: }
williamr@2: 
williamr@2: # endif /* _STLP_NO_BOOL */
williamr@2: 
williamr@2: //# ifdef _STLP_FIX_LIBRARY_ISSUES
williamr@2: template <class _CharT, class _InputIter>
williamr@2: _InputIter
williamr@2: num_get<_CharT, _InputIter>::do_get(_InputIter __stl_in, _InputIter __end, ios_base& __str,
williamr@2:                                     ios_base::iostate& __err, short& __val) const {
williamr@2:   return _M_do_get_integer(__stl_in, __end, __str, __err, __val, (_CharT*)0 );
williamr@2: }
williamr@2: 
williamr@2: template <class _CharT, class _InputIter>
williamr@2: _InputIter
williamr@2: num_get<_CharT, _InputIter>::do_get(_InputIter __stl_in, _InputIter __end, ios_base& __str,
williamr@2:                                     ios_base::iostate& __err, int& __val) const {
williamr@2:   return _M_do_get_integer(__stl_in, __end, __str, __err, __val, (_CharT*)0 );
williamr@2: }
williamr@2: 
williamr@2: //# endif
williamr@2: 
williamr@2: template <class _CharT, class _InputIter>
williamr@2: _InputIter
williamr@2: num_get<_CharT, _InputIter>::do_get(_InputIter __stl_in, _InputIter __end, ios_base& __str,
williamr@2:                                     ios_base::iostate& __err, long& __val) const {
williamr@2:   return _M_do_get_integer(__stl_in, __end, __str, __err, __val, (_CharT*)0 );
williamr@2: }
williamr@2: 
williamr@2: template <class _CharT, class _InputIter>
williamr@2: _InputIter
williamr@2: num_get<_CharT, _InputIter>::do_get(_InputIter __stl_in, _InputIter __end, ios_base& __str,
williamr@2:                                     ios_base::iostate& __err,
williamr@2:                                     unsigned short& __val) const {
williamr@2:   return _M_do_get_integer(__stl_in, __end, __str, __err, __val, (_CharT*)0 );
williamr@2: }
williamr@2: 
williamr@2: template <class _CharT, class _InputIter>
williamr@2: _InputIter
williamr@2: num_get<_CharT, _InputIter>::do_get(_InputIter __stl_in, _InputIter __end, ios_base& __str,
williamr@2:                                     ios_base::iostate& __err,
williamr@2:                                     unsigned int& __val) const {
williamr@2:   return _M_do_get_integer(__stl_in, __end, __str, __err, __val, (_CharT*)0 );
williamr@2: }
williamr@2: 
williamr@2: template <class _CharT, class _InputIter>
williamr@2: _InputIter
williamr@2: num_get<_CharT, _InputIter>::do_get(_InputIter __stl_in, _InputIter __end, ios_base& __str,
williamr@2:                                     ios_base::iostate& __err,
williamr@2:                                     unsigned long& __val) const {
williamr@2:   return _M_do_get_integer(__stl_in, __end, __str, __err, __val, (_CharT*)0 );
williamr@2: }
williamr@2: 
williamr@2: 
williamr@2: template <class _CharT, class _InputIter>
williamr@2: _InputIter
williamr@2: num_get<_CharT, _InputIter>::do_get(_InputIter __stl_in, _InputIter __end, ios_base& __str,
williamr@2:                                     ios_base::iostate& __err,
williamr@2:                                     float& __val) const {
williamr@2:   string __buf ;
williamr@2:   bool __ok = _M_read_float(__buf, __stl_in, __end, __str, (_CharT*)0 );
williamr@2:   if(__ok) //If success reading float then convert it.
williamr@2:   {
williamr@2: #ifdef __SYMBIAN32__
williamr@2:     float __tval;
williamr@2:     __ok = __string_to_float(__buf, __tval);
williamr@2:     if(__ok)
williamr@2:         __val = __tval;
williamr@2: #else
williamr@2:     __string_to_float(__buf, __val);
williamr@2: #endif    
williamr@2:   }
williamr@2:   __err = __STATIC_CAST(ios_base::iostate, __ok ? ios_base::goodbit : ios_base::failbit);
williamr@2:   if (__stl_in == __end)
williamr@2:     __err |= ios_base::eofbit;
williamr@2:   return __stl_in;
williamr@2: }
williamr@2: 
williamr@2: template <class _CharT, class _InputIter>
williamr@2: _InputIter
williamr@2: num_get<_CharT, _InputIter>::do_get(_InputIter __stl_in, _InputIter __end, ios_base& __str,
williamr@2:                                     ios_base::iostate& __err,
williamr@2:                                     double& __val) const {
williamr@2:   string __buf ;
williamr@2:   bool __ok = _M_read_float(__buf, __stl_in, __end, __str, (_CharT*)0 );
williamr@2:   if(__ok) //If success reading float then convert it.
williamr@2:   {
williamr@2: #ifdef __SYMBIAN32__
williamr@2:     double __tval;
williamr@2:     __ok = __string_to_float(__buf, __tval);
williamr@2:     if(__ok)
williamr@2:         __val = __tval;
williamr@2: #else
williamr@2:     __string_to_float(__buf, __val);
williamr@2: #endif    
williamr@2:   }
williamr@2:   __err = __STATIC_CAST(ios_base::iostate, __ok ? ios_base::goodbit : ios_base::failbit);
williamr@2:   if (__stl_in == __end)
williamr@2:     __err |= ios_base::eofbit;
williamr@2:   return __stl_in;
williamr@2: }
williamr@2: 
williamr@2: #ifndef _STLP_NO_LONG_DOUBLE
williamr@2: template <class _CharT, class _InputIter>
williamr@2: _InputIter
williamr@2: num_get<_CharT, _InputIter>::do_get(_InputIter __stl_in, _InputIter __end, ios_base& __str,
williamr@2: 				    ios_base::iostate& __err,
williamr@2:                                     long double& __val) const {
williamr@2:   string __buf ;
williamr@2:   bool __ok = _M_read_float(__buf, __stl_in, __end, __str, (_CharT*)0 );
williamr@2:   if(__ok) //If success reading float then convert it.
williamr@2:   {
williamr@2: #ifdef __SYMBIAN32__
williamr@2:     long double __tval;
williamr@2:     __ok = __string_to_float(__buf, __tval);
williamr@2:     if(__ok)
williamr@2:         __val = __tval;
williamr@2: #else
williamr@2:     __string_to_float(__buf, __val);
williamr@2: #endif    
williamr@2:   }
williamr@2:   __err = __STATIC_CAST(ios_base::iostate, __ok ? ios_base::goodbit : ios_base::failbit);
williamr@2:   if (__stl_in == __end)
williamr@2:     __err |= ios_base::eofbit;
williamr@2:   return __stl_in;
williamr@2: }
williamr@2: #endif /* _STLP_NO_LONG_DOUBLE */
williamr@2: 
williamr@2: template <class _CharT, class _InputIter>
williamr@2: _InputIter
williamr@2: num_get<_CharT, _InputIter>::do_get(_InputIter __stl_in, _InputIter __end, ios_base& __str,
williamr@2:                            ios_base::iostate& __err,
williamr@2:                            void*& __p) const {
williamr@2: #ifdef	__SYMBIAN32__
williamr@2: 	unsigned long __val;	//using only long
williamr@2: #else
williamr@2: # if defined(_STLP_LONG_LONG)&&!defined(__MRC__)		//*ty 12/07/2001 - MrCpp can not cast from long long to void*
williamr@2:   unsigned _STLP_LONG_LONG __val;
williamr@2: # else
williamr@2:   unsigned long __val;
williamr@2: # endif
williamr@2: #endif //__SYMBIAN32__
williamr@2: #ifdef __SYMBIAN32__
williamr@2:     ios_base::fmtflags __save_flags = __str.flags();
williamr@2: 
williamr@2:     __str.setf(ios_base::hex, ios_base::basefield);
williamr@2:     __str.setf(ios_base::showbase);
williamr@2:     __str.setf(ios_base::internal, ios_base::adjustfield);
williamr@2:     __str.width((sizeof(void*) * 2) + 2);
williamr@2: #endif // __SYMBIAN32__
williamr@2:     iter_type __tmp = _M_do_get_integer(__stl_in, __end, __str, __err, __val, (_CharT*)0 );
williamr@2:     if (!(__err & ios_base::failbit))
williamr@2:       __p = __REINTERPRET_CAST(void*,(long)__val);
williamr@2: #ifdef __SYMBIAN32__
williamr@2:     __str.flags(__save_flags);
williamr@2: #endif //__SYMBIAN32__
williamr@2:     return __tmp;
williamr@2:   }
williamr@2: 
williamr@2: 
williamr@2: #ifdef _STLP_LONG_LONG
williamr@2: 
williamr@2: template <class _CharT, class _InputIter>
williamr@2: _InputIter
williamr@2: num_get<_CharT, _InputIter>::do_get(_InputIter __stl_in, _InputIter __end, ios_base& __str,
williamr@2:                                     ios_base::iostate& __err,
williamr@2:                                     _STLP_LONG_LONG& __val) const {
williamr@2:   return _M_do_get_integer(__stl_in, __end, __str, __err, __val, (_CharT*)0 );
williamr@2: }
williamr@2: 
williamr@2: template <class _CharT, class _InputIter>
williamr@2: _InputIter
williamr@2: num_get<_CharT, _InputIter>::do_get(_InputIter __stl_in, _InputIter __end, ios_base& __str,
williamr@2:                                     ios_base::iostate& __err,
williamr@2:                                     unsigned _STLP_LONG_LONG& __val) const {
williamr@2:   return _M_do_get_integer(__stl_in, __end, __str, __err, __val, (_CharT*)0 );
williamr@2: }
williamr@2: 
williamr@2: #endif /* _STLP_LONG_LONG */
williamr@2: 
williamr@2: _STLP_END_NAMESPACE
williamr@2: 
williamr@2: # endif /* _STLP_EXPOSE_STREAM_IMPLEMENTATION */
williamr@2: 
williamr@2: #endif /* _STLP_NUMERIC_FACETS_C */
williamr@2: 
williamr@2: // Local Variables:
williamr@2: // mode:C++
williamr@2: // End: