diff options
Diffstat (limited to 'libstdc++-v3/include/bits/locale_facets.h')
-rw-r--r-- | libstdc++-v3/include/bits/locale_facets.h | 303 |
1 files changed, 242 insertions, 61 deletions
diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h index 660bad3c11a..8c6ac5023a3 100644 --- a/libstdc++-v3/include/bits/locale_facets.h +++ b/libstdc++-v3/include/bits/locale_facets.h @@ -1,6 +1,6 @@ // Locale support -*- 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 @@ -44,7 +44,9 @@ #include <ctime> // For struct tm #include <cwctype> // For wctype_t -#include <ios> // For ios_base +#include <iosfwd> +#include <bits/ios_base.h> // For ios_base, ios_base::iostate +#include <streambuf> namespace std { @@ -55,8 +57,109 @@ namespace std # define _GLIBCPP_NUM_FACETS 14 #endif + // Convert string to numeric value of type _Tv and store results. + // NB: This is specialized for all required types, there is no + // generic definition. + template<typename _Tv> + void + __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err, + const __c_locale& __cloc, int __base = 10); + + // Explicit specializations for required types. + template<> + void + __convert_to_v(const char*, long&, ios_base::iostate&, + const __c_locale&, int); + + template<> + void + __convert_to_v(const char*, unsigned long&, ios_base::iostate&, + const __c_locale&, int); + +#ifdef _GLIBCPP_USE_LONG_LONG + template<> + void + __convert_to_v(const char*, long long&, ios_base::iostate&, + const __c_locale&, int); + + template<> + void + __convert_to_v(const char*, unsigned long long&, ios_base::iostate&, + const __c_locale&, int); +#endif + + template<> + void + __convert_to_v(const char*, float&, ios_base::iostate&, + const __c_locale&, int); + + template<> + void + __convert_to_v(const char*, double&, ios_base::iostate&, + const __c_locale&, int); + + template<> + void + __convert_to_v(const char*, long double&, ios_base::iostate&, + const __c_locale&, int); + + // NB: __pad is a struct, rather than a function, so it can be + // partially-specialized. template<typename _CharT, typename _Traits> - struct __pad; + struct __pad + { + static void + _S_pad(ios_base& __io, _CharT __fill, _CharT* __news, + const _CharT* __olds, const streamsize __newlen, + 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, + const char* __gbeg, const char* __gend, + const _CharT* __first, const _CharT* __last); + + // This template permits specializing facet output code for + // ostreambuf_iterator. For ostreambuf_iterator, sputn is + // significantly more efficient than incrementing iterators. + template<typename _CharT> + inline + ostreambuf_iterator<_CharT> + __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len) + { + __s._M_put(__ws, __len); + return __s; + } + + // This is the unspecialized form of the template. + template<typename _CharT, typename _OutIter> + inline + _OutIter + __write(_OutIter __s, const _CharT* __ws, int __len) + { + for (int __j = 0; __j < __len; __j++, ++__s) + *__s = __ws[__j]; + return __s; + } // 22.2.1.1 Template class ctype // Include host and configuration specific ctype enums for ctype_base. @@ -424,14 +527,38 @@ namespace std // 22.2.1.5 Template class codecvt #include <bits/codecvt.h> - // 22.2.2 The numeric category. class __num_base { + public: + // NB: Code depends on the order of _S_atoms_out elements. + // Below are the indices into _S_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' + _S_end = _S_udigits_end + }; + + // A list of valid numeric literals for output. This array + // contains chars that will be passed through the current locale's + // ctype<_CharT>.widen() and then used to render numbers. + // 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 { @@ -443,7 +570,7 @@ namespace std // num_put // Construct and return valid scanf format for floating point types. - static bool + static void _S_format_float(const ios_base& __io, char* __fptr, char __mod, streamsize __prec); @@ -725,7 +852,6 @@ namespace std // Types: typedef _CharT char_type; typedef _OutIter iter_type; - static locale::id id; explicit @@ -775,6 +901,27 @@ 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<typename _ValueT> + iter_type + _M_convert_int(iter_type, ios_base& __io, char_type __fill, + _ValueT __v) const; + + void + _M_group_int(const string& __grouping, char_type __sep, + ios_base& __io, char_type* __new, char_type* __cs, + int& __len) const; + + void + _M_pad(char_type __fill, streamsize __w, ios_base& __io, + char_type* __new, const char_type* __cs, int& __len) const; + +#if 1 + // XXX GLIBCXX_ABI Deprecated, compatibility only. template<typename _ValueT> iter_type _M_convert_int(iter_type, ios_base& __io, char_type __fill, @@ -791,8 +938,9 @@ namespace std iter_type _M_insert(iter_type, ios_base& __io, char_type __fill, const char_type* __ws, int __len) const; +#endif - virtual + virtual ~num_put() { }; virtual iter_type @@ -1011,22 +1159,10 @@ namespace std public: explicit - __timepunct(size_t __refs = 0) - : locale::facet(__refs) - { - _M_name_timepunct = new char[2]; - strcpy(_M_name_timepunct, "C"); - _M_initialize_timepunct(); - } + __timepunct(size_t __refs = 0); explicit - __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0) - : locale::facet(__refs) - { - _M_name_timepunct = new char[strlen(__s) + 1]; - strcpy(_M_name_timepunct, __s); - _M_initialize_timepunct(__cloc); - } + __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0); void _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format, @@ -1123,11 +1259,7 @@ namespace std protected: virtual - ~__timepunct() - { - delete [] _M_name_timepunct; - _S_destroy_c_locale(_M_c_locale_timepunct); - } + ~__timepunct(); // For use at construction time only. void @@ -1169,6 +1301,8 @@ namespace std template<typename _CharT> const _CharT* __timepunct<_CharT>::_S_timezones[14]; + // Include host and configuration specific timepunct functions. + #include <bits/time_members.h> template<typename _CharT, typename _InIter> class time_get : public locale::facet, public time_base @@ -1628,32 +1762,17 @@ namespace std // Underlying "C" library locale information saved from // initialization, needed by messages_byname as well. __c_locale _M_c_locale_messages; -#if 1 - // Only needed if glibc < 2.3 char* _M_name_messages; -#endif public: static locale::id id; explicit - messages(size_t __refs = 0) - : locale::facet(__refs) - { - _M_name_messages = new char[2]; - strcpy(_M_name_messages, "C"); - _M_c_locale_messages = _S_c_locale; - } + messages(size_t __refs = 0); // Non-standard. explicit - messages(__c_locale __cloc, const char* __s, size_t __refs = 0) - : locale::facet(__refs) - { - _M_name_messages = new char[strlen(__s) + 1]; - strcpy(_M_name_messages, __s); - _M_c_locale_messages = _S_clone_c_locale(__cloc); - } + messages(__c_locale __cloc, const char* __s, size_t __refs = 0); catalog open(const basic_string<char>& __s, const locale& __loc) const @@ -1673,11 +1792,7 @@ namespace std protected: virtual - ~messages() - { - delete [] _M_name_messages; - _S_destroy_c_locale(_M_c_locale_messages); - } + ~messages(); virtual catalog do_open(const basic_string<char>&, const locale&) const; @@ -1751,9 +1866,6 @@ namespace std messages<wchar_t>::do_get(catalog, int, int, const wstring&) const; #endif - // Include host and configuration specific messages virtual functions. - #include <bits/messages_members.h> - template<typename _CharT> class messages_byname : public messages<_CharT> { @@ -1762,15 +1874,7 @@ namespace std typedef basic_string<_CharT> string_type; explicit - messages_byname(const char* __s, size_t __refs = 0) - : messages<_CharT>(__refs) - { - delete [] _M_name_messages; - _M_name_messages = new char[strlen(__s) + 1]; - strcpy(_M_name_messages, __s); - _S_destroy_c_locale(_M_c_locale_messages); - _S_create_c_locale(_M_c_locale_messages, __s); - } + messages_byname(const char* __s, size_t __refs = 0); protected: virtual @@ -1778,6 +1882,9 @@ namespace std { } }; + // Include host and configuration specific messages functions. + #include <bits/messages_members.h> + // Subclause convenience interfaces, inlines. // NB: These are inline because, when used in a loop, some compilers @@ -1846,6 +1953,80 @@ namespace std inline _CharT tolower(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).tolower(__c); } + + // __locale_cache holds the information extracted from the + // numpunct<> and moneypunct<> facets in a form optimized for + // parsing and formatting. To avoid breaking the 3.2 library + // API, it is stored in ios_base::_M_local_word[0]. 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. + class __locale_cache_base + { + public: + virtual + ~__locale_cache_base() {} + }; + + template<typename _CharT> + class __locale_cache : public __locale_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(). + _CharT _M_literals[__num_base::_S_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; + + __locale_cache() : _M_use_grouping(false) + { }; + + __locale_cache& + operator=(const __locale_cache& __lc); + + + // Make sure the cache is built before the first use. + void + _M_init(const locale&); + + // ios_base::pword callbacks come here + static void + _S_callback(ios_base::event __ev, ios_base& __io, int); + }; } // namespace std #endif |