From 0479a46292a4ead8ef2be5a122603432c754cd3d Mon Sep 17 00:00:00 2001 From: Benjamin Kosnik Date: Fri, 1 Sep 2000 08:58:07 +0000 Subject: [PATCH] locale_facets.tcc (_S_build_float_format): Move ... 2000-08-31 Benjamin Kosnik * bits/locale_facets.tcc (_S_build_float_format): Move ... * src/locale.cc: Here. * bits/locale_facets.tcc (num_get::_M_extract): Clean up generic definition. Move specialization to ... * src/locale.cc: Here. * bits/locale_facets.tcc: Move _Format_cache specializations to ... * src/locale.cc: Here. * bits/locale_facets.tcc: Move use_facet specializations to ... * src/locale.cc: Here. * bits/std_locale.h: Note that locale_facets.tcc should be included here, for standards conformance. It may increase compile times though. For the time being, enable. * testsuite/22_locale/facet.cc: New file, some parts commented out for the time being. * mkcheck.in: Append total time to test summary file. * bits/sbuf_iter.h : Formatting tweaks. Clean up static const data member definitions. * src/locale.cc: Add definitions for all missing locale, locale::_Imp, and locale::id static data members. (ctype): Add table_size define. (money_base): Add _S_default_pattern, uglify. * bits/localefwd.h: Add definitions for static members of _Count_ones. * bits/locale_facets.h: Tweaks. * bits/locale_facets.tcc: Tweaks. * bits/string.tcc: Add definition for npos. * bits/ios_base.h: Tweaks. * bits/ios_base.h (ios_base::Init::_M_ios_base_init): Change to _S_ios_base_init. * src/ios.cc: And here. Add _S_local_words definition. Add definitions for __ios_flags const static data. * src/codecvt.cc: Same for __enc_traits. * src/locale-inst.cc: Remove money_base data member definition here. From-SVN: r36093 --- libstdc++-v3/ChangeLog | 40 ++ libstdc++-v3/bits/ios_base.h | 2 +- libstdc++-v3/bits/locale_facets.h | 15 +- libstdc++-v3/bits/locale_facets.tcc | 439 ++------------- libstdc++-v3/bits/localefwd.h | 25 +- libstdc++-v3/bits/sbuf_iter.h | 2 +- libstdc++-v3/bits/std_locale.h | 1 + libstdc++-v3/bits/string.tcc | 18 +- libstdc++-v3/src/codecvt.cc | 3 + libstdc++-v3/src/ios.cc | 45 +- libstdc++-v3/src/locale-inst.cc | 4 - libstdc++-v3/src/locale.cc | 625 ++++++++++++++++++---- libstdc++-v3/testsuite/22_locale/facet.cc | 258 +++++++++ 13 files changed, 941 insertions(+), 536 deletions(-) create mode 100644 libstdc++-v3/testsuite/22_locale/facet.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 3c27ef46c4f..ce442724195 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,43 @@ +2000-08-31 Benjamin Kosnik + + * bits/locale_facets.tcc (_S_build_float_format): Move ... + * src/locale.cc: Here. + * bits/locale_facets.tcc (num_get::_M_extract): Clean up generic + definition. Move specialization to ... + * src/locale.cc: Here. + * bits/locale_facets.tcc: Move _Format_cache specializations to ... + * src/locale.cc: Here. + * bits/locale_facets.tcc: Move use_facet specializations to ... + * src/locale.cc: Here. + + * bits/std_locale.h: Note that locale_facets.tcc should be + included here, for standards conformance. It may increase + compile times though. For the time being, enable. + * testsuite/22_locale/facet.cc: New file, some parts commented out + for the time being. + + * mkcheck.in: Append total time to test summary file. + + * bits/sbuf_iter.h : Formatting tweaks. + + Clean up static const data member definitions. + * src/locale.cc: Add definitions for all missing locale, + locale::_Imp, and locale::id static data members. + (ctype): Add table_size define. + (money_base): Add _S_default_pattern, uglify. + * bits/localefwd.h: Add definitions for static members of _Count_ones. + * bits/locale_facets.h: Tweaks. + * bits/locale_facets.tcc: Tweaks. + * bits/string.tcc: Add definition for npos. + * bits/ios_base.h: Tweaks. + * bits/ios_base.h (ios_base::Init::_M_ios_base_init): Change to + _S_ios_base_init. + * src/ios.cc: And here. Add _S_local_words definition. + Add definitions for __ios_flags const static data. + * src/codecvt.cc: Same for __enc_traits. + * src/locale-inst.cc: Remove money_base data member definition + here. + 2000-08-30 Benjamin Kosnik * testsuite/22_locale/ctype_wchar_t_members.cc (test01): New file. diff --git a/libstdc++-v3/bits/ios_base.h b/libstdc++-v3/bits/ios_base.h index f7b8ca9191c..59462145522 100644 --- a/libstdc++-v3/bits/ios_base.h +++ b/libstdc++-v3/bits/ios_base.h @@ -294,7 +294,7 @@ namespace std { Init(); ~Init(); private: - static int _M_ios_base_init; + static int _S_ios_base_init; filebuf* _M_cout; filebuf* _M_cin; filebuf* _M_cerr; diff --git a/libstdc++-v3/bits/locale_facets.h b/libstdc++-v3/bits/locale_facets.h index db8912400e1..13def7d6053 100644 --- a/libstdc++-v3/bits/locale_facets.h +++ b/libstdc++-v3/bits/locale_facets.h @@ -755,6 +755,7 @@ namespace std get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, void*& __v) const { return do_get(__in, __end, __io, __err, __v); } + static locale::id id; protected: @@ -762,7 +763,8 @@ namespace std // This consolidates the extraction, storage and // error-processing parts of the do_get(...) overloaded member - // functions. NB: this is specialized for char. + // functions. + // NB: This is specialized for char. void _M_extract(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, char* __xtrc, @@ -1454,7 +1456,7 @@ namespace std enum part { none, space, symbol, sign, value }; struct pattern { char field[4]; }; - static const pattern __default_pattern; + static const pattern _S_default_pattern; }; template @@ -1513,16 +1515,11 @@ namespace std virtual pattern do_pos_format() const - { - return money_base::__default_pattern; - } + { return money_base::_S_default_pattern; } virtual pattern do_neg_format() const - { - return money_base::__default_pattern; - } - + { return money_base::_S_default_pattern; } }; template diff --git a/libstdc++-v3/bits/locale_facets.tcc b/libstdc++-v3/bits/locale_facets.tcc index 44f36e78400..199aa16fdac 100644 --- a/libstdc++-v3/bits/locale_facets.tcc +++ b/libstdc++-v3/bits/locale_facets.tcc @@ -173,20 +173,10 @@ namespace std { } template<> - _Format_cache::_Format_cache() - : _M_valid(true), - _M_decimal_point('.'), _M_thousands_sep(','), - _M_truename("true"), _M_falsename("false"), _M_use_grouping(false) - { } + _Format_cache::_Format_cache(); -#ifdef _GLIBCPP_USE_WCHAR_T template<> - _Format_cache::_Format_cache() - : _M_valid(true), - _M_decimal_point(L'.'), _M_thousands_sep(L','), - _M_truename(L"true"), _M_falsename(L"false"), _M_use_grouping(false) - { } -#endif + _Format_cache::_Format_cache(); template void @@ -278,7 +268,7 @@ namespace std template void num_get<_CharT, _InIter>:: - _M_extract(iter_type /*__beg*/, iter_type /*__end*/, ios_base& /*__io*/, + _M_extract(_InIter /*__beg*/, _InIter /*__end*/, ios_base& /*__io*/, ios_base::iostate& /*__err*/, char* /*__xtrc*/, int& /*__base*/, bool /*__fp*/) const { @@ -288,305 +278,13 @@ namespace std template<> void num_get >:: - _M_extract(istreambuf_iterator __beg, - istreambuf_iterator __end, ios_base& __io, - ios_base::iostate& __err, char* __xtrc, - int& __base, bool __fp) const - { - typedef _Format_cache __cache_type; - - // Prepare for possible failure - __xtrc[0] = '\0'; - - // Stage 1: determine a conversion specifier. - ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield; - if (__basefield == ios_base::dec) - __base = 10; - else if (__basefield == ios_base::oct) - __base = 8; - else if (__basefield == ios_base::hex) - __base = 16; - else - __base = 0; - // As far as I can tell, bases other than 10 are not available for - // floating point types - if (__fp) - __base = 10; - - // Stage 2: extract characters. - __cache_type const* __fmt = __cache_type::_S_get(__io); - bool __valid = __beg != __end; - // Fail quickly if !__valid - if (!__valid) - { - __err |= (ios_base::eofbit | ios_base::failbit); - return; - } - - // Acceptable formats for numbers here are based on 22.2.3.1 - string __grp; - int __sep_pos = 0; - int __pos = 0; - const char* __lits = __fmt->_S_literals; - char __c = *__beg; - - // Check first for sign - bool __testsign = false; - if ((__c == __lits[__cache_type::_S_minus]) - || (__c == __lits[__cache_type::_S_plus])) - { - __xtrc[__pos++] = __c; - ++__beg; - __testsign = true; - // whitespace may follow a sign - while ((__beg != __end) && (isspace(*__beg))) - ++__beg; - - // There had better be more to come... - if (__beg == __end) - { - __xtrc[__pos] = '\0'; - __err |= (ios_base::eofbit | ios_base::failbit); - return; - } - } - - bool __testzero = false; // Has there been a leading zero? - - // Now check if first character is a zero - __c = *__beg; - if (__c == __lits[__cache_type::_S_digits]) - { - __testzero = true; - ++__beg; - - // We have to check for __beg == __end here. If so, - // a plain '0' (possibly with a sign) can be got rid of now - if (__beg == __end) - { - __xtrc[__pos++] = __c; - __xtrc[__pos] = '\0'; - __err |= ios_base::eofbit; - return; - } - - // Figure out base for integer types only - // Based on Table 55 of 22.2.2.1.2 - if (!__fp && __base != 10 && __base != 8) - { - // Here, __base == 0 or 16 - __c = *__beg; - if ((__c == __lits[__cache_type::_S_x]) - || (__c == __lits[__cache_type::_S_X])) - { - ++__beg; - __base = 16; - __testzero = false; // "0x" is not a leading zero - } - else if (__base == 0) - __base = 8; - } - - // Remove any more leading zeros - while (__beg != __end) - { - if (*__beg == __lits[__cache_type::_S_digits]) - { - ++__beg; - __testzero = true; - } - else - break; - } - } - else if (__base == 0) // 1st character is not zero - __base = 10; - - // We now seek "units", i.e. digits and thousands separators. - // We may need to know if anything is found here. A leading zero - // (removed by now) would count. - bool __testunits = __testzero; - while (__valid && __beg != __end) - { - __valid = false; - __c = *__beg; - const char* __p = strchr(__fmt->_S_literals, __c); - - // NB: strchr returns true for __c == 0x0 - if (__p && __c) - { - // Try first for acceptable digit; record it if found - if ((__p >= &__lits[__cache_type::_S_digits] - && __p < &__lits[__cache_type::_S_digits + __base]) - || (__p >= &__lits[__cache_type::_S_udigits] - && __p < &__lits[__cache_type::_S_udigits + __base])) - { - __xtrc[__pos++] = __c; - ++__sep_pos; - __valid = true; - __testunits = true; - } - } - else if (__c == __fmt->_M_thousands_sep - && __fmt->_M_use_grouping) - { - // NB: Thousands separator at the beginning of a string - // is a no-no, as is two consecutive thousands - // separators - if (__sep_pos) - { - __grp += static_cast(__sep_pos); - __sep_pos = 0; - __valid = true; - } - else - __err |= ios_base::failbit; - } - if (__valid) - ++__beg; - } - - // Digit grouping is checked. If _M_groupings() doesn't - // match, then get very very upset, and set failbit. - if (__fmt->_M_use_grouping && !__grp.empty()) - { - // Add the ending grouping - __grp += static_cast(__sep_pos); - - // __grp is parsed L to R - // 1,222,444 == __grp of "/1/3/3" - // __fmt->_M_grouping is parsed R to L - // 1,222,444 == __fmt->_M_grouping of "/3" == "/3/3/3" - int __i = 0; - int __j = 0; - const int __len = __fmt->_M_grouping.size(); - int __n = __grp.size(); - bool __test = true; - - // Parsed number groupings have to match the - // numpunct::grouping string exactly, starting at the - // right-most point of the parsed sequence of elements ... - while (__test && __i < __n - 1) - for (__j = 0; __test && __j < __len && __i < __n - 1; ++__j,++__i) - __test &= __fmt->_M_grouping[__j] == __grp[__n - __i - 1]; - // ... but the last parsed grouping can be <= numpunct - // grouping. - __j == __len ? __j = 0 : __j; - __test &= __fmt->_M_grouping[__j] >= __grp[__n - __i - 1]; - - if (!__test) - { - __err |= ios_base::failbit; - __xtrc[__pos] = '\0'; - if (__beg == __end) - __err |= ios_base::eofbit; - return; - } - } - - // If there was nothing but zeros, put one in the output string - if (__testzero && (__pos == 0 || (__pos == 1 && __testsign))) - __xtrc[__pos++] = __lits[__cache_type::_S_digits]; - - // That's it for integer types. Remaining code is for floating point - if (__fp && __beg != __end) - { - __c = *__beg; - // Check first for decimal point. There MUST be one if - // __testunits is false. - bool __testdec = false; // Is there a decimal point - // with digits following it? - if (__c == __fmt->_M_decimal_point) - { - __xtrc[__pos++] = '.'; - ++__beg; - // Now we get any digits after the decimal point - // There MUST be some if __testunits is false. - while (__beg != __end) - { - __c = *__beg; - const char* __p = strchr(__fmt->_S_literals, __c); - if ((__p >= &__lits[__cache_type::_S_digits] - && __p < &__lits[__cache_type::_S_digits + __base]) - || (__p >= &__lits[__cache_type::_S_udigits] - && __p < &__lits[__cache_type::_S_udigits + __base])) - { - __xtrc[__pos++] = __c; - ++__beg; - __testdec = true; - } - else - break; - } - } - if (!__testunits && !__testdec) // Ill formed - { - __err |= ios_base::failbit; - __xtrc[__pos] = '\0'; - if (__beg == __end) - __err |= ios_base::eofbit; - return; - } - - // Now we may find an exponent - if (__beg != __end) - { - __c = *__beg; - if ((__c == __lits[__cache_type::_S_ee]) - || (__c == __lits[__cache_type::_S_Ee])) - { - __xtrc[__pos++] = __c; - ++__beg; - // Now there may be a sign - if (__beg != __end) - { - __c = *__beg; - if ((__c == __lits[__cache_type::_S_minus]) - || (__c == __lits[__cache_type::_S_plus])) - { - __xtrc[__pos++] = __c; - ++__beg; - // whitespace may follow a sign - while ((__beg != __end) && (isspace(*__beg))) - ++__beg; - - } - } - // And now there must be some digits - if (__beg == __end) - { - __xtrc[__pos] = '\0'; - __err |= (ios_base::eofbit | ios_base::failbit); - return; - } - while (__beg != __end) - { - __c = *__beg; - const char* __p = strchr(__fmt->_S_literals, __c); - if ((__p >= &__lits[__cache_type::_S_digits] - && __p < &__lits[__cache_type::_S_digits + __base]) - || (__p >= &__lits[__cache_type::_S_udigits] - && __p < &__lits[__cache_type::_S_udigits + __base])) - { - __xtrc[__pos++] = __c; - ++__beg; - } - else - break; - } - } - } - // Finally, that's it for floating point - } - - // Finish up - __xtrc[__pos] = '\0'; - if (__beg == __end) - __err |= ios_base::eofbit; - } + _M_extract(istreambuf_iterator __beg, + istreambuf_iterator __end, ios_base& __io, + ios_base::iostate& __err, char* __xtrc, int& __base, + bool __fp) const; +#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS // NB: This is an unresolved library defect #17 - // _GLIBCPP_RESOLVE_LIB_DEFECTS template _InIter num_get<_CharT, _InIter>:: @@ -655,6 +353,7 @@ namespace std return __beg; } +#endif #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS template @@ -1063,10 +762,23 @@ namespace std template _OutIter - _S_pad_numeric(_OutIter __s, ios_base::fmtflags __flags, + _S_pad_numeric(_OutIter __s, ios_base::fmtflags /*__flags*/, + _CharT /*__fill*/, int /*__width*/, + _CharT const* /*__first*/, _CharT const* /*__middle*/, + _CharT const* /*__last*/) + { + // XXX Not currently done: non streambuf_iterator + return __s; + } + + // Partial specialization for ostreambuf_iterator. + template + ostreambuf_iterator<_CharT> + _S_pad_numeric(ostreambuf_iterator<_CharT> __s, ios_base::fmtflags __flags, _CharT __fill, int __width, _CharT const* __first, _CharT const* __middle, _CharT const* __last) { + typedef ostreambuf_iterator<_CharT> __out_iter; int __padding = __width - (__last - __first); if (__padding < 0) __padding = 0; @@ -1084,14 +796,14 @@ namespace std } copy(__first, __middle, __s); } - _OutIter __s2 = __s; + __out_iter __s2 = __s; if (__padding && __aflags != ios_base::left) { _S_fill(__s2, __fill, __padding); __padding = 0; } - _OutIter __s3 = copy(__middle, __last, __s2); + __out_iter __s3 = copy(__middle, __last, __s2); if (__padding) _S_fill(__s3, __fill, __padding); return __s3; @@ -1271,55 +983,21 @@ namespace std { return _S_format(__s, __io, __fill, false, __v); } #endif - // The following code uses sprintf() to convert floating point - // values for insertion into a stream. The current implementation - // replicates the code in _S_pad_numeric() (in _S_output_float()) in - // order to prevent having to create a "wide" buffer in addition to - // the "narrow" buffer passed to sprintf(). An optimization would be - // to replace sprintf() with code that works directly on a wide - // buffer and then use _S_pad_numeric() to do the padding. It would - // be good to replace sprintf() anyway to avoid accidental buffer - // overruns and to gain back the efficiency that C++ provides by - // knowing up front the type of the values to insert. This - // implementation follows the C++ standard fairly directly as - // outlined in 22.2.2.2 [lib.locale.num.put] - bool - _S_build_float_format(ios_base& __io, char* __fptr, char __modifier, - streamsize __prec) - { - bool __incl_prec = false; - ios_base::fmtflags __flags = __io.flags(); - *__fptr++ = '%'; - // [22.2.2.2.2] Table 60 - if (__flags & ios_base::showpos) - *__fptr++ = '+'; - if (__flags & ios_base::showpoint) - *__fptr++ = '#'; - // As per [22.2.2.2.2.11] - if (__flags & ios_base::fixed || __prec > 0) - { - *__fptr++ = '.'; - *__fptr++ = '*'; - __incl_prec = true; - } - if (__modifier) - *__fptr++ = __modifier; - ios_base::fmtflags __fltfield = __flags & ios_base::floatfield; - // [22.2.2.2.2] Table 58 - if (__fltfield == ios_base::fixed) - *__fptr++ = 'f'; - else if (__fltfield == ios_base::scientific) - *__fptr++ = (__flags & ios_base::uppercase) ? 'E' : 'e'; - else - *__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g'; - *__fptr = '\0'; - return __incl_prec; - } - - template - _OutIter - _S_output_float(_OutIter __s, ios_base& __io,_CharT __fill, + // Generic helper function + template + static _OutIter + _S_output_float(_OutIter __s, ios_base& __io, _CharT __fill, const char* __sptr, size_t __slen) + { + // XXX Not currently done: non streambuf_iterator + return __s; + } + + // Partial specialization for ostreambuf_iterator. + template + static ostreambuf_iterator<_CharT> + _S_output_float(ostreambuf_iterator<_CharT> __s, ios_base& __io, + _CharT __fill, const char* __sptr, size_t __slen) { size_t __padding = __io.width() > streamsize(__slen) ? __io.width() -__slen : 0; @@ -1364,6 +1042,10 @@ namespace std return __s; } + bool + _S_build_float_format(ios_base& __io, char* __fptr, char __modifier, + streamsize __prec); + template _OutIter num_put<_CharT, _OutIter>:: @@ -1454,7 +1136,7 @@ namespace std template const char* const - _Weekdaynames::_S_names[14] = + _Weekdaynames::_S_names[14] = { "Sun", "Sunday", "Mon", "Monday", "Tue", "Tuesday", "Wed", "Wednesday", @@ -1463,12 +1145,12 @@ namespace std #ifdef _GLIBCPP_USE_WCHAR_T template - struct _Weekdaynames + struct _Weekdaynames { static const wchar_t* const _S_names[14]; }; template const wchar_t* const - _Weekdaynames::_S_names[14] = + _Weekdaynames::_S_names[14] = { L"Sun", L"Sunday", L"Mon", L"Monday", L"Tue", L"Tuesday", L"Wed", L"Wednesday", @@ -1576,31 +1258,16 @@ namespace std locale::id money_put<_CharT, _OutIter>::id; template - locale::id moneypunct<_CharT,_Intl>::id; + locale::id moneypunct<_CharT, _Intl>::id; + + template + const bool moneypunct<_CharT, _Intl>::intl; + + template + const bool moneypunct_byname<_CharT, _Intl>::intl; template locale::id messages<_CharT>::id; - - template<> - const ctype& - use_facet > (const locale& __loc) - { - size_t __i = ctype::id._M_index; - const locale::_Impl* __tmp = __loc._M_impl; - return static_cast&>(* (*(__tmp->_M_facets))[__i]); - } - -#ifdef _GLIBCPP_USE_WCHAR_T - template<> - const ctype& - use_facet< const ctype > (const locale& __loc) - { - size_t __i = ctype::id._M_index; - const locale::_Impl* __tmp = __loc._M_impl; - return static_cast&>(* (*(__tmp->_M_facets))[__i]); - } -#endif - } // std:: #endif /* _CPP_BITS_LOCFACETS_TCC */ diff --git a/libstdc++-v3/bits/localefwd.h b/libstdc++-v3/bits/localefwd.h index 23347be37a7..e7cbd1dedaf 100644 --- a/libstdc++-v3/bits/localefwd.h +++ b/libstdc++-v3/bits/localefwd.h @@ -45,23 +45,32 @@ namespace std // _Count_ones: compile-time computation of number of 1-bits in a value N // This takes only 5 (or 6) instantiations, doing recursive descent // in parallel -- ncm - template> _Shift) > + template> _Shift) > struct _Count_ones; - template - struct _Count_ones<_Num,0,_Mask> - { static const unsigned _S_count = _Num; }; + template + struct _Count_ones<_Num, 0, _Mask> + { static const unsigned int _S_count = _Num; }; - template + template + const unsigned int _Count_ones<_Num, 0, _Mask>::_S_count; + + template struct _Count_ones { - static const unsigned _S_halfcount = + static const unsigned int _S_halfcount = _Count_ones<_Num, _Shift/2, (_Mask^((~_Mask)>>(_Shift/2))) >::_S_count; - static const unsigned _S_count + static const unsigned int _S_count = (_S_halfcount&_Mask) + ((_S_halfcount>>_Shift)&_Mask); }; + template + const unsigned int _Count_ones<_Num, _Shift, _Mask>::_S_count; + + template + const unsigned int _Count_ones<_Num, _Shift, _Mask>::_S_halfcount; + // 22.1.1 Locale template class allocator; template class vector; diff --git a/libstdc++-v3/bits/sbuf_iter.h b/libstdc++-v3/bits/sbuf_iter.h index 14634790439..7a0e1d5db22 100644 --- a/libstdc++-v3/bits/sbuf_iter.h +++ b/libstdc++-v3/bits/sbuf_iter.h @@ -38,7 +38,7 @@ namespace std template class ostreambuf_iterator #if 0 // XXX this is standard: - : public iterator + : public iterator #else : public output_iterator #endif diff --git a/libstdc++-v3/bits/std_locale.h b/libstdc++-v3/bits/std_locale.h index dc3c9aa8af4..7eaba90e7ea 100644 --- a/libstdc++-v3/bits/std_locale.h +++ b/libstdc++-v3/bits/std_locale.h @@ -36,6 +36,7 @@ #include #include +#include #include #endif diff --git a/libstdc++-v3/bits/string.tcc b/libstdc++-v3/bits/string.tcc index 20838e5aa0b..c8857f6891d 100644 --- a/libstdc++-v3/bits/string.tcc +++ b/libstdc++-v3/bits/string.tcc @@ -53,6 +53,17 @@ namespace std basic_string<_CharT, _Traits, _Alloc>:: _Rep::_S_max_size = (((npos - sizeof(_Rep))/sizeof(_CharT)) - 1) / 4; + template + const basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>::npos; + + // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string) + // at static init time (before static ctors are run). + template + basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>::_S_empty_rep_storage[ + (sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)]; + // NB: This is the special case for Input Iterators, used in // istreambuf_iterators, etc. // Input Iterators have a cost structure very different from @@ -396,13 +407,6 @@ namespace std return 2 * (__s <= 16 ? 16 : __s) < __r; } - // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string) - // at static init time (before static ctors are run). - template - basic_string<_CharT, _Traits, _Alloc>::size_type - basic_string<_CharT, _Traits, _Alloc>::_S_empty_rep_storage[ - (sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)]; - template void basic_string<_CharT, _Traits, _Alloc>::resize(size_type __n, _CharT __c) diff --git a/libstdc++-v3/src/codecvt.cc b/libstdc++-v3/src/codecvt.cc index 09f372e522b..839a9763167 100644 --- a/libstdc++-v3/src/codecvt.cc +++ b/libstdc++-v3/src/codecvt.cc @@ -31,6 +31,9 @@ namespace std { + // Definitions for static const data members of __enc_traits. + const int __enc_traits::_S_max_size; + // codecvt required specialization locale::id codecvt::id; diff --git a/libstdc++-v3/src/ios.cc b/libstdc++-v3/src/ios.cc index af0ba56f3ce..ea8fecdc631 100644 --- a/libstdc++-v3/src/ios.cc +++ b/libstdc++-v3/src/ios.cc @@ -1,6 +1,6 @@ // Iostreams base classes -*- C++ -*- -// Copyright (C) 1997-1999 Free Software Foundation, Inc. +// Copyright (C) 1997, 1998, 1999, 2000 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 @@ -37,7 +37,38 @@ namespace std { - // Out-of-line definitions for static const ios_base members. + // Definitions for static const data members of __ios_flags. + const __ios_flags::__int_type __ios_flags::_S_boolalpha; + const __ios_flags::__int_type __ios_flags::_S_dec; + const __ios_flags::__int_type __ios_flags::_S_fixed; + const __ios_flags::__int_type __ios_flags::_S_hex; + const __ios_flags::__int_type __ios_flags::_S_internal; + const __ios_flags::__int_type __ios_flags::_S_left; + const __ios_flags::__int_type __ios_flags::_S_oct; + const __ios_flags::__int_type __ios_flags::_S_right; + const __ios_flags::__int_type __ios_flags::_S_scientific; + const __ios_flags::__int_type __ios_flags::_S_showbase; + const __ios_flags::__int_type __ios_flags::_S_showpoint; + const __ios_flags::__int_type __ios_flags::_S_showpos; + const __ios_flags::__int_type __ios_flags::_S_skipws; + const __ios_flags::__int_type __ios_flags::_S_unitbuf; + const __ios_flags::__int_type __ios_flags::_S_uppercase; + const __ios_flags::__int_type __ios_flags::_S_adjustfield; + const __ios_flags::__int_type __ios_flags::_S_basefield; + const __ios_flags::__int_type __ios_flags::_S_floatfield; + + const __ios_flags::__int_type __ios_flags::_S_badbit; + const __ios_flags::__int_type __ios_flags::_S_eofbit; + const __ios_flags::__int_type __ios_flags::_S_failbit; + + const __ios_flags::__int_type __ios_flags::_S_app; + const __ios_flags::__int_type __ios_flags::_S_ate; + const __ios_flags::__int_type __ios_flags::_S_bin; + const __ios_flags::__int_type __ios_flags::_S_in; + const __ios_flags::__int_type __ios_flags::_S_out; + const __ios_flags::__int_type __ios_flags::_S_trunc; + + // Definitions for static const members of ios_base. const ios_base::fmtflags ios_base::boolalpha; const ios_base::fmtflags ios_base::dec; const ios_base::fmtflags ios_base::fixed; @@ -73,17 +104,19 @@ namespace std { const ios_base::seekdir ios_base::cur; const ios_base::seekdir ios_base::end; + int ios_base::Init::_S_ios_base_init = 0; + + const int ios_base::_S_local_words; + ios_base::failure::failure(const string& __str) { strncpy(_M_name, __str.c_str(), _M_bufsize); _M_name[_M_bufsize - 1] = '\0'; } - int ios_base::Init::_M_ios_base_init = 0; - ios_base::Init::Init() { - if (++_M_ios_base_init == 1) + if (++_S_ios_base_init == 1) { // NB: std_iostream.h creates the four standard files with // default buffers. At this point, we swap out the default @@ -124,7 +157,7 @@ namespace std { ios_base::Init::~Init() { - if (--_M_ios_base_init == 0) + if (--_S_ios_base_init == 0) { cout.flush(); cerr.flush(); diff --git a/libstdc++-v3/src/locale-inst.cc b/libstdc++-v3/src/locale-inst.cc index 7a0af3575cf..20ff88d584f 100644 --- a/libstdc++-v3/src/locale-inst.cc +++ b/libstdc++-v3/src/locale-inst.cc @@ -50,10 +50,6 @@ namespace std { typedef istreambuf_iterator > wibuf_iterator; // moneypunct, money_get, and money_put - - const money_base::pattern - money_base::__default_pattern = {{symbol, sign, none, value}}; - template class moneypunct; template class moneypunct; template class moneypunct_byname; diff --git a/libstdc++-v3/src/locale.cc b/libstdc++-v3/src/locale.cc index 7f9a9ff2b85..2359de8a4cf 100644 --- a/libstdc++-v3/src/locale.cc +++ b/libstdc++-v3/src/locale.cc @@ -42,6 +42,514 @@ #endif namespace std { + // Definitions for static const data members of locale. + const locale::category locale::none; + const locale::category locale::collate; + const locale::category locale::ctype; + const locale::category locale::monetary; + const locale::category locale::numeric; + const locale::category locale::time; + const locale::category locale::messages; + const locale::category locale::all; + + locale::_Impl* locale::_S_global; // init'd to 0 before static ctors run + locale::_Impl* locale::_S_classic; // init'd to 0 before static ctors run + const int locale::_S_num_categories; + + // Definitions for static const data members of locale::_Impl + const locale::id* const + locale::_Impl::_S_id_collate[] = + { + &std::collate::id, +#ifdef _GLIBCPP_USE_WCHAR_T + &std::collate::id, +#endif + 0 + }; + + const locale::id* const + locale::_Impl::_S_id_ctype[] = + { + &std::ctype::id, +#ifdef _GLIBCPP_USE_WCHAR_T + &std::ctype::id, +#endif + &std::codecvt::id, +#ifdef _GLIBCPP_USE_WCHAR_T + &std::codecvt::id, +#endif + 0 + }; + + const locale::id* const + locale::_Impl::_S_id_monetary[] = + { + &std::moneypunct::id, +#ifdef _GLIBCPP_USE_WCHAR_T + &std::moneypunct::id, +#endif + &std::moneypunct::id, +#ifdef _GLIBCPP_USE_WCHAR_T + &std::moneypunct::id, +#endif + &std::money_get::id, +#ifdef _GLIBCPP_USE_WCHAR_T + &std::money_get::id, +#endif + &std::money_put::id, +#ifdef _GLIBCPP_USE_WCHAR_T + &std::money_put::id, +#endif + 0 + }; + + const locale::id* const + locale::_Impl::_S_id_numeric[] = + { + &std::numpunct::id, +#ifdef _GLIBCPP_USE_WCHAR_T + &std::numpunct::id, +#endif + &std::num_get::id, + #ifdef _GLIBCPP_USE_WCHAR_T + &std::num_get::id, +#endif + &std::num_put::id, +#ifdef _GLIBCPP_USE_WCHAR_T + &std::num_put::id, +#endif + 0 + }; + + const locale::id* const + locale::_Impl::_S_id_time[] = + { + &std::time_get::id, +#ifdef _GLIBCPP_USE_WCHAR_T + &std::time_get::id, +#endif + &std::time_put::id, +#ifdef _GLIBCPP_USE_WCHAR_T + &std::time_put::id, +#endif + 0 + }; + + const locale::id* const + locale::_Impl::_S_id_messages[] = + { + &std::time_get::id, +#ifdef _GLIBCPP_USE_WCHAR_T + &std::time_get::id, +#endif + &std::time_put::id, +#ifdef _GLIBCPP_USE_WCHAR_T + &std::time_put::id, +#endif + 0 + }; + + const locale::id* const* const + locale::_Impl::_S_facet_categories[] = + { + // order must match the decl order in class locale. + locale::_Impl::_S_id_collate, + locale::_Impl::_S_id_ctype, + locale::_Impl::_S_id_monetary, + locale::_Impl::_S_id_numeric, + locale::_Impl::_S_id_time, + locale::_Impl::_S_id_messages, + 0 + }; + + // Definitions for static const data members of locale::id + size_t locale::id::_S_highwater; // init'd to 0 by linker + + // Definitions for static const data members of money_base + const money_base::pattern + money_base::_S_default_pattern = {{symbol, sign, none, value}};; + + template<> + _Format_cache::_Format_cache() + : _M_valid(true), + _M_decimal_point('.'), _M_thousands_sep(','), + _M_truename("true"), _M_falsename("false"), _M_use_grouping(false) + { } + +#ifdef _GLIBCPP_USE_WCHAR_T + template<> + _Format_cache::_Format_cache() + : _M_valid(true), + _M_decimal_point(L'.'), _M_thousands_sep(L','), + _M_truename(L"true"), _M_falsename(L"false"), _M_use_grouping(false) + { } +#endif + + template<> + const ctype& + use_facet > (const locale& __loc) + { + size_t __i = ctype::id._M_index; + const locale::_Impl* __tmp = __loc._M_impl; + return static_cast&>(* (*(__tmp->_M_facets))[__i]); + } + +#ifdef _GLIBCPP_USE_WCHAR_T + template<> + const ctype& + use_facet< const ctype > (const locale& __loc) + { + size_t __i = ctype::id._M_index; + const locale::_Impl* __tmp = __loc._M_impl; + return static_cast&>(* (*(__tmp->_M_facets))[__i]); + } +#endif + + template<> + void + num_get >:: + _M_extract(istreambuf_iterator __beg, + istreambuf_iterator __end, ios_base& __io, + ios_base::iostate& __err, char* __xtrc, int& __base, + bool __fp) const + { + typedef _Format_cache __cache_type; + + // Prepare for possible failure + __xtrc[0] = '\0'; + + // Stage 1: determine a conversion specifier. + ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield; + if (__basefield == ios_base::dec) + __base = 10; + else if (__basefield == ios_base::oct) + __base = 8; + else if (__basefield == ios_base::hex) + __base = 16; + else + __base = 0; + // As far as I can tell, bases other than 10 are not available for + // floating point types + if (__fp) + __base = 10; + + // Stage 2: extract characters. + __cache_type const* __fmt = __cache_type::_S_get(__io); + bool __valid = __beg != __end; + // Fail quickly if !__valid + if (!__valid) + { + __err |= (ios_base::eofbit | ios_base::failbit); + return; + } + + // Acceptable formats for numbers here are based on 22.2.3.1 + string __grp; + int __sep_pos = 0; + int __pos = 0; + const char* __lits = __fmt->_S_literals; + char __c = *__beg; + + // Check first for sign + bool __testsign = false; + if ((__c == __lits[__cache_type::_S_minus]) + || (__c == __lits[__cache_type::_S_plus])) + { + __xtrc[__pos++] = __c; + ++__beg; + __testsign = true; + // whitespace may follow a sign + while ((__beg != __end) && (isspace(*__beg))) + ++__beg; + + // There had better be more to come... + if (__beg == __end) + { + __xtrc[__pos] = '\0'; + __err |= (ios_base::eofbit | ios_base::failbit); + return; + } + } + + bool __testzero = false; // Has there been a leading zero? + + // Now check if first character is a zero + __c = *__beg; + if (__c == __lits[__cache_type::_S_digits]) + { + __testzero = true; + ++__beg; + + // We have to check for __beg == __end here. If so, + // a plain '0' (possibly with a sign) can be got rid of now + if (__beg == __end) + { + __xtrc[__pos++] = __c; + __xtrc[__pos] = '\0'; + __err |= ios_base::eofbit; + return; + } + + // Figure out base for integer types only + // Based on Table 55 of 22.2.2.1.2 + if (!__fp && __base != 10 && __base != 8) + { + // Here, __base == 0 or 16 + __c = *__beg; + if ((__c == __lits[__cache_type::_S_x]) + || (__c == __lits[__cache_type::_S_X])) + { + ++__beg; + __base = 16; + __testzero = false; // "0x" is not a leading zero + } + else if (__base == 0) + __base = 8; + } + + // Remove any more leading zeros + while (__beg != __end) + { + if (*__beg == __lits[__cache_type::_S_digits]) + { + ++__beg; + __testzero = true; + } + else + break; + } + } + else if (__base == 0) // 1st character is not zero + __base = 10; + + // We now seek "units", i.e. digits and thousands separators. + // We may need to know if anything is found here. A leading zero + // (removed by now) would count. + bool __testunits = __testzero; + while (__valid && __beg != __end) + { + __valid = false; + __c = *__beg; + const char* __p = strchr(__fmt->_S_literals, __c); + + // NB: strchr returns true for __c == 0x0 + if (__p && __c) + { + // Try first for acceptable digit; record it if found + if ((__p >= &__lits[__cache_type::_S_digits] + && __p < &__lits[__cache_type::_S_digits + __base]) + || (__p >= &__lits[__cache_type::_S_udigits] + && __p < &__lits[__cache_type::_S_udigits + __base])) + { + __xtrc[__pos++] = __c; + ++__sep_pos; + __valid = true; + __testunits = true; + } + } + else if (__c == __fmt->_M_thousands_sep + && __fmt->_M_use_grouping) + { + // NB: Thousands separator at the beginning of a string + // is a no-no, as is two consecutive thousands + // separators + if (__sep_pos) + { + __grp += static_cast(__sep_pos); + __sep_pos = 0; + __valid = true; + } + else + __err |= ios_base::failbit; + } + if (__valid) + ++__beg; + } + + // Digit grouping is checked. If _M_groupings() doesn't + // match, then get very very upset, and set failbit. + if (__fmt->_M_use_grouping && !__grp.empty()) + { + // Add the ending grouping + __grp += static_cast(__sep_pos); + + // __grp is parsed L to R + // 1,222,444 == __grp of "/1/3/3" + // __fmt->_M_grouping is parsed R to L + // 1,222,444 == __fmt->_M_grouping of "/3" == "/3/3/3" + int __i = 0; + int __j = 0; + const int __len = __fmt->_M_grouping.size(); + int __n = __grp.size(); + bool __test = true; + + // Parsed number groupings have to match the + // numpunct::grouping string exactly, starting at the + // right-most point of the parsed sequence of elements ... + while (__test && __i < __n - 1) + for (__j = 0; __test && __j < __len && __i < __n - 1; ++__j,++__i) + __test &= __fmt->_M_grouping[__j] == __grp[__n - __i - 1]; + // ... but the last parsed grouping can be <= numpunct + // grouping. + __j == __len ? __j = 0 : __j; + __test &= __fmt->_M_grouping[__j] >= __grp[__n - __i - 1]; + + if (!__test) + { + __err |= ios_base::failbit; + __xtrc[__pos] = '\0'; + if (__beg == __end) + __err |= ios_base::eofbit; + return; + } + } + + // If there was nothing but zeros, put one in the output string + if (__testzero && (__pos == 0 || (__pos == 1 && __testsign))) + __xtrc[__pos++] = __lits[__cache_type::_S_digits]; + + // That's it for integer types. Remaining code is for floating point + if (__fp && __beg != __end) + { + __c = *__beg; + // Check first for decimal point. There MUST be one if + // __testunits is false. + bool __testdec = false; // Is there a decimal point + // with digits following it? + if (__c == __fmt->_M_decimal_point) + { + __xtrc[__pos++] = '.'; + ++__beg; + // Now we get any digits after the decimal point + // There MUST be some if __testunits is false. + while (__beg != __end) + { + __c = *__beg; + const char* __p = strchr(__fmt->_S_literals, __c); + if ((__p >= &__lits[__cache_type::_S_digits] + && __p < &__lits[__cache_type::_S_digits + __base]) + || (__p >= &__lits[__cache_type::_S_udigits] + && __p < &__lits[__cache_type::_S_udigits + __base])) + { + __xtrc[__pos++] = __c; + ++__beg; + __testdec = true; + } + else + break; + } + } + if (!__testunits && !__testdec) // Ill formed + { + __err |= ios_base::failbit; + __xtrc[__pos] = '\0'; + if (__beg == __end) + __err |= ios_base::eofbit; + return; + } + + // Now we may find an exponent + if (__beg != __end) + { + __c = *__beg; + if ((__c == __lits[__cache_type::_S_ee]) + || (__c == __lits[__cache_type::_S_Ee])) + { + __xtrc[__pos++] = __c; + ++__beg; + // Now there may be a sign + if (__beg != __end) + { + __c = *__beg; + if ((__c == __lits[__cache_type::_S_minus]) + || (__c == __lits[__cache_type::_S_plus])) + { + __xtrc[__pos++] = __c; + ++__beg; + // whitespace may follow a sign + while ((__beg != __end) && (isspace(*__beg))) + ++__beg; + + } + } + // And now there must be some digits + if (__beg == __end) + { + __xtrc[__pos] = '\0'; + __err |= (ios_base::eofbit | ios_base::failbit); + return; + } + while (__beg != __end) + { + __c = *__beg; + const char* __p = strchr(__fmt->_S_literals, __c); + if ((__p >= &__lits[__cache_type::_S_digits] + && __p < &__lits[__cache_type::_S_digits + __base]) + || (__p >= &__lits[__cache_type::_S_udigits] + && __p < &__lits[__cache_type::_S_udigits + __base])) + { + __xtrc[__pos++] = __c; + ++__beg; + } + else + break; + } + } + } + // Finally, that's it for floating point + } + + // Finish up + __xtrc[__pos] = '\0'; + if (__beg == __end) + __err |= ios_base::eofbit; + } + + // The following code uses sprintf() to convert floating point + // values for insertion into a stream. The current implementation + // replicates the code in _S_pad_numeric() (in _S_output_float()) in + // order to prevent having to create a "wide" buffer in addition to + // the "narrow" buffer passed to sprintf(). An optimization would be + // to replace sprintf() with code that works directly on a wide + // buffer and then use _S_pad_numeric() to do the padding. It would + // be good to replace sprintf() anyway to avoid accidental buffer + // overruns and to gain back the efficiency that C++ provides by + // knowing up front the type of the values to insert. This + // implementation follows the C++ standard fairly directly as + // outlined in 22.2.2.2 [lib.locale.num.put] + bool + _S_build_float_format(ios_base& __io, char* __fptr, char __modifier, + streamsize __prec) + { + bool __incl_prec = false; + ios_base::fmtflags __flags = __io.flags(); + *__fptr++ = '%'; + // [22.2.2.2.2] Table 60 + if (__flags & ios_base::showpos) + *__fptr++ = '+'; + if (__flags & ios_base::showpoint) + *__fptr++ = '#'; + // As per [22.2.2.2.2.11] + if (__flags & ios_base::fixed || __prec > 0) + { + *__fptr++ = '.'; + *__fptr++ = '*'; + __incl_prec = true; + } + if (__modifier) + *__fptr++ = __modifier; + ios_base::fmtflags __fltfield = __flags & ios_base::floatfield; + // [22.2.2.2.2] Table 58 + if (__fltfield == ios_base::fixed) + *__fptr++ = 'f'; + else if (__fltfield == ios_base::scientific) + *__fptr++ = (__flags & ios_base::uppercase) ? 'E' : 'e'; + else + *__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g'; + *__fptr = '\0'; + return __incl_prec; + } + // locale::_Impl locale::_Impl:: ~_Impl() throw() @@ -157,116 +665,7 @@ namespace std { __fpr->_M_remove_reference(); __fpr = __fp; } - - // locale facet category descriptions - const locale::id* const - locale::_Impl::_S_id_collate[] = - { - &std::collate::id, -#ifdef _GLIBCPP_USE_WCHAR_T - &std::collate::id, -#endif - 0 - }; - - const locale::id* const - locale::_Impl::_S_id_ctype[] = - { - &std::ctype::id, -#ifdef _GLIBCPP_USE_WCHAR_T - &std::ctype::id, -#endif - &std::codecvt::id, -#ifdef _GLIBCPP_USE_WCHAR_T - &std::codecvt::id, -#endif - 0 - }; - - const locale::id* const - locale::_Impl::_S_id_monetary[] = - { - &std::moneypunct::id, -#ifdef _GLIBCPP_USE_WCHAR_T - &std::moneypunct::id, -#endif - &std::moneypunct::id, -#ifdef _GLIBCPP_USE_WCHAR_T - &std::moneypunct::id, -#endif - &std::money_get::id, -#ifdef _GLIBCPP_USE_WCHAR_T - &std::money_get::id, -#endif - &std::money_put::id, -#ifdef _GLIBCPP_USE_WCHAR_T - &std::money_put::id, -#endif - 0 - }; - - const locale::id* const - locale::_Impl::_S_id_numeric[] = - { - &std::numpunct::id, -#ifdef _GLIBCPP_USE_WCHAR_T - &std::numpunct::id, -#endif - &std::num_get::id, - #ifdef _GLIBCPP_USE_WCHAR_T - &std::num_get::id, -#endif - &std::num_put::id, -#ifdef _GLIBCPP_USE_WCHAR_T - &std::num_put::id, -#endif - 0 - }; - - const locale::id* const - locale::_Impl::_S_id_time[] = - { - &std::time_get::id, -#ifdef _GLIBCPP_USE_WCHAR_T - &std::time_get::id, -#endif - &std::time_put::id, -#ifdef _GLIBCPP_USE_WCHAR_T - &std::time_put::id, -#endif - 0 - }; - - const locale::id* const - locale::_Impl::_S_id_messages[] = - { - &std::time_get::id, -#ifdef _GLIBCPP_USE_WCHAR_T - &std::time_get::id, -#endif - &std::time_put::id, -#ifdef _GLIBCPP_USE_WCHAR_T - &std::time_put::id, -#endif - 0 - }; - - const locale::id* const* const - locale::_Impl::_S_facet_categories[] = - { - // order must match the decl order in class locale. - locale::_Impl::_S_id_collate, - locale::_Impl::_S_id_ctype, - locale::_Impl::_S_id_monetary, - locale::_Impl::_S_id_numeric, - locale::_Impl::_S_id_time, - locale::_Impl::_S_id_messages, - 0 - }; - - locale::_Impl* locale::_S_global; // init'd to 0 before static ctors run - locale::_Impl* locale::_S_classic; // init'd to 0 before static ctors run - + locale:: locale(_Impl* __ip) throw() : _M_impl(__ip) @@ -457,14 +856,13 @@ namespace std { _Bad_use_facet:: ~_Bad_use_facet() throw() { } - size_t locale::id::_S_highwater; // init'd to 0 by linker - - // Platform-specific initialization code for ctype tables. #include locale::id ctype::id; + const size_t ctype::table_size; + ctype:: ~ctype() { if (_M_del) delete[] this->table(); } @@ -501,7 +899,6 @@ namespace std { : ctype(new mask[table_size], true, __refs) { } - locale::id collate::id; collate::collate(size_t __refs) diff --git a/libstdc++-v3/testsuite/22_locale/facet.cc b/libstdc++-v3/testsuite/22_locale/facet.cc new file mode 100644 index 00000000000..1930c50e6fc --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/facet.cc @@ -0,0 +1,258 @@ +// 2000-08-31 Benjamin Kosnik + +// Copyright (C) 2000 Free Software Foundation +// +// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 22.1.1.1.2 - class locale::facet [lib.locale.facet] + +#include +#include +#include + +// 1 a class if a facet if it is publicly derived from another facet +class gnu_input_iterator: public std::iterator +{ + value_type it; +public: + gnu_input_iterator(value_type orig): it(orig) { } + + value_type + operator*() const { return it; } + + reference + operator++(){ return ++it; } + + reference + operator++(int){ ++it; return it; } +}; + +bool +operator==(const gnu_input_iterator& lhs, const gnu_input_iterator& rhs) +{ return true; } + +bool +operator!=(const gnu_input_iterator& lhs, const gnu_input_iterator& rhs) +{ return true; } + +class gnu_output_iterator: public std::iterator +{ + value_type it; +public: + gnu_output_iterator(value_type orig): it(orig) { } + + value_type + operator*(){ return it; } + + gnu_output_iterator& + operator=(value_type obj){ it = obj; return *this; } + + reference + operator++(){ return ++it; } + + reference + operator++(int){ ++it; return it; } + +}; + +class gnu_collate: public std::collate { }; +class gnu_ctype: public std::ctype { }; +class gnu_codecvt: public std::codecvt { }; +class gnu_moneypunct: public std::moneypunct { }; +class gnu_moneypunct_true: public std::moneypunct { }; +class gnu_money_get: public std::money_get { }; +class gnu_money_put: public std::money_put { }; +class gnu_numpunct: public std::numpunct { }; +class gnu_num_get: public std::num_get { }; +class gnu_num_put: public std::num_put { }; +class gnu_time_get: public std::time_get { }; +class gnu_time_put: public std::time_put { }; +class gnu_messages: public std::messages { }; + +class gnu_collate_byname: public std::collate_byname +{ +public: + explicit + gnu_collate_byname(const char* c, size_t refs = 0) + : std::collate_byname(c, refs) { } +}; + +class gnu_ctype_byname: public std::ctype_byname +{ +public: + explicit + gnu_ctype_byname(const char* c, size_t refs = 0) + : std::ctype_byname(c, refs) { } +}; + +class gnu_moneypunct_byname_true: public std::moneypunct_byname +{ +public: + explicit + gnu_moneypunct_byname_true(const char* c, size_t refs = 0) + : std::moneypunct_byname(c, refs) { } +}; + +class gnu_moneypunct_byname_false: public std::moneypunct_byname +{ +public: + explicit + gnu_moneypunct_byname_false(const char* c, size_t refs = 0) + : std::moneypunct_byname(c, refs) { } +}; + + +class gnu_money_get_in: public std::money_get +{ +public: + explicit + gnu_money_get_in(size_t refs = 0) + : std::money_get(refs) { } +}; + +class gnu_money_put_out: public std::money_put +{ +public: + explicit + gnu_money_put_out(size_t refs = 0) + : std::money_put(refs) { } +}; + +class gnu_numpunct_byname: public std::numpunct_byname +{ +public: + explicit + gnu_numpunct_byname(const char* c, size_t refs = 0) + : std::numpunct_byname(c, refs) { } +}; + +class gnu_num_get_in: public std::num_get +{ +public: + explicit + gnu_num_get_in(size_t refs = 0) + : std::num_get(refs) { } +}; + +class gnu_num_put_out: public std::num_put +{ +public: + explicit + gnu_num_put_out(size_t refs = 0) + : std::num_put(refs) { } +}; + +class gnu_time_get_byname: public std::time_get_byname +{ +public: + explicit + gnu_time_get_byname(const char* c, size_t refs = 0) + : std::time_get_byname(c, refs) { } +}; + +class gnu_time_get_in: public std::time_get +{ +public: + explicit + gnu_time_get_in(size_t refs = 0) + : std::time_get(refs) { } +}; + +class gnu_time_put_byname: public std::time_put_byname +{ +public: + explicit + gnu_time_put_byname(const char* c, size_t refs = 0) + : std::time_put_byname(c, refs) { } +}; + +class gnu_time_put_out: public std::time_put +{ +public: + explicit + gnu_time_put_out(size_t refs = 0) + : std::time_put(refs) { } +}; + +class gnu_messages_byname: public std::messages_byname +{ +public: + explicit + gnu_messages_byname(const char* c, size_t refs = 0) + : std::messages_byname(c, refs) { } +}; + + +// 2 or if it is a class deerived from locale:;facet and containing a +// publicly-accessible declaration as follows: +class gnu_facet: public std::locale::facet +{ +public: + static std::locale::id id; +}; + +std::locale::id gnu_facet::id; + +void test01() +{ + // 1 + gnu_collate obj01; + gnu_ctype obj02; + gnu_codecvt obj03; + gnu_moneypunct obj04; + gnu_moneypunct_true obj05; + gnu_money_get obj06; + gnu_money_put obj07; + gnu_numpunct obj08; + gnu_num_get obj09; + gnu_num_put obj10; + gnu_time_get obj11; + gnu_time_put obj12; + gnu_messages obj13; + gnu_time_put_out obj14(0); + gnu_time_put_byname obj15("gnu_message_byname", 0); + gnu_time_get_in obj16(0); + gnu_time_get_byname obj17("gnu_message_byname", 0); + // gnu_num_put_out obj18(0); + // gnu_num_get_in obj19(0); + gnu_numpunct_byname obj20("gnu_message_byname", 0); + gnu_money_put_out obj21(0); + gnu_money_get_in obj22(0); + gnu_moneypunct_byname_false obj23("gnu_message_byname", 0); + gnu_moneypunct_byname_true obj24("gnu_message_byname", 0); + gnu_ctype_byname obj25("gnu_message_byname", 0); + gnu_collate_byname obj26("gnu_message_byname", 0); + gnu_messages_byname obj27("gnu_message_byname", 0); + + // 2 + gnu_facet obj28; +} + +int main () +{ + test01(); + + return 0; +} + + + + + + + +