_num_get.c

来自「stl的源码」· C语言 代码 · 共 624 行 · 第 1/2 页

C
624
字号
/* * Copyright (c) 1999 * Silicon Graphics Computer Systems, Inc. * * Copyright (c) 1999 * Boris Fomitchev * * This material is provided "as is", with absolutely no warranty expressed * or implied. Any use is at your own risk. * * Permission to use or copy this software for any purpose is hereby granted * without fee, provided the above notices are retained on all copies. * Permission to modify the code and to distribute modified code is granted, * provided the above notices are retained, and a notice that the code was * modified is included with the above copyright notice. * */#ifndef _STLP_NUM_GET_C#define _STLP_NUM_GET_C#ifndef _STLP_INTERNAL_NUM_GET_H#  include <stl/_num_get.h>#endif#ifndef _STLP_INTERNAL_LIMITS#  include <stl/_limits.h>#endif_STLP_BEGIN_NAMESPACE_STLP_MOVE_TO_PRIV_NAMESPACE_STLP_DECLSPEC unsigned char _STLP_CALL __digit_val_table(unsigned);_STLP_DECLSPEC const char* _STLP_CALL __narrow_atoms();// __do_get_integer, __do_get_float and its helper functions.inline bool _STLP_CALL __get_fdigit(char __c, const char*){ return __c >= '0' && __c <= '9'; }inline bool _STLP_CALL __get_fdigit_or_sep(char& __c, char __sep, const char *__digits) {  if (__c == __sep) {    __c = ',' ;    return true ;  }  else    return  __get_fdigit(__c, __digits);}inline int _STLP_CALL__get_digit_from_table(unsigned __index){ return (__index > 127 ? 0xFF : __digit_val_table(__index)); }template <class _InputIter, class _CharT>int__get_base_or_zero(_InputIter& __in_ite, _InputIter& __end,                   ios_base::fmtflags __flags, const ctype<_CharT>& __c_type) {  _CharT __atoms[5];  __c_type.widen(__narrow_atoms(), __narrow_atoms() + 5, __atoms);  bool __negative = false;  _CharT __c = *__in_ite;  if (__c == __atoms[1] /* __xminus_char */ ) {    __negative = true;    ++__in_ite;  }  else if (__c == __atoms[0] /* __xplus_char */ )    ++__in_ite;  int __base;  int __valid_zero = 0;  ios_base::fmtflags __basefield = __flags & ios_base::basefield;  switch (__basefield) {  case ios_base::oct:    __base = 8;    break;  case ios_base::dec:    __base = 10;    break;  case ios_base::hex:    __base = 16;    if (__in_ite != __end && *__in_ite == __atoms[2] /* __zero_char */ ) {      ++__in_ite;      if (__in_ite != __end &&          (*__in_ite == __atoms[3] /* __x_char */ || *__in_ite == __atoms[4] /* __X_char */ ))        ++__in_ite;      else        __valid_zero = 1; // That zero is valid by itself.    }    break;  default:    if (__in_ite != __end && *__in_ite == __atoms[2] /* __zero_char */ ) {      ++__in_ite;      if (__in_ite != __end &&          (*__in_ite == __atoms[3] /* __x_char */ || *__in_ite == __atoms[4] /* __X_char */ )) {        ++__in_ite;        __base = 16;      }      else        {          __base = 8;          __valid_zero = 1; // That zero is still valid by itself.        }    }    else      __base = 10;    break;  }  return (__base << 2) | ((int)__negative << 1) | __valid_zero;}template <class _InputIter, class _Integer, class _CharT>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& /*_IsSigned*/) {  bool __ovflow = false;  _Integer __result = 0;  bool __is_group = !__grouping.empty();  char __group_sizes[64];  char __current_group_size = 0;  char* __group_sizes_end = __group_sizes;  _Integer __over_base = (numeric_limits<_Integer>::min)() / __STATIC_CAST(_Integer, __base);   for ( ; __first != __last ; ++__first) {     const _CharT __c = *__first;     if (__is_group && __c == __separator) {       *__group_sizes_end++ = __current_group_size;       __current_group_size = 0;       continue;     }     int __n = __get_digit_from_table(__c);     if (__n >= __base)       break;     ++__got;     ++__current_group_size;     if (__result < __over_base)       __ovflow = true;  // don't need to keep accumulating     else {       _Integer __next = __STATIC_CAST(_Integer, __base * __result - __n);       if (__result != 0)         __ovflow = __ovflow || __next >= __result;       __result = __next;     }   }   if (__is_group && __group_sizes_end != __group_sizes) {     *__group_sizes_end++ = __current_group_size;   }   // fbp : added to not modify value if nothing was read   if (__got > 0) {       __val = __ovflow ? __is_negative ? (numeric_limits<_Integer>::min)()                                        : (numeric_limits<_Integer>::max)()                        : __is_negative ? __result                                        : __STATIC_CAST(_Integer, -__result);   }  // overflow is being treated as failure  return ((__got > 0) && !__ovflow) &&          (__is_group == 0 ||           __valid_grouping(__group_sizes, __group_sizes_end,                            __grouping.data(), __grouping.data()+ __grouping.size()));}template <class _InputIter, class _Integer, class _CharT>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& /*_IsSigned*/) {  bool __ovflow = false;  _Integer __result = 0;  bool __is_group = !__grouping.empty();  char __group_sizes[64];  char __current_group_size = 0;  char* __group_sizes_end = __group_sizes;  _Integer  __over_base = (numeric_limits<_Integer>::max)() / __STATIC_CAST(_Integer, __base);  for ( ; __first != __last ; ++__first) {    const _CharT __c = *__first;    if (__is_group && __c == __separator) {      *__group_sizes_end++ = __current_group_size;      __current_group_size = 0;      continue;    }    int __n = __get_digit_from_table(__c);    if (__n >= __base)      break;    ++__got;    ++__current_group_size;    if (__result > __over_base)      __ovflow = true;  //don't need to keep accumulating    else {      _Integer __next = __STATIC_CAST(_Integer, __base * __result + __n);      if (__result != 0)        __ovflow = __ovflow || __next <= __result;        __result = __next;      }  }  if (__is_group && __group_sizes_end != __group_sizes) {      *__group_sizes_end++ = __current_group_size;  }  // fbp : added to not modify value if nothing was read  if (__got > 0) {      __val = __ovflow ? (numeric_limits<_Integer>::max)()                       : (__is_negative ? __STATIC_CAST(_Integer, -__result)                                        : __result);  }  // overflow is being treated as failure  return ((__got > 0) && !__ovflow) &&          (__is_group == 0 ||           __valid_grouping(__group_sizes, __group_sizes_end,                            __grouping.data(), __grouping.data()+ __grouping.size()));}template <class _InputIter, class _Integer, class _CharT>bool _STLP_CALL__get_decimal_integer(_InputIter& __first, _InputIter& __last, _Integer& __val, _CharT* /*dummy*/) {  string __grp;  //Here there is no grouping so separator is not important, we just pass the default character.  return __get_integer(__first, __last, 10, __val, 0, false, _CharT() /*separator*/, __grp, __false_type());}template <class _InputIter, class _Integer, class _CharT>_InputIter _STLP_CALL__do_get_integer(_InputIter& __in_ite, _InputIter& __end, ios_base& __str,                 ios_base::iostate& __err, _Integer& __val, _CharT* /*__pc*/) {  locale __loc = __str.getloc();  const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);#if defined (__HP_aCC) && (__HP_aCC == 1)  bool _IsSigned = !((_Integer)(-1) > 0);#else  typedef typename __bool2type<numeric_limits<_Integer>::is_signed>::_Ret _IsSigned;#endif  const int __base_or_zero = __get_base_or_zero(__in_ite, __end, __str.flags(), __ctype);  int  __got = __base_or_zero & 1;  bool __result;  if (__in_ite == __end) {      // We may have already read a 0.  If so,    if (__got > 0) {       // the result is 0 even if we're at eof.      __val = 0;      __result = true;    }    else      __result = false;  }  else {    const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);    const bool __negative = (__base_or_zero & 2) != 0;    const int __base = __base_or_zero >> 2;#if defined (__HP_aCC) && (__HP_aCC == 1)    if (_IsSigned)      __result = __get_integer(__in_ite, __end, __base,  __val, __got, __negative, __np.thousands_sep(), __np.grouping(), __true_type() );    else      __result = __get_integer(__in_ite, __end, __base,  __val, __got, __negative, __np.thousands_sep(), __np.grouping(), __false_type() );#else    __result = __get_integer(__in_ite, __end, __base,  __val, __got, __negative, __np.thousands_sep(), __np.grouping(), _IsSigned());# endif  }  __err = __STATIC_CAST(ios_base::iostate, __result ? ios_base::goodbit : ios_base::failbit);  if (__in_ite == __end)    __err |= ios_base::eofbit;  return __in_ite;}// __read_float and its helper functions.template <class _InputIter, class _CharT>_InputIter  _STLP_CALL__copy_sign(_InputIter __first, _InputIter __last, __iostring& __v,            _CharT __xplus, _CharT __xminus) {  if (__first != __last) {    _CharT __c = *__first;    if (__c == __xplus)      ++__first;    else if (__c == __xminus) {      __v.push_back('-');      ++__first;    }  }  return __first;}template <class _InputIter, class _CharT>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?