|
|
// xlocnum internal header (from <locale>) #pragma once #ifndef _XLOCNUM_ #define _XLOCNUM_ #include <cerrno> #include <climits> #include <cstdio> #include <cstdlib> #include <streambuf>
#pragma pack(push,8) #pragma warning(push,3)
_STD_BEGIN
// TEMPLATE CLASS numpunct template<class _Elem> class numpunct : public locale::facet { // facet for defining numeric punctuation text public: typedef basic_string<_Elem, char_traits<_Elem>, allocator<_Elem> > string_type; typedef _Elem char_type;
static locale::id id; // unique facet id
_Elem decimal_point() const { // return decimal point return (do_decimal_point()); }
_Elem thousands_sep() const { // return thousands separator return (do_thousands_sep()); }
string grouping() const { // return grouping string return (do_grouping()); }
string_type falsename() const { // return name for false return (do_falsename()); }
string_type truename() const { // return name for true return (do_truename()); }
explicit numpunct(size_t _Refs = 0) : locale::facet(_Refs) { // construct from current locale _Init(_Locinfo()); }
numpunct(const _Locinfo& _Lobj, size_t _Refs = 0) : locale::facet(_Refs) { // construct from specified locale _Init(_Lobj); }
static size_t __cdecl _Getcat(const locale::facet **_Ppf = 0) { // return locale category mask and construct standard facet if (_Ppf != 0 && *_Ppf == 0) *_Ppf = _NEW_CRT numpunct<_Elem>; return (_X_NUMERIC); }
_PROTECTED: virtual ~numpunct() { // destroy the object _Tidy(); }
protected: void _Init(const _Locinfo& _Lobj) { // initialize from _Lobj const lconv *_Ptr = _Lobj._Getlconv();
_Grouping = 0; _Falsename = 0; _Truename = 0;
_TRY_BEGIN _Grouping = _MAKLOCSTR(char, _Ptr->grouping, _Lobj._Getcvt()); _Falsename = _MAKLOCSTR(_Elem, _Lobj._Getfalse(), _Lobj._Getcvt()); _Truename = _MAKLOCSTR(_Elem, _Lobj._Gettrue(), _Lobj._Getcvt()); _CATCH_ALL _Tidy(); _RERAISE; _CATCH_END
_Dp = _WIDEN(_Elem, _Ptr->decimal_point[0]); _Kseparator = _WIDEN(_Elem, _Ptr->thousands_sep[0]); }
virtual _Elem do_decimal_point() const { // return decimal point return (_Dp); }
virtual _Elem do_thousands_sep() const { // return thousands separator return (_Kseparator); }
virtual string do_grouping() const { // return grouping string return (string(_Grouping)); }
virtual string_type do_falsename() const { // return name for false return (string_type(_Falsename)); }
virtual string_type do_truename() const { // return name for true return (string_type(_Truename)); }
private: void _Tidy() { // free all storage _DELETE_CRT_VEC((void *)_Grouping); _DELETE_CRT_VEC((void *)_Falsename); _DELETE_CRT_VEC((void *)_Truename); }
const char *_Grouping; // grouping string, "" for "C" locale _Elem _Dp; // decimal point, '.' for "C" locale _Elem _Kseparator; // thousands separator, '\0' for "C" locale const _Elem *_Falsename; // name for false, "false" for "C" locale const _Elem *_Truename; // name for true, "true" for "C" locale };
typedef numpunct<char> _Npc; typedef numpunct<wchar_t> _Npwc;
// TEMPLATE CLASS numpunct_byname template<class _Elem> class numpunct_byname : public numpunct<_Elem> { // numpunct for named locale public: explicit numpunct_byname(const char *_Locname, size_t _Refs = 0) : numpunct<_Elem>(_Locinfo(_Locname), _Refs) { // construct for named locale }
_PROTECTED: virtual ~numpunct_byname() { // destroy the object } };
// STATIC numpunct::id OBJECT template<class _Elem> locale::id numpunct<_Elem>::id;
#define _VIRTUAL virtual
// TEMPLATE CLASS num_get template<class _Elem, class _InIt = istreambuf_iterator<_Elem, char_traits<_Elem> > > class num_get : public locale::facet { // facet for converting text to encoded numbers public: typedef numpunct<_Elem> _Mypunct; typedef basic_string<_Elem, char_traits<_Elem>, allocator<_Elem> > _Mystr;
static size_t __cdecl _Getcat(const locale::facet **_Ppf = 0) { // return locale category mask and construct standard facet if (_Ppf != 0 && *_Ppf == 0) *_Ppf = _NEW_CRT num_get<_Elem, _InIt>; return (_X_NUMERIC); }
static locale::id id; // unique facet id
_PROTECTED: virtual ~num_get() { // destroy the object }
protected: void _Init(const _Locinfo&) { // initialize from _Locinfo object (do nothing) }
public: explicit num_get(size_t _Refs = 0) : locale::facet(_Refs) { // construct from current locale _Init(_Locinfo()); }
num_get(const _Locinfo& _Lobj, size_t _Refs = 0) : locale::facet(_Refs) { // construct from specified locale _Init(_Lobj); }
typedef _Elem char_type; typedef _InIt iter_type;
_InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, _Bool& _Val) const { // get bool from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); }
_InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, unsigned short& _Val) const { // get unsigned short from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); }
_InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, unsigned int& _Val) const { // get unsigned int from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); }
_InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, long& _Val) const { // get long from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); }
_InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, unsigned long& _Val) const { // get unsigned long from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); } #ifdef _LONGLONG
_InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, _LONGLONG& _Val) const { // get long long from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); }
_InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, _ULONGLONG& _Val) const { // get unsigned long long from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); } #endif /* _LONGLONG */
_InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, float& _Val) const { // get float from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); }
_InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, double& _Val) const { // get double from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); }
_InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, long double& _Val) const { // get long double from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); }
_InIt get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, void *& _Val) const { // get void pointer from [_First, _Last) into _Val return (do_get(_First, _Last, _Iosbase, _State, _Val)); }
protected: _VIRTUAL _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, _Bool& _Val) const { // get bool from [_First, _Last) into _Val int _Ans = -1; // negative answer indicates failure
if (_Iosbase.flags() & ios_base::boolalpha) { // get false name or true name const _Mypunct& _Fac = _USE(_Iosbase.getloc(), _Mypunct); _Mystr _Str((typename _Mystr::size_type)1, (char_type)0); _Str += _Fac.falsename(); _Str += (char_type)0; _Str += _Fac.truename(); // construct "\0false\0true" _Ans = _Getloctxt(_First, _Last, (size_t)2, _Str.c_str()); } else { // get zero or nonzero integer char _Ac[_MAX_INT_DIG], *_Ep; errno = 0; const unsigned long _Ulo = ::strtoul(_Ac, &_Ep, _Getifld(_Ac, _First, _Last, _Iosbase.flags(), _Iosbase.getloc())); if (_Ep != _Ac && errno == 0 && _Ulo <= 1) _Ans = _Ulo; }
if (_First == _Last) _State |= ios_base::eofbit; if (_Ans < 0) _State |= ios_base::failbit; else _Val = _Ans != 0; // deliver value return (_First); }
_VIRTUAL _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, unsigned short& _Val) const { // get unsigned short from [_First, _Last) into _Val char _Ac[_MAX_INT_DIG], *_Ep; errno = 0; int _Base = _Getifld(_Ac, _First, _Last, _Iosbase.flags(), _Iosbase.getloc()); // gather field into _Ac char *_Ptr = _Ac[0] == '-' ? _Ac + 1 : _Ac; // point past any sign const unsigned long _Ans = ::strtoul(_Ptr, &_Ep, _Base); // convert
if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ptr || errno != 0 || USHRT_MAX < _Ans) _State |= ios_base::failbit; else _Val = (unsigned short)(_Ac[0] == '-' ? 0 -_Ans : _Ans); // deliver value return (_First); }
_VIRTUAL _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, unsigned int& _Val) const { // get unsigned int from [_First, _Last) into _Val char _Ac[_MAX_INT_DIG], *_Ep; errno = 0; int _Base = _Getifld(_Ac, _First, _Last, _Iosbase.flags(), _Iosbase.getloc()); // gather field into _Ac char *_Ptr = _Ac[0] == '-' ? _Ac + 1 : _Ac; // point past any sign const unsigned long _Ans = ::strtoul(_Ptr, &_Ep, _Base); // convert
if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ptr || errno != 0 || UINT_MAX < _Ans) _State |= ios_base::failbit; else _Val = _Ac[0] == '-' ? 0 -_Ans : _Ans; // deliver value return (_First); }
_VIRTUAL _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, long& _Val) const { // get long from [_First, _Last) into _Val char _Ac[_MAX_INT_DIG], *_Ep; errno = 0; const long _Ans = ::strtol(_Ac, &_Ep, _Getifld(_Ac, _First, _Last, _Iosbase.flags(), _Iosbase.getloc())); // gather field, convert
if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ac || errno != 0) _State |= ios_base::failbit; else _Val = _Ans; // deliver value return (_First); }
_VIRTUAL _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, unsigned long& _Val) const { // get unsigned long from [_First, _Last) into _Val char _Ac[_MAX_INT_DIG], *_Ep; errno = 0; const unsigned long _Ans = ::strtoul(_Ac, &_Ep, _Getifld(_Ac, _First, _Last, _Iosbase.flags(), _Iosbase.getloc())); // gather field, convert
if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ac || errno != 0) _State |= ios_base::failbit; else _Val = _Ans; // deliver value return (_First); } #ifdef _LONGLONG
_VIRTUAL _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, _LONGLONG& _Val) const { // get long long from [_First, _Last) into _Val char _Ac[_MAX_INT_DIG], *_Ep; errno = 0; const _LONGLONG _Ans = ::_strtoi64(_Ac, &_Ep, _Getifld(_Ac, _First, _Last, _Iosbase.flags(), _Iosbase.getloc())); // gather field, convert
if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ac || errno != 0) _State |= ios_base::failbit; else _Val = _Ans; // deliver value return (_First); }
_VIRTUAL _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, _ULONGLONG& _Val) const { // get unsigned long long from [_First, _Last) into _Val char _Ac[_MAX_INT_DIG], *_Ep; errno = 0; const _ULONGLONG _Ans = ::_strtoui64(_Ac, &_Ep, _Getifld(_Ac, _First, _Last, _Iosbase.flags(), _Iosbase.getloc())); // gather field, convert
if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ac || errno != 0) _State |= ios_base::failbit; else _Val = _Ans; // deliver value return (_First); } #endif /* _LONGLONG */
_VIRTUAL _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, float& _Val) const { // get float from [_First, _Last) into _Val char _Ac[_MAX_EXP_DIG + _MAX_SIG_DIG + 16], *_Ep; errno = 0; const float _Ans = ::_Stof(_Ac, &_Ep, _Getffld(_Ac, _First, _Last, _Iosbase.getloc())); // gather field, convert
if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ac || errno != 0) _State |= ios_base::failbit; else _Val = _Ans; // deliver value return (_First); }
_VIRTUAL _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, double& _Val) const { // get double from [_First, _Last) into _Val char _Ac[_MAX_EXP_DIG + _MAX_SIG_DIG + 16], *_Ep; errno = 0; const double _Ans = ::_Stod(_Ac, &_Ep, _Getffld(_Ac, _First, _Last, _Iosbase.getloc())); // gather field, convert
if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ac || errno != 0) _State |= ios_base::failbit; else _Val = _Ans; // deliver value return (_First); }
_VIRTUAL _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, long double& _Val) const { // get long double from [_First, _Last) into _Val char _Ac[_MAX_EXP_DIG + _MAX_SIG_DIG + 16], *_Ep; errno = 0; const long double _Ans = ::_Stold(_Ac, &_Ep, _Getffld(_Ac, _First, _Last, _Iosbase.getloc())); // gather field, convert
if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ac || errno != 0) _State |= ios_base::failbit; else _Val = _Ans; // deliver value return (_First); }
_VIRTUAL _InIt do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, void *& _Val) const { // get void pointer from [_First, _Last) into _Val char _Ac[_MAX_INT_DIG], *_Ep; errno = 0;
#ifdef _LONGLONG int _Base = _Getifld(_Ac, _First, _Last, ios_base::hex, _Iosbase.getloc()); // gather field const _ULONGLONG _Ans = (sizeof (void *) == sizeof (unsigned long)) ? (_ULONGLONG)::strtoul(_Ac, &_Ep, _Base) : ::_strtoui64(_Ac, &_Ep, _Base);
#else /* _LONGLONG */ const unsigned long _Ans = ::strtoul(_Ac, &_Ep, _Getifld(_Ac, _First, _Last, ios_base::hex, _Iosbase.getloc())); // gather field, convert #endif /* _LONGLONG */
if (_First == _Last) _State |= ios_base::eofbit; if (_Ep == _Ac || errno != 0) _State |= ios_base::failbit; else _Val = (void *)((char *)0 + _Ans); // deliver value return (_First); }
private: static int __cdecl _Getifld(char *_Ac, _InIt& _First, _InIt& _Last, ios_base::fmtflags _Basefield, const locale& _Loc) { // get integer field from [_First, _Last) into _Ac const _Elem _E0 = _WIDEN(_Elem, '0'); const _Mypunct& _Fac = _USE(_Loc, _Mypunct); const string _Grouping = _Fac.grouping(); const _Elem _Kseparator = _Fac.thousands_sep(); char *_Ptr = _Ac;
if (_First == _Last) ; // empty field else if (*_First == _WIDEN(_Elem, '+')) *_Ptr++ = '+', ++_First; // gather plus sign else if (*_First == _WIDEN(_Elem, '-')) *_Ptr++ = '-', ++_First; // gather minus sign
_Basefield &= ios_base::basefield; int _Base = _Basefield == ios_base::oct ? 8 : _Basefield == ios_base::hex ? 16 : _Basefield == ios_base::_Fmtzero ? 0 : 10;
bool _Seendigit = false; // seen a digit in input bool _Nonzero = false; // seen a nonzero digit in input
if (_First != _Last && *_First == _E0) { // leading zero, look for 0x, 0X _Seendigit = true, ++_First; if (_First != _Last && (*_First == _WIDEN(_Elem, 'x') || *_First == _WIDEN(_Elem, 'X')) && (_Base == 0 || _Base == 16)) _Base = 16, _Seendigit = false, ++_First; else if (_Base == 0) _Base = 8; }
int _Dlen = _Base == 0 || _Base == 10 ? 10 : _Base == 8 ? 8 : 16 + 6; string _Groups((size_t)1, (char)_Seendigit); size_t _Group = 0;
for (char *const _Pe = &_Ac[_MAX_INT_DIG - 1]; _First != _Last; ++_First) if (::memchr("0123456789abcdefABCDEF", *_Ptr = _NARROW(_Elem, *_First), _Dlen) != 0) { // got a digit, characterize it and add to group size if ((_Nonzero || *_Ptr != '0') && _Ptr < _Pe) ++_Ptr, _Nonzero = true; _Seendigit = true; if (_Groups[_Group] != CHAR_MAX) ++_Groups[_Group]; } else if (_Groups[_Group] == '\0' || _Kseparator == (_Elem)0 || *_First != _Kseparator) break; // not a group separator, done else { // add a new group to _Groups string _Groups.append((string::size_type)1, '\0'); ++_Group; }
if (_Group == 0) ; // no thousands separators seen else if ('\0' < _Groups[_Group]) ++_Group; // add trailing group to group count else _Seendigit = false; // trailing separator, fail
for (const char *_Pg = _Grouping.c_str(); _Seendigit && 0 < _Group; ) if (*_Pg == CHAR_MAX) break; // end of grouping constraints to check else if (0 < --_Group && *_Pg != _Groups[_Group] || 0 == _Group && *_Pg < _Groups[_Group]) _Seendigit = false; // bad group size, fail else if ('\0' < _Pg[1]) ++_Pg; // group size okay, advance to next test
if (_Seendigit && !_Nonzero) *_Ptr++ = '0'; // zero field, replace stripped zero(s) else if (!_Seendigit) _Ptr = _Ac; // roll back pointer to indicate failure *_Ptr = '\0'; return (_Base); }
static int __cdecl _Getffld(char *_Ac, _InIt& _First, _InIt &_Last, const locale& _Loc) { // get floating-point field from [_First, _Last) into _Ac const _Elem _E0 = _WIDEN(_Elem, '0'); const _Mypunct& _Fac = _USE(_Loc, _Mypunct); char *_Ptr = _Ac;
if (_First == _Last) ; // empty field else if (*_First == _WIDEN(_Elem, '+')) *_Ptr++ = '+', ++_First; // gather plus sign else if (*_First == _WIDEN(_Elem, '-')) *_Ptr++ = '-', ++_First; // gather minus sign
bool _Seendigit = false; // seen a digit in input for (; _First != _Last && *_First == _E0; _Seendigit = true, ++_First) ; // strip leading zeros if (_Seendigit) *_Ptr++ = '0'; // put one back
int _Significant = 0; // number of significant digits int _Pten = 0; // power of 10 multiplier
for (; _First != _Last && (::isdigit)(*_Ptr = _NARROW(_Elem, *_First)); _Seendigit = true, ++_First) if (_Significant < _MAX_SIG_DIG) ++_Ptr, ++_Significant; // save a significant digit else ++_Pten; // or just scale by 10
if (_First != _Last && *_First == _Fac.decimal_point()) *_Ptr++ = localeconv()->decimal_point[0], ++_First; // add .
if (_Significant == 0) { // 0000. so far for (; _First != _Last && *_First == _E0; _Seendigit = true, ++_First) --_Pten; // just count leading fraction zeros if (_Pten < 0) *_Ptr++ = '0', ++_Pten; // put one back }
for (; _First != _Last && (::isdigit)(*_Ptr = _NARROW(_Elem, *_First)); _Seendigit = true, ++_First) if (_Significant < _MAX_SIG_DIG) ++_Ptr, ++_Significant; // save a significant fraction digit
if (_Seendigit && _First != _Last && (*_First == _WIDEN(_Elem, 'e') || *_First == _WIDEN(_Elem, 'E'))) { // 'e' or 'E', collect exponent *_Ptr++ = 'e', ++_First; _Seendigit = false, _Significant = 0;
if (_First == _Last) ; // 'e' or 'E' is last element else if (*_First == _WIDEN(_Elem, '+')) *_Ptr++ = '+', ++_First; // gather plus sign else if (*_First == _WIDEN(_Elem, '-')) *_Ptr++ = '-', ++_First; // gather minus sign for (; _First != _Last && *_First == _E0; ) _Seendigit = true, ++_First; // strip leading zeros if (_Seendigit) *_Ptr++ = '0'; // put one back for (; _First != _Last && (::isdigit)(*_Ptr = _NARROW(_Elem, *_First)); _Seendigit = true, ++_First) if (_Significant < _MAX_EXP_DIG) ++_Ptr, ++_Significant; // save a significant digit }
if (!_Seendigit) _Ptr = _Ac; // roll back pointer to indicate failure *_Ptr = '\0'; return (_Pten); }; };
// STATIC num_get::id OBJECT template<class _Elem, class _InIt> locale::id num_get<_Elem, _InIt>::id;
// TEMPLATE CLASS num_put template<class _Elem, class _OutIt = ostreambuf_iterator<_Elem, char_traits<_Elem> > > class num_put : public locale::facet { // facet for converting encoded numbers to text public: typedef numpunct<_Elem> _Mypunct; typedef basic_string<_Elem, char_traits<_Elem>, allocator<_Elem> > _Mystr;
static size_t __cdecl _Getcat(const locale::facet **_Ppf = 0) { // return locale category mask and construct standard facet if (_Ppf != 0 && *_Ppf == 0) *_Ppf = _NEW_CRT num_put<_Elem, _OutIt>; return (_X_NUMERIC); }
static locale::id id; // unique facet id
_PROTECTED: virtual ~num_put() { // destroy the object }
protected: void _Init(const _Locinfo&) { // initialize from _Locinfo object (do nothing) }
public: explicit num_put(size_t _Refs = 0) : locale::facet(_Refs) { // construct from current locale _Init(_Locinfo()); }
num_put(const _Locinfo& _Lobj, size_t _Refs = 0) : locale::facet(_Refs) { // construct from specified locale _Init(_Lobj); }
typedef _Elem char_type; typedef _OutIt iter_type;
_OutIt put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, _Bool _Val) const { // put formatted bool to _Dest return (do_put(_Dest, _Iosbase, _Fill, _Val)); }
_OutIt put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, long _Val) const { // put formatted long to _Dest return (do_put(_Dest, _Iosbase, _Fill, _Val)); }
_OutIt put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, unsigned long _Val) const { // put formatted unsigned long to _Dest return (do_put(_Dest, _Iosbase, _Fill, _Val)); } #ifdef _LONGLONG
_OutIt put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, _LONGLONG _Val) const { // put formatted long long to _Dest return (do_put(_Dest, _Iosbase, _Fill, _Val)); }
_OutIt put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, _ULONGLONG _Val) const { // put formatted unsigned long long to _Dest return (do_put(_Dest, _Iosbase, _Fill, _Val)); } #endif /* _LONGLONG */
_OutIt put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, double _Val) const { // put formatted double to _Dest return (do_put(_Dest, _Iosbase, _Fill, _Val)); }
_OutIt put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, long double _Val) const { // put formatted long double to _Dest return (do_put(_Dest, _Iosbase, _Fill, _Val)); }
_OutIt put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, const void *_Val) const { // put formatted void pointer to _Dest return (do_put(_Dest, _Iosbase, _Fill, _Val)); }
protected: virtual _OutIt do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, _Bool _Val) const { // put formatted bool to _Dest if (!(_Iosbase.flags() & ios_base::boolalpha)) return (do_put(_Dest, _Iosbase, _Fill, (long)_Val)); else { // put "false" or "true" const _Mypunct& _Fac = _USE(_Iosbase.getloc(), _Mypunct); const _Mystr _Str(_Val ? _Fac.truename() : _Fac.falsename());
size_t _Fillcount = _Iosbase.width() <= 0 || (size_t)_Iosbase.width() <= _Str.size() ? 0 : (size_t)_Iosbase.width() - _Str.size();
if ((_Iosbase.flags() & ios_base::adjustfield) != ios_base::left) { // put leading fill _Dest = _Rep(_Dest, _Fill, _Fillcount); _Fillcount = 0; } _Dest = _Put(_Dest, _Str.c_str(), _Str.size()); // put field _Iosbase.width(0); return (_Rep(_Dest, _Fill, _Fillcount)); // put trailing fill } }
virtual _OutIt do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, long _Val) const { // put formatted long to _Dest char _Buf[2 * _MAX_INT_DIG], _Fmt[6]; return (_Iput(_Dest, _Iosbase, _Fill, _Buf, ::sprintf(_Buf, _Ifmt(_Fmt, "ld", _Iosbase.flags()), _Val))); }
virtual _OutIt do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, unsigned long _Val) const { // put formatted unsigned long to _Dest char _Buf[2 * _MAX_INT_DIG], _Fmt[6]; return (_Iput(_Dest, _Iosbase, _Fill, _Buf, ::sprintf(_Buf, _Ifmt(_Fmt, "lu", _Iosbase.flags()), _Val))); } #ifdef _LONGLONG
virtual _OutIt do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, _LONGLONG _Val) const { // put formatted long long to _Dest char _Buf[2 * _MAX_INT_DIG], _Fmt[8]; return (_Iput(_Dest, _Iosbase, _Fill, _Buf, ::sprintf(_Buf, _Ifmt(_Fmt, "Ld", _Iosbase.flags()), _Val))); }
virtual _OutIt do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, _ULONGLONG _Val) const { // put formatted unsigned long long to _Dest char _Buf[2 * _MAX_INT_DIG], _Fmt[8]; return (_Iput(_Dest, _Iosbase, _Fill, _Buf, ::sprintf(_Buf, _Ifmt(_Fmt, "Lu", _Iosbase.flags()), _Val))); } #endif /* _LONGLONG */
virtual _OutIt do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, double _Val) const { // put formatted double to _Dest char _Buf[_MAX_EXP_DIG + _MAX_SIG_DIG + 64], _Fmt[8]; streamsize _Precision = _Iosbase.precision() <= 0 && !(_Iosbase.flags() & ios_base::fixed) ? 6 : _Iosbase.precision(); // desired precision int _Significance = _MAX_SIG_DIG < _Precision ? _MAX_SIG_DIG : (int)_Precision; // actual precision for sprintf _Precision -= _Significance; size_t _Beforepoint = 0; // zeros to add before decimal point size_t _Afterpoint = 0; // zeros to add after decimal point
if ((_Iosbase.flags() & ios_base::floatfield) == ios_base::fixed) { // scale silly fixed-point value bool _Signed = _Val < 0; if (_Signed) _Val = -_Val;
for (; 1e35 <= _Val && _Beforepoint < 5000; _Beforepoint += 10) _Val /= 1e10; // drop 10 zeros before decimal point
if (0 < _Val) for (; 10 <= _Precision && _Val <= 1e-35 && _Afterpoint < 5000; _Afterpoint += 10) { // drop 10 zeros after decimal point _Val *= 1e10; _Precision -= 10; }
if (_Signed) _Val = -_Val; }
return (_Fput(_Dest, _Iosbase, _Fill, _Buf, _Beforepoint, _Afterpoint, _Precision, ::sprintf(_Buf, _Ffmt(_Fmt, 0, _Iosbase.flags()), _Significance, _Val))); // convert and put }
virtual _OutIt do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, long double _Val) const { // put formatted long double to _Dest char _Buf[_MAX_EXP_DIG + _MAX_SIG_DIG + 64], _Fmt[8]; streamsize _Precision = _Iosbase.precision() <= 0 && !(_Iosbase.flags() & ios_base::fixed) ? 6 : _Iosbase.precision(); // desired precision int _Significance = _MAX_SIG_DIG < _Precision ? _MAX_SIG_DIG : (int)_Precision; // actual precision for sprintf _Precision -= _Significance; size_t _Beforepoint = 0; // zeros to add before decimal point size_t _Afterpoint = 0; // zeros to add after decimal point
if ((_Iosbase.flags() & ios_base::floatfield) == ios_base::fixed) { // scale silly fixed-point value bool _Signed = _Val < 0; if (_Signed) _Val = -_Val;
for (; 1e35 <= _Val && _Beforepoint < 5000; _Beforepoint += 10) _Val /= 1e10; // drop 10 zeros before decimal point
if (0 < _Val) for (; 10 <= _Precision && _Val <= 1e-35 && _Afterpoint < 5000; _Afterpoint += 10) { // drop 10 zeros after decimal point _Val *= 1e10; _Precision -= 10; }
if (_Signed) _Val = -_Val; }
return (_Fput(_Dest, _Iosbase, _Fill, _Buf, _Beforepoint, _Afterpoint, _Precision, ::sprintf(_Buf, _Ffmt(_Fmt, 'L', _Iosbase.flags()), _Significance, _Val))); // convert and put }
virtual _OutIt do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, const void *_Val) const { // put formatted void pointer to _Dest char _Buf[2 * _MAX_INT_DIG]; return (_Iput(_Dest, _Iosbase, _Fill, _Buf, ::sprintf(_Buf, "%p", _Val))); }
static char *__cdecl _Ffmt(char *_Fmt, char _Spec, ios_base::fmtflags _Flags) { // generate sprintf format for floating-point char *_Ptr = _Fmt; *_Ptr++ = '%';
if (_Flags & ios_base::showpos) *_Ptr++ = '+'; if (_Flags & ios_base::showpoint) *_Ptr++ = '#'; *_Ptr++ = '.'; *_Ptr++ = '*'; // for precision argument if (_Spec != '\0') *_Ptr++ = _Spec; // 'L' qualifier for long double only
ios_base::fmtflags _Ffl = _Flags & ios_base::floatfield; *_Ptr++ = _Ffl == ios_base::fixed ? 'f' : _Ffl == ios_base::scientific ? 'e' : 'g'; // specifier *_Ptr = '\0'; return (_Fmt); }
static _OutIt __cdecl _Fput(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, const char *_Buf, size_t _Beforepoint, size_t _Afterpoint, size_t _Trailing, size_t _Count) { // put formatted floating-point to _Dest _Elem _E0 = _WIDEN(_Elem, '0'); size_t _Fillcount = _Beforepoint + _Afterpoint + _Trailing + _Count; _Fillcount = _Iosbase.width() <= 0 || (size_t)_Iosbase.width() <= _Fillcount ? 0 : (size_t)_Iosbase.width() - _Fillcount;
ios_base::fmtflags _Adjustfield = _Iosbase.flags() & ios_base::adjustfield; if (_Adjustfield != ios_base::left && _Adjustfield != ios_base::internal) { // put leading fill _Dest = _Rep(_Dest, _Fill, _Fillcount); _Fillcount = 0; } else if (_Adjustfield == ios_base::internal) { // put internal fill if (0 < _Count && (*_Buf == '+' || *_Buf == '-')) { // but first put sign _Dest = _Putc(_Dest, _Buf, 1); ++_Buf, --_Count; } _Dest = _Rep(_Dest, _Fill, _Fillcount); _Fillcount = 0; }
const char *_Ptr = (const char *)::memchr(_Buf, localeconv()->decimal_point[0], _Count); // find decimal point if (_Ptr != 0) { // has decimal point, put pieces and zero fills const _Mypunct& _Fac = _USE(_Iosbase.getloc(), _Mypunct); size_t _Fracoffset = _Ptr - _Buf + 1; _Dest = _Putc(_Dest, _Buf, _Fracoffset - 1); _Dest = _Rep(_Dest, _E0, _Beforepoint); _Dest = _Rep(_Dest, _Fac.decimal_point(), 1); _Dest = _Rep(_Dest, _E0, _Afterpoint); _Buf += _Fracoffset, _Count -= _Fracoffset; }
if ((_Ptr = (const char *)::memchr(_Buf, 'e', _Count)) != 0) { // has exponent field, put it out size_t _Expoffset = _Ptr - _Buf + 1; _Dest = _Putc(_Dest, _Buf, _Expoffset - 1); _Dest = _Rep(_Dest, _E0, _Trailing), _Trailing = 0; _Dest = _Putc(_Dest, _Iosbase.flags() & ios_base::uppercase ? "E" : "e", 1); _Buf += _Expoffset, _Count -= _Expoffset; }
_Dest = _Putc(_Dest, _Buf, _Count); // put leftover field _Dest = _Rep(_Dest, _E0, _Trailing); // put trailing zeros _Iosbase.width(0); return (_Rep(_Dest, _Fill, _Fillcount)); // put trailing fill }
static char *__cdecl _Ifmt(char *_Fmt, const char *_Spec, ios_base::fmtflags _Flags) { // generate sprintf format for integer char *_Ptr = _Fmt; *_Ptr++ = '%';
if (_Flags & ios_base::showpos) *_Ptr++ = '+'; if (_Flags & ios_base::showbase) *_Ptr++ = '#'; if (_Spec[0] != 'L') *_Ptr++ = _Spec[0]; // qualifier else { /* change L to I64 */ *_Ptr++ = 'I'; *_Ptr++ = '6'; *_Ptr++ = '4'; }
ios_base::fmtflags _Basefield = _Flags & ios_base::basefield; *_Ptr++ = _Basefield == ios_base::oct ? 'o' : _Basefield != ios_base::hex ? _Spec[1] // 'd' or 'u' : _Flags & ios_base::uppercase ? 'X' : 'x'; *_Ptr = '\0'; return (_Fmt); }
static _OutIt __cdecl _Iput(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, char *_Buf, size_t _Count) { // put formatted integer to _Dest const size_t _Prefix = *_Buf == '+' || *_Buf == '-' ? 1 : *_Buf == '0' && (_Buf[1] == 'x' || _Buf[1] == 'X') ? 2 : 0; const _Mypunct& _Fac = _USE(_Iosbase.getloc(), _Mypunct); const string _Grouping = _Fac.grouping(); const _Elem _Kseparator = _Fac.thousands_sep(); bool _Grouped = '\0' < *_Grouping.c_str();
if (_Grouped) { // grouping specified, add thousands separators const char *_Pg = _Grouping.c_str(); size_t _Off = _Count; for (_Grouped = false; *_Pg != CHAR_MAX && '\0' < *_Pg && (size_t)*_Pg < _Off - _Prefix; _Grouped = true) { // add a comma to mark thousands separator _Off -= *_Pg; ::memmove(&_Buf[_Off + 1], &_Buf[_Off], _Count + 1 - _Off); _Buf[_Off] = ',', ++_Count; if ('\0' < _Pg[1]) ++_Pg; // not last group, advance } }
size_t _Fillcount = _Iosbase.width() <= 0 || (size_t)_Iosbase.width() <= _Count ? 0 : (size_t)_Iosbase.width() - _Count;
ios_base::fmtflags _Adjustfield = _Iosbase.flags() & ios_base::adjustfield; if (_Adjustfield != ios_base::left && _Adjustfield != ios_base::internal) { // put leading fill _Dest = _Rep(_Dest, _Fill, _Fillcount); _Fillcount = 0; } else if (_Adjustfield == ios_base::internal) { // put internal fill _Dest = _Putc(_Dest, _Buf, _Prefix); // but first put prefix _Buf += _Prefix, _Count -= _Prefix; _Dest = _Rep(_Dest, _Fill, _Fillcount), _Fillcount = 0; }
if (!_Grouped) _Dest = _Putc(_Dest, _Buf, _Count); // put field else for (; ; ++_Buf, --_Count) { // put field with thousands separators for commas size_t _Groupsize = strcspn(_Buf, ","); _Dest = _Putc(_Dest, _Buf, _Groupsize); _Buf += _Groupsize, _Count -= _Groupsize; if (_Count == 0) break; if (_Kseparator != (_Elem)0) _Dest = _Rep(_Dest, _Kseparator, 1); }
_Iosbase.width(0); return (_Rep(_Dest, _Fill, _Fillcount)); // put trailing fill }
static _OutIt __cdecl _Put(_OutIt _Dest, const _Elem *_Ptr, size_t _Count) { // put [_Ptr, _Ptr + _Count) to _Dest for (; 0 < _Count; --_Count, ++_Dest, ++_Ptr) *_Dest = *_Ptr; return (_Dest); }
static _OutIt __cdecl _Putc(_OutIt _Dest, const char *_Ptr, size_t _Count) { // put char sequence [_Ptr, _Ptr + _Count) to _Dest for (; 0 < _Count; --_Count, ++_Dest, ++_Ptr) *_Dest = _WIDEN(_Elem, *_Ptr); return (_Dest); }
static _OutIt __cdecl _Rep(_OutIt _Dest, _Elem _Ch, size_t _Count) { // put _Count * _Ch to _Dest for (; 0 < _Count; --_Count, ++_Dest) *_Dest = _Ch; return (_Dest); } };
// STATIC num_put::id OBJECT template<class _Elem, class _OutIt> locale::id num_put<_Elem, _OutIt>::id;
#ifdef _DLL_CPPLIB template class _CRTIMP2 numpunct<char>; template class _CRTIMP2 numpunct<wchar_t>; template class _CRTIMP2 num_get<char, istreambuf_iterator<char, char_traits<char> > >; template class _CRTIMP2 num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >; template class _CRTIMP2 num_put<char, ostreambuf_iterator<char, char_traits<char> > >; template class _CRTIMP2 num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >; #endif // _DLL_CPPLIB _STD_END #pragma warning(pop) #pragma pack(pop)
#endif /* _XLOCNUM_ */
/* * Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V3.10:0009 */
|