+2000-08-31 Benjamin Kosnik <bkoz@cygnus.com>
+
+ * 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<ctype> 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<char>): 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 <bkoz@redhat.com>
* testsuite/22_locale/ctype_wchar_t_members.cc (test01): New file.
Init();
~Init();
private:
- static int _M_ios_base_init;
+ static int _S_ios_base_init;
filebuf* _M_cout;
filebuf* _M_cin;
filebuf* _M_cerr;
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:
// 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,
enum part { none, space, symbol, sign, value };
struct pattern { char field[4]; };
- static const pattern __default_pattern;
+ static const pattern _S_default_pattern;
};
template<typename _CharT>
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<typename _CharT, bool _Intl>
{ }
template<>
- _Format_cache<char>::_Format_cache()
- : _M_valid(true),
- _M_decimal_point('.'), _M_thousands_sep(','),
- _M_truename("true"), _M_falsename("false"), _M_use_grouping(false)
- { }
+ _Format_cache<char>::_Format_cache();
-#ifdef _GLIBCPP_USE_WCHAR_T
template<>
- _Format_cache<wchar_t>::_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<wchar_t>::_Format_cache();
template<typename _CharT>
void
template<typename _CharT, typename _InIter>
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
{
template<>
void
num_get<char, istreambuf_iterator<char> >::
- _M_extract(istreambuf_iterator<char> __beg,
- istreambuf_iterator<char> __end, ios_base& __io,
- ios_base::iostate& __err, char* __xtrc,
- int& __base, bool __fp) const
- {
- typedef _Format_cache<char> __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<char>(__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<char>(__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<char> __beg,
+ istreambuf_iterator<char> __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<typename _CharT, typename _InIter>
_InIter
num_get<_CharT, _InIter>::
return __beg;
}
+#endif
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
template<typename _CharT, typename _InIter>
template <typename _CharT, typename _OutIter>
_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 <typename _CharT>
+ 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;
}
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;
{ 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<typename _CharT,typename _OutIter>
- _OutIter
- _S_output_float(_OutIter __s, ios_base& __io,_CharT __fill,
+ // Generic helper function
+ template<typename _CharT, typename _OutIter>
+ 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<typename _CharT>
+ 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;
locale __loc = __io.getloc();
return __s;
}
+ bool
+ _S_build_float_format(ios_base& __io, char* __fptr, char __modifier,
+ streamsize __prec);
+
template <typename _CharT, typename _OutIter>
_OutIter
num_put<_CharT, _OutIter>::
template<typename _Dummy>
const char* const
- _Weekdaynames<char,_Dummy>::_S_names[14] =
+ _Weekdaynames<char, _Dummy>::_S_names[14] =
{
"Sun", "Sunday",
"Mon", "Monday", "Tue", "Tuesday", "Wed", "Wednesday",
#ifdef _GLIBCPP_USE_WCHAR_T
template<typename _Dummy>
- struct _Weekdaynames<wchar_t,_Dummy>
+ struct _Weekdaynames<wchar_t, _Dummy>
{ static const wchar_t* const _S_names[14]; };
template<typename _Dummy>
const wchar_t* const
- _Weekdaynames<wchar_t,_Dummy>::_S_names[14] =
+ _Weekdaynames<wchar_t, _Dummy>::_S_names[14] =
{
L"Sun", L"Sunday",
L"Mon", L"Monday", L"Tue", L"Tuesday", L"Wed", L"Wednesday",
locale::id money_put<_CharT, _OutIter>::id;
template<typename _CharT, bool _Intl>
- locale::id moneypunct<_CharT,_Intl>::id;
-
- template<typename _CharT>
- locale::id messages<_CharT>::id;
+ locale::id moneypunct<_CharT, _Intl>::id;
- template<>
- const ctype<char>&
- use_facet<const ctype<char> > (const locale& __loc)
- {
- size_t __i = ctype<char>::id._M_index;
- const locale::_Impl* __tmp = __loc._M_impl;
- return static_cast<const ctype<char>&>(* (*(__tmp->_M_facets))[__i]);
- }
+ template<typename _CharT, bool _Intl>
+ const bool moneypunct<_CharT, _Intl>::intl;
-#ifdef _GLIBCPP_USE_WCHAR_T
- template<>
- const ctype<wchar_t>&
- use_facet< const ctype<wchar_t> > (const locale& __loc)
- {
- size_t __i = ctype<wchar_t>::id._M_index;
- const locale::_Impl* __tmp = __loc._M_impl;
- return static_cast<const ctype<wchar_t>&>(* (*(__tmp->_M_facets))[__i]);
- }
-#endif
+ template<typename _CharT, bool _Intl>
+ const bool moneypunct_byname<_CharT, _Intl>::intl;
+ template<typename _CharT>
+ locale::id messages<_CharT>::id;
} // std::
#endif /* _CPP_BITS_LOCFACETS_TCC */
// _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<unsigned _Num, int _Shift = (sizeof(unsigned) * CHAR_BIT)/2,
- unsigned _Mask = (~0u >> _Shift) >
+ template<unsigned int _Num, int _Shift = (sizeof(unsigned) * CHAR_BIT)/2,
+ unsigned int _Mask = (~0u >> _Shift) >
struct _Count_ones;
- template<unsigned _Num, unsigned _Mask>
- struct _Count_ones<_Num,0,_Mask>
- { static const unsigned _S_count = _Num; };
+ template<unsigned int _Num, unsigned int _Mask>
+ struct _Count_ones<_Num, 0, _Mask>
+ { static const unsigned int _S_count = _Num; };
- template<unsigned _Num, int _Shift, unsigned _Mask>
+ template<unsigned int _Num, unsigned int _Mask>
+ const unsigned int _Count_ones<_Num, 0, _Mask>::_S_count;
+
+ template<unsigned int _Num, int _Shift, unsigned int _Mask>
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<unsigned int _Num, int _Shift, unsigned int _Mask>
+ const unsigned int _Count_ones<_Num, _Shift, _Mask>::_S_count;
+
+ template<unsigned int _Num, int _Shift, unsigned int _Mask>
+ const unsigned int _Count_ones<_Num, _Shift, _Mask>::_S_halfcount;
+
// 22.1.1 Locale
template<typename _Tp> class allocator;
template<typename _Tp, typename _Alloc> class vector;
template<typename _CharT, typename _Traits>
class ostreambuf_iterator
#if 0 // XXX this is standard:
- : public iterator<output_iterator_tag,_CharT,void,void,void>
+ : public iterator<output_iterator_tag, _CharT, void, void, void>
#else
: public output_iterator
#endif
#include <bits/localefwd.h>
#include <bits/locale_facets.h>
+#include <bits/locale_facets.tcc>
#include <bits/codecvt.h>
#endif
basic_string<_CharT, _Traits, _Alloc>::
_Rep::_S_max_size = (((npos - sizeof(_Rep))/sizeof(_CharT)) - 1) / 4;
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ 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<typename _CharT, typename _Traits, typename _Alloc>
+ 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
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<typename _CharT, typename _Traits, typename _Alloc>
- 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<typename _CharT, typename _Traits, typename _Alloc>
void
basic_string<_CharT, _Traits, _Alloc>::resize(size_type __n, _CharT __c)
namespace std {
+ // Definitions for static const data members of __enc_traits.
+ const int __enc_traits::_S_max_size;
+
// codecvt<char, char, mbstate_t> required specialization
locale::id codecvt<char, char, mbstate_t>::id;
// 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
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;
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
ios_base::Init::~Init()
{
- if (--_M_ios_base_init == 0)
+ if (--_S_ios_base_init == 0)
{
cout.flush();
cerr.flush();
typedef istreambuf_iterator<wchar_t, char_traits<wchar_t> > wibuf_iterator;
// moneypunct, money_get, and money_put
-
- const money_base::pattern
- money_base::__default_pattern = {{symbol, sign, none, value}};
-
template class moneypunct<char, false>;
template class moneypunct<char, true>;
template class moneypunct_byname<char, false>;
#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<char>::id,
+#ifdef _GLIBCPP_USE_WCHAR_T
+ &std::collate<wchar_t>::id,
+#endif
+ 0
+ };
+
+ const locale::id* const
+ locale::_Impl::_S_id_ctype[] =
+ {
+ &std::ctype<char>::id,
+#ifdef _GLIBCPP_USE_WCHAR_T
+ &std::ctype<wchar_t>::id,
+#endif
+ &std::codecvt<char, char, mbstate_t>::id,
+#ifdef _GLIBCPP_USE_WCHAR_T
+ &std::codecvt<wchar_t, char, mbstate_t>::id,
+#endif
+ 0
+ };
+
+ const locale::id* const
+ locale::_Impl::_S_id_monetary[] =
+ {
+ &std::moneypunct<char, false>::id,
+#ifdef _GLIBCPP_USE_WCHAR_T
+ &std::moneypunct<wchar_t, false>::id,
+#endif
+ &std::moneypunct<char,true >::id,
+#ifdef _GLIBCPP_USE_WCHAR_T
+ &std::moneypunct<wchar_t,true >::id,
+#endif
+ &std::money_get<char>::id,
+#ifdef _GLIBCPP_USE_WCHAR_T
+ &std::money_get<wchar_t>::id,
+#endif
+ &std::money_put<char>::id,
+#ifdef _GLIBCPP_USE_WCHAR_T
+ &std::money_put<wchar_t>::id,
+#endif
+ 0
+ };
+
+ const locale::id* const
+ locale::_Impl::_S_id_numeric[] =
+ {
+ &std::numpunct<char>::id,
+#ifdef _GLIBCPP_USE_WCHAR_T
+ &std::numpunct<wchar_t>::id,
+#endif
+ &std::num_get<char>::id,
+ #ifdef _GLIBCPP_USE_WCHAR_T
+ &std::num_get<wchar_t>::id,
+#endif
+ &std::num_put<char>::id,
+#ifdef _GLIBCPP_USE_WCHAR_T
+ &std::num_put<wchar_t>::id,
+#endif
+ 0
+ };
+
+ const locale::id* const
+ locale::_Impl::_S_id_time[] =
+ {
+ &std::time_get<char>::id,
+#ifdef _GLIBCPP_USE_WCHAR_T
+ &std::time_get<wchar_t>::id,
+#endif
+ &std::time_put<char>::id,
+#ifdef _GLIBCPP_USE_WCHAR_T
+ &std::time_put<wchar_t>::id,
+#endif
+ 0
+ };
+
+ const locale::id* const
+ locale::_Impl::_S_id_messages[] =
+ {
+ &std::time_get<char>::id,
+#ifdef _GLIBCPP_USE_WCHAR_T
+ &std::time_get<wchar_t>::id,
+#endif
+ &std::time_put<char>::id,
+#ifdef _GLIBCPP_USE_WCHAR_T
+ &std::time_put<wchar_t>::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<char>::_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<wchar_t>::_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<char>&
+ use_facet<const ctype<char> > (const locale& __loc)
+ {
+ size_t __i = ctype<char>::id._M_index;
+ const locale::_Impl* __tmp = __loc._M_impl;
+ return static_cast<const ctype<char>&>(* (*(__tmp->_M_facets))[__i]);
+ }
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+ template<>
+ const ctype<wchar_t>&
+ use_facet< const ctype<wchar_t> > (const locale& __loc)
+ {
+ size_t __i = ctype<wchar_t>::id._M_index;
+ const locale::_Impl* __tmp = __loc._M_impl;
+ return static_cast<const ctype<wchar_t>&>(* (*(__tmp->_M_facets))[__i]);
+ }
+#endif
+
+ template<>
+ void
+ num_get<char, istreambuf_iterator<char> >::
+ _M_extract(istreambuf_iterator<char> __beg,
+ istreambuf_iterator<char> __end, ios_base& __io,
+ ios_base::iostate& __err, char* __xtrc, int& __base,
+ bool __fp) const
+ {
+ typedef _Format_cache<char> __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<char>(__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<char>(__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()
__fpr->_M_remove_reference();
__fpr = __fp;
}
-
- // locale facet category descriptions
- const locale::id* const
- locale::_Impl::_S_id_collate[] =
- {
- &std::collate<char>::id,
-#ifdef _GLIBCPP_USE_WCHAR_T
- &std::collate<wchar_t>::id,
-#endif
- 0
- };
-
- const locale::id* const
- locale::_Impl::_S_id_ctype[] =
- {
- &std::ctype<char>::id,
-#ifdef _GLIBCPP_USE_WCHAR_T
- &std::ctype<wchar_t>::id,
-#endif
- &std::codecvt<char, char, mbstate_t>::id,
-#ifdef _GLIBCPP_USE_WCHAR_T
- &std::codecvt<wchar_t, char, mbstate_t>::id,
-#endif
- 0
- };
-
- const locale::id* const
- locale::_Impl::_S_id_monetary[] =
- {
- &std::moneypunct<char, false>::id,
-#ifdef _GLIBCPP_USE_WCHAR_T
- &std::moneypunct<wchar_t, false>::id,
-#endif
- &std::moneypunct<char,true >::id,
-#ifdef _GLIBCPP_USE_WCHAR_T
- &std::moneypunct<wchar_t,true >::id,
-#endif
- &std::money_get<char>::id,
-#ifdef _GLIBCPP_USE_WCHAR_T
- &std::money_get<wchar_t>::id,
-#endif
- &std::money_put<char>::id,
-#ifdef _GLIBCPP_USE_WCHAR_T
- &std::money_put<wchar_t>::id,
-#endif
- 0
- };
-
- const locale::id* const
- locale::_Impl::_S_id_numeric[] =
- {
- &std::numpunct<char>::id,
-#ifdef _GLIBCPP_USE_WCHAR_T
- &std::numpunct<wchar_t>::id,
-#endif
- &std::num_get<char>::id,
- #ifdef _GLIBCPP_USE_WCHAR_T
- &std::num_get<wchar_t>::id,
-#endif
- &std::num_put<char>::id,
-#ifdef _GLIBCPP_USE_WCHAR_T
- &std::num_put<wchar_t>::id,
-#endif
- 0
- };
-
- const locale::id* const
- locale::_Impl::_S_id_time[] =
- {
- &std::time_get<char>::id,
-#ifdef _GLIBCPP_USE_WCHAR_T
- &std::time_get<wchar_t>::id,
-#endif
- &std::time_put<char>::id,
-#ifdef _GLIBCPP_USE_WCHAR_T
- &std::time_put<wchar_t>::id,
-#endif
- 0
- };
-
- const locale::id* const
- locale::_Impl::_S_id_messages[] =
- {
- &std::time_get<char>::id,
-#ifdef _GLIBCPP_USE_WCHAR_T
- &std::time_get<wchar_t>::id,
-#endif
- &std::time_put<char>::id,
-#ifdef _GLIBCPP_USE_WCHAR_T
- &std::time_put<wchar_t>::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)
_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 <ctype.cc>
locale::id ctype<char>::id;
+ const size_t ctype<char>::table_size;
+
ctype<char>::
~ctype()
{ if (_M_del) delete[] this->table(); }
: ctype<char>(new mask[table_size], true, __refs)
{ }
-
locale::id collate<char>::id;
collate<char>::collate(size_t __refs)
--- /dev/null
+// 2000-08-31 Benjamin Kosnik <bkoz@redhat.com>
+
+// 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 <locale>
+#include <iterator>
+#include <debug_assert.h>
+
+// 1 a class if a facet if it is publicly derived from another facet
+class gnu_input_iterator: public std::iterator<std::input_iterator_tag, char>
+{
+ 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<std::output_iterator_tag, char>
+{
+ 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<char> { };
+class gnu_ctype: public std::ctype<char> { };
+class gnu_codecvt: public std::codecvt<char, char, mbstate_t> { };
+class gnu_moneypunct: public std::moneypunct<char> { };
+class gnu_moneypunct_true: public std::moneypunct<char, true> { };
+class gnu_money_get: public std::money_get<char> { };
+class gnu_money_put: public std::money_put<char> { };
+class gnu_numpunct: public std::numpunct<char> { };
+class gnu_num_get: public std::num_get<char> { };
+class gnu_num_put: public std::num_put<char> { };
+class gnu_time_get: public std::time_get<char> { };
+class gnu_time_put: public std::time_put<char> { };
+class gnu_messages: public std::messages<char> { };
+
+class gnu_collate_byname: public std::collate_byname<char>
+{
+public:
+ explicit
+ gnu_collate_byname(const char* c, size_t refs = 0)
+ : std::collate_byname<char>(c, refs) { }
+};
+
+class gnu_ctype_byname: public std::ctype_byname<char>
+{
+public:
+ explicit
+ gnu_ctype_byname(const char* c, size_t refs = 0)
+ : std::ctype_byname<char>(c, refs) { }
+};
+
+class gnu_moneypunct_byname_true: public std::moneypunct_byname<char, true>
+{
+public:
+ explicit
+ gnu_moneypunct_byname_true(const char* c, size_t refs = 0)
+ : std::moneypunct_byname<char, true>(c, refs) { }
+};
+
+class gnu_moneypunct_byname_false: public std::moneypunct_byname<char, false>
+{
+public:
+ explicit
+ gnu_moneypunct_byname_false(const char* c, size_t refs = 0)
+ : std::moneypunct_byname<char, false>(c, refs) { }
+};
+
+
+class gnu_money_get_in: public std::money_get<char, gnu_input_iterator>
+{
+public:
+ explicit
+ gnu_money_get_in(size_t refs = 0)
+ : std::money_get<char, gnu_input_iterator>(refs) { }
+};
+
+class gnu_money_put_out: public std::money_put<char, gnu_output_iterator>
+{
+public:
+ explicit
+ gnu_money_put_out(size_t refs = 0)
+ : std::money_put<char, gnu_output_iterator>(refs) { }
+};
+
+class gnu_numpunct_byname: public std::numpunct_byname<char>
+{
+public:
+ explicit
+ gnu_numpunct_byname(const char* c, size_t refs = 0)
+ : std::numpunct_byname<char>(c, refs) { }
+};
+
+class gnu_num_get_in: public std::num_get<char, gnu_input_iterator>
+{
+public:
+ explicit
+ gnu_num_get_in(size_t refs = 0)
+ : std::num_get<char, gnu_input_iterator>(refs) { }
+};
+
+class gnu_num_put_out: public std::num_put<char, gnu_output_iterator>
+{
+public:
+ explicit
+ gnu_num_put_out(size_t refs = 0)
+ : std::num_put<char, gnu_output_iterator>(refs) { }
+};
+
+class gnu_time_get_byname: public std::time_get_byname<char>
+{
+public:
+ explicit
+ gnu_time_get_byname(const char* c, size_t refs = 0)
+ : std::time_get_byname<char>(c, refs) { }
+};
+
+class gnu_time_get_in: public std::time_get<char, gnu_input_iterator>
+{
+public:
+ explicit
+ gnu_time_get_in(size_t refs = 0)
+ : std::time_get<char, gnu_input_iterator>(refs) { }
+};
+
+class gnu_time_put_byname: public std::time_put_byname<char>
+{
+public:
+ explicit
+ gnu_time_put_byname(const char* c, size_t refs = 0)
+ : std::time_put_byname<char>(c, refs) { }
+};
+
+class gnu_time_put_out: public std::time_put<char, gnu_output_iterator>
+{
+public:
+ explicit
+ gnu_time_put_out(size_t refs = 0)
+ : std::time_put<char, gnu_output_iterator>(refs) { }
+};
+
+class gnu_messages_byname: public std::messages_byname<char>
+{
+public:
+ explicit
+ gnu_messages_byname(const char* c, size_t refs = 0)
+ : std::messages_byname<char>(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;
+}
+
+
+
+
+
+
+
+