+2001-11-27 Benjamin Kosnik <bkoz@redhat.com>
+
+ Numeric facets cleanup.
+ * include/bits/locale_facets.h (__num_base::_S_atoms): Add, remove
+ + and - signs.
+ (__num_base::_M_zero): Add
+ (__num_base::_M_e): Add.
+ (__num_base::_M_E): Add.
+ * include/bits/locale_facets.tcc (num_get::_M_extract): Remove.
+ (num_get::_M_extract_float): New.
+ (num_get::_M_extract_int): New.
+ * src/locale.cc (num_get::_M_extract): Remove.
+
+ * include/bits/locale_facets.tcc (num_put::_M_insert_float):
+ Simplify, use _M_insert.
+ (num_put::do_put(bool)): Simplify, remove __pad.
+ (__pad): Remove.
+ (__pad_output): Change to __pad.
+ * include/bits/ostream.tcc: And here.
+ * src/locale-inst: Remove instantiations.
+
+ * include/bits/locale_facets.h: Move helper functions in to class
+ num_put.
+ (num_put::_M_insert_float): Same, for __output_integer.
+ (num_put::_M_insert_int): Same, for __output_float.
+ (num_put::_M_insert): New.
+ (__num_base): Add.
+ (__num_base::_S_format_float): Move
+ __build_float_format into class __num_base.
+ (__num_base::_S_format_int): Move __build_int_format into class
+ __num_base.
+ * include/bits/locale_facets.tcc (__group_digits): Change to
+ (__add_grouping): This.
+ * src/locale-inst.cc: And here. Tweak instantiations.
+ * src/misc-inst.cc: Remove instantiations.
+
+ * include/bits/ostream.tcc (__pad_char): Rename, adjust inserters
+ for new calling conventions, move to...
+ * include/bits/locale_facets.tcc (__pad_output): Here. Adjust
+ signature to make it useful for both ostream and num_put.
+ (__pad_numeric): Remove.
+ * src/misc-inst.cc: Remove instantiations.
+ * src/locale-inst.cc: Same.
+
+ * include/bits/locale_facets.h (_Numeric_get): Remove.
+ (_Numeric_put): Remove.
+ (num_get::get(short)): Remove.
+ (num_get::get(int)): Remove.
+ (num_get::do_get(short)): Remove.
+ (num_get::do_get(int)): Remove.
+ * include/bits/istream.tcc (istream::operator>>(short)): Fix as
+ per DR 118.
+ (istream::operator>>(int)): Same.
+
+ * include/bits/locale_facets.h (_Format_cache): Remove.
+ * include/bits/locale_facets.tcc: Same.
+ * src/locale.cc: Same.
+ * src/locale-inst.cc: Same.
+ * include/bits/ostream.tcc: Same.
+ * src/ios.cc (ios_base::imbue): Remove here as well.
+
+ * testsuite/22_locale/num_get.cc: New file.
+ * testsuite/22_locale/num_get_members_char.cc: New file.
+ * testsuite/22_locale/num_get_members_wchar_t.cc: New.
+ * testsuite/22_locale/numpunct_members_wchar_t.cc: New file.
+ * testsuite/22_locale/num_put.cc: New file.
+ * testsuite/22_locale/num_put_members_char.cc: New file.
+ * testsuite/22_locale/num_put_members_wchar_t.cc: New file.
+ * testsuite/27_io/ostream_inserter_arith.cc: Fix.
+ * testsuite/27_io/istream_extractor_arith.cc: Fix.
+
2001-11-27 Phil Edwards <pme@gcc.gnu.org>
* docs/html/explanations.html: New section, empty for now.
try
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ long __l;
if (_M_check_facet(_M_fnumget))
- _M_fnumget->get(*this, 0, *this, __err, __n);
+ _M_fnumget->get(*this, 0, *this, __err, __l);
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+ // 118. basic_istream uses nonexistent num_get member functions.
+ if (!(__err & ios_base::failbit)
+ && (numeric_limits<short>::min() <= __l
+ && __l <= numeric_limits<short>::max()))
+ __n = __l;
+ else
+ __err |= ios_base::failbit;
+#endif
this->setstate(__err);
}
catch(exception& __fail)
try
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ long __l;
if (_M_check_facet(_M_fnumget))
- _M_fnumget->get(*this, 0, *this, __err, __n);
+ _M_fnumget->get(*this, 0, *this, __err, __l);
+#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
+ // 118. basic_istream uses nonexistent num_get member functions.
+ if (!(__err & ios_base::failbit)
+ && (numeric_limits<int>::min() <= __l
+ && __l <= numeric_limits<int>::max()))
+ __n = __l;
+ else
+ __err |= ios_base::failbit;
+#endif
this->setstate(__err);
}
catch(exception& __fail)
// Local Variables:
// mode:C++
// End:
-
// 22.2.1.5 Template class codecvt
#include <bits/codecvt.h>
- template<typename _CharT, typename _InIter>
- class _Numeric_get; // forward
- // _Format_cache holds the information extracted from the numpunct<>
- // and moneypunct<> facets in a form optimized for parsing and
- // formatting. It is stored via a void* pointer in the pword()
- // array of an iosbase object passed to the _get and _put facets.
- // NB: contains no user-serviceable parts.
+ class __num_base
+ {
+ public:
+ // String literal of acceptable (narrow) input, for num_get.
+ // "0123456789eEabcdfxABCDFX"
+ static const char _S_atoms[];
+
+ enum
+ {
+ _M_zero,
+ _M_e = _M_zero + 10,
+ _M_E = _M_zero + 11,
+ _M_size = 23 + 1
+ };
+
+ // Construct and return valid scanf format for floating point types.
+ static bool
+ _S_format_float(const ios_base& __io, char* __fptr, char __mod,
+ streamsize __prec);
+
+ // Construct and return valid scanf format for integer types.
+ static void
+ _S_format_int(const ios_base& __io, char* __fptr, char __mod, char __modl);
+ };
+
template<typename _CharT>
- class _Format_cache
+ class numpunct : public locale::facet
{
- public:
+ public:
// Types:
- typedef _CharT char_type;
- typedef char_traits<_CharT> traits_type;
- typedef basic_string<_CharT> string_type;
- typedef typename string_type::size_type size_type;
-
- // Forward decls and Friends:
- friend class locale;
- template<typename _Char, typename _InIter>
- friend class _Numeric_get;
- friend class num_get<_CharT>;
- friend class num_put<_CharT>;
- friend class time_get<_CharT>;
- friend class money_get<_CharT>;
- friend class time_put<_CharT>;
- friend class money_put<_CharT>;
+ typedef _CharT char_type;
+ typedef basic_string<_CharT> string_type;
- // Data Members:
+ static locale::id id;
- // ios_base::pword() reserved cell
- static int _S_pword_ix;
-
- // True iff data members are consistent with the current locale,
- // ie imbue sets this to false.
- bool _M_valid;
-
- // A list of valid numeric literals: for the standard "C" locale,
- // this would usually be: "-+xX0123456789abcdef0123456789ABCDEF"
- static const char _S_literals[];
-
- // NB: Code depends on the order of definitions of the names
- // these are indices into _S_literals, above.
- // This string is formatted for putting, not getting. (output, not input)
- enum
- {
- _S_minus,
- _S_plus,
- _S_x,
- _S_X,
- _S_digits,
- _S_digits_end = _S_digits + 16,
- _S_udigits = _S_digits_end,
- _S_udigits_end = _S_udigits + 16,
- _S_ee = _S_digits + 14, // For scientific notation, 'E'
- _S_Ee = _S_udigits + 14 // For scientific notation, 'e'
- };
-
- // The sign used to separate decimal values: for standard US
- // locales, this would usually be: "."
- // Abstracted from numpunct::decimal_point().
- char_type _M_decimal_point;
-
- // The sign used to separate groups of digits into smaller
- // strings that the eye can parse with less difficulty: for
- // standard US locales, this would usually be: ","
- // Abstracted from numpunct::thousands_sep().
- char_type _M_thousands_sep;
-
- // However the US's "false" and "true" are translated.
- // From numpunct::truename() and numpunct::falsename(), respectively.
- string_type _M_truename;
- string_type _M_falsename;
-
- // If we are checking groupings. This should be equivalent to
- // numpunct::groupings().size() != 0
- bool _M_use_grouping;
-
- // If we are using numpunct's groupings, this is the current
- // grouping string in effect (from numpunct::grouping()).
- string _M_grouping;
-
- _Format_cache();
-
- ~_Format_cache() throw() { }
-
- // Given a member of the ios hierarchy as an argument, extract
- // out all the current formatting information into a
- // _Format_cache object and return a pointer to it.
- static _Format_cache<_CharT>*
- _S_get(ios_base& __ios);
+ private:
+ char_type _M_decimal_point;
+ char_type _M_thousands_sep;
+ string _M_grouping;
+ string_type _M_truename;
+ string_type _M_falsename;
- void
- _M_populate(ios_base&);
+ public:
+ explicit
+ numpunct(size_t __refs = 0) : locale::facet(__refs)
+ { _M_initialize_numpunct(); }
+
+ explicit
+ numpunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs)
+ { _M_initialize_numpunct(__cloc); }
+
+ char_type
+ decimal_point() const
+ { return this->do_decimal_point(); }
+
+ char_type
+ thousands_sep() const
+ { return this->do_thousands_sep(); }
+
+ string
+ grouping() const
+ { return this->do_grouping(); }
+
+ string_type
+ truename() const
+ { return this->do_truename(); }
+
+ string_type
+ falsename() const
+ { return this->do_falsename(); }
+
+ protected:
+ virtual
+ ~numpunct() { }
+
+ virtual char_type
+ do_decimal_point() const
+ { return _M_decimal_point; }
- static void
- _S_callback(ios_base::event __event, ios_base& __ios, int __ix) throw();
+ virtual char_type
+ do_thousands_sep() const
+ { return _M_thousands_sep; }
+
+ virtual string
+ do_grouping() const
+ { return _M_grouping; }
+
+ virtual string_type
+ do_truename() const
+ { return _M_truename; }
+
+ virtual string_type
+ do_falsename() const
+ { return _M_falsename; }
+
+ // For use at construction time only.
+ void
+ _M_initialize_numpunct(__c_locale __cloc = NULL);
};
template<typename _CharT>
- int _Format_cache<_CharT>::_S_pword_ix;
+ locale::id numpunct<_CharT>::id;
+ // NB: Cannot be made generic.
template<typename _CharT>
- const char _Format_cache<_CharT>::
- _S_literals[] = "-+xX0123456789abcdef0123456789ABCDEF";
+ void
+ numpunct<_CharT>::_M_initialize_numpunct(__c_locale)
+ { }
- template<> _Format_cache<char>::_Format_cache();
+ template<>
+ void
+ numpunct<char>::_M_initialize_numpunct(__c_locale __cloc);
#ifdef _GLIBCPP_USE_WCHAR_T
- template<> _Format_cache<wchar_t>::_Format_cache();
+ template<>
+ void
+ numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc);
#endif
- // _Numeric_get is used by num_get, money_get, and time_get to help
- // in parsing out numbers.
- template<typename _CharT, typename _InIter>
- class _Numeric_get
+ template<typename _CharT>
+ class numpunct_byname : public numpunct<_CharT>
{
+ // Data Member.
+ __c_locale _M_c_locale_numpunct;
+
public:
- // Types:
- typedef _CharT char_type;
- typedef _InIter iter_type;
-
- // Forward decls and Friends:
- template<typename _Char, typename _InIterT>
- friend class num_get;
- template<typename _Char, typename _InIterT>
- friend class time_get;
- template<typename _Char, typename _InIterT>
- friend class money_get;
- template<typename _Char, typename _InIterT>
- friend class num_put;
- template<typename _Char, typename _InIterT>
- friend class time_put;
- template<typename _Char, typename _InIterT>
- friend class money_put;
+ typedef _CharT char_type;
+ typedef basic_string<_CharT> string_type;
- private:
explicit
- _Numeric_get() { }
+ numpunct_byname(const char* __s, size_t __refs = 0)
+ : numpunct<_CharT>(__refs)
+ {
+ _S_create_c_locale(_M_c_locale_numpunct, __s);
+ _M_initialize_numpunct(_M_c_locale_numpunct);
+ }
+ protected:
virtual
- ~_Numeric_get() { }
-
- iter_type
- _M_get_digits(iter_type __in, iter_type __end) const;
+ ~numpunct_byname()
+ { _S_destroy_c_locale(_M_c_locale_numpunct); }
};
template<typename _CharT, typename _InIter>
- class num_get : public locale::facet
+ class num_get : public locale::facet, public __num_base
{
public:
// Types:
typedef _CharT char_type;
typedef _InIter iter_type;
- typedef char_traits<_CharT> __traits_type;
static locale::id id;
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, bool& __v) const
- { return do_get(__in, __end, __io, __err, __v); }
-
-#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
- //XXX. What number?
- iter_type
- get(iter_type __in, iter_type __end, ios_base& __io,
- ios_base::iostate& __err, short& __v) const
- { return do_get(__in, __end, __io, __err, __v); }
-
- iter_type
- get(iter_type __in, iter_type __end, ios_base& __io,
- ios_base::iostate& __err, int& __v) const
- { return do_get(__in, __end, __io, __err, __v); }
-#endif
+ { return this->do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, long& __v) const
- { return do_get(__in, __end, __io, __err, __v); }
-
-#ifdef _GLIBCPP_USE_LONG_LONG
- iter_type
- get(iter_type __in, iter_type __end, ios_base& __io,
- ios_base::iostate& __err, long long& __v) const
- { return do_get(__in, __end, __io, __err, __v); }
-#endif
+ { return this->do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, unsigned short& __v) const
- { return do_get(__in, __end, __io, __err, __v); }
+ { return this->do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, unsigned int& __v) const
- { return do_get(__in, __end, __io, __err, __v); }
+ { return this->do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, unsigned long& __v) const
- { return do_get(__in, __end, __io, __err, __v); }
+ { return this->do_get(__in, __end, __io, __err, __v); }
#ifdef _GLIBCPP_USE_LONG_LONG
+ iter_type
+ get(iter_type __in, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, long long& __v) const
+ { return this->do_get(__in, __end, __io, __err, __v); }
+
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, unsigned long long& __v) const
- { return do_get(__in, __end, __io, __err, __v); }
+ { return this->do_get(__in, __end, __io, __err, __v); }
#endif
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, float& __v) const
- { return do_get(__in, __end, __io, __err, __v); }
+ { return this->do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, double& __v) const
- { return do_get(__in, __end, __io, __err, __v); }
+ { return this->do_get(__in, __end, __io, __err, __v); }
iter_type
get(iter_type __in, iter_type __end, ios_base& __io,
ios_base::iostate& __err, long double& __v) const
- { return do_get(__in, __end, __io, __err, __v); }
+ { return this->do_get(__in, __end, __io, __err, __v); }
iter_type
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); }
+ { return this->do_get(__in, __end, __io, __err, __v); }
protected:
virtual ~num_get() { }
- // This consolidates the extraction, storage and
- // error-processing parts of the do_get(...) overloaded member
- // 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,
- int& __base, bool __fp = true) const;
+ _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&,
+ char* __xtrc) const;
+
+ void
+ _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&,
+ char* __xtrc, int& __base) const;
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
-#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
- //XXX. What number?
virtual iter_type
- do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, short&) const;
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const;
+
virtual iter_type
- do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, int&) const;
-#endif
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
+ unsigned short&) const;
+
+ virtual iter_type
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
+ unsigned int&) const;
+
virtual iter_type
- do_get (iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const;
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
+ unsigned long&) const;
+
#ifdef _GLIBCPP_USE_LONG_LONG
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
long long&) const;
-#endif
+
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
- unsigned short&) const;
- virtual iter_type
- do_get(iter_type, iter_type, ios_base&,
- ios_base::iostate& __err, unsigned int&) const;
- virtual iter_type
- do_get(iter_type, iter_type, ios_base&,
- ios_base::iostate& __err, unsigned long&) const;
-#ifdef _GLIBCPP_USE_LONG_LONG
- virtual iter_type
- do_get(iter_type, iter_type, ios_base&,
- ios_base::iostate& __err, unsigned long long&) const;
+ unsigned long long&) const;
#endif
+
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
float&) const;
double&) const;
virtual iter_type
- do_get(iter_type, iter_type, ios_base&,
- ios_base::iostate& __err, long double&) const;
+ do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
+ long double&) const;
virtual iter_type
do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err,
template<typename _CharT, typename _InIter>
locale::id num_get<_CharT, _InIter>::id;
- // Declare specialized extraction member function.
- 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;
-
- // _Numeric_put is used by num_put, money_put, and time_put
- // to help in formatting out numbers.
template<typename _CharT, typename _OutIter>
- class _Numeric_put
- {
- public:
- typedef _CharT char_type;
- typedef _OutIter iter_type;
- protected:
- explicit
- _Numeric_put() { }
-
- virtual
- ~_Numeric_put() { }
- };
-
- template<typename _CharT, typename _OutIter>
- class num_put : public locale::facet
+ class num_put : public locale::facet, public __num_base
{
public:
// Types:
- typedef _CharT char_type;
- typedef _OutIter iter_type;
+ typedef _CharT char_type;
+ typedef _OutIter iter_type;
static locale::id id;
iter_type
put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const
- { return do_put(__s, __f, __fill, __v); }
+ { return this->do_put(__s, __f, __fill, __v); }
iter_type
put(iter_type __s, ios_base& __f, char_type __fill, long __v) const
- { return do_put(__s, __f, __fill, __v); }
+ { return this->do_put(__s, __f, __fill, __v); }
iter_type
put(iter_type __s, ios_base& __f, char_type __fill,
unsigned long __v) const
- { return do_put(__s, __f, __fill, __v); }
+ { return this->do_put(__s, __f, __fill, __v); }
#ifdef _GLIBCPP_USE_LONG_LONG
iter_type
put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const
- { return do_put(__s, __f, __fill, __v); }
+ { return this->do_put(__s, __f, __fill, __v); }
iter_type
put(iter_type __s, ios_base& __f, char_type __fill,
unsigned long long __v) const
- { return do_put(__s, __f, __fill, __v); }
+ { return this->do_put(__s, __f, __fill, __v); }
#endif
iter_type
put(iter_type __s, ios_base& __f, char_type __fill, double __v) const
- { return do_put(__s, __f, __fill, __v); }
+ { return this->do_put(__s, __f, __fill, __v); }
iter_type
put(iter_type __s, ios_base& __f, char_type __fill,
long double __v) const
- { return do_put(__s, __f, __fill, __v); }
+ { return this->do_put(__s, __f, __fill, __v); }
iter_type
put(iter_type __s, ios_base& __f, char_type __fill,
const void* __v) const
- { return do_put(__s, __f, __fill, __v); }
+ { return this->do_put(__s, __f, __fill, __v); }
protected:
+ template<typename _ValueT>
+ iter_type
+ _M_convert_float(iter_type, ios_base& __io, char_type __fill,
+ char __mod, _ValueT __v) const;
+
+ template<typename _ValueT>
+ iter_type
+ _M_convert_int(iter_type, ios_base& __io, char_type __fill,
+ char __mod, char __modl, _ValueT __v) const;
+
+ iter_type
+ _M_widen_float(iter_type, ios_base& __io, char_type __fill, char* __cs,
+ int __len) const;
+
+ iter_type
+ _M_widen_int(iter_type, ios_base& __io, char_type __fill, char* __cs,
+ int __len) const;
+
+ iter_type
+ _M_insert(iter_type, ios_base& __io, char_type __fill,
+ const char_type* __ws, int __len) const;
+
virtual
~num_put() { };
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, long __v) const;
-#ifdef _GLIBCPP_USE_LONG_LONG
virtual iter_type
- do_put(iter_type, ios_base&, char_type __fill, long long __v) const;
-#endif
+ do_put(iter_type, ios_base&, char_type __fill, unsigned long) const;
+#ifdef _GLIBCPP_USE_LONG_LONG
virtual iter_type
- do_put(iter_type, ios_base&, char_type __fill, unsigned long) const;
+ do_put(iter_type, ios_base&, char_type __fill, long long __v) const;
-#ifdef _GLIBCPP_USE_LONG_LONG
virtual iter_type
do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const;
#endif
locale::id num_put<_CharT, _OutIter>::id;
- template<typename _CharT>
- class numpunct : public locale::facet
- {
- public:
- // Types:
- typedef _CharT char_type;
- typedef basic_string<_CharT> string_type;
-
- static locale::id id;
-
- private:
- char_type _M_decimal_point;
- char_type _M_thousands_sep;
- string _M_grouping;
- string_type _M_truename;
- string_type _M_falsename;
-
- public:
- explicit
- numpunct(size_t __refs = 0) : locale::facet(__refs)
- { _M_initialize_numpunct(); }
-
- explicit
- numpunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs)
- { _M_initialize_numpunct(__cloc); }
-
- char_type
- decimal_point() const
- { return this->do_decimal_point(); }
-
- char_type
- thousands_sep() const
- { return this->do_thousands_sep(); }
-
- string
- grouping() const
- { return this->do_grouping(); }
-
- string_type
- truename() const
- { return this->do_truename(); }
-
- string_type
- falsename() const
- { return this->do_falsename(); }
-
- protected:
- virtual
- ~numpunct() { }
-
- virtual char_type
- do_decimal_point() const
- { return _M_decimal_point; }
-
- virtual char_type
- do_thousands_sep() const
- { return _M_thousands_sep; }
-
- virtual string
- do_grouping() const
- { return _M_grouping; }
-
- virtual string_type
- do_truename() const
- { return _M_truename; }
-
- virtual string_type
- do_falsename() const
- { return _M_falsename; }
-
- // For use at construction time only.
- void
- _M_initialize_numpunct(__c_locale __cloc = NULL);
- };
-
- template<typename _CharT>
- locale::id numpunct<_CharT>::id;
-
- // NB: Cannot be made generic.
- template<typename _CharT>
- void
- numpunct<_CharT>::_M_initialize_numpunct(__c_locale)
- { }
-
- template<>
- void
- numpunct<char>::_M_initialize_numpunct(__c_locale __cloc);
-
-#ifdef _GLIBCPP_USE_WCHAR_T
- template<>
- void
- numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc);
-#endif
-
-
- template<typename _CharT>
- class numpunct_byname : public numpunct<_CharT>
- {
- // Data Member.
- __c_locale _M_c_locale_numpunct;
-
- public:
- typedef _CharT char_type;
- typedef basic_string<_CharT> string_type;
-
- explicit
- numpunct_byname(const char* __s, size_t __refs = 0)
- : numpunct<_CharT>(__refs)
- {
- _S_create_c_locale(_M_c_locale_numpunct, __s);
- _M_initialize_numpunct(_M_c_locale_numpunct);
- }
-
- protected:
- virtual
- ~numpunct_byname()
- { _S_destroy_c_locale(_M_c_locale_numpunct); }
- };
-
-
template<typename _CharT>
class collate : public locale::facet
{
};
- struct money_base
+ class money_base
{
+ public:
enum part { none, space, symbol, sign, value };
struct pattern { char field[4]; };
const basic_string<_CharT, _Traits, _Alloc>& __s2) const
{
typedef std::collate<_CharT> __collate_type;
- const __collate_type* __fcoll = &use_facet<__collate_type>(*this);
- return (__fcoll->compare(__s1.data(), __s1.data() + __s1.length(),
- __s2.data(), __s2.data() + __s2.length()) < 0);
+ const __collate_type& __collate = use_facet<__collate_type>(*this);
+ return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
+ __s2.data(), __s2.data() + __s2.length()) < 0);
}
template<typename _Facet>
const _Facet&
use_facet(const locale& __loc)
{
- typedef locale::_Impl::__vec_facet __vec_facet;
size_t __i = _Facet::id._M_index;
- __vec_facet* __facet = __loc._M_impl->_M_facets;
+ locale::_Impl::__vec_facet* __facet = __loc._M_impl->_M_facets;
const locale::facet* __fp = (*__facet)[__i];
if (__fp == 0 || __i >= __facet->size())
__throw_bad_cast();
bool
has_facet(const locale& __loc) throw()
{
- typedef locale::_Impl::__vec_facet __vec_facet;
size_t __i = _Facet::id._M_index;
- __vec_facet* __facet = __loc._M_impl->_M_facets;
+ locale::_Impl::__vec_facet* __facet = __loc._M_impl->_M_facets;
return (__i < __facet->size() && (*__facet)[__i] != 0);
}
- // This member function takes an (w)istreambuf_iterator object and
- // parses it into a generic char array suitable for parsing with
- // strto[l,ll,f,d]. The thought was to encapsulate the conversion
- // into this one function, and thus the num_get::do_get member
- // functions can just adjust for the type of the overloaded
- // argument and process the char array returned from _M_extract.
- // Other things were also considered, including a fused
- // multiply-add loop that would obviate the need for any call to
- // strto... at all: however, it would b e a bit of a pain, because
- // you'd have to be able to return either floating or integral
- // types, etc etc. The current approach seems to be smack dab in
- // the middle between an unoptimized approach using sscanf, and
- // some kind of hyper-optimized approach alluded to above.
-
- // XXX
- // Need to do partial specialization to account for differences
- // between character sets. For char, this is pretty
- // straightforward, but for wchar_t, the conversion to a plain-jane
- // char type is a bit more involved.
template<typename _CharT, typename _InIter>
void
num_get<_CharT, _InIter>::
- _M_extract(_InIter /*__beg*/, _InIter /*__end*/, ios_base& /*__io*/,
- ios_base::iostate& /*__err*/, char* /*__xtrc*/,
- int& /*__base*/, bool /*__fp*/) const
+ _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
+ ios_base::iostate& __err, char* __xtrc) const
{
- // XXX Not currently done: need to expand upon char version below.
+ const locale __loc = __io.getloc();
+ const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+ const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+ int __pos = 0;
+ char_type __c = *__beg;
+
+ // Check first for sign.
+ const char_type __plus = __ctype.widen('+');
+ const char_type __minus = __ctype.widen('-');
+ if ((__c == __plus || __c == __minus) && __beg != __end)
+ {
+ __xtrc[__pos++] = __ctype.narrow(__c, char());
+ __c = *(++__beg);
+ }
+
+ // Next, strip leading zeros.
+ const char_type __zero = __ctype.widen(_S_atoms[_M_zero]);
+ bool __found_zero = false;
+ while (__c == __zero && __beg != __end)
+ {
+ __c = *(++__beg);
+ __found_zero = true;
+ }
+ if (__found_zero)
+ __xtrc[__pos++] = _S_atoms[_M_zero];
+
+ // Only need acceptable digits for floating point numbers.
+ const size_t __len = _M_E - _M_zero + 1;
+ char_type __watoms[__len];
+ __ctype.widen(_S_atoms, _S_atoms + __len, __watoms);
+ bool __found_dec = false;
+ bool __found_sci = false;
+ const char_type __dec = __np.decimal_point();
+
+ string __found_grouping;
+ const string __grouping = __np.grouping();
+ bool __check_grouping = __grouping.size();
+ int __sep_pos = 0;
+ const char_type __sep = __np.thousands_sep();
+
+ while (__beg != __end)
+ {
+ // Only look in digits.
+ typedef char_traits<_CharT> __traits_type;
+ const char_type* __p = __traits_type::find(__watoms, 10, __c);
+
+ // NB: strchr returns true for __c == 0x0
+ if (__p && __c)
+ {
+ // Try first for acceptable digit; record it if found.
+ __xtrc[__pos++] = _S_atoms[__p - __watoms];
+ ++__sep_pos;
+ __c = *(++__beg);
+ }
+ else if (__c == __sep && __check_grouping && !__found_dec)
+ {
+ // NB: Thousands separator at the beginning of a string
+ // is a no-no, as is two consecutive thousands separators.
+ if (__sep_pos)
+ {
+ __found_grouping += static_cast<char>(__sep_pos);
+ __sep_pos = 0;
+ __c = *(++__beg);
+ }
+ else
+ {
+ __err |= ios_base::failbit;
+ break;
+ }
+ }
+ else if (__c == __dec && !__found_dec)
+ {
+ __found_grouping += static_cast<char>(__sep_pos);
+ __xtrc[__pos++] = '.';
+ __c = *(++__beg);
+ __found_dec = true;
+ }
+ else if ((__c == __watoms[_M_e] || __c == __watoms[_M_E])
+ && !__found_sci && __pos)
+ {
+ // Scientific notation.
+ __xtrc[__pos++] = __ctype.narrow(__c, char());
+ __c = *(++__beg);
+
+ // Remove optional plus or minus sign, if they exist.
+ if (__c == __plus || __c == __minus)
+ {
+ __xtrc[__pos++] = __ctype.narrow(__c, char());
+ __c = *(++__beg);
+ }
+ __found_sci = true;
+ }
+ else
+ // Not a valid input item.
+ break;
+ }
+
+ // Digit grouping is checked. If grouping and found_grouping don't
+ // match, then get very very upset, and set failbit.
+ if (__check_grouping && __found_grouping.size())
+ {
+ // Add the ending grouping if a decimal wasn't found.
+ if (!__found_dec)
+ __found_grouping += static_cast<char>(__sep_pos);
+
+ if (!__verify_grouping(__grouping, __found_grouping))
+ {
+ __err |= ios_base::failbit;
+ __xtrc[__pos] = '\0';
+ if (__beg == __end)
+ __err |= ios_base::eofbit;
+ return;
+ }
+ }
+
+ // Finish up
+ __xtrc[__pos] = char_type();
+ if (__beg == __end)
+ __err |= ios_base::eofbit;
}
- template<>
+ template<typename _CharT, typename _InIter>
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;
+ num_get<_CharT, _InIter>::
+ _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
+ ios_base::iostate& __err, char* __xtrc, int& __base) const
+ {
+ // Stage 1: determine a conversion specifier.
+ ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
+ if (__basefield == ios_base::oct)
+ __base = 8;
+ else if (__basefield == ios_base::hex)
+ __base = 16;
+ else
+ __base = 10;
+
+ const locale __loc = __io.getloc();
+ const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+ const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+ int __pos = 0;
+ char_type __c = *__beg;
+
+ // Check first for sign.
+ if ((__c == __ctype.widen('+') || __c == __ctype.widen('-'))
+ && __beg != __end)
+ {
+ __xtrc[__pos++] = __ctype.narrow(__c, char());
+ __c = *(++__beg);
+ }
+
+ // Next, strip leading zeros
+ const char_type __zero = __ctype.widen(_S_atoms[_M_zero]);
+ bool __found_zero = false;
+ while (__base == 10 && __c == __zero && __beg != __end)
+ {
+ __c = *(++__beg);
+ __found_zero = true;
+ }
+ if (__found_zero)
+ {
+ __xtrc[__pos++] = _S_atoms[_M_zero];
+ if (__basefield == 0)
+ {
+ // Depending on what is discovered, the base may change.
+ if (__c == __ctype.widen('x') || __c == __ctype.widen('X'))
+ __base = 16;
+ else
+ __base = 8;
+ }
+ }
+
+ // At this point, base is determined. If not hex, only allow
+ // base digits as valid input.
+ size_t __len;
+ if (__base == 16)
+ __len = _M_size;
+ else
+ __len = __base;
+
+ char_type __watoms[_M_size];
+ __ctype.widen(_S_atoms, _S_atoms + __len, __watoms);
+ string __found_grouping;
+ const string __grouping = __np.grouping();
+ bool __check_grouping = __grouping.size() && __base == 10;
+ int __sep_pos = 0;
+ const char_type __sep = __np.thousands_sep();
+ while (__beg != __end)
+ {
+ typedef char_traits<_CharT> __traits_type;
+ const char_type* __p = __traits_type::find(__watoms, __len, __c);
+
+ // NB: strchr returns true for __c == 0x0
+ if (__p && __c)
+ {
+ // Try first for acceptable digit; record it if found.
+ __xtrc[__pos++] = _S_atoms[__p - __watoms];
+ ++__sep_pos;
+ __c = *(++__beg);
+ }
+ else if (__c == __sep && __check_grouping)
+ {
+ // NB: Thousands separator at the beginning of a string
+ // is a no-no, as is two consecutive thousands separators.
+ if (__sep_pos)
+ {
+ __found_grouping += static_cast<char>(__sep_pos);
+ __sep_pos = 0;
+ __c = *(++__beg);
+ }
+ else
+ {
+ __err |= ios_base::failbit;
+ break;
+ }
+ }
+ else
+ // Not a valid input item.
+ break;
+ }
+
+ // Digit grouping is checked. If grouping and found_grouping don't
+ // match, then get very very upset, and set failbit.
+ if (__check_grouping && __found_grouping.size())
+ {
+ // Add the ending grouping
+ __found_grouping += static_cast<char>(__sep_pos);
+
+ if (!__verify_grouping(__grouping, __found_grouping))
+ {
+ __err |= ios_base::failbit;
+ __xtrc[__pos] = '\0';
+ if (__beg == __end)
+ __err |= ios_base::eofbit;
+ return;
+ }
+ }
+
+ // Finish up
+ __xtrc[__pos] = char_type();
+ if (__beg == __end)
+ __err |= ios_base::eofbit;
+ }
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
- // NB: This is an unresolved library defect #17
//17. Bad bool parsing
template<typename _CharT, typename _InIter>
_InIter
// integral types.
char __xtrc[32] = {'\0'};
int __base;
- _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
+ _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
// Stage 2: convert and store results.
char* __sanity;
// Parse bool values as alphanumeric
else
{
- typedef _Format_cache<char_type> __fcache_type;
- __fcache_type* __fmt = __fcache_type::_S_get(__io);
- const char_type* __true = __fmt->_M_truename.c_str();
- const char_type* __false = __fmt->_M_falsename.c_str();
- const size_t __truelen = __traits_type::length(__true) - 1;
- const size_t __falselen = __traits_type::length(__false) - 1;
-
- for (size_t __pos = 0; __beg != __end; ++__pos)
+ locale __loc = __io.getloc();
+ const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__loc);
+ const char_type* __true = __np.truename().c_str();
+ const char_type* __false = __np.falsename().c_str();
+
+ const size_t __truen = __np.truename().size() - 1;
+ const size_t __falsen = __np.falsename().size() - 1;
+
+ for (size_t __n = 0; __beg != __end; ++__n)
{
char_type __c = *__beg++;
- bool __testf = __c == __false[__pos];
- bool __testt = __c == __true[__pos];
+ bool __testf = __n <= __falsen ? __c == __false[__n] : false;
+ bool __testt = __n <= __truen ? __c == __true[__n] : false;
if (!(__testf || __testt))
{
__err |= ios_base::failbit;
break;
}
- else if (__testf && __pos == __falselen)
+ else if (__testf && __n == __falsen)
{
__v = 0;
break;
}
- else if (__testt && __pos == __truelen)
+ else if (__testt && __n == __truen)
{
__v = 1;
break;
}
#endif
-#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
- //XXX. Which number? Presumably same as in locale_facets.h...
- template<typename _CharT, typename _InIter>
- _InIter
- num_get<_CharT, _InIter>::
- do_get(iter_type __beg, iter_type __end, ios_base& __io,
- ios_base::iostate& __err, short& __v) const
- {
- // Stage 1: extract and determine the conversion specifier.
- // Assuming leading zeros eliminated, thus the size of 32 for
- // integral types.
- char __xtrc[32]= {'\0'};
- int __base;
- _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
-
- // Stage 2: convert and store results.
- char* __sanity;
- errno = 0;
- long __l = strtol(__xtrc, &__sanity, __base);
- if (!(__err & ios_base::failbit)
- && __sanity != __xtrc && *__sanity == '\0' && errno == 0
- && __l >= SHRT_MIN && __l <= SHRT_MAX)
- __v = static_cast<short>(__l);
- else
- __err |= ios_base::failbit;
-
- return __beg;
- }
-
- template<typename _CharT, typename _InIter>
- _InIter
- num_get<_CharT, _InIter>::
- do_get(iter_type __beg, iter_type __end, ios_base& __io,
- ios_base::iostate& __err, int& __v) const
- {
- // Stage 1: extract and determine the conversion specifier.
- // Assuming leading zeros eliminated, thus the size of 32 for
- // integral types.
- char __xtrc[32] = {'\0'};
- int __base;
- _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
-
- // Stage 2: convert and store results.
- char* __sanity;
- errno = 0;
- long __l = strtol(__xtrc, &__sanity, __base);
- if (!(__err & ios_base::failbit)
- && __sanity != __xtrc && *__sanity == '\0' && errno == 0
- && __l >= INT_MIN && __l <= INT_MAX)
- __v = static_cast<int>(__l);
- else
- __err |= ios_base::failbit;
-
- return __beg;
- }
-#endif
-
template<typename _CharT, typename _InIter>
_InIter
num_get<_CharT, _InIter>::
// integral types.
char __xtrc[32]= {'\0'};
int __base;
- _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
+ _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
// Stage 2: convert and store results.
char* __sanity;
return __beg;
}
-#ifdef _GLIBCPP_USE_LONG_LONG
template<typename _CharT, typename _InIter>
_InIter
num_get<_CharT, _InIter>::
do_get(iter_type __beg, iter_type __end, ios_base& __io,
- ios_base::iostate& __err, long long& __v) const
+ ios_base::iostate& __err, unsigned short& __v) const
{
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
char __xtrc[32]= {'\0'};
int __base;
- _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
+ _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
- long long __ll = strtoll(__xtrc, &__sanity, __base);
+ unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
if (!(__err & ios_base::failbit)
- && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
- __v = __ll;
+ && __sanity != __xtrc && *__sanity == '\0' && errno == 0
+ && __ul <= USHRT_MAX)
+ __v = static_cast<unsigned short>(__ul);
else
__err |= ios_base::failbit;
return __beg;
}
-#endif
template<typename _CharT, typename _InIter>
_InIter
num_get<_CharT, _InIter>::
do_get(iter_type __beg, iter_type __end, ios_base& __io,
- ios_base::iostate& __err, unsigned short& __v) const
+ ios_base::iostate& __err, unsigned int& __v) const
{
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
char __xtrc[32]= {'\0'};
int __base;
- _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
+ _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
// Stage 2: convert and store results.
char* __sanity;
unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
if (!(__err & ios_base::failbit)
&& __sanity != __xtrc && *__sanity == '\0' && errno == 0
- && __ul <= USHRT_MAX)
- __v = static_cast<unsigned short>(__ul);
+ && __ul <= UINT_MAX)
+ __v = static_cast<unsigned int>(__ul);
else
__err |= ios_base::failbit;
_InIter
num_get<_CharT, _InIter>::
do_get(iter_type __beg, iter_type __end, ios_base& __io,
- ios_base::iostate& __err, unsigned int& __v) const
+ ios_base::iostate& __err, unsigned long& __v) const
{
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
- char __xtrc[32]= {'\0'};
+ char __xtrc[32] = {'\0'};
int __base;
- _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
+ _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
if (!(__err & ios_base::failbit)
- && __sanity != __xtrc && *__sanity == '\0' && errno == 0
- && __ul <= UINT_MAX)
- __v = static_cast<unsigned int>(__ul);
+ && __sanity != __xtrc && *__sanity == '\0' && errno == 0)
+ __v = __ul;
else
__err |= ios_base::failbit;
return __beg;
}
+#ifdef _GLIBCPP_USE_LONG_LONG
template<typename _CharT, typename _InIter>
_InIter
num_get<_CharT, _InIter>::
do_get(iter_type __beg, iter_type __end, ios_base& __io,
- ios_base::iostate& __err, unsigned long& __v) const
+ ios_base::iostate& __err, long long& __v) const
{
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 32 for
// integral types.
- char __xtrc[32] = {'\0'};
+ char __xtrc[32]= {'\0'};
int __base;
- _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
+ _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
// Stage 2: convert and store results.
char* __sanity;
errno = 0;
- unsigned long __ul = strtoul(__xtrc, &__sanity, __base);
+ long long __ll = strtoll(__xtrc, &__sanity, __base);
if (!(__err & ios_base::failbit)
&& __sanity != __xtrc && *__sanity == '\0' && errno == 0)
- __v = __ul;
+ __v = __ll;
else
__err |= ios_base::failbit;
return __beg;
}
-#ifdef _GLIBCPP_USE_LONG_LONG
template<typename _CharT, typename _InIter>
_InIter
num_get<_CharT, _InIter>::
// integral types.
char __xtrc[32]= {'\0'};
int __base;
- _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
+ _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
// Stage 2: convert and store results.
char* __sanity;
template<typename _CharT, typename _InIter>
_InIter
num_get<_CharT, _InIter>::
- do_get(iter_type __beg, iter_type __end, ios_base& __io,
- ios_base::iostate& __err, float& __v) const
+ do_get(iter_type __beg, iter_type __end, ios_base& __io,
+ ios_base::iostate& __err, float& __v) const
{
// Stage 1: extract and determine the conversion specifier.
// Assuming leading zeros eliminated, thus the size of 256 for
// floating-point types.
char __xtrc[32]= {'\0'};
- int __base;
- _M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
+ _M_extract_float(__beg, __end, __io, __err, __xtrc);
// Stage 2: convert and store results.
char* __sanity;
// Assuming leading zeros eliminated, thus the size of 256 for
// floating-point types.
char __xtrc[32]= {'\0'};
- int __base;
- _M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
+ _M_extract_float(__beg, __end, __io, __err, __xtrc);
// Stage 2: convert and store results.
char* __sanity;
// Assuming leading zeros eliminated, thus the size of 256 for
// floating-point types.
char __xtrc[32]= {'\0'};
- int __base;
- _M_extract(__beg, __end, __io, __err, __xtrc, __base, true);
+ _M_extract_float(__beg, __end, __io, __err, __xtrc);
#if defined(_GLIBCPP_USE_C99) && !defined(__hpux)
// Stage 2: convert and store results.
// integral types.
char __xtrc[32]= {'\0'};
int __base;
- _M_extract(__beg, __end, __io, __err, __xtrc, __base, false);
+ _M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
// Stage 2: convert and store results.
char* __sanity;
return __beg;
}
- // __pad is specialized for ostreambuf_iterator, random access iterator.
+
+ // The following code uses sprintf() to convert floating point
+ // values for insertion into a stream. An optimization would be to
+ // replace sprintf() with code that works directly on a wide buffer
+ // and then use __pad 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]
template<typename _CharT, typename _OutIter>
- inline _OutIter
- __pad(_OutIter __s, _CharT __fill, int __padding);
+ template<typename _ValueT>
+ _OutIter
+ num_put<_CharT, _OutIter>::
+ _M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
+ _ValueT __v) const
+ {
+ const streamsize __max_prec = numeric_limits<_ValueT>::digits10;
+ streamsize __prec = __io.precision();
+ // Protect against sprintf() buffer overflows.
+ if (__prec > __max_prec)
+ __prec = __max_prec;
+
+ // Long enough for the max format spec.
+ char __fbuf[16];
+ char __cs[64];
+ int __len;
+ // [22.2.2.2.2] Stage 1, numeric conversion to character.
+ if (_S_format_float(__io, __fbuf, __mod, __prec))
+ __len = sprintf(__cs, __fbuf, __prec, __v);
+ else
+ __len = sprintf(__cs, __fbuf, __v);
+ return _M_widen_float(__s, __io, __fill, __cs, __len);
+ }
- template<typename _CharT, typename _RaIter>
- _RaIter
- __pad(_RaIter __s, _CharT __fill, int __padding,
- random_access_iterator_tag)
- {
- fill_n(__s, __fill);
- return __s + __padding;
- }
+ template<typename _CharT, typename _OutIter>
+ template<typename _ValueT>
+ _OutIter
+ num_put<_CharT, _OutIter>::
+ _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
+ char __modl, _ValueT __v) const
+ {
+ // [22.2.2.2.2] Stage 1, numeric conversion to character.
+ // Leave room for "+/-," "0x," and commas. This size is
+ // arbitrary, but should work.
+ char __cs[64];
+ // Long enough for the max format spec.
+ char __fbuf[16];
+ _S_format_int(__io, __fbuf, __mod, __modl);
+ int __len = sprintf(__cs, __fbuf, __v);
+ return _M_widen_int(__s, __io, __fill, __cs, __len);
+ }
- template<typename _CharT, typename _OutIter, typename _Tag>
+ template<typename _CharT, typename _OutIter>
_OutIter
- __pad(_OutIter __s, _CharT __fill, int __padding, _Tag)
+ num_put<_CharT, _OutIter>::
+ _M_widen_float(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs,
+ int __len) const
{
- while (--__padding >= 0) { *__s = __fill; ++__s; }
- return __s;
+ // [22.2.2.2.2] Stage 2, convert to char_type, using correct
+ // numpunct.decimal_point() values for '.' and adding grouping.
+ const locale __loc = __io.getloc();
+ const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+ _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * 64));
+ __ctype.widen(__cs, __cs + __len, __ws);
+
+ const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+ // Replace decimal point.
+ const _CharT* __p;
+ if (__p = char_traits<_CharT>::find(__ws, __len, __ctype.widen('.')))
+ __ws[__p - __ws] = __np.decimal_point();
+ return _M_insert(__s, __io, __fill, __ws, __len);
}
template<typename _CharT, typename _OutIter>
- inline _OutIter
- __pad(_OutIter __s, _CharT __fill, int __padding)
+ _OutIter
+ num_put<_CharT, _OutIter>::
+ _M_widen_int(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs,
+ int __len) const
{
- return __pad(__s, __fill, __padding,
- typename iterator_traits<_OutIter>::iterator_category());
+ // [22.2.2.2.2] Stage 2, convert to char_type, using correct
+ // numpunct.decimal_point() values for '.' and adding grouping.
+ const locale __loc = __io.getloc();
+ const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+ _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * 64));
+ _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * 64));
+ __ctype.widen(__cs, __cs + __len, __ws);
+
+ // Add grouping, if necessary.
+ const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+ string __grouping = __np.grouping();
+ ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
+ bool __dec = __basefield != ios_base::oct
+ && __basefield != ios_base::hex;
+ if (__grouping.size() && __dec)
+ {
+ _CharT* __p;
+ __p = __add_grouping(__ws2, __np.thousands_sep(), __grouping.c_str(),
+ __grouping.c_str() + __grouping.size(),
+ __ws, __ws + __len);
+ __len = __p - __ws2;
+ // Switch strings.
+ __ws = __ws2;
+ }
+ return _M_insert(__s, __io, __fill, __ws, __len);
}
+ // For use by integer and floating-point types after they have been
+ // converted into a char_type string.
template<typename _CharT, typename _OutIter>
_OutIter
- __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>
- __pad_numeric(ostreambuf_iterator<_CharT> __s, ios_base::fmtflags __flags,
- _CharT __fill, int __width, _CharT const* __first,
- _CharT const* __middle, _CharT const* __last)
+ num_put<_CharT, _OutIter>::
+ _M_insert(_OutIter __s, ios_base& __io, _CharT __fill, const _CharT* __ws,
+ int __len) const
{
- typedef ostreambuf_iterator<_CharT> __out_iter;
- int __padding = __width - (__last - __first);
- if (__padding < 0)
- __padding = 0;
- ios_base::fmtflags __aflags = __flags & ios_base::adjustfield;
- bool __testfield = __padding == 0 || __aflags == ios_base::left
- || __aflags == ios_base::internal;
-
- // This was needlessly complicated.
- if (__first != __middle)
- {
- if (!__testfield)
- {
- __pad(__s, __fill, __padding);
- __padding = 0;
- }
- copy(__first, __middle, __s);
- }
- __out_iter __s2 = __s;
+ // [22.2.2.2.2] Stage 3.
+ _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * 64));
+ streamsize __w = __io.width();
+ if (__w > static_cast<streamsize>(__len))
+ {
+ __pad(__io, __fill, __ws2, __ws, __w, __len);
+ __len = static_cast<int>(__w);
+ // Switch strings.
+ __ws = __ws2;
+ }
+ __io.width(0);
- if (__padding && __aflags != ios_base::left)
- {
- __pad(__s2, __fill, __padding);
- __padding = 0;
- }
- __out_iter __s3 = copy(__middle, __last, __s2);
- if (__padding)
- __pad(__s3, __fill, __padding);
- return __s3;
+ // [22.2.2.2.2] Stage 4.
+ // Write resulting, fully-formatted string to output iterator.
+ for (int __j = 0; __j < __len; ++__j, ++__s)
+ *__s = __ws[__j];
+ return __s;
}
template<typename _CharT, typename _OutIter>
num_put<_CharT, _OutIter>::
do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
{
- const _Format_cache<_CharT>* __fmt = _Format_cache<_CharT>::_S_get(__io);
ios_base::fmtflags __flags = __io.flags();
-
if ((__flags & ios_base::boolalpha) == 0)
{
unsigned long __uv = __v;
- return __output_integer(__s, __io, __fill, false, __uv);
+ _M_convert_int(__s, __io, __fill, 'u', char_type(), __uv);
}
else
{
- const char_type* __first;
- const char_type* __last;
+ locale __loc = __io.getloc();
+ const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+ const char_type* __ws;
+ int __len;
if (__v)
{
- __first = __fmt->_M_truename.data();
- __last = __first + __fmt->_M_truename.size();
+ __ws = __np.truename().c_str();
+ __len = __np.truename().size();
}
else
{
- __first = __fmt->_M_falsename.data();
- __last = __first + __fmt->_M_falsename.size();
+ __ws = __np.falsename().c_str();
+ __len = __np.falsename().size();
}
- streamsize __width = __io.width(0);
- if (__last - __first >= __width)
- return copy(__first, __last, __s);
- else
- {
- int __padding = __width - (__last - __first);
- ios_base::fmtflags __aflags = __flags & ios_base::adjustfield;
- if (__aflags != ios_base::left)
- {
- __pad(__s, __fill, __padding);
- return copy(__first, __last, __s);
- }
- else
- {
- copy(__first, __last, __s);
- return __pad(__s, __fill, __padding);
- }
- }
- }
- }
-
- template<typename _CharT, typename _OutIter, typename _ValueT>
- _OutIter
- __output_integer(_OutIter __s, ios_base& __io, _CharT __fill, bool __neg,
- _ValueT __v)
- {
- // Leave room for "+/-," "0x," and commas. This size is
- // arbitrary, but should work.
- const int __n = numeric_limits<_ValueT>::digits10 * 2 + 4;
- _CharT* __digits = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
- _CharT* __digits_end = __digits + __n;
- ios_base::fmtflags __flags = __io.flags();
- const _Format_cache<_CharT>* __fmt = _Format_cache<_CharT>::_S_get(__io);
- char const* __table = __fmt->_S_literals + __fmt->_S_digits;
-
- ios_base::fmtflags __basefield = (__flags & __io.basefield);
- _CharT* __sign_end = __digits_end;
- if (__basefield == ios_base::hex)
- {
- if (__flags & ios_base::uppercase)
- __table += 16; // use ABCDEF
- do
- *--__digits_end = __table[__v & 15];
- while ((__v >>= 4) != 0);
- __sign_end = __digits_end;
- if (__flags & ios_base::showbase)
- {
- *--__digits_end = __fmt->_S_literals[__fmt->_S_x +
- ((__flags & ios_base::uppercase) ? 1 : 0)];
- *--__digits_end = __table[0];
- }
- }
- else if (__basefield == ios_base::oct)
- {
- do
- *--__digits_end = __table[__v & 7];
- while ((__v >>= 3) != 0);
- if (__flags & ios_base::showbase
- && static_cast<char>(*__digits_end) != __table[0])
- *--__digits_end = __table[0];
- __sign_end = __digits_end;
- }
- else
- {
- // NB: This is _lots_ faster than using ldiv.
- do
- *--__digits_end = __table[__v % 10];
- while ((__v /= 10) != 0);
- __sign_end = __digits_end;
- // NB: ios_base:hex || ios_base::oct assumed to be unsigned.
- if (__neg || (__flags & ios_base::showpos))
- *--__digits_end = __fmt->_S_literals[__fmt->_S_plus - __neg];
- }
-
- // XXX should specialize!
- if (!__fmt->_M_use_grouping && !__io.width())
- return copy(__digits_end, __digits + __n, __s);
-
- if (!__fmt->_M_use_grouping)
- return __pad_numeric(__s, __flags, __fill, __io.width(0),
- __digits_end, __sign_end, __digits + __n);
-
- _CharT* __p = __digits;
- while (__digits_end < __sign_end)
- *__p++ = *__digits_end++;
- const char* __gbeg = __fmt->_M_grouping.data();
- const char* __gend = __gbeg + __fmt->_M_grouping.size();
- __digits_end = __group_digits(__p, __fmt->_M_thousands_sep,
- __gbeg, __gend,
- __sign_end, __digits + __n);
- return __pad_numeric(__s, __flags, __fill, __io.width(0),
- __digits, __p, __digits_end);
+ _M_insert(__s, __io, __fill, __ws, __len);
+ }
+ return __s;
}
template<typename _CharT, typename _OutIter>
_OutIter
num_put<_CharT, _OutIter>::
do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const
- {
- unsigned long __uv = __v;
- bool __neg = false;
- if (__v < 0)
- {
- __neg = true;
- __uv = -__uv;
- }
- return __output_integer(__s, __io, __fill, __neg, __uv);
- }
+ { return _M_convert_int(__s, __io, __fill, 'd', char_type(), __v); }
template<typename _CharT, typename _OutIter>
_OutIter
num_put<_CharT, _OutIter>::
do_put(iter_type __s, ios_base& __io, char_type __fill,
unsigned long __v) const
- { return __output_integer(__s, __io, __fill, false, __v); }
+ { return _M_convert_int(__s, __io, __fill, 'u', char_type(), __v); }
#ifdef _GLIBCPP_USE_LONG_LONG
template<typename _CharT, typename _OutIter>
_OutIter
num_put<_CharT, _OutIter>::
do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const
- {
- unsigned long long __uv = __v;
- bool __neg = false;
- if (__v < 0)
- {
- __neg = true;
- __uv = -__uv;
- }
- return __output_integer(__s, __b, __fill, __neg, __uv);
- }
+ { return _M_convert_int(__s, __b, __fill, 'd', 'l', __v); }
template<typename _CharT, typename _OutIter>
_OutIter
num_put<_CharT, _OutIter>::
do_put(iter_type __s, ios_base& __io, char_type __fill,
unsigned long long __v) const
- { return __output_integer(__s, __io, __fill, false, __v); }
+ { return _M_convert_int(__s, __io, __fill, 'u', 'l', __v); }
#endif
- // Generic helper function
- template<typename _CharT, typename _Traits, typename _OutIter>
- _OutIter
- __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, typename _Traits>
- ostreambuf_iterator<_CharT, _Traits>
- __output_float(ostreambuf_iterator<_CharT, _Traits> __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();
- ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc);
- ios_base::fmtflags __adjfield = __io.flags() & ios_base::adjustfield;
- const char* const __eptr = __sptr + __slen;
- // [22.2.2.2.2.19] Table 61
- if (__adjfield == ios_base::internal)
- {
- // [22.2.2.2.2.14]; widen()
- if (__sptr < __eptr && (*__sptr == '+' || *__sptr == '-'))
- {
- __s = __ctype.widen(*__sptr);
- ++__s;
- ++__sptr;
- }
- __s = __pad(__s, __fill, __padding);
- __padding = 0;
- }
- else if (__adjfield != ios_base::left)
- {
- __s = __pad(__s, __fill, __padding);
- __padding = 0;
- }
- // the "C" locale decimal character
- char __decimal_point = *(localeconv()->decimal_point);
- const _Format_cache<_CharT>* __fmt = _Format_cache<_CharT>::_S_get(__io);
- for (; __sptr != __eptr; ++__s, ++__sptr)
- {
- // [22.2.2.2.2.17]; decimal point conversion
- if (*__sptr == __decimal_point)
- __s = __fmt->_M_decimal_point;
- // [22.2.2.2.2.14]; widen()
- else
- __s = __ctype.widen(*__sptr);
- }
- // [22.2.2.2.2.19] Table 61
- if (__padding)
- __pad(__s, __fill, __padding);
- __io.width(0);
- return __s;
- }
-
- bool
- __build_float_format(ios_base& __io, char* __fptr, char __modifier,
- streamsize __prec);
-
template<typename _CharT, typename _OutIter>
_OutIter
num_put<_CharT, _OutIter>::
do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
- {
- const streamsize __max_prec = numeric_limits<double>::digits10 + 3;
- streamsize __prec = __io.precision();
- // Protect against sprintf() buffer overflows.
- if (__prec > __max_prec)
- __prec = __max_prec;
- // The *2 provides for signs, exp, 'E', and pad.
- char __sbuf[__max_prec * 2];
- size_t __slen;
- // Long enough for the max format spec.
- char __fbuf[16];
- if (__build_float_format(__io, __fbuf, 0, __prec))
- __slen = sprintf(__sbuf, __fbuf, __prec, __v);
- else
- __slen = sprintf(__sbuf, __fbuf, __v);
- // [22.2.2.2.2] Stages 2-4.
- return __output_float(__s, __io, __fill, __sbuf, __slen);
- }
+ { return _M_convert_float(__s, __io, __fill, char_type(), __v); }
template<typename _CharT, typename _OutIter>
_OutIter
num_put<_CharT, _OutIter>::
- do_put(iter_type __s, ios_base& __io, char_type __fill,
- long double __v) const
- {
- const streamsize __max_prec = numeric_limits<long double>::digits10 + 3;
- streamsize __prec = __io.precision();
- // Protect against sprintf() buffer overflows.
- if (__prec > __max_prec)
- __prec = __max_prec;
- // The *2 provides for signs, exp, 'E', and pad.
- char __sbuf[__max_prec * 2];
- size_t __slen;
- // Long enough for the max format spec.
- char __fbuf[16];
- // 'L' as per [22.2.2.2.2] Table 59
- if (__build_float_format(__io, __fbuf, 'L', __prec))
- __slen = sprintf(__sbuf, __fbuf, __prec, __v);
- else
- __slen = sprintf(__sbuf, __fbuf, __v);
- // [22.2.2.2.2] Stages 2-4
- return __output_float(__s, __io, __fill, __sbuf, __slen);
- }
+ do_put(iter_type __s, ios_base& __io, char_type __fill,
+ long double __v) const
+ { return _M_convert_float(__s, __io, __fill, 'L', __v); }
template<typename _CharT, typename _OutIter>
_OutIter
do_put(iter_type __s, ios_base& __io, char_type __fill,
const void* __v) const
{
- typedef ios_base::fmtflags fmtflags;
- fmtflags __fmt = __io.flags();
- fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield
- | ios_base::uppercase | ios_base::internal);
- __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase));
- try {
- _OutIter __s2 = __output_integer(__s, __io, __fill, false,
- reinterpret_cast<unsigned long>(__v));
- __io.flags(__fmt);
- return __s2;
- }
- catch (...) {
- __io.flags(__fmt);
- __throw_exception_again;
- }
+ ios_base::fmtflags __flags = __io.flags();
+ ios_base::fmtflags __fmt = ~(ios_base::showpos | ios_base::basefield
+ | ios_base::uppercase | ios_base::internal);
+ __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase));
+ try
+ {
+ _M_convert_int(__s, __io, __fill, 'u', char_type(),
+ reinterpret_cast<unsigned long>(__v));
+ __io.flags(__flags);
+ }
+ catch (...)
+ {
+ __io.flags(__flags);
+ __throw_exception_again;
+ }
+ return __s;
}
{
const char_type __sep = __intl ? __mpt.thousands_sep()
: __mpf.thousands_sep();
- const char* __gbeg = __grouping.data();
+ const char* __gbeg = __grouping.c_str();
const char* __gend = __gbeg + __grouping.size();
const int __n = numeric_limits<long double>::digits10 * 2;
- _CharT* __s = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
- _CharT* __s_end = __group_digits(__s, __sep, __gbeg,
- __gend, __beg, __end);
- __value.insert(0, __s, __s_end - __s);
+ _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n));
+ _CharT* __ws_end = __add_grouping(__ws2, __sep, __gbeg,
+ __gend, __beg, __end);
+ __value.insert(0, __ws2, __ws_end - __ws2);
}
else
__value.insert(0, string_type(__beg, __end));
return static_cast<long>(__val);
}
+ // Construct correctly padded string, as per 22.2.2.2.2
+ // Assumes
+ // __newlen > __oldlen
+ // __news is allocated for __newlen size
+ // Used by both num_put and ostream inserters.
+ template<typename _CharT, typename _Traits>
+ void
+ __pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds,
+ const streamsize __newlen, const streamsize __oldlen)
+ {
+ typedef _CharT char_type;
+ typedef _Traits traits_type;
+ typedef typename traits_type::int_type int_type;
+
+ int_type __plen = static_cast<size_t>(__newlen - __oldlen);
+ char_type* __pads = static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __plen));
+ traits_type::assign(__pads, __plen, __fill);
+
+ char_type* __beg;
+ char_type* __end;
+ size_t __mod = 0;
+ size_t __beglen; //either __plen or __oldlen
+ ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
+
+ if (__adjust == ios_base::left)
+ {
+ // Padding last.
+ __beg = const_cast<char_type*>(__olds);
+ __beglen = __oldlen;
+ __end = __pads;
+ }
+ else if (__adjust == ios_base::internal)
+ {
+ // Pad after the sign, if there is one.
+ // Pad after 0[xX], if there is one.
+ // Who came up with these rules, anyway? Jeeze.
+ locale __loc = __io.getloc();
+ const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
+ const char_type __minus = __ctype.widen('-');
+ const char_type __plus = __ctype.widen('+');
+ bool __testsign = __olds[0] == __minus || __olds[0] == __plus;
+ bool __testhex = __ctype.widen('0') == __olds[0]
+ && (__ctype.widen('x') == __olds[1]
+ || __ctype.widen('X') == __olds[1]);
+ if (__testhex)
+ {
+ __news[0] = __olds[0];
+ __news[1] = __olds[1];
+ __mod += 2;
+ __news += 2;
+ __beg = const_cast<char_type*>(__olds + __mod);
+ __beglen = __oldlen - __mod;
+ __end = __pads;
+ }
+ else if (__testsign)
+ {
+ __news[0] = __olds[0] == __plus ? __plus : __minus;
+ ++__mod;
+ ++__news;
+ __beg = __pads;
+ __beglen = __plen;
+ __end = const_cast<char_type*>(__olds + __mod);
+ }
+ else
+ {
+ // Padding first.
+ __beg = __pads;
+ __beglen = __plen;
+ __end = const_cast<char_type*>(__olds);
+ }
+ }
+ else
+ {
+ // Padding first.
+ __beg = __pads;
+ __beglen = __plen;
+ __end = const_cast<char_type*>(__olds);
+ }
+ traits_type::copy(__news, __beg, __beglen);
+ traits_type::copy(__news + __beglen, __end, __newlen - __beglen - __mod);
+ }
+
+ // NB: Can't have default argument on non-member template, and
+ // num_put doesn't have a _Traits template parameter, so this
+ // forwarding template adds in the default template argument.
+ template<typename _CharT>
+ void
+ __pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds,
+ const streamsize __newlen, const streamsize __oldlen)
+ {
+ return __pad<_CharT, char_traits<_CharT> >(__io, __fill, __news,
+ __olds, __newlen, __oldlen);
+ }
+
// Used by both numeric and monetary facets.
// Check to make sure that the __grouping_tmp string constructed in
// money_get or num_get matches the canonical grouping for a given
// only with __gbeg != __gend.
template<typename _CharT>
_CharT*
- __group_digits(_CharT* __s, _CharT __sep,
+ __add_grouping(_CharT* __s, _CharT __sep,
const char* __gbeg, const char* __gend,
const _CharT* __first, const _CharT* __last)
{
if (__last - __first > *__gbeg)
{
- __s = __group_digits(__s, __sep,
+ __s = __add_grouping(__s, __sep,
(__gbeg + 1 == __gend ? __gbeg : __gbeg + 1),
__gend, __first, __last - *__gbeg);
__first = __last - *__gbeg;
*__s++ = __sep;
}
do
- {
- *__s++ = *__first++;
- }
+ *__s++ = *__first++;
while (__first != __last);
return __s;
}
-
- // XXX This stuff needs to be re-examined, heavily modified, or ditched.
- template<typename _CharT>
- _Format_cache<_CharT>::_Format_cache()
- : _M_valid(true), _M_use_grouping(false)
- { }
-
- template<>
- _Format_cache<char>::_Format_cache();
-
- template<>
- _Format_cache<wchar_t>::_Format_cache();
-
- template<typename _CharT>
- void
- _Format_cache<_CharT>::_M_populate(ios_base& __io)
- {
- locale __loc = __io.getloc();
- numpunct<_CharT> const& __np = use_facet<numpunct<_CharT> >(__loc);
- _M_truename = __np.truename();
- _M_falsename = __np.falsename();
- _M_thousands_sep = __np.thousands_sep();
- _M_decimal_point = __np.decimal_point();
- _M_grouping = __np.grouping();
- _M_use_grouping = _M_grouping.size() != 0 && _M_grouping.data()[0] != 0;
- _M_valid = true;
- }
-
- // This function is always called via a pointer installed in
- // an ios_base by ios_base::register_callback.
- template<typename _CharT>
- void
- _Format_cache<_CharT>::
- _S_callback(ios_base::event __ev, ios_base& __ios, int __ix) throw()
- {
- void*& __p = __ios.pword(__ix);
- switch (__ev)
- {
- case ios_base::erase_event:
- delete static_cast<_Format_cache<_CharT>*>(__p);
- __p = 0;
- break;
- case ios_base::copyfmt_event:
- // If just stored zero, the callback would get registered again.
- try
- { __p = new _Format_cache<_CharT>; }
- catch(...)
- { }
- break;
- case ios_base::imbue_event:
- static_cast<_Format_cache<_CharT>*>(__p)->_M_valid = false;
- break;
- }
- }
-
- template<typename _CharT>
- _Format_cache<_CharT>*
- _Format_cache<_CharT>::_S_get(ios_base& __ios)
- {
- if (!_S_pword_ix)
- _S_pword_ix = ios_base::xalloc(); // XXX MT
- void*& __p = __ios.pword(_S_pword_ix);
-
- // XXX What if pword fails? must check failbit, throw.
- if (__p == 0) // XXX MT? maybe sentry takes care of it
- {
- auto_ptr<_Format_cache<_CharT> > __ap(new _Format_cache<_CharT>);
- __ios.register_callback(&_Format_cache<_CharT>::_S_callback,
- _S_pword_ix);
- __p = __ap.release();
- }
- _Format_cache<_CharT>* __ncp = static_cast<_Format_cache<_CharT>*>(__p);
- if (!__ncp->_M_valid)
- __ncp->_M_populate(__ios);
-
- return __ncp;
- }
} // namespace std
#endif
}
// 27.6.2.5.4 Character inserters
-
- // Construct correctly padded string, as per 22.2.2.2.2
- // Similar in theory to __pad_numeric, from num_put, but it doesn't
- // use _S_fill: perhaps it should.
- // Assumes
- // __newlen > __oldlen
- // __news is allocated for __newlen size
- template<typename _CharT, typename _Traits>
- void
- __pad_char(basic_ios<_CharT, _Traits>& __ios,
- _CharT* __news, const _CharT* __olds,
- const streamsize __newlen, const streamsize __oldlen)
- {
- typedef _CharT char_type;
- typedef _Traits traits_type;
- typedef typename traits_type::int_type int_type;
-
- int_type __plen = static_cast<size_t>(__newlen - __oldlen);
- char_type* __pads = static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __plen));
- traits_type::assign(__pads, __plen, __ios.fill());
-
- char_type* __beg;
- char_type* __end;
- size_t __mod = 0;
- size_t __beglen; //either __plen or __oldlen
- ios_base::fmtflags __adjust = __ios.flags() & ios_base::adjustfield;
-
- if (__adjust == ios_base::left)
- {
- // Padding last.
- __beg = const_cast<char_type*>(__olds);
- __beglen = __oldlen;
- __end = __pads;
- }
- else if (__adjust == ios_base::internal)
- {
- // Pad after the sign, if there is one.
- // Pad after 0[xX], if there is one.
- // Who came up with these rules, anyway? Jeeze.
- typedef _Format_cache<_CharT> __cache_type;
- __cache_type const* __fmt = __cache_type::_S_get(__ios);
- const char_type* __minus = traits_type::find(__olds, __oldlen,
- __fmt->_S_minus);
- const char_type* __plus = traits_type::find(__olds, __oldlen,
- __fmt->_S_plus);
- bool __testsign = __minus || __plus;
- bool __testhex = __olds[0] == '0'
- && (__olds[1] == 'x' || __olds[1] == 'X');
-
- if (__testhex)
- {
- __news[0] = __olds[0];
- __news[1] = __olds[1];
- __mod += 2;
- __beg = const_cast<char_type*>(__olds + __mod);
- __beglen = __oldlen - __mod;
- __end = __pads;
- }
- else if (__testsign)
- {
- __mod += __plen;
- const char_type* __sign = __minus ? __minus + 1: __plus + 1;
- __beg = const_cast<char_type*>(__olds);
- __beglen = __sign - __olds;
- __end = const_cast<char_type*>(__sign + __plen);
- traits_type::copy(__news + __beglen, __pads, __plen);
- }
- else
- {
- // Padding first.
- __beg = __pads;
- __beglen = __plen;
- __end = const_cast<char_type*>(__olds);
- }
- }
- else
- {
- // Padding first.
- __beg = __pads;
- __beglen = __plen;
- __end = const_cast<char_type*>(__olds);
- }
-
- traits_type::copy(__news, __beg, __beglen);
- traits_type::copy(__news + __beglen, __end, __newlen - __beglen - __mod);
- }
-
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)
streamsize __len = 1;
if (__w > __len)
{
- __pad_char(__out, __pads, &__c, __w, __len);
+ __pad(__out, __out.fill(), __pads, &__c, __w, __len);
__len = __w;
}
__out.write(__pads, __len);
streamsize __len = 1;
if (__w > __len)
{
- __pad_char(__out, __pads, &__c, __w, __len);
+ __pad(__out, __out.fill(), __pads, &__c, __w, __len);
__len = __w;
}
__out.write(__pads, __len);
streamsize __len = static_cast<streamsize>(_Traits::length(__s));
if (__w > __len)
{
- __pad_char(__out, __pads, __s, __w, __len);
+ __pad(__out, __out.fill(), __pads, __s, __w, __len);
__s = __pads;
__len = __w;
}
if (__w > __len)
{
- __pad_char(__out, __pads, __ws, __w, __len);
+ __pad(__out, __out.fill(), __pads, __ws, __w, __len);
__str = __pads;
__len = __w;
}
streamsize __len = static_cast<streamsize>(_Traits::length(__s));
if (__w > __len)
{
- __pad_char(__out, __pads, __s, __w, __len);
+ __pad(__out, __out.fill(), __pads, __s, __w, __len);
__s = __pads;
__len = __w;
}
#endif
if (__w > __len)
{
- __pad_char(__out, __pads, __s, __w, __len);
+ __pad(__out, __out.fill(), __pads, __s, __w, __len);
__s = __pads;
__len = __w;
}
inline __istream_type&
get(char_type* __s, streamsize __n)
- { return get(__s, __n, this->widen('\n')); }
+ { return this->get(__s, __n, this->widen('\n')); }
__istream_type&
get(__streambuf_type& __sb, char_type __delim);
inline __istream_type&
get(__streambuf_type& __sb)
- { return get(__sb, this->widen('\n')); }
+ { return this->get(__sb, this->widen('\n')); }
__istream_type&
getline(char_type* __s, streamsize __n, char_type __delim);
inline __istream_type&
getline(char_type* __s, streamsize __n)
- { return getline(__s, __n, this->widen('\n')); }
+ { return this->getline(__s, __n, this->widen('\n')); }
__istream_type&
ignore(streamsize __n = 1, int_type __delim = traits_type::eof());
#endif
#endif /* _CPP_ISTREAM */
-
{
int_type __eof = traits_type::eof();
bool __thiseof = !_M_sbuf || _M_sbuf->sgetc() == __eof;
- bool __beof = !__b._M_sbuf
- || __b._M_sbuf->sgetc() == __eof;
+ bool __beof = !__b._M_sbuf || __b._M_sbuf->sgetc() == __eof;
return (__thiseof && __beof || (!__thiseof && !__beof));
}
{
int_type __eof = traits_type::eof();
bool __thiseof = !_M_sbuf || _M_sbuf->sgetc() == __eof;
- bool __beof = !__b._M_sbuf
- || __b._M_sbuf->sgetc() == __eof;
+ bool __beof = !__b._M_sbuf || __b._M_sbuf->sgetc() == __eof;
return (__thiseof && __beof || (!__thiseof && !__beof));
}
#endif
{
locale __old = _M_ios_locale;
_M_ios_locale = __loc;
- // Make sure there's a callback for the format caches so they will be
- // marked dirty.
- _Format_cache<char>::_S_get(*this);
-#ifdef _GLIBCPP_USE_WCHAR_T
- _Format_cache<wchar_t>::_S_get(*this);
-#endif
_M_call_callbacks(imbue_event);
return __old;
}
template class moneypunct_byname<char, true>;
template class money_get<char, ibuf_iterator>;
template class money_put<char, obuf_iterator>;
- template class _Format_cache<char>;
#ifdef _GLIBCPP_USE_WCHAR_T
template class moneypunct<wchar_t, false>;
template class moneypunct_byname<wchar_t, true>;
template class money_get<wchar_t, wibuf_iterator>;
template class money_put<wchar_t, wobuf_iterator>;
- template class _Format_cache<wchar_t>;
#endif
// numpunct, numpunct_byname, num_get, and num_put
template class numpunct<char>;
template class numpunct_byname<char>;
template class num_get<char, ibuf_iterator>;
- template class num_put<char, obuf_iterator>;
+ template class num_put<char, obuf_iterator>;
+ template
+ obuf_iterator
+ num_put<char, obuf_iterator>::
+ _M_convert_int(obuf_iterator, ios_base&, char, char, char, long) const;
+
+ template
+ obuf_iterator
+ num_put<char, obuf_iterator>::
+ _M_convert_int(obuf_iterator, ios_base&, char, char, char,
+ unsigned long) const;
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+ template
+ obuf_iterator
+ num_put<char, obuf_iterator>::
+ _M_convert_int(obuf_iterator, ios_base&, char, char, char,
+ long long) const;
+
+ template
+ obuf_iterator
+ num_put<char, obuf_iterator>::
+ _M_convert_int(obuf_iterator, ios_base&, char, char, char,
+ unsigned long long) const;
+#endif
+
+ template
+ obuf_iterator
+ num_put<char, obuf_iterator>::
+ _M_convert_float(obuf_iterator, ios_base&, char, char, double) const;
+
+ template
+ obuf_iterator
+ num_put<char, obuf_iterator>::
+ _M_convert_float(obuf_iterator, ios_base&, char, char,
+ long double) const;
+
#ifdef _GLIBCPP_USE_WCHAR_T
template class numpunct<wchar_t>;
template class numpunct_byname<wchar_t>;
template class num_get<wchar_t, wibuf_iterator>;
template class num_put<wchar_t, wobuf_iterator>;
+
+ template
+ wobuf_iterator
+ num_put<wchar_t, wobuf_iterator>::
+ _M_convert_int(wobuf_iterator, ios_base&, wchar_t, char, char, long) const;
+
+ template
+ wobuf_iterator
+ num_put<wchar_t, wobuf_iterator>::
+ _M_convert_int(wobuf_iterator, ios_base&, wchar_t, char, char,
+ unsigned long) const;
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+ template
+ wobuf_iterator
+ num_put<wchar_t, wobuf_iterator>::
+ _M_convert_int(wobuf_iterator, ios_base&, wchar_t, char, char,
+ long long) const;
+
+ template
+ wobuf_iterator
+ num_put<wchar_t, wobuf_iterator>::
+ _M_convert_int(wobuf_iterator, ios_base&, wchar_t, char, char,
+ unsigned long long) const;
+#endif
+
+ template
+ wobuf_iterator
+ num_put<wchar_t, wobuf_iterator>::
+ _M_convert_float(wobuf_iterator, ios_base&, wchar_t, char,
+ double) const;
+
+ template
+ wobuf_iterator
+ num_put<wchar_t, wobuf_iterator>::
+ _M_convert_float(wobuf_iterator, ios_base&, wchar_t, char,
+ long double) const;
#endif
// time_get and time_put
typedef ostreambuf_iterator<char, char_traits<char> > ostreambuf_iter;
#ifdef _GLIBCPP_USE_WCHAR_T
- typedef istreambuf_iterator<wchar_t,char_traits<wchar_t> > wistreambuf_iter;
- typedef ostreambuf_iterator<wchar_t,char_traits<wchar_t> > wostreambuf_iter;
+ typedef istreambuf_iterator<wchar_t, char_traits<wchar_t> > wistreambuf_iter;
+ typedef ostreambuf_iterator<wchar_t, char_traits<wchar_t> > wostreambuf_iter;
#endif
template
bool
locale::operator()(const string&, const string&) const;
- template
- ostreambuf_iter
- __pad<char, ostreambuf_iter, output_iterator_tag>
- (ostreambuf_iter, char, int, output_iterator_tag);
-
- template
- ostreambuf_iter
- __pad_numeric<char, ostreambuf_iter>
- (ostreambuf_iter, ios_base::fmtflags, char, int, char const*, char const*,
- char const*);
-
template
char*
- __group_digits<char>(char*, char, char const*, char const*,
+ __add_grouping<char>(char*, char, char const*, char const*,
char const*, char const*);
template
bool
__verify_grouping<char>(const basic_string<char>&, basic_string<char>&);
- template
- ostreambuf_iter
- __output_integer<char, ostreambuf_iter, unsigned long>
- (ostreambuf_iter, ios_base &, char, bool, unsigned long);
+ template
+ void
+ __pad<char>(ios_base&, char, char*, const char *, streamsize,
+ streamsize);
-#ifdef _GLIBCPP_USE_LONG_LONG
template
- ostreambuf_iter
- __output_integer<char, ostreambuf_iter, unsigned long long>
- (ostreambuf_iter, ios_base &, char, bool, unsigned long long);
-#endif
+ void
+ __pad<char, char_traits<char> >(ios_base&, char, char*,
+ const char *, streamsize, streamsize);
#ifdef _GLIBCPP_USE_WCHAR_T
template
typedef ostreambuf_iterator<wchar_t> wostreambuf_iter;
- template
- wostreambuf_iter
- __pad<wchar_t, wostreambuf_iter, output_iterator_tag>
- (wostreambuf_iter, wchar_t, int, output_iterator_tag);
-
- template
- wostreambuf_iter
- __pad_numeric<wchar_t, wostreambuf_iter>
- (wostreambuf_iter, ios_base::fmtflags, wchar_t __fill, int, wchar_t const*,
- wchar_t const*, wchar_t const*);
-
template
wchar_t*
- __group_digits<wchar_t>(wchar_t*, wchar_t, char const*, char const*,
+ __add_grouping<wchar_t>(wchar_t*, wchar_t, char const*, char const*,
wchar_t const*, wchar_t const*);
template
bool
__verify_grouping<wchar_t>(const basic_string<wchar_t>&,
basic_string<wchar_t>&);
- template
- wostreambuf_iter
- __output_integer<wchar_t, wostreambuf_iter, unsigned long>
- (wostreambuf_iter, ios_base &, wchar_t, bool, unsigned long);
+ template
+ void
+ __pad<wchar_t>(ios_base&, wchar_t, wchar_t*, const wchar_t*,
+ streamsize, streamsize);
-#ifdef _GLIBCPP_USE_LONG_LONG
template
- wostreambuf_iter
- __output_integer<wchar_t, wostreambuf_iter, unsigned long long>
- (wostreambuf_iter, ios_base &, wchar_t, bool, unsigned long long);
-#endif
+ void
+ __pad<wchar_t, char_traits<wchar_t> >(ios_base&, wchar_t, wchar_t*,
+ const wchar_t*,
+ streamsize, streamsize);
#endif // _GLIBCPP_USE_WCHAR_T
template
__normal_iterator<locale::facet**, vector<locale::facet*> >,
locale::facet* const&);
} // namespace std
-
// Definitions for static const data members of locale::id
size_t locale::id::_S_highwater; // init'd to 0 by linker
+ const char __num_base::_S_atoms[] = "0123456789eEabcdfxABCDFX";
+
// Definitions for static const data members of locale::_Impl
const locale::id* const
locale::_Impl::_S_id_ctype[] =
void
locale::facet::
_M_add_reference() throw()
- { ++_M_references; } // XXX MT
+ { ++_M_references; } // XXX MT
void
locale::facet::
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<ctype<char> >(const locale& __loc)
}
#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);
-
- // Fail quickly if !__valid
- if (__beg == __end)
- {
- __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]))
- {
- __testsign = true;
- __xtrc[__pos++] = __c;
- ++__beg;
- __c = * __beg;
-
- // Whitespace may follow a sign
- while ((__beg != __end) && (isspace(__c)))
- {
- ++__beg;
- __c = *__beg;
- }
-
- // There had better be more to come...
- if (__beg == __end)
- {
- __xtrc[__pos] = '\0';
- __err |= (ios_base::eofbit | ios_base::failbit);
- return;
- }
- }
-
- // Now check if first character is a zero.
- bool __testzero = false;
- if (__c == __lits[__cache_type::_S_digits])
- {
- __testzero = true;
- ++__beg;
- __c = *__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++] = __lits[__cache_type::_S_digits];
- __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
- if ((__c == __lits[__cache_type::_S_x])
- || (__c == __lits[__cache_type::_S_X]))
- {
- ++__beg;
- __c = *__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 (__c == __lits[__cache_type::_S_digits])
- {
- ++__beg;
- __c = *__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 (__beg != __end)
- {
- const char* __p = strchr(__lits, __c);
-
- // NB: strchr returns true for __c == 0x0
- if (__p && __c
- &&((__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])))
- {
- // Try first for acceptable digit; record it if found.
- __xtrc[__pos++] = __c;
- ++__sep_pos;
- __testunits = true;
- ++__beg;
- __c = *__beg;
- }
- 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;
- ++__beg;
- __c = *__beg;
- }
- else
- {
- __err |= ios_base::failbit;
- break;
- }
- }
- else
- // Not a valid input item.
- break;
- }
-
- // 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);
-
- if (!__verify_grouping(__fmt->_M_grouping, __grp))
- {
- __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)
- {
- // 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;
- __c = *__beg;
-
- // Now we get any digits after the decimal point
- // There MUST be some if __testunits is false.
- while (__beg != __end)
- {
- const char* __p = strchr(__lits, __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;
- __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)
- {
- if ((__c == __lits[__cache_type::_S_ee])
- || (__c == __lits[__cache_type::_S_Ee]))
- {
- __xtrc[__pos++] = __c;
- ++__beg;
- __c = *__beg;
-
- // Now there may be a sign
- if (__beg != __end)
- {
- if ((__c == __lits[__cache_type::_S_minus])
- || (__c == __lits[__cache_type::_S_plus]))
- {
- __xtrc[__pos++] = __c;
- ++__beg;
- __c = *__beg;
- // whitespace may follow a sign
- while ((__beg != __end) && (isspace(__c)))
- {
- ++__beg;
- __c = *__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)
- {
- const char* __p = strchr(__lits, __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;
- __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
- __build_float_format(ios_base& __io, char* __fptr, char __modifier,
- streamsize __prec)
+ __num_base::_S_format_float(const ios_base& __io, char* __fptr, char __mod,
+ streamsize __prec)
{
bool __incl_prec = false;
ios_base::fmtflags __flags = __io.flags();
// As per [22.2.2.2.2.11]
if (__flags & ios_base::fixed || __prec > 0)
{
- *__fptr++ = '.';
- *__fptr++ = '*';
- __incl_prec = true;
+ *__fptr++ = '.';
+ *__fptr++ = '*';
+ __incl_prec = true;
}
- if (__modifier)
- *__fptr++ = __modifier;
+ if (__mod)
+ *__fptr++ = __mod;
ios_base::fmtflags __fltfield = __flags & ios_base::floatfield;
// [22.2.2.2.2] Table 58
if (__fltfield == ios_base::fixed)
*__fptr = '\0';
return __incl_prec;
}
+
+ void
+ __num_base::_S_format_int(const ios_base& __io, char* __fptr, char __mod,
+ char __modl)
+ {
+ ios_base::fmtflags __flags = __io.flags();
+ *__fptr++ = '%';
+ // [22.2.2.2.2] Table 60
+ if (__flags & ios_base::showpos)
+ *__fptr++ = '+';
+ if (__flags & ios_base::showbase)
+ *__fptr++ = '#';
+ *__fptr++ = 'l';
+
+ // For long long types.
+ if (__modl)
+ *__fptr++ = __modl;
+ ios_base::fmtflags __bsefield = __flags & ios_base::basefield;
+ if (__bsefield == ios_base::hex)
+ *__fptr++ = (__flags & ios_base::uppercase) ? 'X' : 'x';
+ else if (__bsefield == ios_base::oct)
+ *__fptr++ = 'o';
+ else
+ *__fptr++ = __mod;
+ *__fptr = '\0';
+ }
+
template<>
- moneypunct_byname<char, false>::moneypunct_byname(const char* /*__s*/,
- size_t __refs)
- : moneypunct<char, false>(__refs) { }
+ moneypunct_byname<char, false>::moneypunct_byname(const char* /*__s*/,
+ size_t __refs)
+ : moneypunct<char, false>(__refs) { }
template<>
- moneypunct_byname<char, true>::moneypunct_byname(const char* /*__s*/,
- size_t __refs)
- : moneypunct<char, true>(__refs) { }
+ moneypunct_byname<char, true>::moneypunct_byname(const char* /*__s*/,
+ size_t __refs)
+ : moneypunct<char, true>(__refs) { }
#ifdef _GLIBCPP_USE_WCHAR_T
ctype<wchar_t>::__wmask_type
(vector<string>::const_iterator, vector<string>::const_iterator,
string*, __false_type);
- template
- void
- __pad_char(basic_ios<char>&, char*, const char*,
- const streamsize, const streamsize);
-#ifdef _GLIBCPP_USE_WCHAR_T
- template
- void
- __pad_char(basic_ios<wchar_t>&, wchar_t*, const wchar_t*,
- const streamsize, const streamsize);
-#endif
-
- template
- ostreambuf_iterator<char>
- __pad_numeric(ostreambuf_iterator<char>, _Ios_Fmtflags, char, int,
- const char*, const char*, const char*);
-#ifdef _GLIBCPP_USE_WCHAR_T
- template
- ostreambuf_iterator<wchar_t>
- __pad_numeric(ostreambuf_iterator<wchar_t>, _Ios_Fmtflags, wchar_t, int,
- const wchar_t*, const wchar_t*, const wchar_t*);
-#endif
-
- template
- ostreambuf_iterator<char>
- __output_float(ostreambuf_iterator<char>, ios_base&, char,
- const char*, size_t);
-#ifdef _GLIBCPP_USE_WCHAR_T
- template
- ostreambuf_iterator<wchar_t>
- __output_float(ostreambuf_iterator<wchar_t>, ios_base&, wchar_t,
- const char*, size_t);
-#endif
-
template
streamsize
__copy_streambufs(basic_ios<char>&, basic_streambuf<char>*,
--- /dev/null
+// 2001-11-21 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2001 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.2.2.1 Template class num_get
+
+#include <locale>
+
+void test01()
+{
+ // Check for required base class.
+ typedef std::num_get<char> test_type;
+ typedef std::locale::facet base_type;
+ const test_type& obj = std::use_facet<test_type>(std::locale());
+ const base_type* base = &obj;
+
+ // Check for required typedefs
+ typedef test_type::char_type char_type;
+ typedef test_type::iter_type iter_type;
+}
+
+// Should be able to instantiate this for other types besides char, wchar_t
+class gnu_num_get: public std::num_get<unsigned char>
+{ };
+
+void test02()
+{
+ gnu_num_get facet01;
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
--- /dev/null
+// 2001-11-21 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2001 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.2.2.1.1 num_get members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// XXX This test is not working for non-glibc locale models.
+// { dg-do run { xfail *-*-* } }
+
+void test01()
+{
+ using namespace std;
+ typedef istreambuf_iterator<char> iterator_type;
+
+ bool test = true;
+
+ // basic construction
+ locale loc_c = locale::classic();
+ locale loc_hk("en_HK");
+ locale loc_fr("fr_FR@euro");
+ locale loc_de("de_DE");
+ VERIFY( loc_c != loc_de );
+ VERIFY( loc_hk != loc_fr );
+ VERIFY( loc_hk != loc_de );
+ VERIFY( loc_de != loc_fr );
+
+ // cache the numpunct facets
+ const numpunct<char>& numpunct_c = use_facet<numpunct<char> >(loc_c);
+ const numpunct<char>& numpunct_de = use_facet<numpunct<char> >(loc_de);
+ const numpunct<char>& numpunct_hk = use_facet<numpunct<char> >(loc_hk);
+
+ // sanity check the data is correct.
+ const string empty;
+ char c;
+
+ bool b1 = true;
+ bool b0 = false;
+ long l1 = 2147483647;
+ long l2 = -2147483647;
+ long l;
+ unsigned long ul1 = 1294967294;
+ unsigned long ul2 = 0;
+ unsigned long ul;
+ double d1 = 1.02345e+308;
+ double d2 = 3.15e-308;
+ double d;
+ long double ld1 = 6.630025e+4;
+ long double ld2 = 0.0;
+ long double ld;
+ void* v;
+ const void* cv = &ul2;
+
+ // cache the num_get facet
+ istringstream iss;
+ iss.imbue(loc_de);
+ const num_get<char>& ng = use_facet<num_get<char> >(iss.getloc());
+ const ios_base::iostate goodbit = ios_base::goodbit;
+ const ios_base::iostate eofbit = ios_base::eofbit;
+ ios_base::iostate err = ios_base::goodbit;
+
+ // bool, simple
+ iss.str("1");
+ iterator_type os_it00 = iss.rdbuf();
+ iterator_type os_it01 = ng.get(os_it00, 0, iss, err, b1);
+ VERIFY( b1 == true );
+ VERIFY( err & ios_base::eofbit );
+
+ iss.str("0");
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, b0);
+ VERIFY( b0 == false );
+ VERIFY( err & eofbit );
+
+ // bool, more twisted examples
+ iss.imbue(loc_c);
+ iss.str("true ");
+ iss.clear();
+ iss.setf(ios_base::boolalpha);
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, b0);
+ VERIFY( b0 == true );
+ VERIFY( err == goodbit );
+
+ iss.str("false ");
+ iss.clear();
+ iss.setf(ios_base::boolalpha);
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, b1);
+ VERIFY( b1 == false );
+ VERIFY( err == goodbit );
+
+ // long, in a locale that expects grouping
+ iss.imbue(loc_hk);
+ iss.str("2,147,483,647 ");
+ iss.clear();
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, l);
+ VERIFY( l == l1 );
+ VERIFY( err == goodbit );
+
+ iss.str("-2,147,483,647++++++");
+ iss.clear();
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, l);
+ VERIFY( l == l2 );
+ VERIFY( err == goodbit );
+
+ // unsigned long, in a locale that does not group
+ iss.imbue(loc_c);
+ iss.str("1294967294");
+ iss.clear();
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, ul);
+ VERIFY( ul == ul1);
+ VERIFY( err == eofbit );
+
+ iss.str("0+++++++++++++++++++");
+ iss.clear();
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, ul);
+ VERIFY( ul == ul2);
+ VERIFY( err == goodbit );
+
+ // ... and one that does
+ iss.imbue(loc_de);
+ iss.str("1.294.967.294+++++++");
+ iss.clear();
+ iss.width(20);
+ iss.setf(ios_base::left, ios_base::adjustfield);
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, ul);
+ VERIFY( ul == ul1 );
+ VERIFY( err == goodbit );
+
+ // double
+ iss.imbue(loc_c);
+ iss.str("1.02345e+308++++++++");
+ iss.clear();
+ iss.width(20);
+ iss.setf(ios_base::left, ios_base::adjustfield);
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, d);
+ VERIFY( d == d1 );
+ VERIFY( err == goodbit );
+
+ iss.str("+3.15e-308");
+ iss.clear();
+ iss.width(20);
+ iss.setf(ios_base::right, ios_base::adjustfield);
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, d);
+ VERIFY( d == d2 );
+ VERIFY( err == eofbit );
+
+ iss.imbue(loc_de);
+ iss.str("+1,02345e+308");
+ iss.clear();
+ iss.width(20);
+ iss.setf(ios_base::right, ios_base::adjustfield);
+ iss.setf(ios_base::scientific, ios_base::floatfield);
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, d);
+ VERIFY( d == d1 );
+ VERIFY( err == eofbit );
+
+ iss.str("3,15E-308 ");
+ iss.clear();
+ iss.width(20);
+ iss.precision(10);
+ iss.setf(ios_base::right, ios_base::adjustfield);
+ iss.setf(ios_base::scientific, ios_base::floatfield);
+ iss.setf(ios_base::uppercase);
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, d);
+ VERIFY( d == d2 );
+ VERIFY( err == goodbit );
+
+ // long double
+ iss.str("6,630025e+4");
+ iss.clear();
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, ld);
+ VERIFY( ld == ld1 );
+ VERIFY( err == eofbit );
+
+ iss.str("0 ");
+ iss.clear();
+ iss.precision(0);
+ iss.setf(ios_base::fixed, ios_base::floatfield);
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, ld);
+ VERIFY( ld == 0 );
+ VERIFY( err == goodbit );
+
+ // const void
+ iss.str("0xbffff74c.");
+ iss.clear();
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, v);
+ VERIFY( &v != &cv );
+ VERIFY( err == goodbit );
+
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+ long long ll1 = 9223372036854775807;
+ long long ll2 = -9223372036854775807;
+ long long ll;
+
+ iss.str("9.223.372.036.854.775.807");
+ iss.clear();
+ err = goodbit;
+ ng.get(iss.rdbuf(), 0, iss, err, ll);
+ VERIFY( ll == ll1 );
+ VERIFY( err == eofbit );
+#endif
+}
+
+
+int main()
+{
+ test01();
+ return 0;
+}
+
+
+// Kathleen Hannah, humanitarian, woman, art-thief
--- /dev/null
+// 2001-11-19 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2001 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.2.2.2 Template class num_put
+
+#include <locale>
+
+void test01()
+{
+ // Check for required base class.
+ typedef std::num_put<char> test_type;
+ typedef std::locale::facet base_type;
+ const test_type& obj = std::use_facet<test_type>(std::locale());
+ const base_type* base = &obj;
+
+ // Check for required typedefs
+ typedef test_type::char_type char_type;
+ typedef test_type::iter_type iter_type;
+}
+
+// Should be able to instantiate this for other types besides char, wchar_t
+class gnu_num_put: public std::num_put<unsigned char>
+{ };
+
+void test02()
+{
+ gnu_num_put facet01;
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
--- /dev/null
+// 2001-11-19 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2001 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.2.2.2.1 num_put members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// XXX This test is not working for non-glibc locale models.
+// { dg-do run { xfail *-*-* } }
+
+void test01()
+{
+ using namespace std;
+ typedef ostreambuf_iterator<char> iterator_type;
+
+ bool test = true;
+
+ // basic construction
+ locale loc_c = locale::classic();
+ locale loc_hk("en_HK");
+ locale loc_fr("fr_FR@euro");
+ locale loc_de("de_DE");
+ VERIFY( loc_c != loc_de );
+ VERIFY( loc_hk != loc_fr );
+ VERIFY( loc_hk != loc_de );
+ VERIFY( loc_de != loc_fr );
+
+ // cache the numpunct facets
+ const numpunct<char>& numpunct_c = use_facet<numpunct<char> >(loc_c);
+ const numpunct<char>& numpunct_de = use_facet<numpunct<char> >(loc_de);
+ const numpunct<char>& numpunct_hk = use_facet<numpunct<char> >(loc_hk);
+
+ // sanity check the data is correct.
+ const string empty;
+ string result1;
+ string result2;
+ char c;
+
+ bool b1 = true;
+ bool b0 = false;
+ long l1 = 2147483647;
+ long l2 = -2147483647;
+ unsigned long ul1 = 1294967294;
+ unsigned long ul2 = 0;
+ double d1 = 1.7976931348623157e+308;
+ double d2 = 2.2250738585072014e-308;
+ long double ld1 = 1.7976931348623157e+308;
+ long double ld2 = 2.2250738585072014e-308;
+ const void* cv = &ld1;
+
+ // cache the num_put facet
+ ostringstream oss;
+ oss.imbue(loc_de);
+ const num_put<char>& np = use_facet<num_put<char> >(oss.getloc());
+
+ // bool, simple
+ iterator_type os_it00 = oss.rdbuf();
+ iterator_type os_it01 = np.put(os_it00, oss, '+', b1);
+ result1 = oss.str();
+ VERIFY( result1 == "1" );
+ // VERIFY( os_it00 != os_it01 );
+
+ oss.str(empty);
+ np.put(oss.rdbuf(), oss, '+', b0);
+ result2 = oss.str();
+ VERIFY( result2 == "0" );
+
+ // bool, more twisted examples
+ oss.imbue(loc_c);
+ oss.str(empty);
+ oss.width(20);
+ oss.setf(ios_base::right, ios_base::adjustfield);
+ np.put(oss.rdbuf(), oss, '+', b0);
+ result1 = oss.str();
+ VERIFY( result1 == "+++++++++++++++++++0" );
+
+ oss.str(empty);
+ oss.width(20);
+ oss.setf(ios_base::left, ios_base::adjustfield);
+ oss.setf(ios_base::boolalpha);
+ np.put(oss.rdbuf(), oss, '+', b1);
+ result2 = oss.str();
+ VERIFY( result2 == "true++++++++++++++++" );
+
+ // long, in a locale that expects grouping
+ oss.imbue(loc_hk);
+ oss.str(empty);
+ oss.clear();
+ np.put(oss.rdbuf(), oss, '+', l1);
+ result1 = oss.str();
+ VERIFY( result1 == "2,147,483,647" );
+
+ oss.str(empty);
+ oss.clear();
+ oss.width(20);
+ oss.setf(ios_base::left, ios_base::adjustfield);
+ np.put(oss.rdbuf(), oss, '+', l2);
+ result1 = oss.str();
+ VERIFY( result1 == "-2,147,483,647++++++" );
+
+ // unsigned long, in a locale that does not group
+ oss.imbue(loc_c);
+ oss.str(empty);
+ oss.clear();
+ np.put(oss.rdbuf(), oss, '+', ul1);
+ result1 = oss.str();
+ VERIFY( result1 == "1294967294" );
+
+ oss.str(empty);
+ oss.clear();
+ oss.width(20);
+ oss.setf(ios_base::left, ios_base::adjustfield);
+ np.put(oss.rdbuf(), oss, '+', ul2);
+ result1 = oss.str();
+ VERIFY( result1 == "0+++++++++++++++++++" );
+
+ // ... and one that does
+ oss.imbue(loc_de);
+ oss.str(empty);
+ oss.clear();
+ oss.width(20);
+ oss.setf(ios_base::left, ios_base::adjustfield);
+ np.put(oss.rdbuf(), oss, '+', ul1);
+ result1 = oss.str();
+ VERIFY( result1 == "1.294.967.294+++++++" );
+
+ // double
+ oss.str(empty);
+ oss.clear();
+ oss.width(20);
+ oss.setf(ios_base::left, ios_base::adjustfield);
+ np.put(oss.rdbuf(), oss, '+', d1);
+ result1 = oss.str();
+ VERIFY( result1 == "1,79769e+308++++++++" );
+
+ oss.str(empty);
+ oss.clear();
+ oss.width(20);
+ oss.setf(ios_base::right, ios_base::adjustfield);
+ np.put(oss.rdbuf(), oss, '+', d2);
+ result1 = oss.str();
+ VERIFY( result1 == "++++++++2,22507e-308" );
+
+ oss.str(empty);
+ oss.clear();
+ oss.width(20);
+ oss.setf(ios_base::right, ios_base::adjustfield);
+ oss.setf(ios_base::scientific, ios_base::floatfield);
+ np.put(oss.rdbuf(), oss, '+', d2);
+ result2 = oss.str();
+ VERIFY( result2 == "+++++++2,225074e-308" );
+
+ oss.str(empty);
+ oss.clear();
+ oss.width(20);
+ oss.precision(10);
+ oss.setf(ios_base::right, ios_base::adjustfield);
+ oss.setf(ios_base::scientific, ios_base::floatfield);
+ oss.setf(ios_base::uppercase);
+ np.put(oss.rdbuf(), oss, '+', d2);
+ result1 = oss.str();
+ VERIFY( result1 == "+++2,2250738585E-308" );
+
+ // long double
+ oss.str(empty);
+ oss.clear();
+ np.put(oss.rdbuf(), oss, '+', ld1);
+ result1 = oss.str();
+ VERIFY( result1 == "1,7976931349E+308" );
+
+ oss.str(empty);
+ oss.clear();
+ oss.precision(0);
+ oss.setf(ios_base::fixed, ios_base::floatfield);
+ np.put(oss.rdbuf(), oss, '+', ld2);
+ result1 = oss.str();
+ VERIFY( result1 == "0" );
+
+ // const void
+ oss.str(empty);
+ oss.clear();
+ np.put(oss.rdbuf(), oss, '+', cv);
+ result1 = oss.str();
+ // No grouping characters.
+ VERIFY( !char_traits<char>::find(result1.c_str(),
+ numpunct_de.decimal_point(),
+ result1.size()) );
+ // Should contain an 'x'.
+ VERIFY( !char_traits<char>::find(result1.c_str(), 'x', result1.size()) );
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+ long long ll1 = 9223372036854775807;
+ long long ll2 = -9223372036854775807;
+
+ oss.str(empty);
+ oss.clear();
+ np.put(oss.rdbuf(), oss, '+', ll1);
+ result1 = oss.str();
+ VERIFY( result1 == "9.223.372.036.854.775.807" );
+#endif
+}
+
+
+int main()
+{
+ test01();
+ return 0;
+}
+
+
+
--- /dev/null
+// 2001-11-19 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2001 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.2.2.2.1 num_put members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// XXX This test is not working for non-glibc locale models.
+// { dg-do run { xfail *-*-* } }
+
+#ifdef _GLIBCPP_USE_WCHAR_T
+void test01()
+{
+ using namespace std;
+ typedef ostreambuf_iterator<wchar_t> iterator_type;
+
+ bool test = true;
+
+ // basic construction
+ locale loc_c = locale::classic();
+ locale loc_hk("en_HK");
+ locale loc_fr("fr_FR@euro");
+ locale loc_de("de_DE");
+ VERIFY( loc_c != loc_de );
+ VERIFY( loc_hk != loc_fr );
+ VERIFY( loc_hk != loc_de );
+ VERIFY( loc_de != loc_fr );
+
+ // cache the numpunct facets
+ const numpunct<wchar_t>& numpunct_c = use_facet<numpunct<wchar_t> >(loc_c);
+ const numpunct<wchar_t>& numpunct_de = use_facet<numpunct<wchar_t> >(loc_de);
+ const numpunct<wchar_t>& numpunct_hk = use_facet<numpunct<wchar_t> >(loc_hk);
+
+ // sanity check the data is correct.
+ const wstring empty;
+ wstring result1;
+ wstring result2;
+ wchar_t c;
+
+ bool b1 = true;
+ bool b0 = false;
+ long l1 = 2147483647;
+ long l2 = -2147483647;
+ unsigned long ul1 = 1294967294;
+ unsigned long ul2 = 0;
+ double d1 = 1.7976931348623157e+308;
+ double d2 = 2.2250738585072014e-308;
+ long double ld1 = 1.7976931348623157e+308;
+ long double ld2 = 2.2250738585072014e-308;
+ const void* cv = &ld1;
+
+ // cache the num_put facet
+ wostringstream oss;
+ oss.imbue(loc_de);
+ const num_put<wchar_t>& np = use_facet<num_put<wchar_t> >(oss.getloc());
+
+ // bool, simple
+ iterator_type os_it00 = oss.rdbuf();
+ iterator_type os_it01 = np.put(os_it00, oss, '+', b1);
+ result1 = oss.str();
+ VERIFY( result1 == L"1" );
+ // VERIFY( os_it00 != os_it01 );
+
+ oss.str(empty);
+ np.put(oss.rdbuf(), oss, L'+', b0);
+ result2 = oss.str();
+ VERIFY( result2 == L"0" );
+
+ // bool, more twisted examples
+ oss.imbue(loc_c);
+ oss.str(empty);
+ oss.width(20);
+ oss.setf(ios_base::right, ios_base::adjustfield);
+ np.put(oss.rdbuf(), oss, L'+', b0);
+ result1 = oss.str();
+ VERIFY( result1 == L"+++++++++++++++++++0" );
+
+ oss.str(empty);
+ oss.width(20);
+ oss.setf(ios_base::left, ios_base::adjustfield);
+ oss.setf(ios_base::boolalpha);
+ np.put(oss.rdbuf(), oss, L'+', b1);
+ result2 = oss.str();
+ VERIFY( result2 == L"true++++++++++++++++" );
+
+ // long, in a locale that expects grouping
+ oss.imbue(loc_hk);
+ oss.str(empty);
+ oss.clear();
+ np.put(oss.rdbuf(), oss, L'+', l1);
+ result1 = oss.str();
+ VERIFY( result1 == L"2,147,483,647" );
+
+ oss.str(empty);
+ oss.clear();
+ oss.width(20);
+ oss.setf(ios_base::left, ios_base::adjustfield);
+ np.put(oss.rdbuf(), oss, L'+', l2);
+ result1 = oss.str();
+ VERIFY( result1 == L"-2,147,483,647++++++" );
+
+ // unsigned long, in a locale that does not group
+ oss.imbue(loc_c);
+ oss.str(empty);
+ oss.clear();
+ np.put(oss.rdbuf(), oss, L'+', ul1);
+ result1 = oss.str();
+ VERIFY( result1 == L"1294967294" );
+
+ oss.str(empty);
+ oss.clear();
+ oss.width(20);
+ oss.setf(ios_base::left, ios_base::adjustfield);
+ np.put(oss.rdbuf(), oss, L'+', ul2);
+ result1 = oss.str();
+ VERIFY( result1 == L"0+++++++++++++++++++" );
+
+ // ... and one that does
+ oss.imbue(loc_de);
+ oss.str(empty);
+ oss.clear();
+ oss.width(20);
+ oss.setf(ios_base::left, ios_base::adjustfield);
+ np.put(oss.rdbuf(), oss, L'+', ul1);
+ result1 = oss.str();
+ VERIFY( result1 == L"1.294.967.294+++++++" );
+
+ // double
+ oss.str(empty);
+ oss.clear();
+ oss.width(20);
+ oss.setf(ios_base::left, ios_base::adjustfield);
+ np.put(oss.rdbuf(), oss, L'+', d1);
+ result1 = oss.str();
+ VERIFY( result1 == L"1,79769e+308++++++++" );
+
+ oss.str(empty);
+ oss.clear();
+ oss.width(20);
+ oss.setf(ios_base::right, ios_base::adjustfield);
+ np.put(oss.rdbuf(), oss, L'+', d2);
+ result1 = oss.str();
+ VERIFY( result1 == L"++++++++2,22507e-308" );
+
+ oss.str(empty);
+ oss.clear();
+ oss.width(20);
+ oss.setf(ios_base::right, ios_base::adjustfield);
+ oss.setf(ios_base::scientific, ios_base::floatfield);
+ np.put(oss.rdbuf(), oss, L'+', d2);
+ result2 = oss.str();
+ VERIFY( result2 == L"+++++++2,225074e-308" );
+
+ oss.str(empty);
+ oss.clear();
+ oss.width(20);
+ oss.precision(10);
+ oss.setf(ios_base::right, ios_base::adjustfield);
+ oss.setf(ios_base::scientific, ios_base::floatfield);
+ oss.setf(ios_base::uppercase);
+ np.put(oss.rdbuf(), oss, L'+', d2);
+ result1 = oss.str();
+ VERIFY( result1 == L"+++2,2250738585E-308" );
+
+ // long double
+ oss.str(empty);
+ oss.clear();
+ np.put(oss.rdbuf(), oss, L'+', ld1);
+ result1 = oss.str();
+ VERIFY( result1 == L"1,7976931349E+308" );
+
+ oss.str(empty);
+ oss.clear();
+ oss.precision(0);
+ oss.setf(ios_base::fixed, ios_base::floatfield);
+ np.put(oss.rdbuf(), oss, L'+', ld2);
+ result1 = oss.str();
+ VERIFY( result1 == L"0" );
+
+ // const void
+ oss.str(empty);
+ oss.clear();
+ np.put(oss.rdbuf(), oss, L'+', cv);
+ result1 = oss.str();
+ // No grouping characters.
+ VERIFY( !char_traits<wchar_t>::find(result1.c_str(),
+ numpunct_de.decimal_point(),
+ result1.size()) );
+ // Should contain an 'x'.
+ VERIFY( !char_traits<wchar_t>::find(result1.c_str(), L'x', result1.size()) );
+
+#ifdef _GLIBCPP_USE_LONG_LONG
+ long long ll1 = 9223372036854775807;
+ long long ll2 = -9223372036854775807;
+
+ oss.str(empty);
+ oss.clear();
+ np.put(oss.rdbuf(), oss, '+', ll1);
+ result1 = oss.str();
+ VERIFY( result1 == L"9.223.372.036.854.775.807" );
+#endif
+}
+#endif
+
+int main()
+{
+#ifdef _GLIBCPP_USE_WCHAR_T
+ test01();
+#endif
+ return 0;
+}
+
+
+// Diana D. Brooks, former chief executive of Sotheby's
+// art-thief extraordinaire
VERIFY( dp2 != dp3 );
VERIFY( th2 != th3 );
-#if 0
- // XXX isn't actually supported right now.
- VERIFY( t2 != t3 );
- VERIFY( f2 != f3 );
-#endif
VERIFY( dp2 != dp4 );
VERIFY( th2 != th4 );
-#if 0
- // XXX isn't actually supported right now.
- VERIFY( t2 != t3 );
- VERIFY( f2 != f3 );
-#endif
+ // XXX This isn't actually supported right now.
+ // VERIFY( t2 != t3 );
+ // VERIFY( f2 != f3 );
}
int main()
--- /dev/null
+// 2001-11-20 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2001 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.2.3.1.1 nunpunct members
+
+#include <locale>
+#include <testsuite_hooks.h>
+
+// XXX This test is not working for non-glibc locale models.
+// { dg-do run { xfail *-*-* } }
+
+void test01()
+{
+ using namespace std;
+
+ bool test = true;
+
+ // basic construction
+ locale loc_c = locale::classic();
+ locale loc_us("en_US");
+ locale loc_fr("fr_FR");
+ locale loc_de("de_DE");
+ VERIFY( loc_c != loc_de );
+ VERIFY( loc_us != loc_fr );
+ VERIFY( loc_us != loc_de );
+ VERIFY( loc_de != loc_fr );
+
+ // cache the numpunct facets
+ const numpunct<wchar_t>& nump_c = use_facet<numpunct<wchar_t> >(loc_c);
+ const numpunct<wchar_t>& nump_us = use_facet<numpunct<wchar_t> >(loc_us);
+ const numpunct<wchar_t>& nump_fr = use_facet<numpunct<wchar_t> >(loc_fr);
+ const numpunct<wchar_t>& nump_de = use_facet<numpunct<wchar_t> >(loc_de);
+
+ // sanity check the data is correct.
+ wchar_t dp1 = nump_c.decimal_point();
+ wchar_t th1 = nump_c.thousands_sep();
+ string g1 = nump_c.grouping();
+ wstring t1 = nump_c.truename();
+ wstring f1 = nump_c.falsename();
+
+ wchar_t dp2 = nump_us.decimal_point();
+ wchar_t th2 = nump_us.thousands_sep();
+ string g2 = nump_us.grouping();
+ wstring t2 = nump_us.truename();
+ wstring f2 = nump_us.falsename();
+
+ wchar_t dp3 = nump_fr.decimal_point();
+ wchar_t th3 = nump_fr.thousands_sep();
+ string g3 = nump_fr.grouping();
+ wstring t3 = nump_fr.truename();
+ wstring f3 = nump_fr.falsename();
+
+ wchar_t dp4 = nump_de.decimal_point();
+ wchar_t th4 = nump_de.thousands_sep();
+ string g4 = nump_de.grouping();
+ wstring t4 = nump_de.truename();
+ wstring f4 = nump_de.falsename();
+
+ VERIFY( dp2 != dp3 );
+ VERIFY( th2 != th3 );
+
+ VERIFY( dp2 != dp4 );
+ VERIFY( th2 != th4 );
+}
+
+int main()
+{
+ test01();
+
+ return 0;
+}
}
bool test10() {
- std::string str_01("0 00 000 +0 + 0 - 0");
+ std::string str_01("0 00 000 +0 +0 -0");
std::stringbuf isbuf_01(str_01);
std::istream is_01(&isbuf_01);
VERIFY( n == 33 );
VERIFY( is_03.rdstate() == std::ios_base::eofbit );
- std::string str_04("3. 4.5E+ 2a5E-3 .6E1");
+ std::string str_04("3. 4.5E+2a5E-3 .6E1");
std::stringbuf isbuf_04(str_04);
std::istream is_04(&isbuf_04);
static _TestCase testcases[] =
{
#if _GLIBCPP_USE_WCHAR_T
- // standard output (no formatting applied)
+ // standard output (no formatting applied) 1-4
{ 1.2, 6,0,'.',' ', F,F,F,F,F,F,F,F, "1.2",L"1.2" },
{ 54, 6,0,'.',' ', F,F,F,F,F,F,F,F, "54",L"54" },
{ -.012, 6,0,'.',' ', F,F,F,F,F,F,F,F, "-0.012",L"-0.012" },
{ -.00000012, 6,0,'.',' ', F,F,F,F,F,F,F,F, "-1.2e-07",L"-1.2e-07" },
- // fixed formatting
+ // fixed formatting 5-11
{ 10.2345, 0,0,'.',' ', T,F,F,F,F,F,F,F, "10",L"10" },
{ 10.2345, 0,0,'.',' ', T,F,F,T,F,F,F,F, "10.",L"10." },
{ 10.2345, 1,0,'.',' ', T,F,F,F,F,F,F,F, "10.2",L"10.2" },
{ -10.2345, 6,0,'.',' ', T,F,F,F,F,F,F,F, "-10.234500",L"-10.234500" },
{ -10.2345, 6,0,',',' ', T,F,F,F,F,F,F,F, "-10,234500",L"-10,234500" },
- // fixed formatting with width
+ // fixed formatting with width 12-22
{ 10.2345, 4,5,'.',' ', T,F,F,F,F,F,F,F, "10.2345",L"10.2345" },
{ 10.2345, 4,6,'.',' ', T,F,F,F,F,F,F,F, "10.2345",L"10.2345" },
{ 10.2345, 4,7,'.',' ', T,F,F,F,F,F,F,F, "10.2345",L"10.2345" },
{ -10.2345, 4,10,'.','A', T,F,F,F,F,T,F,F, "-AA10.2345",L"-AA10.2345" },
{ 10.2345, 4,10,'.','#', T,F,T,F,F,T,F,F, "+##10.2345",L"+##10.2345" },
- // scientific formatting
+ // scientific formatting 23-29
{ 1.23e+12, 1,0,'.',' ', F,T,F,F,F,F,F,F, "1.2e+12",L"1.2e+12" },
{ 1.23e+12, 1,0,'.',' ', F,T,F,F,T,F,F,F, "1.2E+12",L"1.2E+12" },
{ 1.23e+12, 2,0,'.',' ', F,T,F,F,F,F,F,F, "1.23e+12",L"1.23e+12" },
apply_formatting(tc, os);
os << tc.val;
#ifdef TEST_NUMPUT_VERBOSE
- cout << "result: " << os.str() << endl;
+ cout << j << "result 1: " << os.str() << endl;
#endif
VERIFY( os && os.str() == tc.result );
}
apply_formatting(tc, os);
os << (long double)tc.val;
#ifdef TEST_NUMPUT_VERBOSE
- cout << "result: " << os.str() << endl;
+ cout << j << "result 2: " << os.str() << endl;
#endif
VERIFY( os && os.str() == tc.result );
}