3 * Silicon Graphics Computer Systems, Inc.
8 * This material is provided "as is", with absolutely no warranty expressed
9 * or implied. Any use is at your own risk.
11 * Permission to use or copy this software for any purpose is hereby granted
12 * without fee, provided the above notices are retained on all copies.
13 * Permission to modify the code and to distribute modified code is granted,
14 * provided the above notices are retained, and a notice that the code was
15 * modified is included with the above copyright notice.
18 #ifndef _STLP_NUM_GET_C
19 #define _STLP_NUM_GET_C
21 #ifndef _STLP_INTERNAL_NUM_GET_H
22 # include <stl/_num_get.h>
25 #ifndef _STLP_INTERNAL_LIMITS
26 # include <stl/_limits.h>
31 _STLP_MOVE_TO_PRIV_NAMESPACE
33 _STLP_DECLSPEC
unsigned char _STLP_CALL
__digit_val_table(unsigned);
34 _STLP_DECLSPEC
const char* _STLP_CALL
__narrow_atoms();
36 // __do_get_integer, __do_get_float and its helper functions.
38 inline bool _STLP_CALL
__get_fdigit(char __c
, const char*)
39 { return __c
>= '0' && __c
<= '9'; }
41 inline bool _STLP_CALL
__get_fdigit_or_sep(char& __c
, char __sep
, const char *__digits
) {
47 return __get_fdigit(__c
, __digits
);
51 __get_digit_from_table(unsigned __index
)
52 { return (__index
> 127 ? 0xFF : __digit_val_table(__index
)); }
54 template <class _InputIter
, class _CharT
>
56 __get_base_or_zero(_InputIter
& __in_ite
, _InputIter
& __end
,
57 ios_base::fmtflags __flags
, const ctype
<_CharT
>& __c_type
) {
59 __c_type
.widen(__narrow_atoms(), __narrow_atoms() + 5, __atoms
);
61 bool __negative
= false;
62 _CharT __c
= *__in_ite
;
64 if (__c
== __atoms
[1] /* __xminus_char */ ) {
68 else if (__c
== __atoms
[0] /* __xplus_char */ )
74 ios_base::fmtflags __basefield
= __flags
& ios_base::basefield
;
76 switch (__basefield
) {
85 if (__in_ite
!= __end
&& *__in_ite
== __atoms
[2] /* __zero_char */ ) {
87 if (__in_ite
!= __end
&&
88 (*__in_ite
== __atoms
[3] /* __x_char */ || *__in_ite
== __atoms
[4] /* __X_char */ ))
91 __valid_zero
= 1; // That zero is valid by itself.
95 if (__in_ite
!= __end
&& *__in_ite
== __atoms
[2] /* __zero_char */ ) {
97 if (__in_ite
!= __end
&&
98 (*__in_ite
== __atoms
[3] /* __x_char */ || *__in_ite
== __atoms
[4] /* __X_char */ )) {
105 __valid_zero
= 1; // That zero is still valid by itself.
112 return (__base
<< 2) | ((int)__negative
<< 1) | __valid_zero
;
116 template <class _InputIter
, class _Integer
, class _CharT
>
118 __get_integer(_InputIter
& __first
, _InputIter
& __last
,
119 int __base
, _Integer
& __val
,
120 int __got
, bool __is_negative
, _CharT __separator
, const string
& __grouping
, const __true_type
& /*_IsSigned*/) {
121 bool __ovflow
= false;
122 _Integer __result
= 0;
123 bool __is_group
= !__grouping
.empty();
124 char __group_sizes
[64];
125 char __current_group_size
= 0;
126 char* __group_sizes_end
= __group_sizes
;
128 _Integer __over_base
= (numeric_limits
<_Integer
>::min
)() / __STATIC_CAST(_Integer
, __base
);
130 for ( ; __first
!= __last
; ++__first
) {
132 const _CharT __c
= *__first
;
134 if (__is_group
&& __c
== __separator
) {
135 *__group_sizes_end
++ = __current_group_size
;
136 __current_group_size
= 0;
140 int __n
= __get_digit_from_table(__c
);
146 ++__current_group_size
;
148 if (__result
< __over_base
)
149 __ovflow
= true; // don't need to keep accumulating
151 _Integer __next
= __STATIC_CAST(_Integer
, __base
* __result
- __n
);
153 __ovflow
= __ovflow
|| __next
>= __result
;
158 if (__is_group
&& __group_sizes_end
!= __group_sizes
) {
159 *__group_sizes_end
++ = __current_group_size
;
162 // fbp : added to not modify value if nothing was read
164 __val
= __ovflow
? __is_negative
? (numeric_limits
<_Integer
>::min
)()
165 : (numeric_limits
<_Integer
>::max
)()
166 : __is_negative
? __result
167 : __STATIC_CAST(_Integer
, -__result
);
169 // overflow is being treated as failure
170 return ((__got
> 0) && !__ovflow
) &&
172 __valid_grouping(__group_sizes
, __group_sizes_end
,
173 __grouping
.data(), __grouping
.data()+ __grouping
.size()));
176 template <class _InputIter
, class _Integer
, class _CharT
>
178 __get_integer(_InputIter
& __first
, _InputIter
& __last
,
179 int __base
, _Integer
& __val
,
180 int __got
, bool __is_negative
, _CharT __separator
, const string
& __grouping
, const __false_type
& /*_IsSigned*/) {
181 bool __ovflow
= false;
182 _Integer __result
= 0;
183 bool __is_group
= !__grouping
.empty();
184 char __group_sizes
[64];
185 char __current_group_size
= 0;
186 char* __group_sizes_end
= __group_sizes
;
188 _Integer __over_base
= (numeric_limits
<_Integer
>::max
)() / __STATIC_CAST(_Integer
, __base
);
190 for ( ; __first
!= __last
; ++__first
) {
192 const _CharT __c
= *__first
;
194 if (__is_group
&& __c
== __separator
) {
195 *__group_sizes_end
++ = __current_group_size
;
196 __current_group_size
= 0;
200 int __n
= __get_digit_from_table(__c
);
206 ++__current_group_size
;
208 if (__result
> __over_base
)
209 __ovflow
= true; //don't need to keep accumulating
211 _Integer __next
= __STATIC_CAST(_Integer
, __base
* __result
+ __n
);
213 __ovflow
= __ovflow
|| __next
<= __result
;
218 if (__is_group
&& __group_sizes_end
!= __group_sizes
) {
219 *__group_sizes_end
++ = __current_group_size
;
222 // fbp : added to not modify value if nothing was read
224 __val
= __ovflow
? (numeric_limits
<_Integer
>::max
)()
225 : (__is_negative
? __STATIC_CAST(_Integer
, -__result
)
229 // overflow is being treated as failure
230 return ((__got
> 0) && !__ovflow
) &&
232 __valid_grouping(__group_sizes
, __group_sizes_end
,
233 __grouping
.data(), __grouping
.data()+ __grouping
.size()));
237 template <class _InputIter
, class _Integer
, class _CharT
>
239 __get_decimal_integer(_InputIter
& __first
, _InputIter
& __last
, _Integer
& __val
, _CharT
* /*dummy*/) {
241 //Here there is no grouping so separator is not important, we just pass the default character.
242 return __get_integer(__first
, __last
, 10, __val
, 0, false, _CharT() /*separator*/, __grp
, __false_type());
245 template <class _InputIter
, class _Integer
, class _CharT
>
246 _InputIter _STLP_CALL
247 __do_get_integer(_InputIter
& __in_ite
, _InputIter
& __end
, ios_base
& __str
,
248 ios_base::iostate
& __err
, _Integer
& __val
, _CharT
* /*__pc*/) {
249 locale __loc
= __str
.getloc();
250 const ctype
<_CharT
>& __ctype
= use_facet
<ctype
<_CharT
> >(__loc
);
252 #if defined (__HP_aCC) && (__HP_aCC == 1)
253 bool _IsSigned
= !((_Integer
)(-1) > 0);
255 typedef typename __bool2type
<numeric_limits
<_Integer
>::is_signed
>::_Ret _IsSigned
;
258 const int __base_or_zero
= __get_base_or_zero(__in_ite
, __end
, __str
.flags(), __ctype
);
259 int __got
= __base_or_zero
& 1;
263 if (__in_ite
== __end
) { // We may have already read a 0. If so,
265 if (__got
> 0) { // the result is 0 even if we're at eof.
273 const numpunct
<_CharT
>& __np
= use_facet
<numpunct
<_CharT
> >(__loc
);
274 const bool __negative
= (__base_or_zero
& 2) != 0;
275 const int __base
= __base_or_zero
>> 2;
277 #if defined (__HP_aCC) && (__HP_aCC == 1)
279 __result
= __get_integer(__in_ite
, __end
, __base
, __val
, __got
, __negative
, __np
.thousands_sep(), __np
.grouping(), __true_type() );
281 __result
= __get_integer(__in_ite
, __end
, __base
, __val
, __got
, __negative
, __np
.thousands_sep(), __np
.grouping(), __false_type() );
283 __result
= __get_integer(__in_ite
, __end
, __base
, __val
, __got
, __negative
, __np
.thousands_sep(), __np
.grouping(), _IsSigned());
287 __err
= __STATIC_CAST(ios_base::iostate
, __result
? ios_base::goodbit
: ios_base::failbit
);
289 if (__in_ite
== __end
)
290 __err
|= ios_base::eofbit
;
294 // __read_float and its helper functions.
295 template <class _InputIter
, class _CharT
>
296 _InputIter _STLP_CALL
297 __copy_sign(_InputIter __first
, _InputIter __last
, __iostring
& __v
,
298 _CharT __xplus
, _CharT __xminus
) {
299 if (__first
!= __last
) {
300 _CharT __c
= *__first
;
303 else if (__c
== __xminus
) {
312 template <class _InputIter
, class _CharT
>
314 __copy_digits(_InputIter
& __first
, _InputIter __last
,
315 __iostring
& __v
, const _CharT
* __digits
) {
318 for ( ; __first
!= __last
; ++__first
) {
319 _CharT __c
= *__first
;
320 if (__get_fdigit(__c
, __digits
)) {
321 __v
.push_back((char)__c
);
330 template <class _InputIter
, class _CharT
>
332 __copy_grouped_digits(_InputIter
& __first
, _InputIter __last
,
333 __iostring
& __v
, const _CharT
* __digits
,
334 _CharT __sep
, const string
& __grouping
,
335 bool& __grouping_ok
) {
337 char __group_sizes
[64];
338 char*__group_sizes_end
= __group_sizes
;
339 char __current_group_size
= 0;
341 for ( ; __first
!= __last
; ++__first
) {
342 _CharT __c
= *__first
;
343 bool __tmp
= __get_fdigit_or_sep(__c
, __sep
, __digits
);
346 *__group_sizes_end
++ = __current_group_size
;
347 __current_group_size
= 0;
351 __v
.push_back((char)__c
);
352 ++__current_group_size
;
359 if (__group_sizes_end
!= __group_sizes
)
360 *__group_sizes_end
++ = __current_group_size
;
361 __grouping_ok
= __valid_grouping(__group_sizes
, __group_sizes_end
, __grouping
.data(), __grouping
.data() + __grouping
.size());
366 template <class _InputIter
, class _CharT
>
368 __read_float(__iostring
& __buf
, _InputIter
& __in_ite
, _InputIter
& __end
,
369 const ctype
<_CharT
> &__ct
, const numpunct
<_CharT
> &__numpunct
) {
370 // Create a string, copying characters of the form
371 // [+-]? [0-9]* .? [0-9]* ([eE] [+-]? [0-9]+)?
373 string __grouping
= __numpunct
.grouping();
374 bool __digits_before_dot
/* = false */;
375 bool __digits_after_dot
= false;
378 bool __grouping_ok
= true;
380 _CharT __dot
= __numpunct
.decimal_point();
381 _CharT __sep
= __numpunct
.thousands_sep();
390 _Initialize_get_float(__ct
, __xplus
, __xminus
, __pow_e
, __pow_E
, __digits
);
392 // Get an optional sign
393 __in_ite
= __copy_sign(__in_ite
, __end
, __buf
, __xplus
, __xminus
);
395 // Get an optional string of digits.
396 if (!__grouping
.empty())
397 __digits_before_dot
= __copy_grouped_digits(__in_ite
, __end
, __buf
, __digits
,
398 __sep
, __grouping
, __grouping_ok
);
400 __digits_before_dot
= __copy_digits(__in_ite
, __end
, __buf
, __digits
);
402 // Get an optional decimal point, and an optional string of digits.
403 if (__in_ite
!= __end
&& *__in_ite
== __dot
) {
404 __buf
.push_back('.');
406 __digits_after_dot
= __copy_digits(__in_ite
, __end
, __buf
, __digits
);
409 // There have to be some digits, somewhere.
410 __ok
= __digits_before_dot
|| __digits_after_dot
;
412 // Get an optional exponent.
413 if (__ok
&& __in_ite
!= __end
&& (*__in_ite
== __pow_e
|| *__in_ite
== __pow_E
)) {
414 __buf
.push_back('e');
416 __in_ite
= __copy_sign(__in_ite
, __end
, __buf
, __xplus
, __xminus
);
417 __ok
= __copy_digits(__in_ite
, __end
, __buf
, __digits
);
418 // If we have an exponent then the sign
419 // is optional but the digits aren't.
425 template <class _InputIter
, class _Float
, class _CharT
>
426 _InputIter _STLP_CALL
427 __do_get_float(_InputIter
& __in_ite
, _InputIter
& __end
, ios_base
& __str
,
428 ios_base::iostate
& __err
, _Float
& __val
, _CharT
* /*__pc*/) {
429 locale __loc
= __str
.getloc();
430 const ctype
<_CharT
> &__ctype
= use_facet
<ctype
<_CharT
> >(__loc
);
431 const numpunct
<_CharT
> &__numpunct
= use_facet
<numpunct
<_CharT
> >(__loc
);
434 bool __ok
= __read_float(__buf
, __in_ite
, __end
, __ctype
, __numpunct
);
436 __string_to_float(__buf
, __val
);
437 __err
= ios_base::goodbit
;
440 __err
= ios_base::failbit
;
442 if (__in_ite
== __end
)
443 __err
|= ios_base::eofbit
;
447 template <class _InputIter
, class _CharT
>
448 _InputIter _STLP_CALL
449 __do_get_alphabool(_InputIter
& __in_ite
, _InputIter
& __end
, ios_base
& __str
,
450 ios_base::iostate
& __err
, bool& __x
, _CharT
* /*__pc*/) {
451 const numpunct
<_CharT
>& __np
= use_facet
<numpunct
<_CharT
> >(__str
.getloc());
452 const basic_string
<_CharT
, char_traits
<_CharT
>, allocator
<_CharT
> > __truename
= __np
.truename();
453 const basic_string
<_CharT
, char_traits
<_CharT
>, allocator
<_CharT
> > __falsename
= __np
.falsename();
454 bool __true_ok
= true;
455 bool __false_ok
= true;
458 for ( ; __in_ite
!= __end
; ++__in_ite
) {
459 _CharT __c
= *__in_ite
;
460 __true_ok
= __true_ok
&& (__c
== __truename
[__n
]);
461 __false_ok
= __false_ok
&& (__c
== __falsename
[__n
]);
464 if ((!__true_ok
&& !__false_ok
) ||
465 (__true_ok
&& __n
>= __truename
.size()) ||
466 (__false_ok
&& __n
>= __falsename
.size())) {
471 if (__true_ok
&& __n
< __truename
.size()) __true_ok
= false;
472 if (__false_ok
&& __n
< __falsename
.size()) __false_ok
= false;
474 if (__true_ok
|| __false_ok
) {
475 __err
= ios_base::goodbit
;
479 __err
= ios_base::failbit
;
481 if (__in_ite
== __end
)
482 __err
|= ios_base::eofbit
;
487 _STLP_MOVE_TO_STD_NAMESPACE
490 // num_get<>, num_put<>
493 template <class _CharT
, class _InputIterator
>
494 locale::id num_get
<_CharT
, _InputIterator
>::id
;
496 #if !defined (_STLP_NO_BOOL)
497 template <class _CharT
, class _InputIter
>
499 num_get
<_CharT
, _InputIter
>::do_get(_InputIter __in_ite
, _InputIter __end
,
500 ios_base
& __s
, ios_base::iostate
& __err
, bool& __x
) const {
501 if (__s
.flags() & ios_base::boolalpha
) {
502 return _STLP_PRIV
__do_get_alphabool(__in_ite
, __end
, __s
, __err
, __x
, (_CharT
*)0);
506 _InputIter __tmp
= _STLP_PRIV
__do_get_integer(__in_ite
, __end
, __s
, __err
, __lx
, (_CharT
*)0 );
507 if (!(__err
& ios_base::failbit
)) {
513 __err
|= ios_base::failbit
;
520 #if defined (_STLP_FIX_LIBRARY_ISSUES)
521 template <class _CharT
, class _InputIter
>
523 num_get
<_CharT
, _InputIter
>::do_get(_InputIter __in_ite
, _InputIter __end
, ios_base
& __str
,
524 ios_base::iostate
& __err
, short& __val
) const
525 { return _STLP_PRIV
__do_get_integer(__in_ite
, __end
, __str
, __err
, __val
, (_CharT
*)0 ); }
527 template <class _CharT
, class _InputIter
>
529 num_get
<_CharT
, _InputIter
>::do_get(_InputIter __in_ite
, _InputIter __end
, ios_base
& __str
,
530 ios_base::iostate
& __err
, int& __val
) const
531 { return _STLP_PRIV
__do_get_integer(__in_ite
, __end
, __str
, __err
, __val
, (_CharT
*)0 ); }
535 template <class _CharT
, class _InputIter
>
537 num_get
<_CharT
, _InputIter
>::do_get(_InputIter __in_ite
, _InputIter __end
, ios_base
& __str
,
538 ios_base::iostate
& __err
, long& __val
) const
539 { return _STLP_PRIV
__do_get_integer(__in_ite
, __end
, __str
, __err
, __val
, (_CharT
*)0 ); }
541 template <class _CharT
, class _InputIter
>
543 num_get
<_CharT
, _InputIter
>::do_get(_InputIter __in_ite
, _InputIter __end
, ios_base
& __str
,
544 ios_base::iostate
& __err
,
545 unsigned short& __val
) const
546 { return _STLP_PRIV
__do_get_integer(__in_ite
, __end
, __str
, __err
, __val
, (_CharT
*)0 ); }
548 template <class _CharT
, class _InputIter
>
550 num_get
<_CharT
, _InputIter
>::do_get(_InputIter __in_ite
, _InputIter __end
, ios_base
& __str
,
551 ios_base::iostate
& __err
,
552 unsigned int& __val
) const
553 { return _STLP_PRIV
__do_get_integer(__in_ite
, __end
, __str
, __err
, __val
, (_CharT
*)0 ); }
555 template <class _CharT
, class _InputIter
>
557 num_get
<_CharT
, _InputIter
>::do_get(_InputIter __in_ite
, _InputIter __end
, ios_base
& __str
,
558 ios_base::iostate
& __err
,
559 unsigned long& __val
) const
560 { return _STLP_PRIV
__do_get_integer(__in_ite
, __end
, __str
, __err
, __val
, (_CharT
*)0 ); }
562 template <class _CharT
, class _InputIter
>
564 num_get
<_CharT
, _InputIter
>::do_get(_InputIter __in_ite
, _InputIter __end
, ios_base
& __str
,
565 ios_base::iostate
& __err
,
567 { return _STLP_PRIV
__do_get_float(__in_ite
, __end
, __str
, __err
, __val
, (_CharT
*)0 ); }
569 template <class _CharT
, class _InputIter
>
571 num_get
<_CharT
, _InputIter
>::do_get(_InputIter __in_ite
, _InputIter __end
, ios_base
& __str
,
572 ios_base::iostate
& __err
,
574 { return _STLP_PRIV
__do_get_float(__in_ite
, __end
, __str
, __err
, __val
, (_CharT
*)0 ); }
576 #if !defined (_STLP_NO_LONG_DOUBLE)
577 template <class _CharT
, class _InputIter
>
579 num_get
<_CharT
, _InputIter
>::do_get(_InputIter __in_ite
, _InputIter __end
, ios_base
& __str
,
580 ios_base::iostate
& __err
,
581 long double& __val
) const
582 { return _STLP_PRIV
__do_get_float(__in_ite
, __end
, __str
, __err
, __val
, (_CharT
*)0 ); }
585 template <class _CharT
, class _InputIter
>
587 num_get
<_CharT
, _InputIter
>::do_get(_InputIter __in_ite
, _InputIter __end
, ios_base
& __str
,
588 ios_base::iostate
& __err
,
590 #if defined (_STLP_LONG_LONG) && !defined (__MRC__) //*ty 12/07/2001 - MrCpp can not cast from long long to void*
591 unsigned _STLP_LONG_LONG __val
;
595 iter_type __tmp
= _STLP_PRIV
__do_get_integer(__in_ite
, __end
, __str
, __err
, __val
, (_CharT
*)0 );
596 if (!(__err
& ios_base::failbit
))
597 __p
= __REINTERPRET_CAST(void*, __val
);
601 #if defined (_STLP_LONG_LONG)
602 template <class _CharT
, class _InputIter
>
604 num_get
<_CharT
, _InputIter
>::do_get(_InputIter __in_ite
, _InputIter __end
, ios_base
& __str
,
605 ios_base::iostate
& __err
,
606 _STLP_LONG_LONG
& __val
) const
607 { return _STLP_PRIV
__do_get_integer(__in_ite
, __end
, __str
, __err
, __val
, (_CharT
*)0 ); }
609 template <class _CharT
, class _InputIter
>
611 num_get
<_CharT
, _InputIter
>::do_get(_InputIter __in_ite
, _InputIter __end
, ios_base
& __str
,
612 ios_base::iostate
& __err
,
613 unsigned _STLP_LONG_LONG
& __val
) const
614 { return _STLP_PRIV
__do_get_integer(__in_ite
, __end
, __str
, __err
, __val
, (_CharT
*)0 ); }
619 #endif /* _STLP_NUMERIC_FACETS_C */