From ce3039af7dc478d4ac6d0fdeda3d1c3e0f97c943 Mon Sep 17 00:00:00 2001 From: Jerry Quinn Date: Tue, 11 Feb 2003 21:55:49 +0000 Subject: [PATCH] locale_facets.h (__num_base): Add _S_atoms_out. 2003-02-11 Jerry Quinn Benjamin Kosnik * include/bits/locale_facets.h (__num_base): Add _S_atoms_out. Add indexes into this array. (__num_base::_S_atoms): To _S_atoms_in. (num_put::_M_insert): Rename to _M_pad. (num_put::_M_convert_int): Adjust remove __mod, __modl arguments. (num_put::_M_widen_int): Rename to _M_group_int. (num_put::_M_widen_float): Rename to _M_group_float. * include/bits/locale_facets.tcc (__int_to_char): New inline function and adapter functions. (num_put::_M_group_int): Streamline. (num_put::_M_group_float): Streamline. (num_put::_M_convert_int): Remove unused parameter names. Choose large enough buffer for text. Use __int_to_char instead of __convert_from_v. Formatted text is now at the end of the buffer. (num_put::_M_convert_float): Preliminary fixups. * src/locale-inst.cc (__convert_from_v): Add ifdef. (__int_to_char): Same. (__int_to_char): New. (__int_to_char): New. (__int_to_char): New. (__int_to_char): New. Co-Authored-By: Benjamin Kosnik From-SVN: r62731 --- libstdc++-v3/ChangeLog | 25 + libstdc++-v3/include/bits/locale_facets.h | 52 +- libstdc++-v3/include/bits/locale_facets.tcc | 509 ++++++++++++-------- libstdc++-v3/src/locale-inst.cc | 58 ++- libstdc++-v3/src/locale.cc | 3 +- 5 files changed, 426 insertions(+), 221 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 721b0f267b6..b85048d4391 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,28 @@ +2003-02-11 Jerry Quinn + Benjamin Kosnik + + * include/bits/locale_facets.h (__num_base): Add _S_atoms_out. + Add indexes into this array. + (__num_base::_S_atoms): To _S_atoms_in. + (num_put::_M_insert): Rename to _M_pad. + (num_put::_M_convert_int): Adjust remove __mod, __modl arguments. + (num_put::_M_widen_int): Rename to _M_group_int. + (num_put::_M_widen_float): Rename to _M_group_float. + * include/bits/locale_facets.tcc (__int_to_char): New inline + function and adapter functions. + (num_put::_M_group_int): Streamline. + (num_put::_M_group_float): Streamline. + (num_put::_M_convert_int): Remove unused parameter names. Choose + large enough buffer for text. Use __int_to_char instead of + __convert_from_v. Formatted text is now at the end of the buffer. + (num_put::_M_convert_float): Preliminary fixups. + * src/locale-inst.cc (__convert_from_v): Add ifdef. + (__int_to_char): Same. + (__int_to_char): New. + (__int_to_char): New. + (__int_to_char): New. + (__int_to_char): New. + 2003-02-11 Scott Snyder PR libstdc++/9659 diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h index 59f9d5bb530..1feb960c2cf 100644 --- a/libstdc++-v3/include/bits/locale_facets.h +++ b/libstdc++-v3/include/bits/locale_facets.h @@ -527,14 +527,37 @@ namespace std // 22.2.1.5 Template class codecvt #include - // 22.2.2 The numeric category. class __num_base { + public: + // NB: Code depends on the order of _M_atoms_out elements. + // Below are the indices into _M_atoms_out. + enum + { + _S_minus, + _S_plus, + _S_x, + _S_X, + _S_digits, + _S_digits_end = _S_digits + 16, + _S_udigits = _S_digits_end, + _S_udigits_end = _S_udigits + 16, + _S_e = _S_digits + 14, // For scientific notation, 'e' + _S_E = _S_udigits + 14 // For scientific notation, 'E' + }; + + // A list of valid numeric literals for output. + // This array contains the chars after having been passed through + // the current locale's ctype<_CharT>.widen(). + // For the standard "C" locale, this is + // "-+xX0123456789abcdef0123456789ABCDEF". + static const char* _S_atoms_out; + protected: // String literal of acceptable (narrow) input, for num_get. // "0123456789eEabcdfABCDF" - static const char _S_atoms[]; + static const char* _S_atoms_in; enum { @@ -827,7 +850,6 @@ namespace std // Types: typedef _CharT char_type; typedef _OutIter iter_type; - static locale::id id; explicit @@ -877,22 +899,24 @@ namespace std _M_convert_float(iter_type, ios_base& __io, char_type __fill, char __mod, _ValueT __v) const; + void + _M_group_float(const string& __grouping, char_type __sep, + const char_type* __p, char_type* __new, char_type* __cs, + int& __len) const; + template iter_type _M_convert_int(iter_type, ios_base& __io, char_type __fill, - char __mod, char __modl, _ValueT __v) const; + _ValueT __v) const; - iter_type - _M_widen_float(iter_type, ios_base& __io, char_type __fill, char* __cs, - int __len) const; + void + _M_group_int(const string& __grouping, char_type __sep, + ios_base& __io, char_type* __new, char_type* __cs, + int& __len) const; - iter_type - _M_widen_int(iter_type, ios_base& __io, char_type __fill, char* __cs, - int __len) const; - - iter_type - _M_insert(iter_type, ios_base& __io, char_type __fill, - const char_type* __ws, int __len) const; + void + _M_pad(char_type __fill, streamsize __w, ios_base& __io, + char_type* __new, const char_type* __cs, int& __len) const; virtual ~num_put() { }; diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index a30404c0341..c8eaa2e5b15 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -113,7 +113,7 @@ namespace std } // Next, strip leading zeros. - const char_type __zero = __ctype.widen(_S_atoms[_M_zero]); + const char_type __zero = __ctype.widen(_S_atoms_in[_M_zero]); bool __found_zero = false; while (__traits_type::eq(__c, __zero) && __beg != __end) { @@ -122,14 +122,14 @@ namespace std } if (__found_zero) { - __xtrc += _S_atoms[_M_zero]; + __xtrc += _S_atoms_in[_M_zero]; ++__pos; } // Only need acceptable digits for floating point numbers. const size_t __len = _M_E - _M_zero + 1; char_type __watoms[__len]; - __ctype.widen(_S_atoms, _S_atoms + __len, __watoms); + __ctype.widen(_S_atoms_in, _S_atoms_in + __len, __watoms); bool __found_dec = false; bool __found_sci = false; const char_type __dec = __np.decimal_point(); @@ -150,7 +150,7 @@ namespace std { // Try first for acceptable digit; record it if found. ++__pos; - __xtrc += _S_atoms[__p - __watoms]; + __xtrc += _S_atoms_in[__p - __watoms]; ++__sep_pos; __c = *(++__beg); } @@ -261,7 +261,7 @@ namespace std } // Next, strip leading zeros and check required digits for base formats. - const char_type __zero = __ctype.widen(_S_atoms[_M_zero]); + const char_type __zero = __ctype.widen(_S_atoms_in[_M_zero]); const char_type __x = __ctype.widen('x'); const char_type __X = __ctype.widen('X'); if (__base == 10) @@ -274,7 +274,7 @@ namespace std } if (__found_zero) { - __xtrc += _S_atoms[_M_zero]; + __xtrc += _S_atoms_in[_M_zero]; ++__pos; if (__basefield == 0) { @@ -296,7 +296,7 @@ namespace std { if (__traits_type::eq(__c, __zero) && __beg != __end) { - __xtrc += _S_atoms[_M_zero]; + __xtrc += _S_atoms_in[_M_zero]; ++__pos; __c = *(++__beg); if ((__traits_type::eq(__c, __x) || __traits_type::eq(__c, __X)) @@ -319,7 +319,7 @@ namespace std // Extract. char_type __watoms[_M_size]; - __ctype.widen(_S_atoms, _S_atoms + __len, __watoms); + __ctype.widen(_S_atoms_in, _S_atoms_in + __len, __watoms); string __found_grouping; const string __grouping = __np.grouping(); bool __check_grouping = __grouping.size(); @@ -333,7 +333,7 @@ namespace std if (__p && !__traits_type::eq(__c, char_type())) { // Try first for acceptable digit; record it if found. - __xtrc += _S_atoms[__p - __watoms]; + __xtrc += _S_atoms_in[__p - __watoms]; ++__pos; ++__sep_pos; __c = *(++__beg); @@ -606,14 +606,256 @@ namespace std return __beg; } - // The following code uses snprintf (or sprintf(), when _GLIBCPP_USE_C99 - // is not defined) to convert floating point values for insertion into a - // stream. An optimization would be to replace them with code that works - // directly on a wide buffer and then use __pad to do the padding. - // It would be good to replace them anyway to gain back the efficiency - // that C++ provides by knowing up front the type of the values to insert. - // Also, sprintf is dangerous since may lead to accidental buffer overruns. - // This implementation follows the C++ standard fairly directly as + // For use by integer and floating-point types after they have been + // converted into a char_type string. + template + void + num_put<_CharT, _OutIter>:: + _M_pad(_CharT __fill, streamsize __w, ios_base& __io, + _CharT* __new, const _CharT* __cs, int& __len) const + { + // [22.2.2.2.2] Stage 3. + // If necessary, pad. + __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new, __cs, + __w, __len, true); + __len = static_cast(__w); + } + + // Forwarding functions to peel signed from unsigned integer types. + template + inline int + __int_to_char(_CharT* __out, const int __size, long __v, + const _CharT* __lit, ios_base::fmtflags __flags) + { + unsigned long __ul = static_cast(__v); + bool __neg = false; + if (__v < 0) + { + __ul = -__ul; + __neg = true; + } + return __int_to_char(__out, __size, __ul, __lit, __flags, __neg); + } + + template + inline int + __int_to_char(_CharT* __out, const int __size, unsigned long __v, + const _CharT* __lit, ios_base::fmtflags __flags) + { return __int_to_char(__out, __size, __v, __lit, __flags, false); } + +#ifdef _GLIBCPP_USE_LONG_LONG + template + inline int + __int_to_char(_CharT* __out, const int __size, long long __v, + const _CharT* __lit, ios_base::fmtflags __flags) + { + unsigned long long __ull = static_cast(__v); + bool __neg = false; + if (__v < 0) + { + __ull = -__ull; + __neg = true; + } + return __int_to_char(__out, __size, __ull, __lit, __flags, __neg); + } + + template + inline int + __int_to_char(_CharT* __out, const int __size, unsigned long long __v, + const _CharT* __lit, ios_base::fmtflags __flags) + { return __int_to_char(__out, __size, __v, __lit, __flags, false); } +#endif + + template + int + __int_to_char(_CharT* __out, const int __size, _ValueT __v, + const _CharT* __lit, ios_base::fmtflags __flags, bool __neg) + { + // Don't write base if already 0. + const bool __showbase = (__flags & ios_base::showbase) && __v; + const ios_base::fmtflags __basefield = __flags & ios_base::basefield; + _CharT* __buf = __out + __size - 1; + _CharT* __bufend = __out + __size; + + if (__builtin_expect(__basefield == ios_base::oct, false)) + { + // Octal. + do + { + *__buf-- = __lit[(__v & 0x7) + __num_base::_S_digits]; + __v >>= 3; + } + while (__v != 0); + if (__showbase) + *__buf-- = __lit[__num_base::_S_digits]; + } + else if (__builtin_expect(__basefield == ios_base::hex, false)) + { + // Hex. + const bool __uppercase = __flags & ios_base::uppercase; + int __case_offset = __uppercase + ? __num_base::_S_udigits : __num_base::_S_digits; + do + { + *__buf-- = __lit[(__v & 0xf) + __case_offset]; + __v >>= 4; + } + while (__v != 0); + if (__showbase) + { + // 'x' or 'X' + *__buf-- = __lit[__num_base::_S_x + __uppercase]; + // '0' + *__buf-- = __lit[__num_base::_S_digits]; + } + } + else + { + // Decimal. + do + { + *__buf-- = __lit[(__v % 10) + __num_base::_S_digits]; + __v /= 10; + } + while (__v != 0); + if (__neg) + *__buf-- = __lit[__num_base::_S_minus]; + else if (__flags & ios_base::showpos) + *__buf-- = __lit[__num_base::_S_plus]; + } + int __ret = __bufend - __buf - 1; + return __ret; + } + + template + void + num_put<_CharT, _OutIter>:: + _M_group_int(const string& __grouping, _CharT __sep, ios_base& __io, + _CharT* __new, _CharT* __cs, int& __len) const + { + // By itself __add_grouping cannot deal correctly with __ws when + // ios::showbase is set and ios_base::oct || ios_base::hex. + // Therefore we take care "by hand" of the initial 0, 0x or 0X. + // However, remember that the latter do not occur if the number + // printed is '0' (__len == 1). + streamsize __off = 0; + const ios_base::fmtflags __basefield = __io.flags() + & ios_base::basefield; + if ((__io.flags() & ios_base::showbase) && __len > 1) + if (__basefield == ios_base::oct) + { + __off = 1; + *__new = *__cs; + } + else if (__basefield == ios_base::hex) + { + __off = 2; + *__new = *__cs; + *(__new + 1) = *(__cs + 1); + } + _CharT* __p; + __p = __add_grouping(__new + __off, __sep, + __grouping.c_str(), + __grouping.c_str() + __grouping.size(), + __cs + __off, __cs + __len); + __len = __p - __new; + } + + template + template + _OutIter + num_put<_CharT, _OutIter>:: + _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, + _ValueT __v) const + { + // Buildup list of digits given the current ctype. + _CharT __lit[_S_udigits_end]; + const locale __loc = __io.getloc(); + if (__builtin_expect(has_facet< ctype<_CharT> >(__loc), true)) + { + const ctype<_CharT>& __ct = use_facet< ctype<_CharT> >(__loc); + __ct.widen(_S_atoms_out, _S_atoms_out + _S_udigits_end, __lit); + } + + // Long enough to hold hex, dec, and octal representations. + int __ilen = 4 * sizeof(_ValueT); + _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __ilen)); + + // [22.2.2.2.2] Stage 1, numeric conversion to character. + // Result is returned right-justified in the buffer. + int __len; + __len = __int_to_char(&__cs[0], __ilen, __v, __lit, __io.flags()); + __cs = __cs + __ilen - __len; + + // Add grouping, if necessary. + _CharT* __cs2; + const numpunct<_CharT>& __np = use_facet >(__loc); + const string __grouping = __np.grouping(); + if (__grouping.size()) + { + // Grouping can add (almost) as many separators as the + // number of digits, but no more. + __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len * 2)); + _M_group_int(__grouping, __np.thousands_sep(), __io, + __cs2, __cs, __len); + __cs = __cs2; + } + + // Pad. + _CharT* __cs3; + streamsize __w = __io.width(); + if (__w > static_cast(__len)) + { + __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); + _M_pad(__fill, __w, __io, __cs3, __cs, __len); + __cs = __cs3; + } + __io.width(0); + + // [22.2.2.2.2] Stage 4. + // Write resulting, fully-formatted string to output iterator. + return __write(__s, __cs, __len); + } + + template + void + num_put<_CharT, _OutIter>:: + _M_group_float(const string& __grouping, _CharT __sep, const _CharT* __p, + _CharT* __new, _CharT* __cs, int& __len) const + { +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + //282. What types does numpunct grouping refer to? + // Add grouping, if necessary. + _CharT* __p2; + int __declen = __p ? __p - __cs : __len; + __p2 = __add_grouping(__new, __sep, + __grouping.c_str(), + __grouping.c_str() + __grouping.size(), + __cs, __cs + __declen); + + // Tack on decimal part. + int __newlen = __p2 - __new; + if (__p) + { + char_traits<_CharT>::copy(__p2, __p, __len - __declen); + __newlen += __len - __declen; + } + __len = __newlen; +#endif + } + + // The following code uses snprintf (or sprintf(), when + // _GLIBCPP_USE_C99 is not defined) to convert floating point values + // for insertion into a stream. An optimization would be to replace + // them with code that works directly on a wide buffer and then use + // __pad to do the padding. It would be good to replace them anyway + // to gain back the efficiency that C++ provides by knowing up front + // the type of the values to insert. Also, sprintf is dangerous + // since may lead to accidental buffer overruns. This + // implementation follows the C++ standard fairly directly as // outlined in 22.2.2.2 [lib.locale.num.put] template template @@ -622,30 +864,30 @@ namespace std _M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod, _ValueT __v) const { - // Note: digits10 is rounded down: we need to add 1 to ensure - // we get the full available precision. - // Then, in general, one more 1 needs to be added since, when the - // %{g,G} conversion specifiers are chosen inside _S_format_float, the - // precision field is "the maximum number of significant digits", *not* - // the "number of digits to appear after the decimal point", as happens - // for %{e,E,f,F} (C99, 7.19.6.1,4). + // Note: digits10 is rounded down: add 1 to ensure the maximum + // available precision. Then, in general, one more 1 needs to + // be added since, when the %{g,G} conversion specifiers are + // chosen inside _S_format_float, the precision field is "the + // maximum number of significant digits", *not* the "number of + // digits to appear after the decimal point", as happens for + // %{e,E,f,F} (C99, 7.19.6.1,4). const int __max_digits = numeric_limits<_ValueT>::digits10 + 2; - streamsize __prec = __io.precision(); + // Use default precision if out of range. + streamsize __prec = __io.precision(); if (__prec > static_cast(__max_digits)) __prec = static_cast(__max_digits); else if (__prec < static_cast(0)) - // Default precision. __prec = static_cast(6); - // Long enough for the max format spec. - char __fbuf[16]; - // [22.2.2.2.2] Stage 1, numeric conversion to character. int __len; + // Long enough for the max format spec. + char __fbuf[16]; + #ifdef _GLIBCPP_USE_C99 - // First try a buffer perhaps big enough (for sure sufficient for - // non-ios_base::fixed outputs) + // First try a buffer perhaps big enough (for sure sufficient + // for non-ios_base::fixed outputs) int __cs_size = __max_digits * 3; char* __cs = static_cast(__builtin_alloca(__cs_size)); @@ -665,6 +907,7 @@ namespace std // Consider the possibility of long ios_base::fixed outputs const bool __fixed = __io.flags() & ios_base::fixed; const int __max_exp = numeric_limits<_ValueT>::max_exponent10; + // ios_base::fixed outputs may need up to __max_exp+1 chars // for the integer part + up to __max_digits chars for the // fractional part + 3 chars for sign, decimal point, '\0'. On @@ -677,181 +920,53 @@ namespace std _S_format_float(__io, __fbuf, __mod); __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale, __prec); #endif - return _M_widen_float(__s, __io, __fill, __cs, __len); - } - template - template - _OutIter - num_put<_CharT, _OutIter>:: - _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, char __mod, - char __modl, _ValueT __v) const - { - // [22.2.2.2.2] Stage 1, numeric conversion to character. - - // Long enough for the max format spec. - char __fbuf[16]; - _S_format_int(__io, __fbuf, __mod, __modl); -#ifdef _GLIBCPP_USE_C99 - // First try a buffer perhaps big enough. - int __cs_size = 64; - char* __cs = static_cast(__builtin_alloca(__cs_size)); - int __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, - _S_c_locale); - // If the buffer was not large enough, try again with the correct size. - if (__len >= __cs_size) - { - __cs_size = __len + 1; - __cs = static_cast(__builtin_alloca(__cs_size)); - __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, - _S_c_locale); - } -#else - // Leave room for "+/-," "0x," and commas. This size is - // arbitrary, but should be largely sufficient. - char __cs[128]; - int __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale); -#endif - return _M_widen_int(__s, __io, __fill, __cs, __len); - } - - template - _OutIter - num_put<_CharT, _OutIter>:: - _M_widen_float(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs, - int __len) const - { - typedef char_traits<_CharT> __traits_type; // [22.2.2.2.2] Stage 2, convert to char_type, using correct // numpunct.decimal_point() values for '.' and adding grouping. const locale __loc = __io.getloc(); const ctype<_CharT>& __ctype = use_facet >(__loc); + const numpunct<_CharT>& __np = use_facet >(__loc); + _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len)); - // Grouping can add (almost) as many separators as the number of - // digits, but no more. - _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __len * 2)); __ctype.widen(__cs, __cs + __len, __ws); // Replace decimal point. + const _CharT __cdec = __ctype.widen('.'); + const _CharT __dec = __np.decimal_point(); const _CharT* __p; - const numpunct<_CharT>& __np = use_facet >(__loc); - if (__p = __traits_type::find(__ws, __len, __ctype.widen('.'))) - __ws[__p - __ws] = __np.decimal_point(); + if (__p = char_traits<_CharT>::find(__ws, __len, __cdec)) + __ws[__p - __ws] = __dec; -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -//282. What types does numpunct grouping refer to? // Add grouping, if necessary. + _CharT* __ws2; const string __grouping = __np.grouping(); if (__grouping.size()) { - _CharT* __p2; - int __declen = __p ? __p - __ws : __len; - __p2 = __add_grouping(__ws2, __np.thousands_sep(), - __grouping.c_str(), - __grouping.c_str() + __grouping.size(), - __ws, __ws + __declen); - int __newlen = __p2 - __ws2; - - // Tack on decimal part. - if (__p) - { - __traits_type::copy(__p2, __p, __len - __declen); - __newlen += __len - __declen; - } - - // Switch strings, establish correct new length. - __ws = __ws2; - __len = __newlen; + // Grouping can add (almost) as many separators as the + // number of digits, but no more. + __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len * 2)); + _M_group_float(__grouping, __np.thousands_sep(), __p, + __ws2, __ws, __len); + __ws = __ws2; } -#endif - return _M_insert(__s, __io, __fill, __ws, __len); - } - template - _OutIter - num_put<_CharT, _OutIter>:: - _M_widen_int(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs, - int __len) const - { - // [22.2.2.2.2] Stage 2, convert to char_type, using correct - // numpunct.decimal_point() values for '.' and adding grouping. - const locale __loc = __io.getloc(); - const ctype<_CharT>& __ctype = use_facet >(__loc); - _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __len)); - // Grouping can add (almost) as many separators as the number of - // digits, but no more. - _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __len * 2)); - __ctype.widen(__cs, __cs + __len, __ws); - - // Add grouping, if necessary. - const numpunct<_CharT>& __np = use_facet >(__loc); - const string __grouping = __np.grouping(); - if (__grouping.size()) - { - // By itself __add_grouping cannot deal correctly with __ws when - // ios::showbase is set and ios_base::oct || ios_base::hex. - // Therefore we take care "by hand" of the initial 0, 0x or 0X. - // However, remember that the latter do not occur if the number - // printed is '0' (__len == 1). - streamsize __off = 0; - const ios_base::fmtflags __basefield = __io.flags() - & ios_base::basefield; - if ((__io.flags() & ios_base::showbase) && __len > 1) - if (__basefield == ios_base::oct) - { - __off = 1; - *__ws2 = *__ws; - } - else if (__basefield == ios_base::hex) - { - __off = 2; - *__ws2 = *__ws; - *(__ws2 + 1) = *(__ws + 1); - } - _CharT* __p; - __p = __add_grouping(__ws2 + __off, __np.thousands_sep(), - __grouping.c_str(), - __grouping.c_str() + __grouping.size(), - __ws + __off, __ws + __len); - __len = __p - __ws2; - // Switch strings. - __ws = __ws2; - } - return _M_insert(__s, __io, __fill, __ws, __len); - } - - // For use by integer and floating-point types after they have been - // converted into a char_type string. - template - _OutIter - num_put<_CharT, _OutIter>:: - _M_insert(_OutIter __s, ios_base& __io, _CharT __fill, const _CharT* __ws, - int __len) const - { - typedef char_traits<_CharT> __traits_type; - // [22.2.2.2.2] Stage 3. - // If necessary, pad. + // Pad. + _CharT* __ws3; streamsize __w = __io.width(); - _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __w)); if (__w > static_cast(__len)) { - __pad<_CharT, __traits_type>::_S_pad(__io, __fill, __ws2, __ws, - __w, __len, true); - __len = static_cast(__w); - // Switch strings. - __ws = __ws2; + __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w)); + _M_pad(__fill, __w, __io, __ws3, __ws, __len); + __ws = __ws3; } __io.width(0); - + // [22.2.2.2.2] Stage 4. // Write resulting, fully-formatted string to output iterator. return __write(__s, __ws, __len); - } + } template _OutIter @@ -862,19 +977,32 @@ namespace std if ((__flags & ios_base::boolalpha) == 0) { unsigned long __uv = __v; - __s = _M_convert_int(__s, __io, __fill, 'u', char(), __uv); + __s = _M_convert_int(__s, __io, __fill, __uv); } else { - typedef basic_string<_CharT> __string_type; locale __loc = __io.getloc(); const numpunct<_CharT>& __np = use_facet >(__loc); + typedef basic_string<_CharT> __string_type; __string_type __name; if (__v) __name = __np.truename(); else __name = __np.falsename(); - __s = _M_insert(__s, __io, __fill, __name.c_str(), __name.size()); + + const _CharT* __cs = __name.c_str(); + int __len = __name.size(); + _CharT* __cs3; + streamsize __w = __io.width(); + if (__w > static_cast(__len)) + { + __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); + _M_pad(__fill, __w, __io, __cs3, __cs, __len); + __cs = __cs3; + } + __io.width(0); + __s = __write(__s, __cs, __len); } return __s; } @@ -883,28 +1011,28 @@ namespace std _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const - { return _M_convert_int(__s, __io, __fill, 'd', char(), __v); } + { return _M_convert_int(__s, __io, __fill, __v); } template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, unsigned long __v) const - { return _M_convert_int(__s, __io, __fill, 'u', char(), __v); } + { return _M_convert_int(__s, __io, __fill, __v); } #ifdef _GLIBCPP_USE_LONG_LONG template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const - { return _M_convert_int(__s, __b, __fill, 'd', 'l', __v); } + { return _M_convert_int(__s, __b, __fill, __v); } template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, unsigned long long __v) const - { return _M_convert_int(__s, __io, __fill, 'u', 'l', __v); } + { return _M_convert_int(__s, __io, __fill, __v); } #endif template @@ -932,7 +1060,7 @@ namespace std __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase)); try { - __s = _M_convert_int(__s, __io, __fill, 'u', char(), + __s = _M_convert_int(__s, __io, __fill, reinterpret_cast(__v)); __io.flags(__flags); } @@ -1622,7 +1750,7 @@ namespace std if (__c == __names[__i1][0]) __matches[__nmatches++] = __i1; - while(__nmatches > 1) + while (__nmatches > 1) { // Find smallest matching string. size_t __minlen = 10; @@ -1847,8 +1975,7 @@ namespace std } else __format = __c; - __s = this->do_put(__s, __io, char_type(), __tm, __format, - __mod); + __s = this->do_put(__s, __io, _CharT(), __tm, __format, __mod); } else { diff --git a/libstdc++-v3/src/locale-inst.cc b/libstdc++-v3/src/locale-inst.cc index 8f2c8638177..954e5170998 100644 --- a/libstdc++-v3/src/locale-inst.cc +++ b/libstdc++-v3/src/locale-inst.cc @@ -1,6 +1,6 @@ // Locale support -*- C++ -*- -// Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -64,26 +64,26 @@ namespace std template ostreambuf_iterator num_put >:: - _M_convert_int(ostreambuf_iterator, ios_base&, char, char, char, + _M_convert_int(ostreambuf_iterator, ios_base&, char, long) const; template ostreambuf_iterator num_put >:: - _M_convert_int(ostreambuf_iterator, ios_base&, char, char, char, + _M_convert_int(ostreambuf_iterator, ios_base&, char, unsigned long) const; #ifdef _GLIBCPP_USE_LONG_LONG template ostreambuf_iterator num_put >:: - _M_convert_int(ostreambuf_iterator, ios_base&, char, char, char, + _M_convert_int(ostreambuf_iterator, ios_base&, char, long long) const; template ostreambuf_iterator num_put >:: - _M_convert_int(ostreambuf_iterator, ios_base&, char, char, char, + _M_convert_int(ostreambuf_iterator, ios_base&, char, unsigned long long) const; #endif @@ -97,8 +97,8 @@ namespace std ostreambuf_iterator num_put >:: _M_convert_float(ostreambuf_iterator, ios_base&, char, char, - long double) const; - + long double) const; + #ifdef _GLIBCPP_USE_WCHAR_T template class numpunct; template class numpunct_byname; @@ -108,27 +108,27 @@ namespace std template ostreambuf_iterator num_put >:: - _M_convert_int(ostreambuf_iterator, ios_base&, wchar_t, char, - char, long) const; + _M_convert_int(ostreambuf_iterator, ios_base&, wchar_t, + long) const; template ostreambuf_iterator num_put >:: - _M_convert_int(ostreambuf_iterator, ios_base&, wchar_t, char, - char, unsigned long) const; + _M_convert_int(ostreambuf_iterator, ios_base&, wchar_t, + unsigned long) const; #ifdef _GLIBCPP_USE_LONG_LONG template ostreambuf_iterator num_put >:: - _M_convert_int(ostreambuf_iterator, ios_base&, wchar_t, char, - char, long long) const; + _M_convert_int(ostreambuf_iterator, ios_base&, wchar_t, + long long) const; template ostreambuf_iterator num_put >:: - _M_convert_int(ostreambuf_iterator, ios_base&, wchar_t, char, - char, unsigned long long) const; + _M_convert_int(ostreambuf_iterator, ios_base&, wchar_t, + unsigned long long) const; #endif template @@ -451,6 +451,7 @@ namespace std __convert_from_v(char*, const int, const char*, unsigned long, const __c_locale&, int); +#ifdef _GLIBCPP_USE_LONG_LONG template int __convert_from_v(char*, const int, const char*, long long, @@ -460,4 +461,31 @@ namespace std int __convert_from_v(char*, const int, const char*, unsigned long long, const __c_locale&, int); +#endif + + template + int + __int_to_char(char*, const int, unsigned long, const char*, + ios_base::fmtflags, bool); + +#ifdef _GLIBCPP_USE_WCHAR_T + template + int + __int_to_char(wchar_t*, const int, unsigned long, const wchar_t*, + ios_base::fmtflags, bool); +#endif + +#ifdef _GLIBCPP_USE_LONG_LONG + template + int + __int_to_char(char*, const int, unsigned long long, const char*, + ios_base::fmtflags, bool); + +#ifdef _GLIBCPP_USE_WCHAR_T + template + int + __int_to_char(wchar_t*, const int, unsigned long long, const wchar_t*, + ios_base::fmtflags, bool); +#endif +#endif } // namespace std diff --git a/libstdc++-v3/src/locale.cc b/libstdc++-v3/src/locale.cc index 4e90f37eac6..e27f7690c21 100644 --- a/libstdc++-v3/src/locale.cc +++ b/libstdc++-v3/src/locale.cc @@ -503,7 +503,8 @@ namespace std const money_base::pattern money_base::_S_default_pattern = { {symbol, sign, none, value} }; - const char __num_base::_S_atoms[] = "0123456789eEabcdfABCDF"; + const char* __num_base::_S_atoms_in = "0123456789eEabcdfABCDF"; + const char* __num_base::_S_atoms_out ="-+xX0123456789abcdef0123456789ABCDEF"; // _GLIBCPP_RESOLVE_LIB_DEFECTS // According to the resolution of DR 231, about 22.2.2.2.2, p11,