From 4712681555dfa63280eeb06b6c609e657b1f3cfb Mon Sep 17 00:00:00 2001 From: paolo Date: Mon, 23 Apr 2007 20:26:30 +0000 Subject: [PATCH] 2007-04-23 Paolo Carlini * include/bits/locale_facets.h (class time_base, struct __timepunct_cache, class __timepunct, class time_get, class time_get_byname, class time_put, class time_put_byname, class money_base, struct __moneypunct_cache, class moneypunct, class moneypunct_byname, class money_get, class money_put, struct messages_base, class messages, class messages_byname): Move... * include/bits/locale_facets_nonio.h: ... here. * include/bits/locale_facets.tcc (struct __use_cache<__moneypunct_cache<> >, __moneypunct_cache<>::_M_cache, money_get<>::_M_extract, money_get<>::__do_get, money_get<>::do_get, money_put<>::_M_insert, money_put<>::__do_put, money_put<>::do_put, time_get<>::do_date_order, time_get<>::_M_extract_via_format, time_get<>::_M_extract_num, time_get<>::_M_extract_name, time_get<>::do_get_time, time_get<>::do_get_date, time_get<>::do_get_weekday, time_get<>::do_get_monthname, time_get<>::do_get_year, time_put<>::put, time_put<>::do_put): Move... * include/bits/locale_facets_nonio.tcc: ... here. * include/Makefile.am: Add. * include/std/locale: Adjust includes. * include/std/fstream: Likewise. * include/std/istream: Likewise. * include/std/ostream: Likewise. * include/Makefile.in: Regenerate. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@124080 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 27 + libstdc++-v3/include/Makefile.am | 2 + libstdc++-v3/include/Makefile.in | 2 + libstdc++-v3/include/bits/locale_facets.h | 1872 +------------------- libstdc++-v3/include/bits/locale_facets.tcc | 1282 -------------- libstdc++-v3/include/bits/locale_facets_nonio.h | 1909 +++++++++++++++++++++ libstdc++-v3/include/bits/locale_facets_nonio.tcc | 1328 ++++++++++++++ libstdc++-v3/include/std/fstream | 1 - libstdc++-v3/include/std/istream | 2 +- libstdc++-v3/include/std/locale | 10 +- libstdc++-v3/include/std/ostream | 2 +- 11 files changed, 3283 insertions(+), 3154 deletions(-) create mode 100644 libstdc++-v3/include/bits/locale_facets_nonio.h create mode 100644 libstdc++-v3/include/bits/locale_facets_nonio.tcc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c0f36593ed6..55b90855a5a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,30 @@ +2007-04-23 Paolo Carlini + + * include/bits/locale_facets.h (class time_base, + struct __timepunct_cache, class __timepunct, class time_get, + class time_get_byname, class time_put, class time_put_byname, + class money_base, struct __moneypunct_cache, class moneypunct, + class moneypunct_byname, class money_get, class money_put, + struct messages_base, class messages, class messages_byname): Move... + * include/bits/locale_facets_nonio.h: ... here. + * include/bits/locale_facets.tcc + (struct __use_cache<__moneypunct_cache<> >, + __moneypunct_cache<>::_M_cache, money_get<>::_M_extract, + money_get<>::__do_get, money_get<>::do_get, money_put<>::_M_insert, + money_put<>::__do_put, money_put<>::do_put, time_get<>::do_date_order, + time_get<>::_M_extract_via_format, time_get<>::_M_extract_num, + time_get<>::_M_extract_name, time_get<>::do_get_time, + time_get<>::do_get_date, time_get<>::do_get_weekday, + time_get<>::do_get_monthname, time_get<>::do_get_year, time_put<>::put, + time_put<>::do_put): Move... + * include/bits/locale_facets_nonio.tcc: ... here. + * include/Makefile.am: Add. + * include/std/locale: Adjust includes. + * include/std/fstream: Likewise. + * include/std/istream: Likewise. + * include/std/ostream: Likewise. + * include/Makefile.in: Regenerate. + 2007-04-23 Nathan Sidwell * scripts/testsuite_flags.in: Add --build-cc option. diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index dd79459b14c..2ce67ab7eff 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -91,6 +91,8 @@ bits_headers = \ ${bits_srcdir}/locale_classes.h \ ${bits_srcdir}/locale_facets.h \ ${bits_srcdir}/locale_facets.tcc \ + ${bits_srcdir}/locale_facets_nonio.h \ + ${bits_srcdir}/locale_facets_nonio.tcc \ ${bits_srcdir}/localefwd.h \ ${bits_srcdir}/mask_array.h \ ${bits_srcdir}/ostream.tcc \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index e8290012458..b382004914f 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -325,6 +325,8 @@ bits_headers = \ ${bits_srcdir}/locale_classes.h \ ${bits_srcdir}/locale_facets.h \ ${bits_srcdir}/locale_facets.tcc \ + ${bits_srcdir}/locale_facets_nonio.h \ + ${bits_srcdir}/locale_facets_nonio.tcc \ ${bits_srcdir}/localefwd.h \ ${bits_srcdir}/mask_array.h \ ${bits_srcdir}/ostream.tcc \ diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h index 69500dc64d2..e5fa9ad939d 100644 --- a/libstdc++-v3/include/bits/locale_facets.h +++ b/libstdc++-v3/include/bits/locale_facets.h @@ -43,7 +43,6 @@ #pragma GCC system_header -#include // For struct tm #include // For wctype_t #include #include @@ -51,6 +50,9 @@ #include // For ios_base, ios_base::iostate #include #include +#include +#include +#include _GLIBCXX_BEGIN_NAMESPACE(std) @@ -100,7 +102,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) // 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 __glen != 0. + // only with __gsize != 0. template _CharT* __add_grouping(_CharT* __s, _CharT __sep, @@ -1938,6 +1940,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) }; _GLIBCXX_BEGIN_LDBL_NAMESPACE + /** * @brief Facet for parsing number strings. * @@ -2757,1871 +2760,6 @@ _GLIBCXX_END_LDBL_NAMESPACE ~collate_byname() { } }; - - /** - * @brief Time format ordering data. - * - * This class provides an enum representing different orderings of day, - * month, and year. - */ - class time_base - { - public: - enum dateorder { no_order, dmy, mdy, ymd, ydm }; - }; - - template - struct __timepunct_cache : public locale::facet - { - // List of all known timezones, with GMT first. - static const _CharT* _S_timezones[14]; - - const _CharT* _M_date_format; - const _CharT* _M_date_era_format; - const _CharT* _M_time_format; - const _CharT* _M_time_era_format; - const _CharT* _M_date_time_format; - const _CharT* _M_date_time_era_format; - const _CharT* _M_am; - const _CharT* _M_pm; - const _CharT* _M_am_pm_format; - - // Day names, starting with "C"'s Sunday. - const _CharT* _M_day1; - const _CharT* _M_day2; - const _CharT* _M_day3; - const _CharT* _M_day4; - const _CharT* _M_day5; - const _CharT* _M_day6; - const _CharT* _M_day7; - - // Abbreviated day names, starting with "C"'s Sun. - const _CharT* _M_aday1; - const _CharT* _M_aday2; - const _CharT* _M_aday3; - const _CharT* _M_aday4; - const _CharT* _M_aday5; - const _CharT* _M_aday6; - const _CharT* _M_aday7; - - // Month names, starting with "C"'s January. - const _CharT* _M_month01; - const _CharT* _M_month02; - const _CharT* _M_month03; - const _CharT* _M_month04; - const _CharT* _M_month05; - const _CharT* _M_month06; - const _CharT* _M_month07; - const _CharT* _M_month08; - const _CharT* _M_month09; - const _CharT* _M_month10; - const _CharT* _M_month11; - const _CharT* _M_month12; - - // Abbreviated month names, starting with "C"'s Jan. - const _CharT* _M_amonth01; - const _CharT* _M_amonth02; - const _CharT* _M_amonth03; - const _CharT* _M_amonth04; - const _CharT* _M_amonth05; - const _CharT* _M_amonth06; - const _CharT* _M_amonth07; - const _CharT* _M_amonth08; - const _CharT* _M_amonth09; - const _CharT* _M_amonth10; - const _CharT* _M_amonth11; - const _CharT* _M_amonth12; - - bool _M_allocated; - - __timepunct_cache(size_t __refs = 0) : facet(__refs), - _M_date_format(NULL), _M_date_era_format(NULL), _M_time_format(NULL), - _M_time_era_format(NULL), _M_date_time_format(NULL), - _M_date_time_era_format(NULL), _M_am(NULL), _M_pm(NULL), - _M_am_pm_format(NULL), _M_day1(NULL), _M_day2(NULL), _M_day3(NULL), - _M_day4(NULL), _M_day5(NULL), _M_day6(NULL), _M_day7(NULL), - _M_aday1(NULL), _M_aday2(NULL), _M_aday3(NULL), _M_aday4(NULL), - _M_aday5(NULL), _M_aday6(NULL), _M_aday7(NULL), _M_month01(NULL), - _M_month02(NULL), _M_month03(NULL), _M_month04(NULL), _M_month05(NULL), - _M_month06(NULL), _M_month07(NULL), _M_month08(NULL), _M_month09(NULL), - _M_month10(NULL), _M_month11(NULL), _M_month12(NULL), _M_amonth01(NULL), - _M_amonth02(NULL), _M_amonth03(NULL), _M_amonth04(NULL), - _M_amonth05(NULL), _M_amonth06(NULL), _M_amonth07(NULL), - _M_amonth08(NULL), _M_amonth09(NULL), _M_amonth10(NULL), - _M_amonth11(NULL), _M_amonth12(NULL), _M_allocated(false) - { } - - ~__timepunct_cache(); - - void - _M_cache(const locale& __loc); - - private: - __timepunct_cache& - operator=(const __timepunct_cache&); - - explicit - __timepunct_cache(const __timepunct_cache&); - }; - - template - __timepunct_cache<_CharT>::~__timepunct_cache() - { - if (_M_allocated) - { - // Unused. - } - } - - // Specializations. - template<> - const char* - __timepunct_cache::_S_timezones[14]; - -#ifdef _GLIBCXX_USE_WCHAR_T - template<> - const wchar_t* - __timepunct_cache::_S_timezones[14]; -#endif - - // Generic. - template - const _CharT* __timepunct_cache<_CharT>::_S_timezones[14]; - - template - class __timepunct : public locale::facet - { - public: - // Types: - typedef _CharT __char_type; - typedef basic_string<_CharT> __string_type; - typedef __timepunct_cache<_CharT> __cache_type; - - protected: - __cache_type* _M_data; - __c_locale _M_c_locale_timepunct; - const char* _M_name_timepunct; - - public: - /// Numpunct facet id. - static locale::id id; - - explicit - __timepunct(size_t __refs = 0); - - explicit - __timepunct(__cache_type* __cache, size_t __refs = 0); - - /** - * @brief Internal constructor. Not for general use. - * - * This is a constructor for use by the library itself to set up new - * locales. - * - * @param cloc The "C" locale. - * @param s The name of a locale. - * @param refs Passed to the base facet class. - */ - explicit - __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0); - - // FIXME: for error checking purposes _M_put should return the return - // value of strftime/wcsftime. - void - _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format, - const tm* __tm) const; - - void - _M_date_formats(const _CharT** __date) const - { - // Always have default first. - __date[0] = _M_data->_M_date_format; - __date[1] = _M_data->_M_date_era_format; - } - - void - _M_time_formats(const _CharT** __time) const - { - // Always have default first. - __time[0] = _M_data->_M_time_format; - __time[1] = _M_data->_M_time_era_format; - } - - void - _M_date_time_formats(const _CharT** __dt) const - { - // Always have default first. - __dt[0] = _M_data->_M_date_time_format; - __dt[1] = _M_data->_M_date_time_era_format; - } - - void - _M_am_pm_format(const _CharT* __ampm) const - { __ampm = _M_data->_M_am_pm_format; } - - void - _M_am_pm(const _CharT** __ampm) const - { - __ampm[0] = _M_data->_M_am; - __ampm[1] = _M_data->_M_pm; - } - - void - _M_days(const _CharT** __days) const - { - __days[0] = _M_data->_M_day1; - __days[1] = _M_data->_M_day2; - __days[2] = _M_data->_M_day3; - __days[3] = _M_data->_M_day4; - __days[4] = _M_data->_M_day5; - __days[5] = _M_data->_M_day6; - __days[6] = _M_data->_M_day7; - } - - void - _M_days_abbreviated(const _CharT** __days) const - { - __days[0] = _M_data->_M_aday1; - __days[1] = _M_data->_M_aday2; - __days[2] = _M_data->_M_aday3; - __days[3] = _M_data->_M_aday4; - __days[4] = _M_data->_M_aday5; - __days[5] = _M_data->_M_aday6; - __days[6] = _M_data->_M_aday7; - } - - void - _M_months(const _CharT** __months) const - { - __months[0] = _M_data->_M_month01; - __months[1] = _M_data->_M_month02; - __months[2] = _M_data->_M_month03; - __months[3] = _M_data->_M_month04; - __months[4] = _M_data->_M_month05; - __months[5] = _M_data->_M_month06; - __months[6] = _M_data->_M_month07; - __months[7] = _M_data->_M_month08; - __months[8] = _M_data->_M_month09; - __months[9] = _M_data->_M_month10; - __months[10] = _M_data->_M_month11; - __months[11] = _M_data->_M_month12; - } - - void - _M_months_abbreviated(const _CharT** __months) const - { - __months[0] = _M_data->_M_amonth01; - __months[1] = _M_data->_M_amonth02; - __months[2] = _M_data->_M_amonth03; - __months[3] = _M_data->_M_amonth04; - __months[4] = _M_data->_M_amonth05; - __months[5] = _M_data->_M_amonth06; - __months[6] = _M_data->_M_amonth07; - __months[7] = _M_data->_M_amonth08; - __months[8] = _M_data->_M_amonth09; - __months[9] = _M_data->_M_amonth10; - __months[10] = _M_data->_M_amonth11; - __months[11] = _M_data->_M_amonth12; - } - - protected: - virtual - ~__timepunct(); - - // For use at construction time only. - void - _M_initialize_timepunct(__c_locale __cloc = NULL); - }; - - template - locale::id __timepunct<_CharT>::id; - - // Specializations. - template<> - void - __timepunct::_M_initialize_timepunct(__c_locale __cloc); - - template<> - void - __timepunct::_M_put(char*, size_t, const char*, const tm*) const; - -#ifdef _GLIBCXX_USE_WCHAR_T - template<> - void - __timepunct::_M_initialize_timepunct(__c_locale __cloc); - - template<> - void - __timepunct::_M_put(wchar_t*, size_t, const wchar_t*, - const tm*) const; -#endif - -_GLIBCXX_END_NAMESPACE - - // Include host and configuration specific timepunct functions. - #include - -_GLIBCXX_BEGIN_NAMESPACE(std) - - /** - * @brief Facet for parsing dates and times. - * - * This facet encapsulates the code to parse and return a date or - * time from a string. It is used by the istream numeric - * extraction operators. - * - * The time_get template uses protected virtual functions to provide the - * actual results. The public accessors forward the call to the virtual - * functions. These virtual functions are hooks for developers to - * implement the behavior they require from the time_get facet. - */ - template - class time_get : public locale::facet, public time_base - { - public: - // Types: - //@{ - /// Public typedefs - typedef _CharT char_type; - typedef _InIter iter_type; - //@} - typedef basic_string<_CharT> __string_type; - - /// Numpunct facet id. - static locale::id id; - - /** - * @brief Constructor performs initialization. - * - * This is the constructor provided by the standard. - * - * @param refs Passed to the base facet class. - */ - explicit - time_get(size_t __refs = 0) - : facet (__refs) { } - - /** - * @brief Return preferred order of month, day, and year. - * - * This function returns an enum from timebase::dateorder giving the - * preferred ordering if the format "x" given to time_put::put() only - * uses month, day, and year. If the format "x" for the associated - * locale uses other fields, this function returns - * timebase::dateorder::noorder. - * - * NOTE: The library always returns noorder at the moment. - * - * @return A member of timebase::dateorder. - */ - dateorder - date_order() const - { return this->do_date_order(); } - - /** - * @brief Parse input time string. - * - * This function parses a time according to the format "x" and puts the - * results into a user-supplied struct tm. The result is returned by - * calling time_get::do_get_time(). - * - * If there is a valid time string according to format "x", @a tm will - * be filled in accordingly and the returned iterator will point to the - * first character beyond the time string. If an error occurs before - * the end, err |= ios_base::failbit. If parsing reads all the - * characters, err |= ios_base::eofbit. - * - * @param beg Start of string to parse. - * @param end End of string to parse. - * @param io Source of the locale. - * @param err Error flags to set. - * @param tm Pointer to struct tm to fill in. - * @return Iterator to first char beyond time string. - */ - iter_type - get_time(iter_type __beg, iter_type __end, ios_base& __io, - ios_base::iostate& __err, tm* __tm) const - { return this->do_get_time(__beg, __end, __io, __err, __tm); } - - /** - * @brief Parse input date string. - * - * This function parses a date according to the format "X" and puts the - * results into a user-supplied struct tm. The result is returned by - * calling time_get::do_get_date(). - * - * If there is a valid date string according to format "X", @a tm will - * be filled in accordingly and the returned iterator will point to the - * first character beyond the date string. If an error occurs before - * the end, err |= ios_base::failbit. If parsing reads all the - * characters, err |= ios_base::eofbit. - * - * @param beg Start of string to parse. - * @param end End of string to parse. - * @param io Source of the locale. - * @param err Error flags to set. - * @param tm Pointer to struct tm to fill in. - * @return Iterator to first char beyond date string. - */ - iter_type - get_date(iter_type __beg, iter_type __end, ios_base& __io, - ios_base::iostate& __err, tm* __tm) const - { return this->do_get_date(__beg, __end, __io, __err, __tm); } - - /** - * @brief Parse input weekday string. - * - * This function parses a weekday name and puts the results into a - * user-supplied struct tm. The result is returned by calling - * time_get::do_get_weekday(). - * - * Parsing starts by parsing an abbreviated weekday name. If a valid - * abbreviation is followed by a character that would lead to the full - * weekday name, parsing continues until the full name is found or an - * error occurs. Otherwise parsing finishes at the end of the - * abbreviated name. - * - * If an error occurs before the end, err |= ios_base::failbit. If - * parsing reads all the characters, err |= ios_base::eofbit. - * - * @param beg Start of string to parse. - * @param end End of string to parse. - * @param io Source of the locale. - * @param err Error flags to set. - * @param tm Pointer to struct tm to fill in. - * @return Iterator to first char beyond weekday name. - */ - iter_type - get_weekday(iter_type __beg, iter_type __end, ios_base& __io, - ios_base::iostate& __err, tm* __tm) const - { return this->do_get_weekday(__beg, __end, __io, __err, __tm); } - - /** - * @brief Parse input month string. - * - * This function parses a month name and puts the results into a - * user-supplied struct tm. The result is returned by calling - * time_get::do_get_monthname(). - * - * Parsing starts by parsing an abbreviated month name. If a valid - * abbreviation is followed by a character that would lead to the full - * month name, parsing continues until the full name is found or an - * error occurs. Otherwise parsing finishes at the end of the - * abbreviated name. - * - * If an error occurs before the end, err |= ios_base::failbit. If - * parsing reads all the characters, err |= - * ios_base::eofbit. - * - * @param beg Start of string to parse. - * @param end End of string to parse. - * @param io Source of the locale. - * @param err Error flags to set. - * @param tm Pointer to struct tm to fill in. - * @return Iterator to first char beyond month name. - */ - iter_type - get_monthname(iter_type __beg, iter_type __end, ios_base& __io, - ios_base::iostate& __err, tm* __tm) const - { return this->do_get_monthname(__beg, __end, __io, __err, __tm); } - - /** - * @brief Parse input year string. - * - * This function reads up to 4 characters to parse a year string and - * puts the results into a user-supplied struct tm. The result is - * returned by calling time_get::do_get_year(). - * - * 4 consecutive digits are interpreted as a full year. If there are - * exactly 2 consecutive digits, the library interprets this as the - * number of years since 1900. - * - * If an error occurs before the end, err |= ios_base::failbit. If - * parsing reads all the characters, err |= ios_base::eofbit. - * - * @param beg Start of string to parse. - * @param end End of string to parse. - * @param io Source of the locale. - * @param err Error flags to set. - * @param tm Pointer to struct tm to fill in. - * @return Iterator to first char beyond year. - */ - iter_type - get_year(iter_type __beg, iter_type __end, ios_base& __io, - ios_base::iostate& __err, tm* __tm) const - { return this->do_get_year(__beg, __end, __io, __err, __tm); } - - protected: - /// Destructor. - virtual - ~time_get() { } - - /** - * @brief Return preferred order of month, day, and year. - * - * This function returns an enum from timebase::dateorder giving the - * preferred ordering if the format "x" given to time_put::put() only - * uses month, day, and year. This function is a hook for derived - * classes to change the value returned. - * - * @return A member of timebase::dateorder. - */ - virtual dateorder - do_date_order() const; - - /** - * @brief Parse input time string. - * - * This function parses a time according to the format "x" and puts the - * results into a user-supplied struct tm. This function is a hook for - * derived classes to change the value returned. @see get_time() for - * details. - * - * @param beg Start of string to parse. - * @param end End of string to parse. - * @param io Source of the locale. - * @param err Error flags to set. - * @param tm Pointer to struct tm to fill in. - * @return Iterator to first char beyond time string. - */ - virtual iter_type - do_get_time(iter_type __beg, iter_type __end, ios_base& __io, - ios_base::iostate& __err, tm* __tm) const; - - /** - * @brief Parse input date string. - * - * This function parses a date according to the format "X" and puts the - * results into a user-supplied struct tm. This function is a hook for - * derived classes to change the value returned. @see get_date() for - * details. - * - * @param beg Start of string to parse. - * @param end End of string to parse. - * @param io Source of the locale. - * @param err Error flags to set. - * @param tm Pointer to struct tm to fill in. - * @return Iterator to first char beyond date string. - */ - virtual iter_type - do_get_date(iter_type __beg, iter_type __end, ios_base& __io, - ios_base::iostate& __err, tm* __tm) const; - - /** - * @brief Parse input weekday string. - * - * This function parses a weekday name and puts the results into a - * user-supplied struct tm. This function is a hook for derived - * classes to change the value returned. @see get_weekday() for - * details. - * - * @param beg Start of string to parse. - * @param end End of string to parse. - * @param io Source of the locale. - * @param err Error flags to set. - * @param tm Pointer to struct tm to fill in. - * @return Iterator to first char beyond weekday name. - */ - virtual iter_type - do_get_weekday(iter_type __beg, iter_type __end, ios_base&, - ios_base::iostate& __err, tm* __tm) const; - - /** - * @brief Parse input month string. - * - * This function parses a month name and puts the results into a - * user-supplied struct tm. This function is a hook for derived - * classes to change the value returned. @see get_monthname() for - * details. - * - * @param beg Start of string to parse. - * @param end End of string to parse. - * @param io Source of the locale. - * @param err Error flags to set. - * @param tm Pointer to struct tm to fill in. - * @return Iterator to first char beyond month name. - */ - virtual iter_type - do_get_monthname(iter_type __beg, iter_type __end, ios_base&, - ios_base::iostate& __err, tm* __tm) const; - - /** - * @brief Parse input year string. - * - * This function reads up to 4 characters to parse a year string and - * puts the results into a user-supplied struct tm. This function is a - * hook for derived classes to change the value returned. @see - * get_year() for details. - * - * @param beg Start of string to parse. - * @param end End of string to parse. - * @param io Source of the locale. - * @param err Error flags to set. - * @param tm Pointer to struct tm to fill in. - * @return Iterator to first char beyond year. - */ - virtual iter_type - do_get_year(iter_type __beg, iter_type __end, ios_base& __io, - ios_base::iostate& __err, tm* __tm) const; - - // Extract numeric component of length __len. - iter_type - _M_extract_num(iter_type __beg, iter_type __end, int& __member, - int __min, int __max, size_t __len, - ios_base& __io, ios_base::iostate& __err) const; - - // Extract day or month name, or any unique array of string - // literals in a const _CharT* array. - iter_type - _M_extract_name(iter_type __beg, iter_type __end, int& __member, - const _CharT** __names, size_t __indexlen, - ios_base& __io, ios_base::iostate& __err) const; - - // Extract on a component-by-component basis, via __format argument. - iter_type - _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, - ios_base::iostate& __err, tm* __tm, - const _CharT* __format) const; - }; - - template - locale::id time_get<_CharT, _InIter>::id; - - /// @brief class time_get_byname [22.2.5.2]. - template - class time_get_byname : public time_get<_CharT, _InIter> - { - public: - // Types: - typedef _CharT char_type; - typedef _InIter iter_type; - - explicit - time_get_byname(const char*, size_t __refs = 0) - : time_get<_CharT, _InIter>(__refs) { } - - protected: - virtual - ~time_get_byname() { } - }; - - /** - * @brief Facet for outputting dates and times. - * - * This facet encapsulates the code to format and output dates and times - * according to formats used by strftime(). - * - * The time_put template uses protected virtual functions to provide the - * actual results. The public accessors forward the call to the virtual - * functions. These virtual functions are hooks for developers to - * implement the behavior they require from the time_put facet. - */ - template - class time_put : public locale::facet - { - public: - // Types: - //@{ - /// Public typedefs - typedef _CharT char_type; - typedef _OutIter iter_type; - //@} - - /// Numpunct facet id. - static locale::id id; - - /** - * @brief Constructor performs initialization. - * - * This is the constructor provided by the standard. - * - * @param refs Passed to the base facet class. - */ - explicit - time_put(size_t __refs = 0) - : facet(__refs) { } - - /** - * @brief Format and output a time or date. - * - * This function formats the data in struct tm according to the - * provided format string. The format string is interpreted as by - * strftime(). - * - * @param s The stream to write to. - * @param io Source of locale. - * @param fill char_type to use for padding. - * @param tm Struct tm with date and time info to format. - * @param beg Start of format string. - * @param end End of format string. - * @return Iterator after writing. - */ - iter_type - put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, - const _CharT* __beg, const _CharT* __end) const; - - /** - * @brief Format and output a time or date. - * - * This function formats the data in struct tm according to the - * provided format char and optional modifier. The format and modifier - * are interpreted as by strftime(). It does so by returning - * time_put::do_put(). - * - * @param s The stream to write to. - * @param io Source of locale. - * @param fill char_type to use for padding. - * @param tm Struct tm with date and time info to format. - * @param format Format char. - * @param mod Optional modifier char. - * @return Iterator after writing. - */ - iter_type - put(iter_type __s, ios_base& __io, char_type __fill, - const tm* __tm, char __format, char __mod = 0) const - { return this->do_put(__s, __io, __fill, __tm, __format, __mod); } - - protected: - /// Destructor. - virtual - ~time_put() - { } - - /** - * @brief Format and output a time or date. - * - * This function formats the data in struct tm according to the - * provided format char and optional modifier. This function is a hook - * for derived classes to change the value returned. @see put() for - * more details. - * - * @param s The stream to write to. - * @param io Source of locale. - * @param fill char_type to use for padding. - * @param tm Struct tm with date and time info to format. - * @param format Format char. - * @param mod Optional modifier char. - * @return Iterator after writing. - */ - virtual iter_type - do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, - char __format, char __mod) const; - }; - - template - locale::id time_put<_CharT, _OutIter>::id; - - /// @brief class time_put_byname [22.2.5.4]. - template - class time_put_byname : public time_put<_CharT, _OutIter> - { - public: - // Types: - typedef _CharT char_type; - typedef _OutIter iter_type; - - explicit - time_put_byname(const char*, size_t __refs = 0) - : time_put<_CharT, _OutIter>(__refs) - { }; - - protected: - virtual - ~time_put_byname() { } - }; - - - /** - * @brief Money format ordering data. - * - * This class contains an ordered array of 4 fields to represent the - * pattern for formatting a money amount. Each field may contain one entry - * from the part enum. symbol, sign, and value must be present and the - * remaining field must contain either none or space. @see - * moneypunct::pos_format() and moneypunct::neg_format() for details of how - * these fields are interpreted. - */ - class money_base - { - public: - enum part { none, space, symbol, sign, value }; - struct pattern { char field[4]; }; - - static const pattern _S_default_pattern; - - enum - { - _S_minus, - _S_zero, - _S_end = 11 - }; - - // String literal of acceptable (narrow) input/output, for - // money_get/money_put. "-0123456789" - static const char* _S_atoms; - - // Construct and return valid pattern consisting of some combination of: - // space none symbol sign value - static pattern - _S_construct_pattern(char __precedes, char __space, char __posn); - }; - - template - struct __moneypunct_cache : public locale::facet - { - const char* _M_grouping; - size_t _M_grouping_size; - bool _M_use_grouping; - _CharT _M_decimal_point; - _CharT _M_thousands_sep; - const _CharT* _M_curr_symbol; - size_t _M_curr_symbol_size; - const _CharT* _M_positive_sign; - size_t _M_positive_sign_size; - const _CharT* _M_negative_sign; - size_t _M_negative_sign_size; - int _M_frac_digits; - money_base::pattern _M_pos_format; - money_base::pattern _M_neg_format; - - // A list of valid numeric literals for input and output: in the standard - // "C" locale, this is "-0123456789". This array contains the chars after - // having been passed through the current locale's ctype<_CharT>.widen(). - _CharT _M_atoms[money_base::_S_end]; - - bool _M_allocated; - - __moneypunct_cache(size_t __refs = 0) : facet(__refs), - _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false), - _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()), - _M_curr_symbol(NULL), _M_curr_symbol_size(0), - _M_positive_sign(NULL), _M_positive_sign_size(0), - _M_negative_sign(NULL), _M_negative_sign_size(0), - _M_frac_digits(0), - _M_pos_format(money_base::pattern()), - _M_neg_format(money_base::pattern()), _M_allocated(false) - { } - - ~__moneypunct_cache(); - - void - _M_cache(const locale& __loc); - - private: - __moneypunct_cache& - operator=(const __moneypunct_cache&); - - explicit - __moneypunct_cache(const __moneypunct_cache&); - }; - - template - __moneypunct_cache<_CharT, _Intl>::~__moneypunct_cache() - { - if (_M_allocated) - { - delete [] _M_grouping; - delete [] _M_curr_symbol; - delete [] _M_positive_sign; - delete [] _M_negative_sign; - } - } - - /** - * @brief Facet for formatting data for money amounts. - * - * This facet encapsulates the punctuation, grouping and other formatting - * features of money amount string representations. - */ - template - class moneypunct : public locale::facet, public money_base - { - public: - // Types: - //@{ - /// Public typedefs - typedef _CharT char_type; - typedef basic_string<_CharT> string_type; - //@} - typedef __moneypunct_cache<_CharT, _Intl> __cache_type; - - private: - __cache_type* _M_data; - - public: - /// This value is provided by the standard, but no reason for its - /// existence. - static const bool intl = _Intl; - /// Numpunct facet id. - static locale::id id; - - /** - * @brief Constructor performs initialization. - * - * This is the constructor provided by the standard. - * - * @param refs Passed to the base facet class. - */ - explicit - moneypunct(size_t __refs = 0) : facet(__refs), _M_data(NULL) - { _M_initialize_moneypunct(); } - - /** - * @brief Constructor performs initialization. - * - * This is an internal constructor. - * - * @param cache Cache for optimization. - * @param refs Passed to the base facet class. - */ - explicit - moneypunct(__cache_type* __cache, size_t __refs = 0) - : facet(__refs), _M_data(__cache) - { _M_initialize_moneypunct(); } - - /** - * @brief Internal constructor. Not for general use. - * - * This is a constructor for use by the library itself to set up new - * locales. - * - * @param cloc The "C" locale. - * @param s The name of a locale. - * @param refs Passed to the base facet class. - */ - explicit - moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0) - : facet(__refs), _M_data(NULL) - { _M_initialize_moneypunct(__cloc, __s); } - - /** - * @brief Return decimal point character. - * - * This function returns a char_type to use as a decimal point. It - * does so by returning returning - * moneypunct::do_decimal_point(). - * - * @return @a char_type representing a decimal point. - */ - char_type - decimal_point() const - { return this->do_decimal_point(); } - - /** - * @brief Return thousands separator character. - * - * This function returns a char_type to use as a thousands - * separator. It does so by returning returning - * moneypunct::do_thousands_sep(). - * - * @return char_type representing a thousands separator. - */ - char_type - thousands_sep() const - { return this->do_thousands_sep(); } - - /** - * @brief Return grouping specification. - * - * This function returns a string representing groupings for the - * integer part of an amount. Groupings indicate where thousands - * separators should be inserted. - * - * Each char in the return string is interpret as an integer rather - * than a character. These numbers represent the number of digits in a - * group. The first char in the string represents the number of digits - * in the least significant group. If a char is negative, it indicates - * an unlimited number of digits for the group. If more chars from the - * string are required to group a number, the last char is used - * repeatedly. - * - * For example, if the grouping() returns "\003\002" and is applied to - * the number 123456789, this corresponds to 12,34,56,789. Note that - * if the string was "32", this would put more than 50 digits into the - * least significant group if the character set is ASCII. - * - * The string is returned by calling - * moneypunct::do_grouping(). - * - * @return string representing grouping specification. - */ - string - grouping() const - { return this->do_grouping(); } - - /** - * @brief Return currency symbol string. - * - * This function returns a string_type to use as a currency symbol. It - * does so by returning returning - * moneypunct::do_curr_symbol(). - * - * @return @a string_type representing a currency symbol. - */ - string_type - curr_symbol() const - { return this->do_curr_symbol(); } - - /** - * @brief Return positive sign string. - * - * This function returns a string_type to use as a sign for positive - * amounts. It does so by returning returning - * moneypunct::do_positive_sign(). - * - * If the return value contains more than one character, the first - * character appears in the position indicated by pos_format() and the - * remainder appear at the end of the formatted string. - * - * @return @a string_type representing a positive sign. - */ - string_type - positive_sign() const - { return this->do_positive_sign(); } - - /** - * @brief Return negative sign string. - * - * This function returns a string_type to use as a sign for negative - * amounts. It does so by returning returning - * moneypunct::do_negative_sign(). - * - * If the return value contains more than one character, the first - * character appears in the position indicated by neg_format() and the - * remainder appear at the end of the formatted string. - * - * @return @a string_type representing a negative sign. - */ - string_type - negative_sign() const - { return this->do_negative_sign(); } - - /** - * @brief Return number of digits in fraction. - * - * This function returns the exact number of digits that make up the - * fractional part of a money amount. It does so by returning - * returning moneypunct::do_frac_digits(). - * - * The fractional part of a money amount is optional. But if it is - * present, there must be frac_digits() digits. - * - * @return Number of digits in amount fraction. - */ - int - frac_digits() const - { return this->do_frac_digits(); } - - //@{ - /** - * @brief Return pattern for money values. - * - * This function returns a pattern describing the formatting of a - * positive or negative valued money amount. It does so by returning - * returning moneypunct::do_pos_format() or - * moneypunct::do_neg_format(). - * - * The pattern has 4 fields describing the ordering of symbol, sign, - * value, and none or space. There must be one of each in the pattern. - * The none and space enums may not appear in the first field and space - * may not appear in the final field. - * - * The parts of a money string must appear in the order indicated by - * the fields of the pattern. The symbol field indicates that the - * value of curr_symbol() may be present. The sign field indicates - * that the value of positive_sign() or negative_sign() must be - * present. The value field indicates that the absolute value of the - * money amount is present. none indicates 0 or more whitespace - * characters, except at the end, where it permits no whitespace. - * space indicates that 1 or more whitespace characters must be - * present. - * - * For example, for the US locale and pos_format() pattern - * {symbol,sign,value,none}, curr_symbol() == '$' positive_sign() == - * '+', and value 10.01, and options set to force the symbol, the - * corresponding string is "$+10.01". - * - * @return Pattern for money values. - */ - pattern - pos_format() const - { return this->do_pos_format(); } - - pattern - neg_format() const - { return this->do_neg_format(); } - //@} - - protected: - /// Destructor. - virtual - ~moneypunct(); - - /** - * @brief Return decimal point character. - * - * Returns a char_type to use as a decimal point. This function is a - * hook for derived classes to change the value returned. - * - * @return @a char_type representing a decimal point. - */ - virtual char_type - do_decimal_point() const - { return _M_data->_M_decimal_point; } - - /** - * @brief Return thousands separator character. - * - * Returns a char_type to use as a thousands separator. This function - * is a hook for derived classes to change the value returned. - * - * @return @a char_type representing a thousands separator. - */ - virtual char_type - do_thousands_sep() const - { return _M_data->_M_thousands_sep; } - - /** - * @brief Return grouping specification. - * - * Returns a string representing groupings for the integer part of a - * number. This function is a hook for derived classes to change the - * value returned. @see grouping() for details. - * - * @return String representing grouping specification. - */ - virtual string - do_grouping() const - { return _M_data->_M_grouping; } - - /** - * @brief Return currency symbol string. - * - * This function returns a string_type to use as a currency symbol. - * This function is a hook for derived classes to change the value - * returned. @see curr_symbol() for details. - * - * @return @a string_type representing a currency symbol. - */ - virtual string_type - do_curr_symbol() const - { return _M_data->_M_curr_symbol; } - - /** - * @brief Return positive sign string. - * - * This function returns a string_type to use as a sign for positive - * amounts. This function is a hook for derived classes to change the - * value returned. @see positive_sign() for details. - * - * @return @a string_type representing a positive sign. - */ - virtual string_type - do_positive_sign() const - { return _M_data->_M_positive_sign; } - - /** - * @brief Return negative sign string. - * - * This function returns a string_type to use as a sign for negative - * amounts. This function is a hook for derived classes to change the - * value returned. @see negative_sign() for details. - * - * @return @a string_type representing a negative sign. - */ - virtual string_type - do_negative_sign() const - { return _M_data->_M_negative_sign; } - - /** - * @brief Return number of digits in fraction. - * - * This function returns the exact number of digits that make up the - * fractional part of a money amount. This function is a hook for - * derived classes to change the value returned. @see frac_digits() - * for details. - * - * @return Number of digits in amount fraction. - */ - virtual int - do_frac_digits() const - { return _M_data->_M_frac_digits; } - - /** - * @brief Return pattern for money values. - * - * This function returns a pattern describing the formatting of a - * positive valued money amount. This function is a hook for derived - * classes to change the value returned. @see pos_format() for - * details. - * - * @return Pattern for money values. - */ - virtual pattern - do_pos_format() const - { return _M_data->_M_pos_format; } - - /** - * @brief Return pattern for money values. - * - * This function returns a pattern describing the formatting of a - * negative valued money amount. This function is a hook for derived - * classes to change the value returned. @see neg_format() for - * details. - * - * @return Pattern for money values. - */ - virtual pattern - do_neg_format() const - { return _M_data->_M_neg_format; } - - // For use at construction time only. - void - _M_initialize_moneypunct(__c_locale __cloc = NULL, - const char* __name = NULL); - }; - - template - locale::id moneypunct<_CharT, _Intl>::id; - - template - const bool moneypunct<_CharT, _Intl>::intl; - - template<> - moneypunct::~moneypunct(); - - template<> - moneypunct::~moneypunct(); - - template<> - void - moneypunct::_M_initialize_moneypunct(__c_locale, const char*); - - template<> - void - moneypunct::_M_initialize_moneypunct(__c_locale, const char*); - -#ifdef _GLIBCXX_USE_WCHAR_T - template<> - moneypunct::~moneypunct(); - - template<> - moneypunct::~moneypunct(); - - template<> - void - moneypunct::_M_initialize_moneypunct(__c_locale, - const char*); - - template<> - void - moneypunct::_M_initialize_moneypunct(__c_locale, - const char*); -#endif - - /// @brief class moneypunct_byname [22.2.6.4]. - template - class moneypunct_byname : public moneypunct<_CharT, _Intl> - { - public: - typedef _CharT char_type; - typedef basic_string<_CharT> string_type; - - static const bool intl = _Intl; - - explicit - moneypunct_byname(const char* __s, size_t __refs = 0) - : moneypunct<_CharT, _Intl>(__refs) - { - if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) - { - __c_locale __tmp; - this->_S_create_c_locale(__tmp, __s); - this->_M_initialize_moneypunct(__tmp); - this->_S_destroy_c_locale(__tmp); - } - } - - protected: - virtual - ~moneypunct_byname() { } - }; - - template - const bool moneypunct_byname<_CharT, _Intl>::intl; - -_GLIBCXX_BEGIN_LDBL_NAMESPACE - /** - * @brief Facet for parsing monetary amounts. - * - * This facet encapsulates the code to parse and return a monetary - * amount from a string. - * - * The money_get template uses protected virtual functions to - * provide the actual results. The public accessors forward the - * call to the virtual functions. These virtual functions are - * hooks for developers to implement the behavior they require from - * the money_get facet. - */ - template - class money_get : public locale::facet - { - public: - // Types: - //@{ - /// Public typedefs - typedef _CharT char_type; - typedef _InIter iter_type; - typedef basic_string<_CharT> string_type; - //@} - - /// Numpunct facet id. - static locale::id id; - - /** - * @brief Constructor performs initialization. - * - * This is the constructor provided by the standard. - * - * @param refs Passed to the base facet class. - */ - explicit - money_get(size_t __refs = 0) : facet(__refs) { } - - /** - * @brief Read and parse a monetary value. - * - * This function reads characters from @a s, interprets them as a - * monetary value according to moneypunct and ctype facets retrieved - * from io.getloc(), and returns the result in @a units as an integral - * value moneypunct::frac_digits() * the actual amount. For example, - * the string $10.01 in a US locale would store 1001 in @a units. - * - * Any characters not part of a valid money amount are not consumed. - * - * If a money value cannot be parsed from the input stream, sets - * err=(err|io.failbit). If the stream is consumed before finishing - * parsing, sets err=(err|io.failbit|io.eofbit). @a units is - * unchanged if parsing fails. - * - * This function works by returning the result of do_get(). - * - * @param s Start of characters to parse. - * @param end End of characters to parse. - * @param intl Parameter to use_facet >. - * @param io Source of facets and io state. - * @param err Error field to set if parsing fails. - * @param units Place to store result of parsing. - * @return Iterator referencing first character beyond valid money - * amount. - */ - iter_type - get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, - ios_base::iostate& __err, long double& __units) const - { return this->do_get(__s, __end, __intl, __io, __err, __units); } - - /** - * @brief Read and parse a monetary value. - * - * This function reads characters from @a s, interprets them as a - * monetary value according to moneypunct and ctype facets retrieved - * from io.getloc(), and returns the result in @a digits. For example, - * the string $10.01 in a US locale would store "1001" in @a digits. - * - * Any characters not part of a valid money amount are not consumed. - * - * If a money value cannot be parsed from the input stream, sets - * err=(err|io.failbit). If the stream is consumed before finishing - * parsing, sets err=(err|io.failbit|io.eofbit). - * - * This function works by returning the result of do_get(). - * - * @param s Start of characters to parse. - * @param end End of characters to parse. - * @param intl Parameter to use_facet >. - * @param io Source of facets and io state. - * @param err Error field to set if parsing fails. - * @param digits Place to store result of parsing. - * @return Iterator referencing first character beyond valid money - * amount. - */ - iter_type - get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, - ios_base::iostate& __err, string_type& __digits) const - { return this->do_get(__s, __end, __intl, __io, __err, __digits); } - - protected: - /// Destructor. - virtual - ~money_get() { } - - /** - * @brief Read and parse a monetary value. - * - * This function reads and parses characters representing a monetary - * value. This function is a hook for derived classes to change the - * value returned. @see get() for details. - */ - // XXX GLIBCXX_ABI Deprecated -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ - virtual iter_type - __do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, - ios_base::iostate& __err, double& __units) const; -#else - virtual iter_type - do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, - ios_base::iostate& __err, long double& __units) const; -#endif - - /** - * @brief Read and parse a monetary value. - * - * This function reads and parses characters representing a monetary - * value. This function is a hook for derived classes to change the - * value returned. @see get() for details. - */ - virtual iter_type - do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, - ios_base::iostate& __err, string_type& __digits) const; - - // XXX GLIBCXX_ABI Deprecated -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ - virtual iter_type - do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, - ios_base::iostate& __err, long double& __units) const; -#endif - - template - iter_type - _M_extract(iter_type __s, iter_type __end, ios_base& __io, - ios_base::iostate& __err, string& __digits) const; - }; - - template - locale::id money_get<_CharT, _InIter>::id; - - /** - * @brief Facet for outputting monetary amounts. - * - * This facet encapsulates the code to format and output a monetary - * amount. - * - * The money_put template uses protected virtual functions to - * provide the actual results. The public accessors forward the - * call to the virtual functions. These virtual functions are - * hooks for developers to implement the behavior they require from - * the money_put facet. - */ - template - class money_put : public locale::facet - { - public: - //@{ - /// Public typedefs - typedef _CharT char_type; - typedef _OutIter iter_type; - typedef basic_string<_CharT> string_type; - //@} - - /// Numpunct facet id. - static locale::id id; - - /** - * @brief Constructor performs initialization. - * - * This is the constructor provided by the standard. - * - * @param refs Passed to the base facet class. - */ - explicit - money_put(size_t __refs = 0) : facet(__refs) { } - - /** - * @brief Format and output a monetary value. - * - * This function formats @a units as a monetary value according to - * moneypunct and ctype facets retrieved from io.getloc(), and writes - * the resulting characters to @a s. For example, the value 1001 in a - * US locale would write "$10.01" to @a s. - * - * This function works by returning the result of do_put(). - * - * @param s The stream to write to. - * @param intl Parameter to use_facet >. - * @param io Source of facets and io state. - * @param fill char_type to use for padding. - * @param units Place to store result of parsing. - * @return Iterator after writing. - */ - iter_type - put(iter_type __s, bool __intl, ios_base& __io, - char_type __fill, long double __units) const - { return this->do_put(__s, __intl, __io, __fill, __units); } - - /** - * @brief Format and output a monetary value. - * - * This function formats @a digits as a monetary value according to - * moneypunct and ctype facets retrieved from io.getloc(), and writes - * the resulting characters to @a s. For example, the string "1001" in - * a US locale would write "$10.01" to @a s. - * - * This function works by returning the result of do_put(). - * - * @param s The stream to write to. - * @param intl Parameter to use_facet >. - * @param io Source of facets and io state. - * @param fill char_type to use for padding. - * @param units Place to store result of parsing. - * @return Iterator after writing. - */ - iter_type - put(iter_type __s, bool __intl, ios_base& __io, - char_type __fill, const string_type& __digits) const - { return this->do_put(__s, __intl, __io, __fill, __digits); } - - protected: - /// Destructor. - virtual - ~money_put() { } - - /** - * @brief Format and output a monetary value. - * - * This function formats @a units as a monetary value according to - * moneypunct and ctype facets retrieved from io.getloc(), and writes - * the resulting characters to @a s. For example, the value 1001 in a - * US locale would write "$10.01" to @a s. - * - * This function is a hook for derived classes to change the value - * returned. @see put(). - * - * @param s The stream to write to. - * @param intl Parameter to use_facet >. - * @param io Source of facets and io state. - * @param fill char_type to use for padding. - * @param units Place to store result of parsing. - * @return Iterator after writing. - */ - // XXX GLIBCXX_ABI Deprecated -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ - virtual iter_type - __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, - double __units) const; -#else - virtual iter_type - do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, - long double __units) const; -#endif - - /** - * @brief Format and output a monetary value. - * - * This function formats @a digits as a monetary value according to - * moneypunct and ctype facets retrieved from io.getloc(), and writes - * the resulting characters to @a s. For example, the string "1001" in - * a US locale would write "$10.01" to @a s. - * - * This function is a hook for derived classes to change the value - * returned. @see put(). - * - * @param s The stream to write to. - * @param intl Parameter to use_facet >. - * @param io Source of facets and io state. - * @param fill char_type to use for padding. - * @param units Place to store result of parsing. - * @return Iterator after writing. - */ - virtual iter_type - do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, - const string_type& __digits) const; - - // XXX GLIBCXX_ABI Deprecated -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ - virtual iter_type - do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, - long double __units) const; -#endif - - template - iter_type - _M_insert(iter_type __s, ios_base& __io, char_type __fill, - const string_type& __digits) const; - }; - - template - locale::id money_put<_CharT, _OutIter>::id; - -_GLIBCXX_END_LDBL_NAMESPACE - - /** - * @brief Messages facet base class providing catalog typedef. - */ - struct messages_base - { - typedef int catalog; - }; - - /** - * @brief Facet for handling message catalogs - * - * This facet encapsulates the code to retrieve messages from - * message catalogs. The only thing defined by the standard for this facet - * is the interface. All underlying functionality is - * implementation-defined. - * - * This library currently implements 3 versions of the message facet. The - * first version (gnu) is a wrapper around gettext, provided by libintl. - * The second version (ieee) is a wrapper around catgets. The final - * version (default) does no actual translation. These implementations are - * only provided for char and wchar_t instantiations. - * - * The messages template uses protected virtual functions to - * provide the actual results. The public accessors forward the - * call to the virtual functions. These virtual functions are - * hooks for developers to implement the behavior they require from - * the messages facet. - */ - template - class messages : public locale::facet, public messages_base - { - public: - // Types: - //@{ - /// Public typedefs - typedef _CharT char_type; - typedef basic_string<_CharT> string_type; - //@} - - protected: - // Underlying "C" library locale information saved from - // initialization, needed by messages_byname as well. - __c_locale _M_c_locale_messages; - const char* _M_name_messages; - - public: - /// Numpunct facet id. - static locale::id id; - - /** - * @brief Constructor performs initialization. - * - * This is the constructor provided by the standard. - * - * @param refs Passed to the base facet class. - */ - explicit - messages(size_t __refs = 0); - - // Non-standard. - /** - * @brief Internal constructor. Not for general use. - * - * This is a constructor for use by the library itself to set up new - * locales. - * - * @param cloc The "C" locale. - * @param s The name of a locale. - * @param refs Refcount to pass to the base class. - */ - explicit - messages(__c_locale __cloc, const char* __s, size_t __refs = 0); - - /* - * @brief Open a message catalog. - * - * This function opens and returns a handle to a message catalog by - * returning do_open(s, loc). - * - * @param s The catalog to open. - * @param loc Locale to use for character set conversions. - * @return Handle to the catalog or value < 0 if open fails. - */ - catalog - open(const basic_string& __s, const locale& __loc) const - { return this->do_open(__s, __loc); } - - // Non-standard and unorthodox, yet effective. - /* - * @brief Open a message catalog. - * - * This non-standard function opens and returns a handle to a message - * catalog by returning do_open(s, loc). The third argument provides a - * message catalog root directory for gnu gettext and is ignored - * otherwise. - * - * @param s The catalog to open. - * @param loc Locale to use for character set conversions. - * @param dir Message catalog root directory. - * @return Handle to the catalog or value < 0 if open fails. - */ - catalog - open(const basic_string&, const locale&, const char*) const; - - /* - * @brief Look up a string in a message catalog. - * - * This function retrieves and returns a message from a catalog by - * returning do_get(c, set, msgid, s). - * - * For gnu, @a set and @a msgid are ignored. Returns gettext(s). - * For default, returns s. For ieee, returns catgets(c,set,msgid,s). - * - * @param c The catalog to access. - * @param set Implementation-defined. - * @param msgid Implementation-defined. - * @param s Default return value if retrieval fails. - * @return Retrieved message or @a s if get fails. - */ - string_type - get(catalog __c, int __set, int __msgid, const string_type& __s) const - { return this->do_get(__c, __set, __msgid, __s); } - - /* - * @brief Close a message catalog. - * - * Closes catalog @a c by calling do_close(c). - * - * @param c The catalog to close. - */ - void - close(catalog __c) const - { return this->do_close(__c); } - - protected: - /// Destructor. - virtual - ~messages(); - - /* - * @brief Open a message catalog. - * - * This function opens and returns a handle to a message catalog in an - * implementation-defined manner. This function is a hook for derived - * classes to change the value returned. - * - * @param s The catalog to open. - * @param loc Locale to use for character set conversions. - * @return Handle to the opened catalog, value < 0 if open failed. - */ - virtual catalog - do_open(const basic_string&, const locale&) const; - - /* - * @brief Look up a string in a message catalog. - * - * This function retrieves and returns a message from a catalog in an - * implementation-defined manner. This function is a hook for derived - * classes to change the value returned. - * - * For gnu, @a set and @a msgid are ignored. Returns gettext(s). - * For default, returns s. For ieee, returns catgets(c,set,msgid,s). - * - * @param c The catalog to access. - * @param set Implementation-defined. - * @param msgid Implementation-defined. - * @param s Default return value if retrieval fails. - * @return Retrieved message or @a s if get fails. - */ - virtual string_type - do_get(catalog, int, int, const string_type& __dfault) const; - - /* - * @brief Close a message catalog. - * - * @param c The catalog to close. - */ - virtual void - do_close(catalog) const; - - // Returns a locale and codeset-converted string, given a char* message. - char* - _M_convert_to_char(const string_type& __msg) const - { - // XXX - return reinterpret_cast(const_cast<_CharT*>(__msg.c_str())); - } - - // Returns a locale and codeset-converted string, given a char* message. - string_type - _M_convert_from_char(char*) const - { -#if 0 - // Length of message string without terminating null. - size_t __len = char_traits::length(__msg) - 1; - - // "everybody can easily convert the string using - // mbsrtowcs/wcsrtombs or with iconv()" - - // Convert char* to _CharT in locale used to open catalog. - // XXX need additional template parameter on messages class for this.. - // typedef typename codecvt __codecvt_type; - typedef typename codecvt __codecvt_type; - - __codecvt_type::state_type __state; - // XXX may need to initialize state. - //initialize_state(__state._M_init()); - - char* __from_next; - // XXX what size for this string? - _CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1)); - const __codecvt_type& __cvt = use_facet<__codecvt_type>(_M_locale_conv); - __cvt.out(__state, __msg, __msg + __len, __from_next, - __to, __to + __len + 1, __to_next); - return string_type(__to); -#endif -#if 0 - typedef ctype<_CharT> __ctype_type; - // const __ctype_type& __cvt = use_facet<__ctype_type>(_M_locale_msg); - const __ctype_type& __cvt = use_facet<__ctype_type>(locale()); - // XXX Again, proper length of converted string an issue here. - // For now, assume the converted length is not larger. - _CharT* __dest = static_cast<_CharT*>(__builtin_alloca(__len + 1)); - __cvt.widen(__msg, __msg + __len, __dest); - return basic_string<_CharT>(__dest); -#endif - return string_type(); - } - }; - - template - locale::id messages<_CharT>::id; - - // Specializations for required instantiations. - template<> - string - messages::do_get(catalog, int, int, const string&) const; - -#ifdef _GLIBCXX_USE_WCHAR_T - template<> - wstring - messages::do_get(catalog, int, int, const wstring&) const; -#endif - - /// @brief class messages_byname [22.2.7.2]. - template - class messages_byname : public messages<_CharT> - { - public: - typedef _CharT char_type; - typedef basic_string<_CharT> string_type; - - explicit - messages_byname(const char* __s, size_t __refs = 0); - - protected: - virtual - ~messages_byname() - { } - }; - -_GLIBCXX_END_NAMESPACE - - // Include host and configuration specific messages functions. - #include - -_GLIBCXX_BEGIN_NAMESPACE(std) - // Subclause convenience interfaces, inlines. // NB: These are inline because, when used in a loop, some compilers // can hoist the body out of the loop; then it's just as fast as the diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index a53f2643501..d0b0a96fadc 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -39,10 +39,6 @@ #pragma GCC system_header -#include -#include -#include - _GLIBCXX_BEGIN_NAMESPACE(std) template @@ -154,34 +150,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std) } }; - template - struct __use_cache<__moneypunct_cache<_CharT, _Intl> > - { - const __moneypunct_cache<_CharT, _Intl>* - operator() (const locale& __loc) const - { - const size_t __i = moneypunct<_CharT, _Intl>::id._M_id(); - const locale::facet** __caches = __loc._M_impl->_M_caches; - if (!__caches[__i]) - { - __moneypunct_cache<_CharT, _Intl>* __tmp = NULL; - try - { - __tmp = new __moneypunct_cache<_CharT, _Intl>; - __tmp->_M_cache(__loc); - } - catch(...) - { - delete __tmp; - __throw_exception_again; - } - __loc._M_impl->_M_install_cache(__tmp, __i); - } - return static_cast< - const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]); - } - }; - template void __numpunct_cache<_CharT>::_M_cache(const locale& __loc) @@ -217,50 +185,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std) __num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in); } - template - void - __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc) - { - _M_allocated = true; - - const moneypunct<_CharT, _Intl>& __mp = - use_facet >(__loc); - - _M_grouping_size = __mp.grouping().size(); - char* __grouping = new char[_M_grouping_size]; - __mp.grouping().copy(__grouping, _M_grouping_size); - _M_grouping = __grouping; - _M_use_grouping = (_M_grouping_size - && static_cast(__mp.grouping()[0]) > 0); - - _M_decimal_point = __mp.decimal_point(); - _M_thousands_sep = __mp.thousands_sep(); - _M_frac_digits = __mp.frac_digits(); - - _M_curr_symbol_size = __mp.curr_symbol().size(); - _CharT* __curr_symbol = new _CharT[_M_curr_symbol_size]; - __mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size); - _M_curr_symbol = __curr_symbol; - - _M_positive_sign_size = __mp.positive_sign().size(); - _CharT* __positive_sign = new _CharT[_M_positive_sign_size]; - __mp.positive_sign().copy(__positive_sign, _M_positive_sign_size); - _M_positive_sign = __positive_sign; - - _M_negative_sign_size = __mp.negative_sign().size(); - _CharT* __negative_sign = new _CharT[_M_negative_sign_size]; - __mp.negative_sign().copy(__negative_sign, _M_negative_sign_size); - _M_negative_sign = __negative_sign; - - _M_pos_format = __mp.pos_format(); - _M_neg_format = __mp.neg_format(); - - const ctype<_CharT>& __ct = use_facet >(__loc); - __ct.widen(money_base::_S_atoms, - money_base::_S_atoms + money_base::_S_end, _M_atoms); - } - - // 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 @@ -502,10 +426,6 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE return __beg; } -_GLIBCXX_END_LDBL_NAMESPACE - -_GLIBCXX_BEGIN_LDBL_NAMESPACE - template template _InIter @@ -1330,1064 +1250,8 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE return __s; } - template - template - _InIter - money_get<_CharT, _InIter>:: - _M_extract(iter_type __beg, iter_type __end, ios_base& __io, - ios_base::iostate& __err, string& __units) const - { - typedef char_traits<_CharT> __traits_type; - typedef typename string_type::size_type size_type; - typedef money_base::part part; - typedef __moneypunct_cache<_CharT, _Intl> __cache_type; - - const locale& __loc = __io._M_getloc(); - const ctype<_CharT>& __ctype = use_facet >(__loc); - - __use_cache<__cache_type> __uc; - const __cache_type* __lc = __uc(__loc); - const char_type* __lit = __lc->_M_atoms; - - // Deduced sign. - bool __negative = false; - // Sign size. - size_type __sign_size = 0; - // True if sign is mandatory. - const bool __mandatory_sign = (__lc->_M_positive_sign_size - && __lc->_M_negative_sign_size); - // String of grouping info from thousands_sep plucked from __units. - string __grouping_tmp; - if (__lc->_M_use_grouping) - __grouping_tmp.reserve(32); - // Last position before the decimal point. - int __last_pos = 0; - // Separator positions, then, possibly, fractional digits. - int __n = 0; - // If input iterator is in a valid state. - bool __testvalid = true; - // Flag marking when a decimal point is found. - bool __testdecfound = false; - - // The tentative returned string is stored here. - string __res; - __res.reserve(32); - - const char_type* __lit_zero = __lit + money_base::_S_zero; - const money_base::pattern __p = __lc->_M_neg_format; - for (int __i = 0; __i < 4 && __testvalid; ++__i) - { - const part __which = static_cast(__p.field[__i]); - switch (__which) - { - case money_base::symbol: - // According to 22.2.6.1.2, p2, symbol is required - // if (__io.flags() & ios_base::showbase), otherwise - // is optional and consumed only if other characters - // are needed to complete the format. - if (__io.flags() & ios_base::showbase || __sign_size > 1 - || __i == 0 - || (__i == 1 && (__mandatory_sign - || (static_cast(__p.field[0]) - == money_base::sign) - || (static_cast(__p.field[2]) - == money_base::space))) - || (__i == 2 && ((static_cast(__p.field[3]) - == money_base::value) - || (__mandatory_sign - && (static_cast(__p.field[3]) - == money_base::sign))))) - { - const size_type __len = __lc->_M_curr_symbol_size; - size_type __j = 0; - for (; __beg != __end && __j < __len - && *__beg == __lc->_M_curr_symbol[__j]; - ++__beg, ++__j); - if (__j != __len - && (__j || __io.flags() & ios_base::showbase)) - __testvalid = false; - } - break; - case money_base::sign: - // Sign might not exist, or be more than one character long. - if (__lc->_M_positive_sign_size && __beg != __end - && *__beg == __lc->_M_positive_sign[0]) - { - __sign_size = __lc->_M_positive_sign_size; - ++__beg; - } - else if (__lc->_M_negative_sign_size && __beg != __end - && *__beg == __lc->_M_negative_sign[0]) - { - __negative = true; - __sign_size = __lc->_M_negative_sign_size; - ++__beg; - } - else if (__lc->_M_positive_sign_size - && !__lc->_M_negative_sign_size) - // "... if no sign is detected, the result is given the sign - // that corresponds to the source of the empty string" - __negative = true; - else if (__mandatory_sign) - __testvalid = false; - break; - case money_base::value: - // Extract digits, remove and stash away the - // grouping of found thousands separators. - for (; __beg != __end; ++__beg) - { - const char_type __c = *__beg; - const char_type* __q = __traits_type::find(__lit_zero, - 10, __c); - if (__q != 0) - { - __res += money_base::_S_atoms[__q - __lit]; - ++__n; - } - else if (__c == __lc->_M_decimal_point - && !__testdecfound) - { - __last_pos = __n; - __n = 0; - __testdecfound = true; - } - else if (__lc->_M_use_grouping - && __c == __lc->_M_thousands_sep - && !__testdecfound) - { - if (__n) - { - // Mark position for later analysis. - __grouping_tmp += static_cast(__n); - __n = 0; - } - else - { - __testvalid = false; - break; - } - } - else - break; - } - if (__res.empty()) - __testvalid = false; - break; - case money_base::space: - // At least one space is required. - if (__beg != __end && __ctype.is(ctype_base::space, *__beg)) - ++__beg; - else - __testvalid = false; - case money_base::none: - // Only if not at the end of the pattern. - if (__i != 3) - for (; __beg != __end - && __ctype.is(ctype_base::space, *__beg); ++__beg); - break; - } - } - - // Need to get the rest of the sign characters, if they exist. - if (__sign_size > 1 && __testvalid) - { - const char_type* __sign = __negative ? __lc->_M_negative_sign - : __lc->_M_positive_sign; - size_type __i = 1; - for (; __beg != __end && __i < __sign_size - && *__beg == __sign[__i]; ++__beg, ++__i); - - if (__i != __sign_size) - __testvalid = false; - } - - if (__testvalid) - { - // Strip leading zeros. - if (__res.size() > 1) - { - const size_type __first = __res.find_first_not_of('0'); - const bool __only_zeros = __first == string::npos; - if (__first) - __res.erase(0, __only_zeros ? __res.size() - 1 : __first); - } - - // 22.2.6.1.2, p4 - if (__negative && __res[0] != '0') - __res.insert(__res.begin(), '-'); - - // Test for grouping fidelity. - if (__grouping_tmp.size()) - { - // Add the ending grouping. - __grouping_tmp += static_cast(__testdecfound ? __last_pos - : __n); - if (!std::__verify_grouping(__lc->_M_grouping, - __lc->_M_grouping_size, - __grouping_tmp)) - __err |= ios_base::failbit; - } - - // Iff not enough digits were supplied after the decimal-point. - if (__testdecfound && __lc->_M_frac_digits > 0 - && __n != __lc->_M_frac_digits) - __testvalid = false; - } - - // Iff valid sequence is not recognized. - if (!__testvalid) - __err |= ios_base::failbit; - else - __units.swap(__res); - - // Iff no more characters are available. - if (__beg == __end) - __err |= ios_base::eofbit; - return __beg; - } - -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ - template - _InIter - money_get<_CharT, _InIter>:: - __do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, - ios_base::iostate& __err, double& __units) const - { - string __str; - __beg = __intl ? _M_extract(__beg, __end, __io, __err, __str) - : _M_extract(__beg, __end, __io, __err, __str); - std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); - return __beg; - } -#endif - - template - _InIter - money_get<_CharT, _InIter>:: - do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, - ios_base::iostate& __err, long double& __units) const - { - string __str; - __beg = __intl ? _M_extract(__beg, __end, __io, __err, __str) - : _M_extract(__beg, __end, __io, __err, __str); - std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); - return __beg; - } - - template - _InIter - money_get<_CharT, _InIter>:: - do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, - ios_base::iostate& __err, string_type& __digits) const - { - typedef typename string::size_type size_type; - - const locale& __loc = __io._M_getloc(); - const ctype<_CharT>& __ctype = use_facet >(__loc); - - string __str; - __beg = __intl ? _M_extract(__beg, __end, __io, __err, __str) - : _M_extract(__beg, __end, __io, __err, __str); - const size_type __len = __str.size(); - if (__len) - { - __digits.resize(__len); - __ctype.widen(__str.data(), __str.data() + __len, &__digits[0]); - } - return __beg; - } - - template - template - _OutIter - money_put<_CharT, _OutIter>:: - _M_insert(iter_type __s, ios_base& __io, char_type __fill, - const string_type& __digits) const - { - typedef typename string_type::size_type size_type; - typedef money_base::part part; - typedef __moneypunct_cache<_CharT, _Intl> __cache_type; - - const locale& __loc = __io._M_getloc(); - const ctype<_CharT>& __ctype = use_facet >(__loc); - - __use_cache<__cache_type> __uc; - const __cache_type* __lc = __uc(__loc); - const char_type* __lit = __lc->_M_atoms; - - // Determine if negative or positive formats are to be used, and - // discard leading negative_sign if it is present. - const char_type* __beg = __digits.data(); - - money_base::pattern __p; - const char_type* __sign; - size_type __sign_size; - if (!(*__beg == __lit[money_base::_S_minus])) - { - __p = __lc->_M_pos_format; - __sign = __lc->_M_positive_sign; - __sign_size = __lc->_M_positive_sign_size; - } - else - { - __p = __lc->_M_neg_format; - __sign = __lc->_M_negative_sign; - __sign_size = __lc->_M_negative_sign_size; - if (__digits.size()) - ++__beg; - } - - // Look for valid numbers in the ctype facet within input digits. - size_type __len = __ctype.scan_not(ctype_base::digit, __beg, - __beg + __digits.size()) - __beg; - if (__len) - { - // Assume valid input, and attempt to format. - // Break down input numbers into base components, as follows: - // final_value = grouped units + (decimal point) + (digits) - string_type __value; - __value.reserve(2 * __len); - - // Add thousands separators to non-decimal digits, per - // grouping rules. - long __paddec = __len - __lc->_M_frac_digits; - if (__paddec > 0) - { - if (__lc->_M_frac_digits < 0) - __paddec = __len; - if (__lc->_M_grouping_size) - { - __value.assign(2 * __paddec, char_type()); - _CharT* __vend = - std::__add_grouping(&__value[0], __lc->_M_thousands_sep, - __lc->_M_grouping, - __lc->_M_grouping_size, - __beg, __beg + __paddec); - __value.erase(__vend - &__value[0]); - } - else - __value.assign(__beg, __paddec); - } - - // Deal with decimal point, decimal digits. - if (__lc->_M_frac_digits > 0) - { - __value += __lc->_M_decimal_point; - if (__paddec >= 0) - __value.append(__beg + __paddec, __lc->_M_frac_digits); - else - { - // Have to pad zeros in the decimal position. - __value.append(-__paddec, __lit[money_base::_S_zero]); - __value.append(__beg, __len); - } - } - - // Calculate length of resulting string. - const ios_base::fmtflags __f = __io.flags() - & ios_base::adjustfield; - __len = __value.size() + __sign_size; - __len += ((__io.flags() & ios_base::showbase) - ? __lc->_M_curr_symbol_size : 0); - - string_type __res; - __res.reserve(2 * __len); - - const size_type __width = static_cast(__io.width()); - const bool __testipad = (__f == ios_base::internal - && __len < __width); - // Fit formatted digits into the required pattern. - for (int __i = 0; __i < 4; ++__i) - { - const part __which = static_cast(__p.field[__i]); - switch (__which) - { - case money_base::symbol: - if (__io.flags() & ios_base::showbase) - __res.append(__lc->_M_curr_symbol, - __lc->_M_curr_symbol_size); - break; - case money_base::sign: - // Sign might not exist, or be more than one - // charater long. In that case, add in the rest - // below. - if (__sign_size) - __res += __sign[0]; - break; - case money_base::value: - __res += __value; - break; - case money_base::space: - // At least one space is required, but if internal - // formatting is required, an arbitrary number of - // fill spaces will be necessary. - if (__testipad) - __res.append(__width - __len, __fill); - else - __res += __fill; - break; - case money_base::none: - if (__testipad) - __res.append(__width - __len, __fill); - break; - } - } - - // Special case of multi-part sign parts. - if (__sign_size > 1) - __res.append(__sign + 1, __sign_size - 1); - - // Pad, if still necessary. - __len = __res.size(); - if (__width > __len) - { - if (__f == ios_base::left) - // After. - __res.append(__width - __len, __fill); - else - // Before. - __res.insert(0, __width - __len, __fill); - __len = __width; - } - - // Write resulting, fully-formatted string to output iterator. - __s = std::__write(__s, __res.data(), __len); - } - __io.width(0); - return __s; - } - -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ - template - _OutIter - money_put<_CharT, _OutIter>:: - __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, - double __units) const - { return this->do_put(__s, __intl, __io, __fill, (long double) __units); } -#endif - - template - _OutIter - money_put<_CharT, _OutIter>:: - do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, - long double __units) const - { - const locale __loc = __io.getloc(); - const ctype<_CharT>& __ctype = use_facet >(__loc); -#ifdef _GLIBCXX_USE_C99 - // First try a buffer perhaps big enough. - int __cs_size = 64; - char* __cs = static_cast(__builtin_alloca(__cs_size)); - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 328. Bad sprintf format modifier in money_put<>::do_put() - int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, - "%.*Lf", 0, __units); - // 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 = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, - "%.*Lf", 0, __units); - } -#else - // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'. - const int __cs_size = - __gnu_cxx::__numeric_traits::__max_exponent10 + 3; - char* __cs = static_cast(__builtin_alloca(__cs_size)); - int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf", - 0, __units); -#endif - string_type __digits(__len, char_type()); - __ctype.widen(__cs, __cs + __len, &__digits[0]); - return __intl ? _M_insert(__s, __io, __fill, __digits) - : _M_insert(__s, __io, __fill, __digits); - } - - template - _OutIter - money_put<_CharT, _OutIter>:: - do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, - const string_type& __digits) const - { return __intl ? _M_insert(__s, __io, __fill, __digits) - : _M_insert(__s, __io, __fill, __digits); } - _GLIBCXX_END_LDBL_NAMESPACE - // NB: Not especially useful. Without an ios_base object or some - // kind of locale reference, we are left clawing at the air where - // the side of the mountain used to be... - template - time_base::dateorder - time_get<_CharT, _InIter>::do_date_order() const - { return time_base::no_order; } - - // Expand a strftime format string and parse it. E.g., do_get_date() may - // pass %m/%d/%Y => extracted characters. - template - _InIter - time_get<_CharT, _InIter>:: - _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, - ios_base::iostate& __err, tm* __tm, - const _CharT* __format) const - { - const locale& __loc = __io._M_getloc(); - const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); - const ctype<_CharT>& __ctype = use_facet >(__loc); - const size_t __len = char_traits<_CharT>::length(__format); - - ios_base::iostate __tmperr = ios_base::goodbit; - for (size_t __i = 0; __beg != __end && __i < __len && !__tmperr; ++__i) - { - if (__ctype.narrow(__format[__i], 0) == '%') - { - // Verify valid formatting code, attempt to extract. - char __c = __ctype.narrow(__format[++__i], 0); - int __mem = 0; - if (__c == 'E' || __c == 'O') - __c = __ctype.narrow(__format[++__i], 0); - switch (__c) - { - const char* __cs; - _CharT __wcs[10]; - case 'a': - // Abbreviated weekday name [tm_wday] - const char_type* __days1[7]; - __tp._M_days_abbreviated(__days1); - __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days1, - 7, __io, __tmperr); - break; - case 'A': - // Weekday name [tm_wday]. - const char_type* __days2[7]; - __tp._M_days(__days2); - __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days2, - 7, __io, __tmperr); - break; - case 'h': - case 'b': - // Abbreviated month name [tm_mon] - const char_type* __months1[12]; - __tp._M_months_abbreviated(__months1); - __beg = _M_extract_name(__beg, __end, __tm->tm_mon, - __months1, 12, __io, __tmperr); - break; - case 'B': - // Month name [tm_mon]. - const char_type* __months2[12]; - __tp._M_months(__months2); - __beg = _M_extract_name(__beg, __end, __tm->tm_mon, - __months2, 12, __io, __tmperr); - break; - case 'c': - // Default time and date representation. - const char_type* __dt[2]; - __tp._M_date_time_formats(__dt); - __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, - __tm, __dt[0]); - break; - case 'd': - // Day [01, 31]. [tm_mday] - __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2, - __io, __tmperr); - break; - case 'e': - // Day [1, 31], with single digits preceded by - // space. [tm_mday] - if (__ctype.is(ctype_base::space, *__beg)) - __beg = _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9, - 1, __io, __tmperr); - else - __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31, - 2, __io, __tmperr); - break; - case 'D': - // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year] - __cs = "%m/%d/%y"; - __ctype.widen(__cs, __cs + 9, __wcs); - __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, - __tm, __wcs); - break; - case 'H': - // Hour [00, 23]. [tm_hour] - __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2, - __io, __tmperr); - break; - case 'I': - // Hour [01, 12]. [tm_hour] - __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2, - __io, __tmperr); - break; - case 'm': - // Month [01, 12]. [tm_mon] - __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, - __io, __tmperr); - if (!__tmperr) - __tm->tm_mon = __mem - 1; - break; - case 'M': - // Minute [00, 59]. [tm_min] - __beg = _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2, - __io, __tmperr); - break; - case 'n': - if (__ctype.narrow(*__beg, 0) == '\n') - ++__beg; - else - __tmperr |= ios_base::failbit; - break; - case 'R': - // Equivalent to (%H:%M). - __cs = "%H:%M"; - __ctype.widen(__cs, __cs + 6, __wcs); - __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, - __tm, __wcs); - break; - case 'S': - // Seconds. [tm_sec] - // [00, 60] in C99 (one leap-second), [00, 61] in C89. -#ifdef _GLIBCXX_USE_C99 - __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 60, 2, -#else - __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 61, 2, -#endif - __io, __tmperr); - break; - case 't': - if (__ctype.narrow(*__beg, 0) == '\t') - ++__beg; - else - __tmperr |= ios_base::failbit; - break; - case 'T': - // Equivalent to (%H:%M:%S). - __cs = "%H:%M:%S"; - __ctype.widen(__cs, __cs + 9, __wcs); - __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, - __tm, __wcs); - break; - case 'x': - // Locale's date. - const char_type* __dates[2]; - __tp._M_date_formats(__dates); - __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, - __tm, __dates[0]); - break; - case 'X': - // Locale's time. - const char_type* __times[2]; - __tp._M_time_formats(__times); - __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, - __tm, __times[0]); - break; - case 'y': - case 'C': // C99 - // Two digit year. [tm_year] - __beg = _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2, - __io, __tmperr); - break; - case 'Y': - // Year [1900). [tm_year] - __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4, - __io, __tmperr); - if (!__tmperr) - __tm->tm_year = __mem - 1900; - break; - case 'Z': - // Timezone info. - if (__ctype.is(ctype_base::upper, *__beg)) - { - int __tmp; - __beg = _M_extract_name(__beg, __end, __tmp, - __timepunct_cache<_CharT>::_S_timezones, - 14, __io, __tmperr); - - // GMT requires special effort. - if (__beg != __end && !__tmperr && __tmp == 0 - && (*__beg == __ctype.widen('-') - || *__beg == __ctype.widen('+'))) - { - __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2, - __io, __tmperr); - __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2, - __io, __tmperr); - } - } - else - __tmperr |= ios_base::failbit; - break; - default: - // Not recognized. - __tmperr |= ios_base::failbit; - } - } - else - { - // Verify format and input match, extract and discard. - if (__format[__i] == *__beg) - ++__beg; - else - __tmperr |= ios_base::failbit; - } - } - - if (__tmperr) - __err |= ios_base::failbit; - - return __beg; - } - - template - _InIter - time_get<_CharT, _InIter>:: - _M_extract_num(iter_type __beg, iter_type __end, int& __member, - int __min, int __max, size_t __len, - ios_base& __io, ios_base::iostate& __err) const - { - const locale& __loc = __io._M_getloc(); - const ctype<_CharT>& __ctype = use_facet >(__loc); - - // As-is works for __len = 1, 2, 4, the values actually used. - int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1); - - ++__min; - size_t __i = 0; - int __value = 0; - for (; __beg != __end && __i < __len; ++__beg, ++__i) - { - const char __c = __ctype.narrow(*__beg, '*'); - if (__c >= '0' && __c <= '9') - { - __value = __value * 10 + (__c - '0'); - const int __valuec = __value * __mult; - if (__valuec > __max || __valuec + __mult < __min) - break; - __mult /= 10; - } - else - break; - } - if (__i == __len) - __member = __value; - else - __err |= ios_base::failbit; - - return __beg; - } - - // Assumptions: - // All elements in __names are unique. - template - _InIter - time_get<_CharT, _InIter>:: - _M_extract_name(iter_type __beg, iter_type __end, int& __member, - const _CharT** __names, size_t __indexlen, - ios_base& __io, ios_base::iostate& __err) const - { - typedef char_traits<_CharT> __traits_type; - const locale& __loc = __io._M_getloc(); - const ctype<_CharT>& __ctype = use_facet >(__loc); - - int* __matches = static_cast(__builtin_alloca(sizeof(int) - * __indexlen)); - size_t __nmatches = 0; - size_t __pos = 0; - bool __testvalid = true; - const char_type* __name; - - // Look for initial matches. - // NB: Some of the locale data is in the form of all lowercase - // names, and some is in the form of initially-capitalized - // names. Look for both. - if (__beg != __end) - { - const char_type __c = *__beg; - for (size_t __i1 = 0; __i1 < __indexlen; ++__i1) - if (__c == __names[__i1][0] - || __c == __ctype.toupper(__names[__i1][0])) - __matches[__nmatches++] = __i1; - } - - while (__nmatches > 1) - { - // Find smallest matching string. - size_t __minlen = __traits_type::length(__names[__matches[0]]); - for (size_t __i2 = 1; __i2 < __nmatches; ++__i2) - __minlen = std::min(__minlen, - __traits_type::length(__names[__matches[__i2]])); - ++__beg, ++__pos; - if (__pos < __minlen && __beg != __end) - for (size_t __i3 = 0; __i3 < __nmatches;) - { - __name = __names[__matches[__i3]]; - if (!(__name[__pos] == *__beg)) - __matches[__i3] = __matches[--__nmatches]; - else - ++__i3; - } - else - break; - } - - if (__nmatches == 1) - { - // Make sure found name is completely extracted. - ++__beg, ++__pos; - __name = __names[__matches[0]]; - const size_t __len = __traits_type::length(__name); - while (__pos < __len && __beg != __end && __name[__pos] == *__beg) - ++__beg, ++__pos; - - if (__len == __pos) - __member = __matches[0]; - else - __testvalid = false; - } - else - __testvalid = false; - if (!__testvalid) - __err |= ios_base::failbit; - - return __beg; - } - - template - _InIter - time_get<_CharT, _InIter>:: - do_get_time(iter_type __beg, iter_type __end, ios_base& __io, - ios_base::iostate& __err, tm* __tm) const - { - const locale& __loc = __io._M_getloc(); - const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); - const char_type* __times[2]; - __tp._M_time_formats(__times); - __beg = _M_extract_via_format(__beg, __end, __io, __err, - __tm, __times[0]); - if (__beg == __end) - __err |= ios_base::eofbit; - return __beg; - } - - template - _InIter - time_get<_CharT, _InIter>:: - do_get_date(iter_type __beg, iter_type __end, ios_base& __io, - ios_base::iostate& __err, tm* __tm) const - { - const locale& __loc = __io._M_getloc(); - const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); - const char_type* __dates[2]; - __tp._M_date_formats(__dates); - __beg = _M_extract_via_format(__beg, __end, __io, __err, - __tm, __dates[0]); - if (__beg == __end) - __err |= ios_base::eofbit; - return __beg; - } - - template - _InIter - time_get<_CharT, _InIter>:: - do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io, - ios_base::iostate& __err, tm* __tm) const - { - typedef char_traits<_CharT> __traits_type; - const locale& __loc = __io._M_getloc(); - const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); - const ctype<_CharT>& __ctype = use_facet >(__loc); - const char_type* __days[7]; - __tp._M_days_abbreviated(__days); - int __tmpwday; - ios_base::iostate __tmperr = ios_base::goodbit; - __beg = _M_extract_name(__beg, __end, __tmpwday, __days, 7, - __io, __tmperr); - - // Check to see if non-abbreviated name exists, and extract. - // NB: Assumes both _M_days and _M_days_abbreviated organized in - // exact same order, first to last, such that the resulting - // __days array with the same index points to a day, and that - // day's abbreviated form. - // NB: Also assumes that an abbreviated name is a subset of the name. - if (!__tmperr && __beg != __end) - { - size_t __pos = __traits_type::length(__days[__tmpwday]); - __tp._M_days(__days); - const char_type* __name = __days[__tmpwday]; - if (__name[__pos] == *__beg) - { - // Extract the rest of it. - const size_t __len = __traits_type::length(__name); - while (__pos < __len && __beg != __end - && __name[__pos] == *__beg) - ++__beg, ++__pos; - if (__len != __pos) - __tmperr |= ios_base::failbit; - } - } - if (!__tmperr) - __tm->tm_wday = __tmpwday; - else - __err |= ios_base::failbit; - - if (__beg == __end) - __err |= ios_base::eofbit; - return __beg; - } - - template - _InIter - time_get<_CharT, _InIter>:: - do_get_monthname(iter_type __beg, iter_type __end, - ios_base& __io, ios_base::iostate& __err, tm* __tm) const - { - typedef char_traits<_CharT> __traits_type; - const locale& __loc = __io._M_getloc(); - const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); - const ctype<_CharT>& __ctype = use_facet >(__loc); - const char_type* __months[12]; - __tp._M_months_abbreviated(__months); - int __tmpmon; - ios_base::iostate __tmperr = ios_base::goodbit; - __beg = _M_extract_name(__beg, __end, __tmpmon, __months, 12, - __io, __tmperr); - - // Check to see if non-abbreviated name exists, and extract. - // NB: Assumes both _M_months and _M_months_abbreviated organized in - // exact same order, first to last, such that the resulting - // __months array with the same index points to a month, and that - // month's abbreviated form. - // NB: Also assumes that an abbreviated name is a subset of the name. - if (!__tmperr && __beg != __end) - { - size_t __pos = __traits_type::length(__months[__tmpmon]); - __tp._M_months(__months); - const char_type* __name = __months[__tmpmon]; - if (__name[__pos] == *__beg) - { - // Extract the rest of it. - const size_t __len = __traits_type::length(__name); - while (__pos < __len && __beg != __end - && __name[__pos] == *__beg) - ++__beg, ++__pos; - if (__len != __pos) - __tmperr |= ios_base::failbit; - } - } - if (!__tmperr) - __tm->tm_mon = __tmpmon; - else - __err |= ios_base::failbit; - - if (__beg == __end) - __err |= ios_base::eofbit; - return __beg; - } - - template - _InIter - time_get<_CharT, _InIter>:: - do_get_year(iter_type __beg, iter_type __end, ios_base& __io, - ios_base::iostate& __err, tm* __tm) const - { - const locale& __loc = __io._M_getloc(); - const ctype<_CharT>& __ctype = use_facet >(__loc); - - size_t __i = 0; - int __value = 0; - for (; __beg != __end && __i < 4; ++__beg, ++__i) - { - const char __c = __ctype.narrow(*__beg, '*'); - if (__c >= '0' && __c <= '9') - __value = __value * 10 + (__c - '0'); - else - break; - } - if (__i == 2 || __i == 4) - __tm->tm_year = __i == 2 ? __value : __value - 1900; - else - __err |= ios_base::failbit; - - if (__beg == __end) - __err |= ios_base::eofbit; - return __beg; - } - - template - _OutIter - time_put<_CharT, _OutIter>:: - put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, - const _CharT* __beg, const _CharT* __end) const - { - const locale& __loc = __io._M_getloc(); - ctype<_CharT> const& __ctype = use_facet >(__loc); - for (; __beg != __end; ++__beg) - if (__ctype.narrow(*__beg, 0) != '%') - { - *__s = *__beg; - ++__s; - } - else if (++__beg != __end) - { - char __format; - char __mod = 0; - const char __c = __ctype.narrow(*__beg, 0); - if (__c != 'E' && __c != 'O') - __format = __c; - else if (++__beg != __end) - { - __mod = __c; - __format = __ctype.narrow(*__beg, 0); - } - else - break; - __s = this->do_put(__s, __io, __fill, __tm, __format, __mod); - } - else - break; - return __s; - } - - template - _OutIter - time_put<_CharT, _OutIter>:: - do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, - char __format, char __mod) const - { - const locale& __loc = __io._M_getloc(); - ctype<_CharT> const& __ctype = use_facet >(__loc); - __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); - - // NB: This size is arbitrary. Should this be a data member, - // initialized at construction? - const size_t __maxlen = 128; - char_type* __res = - static_cast(__builtin_alloca(sizeof(char_type) * __maxlen)); - - // NB: In IEE 1003.1-200x, and perhaps other locale models, it - // is possible that the format character will be longer than one - // character. Possibilities include 'E' or 'O' followed by a - // format character: if __mod is not the default argument, assume - // it's a valid modifier. - char_type __fmt[4]; - __fmt[0] = __ctype.widen('%'); - if (!__mod) - { - __fmt[1] = __format; - __fmt[2] = char_type(); - } - else - { - __fmt[1] = __mod; - __fmt[2] = __format; - __fmt[3] = char_type(); - } - - __tp._M_put(__res, __maxlen, __fmt, __tm); - - // Write resulting, fully-formatted string to output iterator. - return std::__write(__s, __res, char_traits::length(__res)); - } - // Generic version does nothing. template int @@ -2633,23 +1497,10 @@ _GLIBCXX_END_LDBL_NAMESPACE // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. #if _GLIBCXX_EXTERN_TEMPLATE - extern template class moneypunct; - extern template class moneypunct; - extern template class moneypunct_byname; - extern template class moneypunct_byname; - extern template class _GLIBCXX_LDBL_NAMESPACE money_get; - extern template class _GLIBCXX_LDBL_NAMESPACE money_put; extern template class numpunct; extern template class numpunct_byname; extern template class _GLIBCXX_LDBL_NAMESPACE num_get; extern template class _GLIBCXX_LDBL_NAMESPACE num_put; - extern template class __timepunct; - extern template class time_put; - extern template class time_put_byname; - extern template class time_get; - extern template class time_get_byname; - extern template class messages; - extern template class messages_byname; extern template class ctype_byname; extern template class codecvt_byname; extern template class collate; @@ -2676,38 +1527,6 @@ _GLIBCXX_END_LDBL_NAMESPACE use_facet >(const locale&); extern template - const moneypunct& - use_facet >(const locale&); - - extern template - const moneypunct& - use_facet >(const locale&); - - extern template - const money_put& - use_facet >(const locale&); - - extern template - const money_get& - use_facet >(const locale&); - - extern template - const __timepunct& - use_facet<__timepunct >(const locale&); - - extern template - const time_put& - use_facet >(const locale&); - - extern template - const time_get& - use_facet >(const locale&); - - extern template - const messages& - use_facet >(const locale&); - - extern template bool has_facet >(const locale&); @@ -2731,52 +1550,11 @@ _GLIBCXX_END_LDBL_NAMESPACE bool has_facet >(const locale&); - extern template - bool - has_facet >(const locale&); - - extern template - bool - has_facet >(const locale&); - - extern template - bool - has_facet >(const locale&); - - extern template - bool - has_facet<__timepunct >(const locale&); - - extern template - bool - has_facet >(const locale&); - - extern template - bool - has_facet >(const locale&); - - extern template - bool - has_facet >(const locale&); - #ifdef _GLIBCXX_USE_WCHAR_T - extern template class moneypunct; - extern template class moneypunct; - extern template class moneypunct_byname; - extern template class moneypunct_byname; - extern template class _GLIBCXX_LDBL_NAMESPACE money_get; - extern template class _GLIBCXX_LDBL_NAMESPACE money_put; extern template class numpunct; extern template class numpunct_byname; extern template class _GLIBCXX_LDBL_NAMESPACE num_get; extern template class _GLIBCXX_LDBL_NAMESPACE num_put; - extern template class __timepunct; - extern template class time_put; - extern template class time_put_byname; - extern template class time_get; - extern template class time_get_byname; - extern template class messages; - extern template class messages_byname; extern template class ctype_byname; extern template class codecvt_byname; extern template class collate; @@ -2802,38 +1580,6 @@ _GLIBCXX_END_LDBL_NAMESPACE const num_get& use_facet >(const locale&); - extern template - const moneypunct& - use_facet >(const locale&); - - extern template - const moneypunct& - use_facet >(const locale&); - - extern template - const money_put& - use_facet >(const locale&); - - extern template - const money_get& - use_facet >(const locale&); - - extern template - const __timepunct& - use_facet<__timepunct >(const locale&); - - extern template - const time_put& - use_facet >(const locale&); - - extern template - const time_get& - use_facet >(const locale&); - - extern template - const messages& - use_facet >(const locale&); - extern template bool has_facet >(const locale&); @@ -2857,34 +1603,6 @@ _GLIBCXX_END_LDBL_NAMESPACE extern template bool has_facet >(const locale&); - - extern template - bool - has_facet >(const locale&); - - extern template - bool - has_facet >(const locale&); - - extern template - bool - has_facet >(const locale&); - - extern template - bool - has_facet<__timepunct >(const locale&); - - extern template - bool - has_facet >(const locale&); - - extern template - bool - has_facet >(const locale&); - - extern template - bool - has_facet >(const locale&); #endif #endif diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.h b/libstdc++-v3/include/bits/locale_facets_nonio.h new file mode 100644 index 00000000000..1fee4553bc6 --- /dev/null +++ b/libstdc++-v3/include/bits/locale_facets_nonio.h @@ -0,0 +1,1909 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 2007 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file locale_facets_nonio.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +// +// ISO C++ 14882: 22.1 Locales +// + +#ifndef _LOCALE_FACETS_NONIO_H +#define _LOCALE_FACETS_NONIO_H 1 + +#include // For struct tm + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @brief Time format ordering data. + * + * This class provides an enum representing different orderings of day, + * month, and year. + */ + class time_base + { + public: + enum dateorder { no_order, dmy, mdy, ymd, ydm }; + }; + + template + struct __timepunct_cache : public locale::facet + { + // List of all known timezones, with GMT first. + static const _CharT* _S_timezones[14]; + + const _CharT* _M_date_format; + const _CharT* _M_date_era_format; + const _CharT* _M_time_format; + const _CharT* _M_time_era_format; + const _CharT* _M_date_time_format; + const _CharT* _M_date_time_era_format; + const _CharT* _M_am; + const _CharT* _M_pm; + const _CharT* _M_am_pm_format; + + // Day names, starting with "C"'s Sunday. + const _CharT* _M_day1; + const _CharT* _M_day2; + const _CharT* _M_day3; + const _CharT* _M_day4; + const _CharT* _M_day5; + const _CharT* _M_day6; + const _CharT* _M_day7; + + // Abbreviated day names, starting with "C"'s Sun. + const _CharT* _M_aday1; + const _CharT* _M_aday2; + const _CharT* _M_aday3; + const _CharT* _M_aday4; + const _CharT* _M_aday5; + const _CharT* _M_aday6; + const _CharT* _M_aday7; + + // Month names, starting with "C"'s January. + const _CharT* _M_month01; + const _CharT* _M_month02; + const _CharT* _M_month03; + const _CharT* _M_month04; + const _CharT* _M_month05; + const _CharT* _M_month06; + const _CharT* _M_month07; + const _CharT* _M_month08; + const _CharT* _M_month09; + const _CharT* _M_month10; + const _CharT* _M_month11; + const _CharT* _M_month12; + + // Abbreviated month names, starting with "C"'s Jan. + const _CharT* _M_amonth01; + const _CharT* _M_amonth02; + const _CharT* _M_amonth03; + const _CharT* _M_amonth04; + const _CharT* _M_amonth05; + const _CharT* _M_amonth06; + const _CharT* _M_amonth07; + const _CharT* _M_amonth08; + const _CharT* _M_amonth09; + const _CharT* _M_amonth10; + const _CharT* _M_amonth11; + const _CharT* _M_amonth12; + + bool _M_allocated; + + __timepunct_cache(size_t __refs = 0) : facet(__refs), + _M_date_format(NULL), _M_date_era_format(NULL), _M_time_format(NULL), + _M_time_era_format(NULL), _M_date_time_format(NULL), + _M_date_time_era_format(NULL), _M_am(NULL), _M_pm(NULL), + _M_am_pm_format(NULL), _M_day1(NULL), _M_day2(NULL), _M_day3(NULL), + _M_day4(NULL), _M_day5(NULL), _M_day6(NULL), _M_day7(NULL), + _M_aday1(NULL), _M_aday2(NULL), _M_aday3(NULL), _M_aday4(NULL), + _M_aday5(NULL), _M_aday6(NULL), _M_aday7(NULL), _M_month01(NULL), + _M_month02(NULL), _M_month03(NULL), _M_month04(NULL), _M_month05(NULL), + _M_month06(NULL), _M_month07(NULL), _M_month08(NULL), _M_month09(NULL), + _M_month10(NULL), _M_month11(NULL), _M_month12(NULL), _M_amonth01(NULL), + _M_amonth02(NULL), _M_amonth03(NULL), _M_amonth04(NULL), + _M_amonth05(NULL), _M_amonth06(NULL), _M_amonth07(NULL), + _M_amonth08(NULL), _M_amonth09(NULL), _M_amonth10(NULL), + _M_amonth11(NULL), _M_amonth12(NULL), _M_allocated(false) + { } + + ~__timepunct_cache(); + + void + _M_cache(const locale& __loc); + + private: + __timepunct_cache& + operator=(const __timepunct_cache&); + + explicit + __timepunct_cache(const __timepunct_cache&); + }; + + template + __timepunct_cache<_CharT>::~__timepunct_cache() + { + if (_M_allocated) + { + // Unused. + } + } + + // Specializations. + template<> + const char* + __timepunct_cache::_S_timezones[14]; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + const wchar_t* + __timepunct_cache::_S_timezones[14]; +#endif + + // Generic. + template + const _CharT* __timepunct_cache<_CharT>::_S_timezones[14]; + + template + class __timepunct : public locale::facet + { + public: + // Types: + typedef _CharT __char_type; + typedef basic_string<_CharT> __string_type; + typedef __timepunct_cache<_CharT> __cache_type; + + protected: + __cache_type* _M_data; + __c_locale _M_c_locale_timepunct; + const char* _M_name_timepunct; + + public: + /// Numpunct facet id. + static locale::id id; + + explicit + __timepunct(size_t __refs = 0); + + explicit + __timepunct(__cache_type* __cache, size_t __refs = 0); + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param s The name of a locale. + * @param refs Passed to the base facet class. + */ + explicit + __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0); + + // FIXME: for error checking purposes _M_put should return the return + // value of strftime/wcsftime. + void + _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format, + const tm* __tm) const; + + void + _M_date_formats(const _CharT** __date) const + { + // Always have default first. + __date[0] = _M_data->_M_date_format; + __date[1] = _M_data->_M_date_era_format; + } + + void + _M_time_formats(const _CharT** __time) const + { + // Always have default first. + __time[0] = _M_data->_M_time_format; + __time[1] = _M_data->_M_time_era_format; + } + + void + _M_date_time_formats(const _CharT** __dt) const + { + // Always have default first. + __dt[0] = _M_data->_M_date_time_format; + __dt[1] = _M_data->_M_date_time_era_format; + } + + void + _M_am_pm_format(const _CharT* __ampm) const + { __ampm = _M_data->_M_am_pm_format; } + + void + _M_am_pm(const _CharT** __ampm) const + { + __ampm[0] = _M_data->_M_am; + __ampm[1] = _M_data->_M_pm; + } + + void + _M_days(const _CharT** __days) const + { + __days[0] = _M_data->_M_day1; + __days[1] = _M_data->_M_day2; + __days[2] = _M_data->_M_day3; + __days[3] = _M_data->_M_day4; + __days[4] = _M_data->_M_day5; + __days[5] = _M_data->_M_day6; + __days[6] = _M_data->_M_day7; + } + + void + _M_days_abbreviated(const _CharT** __days) const + { + __days[0] = _M_data->_M_aday1; + __days[1] = _M_data->_M_aday2; + __days[2] = _M_data->_M_aday3; + __days[3] = _M_data->_M_aday4; + __days[4] = _M_data->_M_aday5; + __days[5] = _M_data->_M_aday6; + __days[6] = _M_data->_M_aday7; + } + + void + _M_months(const _CharT** __months) const + { + __months[0] = _M_data->_M_month01; + __months[1] = _M_data->_M_month02; + __months[2] = _M_data->_M_month03; + __months[3] = _M_data->_M_month04; + __months[4] = _M_data->_M_month05; + __months[5] = _M_data->_M_month06; + __months[6] = _M_data->_M_month07; + __months[7] = _M_data->_M_month08; + __months[8] = _M_data->_M_month09; + __months[9] = _M_data->_M_month10; + __months[10] = _M_data->_M_month11; + __months[11] = _M_data->_M_month12; + } + + void + _M_months_abbreviated(const _CharT** __months) const + { + __months[0] = _M_data->_M_amonth01; + __months[1] = _M_data->_M_amonth02; + __months[2] = _M_data->_M_amonth03; + __months[3] = _M_data->_M_amonth04; + __months[4] = _M_data->_M_amonth05; + __months[5] = _M_data->_M_amonth06; + __months[6] = _M_data->_M_amonth07; + __months[7] = _M_data->_M_amonth08; + __months[8] = _M_data->_M_amonth09; + __months[9] = _M_data->_M_amonth10; + __months[10] = _M_data->_M_amonth11; + __months[11] = _M_data->_M_amonth12; + } + + protected: + virtual + ~__timepunct(); + + // For use at construction time only. + void + _M_initialize_timepunct(__c_locale __cloc = NULL); + }; + + template + locale::id __timepunct<_CharT>::id; + + // Specializations. + template<> + void + __timepunct::_M_initialize_timepunct(__c_locale __cloc); + + template<> + void + __timepunct::_M_put(char*, size_t, const char*, const tm*) const; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + void + __timepunct::_M_initialize_timepunct(__c_locale __cloc); + + template<> + void + __timepunct::_M_put(wchar_t*, size_t, const wchar_t*, + const tm*) const; +#endif + +_GLIBCXX_END_NAMESPACE + + // Include host and configuration specific timepunct functions. + #include + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @brief Facet for parsing dates and times. + * + * This facet encapsulates the code to parse and return a date or + * time from a string. It is used by the istream numeric + * extraction operators. + * + * The time_get template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from the time_get facet. + */ + template + class time_get : public locale::facet, public time_base + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _InIter iter_type; + //@} + typedef basic_string<_CharT> __string_type; + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + time_get(size_t __refs = 0) + : facet (__refs) { } + + /** + * @brief Return preferred order of month, day, and year. + * + * This function returns an enum from timebase::dateorder giving the + * preferred ordering if the format "x" given to time_put::put() only + * uses month, day, and year. If the format "x" for the associated + * locale uses other fields, this function returns + * timebase::dateorder::noorder. + * + * NOTE: The library always returns noorder at the moment. + * + * @return A member of timebase::dateorder. + */ + dateorder + date_order() const + { return this->do_date_order(); } + + /** + * @brief Parse input time string. + * + * This function parses a time according to the format "x" and puts the + * results into a user-supplied struct tm. The result is returned by + * calling time_get::do_get_time(). + * + * If there is a valid time string according to format "x", @a tm will + * be filled in accordingly and the returned iterator will point to the + * first character beyond the time string. If an error occurs before + * the end, err |= ios_base::failbit. If parsing reads all the + * characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond time string. + */ + iter_type + get_time(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_time(__beg, __end, __io, __err, __tm); } + + /** + * @brief Parse input date string. + * + * This function parses a date according to the format "X" and puts the + * results into a user-supplied struct tm. The result is returned by + * calling time_get::do_get_date(). + * + * If there is a valid date string according to format "X", @a tm will + * be filled in accordingly and the returned iterator will point to the + * first character beyond the date string. If an error occurs before + * the end, err |= ios_base::failbit. If parsing reads all the + * characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond date string. + */ + iter_type + get_date(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_date(__beg, __end, __io, __err, __tm); } + + /** + * @brief Parse input weekday string. + * + * This function parses a weekday name and puts the results into a + * user-supplied struct tm. The result is returned by calling + * time_get::do_get_weekday(). + * + * Parsing starts by parsing an abbreviated weekday name. If a valid + * abbreviation is followed by a character that would lead to the full + * weekday name, parsing continues until the full name is found or an + * error occurs. Otherwise parsing finishes at the end of the + * abbreviated name. + * + * If an error occurs before the end, err |= ios_base::failbit. If + * parsing reads all the characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond weekday name. + */ + iter_type + get_weekday(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_weekday(__beg, __end, __io, __err, __tm); } + + /** + * @brief Parse input month string. + * + * This function parses a month name and puts the results into a + * user-supplied struct tm. The result is returned by calling + * time_get::do_get_monthname(). + * + * Parsing starts by parsing an abbreviated month name. If a valid + * abbreviation is followed by a character that would lead to the full + * month name, parsing continues until the full name is found or an + * error occurs. Otherwise parsing finishes at the end of the + * abbreviated name. + * + * If an error occurs before the end, err |= ios_base::failbit. If + * parsing reads all the characters, err |= + * ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond month name. + */ + iter_type + get_monthname(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_monthname(__beg, __end, __io, __err, __tm); } + + /** + * @brief Parse input year string. + * + * This function reads up to 4 characters to parse a year string and + * puts the results into a user-supplied struct tm. The result is + * returned by calling time_get::do_get_year(). + * + * 4 consecutive digits are interpreted as a full year. If there are + * exactly 2 consecutive digits, the library interprets this as the + * number of years since 1900. + * + * If an error occurs before the end, err |= ios_base::failbit. If + * parsing reads all the characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond year. + */ + iter_type + get_year(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { return this->do_get_year(__beg, __end, __io, __err, __tm); } + + protected: + /// Destructor. + virtual + ~time_get() { } + + /** + * @brief Return preferred order of month, day, and year. + * + * This function returns an enum from timebase::dateorder giving the + * preferred ordering if the format "x" given to time_put::put() only + * uses month, day, and year. This function is a hook for derived + * classes to change the value returned. + * + * @return A member of timebase::dateorder. + */ + virtual dateorder + do_date_order() const; + + /** + * @brief Parse input time string. + * + * This function parses a time according to the format "x" and puts the + * results into a user-supplied struct tm. This function is a hook for + * derived classes to change the value returned. @see get_time() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond time string. + */ + virtual iter_type + do_get_time(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const; + + /** + * @brief Parse input date string. + * + * This function parses a date according to the format "X" and puts the + * results into a user-supplied struct tm. This function is a hook for + * derived classes to change the value returned. @see get_date() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond date string. + */ + virtual iter_type + do_get_date(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const; + + /** + * @brief Parse input weekday string. + * + * This function parses a weekday name and puts the results into a + * user-supplied struct tm. This function is a hook for derived + * classes to change the value returned. @see get_weekday() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond weekday name. + */ + virtual iter_type + do_get_weekday(iter_type __beg, iter_type __end, ios_base&, + ios_base::iostate& __err, tm* __tm) const; + + /** + * @brief Parse input month string. + * + * This function parses a month name and puts the results into a + * user-supplied struct tm. This function is a hook for derived + * classes to change the value returned. @see get_monthname() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond month name. + */ + virtual iter_type + do_get_monthname(iter_type __beg, iter_type __end, ios_base&, + ios_base::iostate& __err, tm* __tm) const; + + /** + * @brief Parse input year string. + * + * This function reads up to 4 characters to parse a year string and + * puts the results into a user-supplied struct tm. This function is a + * hook for derived classes to change the value returned. @see + * get_year() for details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond year. + */ + virtual iter_type + do_get_year(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const; + + // Extract numeric component of length __len. + iter_type + _M_extract_num(iter_type __beg, iter_type __end, int& __member, + int __min, int __max, size_t __len, + ios_base& __io, ios_base::iostate& __err) const; + + // Extract day or month name, or any unique array of string + // literals in a const _CharT* array. + iter_type + _M_extract_name(iter_type __beg, iter_type __end, int& __member, + const _CharT** __names, size_t __indexlen, + ios_base& __io, ios_base::iostate& __err) const; + + // Extract on a component-by-component basis, via __format argument. + iter_type + _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm, + const _CharT* __format) const; + }; + + template + locale::id time_get<_CharT, _InIter>::id; + + /// @brief class time_get_byname [22.2.5.2]. + template + class time_get_byname : public time_get<_CharT, _InIter> + { + public: + // Types: + typedef _CharT char_type; + typedef _InIter iter_type; + + explicit + time_get_byname(const char*, size_t __refs = 0) + : time_get<_CharT, _InIter>(__refs) { } + + protected: + virtual + ~time_get_byname() { } + }; + + /** + * @brief Facet for outputting dates and times. + * + * This facet encapsulates the code to format and output dates and times + * according to formats used by strftime(). + * + * The time_put template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from the time_put facet. + */ + template + class time_put : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _OutIter iter_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + time_put(size_t __refs = 0) + : facet(__refs) { } + + /** + * @brief Format and output a time or date. + * + * This function formats the data in struct tm according to the + * provided format string. The format string is interpreted as by + * strftime(). + * + * @param s The stream to write to. + * @param io Source of locale. + * @param fill char_type to use for padding. + * @param tm Struct tm with date and time info to format. + * @param beg Start of format string. + * @param end End of format string. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, + const _CharT* __beg, const _CharT* __end) const; + + /** + * @brief Format and output a time or date. + * + * This function formats the data in struct tm according to the + * provided format char and optional modifier. The format and modifier + * are interpreted as by strftime(). It does so by returning + * time_put::do_put(). + * + * @param s The stream to write to. + * @param io Source of locale. + * @param fill char_type to use for padding. + * @param tm Struct tm with date and time info to format. + * @param format Format char. + * @param mod Optional modifier char. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __io, char_type __fill, + const tm* __tm, char __format, char __mod = 0) const + { return this->do_put(__s, __io, __fill, __tm, __format, __mod); } + + protected: + /// Destructor. + virtual + ~time_put() + { } + + /** + * @brief Format and output a time or date. + * + * This function formats the data in struct tm according to the + * provided format char and optional modifier. This function is a hook + * for derived classes to change the value returned. @see put() for + * more details. + * + * @param s The stream to write to. + * @param io Source of locale. + * @param fill char_type to use for padding. + * @param tm Struct tm with date and time info to format. + * @param format Format char. + * @param mod Optional modifier char. + * @return Iterator after writing. + */ + virtual iter_type + do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, + char __format, char __mod) const; + }; + + template + locale::id time_put<_CharT, _OutIter>::id; + + /// @brief class time_put_byname [22.2.5.4]. + template + class time_put_byname : public time_put<_CharT, _OutIter> + { + public: + // Types: + typedef _CharT char_type; + typedef _OutIter iter_type; + + explicit + time_put_byname(const char*, size_t __refs = 0) + : time_put<_CharT, _OutIter>(__refs) + { }; + + protected: + virtual + ~time_put_byname() { } + }; + + + /** + * @brief Money format ordering data. + * + * This class contains an ordered array of 4 fields to represent the + * pattern for formatting a money amount. Each field may contain one entry + * from the part enum. symbol, sign, and value must be present and the + * remaining field must contain either none or space. @see + * moneypunct::pos_format() and moneypunct::neg_format() for details of how + * these fields are interpreted. + */ + class money_base + { + public: + enum part { none, space, symbol, sign, value }; + struct pattern { char field[4]; }; + + static const pattern _S_default_pattern; + + enum + { + _S_minus, + _S_zero, + _S_end = 11 + }; + + // String literal of acceptable (narrow) input/output, for + // money_get/money_put. "-0123456789" + static const char* _S_atoms; + + // Construct and return valid pattern consisting of some combination of: + // space none symbol sign value + static pattern + _S_construct_pattern(char __precedes, char __space, char __posn); + }; + + template + struct __moneypunct_cache : public locale::facet + { + const char* _M_grouping; + size_t _M_grouping_size; + bool _M_use_grouping; + _CharT _M_decimal_point; + _CharT _M_thousands_sep; + const _CharT* _M_curr_symbol; + size_t _M_curr_symbol_size; + const _CharT* _M_positive_sign; + size_t _M_positive_sign_size; + const _CharT* _M_negative_sign; + size_t _M_negative_sign_size; + int _M_frac_digits; + money_base::pattern _M_pos_format; + money_base::pattern _M_neg_format; + + // A list of valid numeric literals for input and output: in the standard + // "C" locale, this is "-0123456789". This array contains the chars after + // having been passed through the current locale's ctype<_CharT>.widen(). + _CharT _M_atoms[money_base::_S_end]; + + bool _M_allocated; + + __moneypunct_cache(size_t __refs = 0) : facet(__refs), + _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false), + _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()), + _M_curr_symbol(NULL), _M_curr_symbol_size(0), + _M_positive_sign(NULL), _M_positive_sign_size(0), + _M_negative_sign(NULL), _M_negative_sign_size(0), + _M_frac_digits(0), + _M_pos_format(money_base::pattern()), + _M_neg_format(money_base::pattern()), _M_allocated(false) + { } + + ~__moneypunct_cache(); + + void + _M_cache(const locale& __loc); + + private: + __moneypunct_cache& + operator=(const __moneypunct_cache&); + + explicit + __moneypunct_cache(const __moneypunct_cache&); + }; + + template + __moneypunct_cache<_CharT, _Intl>::~__moneypunct_cache() + { + if (_M_allocated) + { + delete [] _M_grouping; + delete [] _M_curr_symbol; + delete [] _M_positive_sign; + delete [] _M_negative_sign; + } + } + + /** + * @brief Facet for formatting data for money amounts. + * + * This facet encapsulates the punctuation, grouping and other formatting + * features of money amount string representations. + */ + template + class moneypunct : public locale::facet, public money_base + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + typedef __moneypunct_cache<_CharT, _Intl> __cache_type; + + private: + __cache_type* _M_data; + + public: + /// This value is provided by the standard, but no reason for its + /// existence. + static const bool intl = _Intl; + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + moneypunct(size_t __refs = 0) : facet(__refs), _M_data(NULL) + { _M_initialize_moneypunct(); } + + /** + * @brief Constructor performs initialization. + * + * This is an internal constructor. + * + * @param cache Cache for optimization. + * @param refs Passed to the base facet class. + */ + explicit + moneypunct(__cache_type* __cache, size_t __refs = 0) + : facet(__refs), _M_data(__cache) + { _M_initialize_moneypunct(); } + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param s The name of a locale. + * @param refs Passed to the base facet class. + */ + explicit + moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0) + : facet(__refs), _M_data(NULL) + { _M_initialize_moneypunct(__cloc, __s); } + + /** + * @brief Return decimal point character. + * + * This function returns a char_type to use as a decimal point. It + * does so by returning returning + * moneypunct::do_decimal_point(). + * + * @return @a char_type representing a decimal point. + */ + char_type + decimal_point() const + { return this->do_decimal_point(); } + + /** + * @brief Return thousands separator character. + * + * This function returns a char_type to use as a thousands + * separator. It does so by returning returning + * moneypunct::do_thousands_sep(). + * + * @return char_type representing a thousands separator. + */ + char_type + thousands_sep() const + { return this->do_thousands_sep(); } + + /** + * @brief Return grouping specification. + * + * This function returns a string representing groupings for the + * integer part of an amount. Groupings indicate where thousands + * separators should be inserted. + * + * Each char in the return string is interpret as an integer rather + * than a character. These numbers represent the number of digits in a + * group. The first char in the string represents the number of digits + * in the least significant group. If a char is negative, it indicates + * an unlimited number of digits for the group. If more chars from the + * string are required to group a number, the last char is used + * repeatedly. + * + * For example, if the grouping() returns "\003\002" and is applied to + * the number 123456789, this corresponds to 12,34,56,789. Note that + * if the string was "32", this would put more than 50 digits into the + * least significant group if the character set is ASCII. + * + * The string is returned by calling + * moneypunct::do_grouping(). + * + * @return string representing grouping specification. + */ + string + grouping() const + { return this->do_grouping(); } + + /** + * @brief Return currency symbol string. + * + * This function returns a string_type to use as a currency symbol. It + * does so by returning returning + * moneypunct::do_curr_symbol(). + * + * @return @a string_type representing a currency symbol. + */ + string_type + curr_symbol() const + { return this->do_curr_symbol(); } + + /** + * @brief Return positive sign string. + * + * This function returns a string_type to use as a sign for positive + * amounts. It does so by returning returning + * moneypunct::do_positive_sign(). + * + * If the return value contains more than one character, the first + * character appears in the position indicated by pos_format() and the + * remainder appear at the end of the formatted string. + * + * @return @a string_type representing a positive sign. + */ + string_type + positive_sign() const + { return this->do_positive_sign(); } + + /** + * @brief Return negative sign string. + * + * This function returns a string_type to use as a sign for negative + * amounts. It does so by returning returning + * moneypunct::do_negative_sign(). + * + * If the return value contains more than one character, the first + * character appears in the position indicated by neg_format() and the + * remainder appear at the end of the formatted string. + * + * @return @a string_type representing a negative sign. + */ + string_type + negative_sign() const + { return this->do_negative_sign(); } + + /** + * @brief Return number of digits in fraction. + * + * This function returns the exact number of digits that make up the + * fractional part of a money amount. It does so by returning + * returning moneypunct::do_frac_digits(). + * + * The fractional part of a money amount is optional. But if it is + * present, there must be frac_digits() digits. + * + * @return Number of digits in amount fraction. + */ + int + frac_digits() const + { return this->do_frac_digits(); } + + //@{ + /** + * @brief Return pattern for money values. + * + * This function returns a pattern describing the formatting of a + * positive or negative valued money amount. It does so by returning + * returning moneypunct::do_pos_format() or + * moneypunct::do_neg_format(). + * + * The pattern has 4 fields describing the ordering of symbol, sign, + * value, and none or space. There must be one of each in the pattern. + * The none and space enums may not appear in the first field and space + * may not appear in the final field. + * + * The parts of a money string must appear in the order indicated by + * the fields of the pattern. The symbol field indicates that the + * value of curr_symbol() may be present. The sign field indicates + * that the value of positive_sign() or negative_sign() must be + * present. The value field indicates that the absolute value of the + * money amount is present. none indicates 0 or more whitespace + * characters, except at the end, where it permits no whitespace. + * space indicates that 1 or more whitespace characters must be + * present. + * + * For example, for the US locale and pos_format() pattern + * {symbol,sign,value,none}, curr_symbol() == '$' positive_sign() == + * '+', and value 10.01, and options set to force the symbol, the + * corresponding string is "$+10.01". + * + * @return Pattern for money values. + */ + pattern + pos_format() const + { return this->do_pos_format(); } + + pattern + neg_format() const + { return this->do_neg_format(); } + //@} + + protected: + /// Destructor. + virtual + ~moneypunct(); + + /** + * @brief Return decimal point character. + * + * Returns a char_type to use as a decimal point. This function is a + * hook for derived classes to change the value returned. + * + * @return @a char_type representing a decimal point. + */ + virtual char_type + do_decimal_point() const + { return _M_data->_M_decimal_point; } + + /** + * @brief Return thousands separator character. + * + * Returns a char_type to use as a thousands separator. This function + * is a hook for derived classes to change the value returned. + * + * @return @a char_type representing a thousands separator. + */ + virtual char_type + do_thousands_sep() const + { return _M_data->_M_thousands_sep; } + + /** + * @brief Return grouping specification. + * + * Returns a string representing groupings for the integer part of a + * number. This function is a hook for derived classes to change the + * value returned. @see grouping() for details. + * + * @return String representing grouping specification. + */ + virtual string + do_grouping() const + { return _M_data->_M_grouping; } + + /** + * @brief Return currency symbol string. + * + * This function returns a string_type to use as a currency symbol. + * This function is a hook for derived classes to change the value + * returned. @see curr_symbol() for details. + * + * @return @a string_type representing a currency symbol. + */ + virtual string_type + do_curr_symbol() const + { return _M_data->_M_curr_symbol; } + + /** + * @brief Return positive sign string. + * + * This function returns a string_type to use as a sign for positive + * amounts. This function is a hook for derived classes to change the + * value returned. @see positive_sign() for details. + * + * @return @a string_type representing a positive sign. + */ + virtual string_type + do_positive_sign() const + { return _M_data->_M_positive_sign; } + + /** + * @brief Return negative sign string. + * + * This function returns a string_type to use as a sign for negative + * amounts. This function is a hook for derived classes to change the + * value returned. @see negative_sign() for details. + * + * @return @a string_type representing a negative sign. + */ + virtual string_type + do_negative_sign() const + { return _M_data->_M_negative_sign; } + + /** + * @brief Return number of digits in fraction. + * + * This function returns the exact number of digits that make up the + * fractional part of a money amount. This function is a hook for + * derived classes to change the value returned. @see frac_digits() + * for details. + * + * @return Number of digits in amount fraction. + */ + virtual int + do_frac_digits() const + { return _M_data->_M_frac_digits; } + + /** + * @brief Return pattern for money values. + * + * This function returns a pattern describing the formatting of a + * positive valued money amount. This function is a hook for derived + * classes to change the value returned. @see pos_format() for + * details. + * + * @return Pattern for money values. + */ + virtual pattern + do_pos_format() const + { return _M_data->_M_pos_format; } + + /** + * @brief Return pattern for money values. + * + * This function returns a pattern describing the formatting of a + * negative valued money amount. This function is a hook for derived + * classes to change the value returned. @see neg_format() for + * details. + * + * @return Pattern for money values. + */ + virtual pattern + do_neg_format() const + { return _M_data->_M_neg_format; } + + // For use at construction time only. + void + _M_initialize_moneypunct(__c_locale __cloc = NULL, + const char* __name = NULL); + }; + + template + locale::id moneypunct<_CharT, _Intl>::id; + + template + const bool moneypunct<_CharT, _Intl>::intl; + + template<> + moneypunct::~moneypunct(); + + template<> + moneypunct::~moneypunct(); + + template<> + void + moneypunct::_M_initialize_moneypunct(__c_locale, const char*); + + template<> + void + moneypunct::_M_initialize_moneypunct(__c_locale, const char*); + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + moneypunct::~moneypunct(); + + template<> + moneypunct::~moneypunct(); + + template<> + void + moneypunct::_M_initialize_moneypunct(__c_locale, + const char*); + + template<> + void + moneypunct::_M_initialize_moneypunct(__c_locale, + const char*); +#endif + + /// @brief class moneypunct_byname [22.2.6.4]. + template + class moneypunct_byname : public moneypunct<_CharT, _Intl> + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + static const bool intl = _Intl; + + explicit + moneypunct_byname(const char* __s, size_t __refs = 0) + : moneypunct<_CharT, _Intl>(__refs) + { + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + __c_locale __tmp; + this->_S_create_c_locale(__tmp, __s); + this->_M_initialize_moneypunct(__tmp); + this->_S_destroy_c_locale(__tmp); + } + } + + protected: + virtual + ~moneypunct_byname() { } + }; + + template + const bool moneypunct_byname<_CharT, _Intl>::intl; + +_GLIBCXX_BEGIN_LDBL_NAMESPACE + + /** + * @brief Facet for parsing monetary amounts. + * + * This facet encapsulates the code to parse and return a monetary + * amount from a string. + * + * The money_get template uses protected virtual functions to + * provide the actual results. The public accessors forward the + * call to the virtual functions. These virtual functions are + * hooks for developers to implement the behavior they require from + * the money_get facet. + */ + template + class money_get : public locale::facet + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _InIter iter_type; + typedef basic_string<_CharT> string_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + money_get(size_t __refs = 0) : facet(__refs) { } + + /** + * @brief Read and parse a monetary value. + * + * This function reads characters from @a s, interprets them as a + * monetary value according to moneypunct and ctype facets retrieved + * from io.getloc(), and returns the result in @a units as an integral + * value moneypunct::frac_digits() * the actual amount. For example, + * the string $10.01 in a US locale would store 1001 in @a units. + * + * Any characters not part of a valid money amount are not consumed. + * + * If a money value cannot be parsed from the input stream, sets + * err=(err|io.failbit). If the stream is consumed before finishing + * parsing, sets err=(err|io.failbit|io.eofbit). @a units is + * unchanged if parsing fails. + * + * This function works by returning the result of do_get(). + * + * @param s Start of characters to parse. + * @param end End of characters to parse. + * @param intl Parameter to use_facet >. + * @param io Source of facets and io state. + * @param err Error field to set if parsing fails. + * @param units Place to store result of parsing. + * @return Iterator referencing first character beyond valid money + * amount. + */ + iter_type + get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, long double& __units) const + { return this->do_get(__s, __end, __intl, __io, __err, __units); } + + /** + * @brief Read and parse a monetary value. + * + * This function reads characters from @a s, interprets them as a + * monetary value according to moneypunct and ctype facets retrieved + * from io.getloc(), and returns the result in @a digits. For example, + * the string $10.01 in a US locale would store "1001" in @a digits. + * + * Any characters not part of a valid money amount are not consumed. + * + * If a money value cannot be parsed from the input stream, sets + * err=(err|io.failbit). If the stream is consumed before finishing + * parsing, sets err=(err|io.failbit|io.eofbit). + * + * This function works by returning the result of do_get(). + * + * @param s Start of characters to parse. + * @param end End of characters to parse. + * @param intl Parameter to use_facet >. + * @param io Source of facets and io state. + * @param err Error field to set if parsing fails. + * @param digits Place to store result of parsing. + * @return Iterator referencing first character beyond valid money + * amount. + */ + iter_type + get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, string_type& __digits) const + { return this->do_get(__s, __end, __intl, __io, __err, __digits); } + + protected: + /// Destructor. + virtual + ~money_get() { } + + /** + * @brief Read and parse a monetary value. + * + * This function reads and parses characters representing a monetary + * value. This function is a hook for derived classes to change the + * value returned. @see get() for details. + */ + // XXX GLIBCXX_ABI Deprecated +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ + virtual iter_type + __do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, double& __units) const; +#else + virtual iter_type + do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, long double& __units) const; +#endif + + /** + * @brief Read and parse a monetary value. + * + * This function reads and parses characters representing a monetary + * value. This function is a hook for derived classes to change the + * value returned. @see get() for details. + */ + virtual iter_type + do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, string_type& __digits) const; + + // XXX GLIBCXX_ABI Deprecated +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ + virtual iter_type + do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, long double& __units) const; +#endif + + template + iter_type + _M_extract(iter_type __s, iter_type __end, ios_base& __io, + ios_base::iostate& __err, string& __digits) const; + }; + + template + locale::id money_get<_CharT, _InIter>::id; + + /** + * @brief Facet for outputting monetary amounts. + * + * This facet encapsulates the code to format and output a monetary + * amount. + * + * The money_put template uses protected virtual functions to + * provide the actual results. The public accessors forward the + * call to the virtual functions. These virtual functions are + * hooks for developers to implement the behavior they require from + * the money_put facet. + */ + template + class money_put : public locale::facet + { + public: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _OutIter iter_type; + typedef basic_string<_CharT> string_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + money_put(size_t __refs = 0) : facet(__refs) { } + + /** + * @brief Format and output a monetary value. + * + * This function formats @a units as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the value 1001 in a + * US locale would write "$10.01" to @a s. + * + * This function works by returning the result of do_put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, bool __intl, ios_base& __io, + char_type __fill, long double __units) const + { return this->do_put(__s, __intl, __io, __fill, __units); } + + /** + * @brief Format and output a monetary value. + * + * This function formats @a digits as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the string "1001" in + * a US locale would write "$10.01" to @a s. + * + * This function works by returning the result of do_put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, bool __intl, ios_base& __io, + char_type __fill, const string_type& __digits) const + { return this->do_put(__s, __intl, __io, __fill, __digits); } + + protected: + /// Destructor. + virtual + ~money_put() { } + + /** + * @brief Format and output a monetary value. + * + * This function formats @a units as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the value 1001 in a + * US locale would write "$10.01" to @a s. + * + * This function is a hook for derived classes to change the value + * returned. @see put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ + // XXX GLIBCXX_ABI Deprecated +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ + virtual iter_type + __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + double __units) const; +#else + virtual iter_type + do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + long double __units) const; +#endif + + /** + * @brief Format and output a monetary value. + * + * This function formats @a digits as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the string "1001" in + * a US locale would write "$10.01" to @a s. + * + * This function is a hook for derived classes to change the value + * returned. @see put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ + virtual iter_type + do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + const string_type& __digits) const; + + // XXX GLIBCXX_ABI Deprecated +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ + virtual iter_type + do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + long double __units) const; +#endif + + template + iter_type + _M_insert(iter_type __s, ios_base& __io, char_type __fill, + const string_type& __digits) const; + }; + + template + locale::id money_put<_CharT, _OutIter>::id; + +_GLIBCXX_END_LDBL_NAMESPACE + + /** + * @brief Messages facet base class providing catalog typedef. + */ + struct messages_base + { + typedef int catalog; + }; + + /** + * @brief Facet for handling message catalogs + * + * This facet encapsulates the code to retrieve messages from + * message catalogs. The only thing defined by the standard for this facet + * is the interface. All underlying functionality is + * implementation-defined. + * + * This library currently implements 3 versions of the message facet. The + * first version (gnu) is a wrapper around gettext, provided by libintl. + * The second version (ieee) is a wrapper around catgets. The final + * version (default) does no actual translation. These implementations are + * only provided for char and wchar_t instantiations. + * + * The messages template uses protected virtual functions to + * provide the actual results. The public accessors forward the + * call to the virtual functions. These virtual functions are + * hooks for developers to implement the behavior they require from + * the messages facet. + */ + template + class messages : public locale::facet, public messages_base + { + public: + // Types: + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + + protected: + // Underlying "C" library locale information saved from + // initialization, needed by messages_byname as well. + __c_locale _M_c_locale_messages; + const char* _M_name_messages; + + public: + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + messages(size_t __refs = 0); + + // Non-standard. + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param s The name of a locale. + * @param refs Refcount to pass to the base class. + */ + explicit + messages(__c_locale __cloc, const char* __s, size_t __refs = 0); + + /* + * @brief Open a message catalog. + * + * This function opens and returns a handle to a message catalog by + * returning do_open(s, loc). + * + * @param s The catalog to open. + * @param loc Locale to use for character set conversions. + * @return Handle to the catalog or value < 0 if open fails. + */ + catalog + open(const basic_string& __s, const locale& __loc) const + { return this->do_open(__s, __loc); } + + // Non-standard and unorthodox, yet effective. + /* + * @brief Open a message catalog. + * + * This non-standard function opens and returns a handle to a message + * catalog by returning do_open(s, loc). The third argument provides a + * message catalog root directory for gnu gettext and is ignored + * otherwise. + * + * @param s The catalog to open. + * @param loc Locale to use for character set conversions. + * @param dir Message catalog root directory. + * @return Handle to the catalog or value < 0 if open fails. + */ + catalog + open(const basic_string&, const locale&, const char*) const; + + /* + * @brief Look up a string in a message catalog. + * + * This function retrieves and returns a message from a catalog by + * returning do_get(c, set, msgid, s). + * + * For gnu, @a set and @a msgid are ignored. Returns gettext(s). + * For default, returns s. For ieee, returns catgets(c,set,msgid,s). + * + * @param c The catalog to access. + * @param set Implementation-defined. + * @param msgid Implementation-defined. + * @param s Default return value if retrieval fails. + * @return Retrieved message or @a s if get fails. + */ + string_type + get(catalog __c, int __set, int __msgid, const string_type& __s) const + { return this->do_get(__c, __set, __msgid, __s); } + + /* + * @brief Close a message catalog. + * + * Closes catalog @a c by calling do_close(c). + * + * @param c The catalog to close. + */ + void + close(catalog __c) const + { return this->do_close(__c); } + + protected: + /// Destructor. + virtual + ~messages(); + + /* + * @brief Open a message catalog. + * + * This function opens and returns a handle to a message catalog in an + * implementation-defined manner. This function is a hook for derived + * classes to change the value returned. + * + * @param s The catalog to open. + * @param loc Locale to use for character set conversions. + * @return Handle to the opened catalog, value < 0 if open failed. + */ + virtual catalog + do_open(const basic_string&, const locale&) const; + + /* + * @brief Look up a string in a message catalog. + * + * This function retrieves and returns a message from a catalog in an + * implementation-defined manner. This function is a hook for derived + * classes to change the value returned. + * + * For gnu, @a set and @a msgid are ignored. Returns gettext(s). + * For default, returns s. For ieee, returns catgets(c,set,msgid,s). + * + * @param c The catalog to access. + * @param set Implementation-defined. + * @param msgid Implementation-defined. + * @param s Default return value if retrieval fails. + * @return Retrieved message or @a s if get fails. + */ + virtual string_type + do_get(catalog, int, int, const string_type& __dfault) const; + + /* + * @brief Close a message catalog. + * + * @param c The catalog to close. + */ + virtual void + do_close(catalog) const; + + // Returns a locale and codeset-converted string, given a char* message. + char* + _M_convert_to_char(const string_type& __msg) const + { + // XXX + return reinterpret_cast(const_cast<_CharT*>(__msg.c_str())); + } + + // Returns a locale and codeset-converted string, given a char* message. + string_type + _M_convert_from_char(char*) const + { +#if 0 + // Length of message string without terminating null. + size_t __len = char_traits::length(__msg) - 1; + + // "everybody can easily convert the string using + // mbsrtowcs/wcsrtombs or with iconv()" + + // Convert char* to _CharT in locale used to open catalog. + // XXX need additional template parameter on messages class for this.. + // typedef typename codecvt __codecvt_type; + typedef typename codecvt __codecvt_type; + + __codecvt_type::state_type __state; + // XXX may need to initialize state. + //initialize_state(__state._M_init()); + + char* __from_next; + // XXX what size for this string? + _CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1)); + const __codecvt_type& __cvt = use_facet<__codecvt_type>(_M_locale_conv); + __cvt.out(__state, __msg, __msg + __len, __from_next, + __to, __to + __len + 1, __to_next); + return string_type(__to); +#endif +#if 0 + typedef ctype<_CharT> __ctype_type; + // const __ctype_type& __cvt = use_facet<__ctype_type>(_M_locale_msg); + const __ctype_type& __cvt = use_facet<__ctype_type>(locale()); + // XXX Again, proper length of converted string an issue here. + // For now, assume the converted length is not larger. + _CharT* __dest = static_cast<_CharT*>(__builtin_alloca(__len + 1)); + __cvt.widen(__msg, __msg + __len, __dest); + return basic_string<_CharT>(__dest); +#endif + return string_type(); + } + }; + + template + locale::id messages<_CharT>::id; + + // Specializations for required instantiations. + template<> + string + messages::do_get(catalog, int, int, const string&) const; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + wstring + messages::do_get(catalog, int, int, const wstring&) const; +#endif + + /// @brief class messages_byname [22.2.7.2]. + template + class messages_byname : public messages<_CharT> + { + public: + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + + explicit + messages_byname(const char* __s, size_t __refs = 0); + + protected: + virtual + ~messages_byname() + { } + }; + +_GLIBCXX_END_NAMESPACE + + // Include host and configuration specific messages functions. +#include + +#endif diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.tcc b/libstdc++-v3/include/bits/locale_facets_nonio.tcc new file mode 100644 index 00000000000..190caf37282 --- /dev/null +++ b/libstdc++-v3/include/bits/locale_facets_nonio.tcc @@ -0,0 +1,1328 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 2007 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file locale_facets_nonio.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _LOCALE_FACETS_NONIO_TCC +#define _LOCALE_FACETS_NONIO_TCC 1 + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template + struct __use_cache<__moneypunct_cache<_CharT, _Intl> > + { + const __moneypunct_cache<_CharT, _Intl>* + operator() (const locale& __loc) const + { + const size_t __i = moneypunct<_CharT, _Intl>::id._M_id(); + const locale::facet** __caches = __loc._M_impl->_M_caches; + if (!__caches[__i]) + { + __moneypunct_cache<_CharT, _Intl>* __tmp = NULL; + try + { + __tmp = new __moneypunct_cache<_CharT, _Intl>; + __tmp->_M_cache(__loc); + } + catch(...) + { + delete __tmp; + __throw_exception_again; + } + __loc._M_impl->_M_install_cache(__tmp, __i); + } + return static_cast< + const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]); + } + }; + + template + void + __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc) + { + _M_allocated = true; + + const moneypunct<_CharT, _Intl>& __mp = + use_facet >(__loc); + + _M_grouping_size = __mp.grouping().size(); + char* __grouping = new char[_M_grouping_size]; + __mp.grouping().copy(__grouping, _M_grouping_size); + _M_grouping = __grouping; + _M_use_grouping = (_M_grouping_size + && static_cast(__mp.grouping()[0]) > 0); + + _M_decimal_point = __mp.decimal_point(); + _M_thousands_sep = __mp.thousands_sep(); + _M_frac_digits = __mp.frac_digits(); + + _M_curr_symbol_size = __mp.curr_symbol().size(); + _CharT* __curr_symbol = new _CharT[_M_curr_symbol_size]; + __mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size); + _M_curr_symbol = __curr_symbol; + + _M_positive_sign_size = __mp.positive_sign().size(); + _CharT* __positive_sign = new _CharT[_M_positive_sign_size]; + __mp.positive_sign().copy(__positive_sign, _M_positive_sign_size); + _M_positive_sign = __positive_sign; + + _M_negative_sign_size = __mp.negative_sign().size(); + _CharT* __negative_sign = new _CharT[_M_negative_sign_size]; + __mp.negative_sign().copy(__negative_sign, _M_negative_sign_size); + _M_negative_sign = __negative_sign; + + _M_pos_format = __mp.pos_format(); + _M_neg_format = __mp.neg_format(); + + const ctype<_CharT>& __ct = use_facet >(__loc); + __ct.widen(money_base::_S_atoms, + money_base::_S_atoms + money_base::_S_end, _M_atoms); + } + +_GLIBCXX_BEGIN_LDBL_NAMESPACE + + template + template + _InIter + money_get<_CharT, _InIter>:: + _M_extract(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, string& __units) const + { + typedef char_traits<_CharT> __traits_type; + typedef typename string_type::size_type size_type; + typedef money_base::part part; + typedef __moneypunct_cache<_CharT, _Intl> __cache_type; + + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + __use_cache<__cache_type> __uc; + const __cache_type* __lc = __uc(__loc); + const char_type* __lit = __lc->_M_atoms; + + // Deduced sign. + bool __negative = false; + // Sign size. + size_type __sign_size = 0; + // True if sign is mandatory. + const bool __mandatory_sign = (__lc->_M_positive_sign_size + && __lc->_M_negative_sign_size); + // String of grouping info from thousands_sep plucked from __units. + string __grouping_tmp; + if (__lc->_M_use_grouping) + __grouping_tmp.reserve(32); + // Last position before the decimal point. + int __last_pos = 0; + // Separator positions, then, possibly, fractional digits. + int __n = 0; + // If input iterator is in a valid state. + bool __testvalid = true; + // Flag marking when a decimal point is found. + bool __testdecfound = false; + + // The tentative returned string is stored here. + string __res; + __res.reserve(32); + + const char_type* __lit_zero = __lit + money_base::_S_zero; + const money_base::pattern __p = __lc->_M_neg_format; + for (int __i = 0; __i < 4 && __testvalid; ++__i) + { + const part __which = static_cast(__p.field[__i]); + switch (__which) + { + case money_base::symbol: + // According to 22.2.6.1.2, p2, symbol is required + // if (__io.flags() & ios_base::showbase), otherwise + // is optional and consumed only if other characters + // are needed to complete the format. + if (__io.flags() & ios_base::showbase || __sign_size > 1 + || __i == 0 + || (__i == 1 && (__mandatory_sign + || (static_cast(__p.field[0]) + == money_base::sign) + || (static_cast(__p.field[2]) + == money_base::space))) + || (__i == 2 && ((static_cast(__p.field[3]) + == money_base::value) + || (__mandatory_sign + && (static_cast(__p.field[3]) + == money_base::sign))))) + { + const size_type __len = __lc->_M_curr_symbol_size; + size_type __j = 0; + for (; __beg != __end && __j < __len + && *__beg == __lc->_M_curr_symbol[__j]; + ++__beg, ++__j); + if (__j != __len + && (__j || __io.flags() & ios_base::showbase)) + __testvalid = false; + } + break; + case money_base::sign: + // Sign might not exist, or be more than one character long. + if (__lc->_M_positive_sign_size && __beg != __end + && *__beg == __lc->_M_positive_sign[0]) + { + __sign_size = __lc->_M_positive_sign_size; + ++__beg; + } + else if (__lc->_M_negative_sign_size && __beg != __end + && *__beg == __lc->_M_negative_sign[0]) + { + __negative = true; + __sign_size = __lc->_M_negative_sign_size; + ++__beg; + } + else if (__lc->_M_positive_sign_size + && !__lc->_M_negative_sign_size) + // "... if no sign is detected, the result is given the sign + // that corresponds to the source of the empty string" + __negative = true; + else if (__mandatory_sign) + __testvalid = false; + break; + case money_base::value: + // Extract digits, remove and stash away the + // grouping of found thousands separators. + for (; __beg != __end; ++__beg) + { + const char_type __c = *__beg; + const char_type* __q = __traits_type::find(__lit_zero, + 10, __c); + if (__q != 0) + { + __res += money_base::_S_atoms[__q - __lit]; + ++__n; + } + else if (__c == __lc->_M_decimal_point + && !__testdecfound) + { + __last_pos = __n; + __n = 0; + __testdecfound = true; + } + else if (__lc->_M_use_grouping + && __c == __lc->_M_thousands_sep + && !__testdecfound) + { + if (__n) + { + // Mark position for later analysis. + __grouping_tmp += static_cast(__n); + __n = 0; + } + else + { + __testvalid = false; + break; + } + } + else + break; + } + if (__res.empty()) + __testvalid = false; + break; + case money_base::space: + // At least one space is required. + if (__beg != __end && __ctype.is(ctype_base::space, *__beg)) + ++__beg; + else + __testvalid = false; + case money_base::none: + // Only if not at the end of the pattern. + if (__i != 3) + for (; __beg != __end + && __ctype.is(ctype_base::space, *__beg); ++__beg); + break; + } + } + + // Need to get the rest of the sign characters, if they exist. + if (__sign_size > 1 && __testvalid) + { + const char_type* __sign = __negative ? __lc->_M_negative_sign + : __lc->_M_positive_sign; + size_type __i = 1; + for (; __beg != __end && __i < __sign_size + && *__beg == __sign[__i]; ++__beg, ++__i); + + if (__i != __sign_size) + __testvalid = false; + } + + if (__testvalid) + { + // Strip leading zeros. + if (__res.size() > 1) + { + const size_type __first = __res.find_first_not_of('0'); + const bool __only_zeros = __first == string::npos; + if (__first) + __res.erase(0, __only_zeros ? __res.size() - 1 : __first); + } + + // 22.2.6.1.2, p4 + if (__negative && __res[0] != '0') + __res.insert(__res.begin(), '-'); + + // Test for grouping fidelity. + if (__grouping_tmp.size()) + { + // Add the ending grouping. + __grouping_tmp += static_cast(__testdecfound ? __last_pos + : __n); + if (!std::__verify_grouping(__lc->_M_grouping, + __lc->_M_grouping_size, + __grouping_tmp)) + __err |= ios_base::failbit; + } + + // Iff not enough digits were supplied after the decimal-point. + if (__testdecfound && __lc->_M_frac_digits > 0 + && __n != __lc->_M_frac_digits) + __testvalid = false; + } + + // Iff valid sequence is not recognized. + if (!__testvalid) + __err |= ios_base::failbit; + else + __units.swap(__res); + + // Iff no more characters are available. + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ + template + _InIter + money_get<_CharT, _InIter>:: + __do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, double& __units) const + { + string __str; + __beg = __intl ? _M_extract(__beg, __end, __io, __err, __str) + : _M_extract(__beg, __end, __io, __err, __str); + std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); + return __beg; + } +#endif + + template + _InIter + money_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, long double& __units) const + { + string __str; + __beg = __intl ? _M_extract(__beg, __end, __io, __err, __str) + : _M_extract(__beg, __end, __io, __err, __str); + std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); + return __beg; + } + + template + _InIter + money_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, string_type& __digits) const + { + typedef typename string::size_type size_type; + + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + string __str; + __beg = __intl ? _M_extract(__beg, __end, __io, __err, __str) + : _M_extract(__beg, __end, __io, __err, __str); + const size_type __len = __str.size(); + if (__len) + { + __digits.resize(__len); + __ctype.widen(__str.data(), __str.data() + __len, &__digits[0]); + } + return __beg; + } + + template + template + _OutIter + money_put<_CharT, _OutIter>:: + _M_insert(iter_type __s, ios_base& __io, char_type __fill, + const string_type& __digits) const + { + typedef typename string_type::size_type size_type; + typedef money_base::part part; + typedef __moneypunct_cache<_CharT, _Intl> __cache_type; + + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + __use_cache<__cache_type> __uc; + const __cache_type* __lc = __uc(__loc); + const char_type* __lit = __lc->_M_atoms; + + // Determine if negative or positive formats are to be used, and + // discard leading negative_sign if it is present. + const char_type* __beg = __digits.data(); + + money_base::pattern __p; + const char_type* __sign; + size_type __sign_size; + if (!(*__beg == __lit[money_base::_S_minus])) + { + __p = __lc->_M_pos_format; + __sign = __lc->_M_positive_sign; + __sign_size = __lc->_M_positive_sign_size; + } + else + { + __p = __lc->_M_neg_format; + __sign = __lc->_M_negative_sign; + __sign_size = __lc->_M_negative_sign_size; + if (__digits.size()) + ++__beg; + } + + // Look for valid numbers in the ctype facet within input digits. + size_type __len = __ctype.scan_not(ctype_base::digit, __beg, + __beg + __digits.size()) - __beg; + if (__len) + { + // Assume valid input, and attempt to format. + // Break down input numbers into base components, as follows: + // final_value = grouped units + (decimal point) + (digits) + string_type __value; + __value.reserve(2 * __len); + + // Add thousands separators to non-decimal digits, per + // grouping rules. + long __paddec = __len - __lc->_M_frac_digits; + if (__paddec > 0) + { + if (__lc->_M_frac_digits < 0) + __paddec = __len; + if (__lc->_M_grouping_size) + { + __value.assign(2 * __paddec, char_type()); + _CharT* __vend = + std::__add_grouping(&__value[0], __lc->_M_thousands_sep, + __lc->_M_grouping, + __lc->_M_grouping_size, + __beg, __beg + __paddec); + __value.erase(__vend - &__value[0]); + } + else + __value.assign(__beg, __paddec); + } + + // Deal with decimal point, decimal digits. + if (__lc->_M_frac_digits > 0) + { + __value += __lc->_M_decimal_point; + if (__paddec >= 0) + __value.append(__beg + __paddec, __lc->_M_frac_digits); + else + { + // Have to pad zeros in the decimal position. + __value.append(-__paddec, __lit[money_base::_S_zero]); + __value.append(__beg, __len); + } + } + + // Calculate length of resulting string. + const ios_base::fmtflags __f = __io.flags() + & ios_base::adjustfield; + __len = __value.size() + __sign_size; + __len += ((__io.flags() & ios_base::showbase) + ? __lc->_M_curr_symbol_size : 0); + + string_type __res; + __res.reserve(2 * __len); + + const size_type __width = static_cast(__io.width()); + const bool __testipad = (__f == ios_base::internal + && __len < __width); + // Fit formatted digits into the required pattern. + for (int __i = 0; __i < 4; ++__i) + { + const part __which = static_cast(__p.field[__i]); + switch (__which) + { + case money_base::symbol: + if (__io.flags() & ios_base::showbase) + __res.append(__lc->_M_curr_symbol, + __lc->_M_curr_symbol_size); + break; + case money_base::sign: + // Sign might not exist, or be more than one + // charater long. In that case, add in the rest + // below. + if (__sign_size) + __res += __sign[0]; + break; + case money_base::value: + __res += __value; + break; + case money_base::space: + // At least one space is required, but if internal + // formatting is required, an arbitrary number of + // fill spaces will be necessary. + if (__testipad) + __res.append(__width - __len, __fill); + else + __res += __fill; + break; + case money_base::none: + if (__testipad) + __res.append(__width - __len, __fill); + break; + } + } + + // Special case of multi-part sign parts. + if (__sign_size > 1) + __res.append(__sign + 1, __sign_size - 1); + + // Pad, if still necessary. + __len = __res.size(); + if (__width > __len) + { + if (__f == ios_base::left) + // After. + __res.append(__width - __len, __fill); + else + // Before. + __res.insert(0, __width - __len, __fill); + __len = __width; + } + + // Write resulting, fully-formatted string to output iterator. + __s = std::__write(__s, __res.data(), __len); + } + __io.width(0); + return __s; + } + +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ + template + _OutIter + money_put<_CharT, _OutIter>:: + __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + double __units) const + { return this->do_put(__s, __intl, __io, __fill, (long double) __units); } +#endif + + template + _OutIter + money_put<_CharT, _OutIter>:: + do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + long double __units) const + { + const locale __loc = __io.getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); +#ifdef _GLIBCXX_USE_C99 + // First try a buffer perhaps big enough. + int __cs_size = 64; + char* __cs = static_cast(__builtin_alloca(__cs_size)); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 328. Bad sprintf format modifier in money_put<>::do_put() + int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, + "%.*Lf", 0, __units); + // 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 = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, + "%.*Lf", 0, __units); + } +#else + // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'. + const int __cs_size = + __gnu_cxx::__numeric_traits::__max_exponent10 + 3; + char* __cs = static_cast(__builtin_alloca(__cs_size)); + int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf", + 0, __units); +#endif + string_type __digits(__len, char_type()); + __ctype.widen(__cs, __cs + __len, &__digits[0]); + return __intl ? _M_insert(__s, __io, __fill, __digits) + : _M_insert(__s, __io, __fill, __digits); + } + + template + _OutIter + money_put<_CharT, _OutIter>:: + do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, + const string_type& __digits) const + { return __intl ? _M_insert(__s, __io, __fill, __digits) + : _M_insert(__s, __io, __fill, __digits); } + +_GLIBCXX_END_LDBL_NAMESPACE + + // NB: Not especially useful. Without an ios_base object or some + // kind of locale reference, we are left clawing at the air where + // the side of the mountain used to be... + template + time_base::dateorder + time_get<_CharT, _InIter>::do_date_order() const + { return time_base::no_order; } + + // Expand a strftime format string and parse it. E.g., do_get_date() may + // pass %m/%d/%Y => extracted characters. + template + _InIter + time_get<_CharT, _InIter>:: + _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm, + const _CharT* __format) const + { + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const ctype<_CharT>& __ctype = use_facet >(__loc); + const size_t __len = char_traits<_CharT>::length(__format); + + ios_base::iostate __tmperr = ios_base::goodbit; + for (size_t __i = 0; __beg != __end && __i < __len && !__tmperr; ++__i) + { + if (__ctype.narrow(__format[__i], 0) == '%') + { + // Verify valid formatting code, attempt to extract. + char __c = __ctype.narrow(__format[++__i], 0); + int __mem = 0; + if (__c == 'E' || __c == 'O') + __c = __ctype.narrow(__format[++__i], 0); + switch (__c) + { + const char* __cs; + _CharT __wcs[10]; + case 'a': + // Abbreviated weekday name [tm_wday] + const char_type* __days1[7]; + __tp._M_days_abbreviated(__days1); + __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days1, + 7, __io, __tmperr); + break; + case 'A': + // Weekday name [tm_wday]. + const char_type* __days2[7]; + __tp._M_days(__days2); + __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days2, + 7, __io, __tmperr); + break; + case 'h': + case 'b': + // Abbreviated month name [tm_mon] + const char_type* __months1[12]; + __tp._M_months_abbreviated(__months1); + __beg = _M_extract_name(__beg, __end, __tm->tm_mon, + __months1, 12, __io, __tmperr); + break; + case 'B': + // Month name [tm_mon]. + const char_type* __months2[12]; + __tp._M_months(__months2); + __beg = _M_extract_name(__beg, __end, __tm->tm_mon, + __months2, 12, __io, __tmperr); + break; + case 'c': + // Default time and date representation. + const char_type* __dt[2]; + __tp._M_date_time_formats(__dt); + __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, + __tm, __dt[0]); + break; + case 'd': + // Day [01, 31]. [tm_mday] + __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2, + __io, __tmperr); + break; + case 'e': + // Day [1, 31], with single digits preceded by + // space. [tm_mday] + if (__ctype.is(ctype_base::space, *__beg)) + __beg = _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9, + 1, __io, __tmperr); + else + __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31, + 2, __io, __tmperr); + break; + case 'D': + // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year] + __cs = "%m/%d/%y"; + __ctype.widen(__cs, __cs + 9, __wcs); + __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, + __tm, __wcs); + break; + case 'H': + // Hour [00, 23]. [tm_hour] + __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2, + __io, __tmperr); + break; + case 'I': + // Hour [01, 12]. [tm_hour] + __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2, + __io, __tmperr); + break; + case 'm': + // Month [01, 12]. [tm_mon] + __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, + __io, __tmperr); + if (!__tmperr) + __tm->tm_mon = __mem - 1; + break; + case 'M': + // Minute [00, 59]. [tm_min] + __beg = _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2, + __io, __tmperr); + break; + case 'n': + if (__ctype.narrow(*__beg, 0) == '\n') + ++__beg; + else + __tmperr |= ios_base::failbit; + break; + case 'R': + // Equivalent to (%H:%M). + __cs = "%H:%M"; + __ctype.widen(__cs, __cs + 6, __wcs); + __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, + __tm, __wcs); + break; + case 'S': + // Seconds. [tm_sec] + // [00, 60] in C99 (one leap-second), [00, 61] in C89. +#ifdef _GLIBCXX_USE_C99 + __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 60, 2, +#else + __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 61, 2, +#endif + __io, __tmperr); + break; + case 't': + if (__ctype.narrow(*__beg, 0) == '\t') + ++__beg; + else + __tmperr |= ios_base::failbit; + break; + case 'T': + // Equivalent to (%H:%M:%S). + __cs = "%H:%M:%S"; + __ctype.widen(__cs, __cs + 9, __wcs); + __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, + __tm, __wcs); + break; + case 'x': + // Locale's date. + const char_type* __dates[2]; + __tp._M_date_formats(__dates); + __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, + __tm, __dates[0]); + break; + case 'X': + // Locale's time. + const char_type* __times[2]; + __tp._M_time_formats(__times); + __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, + __tm, __times[0]); + break; + case 'y': + case 'C': // C99 + // Two digit year. [tm_year] + __beg = _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2, + __io, __tmperr); + break; + case 'Y': + // Year [1900). [tm_year] + __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4, + __io, __tmperr); + if (!__tmperr) + __tm->tm_year = __mem - 1900; + break; + case 'Z': + // Timezone info. + if (__ctype.is(ctype_base::upper, *__beg)) + { + int __tmp; + __beg = _M_extract_name(__beg, __end, __tmp, + __timepunct_cache<_CharT>::_S_timezones, + 14, __io, __tmperr); + + // GMT requires special effort. + if (__beg != __end && !__tmperr && __tmp == 0 + && (*__beg == __ctype.widen('-') + || *__beg == __ctype.widen('+'))) + { + __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2, + __io, __tmperr); + __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2, + __io, __tmperr); + } + } + else + __tmperr |= ios_base::failbit; + break; + default: + // Not recognized. + __tmperr |= ios_base::failbit; + } + } + else + { + // Verify format and input match, extract and discard. + if (__format[__i] == *__beg) + ++__beg; + else + __tmperr |= ios_base::failbit; + } + } + + if (__tmperr) + __err |= ios_base::failbit; + + return __beg; + } + + template + _InIter + time_get<_CharT, _InIter>:: + _M_extract_num(iter_type __beg, iter_type __end, int& __member, + int __min, int __max, size_t __len, + ios_base& __io, ios_base::iostate& __err) const + { + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + // As-is works for __len = 1, 2, 4, the values actually used. + int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1); + + ++__min; + size_t __i = 0; + int __value = 0; + for (; __beg != __end && __i < __len; ++__beg, ++__i) + { + const char __c = __ctype.narrow(*__beg, '*'); + if (__c >= '0' && __c <= '9') + { + __value = __value * 10 + (__c - '0'); + const int __valuec = __value * __mult; + if (__valuec > __max || __valuec + __mult < __min) + break; + __mult /= 10; + } + else + break; + } + if (__i == __len) + __member = __value; + else + __err |= ios_base::failbit; + + return __beg; + } + + // Assumptions: + // All elements in __names are unique. + template + _InIter + time_get<_CharT, _InIter>:: + _M_extract_name(iter_type __beg, iter_type __end, int& __member, + const _CharT** __names, size_t __indexlen, + ios_base& __io, ios_base::iostate& __err) const + { + typedef char_traits<_CharT> __traits_type; + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + int* __matches = static_cast(__builtin_alloca(sizeof(int) + * __indexlen)); + size_t __nmatches = 0; + size_t __pos = 0; + bool __testvalid = true; + const char_type* __name; + + // Look for initial matches. + // NB: Some of the locale data is in the form of all lowercase + // names, and some is in the form of initially-capitalized + // names. Look for both. + if (__beg != __end) + { + const char_type __c = *__beg; + for (size_t __i1 = 0; __i1 < __indexlen; ++__i1) + if (__c == __names[__i1][0] + || __c == __ctype.toupper(__names[__i1][0])) + __matches[__nmatches++] = __i1; + } + + while (__nmatches > 1) + { + // Find smallest matching string. + size_t __minlen = __traits_type::length(__names[__matches[0]]); + for (size_t __i2 = 1; __i2 < __nmatches; ++__i2) + __minlen = std::min(__minlen, + __traits_type::length(__names[__matches[__i2]])); + ++__beg, ++__pos; + if (__pos < __minlen && __beg != __end) + for (size_t __i3 = 0; __i3 < __nmatches;) + { + __name = __names[__matches[__i3]]; + if (!(__name[__pos] == *__beg)) + __matches[__i3] = __matches[--__nmatches]; + else + ++__i3; + } + else + break; + } + + if (__nmatches == 1) + { + // Make sure found name is completely extracted. + ++__beg, ++__pos; + __name = __names[__matches[0]]; + const size_t __len = __traits_type::length(__name); + while (__pos < __len && __beg != __end && __name[__pos] == *__beg) + ++__beg, ++__pos; + + if (__len == __pos) + __member = __matches[0]; + else + __testvalid = false; + } + else + __testvalid = false; + if (!__testvalid) + __err |= ios_base::failbit; + + return __beg; + } + + template + _InIter + time_get<_CharT, _InIter>:: + do_get_time(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const char_type* __times[2]; + __tp._M_time_formats(__times); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __times[0]); + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + _InIter + time_get<_CharT, _InIter>:: + do_get_date(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const char_type* __dates[2]; + __tp._M_date_formats(__dates); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __dates[0]); + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + _InIter + time_get<_CharT, _InIter>:: + do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { + typedef char_traits<_CharT> __traits_type; + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const ctype<_CharT>& __ctype = use_facet >(__loc); + const char_type* __days[7]; + __tp._M_days_abbreviated(__days); + int __tmpwday; + ios_base::iostate __tmperr = ios_base::goodbit; + __beg = _M_extract_name(__beg, __end, __tmpwday, __days, 7, + __io, __tmperr); + + // Check to see if non-abbreviated name exists, and extract. + // NB: Assumes both _M_days and _M_days_abbreviated organized in + // exact same order, first to last, such that the resulting + // __days array with the same index points to a day, and that + // day's abbreviated form. + // NB: Also assumes that an abbreviated name is a subset of the name. + if (!__tmperr && __beg != __end) + { + size_t __pos = __traits_type::length(__days[__tmpwday]); + __tp._M_days(__days); + const char_type* __name = __days[__tmpwday]; + if (__name[__pos] == *__beg) + { + // Extract the rest of it. + const size_t __len = __traits_type::length(__name); + while (__pos < __len && __beg != __end + && __name[__pos] == *__beg) + ++__beg, ++__pos; + if (__len != __pos) + __tmperr |= ios_base::failbit; + } + } + if (!__tmperr) + __tm->tm_wday = __tmpwday; + else + __err |= ios_base::failbit; + + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + _InIter + time_get<_CharT, _InIter>:: + do_get_monthname(iter_type __beg, iter_type __end, + ios_base& __io, ios_base::iostate& __err, tm* __tm) const + { + typedef char_traits<_CharT> __traits_type; + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const ctype<_CharT>& __ctype = use_facet >(__loc); + const char_type* __months[12]; + __tp._M_months_abbreviated(__months); + int __tmpmon; + ios_base::iostate __tmperr = ios_base::goodbit; + __beg = _M_extract_name(__beg, __end, __tmpmon, __months, 12, + __io, __tmperr); + + // Check to see if non-abbreviated name exists, and extract. + // NB: Assumes both _M_months and _M_months_abbreviated organized in + // exact same order, first to last, such that the resulting + // __months array with the same index points to a month, and that + // month's abbreviated form. + // NB: Also assumes that an abbreviated name is a subset of the name. + if (!__tmperr && __beg != __end) + { + size_t __pos = __traits_type::length(__months[__tmpmon]); + __tp._M_months(__months); + const char_type* __name = __months[__tmpmon]; + if (__name[__pos] == *__beg) + { + // Extract the rest of it. + const size_t __len = __traits_type::length(__name); + while (__pos < __len && __beg != __end + && __name[__pos] == *__beg) + ++__beg, ++__pos; + if (__len != __pos) + __tmperr |= ios_base::failbit; + } + } + if (!__tmperr) + __tm->tm_mon = __tmpmon; + else + __err |= ios_base::failbit; + + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + _InIter + time_get<_CharT, _InIter>:: + do_get_year(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm) const + { + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet >(__loc); + + size_t __i = 0; + int __value = 0; + for (; __beg != __end && __i < 4; ++__beg, ++__i) + { + const char __c = __ctype.narrow(*__beg, '*'); + if (__c >= '0' && __c <= '9') + __value = __value * 10 + (__c - '0'); + else + break; + } + if (__i == 2 || __i == 4) + __tm->tm_year = __i == 2 ? __value : __value - 1900; + else + __err |= ios_base::failbit; + + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } + + template + _OutIter + time_put<_CharT, _OutIter>:: + put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, + const _CharT* __beg, const _CharT* __end) const + { + const locale& __loc = __io._M_getloc(); + ctype<_CharT> const& __ctype = use_facet >(__loc); + for (; __beg != __end; ++__beg) + if (__ctype.narrow(*__beg, 0) != '%') + { + *__s = *__beg; + ++__s; + } + else if (++__beg != __end) + { + char __format; + char __mod = 0; + const char __c = __ctype.narrow(*__beg, 0); + if (__c != 'E' && __c != 'O') + __format = __c; + else if (++__beg != __end) + { + __mod = __c; + __format = __ctype.narrow(*__beg, 0); + } + else + break; + __s = this->do_put(__s, __io, __fill, __tm, __format, __mod); + } + else + break; + return __s; + } + + template + _OutIter + time_put<_CharT, _OutIter>:: + do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, + char __format, char __mod) const + { + const locale& __loc = __io._M_getloc(); + ctype<_CharT> const& __ctype = use_facet >(__loc); + __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); + + // NB: This size is arbitrary. Should this be a data member, + // initialized at construction? + const size_t __maxlen = 128; + char_type* __res = + static_cast(__builtin_alloca(sizeof(char_type) * __maxlen)); + + // NB: In IEE 1003.1-200x, and perhaps other locale models, it + // is possible that the format character will be longer than one + // character. Possibilities include 'E' or 'O' followed by a + // format character: if __mod is not the default argument, assume + // it's a valid modifier. + char_type __fmt[4]; + __fmt[0] = __ctype.widen('%'); + if (!__mod) + { + __fmt[1] = __format; + __fmt[2] = char_type(); + } + else + { + __fmt[1] = __mod; + __fmt[2] = __format; + __fmt[3] = char_type(); + } + + __tp._M_put(__res, __maxlen, __fmt, __tm); + + // Write resulting, fully-formatted string to output iterator. + return std::__write(__s, __res, char_traits::length(__res)); + } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class moneypunct; + extern template class moneypunct; + extern template class moneypunct_byname; + extern template class moneypunct_byname; + extern template class _GLIBCXX_LDBL_NAMESPACE money_get; + extern template class _GLIBCXX_LDBL_NAMESPACE money_put; + extern template class __timepunct; + extern template class time_put; + extern template class time_put_byname; + extern template class time_get; + extern template class time_get_byname; + extern template class messages; + extern template class messages_byname; + + extern template + const moneypunct& + use_facet >(const locale&); + + extern template + const moneypunct& + use_facet >(const locale&); + + extern template + const money_put& + use_facet >(const locale&); + + extern template + const money_get& + use_facet >(const locale&); + + extern template + const __timepunct& + use_facet<__timepunct >(const locale&); + + extern template + const time_put& + use_facet >(const locale&); + + extern template + const time_get& + use_facet >(const locale&); + + extern template + const messages& + use_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet<__timepunct >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class moneypunct; + extern template class moneypunct; + extern template class moneypunct_byname; + extern template class moneypunct_byname; + extern template class _GLIBCXX_LDBL_NAMESPACE money_get; + extern template class _GLIBCXX_LDBL_NAMESPACE money_put; + extern template class __timepunct; + extern template class time_put; + extern template class time_put_byname; + extern template class time_get; + extern template class time_get_byname; + extern template class messages; + extern template class messages_byname; + + extern template + const moneypunct& + use_facet >(const locale&); + + extern template + const moneypunct& + use_facet >(const locale&); + + extern template + const money_put& + use_facet >(const locale&); + + extern template + const money_get& + use_facet >(const locale&); + + extern template + const __timepunct& + use_facet<__timepunct >(const locale&); + + extern template + const time_put& + use_facet >(const locale&); + + extern template + const time_get& + use_facet >(const locale&); + + extern template + const messages& + use_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet<__timepunct >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); + + extern template + bool + has_facet >(const locale&); +#endif +#endif + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/libstdc++-v3/include/std/fstream b/libstdc++-v3/include/std/fstream index 0687905e262..170c6d66049 100644 --- a/libstdc++-v3/include/std/fstream +++ b/libstdc++-v3/include/std/fstream @@ -44,7 +44,6 @@ #include #include -#include // For codecvt #include // For BUFSIZ #include // For __basic_file, __c_lock diff --git a/libstdc++-v3/include/std/istream b/libstdc++-v3/include/std/istream index 9cd2549b0a3..a3e074a7b85 100644 --- a/libstdc++-v3/include/std/istream +++ b/libstdc++-v3/include/std/istream @@ -43,7 +43,6 @@ #pragma GCC system_header #include -#include #include _GLIBCXX_BEGIN_NAMESPACE(std) @@ -837,6 +836,7 @@ _GLIBCXX_END_NAMESPACE #ifndef _GLIBCXX_EXPORT_TEMPLATE # include +# include #endif #endif /* _GLIBCXX_ISTREAM */ diff --git a/libstdc++-v3/include/std/locale b/libstdc++-v3/include/std/locale index 328332a86b3..6bfd78d93e9 100644 --- a/libstdc++-v3/include/std/locale +++ b/libstdc++-v3/include/std/locale @@ -1,6 +1,7 @@ // Locale support -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2002, 2003 Free Software Foundation, Inc. +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +// 2006, 2007 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 @@ -43,6 +44,11 @@ #include #include #include -#include +#include + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include +# include +#endif #endif /* _GLIBCXX_LOCALE */ diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream index dc859b13c1e..a4019df8431 100644 --- a/libstdc++-v3/include/std/ostream +++ b/libstdc++-v3/include/std/ostream @@ -43,7 +43,6 @@ #pragma GCC system_header #include -#include #include _GLIBCXX_BEGIN_NAMESPACE(std) @@ -571,6 +570,7 @@ _GLIBCXX_END_NAMESPACE #ifndef _GLIBCXX_EXPORT_TEMPLATE # include +# include #endif #endif /* _GLIBCXX_OSTREAM */ -- 2.11.0