locale_facets.tcc (_S_build_float_format): Move ...

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.

From-SVN: r36093
This commit is contained in:
Benjamin Kosnik 2000-09-01 08:58:07 +00:00 committed by Benjamin Kosnik
parent b3e45cb1df
commit 0479a46292
13 changed files with 941 additions and 536 deletions

View file

@ -1,3 +1,43 @@
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.

View file

@ -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;

View file

@ -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<typename _CharT>
@ -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<typename _CharT, bool _Intl>

View file

@ -173,20 +173,10 @@ namespace std
{ }
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
@ -278,7 +268,7 @@ namespace std
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
{
@ -288,305 +278,13 @@ namespace std
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>::
@ -655,6 +353,7 @@ namespace std
return __beg;
}
#endif
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
template<typename _CharT, typename _InIter>
@ -1063,10 +762,23 @@ namespace std
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;
@ -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<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;
@ -1364,6 +1042,10 @@ namespace std
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>::
@ -1454,7 +1136,7 @@ namespace std
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",
@ -1463,12 +1145,12 @@ namespace std
#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",
@ -1576,31 +1258,16 @@ namespace std
locale::id money_put<_CharT, _OutIter>::id;
template<typename _CharT, bool _Intl>
locale::id moneypunct<_CharT,_Intl>::id;
locale::id moneypunct<_CharT, _Intl>::id;
template<typename _CharT, bool _Intl>
const bool moneypunct<_CharT, _Intl>::intl;
template<typename _CharT, bool _Intl>
const bool moneypunct_byname<_CharT, _Intl>::intl;
template<typename _CharT>
locale::id messages<_CharT>::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]);
}
#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
} // std::
#endif /* _CPP_BITS_LOCFACETS_TCC */

View file

@ -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<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;

View file

@ -38,7 +38,7 @@ namespace std
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

View file

@ -36,6 +36,7 @@
#include <bits/localefwd.h>
#include <bits/locale_facets.h>
#include <bits/locale_facets.tcc>
#include <bits/codecvt.h>
#endif

View file

@ -53,6 +53,17 @@ namespace std
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
@ -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<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)

View file

@ -31,6 +31,9 @@
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;

View file

@ -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();

View file

@ -50,10 +50,6 @@ namespace std {
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>;

View file

@ -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<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()
@ -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<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)
@ -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 <ctype.cc>
locale::id ctype<char>::id;
const size_t ctype<char>::table_size;
ctype<char>::
~ctype()
{ if (_M_del) delete[] this->table(); }
@ -501,7 +899,6 @@ namespace std {
: ctype<char>(new mask[table_size], true, __refs)
{ }
locale::id collate<char>::id;
collate<char>::collate(size_t __refs)

View file

@ -0,0 +1,258 @@
// 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;
}