This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [patch] PR 8761 and 7076, take 4
- From: Jerry Quinn <jlquinn at optonline dot net>
- To: libstdc++ at gcc dot gnu dot org
- Date: Sat, 25 Jan 2003 00:57:02 -0500
- Subject: Re: [patch] PR 8761 and 7076, take 4
Fifth time's a charm :-) No pest spray needed :-)
Updated to head of 3.3 branch. No new regressions. Fixed the comment for
__pad, used auto_ptr for the cache ptr, and added virtual functions to
ios_base. Remove parts of patch that are no longer necessary.
Any more nits?
Later,
Jerry
2003-01-23 Jerry Quinn <jlquinn@optonline.net>
* config/linker-map.gnu (_Format_cache::_Format_cache()): Export.
* include/bits/basic_ios.h (_Format_cache::_M_cache): Declare.
* include/bits/basic_ios.tcc (basic_ios::copyfmt): Rebuild format cache.
(basic_ios::imbue): Force format cache to be built.
(basic_ios::_M_init): Create and initialize format cache.
* include/bits/ios_base.h (_Format_cache_base): Declare.
(ios_base): Document reserved storage.
(ios_base::_M_format_cache): New.
(ios_base::_M_cache): Define.
(ios_base::_M_reserved1,ios_base::_M_reserved2): New.
* include/bits/locale_facets.h: (struct __pad): Comment on
* implementation.
(__verify_grouping): Same.
(__add_grouping): Same.
(_Format_cache_base,_Format_cache<_CharT>): New classes.
(_Format_cache<char>, _Format_cache<wchar_t>): New specializations.
* include/bits/locale_facets.tcc (__num_put_abs, __num_put_unsigned):
New inline functions.
(__convert_from_int): New.
(num_put::_M_convert_int): Remove unused parameter names. Choose large
enough buffer for text. Use format cache literal string. Use
__convert_from_int. Use __num_put_abs. Use
__num_put_unsigned. Formatted text is now at the end of the buffer.
(num_put::_M_widen): Remove __loc. Remove __ctype. Remove __np. Use
_Format_cache. Move __basefield to within grouping block. Get
grouping and thousands_sep info from cache.
(__num_put_streambuf_write<_CharT, _OutIter>): New function.
(__num_put_streambuf_write<_CharT>): New function specialization.
(num_put::_M_insert): Remove explicit loop over iterator. Use
__num_put_streambuf_write.
(_Format_cache<_CharT>::_Format_cache): New.
(_Format_cache<_CharT>::_M_init): New.
(_Format_cache<_CharT>::_M_populate): New.
* include/bits/streambuf_iterator.h: Include <streambuf>.
(ostreambuf_iterator): Add __num_put_streambuf_write as friend function.
* src/ios.cc: Clear _M_format_cache in constructor.
* src/locale-inst.cc (_Format_cache<char>, _Format_cache<_char_t>):
New.
(__convert_from_v<long long>, __convert_from_v<unsigned long long>):
Add ifdef.
(__convert_from_int<char,unsigned long>): New.
(__convert_from_int<char,unsigned long long>): New.
(__convert_from_int<wchar_t, unsigned long>): New.
(__convert_from_int<wchar_t, unsigned long long>): New.
* src/localenames.cc: Fix copyright years.
(_Format_cache<char>::_Format_cache,
_Format_cache<wchar_t>::_Format_cache): New.
Index: libstdc++-v3/config/linker-map.gnu
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/config/linker-map.gnu,v
retrieving revision 1.25.2.3
diff -u -r1.25.2.3 linker-map.gnu
--- libstdc++-v3/config/linker-map.gnu 23 Jan 2003 17:19:26 -0000 1.25.2.3
+++ libstdc++-v3/config/linker-map.gnu 25 Jan 2003 05:44:45 -0000
@@ -256,6 +256,12 @@
} GLIBCPP_3.2.1;
+GLIBCPP_3.2.3 {
+
+ #std::_Format_cache<char>::_Format_cache[in-charge]()
+ _ZNSt13_Format_cacheIcEC1Ev;
+
+} GLIBCPP_3.2.2;
# Symbols in the support library (libsupc++) have their own tag.
CXXABI_1.2 {
Index: libstdc++-v3/include/bits/basic_ios.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/basic_ios.h,v
retrieving revision 1.14.2.1
diff -u -r1.14.2.1 basic_ios.h
--- libstdc++-v3/include/bits/basic_ios.h 22 Jan 2003 17:39:50 -0000 1.14.2.1
+++ libstdc++-v3/include/bits/basic_ios.h 25 Jan 2003 05:44:45 -0000
@@ -1,6 +1,6 @@
// Iostreams base classes -*- C++ -*-
-// Copyright (C) 1997, 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
+// Copyright (C) 1997, 1998, 1999, 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
@@ -432,6 +432,15 @@
void
_M_cache_facets(const locale& __loc);
+
+ _Format_cache<_CharT>&
+ _M_cache()
+ { return *(_Format_cache<_CharT>*)_M_format_cache.get(); }
+
+ const _Format_cache<_CharT>&
+ _M_cache() const
+ { return *(_Format_cache<_CharT>*)_M_format_cache.get(); }
+
};
} // namespace std
Index: libstdc++-v3/include/bits/basic_ios.tcc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/basic_ios.tcc,v
retrieving revision 1.17
diff -u -r1.17 basic_ios.tcc
--- libstdc++-v3/include/bits/basic_ios.tcc 1 Nov 2002 17:30:35 -0000 1.17
+++ libstdc++-v3/include/bits/basic_ios.tcc 25 Jan 2003 05:44:45 -0000
@@ -1,6 +1,6 @@
// basic_ios locale and locale-related member functions -*- C++ -*-
-// Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
+// Copyright (C) 1999, 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
@@ -99,6 +99,9 @@
this->exceptions(__rhs.exceptions());
_M_call_callbacks(copyfmt_event);
+
+ _M_cache()._M_populate(*this);
+
return *this;
}
@@ -122,6 +125,9 @@
return __ret;
}
+ // Forward decl makes the _S_get call below happy. Better way to do this?
+ template<typename _CharT> class _Format_cache;
+
// Locales:
template<typename _CharT, typename _Traits>
locale
@@ -130,6 +136,8 @@
locale __old(this->getloc());
ios_base::imbue(__loc);
_M_cache_facets(__loc);
+ // Force the cache to be rebuilt.
+ _M_cache()._M_populate(*this);
if (this->rdbuf() != 0)
this->rdbuf()->pubimbue(__loc);
return __old;
@@ -142,6 +150,12 @@
// NB: This may be called more than once on the same object.
ios_base::_M_init();
_M_cache_facets(_M_ios_locale);
+ if (!_M_format_cache.get())
+ {
+ this->_M_format_cache = auto_ptr<_Format_cache_base>(new _Format_cache<_CharT>);
+ _Format_cache<_CharT>& __fc = (_Format_cache<_CharT>&)_M_cache();
+ __fc._M_init(*this);
+ }
_M_tie = 0;
// NB: The 27.4.4.1 Postconditions Table specifies requirements
Index: libstdc++-v3/include/bits/ios_base.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/ios_base.h,v
retrieving revision 1.21.2.2
diff -u -r1.21.2.2 ios_base.h
--- libstdc++-v3/include/bits/ios_base.h 23 Jan 2003 17:19:27 -0000 1.21.2.2
+++ libstdc++-v3/include/bits/ios_base.h 25 Jan 2003 05:44:46 -0000
@@ -146,6 +146,8 @@
enum _Ios_Seekdir { _M_ios_seekdir_end = 1L << 16 };
+ class _Format_cache_base;
+
// 27.4.2 Class ios_base
/**
* @brief The very top of the I/O class hierarchy.
@@ -416,6 +418,7 @@
_Words _M_word_zero;
// Guaranteed storage.
+ // The first 5 iword and pword slots are reserved for internal use.
static const int _S_local_word_size = 8;
_Words _M_local_word[_S_local_word_size];
@@ -429,6 +432,9 @@
// Members for locale and locale caching.
locale _M_ios_locale;
+ // Access to the format cache. Cast this to _Format_cache<_CharT>*
+ auto_ptr<_Format_cache_base> _M_format_cache;
+
void
_M_init();
@@ -635,6 +641,14 @@
return __word._M_pword;
}
+ // Access to the cache. Not safe to call until basic_ios::_M_init() has
+ // happened.
+ _Format_cache_base& _M_cache() { return *_M_format_cache; }
+
+ // Reserve space in virtual function table for now
+ virtual void _M_reserved1() {}
+ virtual void _M_reserved2() {}
+
// Destructor
/**
* Destroys local storage and
Index: libstdc++-v3/include/bits/locale_facets.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/locale_facets.h,v
retrieving revision 1.49.4.2
diff -u -r1.49.4.2 locale_facets.h
--- libstdc++-v3/include/bits/locale_facets.h 22 Jan 2003 17:39:50 -0000 1.49.4.2
+++ libstdc++-v3/include/bits/locale_facets.h 25 Jan 2003 05:44:46 -0000
@@ -103,7 +103,7 @@
__convert_to_v(const char*, long double&, ios_base::iostate&,
const __c_locale&, int);
-
+ // NB: __pad is meant to be partially-specialized, for optimization.
template<typename _CharT, typename _Traits>
struct __pad
{
@@ -113,11 +113,24 @@
const streamsize __oldlen, const bool __num);
};
+ // Used by both numeric and monetary facets.
+ // Check to make sure that the __grouping_tmp string constructed in
+ // money_get or num_get matches the canonical grouping for a given
+ // locale.
+ // __grouping_tmp is parsed L to R
+ // 1,222,444 == __grouping_tmp of "\1\3\3"
+ // __grouping is parsed R to L
+ // 1,222,444 == __grouping of "\3" == "\3\3\3"
template<typename _CharT>
bool
__verify_grouping(const basic_string<_CharT>& __grouping,
basic_string<_CharT>& __grouping_tmp);
+ // Used by both numeric and monetary facets.
+ // Inserts "group separator" characters into an array of characters.
+ // It's recursive, one iteration per group. It moves the characters
+ // in the buffer this way: "xxxx12345" -> "12,345xxx". Call this
+ // only with __gbeg != __gend.
template<typename _CharT>
_CharT*
__add_grouping(_CharT* __s, _CharT __sep,
@@ -1871,6 +1884,107 @@
inline _CharT
tolower(_CharT __c, const locale& __loc)
{ return use_facet<ctype<_CharT> >(__loc).tolower(__c); }
+
+
+ // Pseudo pointer machinery for transparent casting from void* to
+ // _Format_cache<_CharT>
+ template<typename _CharT>
+ class _Format_cache;
+
+ class _Format_cache_base
+ {
+ public:
+ virtual
+ ~_Format_cache_base() {}
+ };
+
+ // _Format_cache holds the information extracted from the numpunct<> and
+ // moneypunct<> facets in a form optimized for parsing and formatting. It
+ // is stored as a member of basic_ios and accessed via a void* pointer in
+ // the ios_base object passed to the _get and _put facets.
+
+ // Its intent is to avoid the cost of creating a locale object and
+ // calling the virtual functions in locale facets.
+ template<typename _CharT>
+ class _Format_cache : public _Format_cache_base
+ {
+ // Types:
+ typedef _CharT char_type;
+ typedef char_traits<_CharT> traits_type;
+ typedef basic_string<_CharT> string_type;
+
+
+ public:
+ // Data Members:
+
+ // A list of valid numeric literals: for the standard "C" locale, this
+ // is "-+xX0123456789abcdef0123456789ABCDEF". This array contains the
+ // chars after having been passed through the current locale's
+ // ctype<_CharT>.widen().
+ //
+
+ // NB: code depends on the order of definitions of the names
+ // these are indices into _M_numeric_literals, below.
+ // This string is formatted for putting, not getting. (output, not input)
+ 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_ee = _S_digits + 14, // For scientific notation, 'e'
+ _S_Ee = _S_udigits + 14 // For scientific notation, 'E'
+ };
+
+ _CharT _M_literals[_S_udigits_end];
+
+
+ // The sign used to separate decimal values: for standard US
+ // locales, this would usually be: "."
+ // Abstracted from numpunct::decimal_point().
+ _CharT _M_decimal_point;
+
+ // The sign used to separate groups of digits into smaller
+ // strings that the eye can parse with less difficulty: for
+ // standard US locales, this would usually be: ","
+ // Abstracted from numpunct::thousands_sep().
+ _CharT _M_thousands_sep;
+
+ // However the US's "false" and "true" are translated.
+ // From numpunct::truename() and numpunct::falsename(), respectively.
+ string_type _M_truename;
+ string_type _M_falsename;
+
+ // If we are checking groupings. This should be equivalent to
+ // numpunct::groupings().size() != 0
+ bool _M_use_grouping;
+
+ // If we are using numpunct's groupings, this is the current grouping
+ // string in effect (from numpunct::grouping()).
+ string _M_grouping;
+
+ _Format_cache();
+
+ _Format_cache& operator=(const _Format_cache& __fc);
+
+
+ // Make sure the cache is built before the first use.
+ void _M_init(ios_base&);
+
+ void
+ _M_populate (ios_base&);
+ };
+
+ template<>
+ _Format_cache<char>::_Format_cache();
+#ifdef _GLIBCPP_USE_WCHAR_T
+ template<>
+ _Format_cache<wchar_t>::_Format_cache();
+#endif
} // namespace std
#endif
Index: libstdc++-v3/include/bits/locale_facets.tcc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/locale_facets.tcc,v
retrieving revision 1.82.4.2
diff -u -r1.82.4.2 locale_facets.tcc
--- libstdc++-v3/include/bits/locale_facets.tcc 22 Jan 2003 17:39:50 -0000 1.82.4.2
+++ libstdc++-v3/include/bits/locale_facets.tcc 25 Jan 2003 05:44:47 -0000
@@ -686,39 +686,105 @@
return _M_widen_float(__s, __io, __fill, __cs, __len);
}
+ // num_put::_M_convert_int is only ever specialized with long, unsigned
+ // long, long long, and unsigned long long. These adapters permit calling
+ // into unsigned long and unsigned long long functions.
+ inline unsigned long __num_put_abs(long __v) { return -(unsigned long)__v; }
+ inline unsigned long __num_put_abs(unsigned long __v) { return __v; }
+ inline unsigned long __num_put_unsigned(long __v) { return (unsigned long)__v; }
+ inline unsigned long __num_put_unsigned(unsigned long __v) { return __v; }
+#ifdef _GLIBCPP_USE_LONG_LONG
+ inline unsigned long long __num_put_abs(long long __v) { return -(unsigned long long)__v; }
+ inline unsigned long long __num_put_abs(unsigned long long __v) { return __v; }
+ inline unsigned long long __num_put_unsigned(long long __v) { return -(unsigned long long)__v; }
+ inline unsigned long long __num_put_unsigned(unsigned long long __v) { return __v; }
+#endif
+
+ // Only called with unsigned long and unsigned long long
+ template<typename _CharT, typename _ValueT>
+ int
+ __convert_from_int(_CharT* __out, const int __size, _ValueT __v,
+ const _CharT* __lit, ios_base::fmtflags __flags,
+ bool __neg)
+ {
+ _CharT* __bufptr = __out + __size - 1;
+ _CharT* __bufend = __out + __size;
+ ios_base::fmtflags __bf = __flags & ios_base::basefield;
+
+ if (__builtin_expect(__bf == ios_base::oct, false))
+ {
+ // Octal
+ bool __showbase = ((__flags & ios_base::showbase) && __v); // Don't write base if already 0
+ do {
+ *__bufptr-- = __lit[(__v & 0x7) + _Format_cache<_CharT>::_S_digits];
+ __v >>=3;
+ } while (__v != 0);
+ if (__showbase)
+ *__bufptr-- = __lit[_Format_cache<_CharT>::_S_digits];
+ }
+ else if (__builtin_expect(__bf == ios_base::hex, false))
+ {
+ // Hex
+ int __case_offset = (__flags & ios_base::uppercase)
+ ? _Format_cache<_CharT>::_S_udigits
+ : _Format_cache<_CharT>::_S_digits;
+ do {
+ *__bufptr-- = __lit[(__v & 0xf) + __case_offset];
+ __v >>=4;
+ } while (__v != 0);
+ if (__flags & ios_base::showbase)
+ {
+ // 'x' or 'X'
+ *__bufptr-- = __lit[_Format_cache<_CharT>::_S_x +
+ (int)(!!(__flags & ios_base::uppercase))];
+ // '0'
+ *__bufptr-- = __lit[_Format_cache<_CharT>::_S_digits];
+ }
+ }
+ else
+ {
+ // Decimal
+ do {
+ *__bufptr-- = __lit[(__v % 10) + _Format_cache<_CharT>::_S_digits];
+ __v /= 10;
+ } while (__v != 0);
+ if (__neg)
+ *__bufptr-- = __lit[_Format_cache<_CharT>::_S_minus];
+ else if (__flags & ios_base::showpos)
+ *__bufptr-- = __lit[_Format_cache<_CharT>::_S_plus];
+ }
+ int __ret = __bufend - __bufptr - 1;
+ return __ret;
+ }
+
template<typename _CharT, typename _OutIter>
template<typename _ValueT>
_OutIter
num_put<_CharT, _OutIter>::
- _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
- char __modl, _ValueT __v) const
+ _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, char,
+ char, _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<char*>(__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<char*>(__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);
+ // Long enough to hold hex, dec, and octal representations.
+ int __cs_size = 4 * sizeof(_ValueT);
+ _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
+ * __cs_size));
+ _Format_cache<_CharT>& __fc = (_Format_cache<_CharT>&) __io._M_cache();
+ _CharT* __lit = __fc._M_literals;
+
+ int __len;
+ // Choose the adaptor required to convert the value for calling into
+ // an unsigned long (long) rendering function. Result is returned
+ // right-justified in the buffer.
+ if (__v < 0)
+ __len = __convert_from_int(&__cs[0], __cs_size, __num_put_abs(__v),
+ __lit, __io.flags(), true);
+ else
+ __len = __convert_from_int(&__cs[0], __cs_size, __num_put_unsigned(__v),
+ __lit, __io.flags(), false);
+
+ return _M_widen_int(__s, __io, __fill, (char*)(__cs + __cs_size - __len), __len);
}
template<typename _CharT, typename _OutIter>
@@ -784,22 +850,21 @@
{
// [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<ctype<_CharT> >(__loc);
- _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
- * __len));
+
+ _CharT* __ws = (_CharT*)__cs;
// 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);
+
+ _Format_cache<_CharT>& __fc = (_Format_cache<_CharT>&)__io._M_cache();
+
// Add grouping, if necessary.
- const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
- const string __grouping = __np.grouping();
- const ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
- if (__grouping.size())
+ if (__fc._M_use_grouping)
{
+ const ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
+
// 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.
@@ -819,9 +884,9 @@
*(__ws2 + 1) = *(__ws + 1);
}
_CharT* __p;
- __p = __add_grouping(__ws2 + __off, __np.thousands_sep(),
- __grouping.c_str(),
- __grouping.c_str() + __grouping.size(),
+ __p = __add_grouping(__ws2 + __off, __fc._M_thousands_sep,
+ __fc._M_grouping.c_str(),
+ __fc._M_grouping.c_str() + __fc._M_grouping.size(),
__ws + __off, __ws + __len);
__len = __p - __ws2;
// Switch strings.
@@ -830,6 +895,31 @@
return _M_insert(__s, __io, __fill, __ws, __len);
}
+
+ // This template permits specializing the stage 4 output code in _M_insert
+ // on ostreambuf_iterator. For the streambufs, sputn is significantly more
+ // efficient than incrementing iterators.
+ template<typename _CharT>
+ inline
+ ostreambuf_iterator<_CharT>
+ __num_put_streambuf_write (ostreambuf_iterator<_CharT> __s, const _CharT* __ws,
+ int __len)
+ {
+ __s._M_sbuf->sputn(__ws, __len);
+ return __s;
+ }
+
+ // This is the unspecialized form of the template
+ template<typename _CharT, typename _OutIter>
+ inline
+ _OutIter
+ __num_put_streambuf_write(_OutIter __s, const _CharT* __ws, int __len)
+ {
+ for (int __j = 0; __j < __len; __j++, ++__s)
+ *__s = __ws[__j];
+ return __s;
+ }
+
// For use by integer and floating-point types after they have been
// converted into a char_type string.
template<typename _CharT, typename _OutIter>
@@ -855,9 +945,7 @@
// [22.2.2.2.2] Stage 4.
// Write resulting, fully-formatted string to output iterator.
- for (int __j = 0; __j < __len; ++__j, ++__s)
- *__s = __ws[__j];
- return __s;
+ return __num_put_streambuf_write(__s, __ws, __len);
}
template<typename _CharT, typename _OutIter>
@@ -2054,14 +2142,6 @@
__newlen - __beglen - __mod);
}
- // Used by both numeric and monetary facets.
- // Check to make sure that the __grouping_tmp string constructed in
- // money_get or num_get matches the canonical grouping for a given
- // locale.
- // __grouping_tmp is parsed L to R
- // 1,222,444 == __grouping_tmp of "/1/3/3"
- // __grouping is parsed R to L
- // 1,222,444 == __grouping of "/3" == "/3/3/3"
template<typename _CharT>
bool
__verify_grouping(const basic_string<_CharT>& __grouping,
@@ -2086,11 +2166,6 @@
return __test;
}
- // Used by both numeric and monetary facets.
- // Inserts "group separator" characters into an array of characters.
- // It's recursive, one iteration per group. It moves the characters
- // in the buffer this way: "xxxx12345" -> "12,345xxx". Call this
- // only with __gbeg != __gend.
template<typename _CharT>
_CharT*
__add_grouping(_CharT* __s, _CharT __sep,
@@ -2110,6 +2185,62 @@
while (__first != __last);
return __s;
}
+
+ template<typename _CharT>
+ inline
+ _Format_cache<_CharT>::_Format_cache()
+ : _M_use_grouping(false)
+ { }
+
+ // Cache initialization
+ template<typename _CharT>
+ inline
+ void
+ _Format_cache<_CharT>::_M_init(ios_base& __io)
+ { _M_populate(__io); }
+
+ // char and wchar_t specializations start out valid, so no need to call
+ // _M_populate
+ template<>
+ inline
+ void
+ _Format_cache<char>::_M_init(ios_base&)
+ { }
+#ifdef _GLIBCPP_USE_WCHAR_T
+ template<>
+ inline
+ void
+ _Format_cache<wchar_t>::_M_init(ios_base&)
+ { }
+#endif
+
+
+ template<typename _CharT>
+ void
+ _Format_cache<_CharT>::_M_populate(ios_base& __io)
+ {
+ static const char _S_numeric_literals[] = "-+xX0123456789abcdef0123456789ABCDEF";
+ static const int _S_literal_count = sizeof(_S_numeric_literals) - 1;
+
+ locale __loc = __io.getloc();
+ if (__builtin_expect(has_facet<numpunct<_CharT> >(__loc), true))
+ {
+ numpunct<_CharT> const& __np = use_facet<numpunct<_CharT> >(__loc);
+ _M_falsename = __np.falsename();
+ _M_truename = __np.truename();
+ _M_thousands_sep = __np.thousands_sep();
+ _M_decimal_point = __np.decimal_point();
+ _M_grouping = __np.grouping();
+ _M_use_grouping = _M_grouping.size() != 0 && _M_grouping.data()[0] != 0;
+ }
+ if (__builtin_expect(has_facet< ctype<_CharT> >(__loc), true))
+ {
+ ctype<_CharT> const& __ct = use_facet< ctype<_CharT> >(__loc);
+ __ct.widen(_S_numeric_literals,
+ _S_numeric_literals + _S_literal_count, _M_literals);
+ }
+ }
+
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
Index: libstdc++-v3/include/bits/streambuf_iterator.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/streambuf_iterator.h,v
retrieving revision 1.8
diff -u -r1.8 streambuf_iterator.h
--- libstdc++-v3/include/bits/streambuf_iterator.h 31 Jul 2002 02:47:33 -0000 1.8
+++ libstdc++-v3/include/bits/streambuf_iterator.h 25 Jan 2003 05:44:47 -0000
@@ -1,6 +1,6 @@
// Streambuf iterators
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -40,6 +40,8 @@
#pragma GCC system_header
+#include <streambuf>
+
namespace std
{
// 24.5.3 Template class istreambuf_iterator
@@ -191,6 +193,10 @@
bool
failed() const throw()
{ return _M_failed; }
+
+ friend ostreambuf_iterator<_CharT>
+ __num_put_streambuf_write<_CharT>(ostreambuf_iterator<_CharT> __s,
+ const _CharT* __ws, int __len);
};
template<typename _CharT, typename _Traits>
Index: libstdc++-v3/src/ios.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/src/ios.cc,v
retrieving revision 1.33
diff -u -r1.33 ios.cc
--- libstdc++-v3/src/ios.cc 15 Nov 2002 19:12:31 -0000 1.33
+++ libstdc++-v3/src/ios.cc 25 Jan 2003 05:44:47 -0000
@@ -1,6 +1,6 @@
// Iostreams base classes -*- C++ -*-
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -301,7 +301,7 @@
return __old;
}
- ios_base::ios_base() : _M_callbacks(0), _M_word(0)
+ ios_base::ios_base() : _M_callbacks(0), _M_word(0), _M_format_cache(0)
{
// Do nothing: basic_ios::init() does it.
// NB: _M_callbacks and _M_word must be zero for non-initialized
Index: libstdc++-v3/src/locale-inst.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/src/locale-inst.cc,v
retrieving revision 1.35
diff -u -r1.35 locale-inst.cc
--- libstdc++-v3/src/locale-inst.cc 8 Oct 2002 23:32:23 -0000 1.35
+++ libstdc++-v3/src/locale-inst.cc 25 Jan 2003 05:44:47 -0000
@@ -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
@@ -46,6 +46,7 @@
template class moneypunct_byname<char, true>;
template class money_get<char, istreambuf_iterator<char> >;
template class money_put<char, ostreambuf_iterator<char> >;
+ template class _Format_cache<char>;
#ifdef _GLIBCPP_USE_WCHAR_T
template class moneypunct<wchar_t, false>;
@@ -54,6 +55,7 @@
template class moneypunct_byname<wchar_t, true>;
template class money_get<wchar_t, istreambuf_iterator<wchar_t> >;
template class money_put<wchar_t, ostreambuf_iterator<wchar_t> >;
+ template class _Format_cache<wchar_t>;
#endif
// numpunct, numpunct_byname, num_get, and num_put
@@ -451,6 +453,7 @@
__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 +463,35 @@
int
__convert_from_v(char*, const int, const char*, unsigned long long,
const __c_locale&, int);
+#endif
+
+ template
+ int
+ __convert_from_int(char* __out, const int __size, unsigned long __v,
+ const char* __lit, ios_base::fmtflags __flags,
+ bool __neg);
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+ template
+ int
+ __convert_from_int(wchar_t* __out, const int __size, unsigned long __v,
+ const wchar_t* __lit, ios_base::fmtflags __flags,
+ bool __neg);
+#endif
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+ template
+ int
+ __convert_from_int(char* __out, const int __size, unsigned long long __v,
+ const char* __lit, ios_base::fmtflags __flags,
+ bool __neg);
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+ template
+ int
+ __convert_from_int(wchar_t* __out, const int __size, unsigned long long __v,
+ const wchar_t* __lit, ios_base::fmtflags __flags,
+ bool __neg);
+#endif
+#endif
} // namespace std
Index: libstdc++-v3/src/localename.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/src/localename.cc,v
retrieving revision 1.33.2.2
diff -u -r1.33.2.2 localename.cc
--- libstdc++-v3/src/localename.cc 23 Jan 2003 17:19:28 -0000 1.33.2.2
+++ libstdc++-v3/src/localename.cc 25 Jan 2003 05:44:47 -0000
@@ -1,4 +1,4 @@
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002m 2003
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -350,4 +350,28 @@
}
}
}
+
+ template<>
+ _Format_cache<char>::_Format_cache()
+ : _M_decimal_point('.'), _M_thousands_sep(','),
+ _M_truename("true"), _M_falsename("false"), _M_use_grouping(false)
+ {
+ static const char _S_numeric_literals[] = "-+xX0123456789abcdef0123456789ABCDEF";
+ static const int _S_literal_count = sizeof(_S_numeric_literals) - 1;
+
+ copy(_S_numeric_literals, _S_numeric_literals + _S_literal_count, _M_literals);
+ }
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+ template<>
+ _Format_cache<wchar_t>::_Format_cache()
+ : _M_decimal_point(L'.'), _M_thousands_sep(L','),
+ _M_truename(L"true"), _M_falsename(L"false"), _M_use_grouping(false)
+ {
+ static const wchar_t _S_numeric_literals[] = L"-+xX0123456789abcdef0123456789ABCDEF";
+ static const int _S_literal_count = (sizeof(_S_numeric_literals) - 1) / sizeof(wchar_t);
+
+ copy(_S_numeric_literals, _S_numeric_literals + _S_literal_count, _M_literals);
+ }
+#endif
} // namespace std