xref: /reactos/sdk/include/c++/stlport/stl/_num_get.c (revision c2c66aff)
1*c2c66affSColin Finck /*
2*c2c66affSColin Finck  * Copyright (c) 1999
3*c2c66affSColin Finck  * Silicon Graphics Computer Systems, Inc.
4*c2c66affSColin Finck  *
5*c2c66affSColin Finck  * Copyright (c) 1999
6*c2c66affSColin Finck  * Boris Fomitchev
7*c2c66affSColin Finck  *
8*c2c66affSColin Finck  * This material is provided "as is", with absolutely no warranty expressed
9*c2c66affSColin Finck  * or implied. Any use is at your own risk.
10*c2c66affSColin Finck  *
11*c2c66affSColin Finck  * Permission to use or copy this software for any purpose is hereby granted
12*c2c66affSColin Finck  * without fee, provided the above notices are retained on all copies.
13*c2c66affSColin Finck  * Permission to modify the code and to distribute modified code is granted,
14*c2c66affSColin Finck  * provided the above notices are retained, and a notice that the code was
15*c2c66affSColin Finck  * modified is included with the above copyright notice.
16*c2c66affSColin Finck  *
17*c2c66affSColin Finck  */
18*c2c66affSColin Finck #ifndef _STLP_NUM_GET_C
19*c2c66affSColin Finck #define _STLP_NUM_GET_C
20*c2c66affSColin Finck 
21*c2c66affSColin Finck #ifndef _STLP_INTERNAL_NUM_GET_H
22*c2c66affSColin Finck #  include <stl/_num_get.h>
23*c2c66affSColin Finck #endif
24*c2c66affSColin Finck 
25*c2c66affSColin Finck #ifndef _STLP_INTERNAL_LIMITS
26*c2c66affSColin Finck #  include <stl/_limits.h>
27*c2c66affSColin Finck #endif
28*c2c66affSColin Finck 
29*c2c66affSColin Finck _STLP_BEGIN_NAMESPACE
30*c2c66affSColin Finck 
31*c2c66affSColin Finck _STLP_MOVE_TO_PRIV_NAMESPACE
32*c2c66affSColin Finck 
33*c2c66affSColin Finck _STLP_DECLSPEC unsigned char _STLP_CALL __digit_val_table(unsigned);
34*c2c66affSColin Finck _STLP_DECLSPEC const char* _STLP_CALL __narrow_atoms();
35*c2c66affSColin Finck 
36*c2c66affSColin Finck // __do_get_integer, __do_get_float and its helper functions.
37*c2c66affSColin Finck 
__get_fdigit(char __c,const char *)38*c2c66affSColin Finck inline bool _STLP_CALL __get_fdigit(char __c, const char*)
39*c2c66affSColin Finck { return __c >= '0' && __c <= '9'; }
40*c2c66affSColin Finck 
__get_fdigit_or_sep(char & __c,char __sep,const char * __digits)41*c2c66affSColin Finck inline bool _STLP_CALL __get_fdigit_or_sep(char& __c, char __sep, const char *__digits) {
42*c2c66affSColin Finck   if (__c == __sep) {
43*c2c66affSColin Finck     __c = ',' ;
44*c2c66affSColin Finck     return true ;
45*c2c66affSColin Finck   }
46*c2c66affSColin Finck   else
47*c2c66affSColin Finck     return  __get_fdigit(__c, __digits);
48*c2c66affSColin Finck }
49*c2c66affSColin Finck 
50*c2c66affSColin Finck inline int _STLP_CALL
__get_digit_from_table(unsigned __index)51*c2c66affSColin Finck __get_digit_from_table(unsigned __index)
52*c2c66affSColin Finck { return (__index > 127 ? 0xFF : __digit_val_table(__index)); }
53*c2c66affSColin Finck 
54*c2c66affSColin Finck template <class _InputIter, class _CharT>
55*c2c66affSColin Finck int
__get_base_or_zero(_InputIter & __in_ite,_InputIter & __end,ios_base::fmtflags __flags,const ctype<_CharT> & __c_type)56*c2c66affSColin Finck __get_base_or_zero(_InputIter& __in_ite, _InputIter& __end,
57*c2c66affSColin Finck                    ios_base::fmtflags __flags, const ctype<_CharT>& __c_type) {
58*c2c66affSColin Finck   _CharT __atoms[5];
59*c2c66affSColin Finck   __c_type.widen(__narrow_atoms(), __narrow_atoms() + 5, __atoms);
60*c2c66affSColin Finck 
61*c2c66affSColin Finck   bool __negative = false;
62*c2c66affSColin Finck   _CharT __c = *__in_ite;
63*c2c66affSColin Finck 
64*c2c66affSColin Finck   if (__c == __atoms[1] /* __xminus_char */ ) {
65*c2c66affSColin Finck     __negative = true;
66*c2c66affSColin Finck     ++__in_ite;
67*c2c66affSColin Finck   }
68*c2c66affSColin Finck   else if (__c == __atoms[0] /* __xplus_char */ )
69*c2c66affSColin Finck     ++__in_ite;
70*c2c66affSColin Finck 
71*c2c66affSColin Finck   int __base;
72*c2c66affSColin Finck   int __valid_zero = 0;
73*c2c66affSColin Finck 
74*c2c66affSColin Finck   ios_base::fmtflags __basefield = __flags & ios_base::basefield;
75*c2c66affSColin Finck 
76*c2c66affSColin Finck   switch (__basefield) {
77*c2c66affSColin Finck   case ios_base::oct:
78*c2c66affSColin Finck     __base = 8;
79*c2c66affSColin Finck     break;
80*c2c66affSColin Finck   case ios_base::dec:
81*c2c66affSColin Finck     __base = 10;
82*c2c66affSColin Finck     break;
83*c2c66affSColin Finck   case ios_base::hex:
84*c2c66affSColin Finck     __base = 16;
85*c2c66affSColin Finck     if (__in_ite != __end && *__in_ite == __atoms[2] /* __zero_char */ ) {
86*c2c66affSColin Finck       ++__in_ite;
87*c2c66affSColin Finck       if (__in_ite != __end &&
88*c2c66affSColin Finck           (*__in_ite == __atoms[3] /* __x_char */ || *__in_ite == __atoms[4] /* __X_char */ ))
89*c2c66affSColin Finck         ++__in_ite;
90*c2c66affSColin Finck       else
91*c2c66affSColin Finck         __valid_zero = 1; // That zero is valid by itself.
92*c2c66affSColin Finck     }
93*c2c66affSColin Finck     break;
94*c2c66affSColin Finck   default:
95*c2c66affSColin Finck     if (__in_ite != __end && *__in_ite == __atoms[2] /* __zero_char */ ) {
96*c2c66affSColin Finck       ++__in_ite;
97*c2c66affSColin Finck       if (__in_ite != __end &&
98*c2c66affSColin Finck           (*__in_ite == __atoms[3] /* __x_char */ || *__in_ite == __atoms[4] /* __X_char */ )) {
99*c2c66affSColin Finck         ++__in_ite;
100*c2c66affSColin Finck         __base = 16;
101*c2c66affSColin Finck       }
102*c2c66affSColin Finck       else
103*c2c66affSColin Finck         {
104*c2c66affSColin Finck           __base = 8;
105*c2c66affSColin Finck           __valid_zero = 1; // That zero is still valid by itself.
106*c2c66affSColin Finck         }
107*c2c66affSColin Finck     }
108*c2c66affSColin Finck     else
109*c2c66affSColin Finck       __base = 10;
110*c2c66affSColin Finck     break;
111*c2c66affSColin Finck   }
112*c2c66affSColin Finck   return (__base << 2) | ((int)__negative << 1) | __valid_zero;
113*c2c66affSColin Finck }
114*c2c66affSColin Finck 
115*c2c66affSColin Finck 
116*c2c66affSColin Finck template <class _InputIter, class _Integer, class _CharT>
117*c2c66affSColin Finck bool _STLP_CALL
__get_integer(_InputIter & __first,_InputIter & __last,int __base,_Integer & __val,int __got,bool __is_negative,_CharT __separator,const string & __grouping,const __true_type &)118*c2c66affSColin Finck __get_integer(_InputIter& __first, _InputIter& __last,
119*c2c66affSColin Finck               int __base, _Integer& __val,
120*c2c66affSColin Finck               int __got, bool __is_negative, _CharT __separator, const string& __grouping, const __true_type& /*_IsSigned*/) {
121*c2c66affSColin Finck   bool __ovflow = false;
122*c2c66affSColin Finck   _Integer __result = 0;
123*c2c66affSColin Finck   bool __is_group = !__grouping.empty();
124*c2c66affSColin Finck   char __group_sizes[64];
125*c2c66affSColin Finck   char __current_group_size = 0;
126*c2c66affSColin Finck   char* __group_sizes_end = __group_sizes;
127*c2c66affSColin Finck 
128*c2c66affSColin Finck   _Integer __over_base = (numeric_limits<_Integer>::min)() / __STATIC_CAST(_Integer, __base);
129*c2c66affSColin Finck 
130*c2c66affSColin Finck    for ( ; __first != __last ; ++__first) {
131*c2c66affSColin Finck 
132*c2c66affSColin Finck      const _CharT __c = *__first;
133*c2c66affSColin Finck 
134*c2c66affSColin Finck      if (__is_group && __c == __separator) {
135*c2c66affSColin Finck        *__group_sizes_end++ = __current_group_size;
136*c2c66affSColin Finck        __current_group_size = 0;
137*c2c66affSColin Finck        continue;
138*c2c66affSColin Finck      }
139*c2c66affSColin Finck 
140*c2c66affSColin Finck      int __n = __get_digit_from_table(__c);
141*c2c66affSColin Finck 
142*c2c66affSColin Finck      if (__n >= __base)
143*c2c66affSColin Finck        break;
144*c2c66affSColin Finck 
145*c2c66affSColin Finck      ++__got;
146*c2c66affSColin Finck      ++__current_group_size;
147*c2c66affSColin Finck 
148*c2c66affSColin Finck      if (__result < __over_base)
149*c2c66affSColin Finck        __ovflow = true;  // don't need to keep accumulating
150*c2c66affSColin Finck      else {
151*c2c66affSColin Finck        _Integer __next = __STATIC_CAST(_Integer, __base * __result - __n);
152*c2c66affSColin Finck        if (__result != 0)
153*c2c66affSColin Finck          __ovflow = __ovflow || __next >= __result;
154*c2c66affSColin Finck        __result = __next;
155*c2c66affSColin Finck      }
156*c2c66affSColin Finck    }
157*c2c66affSColin Finck 
158*c2c66affSColin Finck    if (__is_group && __group_sizes_end != __group_sizes) {
159*c2c66affSColin Finck      *__group_sizes_end++ = __current_group_size;
160*c2c66affSColin Finck    }
161*c2c66affSColin Finck 
162*c2c66affSColin Finck    // fbp : added to not modify value if nothing was read
163*c2c66affSColin Finck    if (__got > 0) {
164*c2c66affSColin Finck        __val = __ovflow ? __is_negative ? (numeric_limits<_Integer>::min)()
165*c2c66affSColin Finck                                         : (numeric_limits<_Integer>::max)()
166*c2c66affSColin Finck                         : __is_negative ? __result
167*c2c66affSColin Finck                                         : __STATIC_CAST(_Integer, -__result);
168*c2c66affSColin Finck    }
169*c2c66affSColin Finck   // overflow is being treated as failure
170*c2c66affSColin Finck   return ((__got > 0) && !__ovflow) &&
171*c2c66affSColin Finck           (__is_group == 0 ||
172*c2c66affSColin Finck            __valid_grouping(__group_sizes, __group_sizes_end,
173*c2c66affSColin Finck                             __grouping.data(), __grouping.data()+ __grouping.size()));
174*c2c66affSColin Finck }
175*c2c66affSColin Finck 
176*c2c66affSColin Finck template <class _InputIter, class _Integer, class _CharT>
177*c2c66affSColin Finck bool _STLP_CALL
__get_integer(_InputIter & __first,_InputIter & __last,int __base,_Integer & __val,int __got,bool __is_negative,_CharT __separator,const string & __grouping,const __false_type &)178*c2c66affSColin Finck __get_integer(_InputIter& __first, _InputIter& __last,
179*c2c66affSColin Finck               int __base, _Integer& __val,
180*c2c66affSColin Finck               int __got, bool __is_negative, _CharT __separator, const string& __grouping, const __false_type& /*_IsSigned*/) {
181*c2c66affSColin Finck   bool __ovflow = false;
182*c2c66affSColin Finck   _Integer __result = 0;
183*c2c66affSColin Finck   bool __is_group = !__grouping.empty();
184*c2c66affSColin Finck   char __group_sizes[64];
185*c2c66affSColin Finck   char __current_group_size = 0;
186*c2c66affSColin Finck   char* __group_sizes_end = __group_sizes;
187*c2c66affSColin Finck 
188*c2c66affSColin Finck   _Integer  __over_base = (numeric_limits<_Integer>::max)() / __STATIC_CAST(_Integer, __base);
189*c2c66affSColin Finck 
190*c2c66affSColin Finck   for ( ; __first != __last ; ++__first) {
191*c2c66affSColin Finck 
192*c2c66affSColin Finck     const _CharT __c = *__first;
193*c2c66affSColin Finck 
194*c2c66affSColin Finck     if (__is_group && __c == __separator) {
195*c2c66affSColin Finck       *__group_sizes_end++ = __current_group_size;
196*c2c66affSColin Finck       __current_group_size = 0;
197*c2c66affSColin Finck       continue;
198*c2c66affSColin Finck     }
199*c2c66affSColin Finck 
200*c2c66affSColin Finck     int __n = __get_digit_from_table(__c);
201*c2c66affSColin Finck 
202*c2c66affSColin Finck     if (__n >= __base)
203*c2c66affSColin Finck       break;
204*c2c66affSColin Finck 
205*c2c66affSColin Finck     ++__got;
206*c2c66affSColin Finck     ++__current_group_size;
207*c2c66affSColin Finck 
208*c2c66affSColin Finck     if (__result > __over_base)
209*c2c66affSColin Finck       __ovflow = true;  //don't need to keep accumulating
210*c2c66affSColin Finck     else {
211*c2c66affSColin Finck       _Integer __next = __STATIC_CAST(_Integer, __base * __result + __n);
212*c2c66affSColin Finck       if (__result != 0)
213*c2c66affSColin Finck         __ovflow = __ovflow || __next <= __result;
214*c2c66affSColin Finck         __result = __next;
215*c2c66affSColin Finck       }
216*c2c66affSColin Finck   }
217*c2c66affSColin Finck 
218*c2c66affSColin Finck   if (__is_group && __group_sizes_end != __group_sizes) {
219*c2c66affSColin Finck       *__group_sizes_end++ = __current_group_size;
220*c2c66affSColin Finck   }
221*c2c66affSColin Finck 
222*c2c66affSColin Finck   // fbp : added to not modify value if nothing was read
223*c2c66affSColin Finck   if (__got > 0) {
224*c2c66affSColin Finck       __val = __ovflow ? (numeric_limits<_Integer>::max)()
225*c2c66affSColin Finck                        : (__is_negative ? __STATIC_CAST(_Integer, -__result)
226*c2c66affSColin Finck                                         : __result);
227*c2c66affSColin Finck   }
228*c2c66affSColin Finck 
229*c2c66affSColin Finck   // overflow is being treated as failure
230*c2c66affSColin Finck   return ((__got > 0) && !__ovflow) &&
231*c2c66affSColin Finck           (__is_group == 0 ||
232*c2c66affSColin Finck            __valid_grouping(__group_sizes, __group_sizes_end,
233*c2c66affSColin Finck                             __grouping.data(), __grouping.data()+ __grouping.size()));
234*c2c66affSColin Finck }
235*c2c66affSColin Finck 
236*c2c66affSColin Finck 
237*c2c66affSColin Finck template <class _InputIter, class _Integer, class _CharT>
238*c2c66affSColin Finck bool _STLP_CALL
__get_decimal_integer(_InputIter & __first,_InputIter & __last,_Integer & __val,_CharT *)239*c2c66affSColin Finck __get_decimal_integer(_InputIter& __first, _InputIter& __last, _Integer& __val, _CharT* /*dummy*/) {
240*c2c66affSColin Finck   string __grp;
241*c2c66affSColin Finck   //Here there is no grouping so separator is not important, we just pass the default character.
242*c2c66affSColin Finck   return __get_integer(__first, __last, 10, __val, 0, false, _CharT() /*separator*/, __grp, __false_type());
243*c2c66affSColin Finck }
244*c2c66affSColin Finck 
245*c2c66affSColin Finck template <class _InputIter, class _Integer, class _CharT>
246*c2c66affSColin Finck _InputIter _STLP_CALL
__do_get_integer(_InputIter & __in_ite,_InputIter & __end,ios_base & __str,ios_base::iostate & __err,_Integer & __val,_CharT *)247*c2c66affSColin Finck __do_get_integer(_InputIter& __in_ite, _InputIter& __end, ios_base& __str,
248*c2c66affSColin Finck                  ios_base::iostate& __err, _Integer& __val, _CharT* /*__pc*/) {
249*c2c66affSColin Finck   locale __loc = __str.getloc();
250*c2c66affSColin Finck   const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
251*c2c66affSColin Finck 
252*c2c66affSColin Finck #if defined (__HP_aCC) && (__HP_aCC == 1)
253*c2c66affSColin Finck   bool _IsSigned = !((_Integer)(-1) > 0);
254*c2c66affSColin Finck #else
255*c2c66affSColin Finck   typedef typename __bool2type<numeric_limits<_Integer>::is_signed>::_Ret _IsSigned;
256*c2c66affSColin Finck #endif
257*c2c66affSColin Finck 
258*c2c66affSColin Finck   const int __base_or_zero = __get_base_or_zero(__in_ite, __end, __str.flags(), __ctype);
259*c2c66affSColin Finck   int  __got = __base_or_zero & 1;
260*c2c66affSColin Finck 
261*c2c66affSColin Finck   bool __result;
262*c2c66affSColin Finck 
263*c2c66affSColin Finck   if (__in_ite == __end) {      // We may have already read a 0.  If so,
264*c2c66affSColin Finck 
265*c2c66affSColin Finck     if (__got > 0) {       // the result is 0 even if we're at eof.
266*c2c66affSColin Finck       __val = 0;
267*c2c66affSColin Finck       __result = true;
268*c2c66affSColin Finck     }
269*c2c66affSColin Finck     else
270*c2c66affSColin Finck       __result = false;
271*c2c66affSColin Finck   }
272*c2c66affSColin Finck   else {
273*c2c66affSColin Finck     const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
274*c2c66affSColin Finck     const bool __negative = (__base_or_zero & 2) != 0;
275*c2c66affSColin Finck     const int __base = __base_or_zero >> 2;
276*c2c66affSColin Finck 
277*c2c66affSColin Finck #if defined (__HP_aCC) && (__HP_aCC == 1)
278*c2c66affSColin Finck     if (_IsSigned)
279*c2c66affSColin Finck       __result = __get_integer(__in_ite, __end, __base,  __val, __got, __negative, __np.thousands_sep(), __np.grouping(), __true_type() );
280*c2c66affSColin Finck     else
281*c2c66affSColin Finck       __result = __get_integer(__in_ite, __end, __base,  __val, __got, __negative, __np.thousands_sep(), __np.grouping(), __false_type() );
282*c2c66affSColin Finck #else
283*c2c66affSColin Finck     __result = __get_integer(__in_ite, __end, __base,  __val, __got, __negative, __np.thousands_sep(), __np.grouping(), _IsSigned());
284*c2c66affSColin Finck # endif
285*c2c66affSColin Finck   }
286*c2c66affSColin Finck 
287*c2c66affSColin Finck   __err = __STATIC_CAST(ios_base::iostate, __result ? ios_base::goodbit : ios_base::failbit);
288*c2c66affSColin Finck 
289*c2c66affSColin Finck   if (__in_ite == __end)
290*c2c66affSColin Finck     __err |= ios_base::eofbit;
291*c2c66affSColin Finck   return __in_ite;
292*c2c66affSColin Finck }
293*c2c66affSColin Finck 
294*c2c66affSColin Finck // __read_float and its helper functions.
295*c2c66affSColin Finck template <class _InputIter, class _CharT>
296*c2c66affSColin Finck _InputIter  _STLP_CALL
__copy_sign(_InputIter __first,_InputIter __last,__iostring & __v,_CharT __xplus,_CharT __xminus)297*c2c66affSColin Finck __copy_sign(_InputIter __first, _InputIter __last, __iostring& __v,
298*c2c66affSColin Finck             _CharT __xplus, _CharT __xminus) {
299*c2c66affSColin Finck   if (__first != __last) {
300*c2c66affSColin Finck     _CharT __c = *__first;
301*c2c66affSColin Finck     if (__c == __xplus)
302*c2c66affSColin Finck       ++__first;
303*c2c66affSColin Finck     else if (__c == __xminus) {
304*c2c66affSColin Finck       __v.push_back('-');
305*c2c66affSColin Finck       ++__first;
306*c2c66affSColin Finck     }
307*c2c66affSColin Finck   }
308*c2c66affSColin Finck   return __first;
309*c2c66affSColin Finck }
310*c2c66affSColin Finck 
311*c2c66affSColin Finck 
312*c2c66affSColin Finck template <class _InputIter, class _CharT>
313*c2c66affSColin Finck bool _STLP_CALL
__copy_digits(_InputIter & __first,_InputIter __last,__iostring & __v,const _CharT * __digits)314*c2c66affSColin Finck __copy_digits(_InputIter& __first, _InputIter __last,
315*c2c66affSColin Finck               __iostring& __v, const _CharT* __digits) {
316*c2c66affSColin Finck   bool __ok = false;
317*c2c66affSColin Finck 
318*c2c66affSColin Finck   for ( ; __first != __last; ++__first) {
319*c2c66affSColin Finck     _CharT __c = *__first;
320*c2c66affSColin Finck     if (__get_fdigit(__c, __digits)) {
321*c2c66affSColin Finck       __v.push_back((char)__c);
322*c2c66affSColin Finck       __ok = true;
323*c2c66affSColin Finck     }
324*c2c66affSColin Finck     else
325*c2c66affSColin Finck       break;
326*c2c66affSColin Finck   }
327*c2c66affSColin Finck   return __ok;
328*c2c66affSColin Finck }
329*c2c66affSColin Finck 
330*c2c66affSColin Finck template <class _InputIter, class _CharT>
331*c2c66affSColin Finck bool _STLP_CALL
__copy_grouped_digits(_InputIter & __first,_InputIter __last,__iostring & __v,const _CharT * __digits,_CharT __sep,const string & __grouping,bool & __grouping_ok)332*c2c66affSColin Finck __copy_grouped_digits(_InputIter& __first, _InputIter __last,
333*c2c66affSColin Finck                       __iostring& __v, const _CharT * __digits,
334*c2c66affSColin Finck                       _CharT __sep, const string& __grouping,
335*c2c66affSColin Finck                       bool& __grouping_ok) {
336*c2c66affSColin Finck   bool __ok = false;
337*c2c66affSColin Finck   char __group_sizes[64];
338*c2c66affSColin Finck   char*__group_sizes_end = __group_sizes;
339*c2c66affSColin Finck   char __current_group_size = 0;
340*c2c66affSColin Finck 
341*c2c66affSColin Finck   for ( ; __first != __last; ++__first) {
342*c2c66affSColin Finck     _CharT __c = *__first;
343*c2c66affSColin Finck     bool __tmp = __get_fdigit_or_sep(__c, __sep, __digits);
344*c2c66affSColin Finck     if (__tmp) {
345*c2c66affSColin Finck       if (__c == ',') {
346*c2c66affSColin Finck         *__group_sizes_end++ = __current_group_size;
347*c2c66affSColin Finck         __current_group_size = 0;
348*c2c66affSColin Finck       }
349*c2c66affSColin Finck       else {
350*c2c66affSColin Finck         __ok = true;
351*c2c66affSColin Finck         __v.push_back((char)__c);
352*c2c66affSColin Finck         ++__current_group_size;
353*c2c66affSColin Finck       }
354*c2c66affSColin Finck     }
355*c2c66affSColin Finck     else
356*c2c66affSColin Finck       break;
357*c2c66affSColin Finck   }
358*c2c66affSColin Finck 
359*c2c66affSColin Finck   if (__group_sizes_end != __group_sizes)
360*c2c66affSColin Finck     *__group_sizes_end++ = __current_group_size;
361*c2c66affSColin Finck   __grouping_ok = __valid_grouping(__group_sizes, __group_sizes_end, __grouping.data(), __grouping.data() + __grouping.size());
362*c2c66affSColin Finck   return __ok;
363*c2c66affSColin Finck }
364*c2c66affSColin Finck 
365*c2c66affSColin Finck 
366*c2c66affSColin Finck template <class _InputIter, class _CharT>
367*c2c66affSColin Finck bool _STLP_CALL
__read_float(__iostring & __buf,_InputIter & __in_ite,_InputIter & __end,const ctype<_CharT> & __ct,const numpunct<_CharT> & __numpunct)368*c2c66affSColin Finck __read_float(__iostring& __buf, _InputIter& __in_ite, _InputIter& __end,
369*c2c66affSColin Finck              const ctype<_CharT> &__ct, const numpunct<_CharT> &__numpunct) {
370*c2c66affSColin Finck   // Create a string, copying characters of the form
371*c2c66affSColin Finck   // [+-]? [0-9]* .? [0-9]* ([eE] [+-]? [0-9]+)?
372*c2c66affSColin Finck 
373*c2c66affSColin Finck   string __grouping = __numpunct.grouping();
374*c2c66affSColin Finck   bool __digits_before_dot /* = false */;
375*c2c66affSColin Finck   bool __digits_after_dot = false;
376*c2c66affSColin Finck   bool __ok;
377*c2c66affSColin Finck 
378*c2c66affSColin Finck   bool   __grouping_ok = true;
379*c2c66affSColin Finck 
380*c2c66affSColin Finck   _CharT __dot = __numpunct.decimal_point();
381*c2c66affSColin Finck   _CharT __sep = __numpunct.thousands_sep();
382*c2c66affSColin Finck 
383*c2c66affSColin Finck   _CharT __digits[10];
384*c2c66affSColin Finck   _CharT __xplus;
385*c2c66affSColin Finck   _CharT __xminus;
386*c2c66affSColin Finck 
387*c2c66affSColin Finck   _CharT __pow_e;
388*c2c66affSColin Finck   _CharT __pow_E;
389*c2c66affSColin Finck 
390*c2c66affSColin Finck   _Initialize_get_float(__ct, __xplus, __xminus, __pow_e, __pow_E, __digits);
391*c2c66affSColin Finck 
392*c2c66affSColin Finck   // Get an optional sign
393*c2c66affSColin Finck   __in_ite = __copy_sign(__in_ite, __end, __buf, __xplus, __xminus);
394*c2c66affSColin Finck 
395*c2c66affSColin Finck   // Get an optional string of digits.
396*c2c66affSColin Finck   if (!__grouping.empty())
397*c2c66affSColin Finck     __digits_before_dot = __copy_grouped_digits(__in_ite, __end, __buf, __digits,
398*c2c66affSColin Finck                                                 __sep, __grouping, __grouping_ok);
399*c2c66affSColin Finck   else
400*c2c66affSColin Finck     __digits_before_dot = __copy_digits(__in_ite, __end, __buf, __digits);
401*c2c66affSColin Finck 
402*c2c66affSColin Finck   // Get an optional decimal point, and an optional string of digits.
403*c2c66affSColin Finck   if (__in_ite != __end && *__in_ite == __dot) {
404*c2c66affSColin Finck     __buf.push_back('.');
405*c2c66affSColin Finck     ++__in_ite;
406*c2c66affSColin Finck     __digits_after_dot = __copy_digits(__in_ite, __end, __buf, __digits);
407*c2c66affSColin Finck   }
408*c2c66affSColin Finck 
409*c2c66affSColin Finck   // There have to be some digits, somewhere.
410*c2c66affSColin Finck   __ok = __digits_before_dot || __digits_after_dot;
411*c2c66affSColin Finck 
412*c2c66affSColin Finck   // Get an optional exponent.
413*c2c66affSColin Finck   if (__ok && __in_ite != __end && (*__in_ite == __pow_e || *__in_ite == __pow_E)) {
414*c2c66affSColin Finck     __buf.push_back('e');
415*c2c66affSColin Finck     ++__in_ite;
416*c2c66affSColin Finck     __in_ite = __copy_sign(__in_ite, __end, __buf, __xplus, __xminus);
417*c2c66affSColin Finck     __ok = __copy_digits(__in_ite, __end, __buf, __digits);
418*c2c66affSColin Finck     // If we have an exponent then the sign
419*c2c66affSColin Finck     // is optional but the digits aren't.
420*c2c66affSColin Finck   }
421*c2c66affSColin Finck 
422*c2c66affSColin Finck   return __ok;
423*c2c66affSColin Finck }
424*c2c66affSColin Finck 
425*c2c66affSColin Finck template <class _InputIter, class _Float, class _CharT>
426*c2c66affSColin Finck _InputIter _STLP_CALL
__do_get_float(_InputIter & __in_ite,_InputIter & __end,ios_base & __str,ios_base::iostate & __err,_Float & __val,_CharT *)427*c2c66affSColin Finck __do_get_float(_InputIter& __in_ite, _InputIter& __end, ios_base& __str,
428*c2c66affSColin Finck                ios_base::iostate& __err, _Float& __val, _CharT* /*__pc*/) {
429*c2c66affSColin Finck   locale __loc = __str.getloc();
430*c2c66affSColin Finck   const ctype<_CharT> &__ctype = use_facet<ctype<_CharT> >(__loc);
431*c2c66affSColin Finck   const numpunct<_CharT> &__numpunct = use_facet<numpunct<_CharT> >(__loc);
432*c2c66affSColin Finck 
433*c2c66affSColin Finck   __iostring __buf ;
434*c2c66affSColin Finck   bool __ok = __read_float(__buf, __in_ite, __end, __ctype, __numpunct);
435*c2c66affSColin Finck   if (__ok) {
436*c2c66affSColin Finck     __string_to_float(__buf, __val);
437*c2c66affSColin Finck     __err = ios_base::goodbit;
438*c2c66affSColin Finck   }
439*c2c66affSColin Finck   else {
440*c2c66affSColin Finck     __err = ios_base::failbit;
441*c2c66affSColin Finck   }
442*c2c66affSColin Finck   if (__in_ite == __end)
443*c2c66affSColin Finck     __err |= ios_base::eofbit;
444*c2c66affSColin Finck   return __in_ite;
445*c2c66affSColin Finck }
446*c2c66affSColin Finck 
447*c2c66affSColin Finck template <class _InputIter, class _CharT>
448*c2c66affSColin Finck _InputIter _STLP_CALL
__do_get_alphabool(_InputIter & __in_ite,_InputIter & __end,ios_base & __str,ios_base::iostate & __err,bool & __x,_CharT *)449*c2c66affSColin Finck __do_get_alphabool(_InputIter& __in_ite, _InputIter& __end, ios_base& __str,
450*c2c66affSColin Finck                    ios_base::iostate& __err, bool& __x, _CharT* /*__pc*/) {
451*c2c66affSColin Finck   const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__str.getloc());
452*c2c66affSColin Finck   const basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> > __truename  = __np.truename();
453*c2c66affSColin Finck   const basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> > __falsename = __np.falsename();
454*c2c66affSColin Finck   bool __true_ok  = true;
455*c2c66affSColin Finck   bool __false_ok = true;
456*c2c66affSColin Finck 
457*c2c66affSColin Finck   size_t __n = 0;
458*c2c66affSColin Finck   for ( ; __in_ite != __end; ++__in_ite) {
459*c2c66affSColin Finck     _CharT __c = *__in_ite;
460*c2c66affSColin Finck     __true_ok  = __true_ok  && (__c == __truename[__n]);
461*c2c66affSColin Finck     __false_ok = __false_ok && (__c == __falsename[__n]);
462*c2c66affSColin Finck     ++__n;
463*c2c66affSColin Finck 
464*c2c66affSColin Finck     if ((!__true_ok && !__false_ok) ||
465*c2c66affSColin Finck         (__true_ok  && __n >= __truename.size()) ||
466*c2c66affSColin Finck         (__false_ok && __n >= __falsename.size())) {
467*c2c66affSColin Finck       ++__in_ite;
468*c2c66affSColin Finck       break;
469*c2c66affSColin Finck     }
470*c2c66affSColin Finck   }
471*c2c66affSColin Finck   if (__true_ok  && __n < __truename.size())  __true_ok  = false;
472*c2c66affSColin Finck   if (__false_ok && __n < __falsename.size()) __false_ok = false;
473*c2c66affSColin Finck 
474*c2c66affSColin Finck   if (__true_ok || __false_ok) {
475*c2c66affSColin Finck     __err = ios_base::goodbit;
476*c2c66affSColin Finck     __x = __true_ok;
477*c2c66affSColin Finck   }
478*c2c66affSColin Finck   else
479*c2c66affSColin Finck     __err = ios_base::failbit;
480*c2c66affSColin Finck 
481*c2c66affSColin Finck   if (__in_ite == __end)
482*c2c66affSColin Finck     __err |= ios_base::eofbit;
483*c2c66affSColin Finck 
484*c2c66affSColin Finck   return __in_ite;
485*c2c66affSColin Finck }
486*c2c66affSColin Finck 
487*c2c66affSColin Finck _STLP_MOVE_TO_STD_NAMESPACE
488*c2c66affSColin Finck 
489*c2c66affSColin Finck //
490*c2c66affSColin Finck // num_get<>, num_put<>
491*c2c66affSColin Finck //
492*c2c66affSColin Finck 
493*c2c66affSColin Finck template <class _CharT, class _InputIterator>
494*c2c66affSColin Finck locale::id num_get<_CharT, _InputIterator>::id;
495*c2c66affSColin Finck 
496*c2c66affSColin Finck #if !defined (_STLP_NO_BOOL)
497*c2c66affSColin Finck template <class _CharT, class _InputIter>
498*c2c66affSColin Finck _InputIter
do_get(_InputIter __in_ite,_InputIter __end,ios_base & __s,ios_base::iostate & __err,bool & __x)499*c2c66affSColin Finck num_get<_CharT, _InputIter>::do_get(_InputIter __in_ite, _InputIter __end,
500*c2c66affSColin Finck                                     ios_base& __s, ios_base::iostate& __err, bool& __x) const {
501*c2c66affSColin Finck   if (__s.flags() & ios_base::boolalpha) {
502*c2c66affSColin Finck     return _STLP_PRIV __do_get_alphabool(__in_ite, __end, __s, __err, __x, (_CharT*)0);
503*c2c66affSColin Finck   }
504*c2c66affSColin Finck   else {
505*c2c66affSColin Finck     long __lx;
506*c2c66affSColin Finck     _InputIter __tmp = _STLP_PRIV __do_get_integer(__in_ite, __end, __s, __err, __lx, (_CharT*)0 );
507*c2c66affSColin Finck     if (!(__err & ios_base::failbit)) {
508*c2c66affSColin Finck       if (__lx == 0)
509*c2c66affSColin Finck         __x = false;
510*c2c66affSColin Finck       else if (__lx == 1)
511*c2c66affSColin Finck         __x = true;
512*c2c66affSColin Finck       else
513*c2c66affSColin Finck         __err |= ios_base::failbit;
514*c2c66affSColin Finck     }
515*c2c66affSColin Finck     return __tmp;
516*c2c66affSColin Finck   }
517*c2c66affSColin Finck }
518*c2c66affSColin Finck #endif
519*c2c66affSColin Finck 
520*c2c66affSColin Finck #if defined (_STLP_FIX_LIBRARY_ISSUES)
521*c2c66affSColin Finck template <class _CharT, class _InputIter>
522*c2c66affSColin Finck _InputIter
do_get(_InputIter __in_ite,_InputIter __end,ios_base & __str,ios_base::iostate & __err,short & __val)523*c2c66affSColin Finck num_get<_CharT, _InputIter>::do_get(_InputIter __in_ite, _InputIter __end, ios_base& __str,
524*c2c66affSColin Finck                                     ios_base::iostate& __err, short& __val) const
525*c2c66affSColin Finck { return _STLP_PRIV __do_get_integer(__in_ite, __end, __str, __err, __val, (_CharT*)0 ); }
526*c2c66affSColin Finck 
527*c2c66affSColin Finck template <class _CharT, class _InputIter>
528*c2c66affSColin Finck _InputIter
do_get(_InputIter __in_ite,_InputIter __end,ios_base & __str,ios_base::iostate & __err,int & __val)529*c2c66affSColin Finck num_get<_CharT, _InputIter>::do_get(_InputIter __in_ite, _InputIter __end, ios_base& __str,
530*c2c66affSColin Finck                                     ios_base::iostate& __err, int& __val) const
531*c2c66affSColin Finck { return _STLP_PRIV __do_get_integer(__in_ite, __end, __str, __err, __val, (_CharT*)0 ); }
532*c2c66affSColin Finck 
533*c2c66affSColin Finck #endif
534*c2c66affSColin Finck 
535*c2c66affSColin Finck template <class _CharT, class _InputIter>
536*c2c66affSColin Finck _InputIter
do_get(_InputIter __in_ite,_InputIter __end,ios_base & __str,ios_base::iostate & __err,long & __val)537*c2c66affSColin Finck num_get<_CharT, _InputIter>::do_get(_InputIter __in_ite, _InputIter __end, ios_base& __str,
538*c2c66affSColin Finck                                     ios_base::iostate& __err, long& __val) const
539*c2c66affSColin Finck { return _STLP_PRIV __do_get_integer(__in_ite, __end, __str, __err, __val, (_CharT*)0 ); }
540*c2c66affSColin Finck 
541*c2c66affSColin Finck template <class _CharT, class _InputIter>
542*c2c66affSColin Finck _InputIter
do_get(_InputIter __in_ite,_InputIter __end,ios_base & __str,ios_base::iostate & __err,unsigned short & __val)543*c2c66affSColin Finck num_get<_CharT, _InputIter>::do_get(_InputIter __in_ite, _InputIter __end, ios_base& __str,
544*c2c66affSColin Finck                                     ios_base::iostate& __err,
545*c2c66affSColin Finck                                     unsigned short& __val) const
546*c2c66affSColin Finck { return _STLP_PRIV __do_get_integer(__in_ite, __end, __str, __err, __val, (_CharT*)0 ); }
547*c2c66affSColin Finck 
548*c2c66affSColin Finck template <class _CharT, class _InputIter>
549*c2c66affSColin Finck _InputIter
do_get(_InputIter __in_ite,_InputIter __end,ios_base & __str,ios_base::iostate & __err,unsigned int & __val)550*c2c66affSColin Finck num_get<_CharT, _InputIter>::do_get(_InputIter __in_ite, _InputIter __end, ios_base& __str,
551*c2c66affSColin Finck                                     ios_base::iostate& __err,
552*c2c66affSColin Finck                                     unsigned int& __val) const
553*c2c66affSColin Finck { return _STLP_PRIV __do_get_integer(__in_ite, __end, __str, __err, __val, (_CharT*)0 ); }
554*c2c66affSColin Finck 
555*c2c66affSColin Finck template <class _CharT, class _InputIter>
556*c2c66affSColin Finck _InputIter
do_get(_InputIter __in_ite,_InputIter __end,ios_base & __str,ios_base::iostate & __err,unsigned long & __val)557*c2c66affSColin Finck num_get<_CharT, _InputIter>::do_get(_InputIter __in_ite, _InputIter __end, ios_base& __str,
558*c2c66affSColin Finck                                     ios_base::iostate& __err,
559*c2c66affSColin Finck                                     unsigned long& __val) const
560*c2c66affSColin Finck { return _STLP_PRIV __do_get_integer(__in_ite, __end, __str, __err, __val, (_CharT*)0 ); }
561*c2c66affSColin Finck 
562*c2c66affSColin Finck template <class _CharT, class _InputIter>
563*c2c66affSColin Finck _InputIter
do_get(_InputIter __in_ite,_InputIter __end,ios_base & __str,ios_base::iostate & __err,float & __val)564*c2c66affSColin Finck num_get<_CharT, _InputIter>::do_get(_InputIter __in_ite, _InputIter __end, ios_base& __str,
565*c2c66affSColin Finck                                     ios_base::iostate& __err,
566*c2c66affSColin Finck                                     float& __val) const
567*c2c66affSColin Finck { return _STLP_PRIV __do_get_float(__in_ite, __end, __str, __err, __val, (_CharT*)0 ); }
568*c2c66affSColin Finck 
569*c2c66affSColin Finck template <class _CharT, class _InputIter>
570*c2c66affSColin Finck _InputIter
do_get(_InputIter __in_ite,_InputIter __end,ios_base & __str,ios_base::iostate & __err,double & __val)571*c2c66affSColin Finck num_get<_CharT, _InputIter>::do_get(_InputIter __in_ite, _InputIter __end, ios_base& __str,
572*c2c66affSColin Finck                                     ios_base::iostate& __err,
573*c2c66affSColin Finck                                     double& __val) const
574*c2c66affSColin Finck { return _STLP_PRIV __do_get_float(__in_ite, __end, __str, __err, __val, (_CharT*)0 ); }
575*c2c66affSColin Finck 
576*c2c66affSColin Finck #if !defined (_STLP_NO_LONG_DOUBLE)
577*c2c66affSColin Finck template <class _CharT, class _InputIter>
578*c2c66affSColin Finck _InputIter
do_get(_InputIter __in_ite,_InputIter __end,ios_base & __str,ios_base::iostate & __err,long double & __val)579*c2c66affSColin Finck num_get<_CharT, _InputIter>::do_get(_InputIter __in_ite, _InputIter __end, ios_base& __str,
580*c2c66affSColin Finck                                     ios_base::iostate& __err,
581*c2c66affSColin Finck                                     long double& __val) const
582*c2c66affSColin Finck { return _STLP_PRIV __do_get_float(__in_ite, __end, __str, __err, __val, (_CharT*)0 ); }
583*c2c66affSColin Finck #endif
584*c2c66affSColin Finck 
585*c2c66affSColin Finck template <class _CharT, class _InputIter>
586*c2c66affSColin Finck _InputIter
do_get(_InputIter __in_ite,_InputIter __end,ios_base & __str,ios_base::iostate & __err,void * & __p)587*c2c66affSColin Finck num_get<_CharT, _InputIter>::do_get(_InputIter __in_ite, _InputIter __end, ios_base& __str,
588*c2c66affSColin Finck                                     ios_base::iostate& __err,
589*c2c66affSColin Finck                                     void*& __p) const {
590*c2c66affSColin Finck #if defined (_STLP_LONG_LONG) && !defined (__MRC__)    //*ty 12/07/2001 - MrCpp can not cast from long long to void*
591*c2c66affSColin Finck   unsigned _STLP_LONG_LONG __val;
592*c2c66affSColin Finck #else
593*c2c66affSColin Finck   unsigned long __val;
594*c2c66affSColin Finck #endif
595*c2c66affSColin Finck   iter_type __tmp = _STLP_PRIV __do_get_integer(__in_ite, __end, __str, __err, __val, (_CharT*)0 );
596*c2c66affSColin Finck   if (!(__err & ios_base::failbit))
597*c2c66affSColin Finck     __p = __REINTERPRET_CAST(void*, __val);
598*c2c66affSColin Finck   return __tmp;
599*c2c66affSColin Finck }
600*c2c66affSColin Finck 
601*c2c66affSColin Finck #if defined (_STLP_LONG_LONG)
602*c2c66affSColin Finck template <class _CharT, class _InputIter>
603*c2c66affSColin Finck _InputIter
do_get(_InputIter __in_ite,_InputIter __end,ios_base & __str,ios_base::iostate & __err,_STLP_LONG_LONG & __val)604*c2c66affSColin Finck num_get<_CharT, _InputIter>::do_get(_InputIter __in_ite, _InputIter __end, ios_base& __str,
605*c2c66affSColin Finck                                     ios_base::iostate& __err,
606*c2c66affSColin Finck                                     _STLP_LONG_LONG& __val) const
607*c2c66affSColin Finck { return _STLP_PRIV __do_get_integer(__in_ite, __end, __str, __err, __val, (_CharT*)0 ); }
608*c2c66affSColin Finck 
609*c2c66affSColin Finck template <class _CharT, class _InputIter>
610*c2c66affSColin Finck _InputIter
do_get(_InputIter __in_ite,_InputIter __end,ios_base & __str,ios_base::iostate & __err,unsigned _STLP_LONG_LONG & __val)611*c2c66affSColin Finck num_get<_CharT, _InputIter>::do_get(_InputIter __in_ite, _InputIter __end, ios_base& __str,
612*c2c66affSColin Finck                                     ios_base::iostate& __err,
613*c2c66affSColin Finck                                     unsigned _STLP_LONG_LONG& __val) const
614*c2c66affSColin Finck { return _STLP_PRIV __do_get_integer(__in_ite, __end, __str, __err, __val, (_CharT*)0 ); }
615*c2c66affSColin Finck #endif
616*c2c66affSColin Finck 
617*c2c66affSColin Finck _STLP_END_NAMESPACE
618*c2c66affSColin Finck 
619*c2c66affSColin Finck #endif /* _STLP_NUMERIC_FACETS_C */
620*c2c66affSColin Finck 
621*c2c66affSColin Finck // Local Variables:
622*c2c66affSColin Finck // mode:C++
623*c2c66affSColin Finck // End:
624