2455 lines
96 KiB
C++
2455 lines
96 KiB
C++
/***************************************************************************
|
|
*
|
|
* 22.locale.num.put.cpp - tests exercising the std::num_put facet
|
|
*
|
|
* $Id: 22.locale.num.put.cpp 648752 2008-04-16 17:01:56Z faridz $
|
|
*
|
|
***************************************************************************
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* permissions and limitations under the License.
|
|
*
|
|
* Copyright 2001-2006 Rogue Wave Software.
|
|
*
|
|
**************************************************************************/
|
|
|
|
#ifdef __GNUG__
|
|
// prevent gcc -Wshadow warnings for convenience types
|
|
# define ushort __rw_ushort
|
|
# define uint __rw_uint
|
|
# define ulong __rw_ulong
|
|
# include <sys/types.h>
|
|
# undef ushort
|
|
# undef uint
|
|
# undef ulong
|
|
#endif // __GNUG__
|
|
|
|
#include <ios>
|
|
#include <locale>
|
|
|
|
#include <cerrno> // for ERANGE, errno
|
|
#include <cfloat> // for floating limits macros
|
|
#include <climits> // for integral limits macros
|
|
#include <clocale> // for LC_NUMERIC, setlocale()
|
|
#include <cstdio> // for sprintf()
|
|
#include <cstring> // for strcmp(), strlen()
|
|
|
|
#include <any.h> // for TOSTR()
|
|
#include <cmdopt.h> // for rw_enabled
|
|
#include <driver.h> // for rw_test
|
|
#include <rw_locale.h> // for rw_locales
|
|
#include <valcmp.h> // for rw_equal
|
|
|
|
/**************************************************************************/
|
|
|
|
// set by the command line option handler in response to:
|
|
static int rw_opt_enable_num_get = 0; // --enable-num_get
|
|
static int rw_opt_no_errno = 0; // --no-errno
|
|
static int rw_opt_no_grouping = 0; // --no-grouping
|
|
static int rw_opt_no_widen = 0; // --no-widen
|
|
|
|
/**************************************************************************/
|
|
|
|
// replacement ctype facet
|
|
template <class charT>
|
|
struct Ctype: std::ctype<charT>
|
|
{
|
|
typedef std::ctype<charT> Base;
|
|
|
|
typedef typename Base::char_type char_type;
|
|
|
|
static int n_widen_;
|
|
|
|
Ctype (): Base (0, 0, 1) { }
|
|
|
|
virtual char_type do_widen (char c) const {
|
|
++n_widen_;
|
|
|
|
switch (c) {
|
|
case '0': c = '9'; break;
|
|
case '1': c = '8'; break;
|
|
case '2': c = '7'; break;
|
|
case '3': c = '6'; break;
|
|
case '4': c = '5'; break;
|
|
case '5': c = '4'; break;
|
|
case '6': c = '3'; break;
|
|
case '7': c = '2'; break;
|
|
case '8': c = '1'; break;
|
|
case '9': c = '0'; break;
|
|
default: break;
|
|
}
|
|
|
|
return char_type (c);
|
|
}
|
|
|
|
virtual const char_type*
|
|
do_widen (const char *lo, const char *hi, char_type *dst) const {
|
|
return Base::do_widen (lo, hi, dst);
|
|
}
|
|
};
|
|
|
|
template <class charT>
|
|
int Ctype<charT>::n_widen_;
|
|
|
|
|
|
/**************************************************************************/
|
|
|
|
// replacement numpunct facet
|
|
|
|
template <class charT>
|
|
struct Punct: std::numpunct<charT>
|
|
{
|
|
typedef typename std::numpunct<charT>::char_type char_type;
|
|
typedef typename std::numpunct<charT>::string_type string_type;
|
|
|
|
static char_type decimal_point_;
|
|
static char_type thousands_sep_;
|
|
static const char *grouping_;
|
|
static const char_type *truename_;
|
|
static const char_type *falsename_;
|
|
|
|
static int n_objs_; // number of facet objects in existence
|
|
static int n_thousands_sep_; // number of calls to do_thousands_sep()
|
|
|
|
Punct (std::size_t ref = 0)
|
|
: std::numpunct<charT>(ref) {
|
|
++n_objs_;
|
|
}
|
|
|
|
~Punct () {
|
|
--n_objs_;
|
|
}
|
|
|
|
virtual char_type do_decimal_point () const {
|
|
return decimal_point_;
|
|
}
|
|
|
|
virtual std::string do_grouping () const {
|
|
return grouping_;
|
|
}
|
|
|
|
virtual char_type do_thousands_sep () const {
|
|
++n_thousands_sep_;
|
|
return thousands_sep_;
|
|
}
|
|
|
|
virtual string_type do_truename () const {
|
|
return truename_ ? string_type (truename_) : string_type ();
|
|
}
|
|
|
|
virtual string_type do_falsename () const {
|
|
return falsename_ ? string_type (falsename_) : string_type ();
|
|
}
|
|
};
|
|
|
|
template <class charT>
|
|
const char* Punct<charT>::grouping_ = "";
|
|
|
|
template <class charT>
|
|
typename Punct<charT>::char_type Punct<charT>::decimal_point_ = '.';
|
|
|
|
template <class charT>
|
|
typename Punct<charT>::char_type Punct<charT>::thousands_sep_ = ',';
|
|
|
|
template <class charT>
|
|
const typename Punct<charT>::char_type* Punct<charT>::truename_;
|
|
|
|
template <class charT>
|
|
const typename Punct<charT>::char_type* Punct<charT>::falsename_;
|
|
|
|
template <class charT>
|
|
int Punct<charT>::n_thousands_sep_;
|
|
|
|
template <class charT>
|
|
int Punct<charT>::n_objs_;
|
|
|
|
|
|
/**************************************************************************/
|
|
|
|
template <class charT>
|
|
struct Ios: std::basic_ios<charT>
|
|
{
|
|
Ios () { this->init (0); }
|
|
};
|
|
|
|
|
|
template <class charT>
|
|
struct NumGet: std::num_get<charT, const charT*> { NumGet () { } };
|
|
|
|
|
|
template <class charT>
|
|
struct NumPut: std::num_put<charT, charT*>
|
|
{
|
|
typedef std::num_put<charT, charT*> Base;
|
|
typedef typename Base::char_type char_type;
|
|
typedef typename Base::iter_type iter_type;
|
|
|
|
enum {
|
|
test_bool, test_short, test_ushort, test_int, test_uint,
|
|
test_long, test_ulong, test_llong, test_ullong,
|
|
test_pvoid, test_float, test_double, test_ldouble
|
|
};
|
|
|
|
static int ncalls_ [13];
|
|
|
|
NumPut (std::size_t ref = 0): Base (ref) { }
|
|
|
|
#ifndef _RWSTD_NO_BOOL
|
|
|
|
virtual iter_type
|
|
do_put (iter_type it, std::ios_base &f, char_type fill, bool v) const {
|
|
++ncalls_ [test_bool];
|
|
return Base::do_put (it, f, fill, v);
|
|
}
|
|
|
|
#endif // _RWSTD_NO_BOOL
|
|
|
|
virtual iter_type
|
|
do_put (iter_type it, std::ios_base &f, char_type fill, long v) const {
|
|
++ncalls_ [test_long];
|
|
return Base::do_put (it, f, fill, v);
|
|
}
|
|
|
|
virtual iter_type
|
|
do_put (iter_type it, std::ios_base &f, char_type fill,
|
|
unsigned long v) const {
|
|
++ncalls_ [test_ulong];
|
|
return Base::do_put (it, f, fill, v);
|
|
}
|
|
|
|
#ifdef _RWSTD_LONG_LONG
|
|
|
|
// provided as an extension unless _RWSTD_NO_LONG_LONG is #defined
|
|
virtual iter_type
|
|
do_put (iter_type it, std::ios_base &f, char_type fill,
|
|
unsigned _RWSTD_LONG_LONG v) const {
|
|
++ncalls_ [test_ullong];
|
|
return Base::do_put (it, f, fill, v);
|
|
}
|
|
|
|
// provided as an extension unless _RWSTD_NO_LONG_LONG is #defined
|
|
virtual iter_type
|
|
do_put (iter_type it, std::ios_base &f, char_type fill,
|
|
_RWSTD_LONG_LONG v) const {
|
|
++ncalls_ [test_llong];
|
|
return Base::do_put (it, f, fill, v);
|
|
}
|
|
|
|
#endif // _RWSTD_LONG_LONG
|
|
|
|
virtual iter_type
|
|
do_put (iter_type it, std::ios_base &f, char_type fill, double v) const {
|
|
++ncalls_ [test_double];
|
|
return Base::do_put (it, f, fill, v);
|
|
}
|
|
|
|
#ifndef _RWSTD_NO_LONG_DOUBLE
|
|
|
|
virtual iter_type
|
|
do_put (iter_type it, std::ios_base &f, char_type fill,
|
|
long double v) const {
|
|
++ncalls_ [test_ldouble];
|
|
return Base::do_put (it, f, fill, v);
|
|
}
|
|
|
|
#endif // _RWSTD_NO_LONG_DOUBLE
|
|
|
|
virtual iter_type
|
|
do_put (iter_type it, std::ios_base &f, char_type fill,
|
|
const void *v) const {
|
|
++ncalls_ [test_pvoid];
|
|
return Base::do_put (it, f, fill, v);
|
|
}
|
|
};
|
|
|
|
|
|
// explicit initialization of the static array below used
|
|
// to work around a SunPro 5.4 bug (PR #27293)
|
|
template <class charT>
|
|
/* static */ int NumPut<charT>::ncalls_ [13] = { 0 };
|
|
|
|
/**************************************************************************/
|
|
|
|
template <class charT, class T>
|
|
void do_test (charT /* dummy */,
|
|
const char *cname, // charT name
|
|
const char *tname, // T name
|
|
int lineno, // line number
|
|
T val, // value to format
|
|
int flags, // ios flags
|
|
std::streamsize prec, // precision
|
|
std::streamsize width, // field width
|
|
char fill, // fill character
|
|
const char *grouping, // grouping string
|
|
const char *str, // expected output
|
|
int err_expect = -1, // expected iostate
|
|
T val_expect = T () /* expected num_get result */)
|
|
{
|
|
if (!rw_enabled (lineno)) {
|
|
rw_note (0, __FILE__, __LINE__, "test on line %d disabled", lineno);
|
|
return;
|
|
}
|
|
|
|
// create a distinct punctuation facet for each iteration to make sure
|
|
// any data cached in between successive calls to the facet's public
|
|
// member functions are flushed
|
|
const Punct<charT> pun (1);
|
|
|
|
Ios<charT> ios;
|
|
NumPut<charT> np;
|
|
|
|
ios.imbue (std::locale (ios.getloc (), (const std::numpunct<charT>*)&pun));
|
|
|
|
ios.flags (std::ios_base::fmtflags (flags));
|
|
ios.precision (prec);
|
|
ios.width (width);
|
|
pun.grouping_ = grouping;
|
|
|
|
#if defined (_RWSTD_LDBL_MAX_10_EXP)
|
|
|
|
charT buf [_RWSTD_LDBL_MAX_10_EXP + 2] = { 0 };
|
|
|
|
#else // if !defined (_RWSTD_LDBL_MAX_10_EXP)
|
|
|
|
charT buf [4096] = { 0 };
|
|
|
|
#endif // _RWSTD_LDBL_MAX_10_EXP
|
|
|
|
const charT* const bufend = np.put (buf, ios, fill, val);
|
|
|
|
// verify 22.2.2.2.2, p21
|
|
if (ios.width ()) {
|
|
|
|
static int width_fail = 0;
|
|
|
|
// fail at most once for each specialization
|
|
rw_assert (!width_fail++, 0, lineno,
|
|
"line %d: num_put<%s>::put (..., %s = %s) "
|
|
"failed to reset width from %d; width() = %d",
|
|
__LINE__, cname, tname, TOSTR (val),
|
|
TOSTR (buf), width, ios.width ());
|
|
}
|
|
|
|
/******************************************************************/
|
|
|
|
if (str) {
|
|
|
|
char cbuf [sizeof buf / sizeof *buf] = { '\0' };
|
|
|
|
if ('%' == *str) {
|
|
std::sprintf (cbuf, str, val);
|
|
str = cbuf;
|
|
|
|
#if defined (_WIN32) || defined (_WIN64)
|
|
|
|
std::size_t len = std::strlen (str);
|
|
|
|
if ( ('e' == cbuf [len - 5] || 'E' == cbuf [len - 5])
|
|
&& ('-' == cbuf [len - 4] || '+' == cbuf [len - 4])
|
|
&& ('0' == cbuf [len - 3])) {
|
|
cbuf [len - 3] = cbuf [len - 2];
|
|
cbuf [len - 2] = cbuf [len - 1];
|
|
cbuf [len - 1] = cbuf [len];
|
|
}
|
|
|
|
#endif // _WIN{32,64}
|
|
}
|
|
|
|
// compare output produced by num_put with that produced by printf()
|
|
rw_assert (0 == rw_strncmp (buf, str), 0, lineno,
|
|
"line %d: num_put<%s>::put (..., %s = %s) "
|
|
"wrote %{*Ac}, expected %{*Ac}, "
|
|
"flags = %{If}, precision = %d"
|
|
"%{?}, grouping = \"%#s\"%{;}",
|
|
__LINE__, cname, tname, TOSTR (val),
|
|
sizeof *buf, buf, sizeof *str, str,
|
|
flags, prec,
|
|
grouping && *grouping, grouping);
|
|
}
|
|
|
|
/******************************************************************/
|
|
|
|
#ifndef NO_NUM_GET
|
|
|
|
if (!rw_opt_enable_num_get)
|
|
return;
|
|
|
|
// skip negative precision (extension requiring special treatment)
|
|
if (prec < 0)
|
|
return;
|
|
|
|
const charT *next = buf;
|
|
|
|
// skip leading fill characters (if any)
|
|
for ( ; *next == fill; ++next);
|
|
|
|
// find the first non-fill character if it exists
|
|
const charT *last = next;
|
|
for ( ; *last && *last != fill; ++last);
|
|
for ( ; *last && *last == fill; ++last);
|
|
|
|
// do not perform extraction if there are any fill characters
|
|
// in the middle of output (they serve as punctuators and break
|
|
// up the input sequence)
|
|
if (next != last && *last)
|
|
return;
|
|
|
|
// do not perform extraction if the fill character is the minus
|
|
// sign, the plus sign, the thousands separator, the decimal point,
|
|
// or a digit
|
|
if ( '-' == fill
|
|
|| '+' == fill
|
|
|| pun.thousands_sep_ == fill
|
|
|| pun.decimal_point_ == fill
|
|
|| fill >= '0' && fill <= '9')
|
|
return;
|
|
|
|
// do not perform extraction if there is no data to extract
|
|
// (unless this is an extraction-only test)
|
|
if (!*next && str)
|
|
return;
|
|
|
|
NumGet<charT> ng;
|
|
|
|
T x = T ();
|
|
|
|
std::ios_base::iostate err = std::ios_base::goodbit;
|
|
|
|
if (-1 == err_expect) {
|
|
|
|
// lwg issue 17: special treatment for bool:
|
|
|
|
// The in iterator is always left pointing one position beyond
|
|
// the last character successfully matched. If val is set, then
|
|
// err is set to str.goodbit; or to str.eofbit if, when seeking
|
|
// another character to match, it is found that (in==end). If
|
|
// val is not set, then err is set to str.failbit; or to
|
|
// (str.failbit|str.eofbit) if the reason for the failure was
|
|
// that (in==end). [Example: for targets true:"a" and false:"abb",
|
|
// the input sequence "a" yields val==true and err==str.eofbit;
|
|
// the input sequence "abc" yields err=str.failbit, with in ending
|
|
// at the 'c' element. For targets true:"1" and false:"0", the
|
|
// input sequence "1" yields val==true and err=str.goodbit. For
|
|
// empty targets (""), any input sequence yields err==str.failbit.
|
|
// --end example]
|
|
|
|
err_expect = T (1) == T (2) && flags & std::ios::boolalpha
|
|
? std::ios::goodbit
|
|
: last == bufend && last [-1] != fill
|
|
? std::ios::eofbit : std::ios::goodbit;
|
|
|
|
val_expect = val;
|
|
}
|
|
|
|
last = ng.get (next, bufend, ios, err, x);
|
|
|
|
// verify the state
|
|
rw_assert (err == err_expect, 0, lineno,
|
|
"line %d: num_get<%s>::get (%s, ..., %s&) "
|
|
"flags = %{If}, "
|
|
"%{?}grouping = \"%#s\", %{;}"
|
|
"iostate = %{Is}, expected %{Is}",
|
|
__LINE__, cname,
|
|
TOSTR (next), tname,
|
|
flags,
|
|
grouping && *grouping, grouping,
|
|
err, err_expect);
|
|
|
|
// verify the parsed value
|
|
rw_assert (rw_equal (x, val_expect), 0, lineno,
|
|
"line %d: num_get<%s>::get (%s, ..., %s&) got %s, "
|
|
"expected %s, flags = %{If}, "
|
|
"%{?}grouping = \"%#s\", %{;}",
|
|
__LINE__, cname,
|
|
TOSTR (next), tname,
|
|
TOSTR (x), TOSTR (val_expect),
|
|
flags,
|
|
grouping && *grouping, grouping);
|
|
|
|
#else
|
|
|
|
_RWSTD_UNUSED (bufend);
|
|
_RWSTD_UNUSED (err_expect);
|
|
_RWSTD_UNUSED (val_expect);
|
|
|
|
#endif // NO_NUM_GET
|
|
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
template <class charT>
|
|
struct Streambuf: std::basic_streambuf<charT, std::char_traits<charT> > { };
|
|
|
|
template <class charT>
|
|
void direct_use_test (charT, const char *cname)
|
|
{
|
|
_RWSTD_UNUSED (cname);
|
|
|
|
// verify that num_put objects can be used directly w/o first
|
|
// having been installed in a locale object; the behavior of
|
|
// such facets is unspecified (but not undefined)
|
|
|
|
Ios<charT> ios;
|
|
|
|
const std::num_put<charT> np;
|
|
|
|
Streambuf<charT> sb;
|
|
|
|
#define DIRECT_USE_TEST(T) \
|
|
np.put (std::ostreambuf_iterator<charT>(&sb), ios, charT (), (T)0)
|
|
|
|
#ifndef _RWSTD_NO_BOOL
|
|
|
|
DIRECT_USE_TEST (bool);
|
|
|
|
#endif // _RWSTD_NO_BOOL
|
|
|
|
DIRECT_USE_TEST (unsigned long);
|
|
DIRECT_USE_TEST (long);
|
|
DIRECT_USE_TEST (double);
|
|
|
|
#ifndef _RWSTD_NO_LONG_DOUBLE
|
|
|
|
DIRECT_USE_TEST (long double);
|
|
|
|
#endif
|
|
|
|
DIRECT_USE_TEST (void*);
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
|
|
// for convenience
|
|
#define boolalpha std::ios_base::boolalpha
|
|
#define dec std::ios_base::dec
|
|
#define fixed std::ios_base::fixed
|
|
#define hex std::ios_base::hex
|
|
#define internal std::ios_base::internal
|
|
#define left std::ios_base::left
|
|
#define oct std::ios_base::oct
|
|
#define right std::ios_base::right
|
|
#define scientific std::ios_base::scientific
|
|
#define showbase std::ios_base::showbase
|
|
#define showpoint std::ios_base::showpoint
|
|
#define showpos std::ios_base::showpos
|
|
#define skipws std::ios_base::skipws
|
|
#define unitbuf std::ios_base::unitbuf
|
|
#define uppercase std::ios_base::uppercase
|
|
#define bin std::ios_base::bin
|
|
#define adjustfield std::ios_base::adjustfield
|
|
#define basefield std::ios_base::basefield
|
|
#define floatfield std::ios_base::floatfield
|
|
#define nolock std::ios_base::nolock
|
|
#define nolockbuf std::ios_base::nolockbuf
|
|
|
|
#define Bad std::ios_base::badbit
|
|
#define Eof std::ios_base::eofbit
|
|
#define Fail std::ios_base::failbit
|
|
#define Good std::ios_base::goodbit
|
|
|
|
|
|
template <class charT>
|
|
void bool_test (charT, const char *cname)
|
|
{
|
|
#ifndef _RWSTD_NO_BOOL
|
|
|
|
rw_info (0, 0, __LINE__, "std::num_put<%s>::put (..., bool)", cname);
|
|
|
|
const char* const tname = "bool";
|
|
|
|
static const charT boolnames[][4] = {
|
|
{ 'y', 'e', 's', '\0' }, { 'n', 'o', '.', '\0' },
|
|
|
|
// unusual strings to try to trip up the formatting algorithm
|
|
{ '+', '1', '\0' }, { '-', '2', '\0' },
|
|
{ '-', '+', '1', '\0' }, { '+', '-', '0', '\0' },
|
|
{ '\001', '\0' }, { '\0' }
|
|
};
|
|
|
|
Punct<charT>::decimal_point_ = '*';
|
|
Punct<charT>::truename_ = boolnames [0];
|
|
Punct<charT>::falsename_ = boolnames [1];
|
|
|
|
// set line number to __LINE__ and perform test so that
|
|
// assertion output will point to the failed TEST line
|
|
#define TEST do_test
|
|
#define T charT (), cname, tname, __LINE__
|
|
|
|
|
|
TEST (T, false, 0, 0, 0, ' ', "", "0");
|
|
TEST (T, true, 0, 0, 0, ' ', "", "1");
|
|
|
|
TEST (T, false, 0, 0, 0, ' ', "", "%d");
|
|
TEST (T, true, 0, 0, 0, ' ', "", "%d");
|
|
|
|
TEST (T, false, showpos, 0, 0, ' ', "", "%+d");
|
|
TEST (T, true, showpos, 0, 0, ' ', "", "%+d");
|
|
|
|
TEST (T, false, oct, 0, 0, ' ', "", "%o");
|
|
TEST (T, true, oct, 0, 0, ' ', "", "%o");
|
|
|
|
TEST (T, false, dec, 0, 0, ' ', "", "%d");
|
|
TEST (T, true, dec, 0, 0, ' ', "", "%d");
|
|
|
|
TEST (T, false, hex, 0, 0, ' ', "", "%x");
|
|
TEST (T, true, hex, 0, 0, ' ', "", "%x");
|
|
|
|
rw_info (0, 0, __LINE__, "std::ios::boolalpha");
|
|
|
|
TEST (T, false, boolalpha, 0, 0, ' ', "", "no.");
|
|
TEST (T, true, boolalpha, 0, 0, ' ', "", "yes");
|
|
|
|
// left justified boolalpha
|
|
TEST (T, false, boolalpha | left, 0, 6, ' ', "", "no. ");
|
|
TEST (T, true, boolalpha | left, 0, 6, ' ', "", "yes ");
|
|
|
|
// right justified boolalpha
|
|
TEST (T, false, boolalpha | right, 0, 6, ' ', "", " no.");
|
|
TEST (T, true, boolalpha | right, 0, 6, ' ', "", " yes");
|
|
|
|
// implied right justified boolalpha (internal bit set)
|
|
TEST (T, false, boolalpha | internal, 0, 4, ' ', "", " no.");
|
|
TEST (T, true, boolalpha | internal, 0, 4, ' ', "", " yes");
|
|
|
|
|
|
Punct<charT>::truename_ = boolnames [2];
|
|
Punct<charT>::falsename_ = boolnames [3];
|
|
|
|
TEST (T, false, boolalpha, 0, 1, ' ', "", "-2");
|
|
TEST (T, true, boolalpha, 0, 1, ' ', "", "+1");
|
|
|
|
TEST (T, false, boolalpha | internal, 0, 4, ' ', "", " -2");
|
|
TEST (T, true, boolalpha | internal, 0, 4, ' ', "", " +1");
|
|
|
|
|
|
Punct<charT>::truename_ = boolnames [4];
|
|
Punct<charT>::falsename_ = boolnames [5];
|
|
|
|
TEST (T, false, boolalpha, 0, 1, ' ', "", "+-0");
|
|
TEST (T, true, boolalpha, 0, 1, ' ', "", "-+1");
|
|
|
|
TEST (T, false, boolalpha | internal, 0, 4, ' ', "", " +-0");
|
|
TEST (T, true, boolalpha | internal, 0, 4, ' ', "", " -+1");
|
|
|
|
|
|
Punct<charT>::truename_ = boolnames [6];
|
|
Punct<charT>::falsename_ = boolnames [7];
|
|
|
|
TEST (T, false, boolalpha, 0, 0, ' ', "", "");
|
|
TEST (T, true, boolalpha, 0, 0, ' ', "", "\001");
|
|
|
|
TEST (T, false, boolalpha, 0, 1, ' ', "", " ");
|
|
TEST (T, true, boolalpha, 0, 1, ' ', "", "\001");
|
|
|
|
TEST (T, false, boolalpha, 0, 1, ',', "", ",");
|
|
TEST (T, true, boolalpha, 0, 1, ',', "", "\001");
|
|
|
|
TEST (T, false, boolalpha | internal, 0,4, ',', "", ",,,,");
|
|
TEST (T, true, boolalpha | internal, 0,4, ',', "", ",,,\001");
|
|
|
|
#endif // _RWSTD_NO_BOOL
|
|
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
template <class charT>
|
|
void long_test (charT, const char *cname)
|
|
{
|
|
const char* const tname = "long";
|
|
|
|
rw_info (0, 0, __LINE__, "std::num_put<%s>::put (..., %s)", cname, tname);
|
|
|
|
// working around a VAC++/AIX bug where LONG_{MIN,MAX} are
|
|
// of type int rather than long as required (see PR #28798)
|
|
#undef LONG_MIN
|
|
#define LONG_MIN _RWSTD_LONG_MIN
|
|
|
|
#undef LONG_MAX
|
|
#define LONG_MAX _RWSTD_LONG_MAX
|
|
|
|
#undef GET_FAIL
|
|
#define GET_FAIL (Eof | Fail), LONG_MAX
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// implicit decimal output
|
|
rw_info (0, 0, __LINE__, "std::ios::fmtflags ()");
|
|
|
|
TEST (T, 0L, 0, 0, 0, ' ', "", "%ld");
|
|
TEST (T, 1L, 0, 0, 0, ' ', "", "%ld");
|
|
TEST (T, 2L, 0, 0, 0, ' ', "", "%ld");
|
|
TEST (T, -3L, 0, 0, 0, ' ', "", "%ld");
|
|
TEST (T, 12L, 0, 0, 0, ' ', "", "%ld");
|
|
TEST (T, -13L, 0, 0, 0, ' ', "", "%ld");
|
|
TEST (T, 345L, 0, 0, 0, ' ', "", "%ld");
|
|
TEST (T, -456L, 0, 0, 0, ' ', "", "%ld");
|
|
TEST (T, 6789L, 0, 0, 0, ' ', "", "%ld");
|
|
TEST (T, -7890L, 0, 0, 0, ' ', "", "%ld");
|
|
TEST (T, 98765L, 0, 0, 0, ' ', "", "%ld");
|
|
TEST (T, -98766L, 0, 0, 0, ' ', "", "%ld");
|
|
TEST (T, LONG_MAX, 0, 0, 0, ' ', "", "%ld");
|
|
TEST (T, LONG_MIN, 0, 0, 0, ' ', "", "%ld");
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// explicit decimal ouptut
|
|
rw_info (0, 0, __LINE__, "std::ios::dec");
|
|
|
|
TEST (T, 0L, dec, 0, 0, ' ', "", "%ld");
|
|
TEST (T, 1L, dec, 0, 0, ' ', "", "%ld");
|
|
TEST (T, 2L, dec, 0, 0, ' ', "", "%ld");
|
|
TEST (T, 12L, dec, 0, 0, ' ', "", "%ld");
|
|
TEST (T, 345L, dec, 0, 0, ' ', "", "%ld");
|
|
TEST (T, 6789L, dec, 0, 0, ' ', "", "%ld");
|
|
TEST (T, 98765L, dec, 0, 0, ' ', "", "%ld");
|
|
TEST (T, LONG_MAX, dec, 0, 0, ' ', "", "%ld");
|
|
|
|
TEST (T, ~0L, dec, 0, 0, ' ', "", "%ld");
|
|
TEST (T, -1L, dec, 0, 0, ' ', "", "%ld");
|
|
TEST (T, -2L, dec, 0, 0, ' ', "", "%ld");
|
|
TEST (T, -12L, dec, 0, 0, ' ', "", "%ld");
|
|
TEST (T, -345L, dec, 0, 0, ' ', "", "%ld");
|
|
TEST (T, -6789L, dec, 0, 0, ' ', "", "%ld");
|
|
TEST (T, -98765L, dec, 0, 0, ' ', "", "%ld");
|
|
TEST (T, LONG_MIN, dec, 0, 0, ' ', "", "%ld");
|
|
|
|
rw_info (0, 0, __LINE__, "std::ios::dec | std::ios::showbase");
|
|
|
|
TEST (T, 0L, dec | showbase, 0, 0, ' ', "", "%#ld");
|
|
TEST (T, 1234L, dec | showbase, 0, 0, ' ', "", "%#ld");
|
|
TEST (T, -1235L, dec | showbase, 0, 0, ' ', "", "%#ld");
|
|
TEST (T, LONG_MAX, dec | showbase, 0, 0, ' ', "", "%#ld");
|
|
TEST (T, LONG_MIN, dec | showbase, 0, 0, ' ', "", "%#ld");
|
|
|
|
rw_info (0, 0, __LINE__, "std::ios::dec | std::ios::showpos");
|
|
|
|
TEST (T, 0L, dec | showpos, 0, 0, ' ', "", "%+ld");
|
|
TEST (T, 1236L, dec | showpos, 0, 0, ' ', "", "%+ld");
|
|
TEST (T, -1237L, dec | showpos, 0, 0, ' ', "", "%+ld");
|
|
TEST (T, LONG_MAX, dec | showpos, 0, 0, ' ', "", "%+ld");
|
|
TEST (T, LONG_MIN, dec | showpos, 0, 0, ' ', "", "%+ld");
|
|
|
|
rw_info (0, 0, __LINE__,
|
|
"std::ios::dec | std::ios::showbase | std::ios::showpos");
|
|
|
|
TEST (T, 0L, dec | showbase | showpos, 0, 0, ' ', "", "%#+ld");
|
|
TEST (T, 1238L, dec | showbase | showpos, 0, 0, ' ', "", "%#+ld");
|
|
TEST (T, -1239L, dec | showbase | showpos, 0, 0, ' ', "", "%#+ld");
|
|
TEST (T, LONG_MAX, dec | showbase | showpos, 0, 0, ' ', "", "%#+ld");
|
|
TEST (T, LONG_MIN, dec | showbase | showpos, 0, 0, ' ', "", "%#+ld");
|
|
|
|
// left justfication
|
|
rw_info (0, 0, __LINE__, "std::ios::dec | std::ios::left");
|
|
|
|
TEST (T, 0L, dec | left, 0, 10, ' ', "", "%-10ld");
|
|
TEST (T, 1L, dec | left, 0, 10, ' ', "", "%-10ld");
|
|
TEST (T, 12L, dec | left, 0, 10, ' ', "", "%-10ld");
|
|
TEST (T, 123L, dec | left, 0, 10, ' ', "", "%-10ld");
|
|
TEST (T, 1234L, dec | left, 0, 10, ' ', "", "%-10ld");
|
|
TEST (T, 12345L, dec | left, 0, 10, ' ', "", "%-10ld");
|
|
TEST (T, 123456L, dec | left, 0, 10, ' ', "", "%-10ld");
|
|
TEST (T, 1234567L, dec | left, 0, 10, ' ', "", "%-10ld");
|
|
TEST (T, 12345678L, dec | left, 0, 10, ' ', "", "%-10ld");
|
|
TEST (T, 123456789L, dec | left, 0, 10, ' ', "", "%-10ld");
|
|
|
|
// left justfication, signed dec
|
|
TEST (T, -1L, dec | left, 0, 10, ' ', "", "-1 ");
|
|
TEST (T, -12L, dec | left, 0, 10, ' ', "", "-12 ");
|
|
TEST (T, -123L, dec | left, 0, 10, ' ', "", "-123 ");
|
|
TEST (T, -1234L, dec | left, 0, 10, ' ', "", "-1234 ");
|
|
TEST (T, -12345L, dec | left, 0, 10, ' ', "", "-12345 ");
|
|
TEST (T, -123456L, dec | left, 0, 10, ' ', "", "-123456 ");
|
|
TEST (T, -1234567L, dec | left, 0, 10, ' ', "", "-1234567 ");
|
|
TEST (T, -12345678L, dec | left, 0, 10, ' ', "", "-12345678 ");
|
|
TEST (T, -123456789L, dec | left, 0, 10, ' ', "", "-123456789");
|
|
|
|
// left justification with fill char
|
|
TEST (T, -1L, dec | left, 0, 10, '#', "", "-1########");
|
|
TEST (T, -12L, dec | left, 0, 10, '@', "", "-12@@@@@@@");
|
|
TEST (T, -123L, dec | left, 0, 10, '*', "", "-123******");
|
|
TEST (T, -1234L, dec | left, 0, 10, '=', "", "-1234=====");
|
|
TEST (T, -12345L, dec | left, 0, 10, '.', "", "-12345....");
|
|
TEST (T, -123456L, dec | left, 0, 10, ',', "", "-123456,,,");
|
|
TEST (T, -1234567L, dec | left, 0, 10, '-', "", "-1234567--");
|
|
TEST (T, -12345678L, dec | left, 0, 10, '+', "", "-12345678+");
|
|
TEST (T, -123456789L, dec | left, 0, 10, ';', "", "-123456789");
|
|
|
|
// left justfication with grouping
|
|
TEST (T, 1L, dec | left, 0, 14, ' ', "\2", "1 ");
|
|
TEST (T, 12L, dec | left, 0, 14, ' ', "\2", "12 ");
|
|
TEST (T, 123L, dec | left, 0, 14, ' ', "\2", "1,23 ");
|
|
TEST (T, 1234L, dec | left, 0, 14, ' ', "\2", "12,34 ");
|
|
TEST (T, 12345L, dec | left, 0, 14, ' ', "\2", "1,23,45 ");
|
|
TEST (T, 123456L, dec | left, 0, 14, ' ', "\2", "12,34,56 ");
|
|
TEST (T, 1234567L, dec | left, 0, 14, ' ', "\2", "1,23,45,67 ");
|
|
TEST (T, 12345678L, dec | left, 0, 14, ' ', "\2", "12,34,56,78 ");
|
|
TEST (T, 123456789L, dec | left, 0, 14, ' ', "\2", "1,23,45,67,89 ");
|
|
TEST (T, 123456789L, dec | left, 0, 14, ',', "\2", "1,23,45,67,89,");
|
|
|
|
TEST (T, 1L, dec | left, 0, 14, ' ', "\2\1\3", "1 ");
|
|
TEST (T, 12L, dec | left, 0, 14, ' ', "\2\1\3", "12 ");
|
|
TEST (T, 123L, dec | left, 0, 14, ' ', "\2\1\3", "1,23 ");
|
|
TEST (T, 1234L, dec | left, 0, 14, ' ', "\2\1\3", "1,2,34 ");
|
|
TEST (T, 12345L, dec | left, 0, 14, ' ', "\2\1\3", "12,3,45 ");
|
|
TEST (T, 123456L, dec | left, 0, 14, ' ', "\2\1\3", "123,4,56 ");
|
|
TEST (T, 1234567L, dec | left, 0, 14, ' ', "\2\1\3", "1,234,5,67 ");
|
|
TEST (T, 12345678L, dec | left, 0, 14, ' ', "\2\1\3", "12,345,6,78 ");
|
|
TEST (T, 123456789L, dec | left, 0, 14, ' ', "\2\1\3", "123,456,7,89 ");
|
|
TEST (T, 123456789L, dec | left, 0, 14, '0', "\2\1\3", "123,456,7,8900");
|
|
|
|
TEST (T, -1L, dec | left, 0, 14, ' ', "\1\2\3", "-1 ");
|
|
TEST (T, -12L, dec | left, 0, 14, ' ', "\1\2\3", "-1,2 ");
|
|
TEST (T, -123L, dec | left, 0, 14, ' ', "\1\2\3", "-12,3 ");
|
|
TEST (T, -1234L, dec | left, 0, 14, ' ', "\1\2\3", "-1,23,4 ");
|
|
TEST (T, -12345L, dec | left, 0, 14, ' ', "\1\2\3", "-12,34,5 ");
|
|
TEST (T, -123456L, dec | left, 0, 14, ' ', "\1\2\3", "-123,45,6 ");
|
|
TEST (T, -1234567L, dec | left, 0, 14, ' ', "\1\2\3", "-1,234,56,7 ");
|
|
TEST (T, -12345678L, dec | left, 0, 14, ' ', "\1\2\3", "-12,345,67,8 ");
|
|
TEST (T, -123456789L, dec | left, 0, 14, ' ', "\1\2\3", "-123,456,78,9 ");
|
|
TEST (T, -123456789L, dec | left, 0, 14, ' ', "\3\1\2", "-1,23,45,6,789");
|
|
|
|
TEST (T, -123456780L, dec | left, 0, 14, ' ', "\x1", "-1,2,3,4,5,6,7,8,0");
|
|
|
|
TEST (T, -123456781L, dec | left, 0, 14, ' ', "\x2", "-1,23,45,67,81");
|
|
TEST (T, -123456782L, dec | left, 0, 14, ' ', "\x3", "-123,456,782 ");
|
|
TEST (T, -123456783L, dec | left, 0, 14, ' ', "\x4", "-1,2345,6783 ");
|
|
TEST (T, -123456784L, dec | left, 0, 14, ' ', "\x5", "-1234,56784 ");
|
|
TEST (T, -123456785L, dec | left, 0, 14, ' ', "\x6", "-123,456785 ");
|
|
TEST (T, -123456786L, dec | left, 0, 14, ' ', "\x7", "-12,3456786 ");
|
|
TEST (T, -123456787L, dec | left, 0, 14, ' ', "\x8", "-1,23456787 ");
|
|
TEST (T, -123456788L, dec | left, 0, 14, ' ', "\x9", "-123456788 ");
|
|
|
|
#ifndef _RWSTD_NO_EXT_BIN_IO
|
|
|
|
rw_info (0, 0, __LINE__, "std::ios::dec | std::ios::bin [extension]");
|
|
|
|
TEST (T, 33333333L, bin | dec, 0, 0, ' ', "", "%ld");
|
|
|
|
#endif // _RWSTD_NO_EXT_BIN_IO
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// explicit octal ouptut
|
|
rw_info (0, 0, __LINE__, "std::ios::oct");
|
|
|
|
TEST (T, 0L, oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, 1L, oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, 2L, oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, 12L, oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, 345L, oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, 6789L, oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, 98765L, oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, LONG_MAX, oct, 0, 0, ' ', "", "%lo");
|
|
|
|
TEST (T, LONG_MAX - 1, oct, 0, 0, ' ', "", "%lo");
|
|
|
|
// negative values formatted as oct cause overflow on input (lwg issue 23)
|
|
TEST (T, ~0L, oct, 0, 0, ' ', "", "%lo", GET_FAIL);
|
|
TEST (T, -1L, oct, 0, 0, ' ', "", "%lo", GET_FAIL);
|
|
TEST (T, -2L, oct, 0, 0, ' ', "", "%lo", GET_FAIL);
|
|
TEST (T, -12L, oct, 0, 0, ' ', "", "%lo", GET_FAIL);
|
|
TEST (T, -345L, oct, 0, 0, ' ', "", "%lo", GET_FAIL);
|
|
TEST (T, -6789L, oct, 0, 0, ' ', "", "%lo", GET_FAIL);
|
|
TEST (T, -98765L, oct, 0, 0, ' ', "", "%lo", GET_FAIL);
|
|
TEST (T, LONG_MIN, oct, 0, 0, ' ', "", "%lo", GET_FAIL);
|
|
|
|
rw_info (0, 0, __LINE__, "std::ios::oct | std::ios::dec");
|
|
|
|
TEST (T, 13579L, oct | dec, 0, 0, ' ', "", "%ld");
|
|
|
|
rw_info (0, 0, __LINE__, "std::ios::oct | std::ios::showbase");
|
|
|
|
TEST (T, 0L, oct | showbase, 0, 0, ' ', "", "%#lo");
|
|
TEST (T, 2345L, oct | showbase, 0, 0, ' ', "", "%#lo");
|
|
TEST (T, -2346L, oct | showbase, 0, 0, ' ', "", "%#lo", GET_FAIL);
|
|
TEST (T, LONG_MAX, oct | showbase, 0, 0, ' ', "", "%#+lo");
|
|
TEST (T, LONG_MIN, oct | showbase, 0, 0, ' ', "", "%#+lo", GET_FAIL);
|
|
|
|
rw_info (0, 0, __LINE__, "std::ios::oct | std::ios::showpos");
|
|
|
|
TEST (T, 0L, oct | showpos, 0, 0, ' ', "", "%+lo");
|
|
TEST (T, 2347L, oct | showpos, 0, 0, ' ', "", "%+lo");
|
|
TEST (T, -2348L, oct | showpos, 0, 0, ' ', "", "%+lo", GET_FAIL);
|
|
|
|
TEST (T, LONG_MAX, oct | showpos, 0, 0, ' ', "", "%+lo");
|
|
TEST (T, LONG_MIN, oct | showpos, 0, 0, ' ', "", "%+lo", GET_FAIL);
|
|
|
|
rw_info (0, 0, __LINE__,
|
|
"std::ios::oct | std::ios::showbase | std::ios::showpos");
|
|
|
|
TEST (T, 0L, oct | showbase | showpos, 0, 0, ' ', "", "%#+lo");
|
|
TEST (T, 2349L, oct | showbase | showpos, 0, 0, ' ', "", "%#+lo");
|
|
TEST (T, -2350L, oct | showbase | showpos, 0, 0, ' ', "", "%#+lo",
|
|
GET_FAIL);
|
|
|
|
TEST (T, LONG_MAX, oct | showbase | showpos, 0, 0, ' ', "", "%#+lo");
|
|
TEST (T, LONG_MIN, oct | showbase | showpos, 0, 0, ' ', "", "%#+lo",
|
|
GET_FAIL);
|
|
|
|
#ifndef _RWSTD_NO_EXT_BIN_IO
|
|
|
|
rw_info (0, 0, __LINE__, "std::ios::oct | std::ios::bin [extension]");
|
|
|
|
TEST (T, 22222222L, bin | oct, 0, 0, ' ', "", "%ld");
|
|
|
|
#endif // _RWSTD_NO_EXT_BIN_IO
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// explicit hexadecimal ouptut
|
|
rw_info (0, 0, __LINE__, "std::ios::hex");
|
|
|
|
TEST (T, 0L, hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, 1L, hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, 2L, hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, 12L, hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, 345L, hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, 6789L, hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, 98765L, hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, LONG_MAX, hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, LONG_MAX - 1, hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, LONG_MAX - 2, hex, 0, 0, ' ', "", "%lx");
|
|
|
|
// negative values formatted as hex cause overflow on input (lwg issue 23)
|
|
TEST (T, ~0L, hex, 0, 0, ' ', "", "%lx", GET_FAIL);
|
|
TEST (T, -1L, hex, 0, 0, ' ', "", "%lx", GET_FAIL);
|
|
TEST (T, -2L, hex, 0, 0, ' ', "", "%lx", GET_FAIL);
|
|
TEST (T, -12L, hex, 0, 0, ' ', "", "%lx", GET_FAIL);
|
|
TEST (T, -345L, hex, 0, 0, ' ', "", "%lx", GET_FAIL);
|
|
TEST (T, -6789L, hex, 0, 0, ' ', "", "%lx", GET_FAIL);
|
|
TEST (T, -98765L, hex, 0, 0, ' ', "", "%lx", GET_FAIL);
|
|
TEST (T, LONG_MIN, hex, 0, 0, ' ', "", "%lx", GET_FAIL);
|
|
|
|
rw_info (0, 0, __LINE__, "std::ios::hex | std::ios::uppercase");
|
|
|
|
TEST (T, 0L, hex | uppercase, 0, 0, ' ', "", "%lX");
|
|
TEST (T, 1L, hex | uppercase, 0, 0, ' ', "", "%lX");
|
|
TEST (T, 0XABCDL, hex | uppercase, 0, 0, ' ', "", "%lX");
|
|
TEST (T, 0XBCDEL, hex | uppercase, 0, 0, ' ', "", "%lX");
|
|
TEST (T, 0XCDEFL, hex | uppercase, 0, 0, ' ', "", "%lX");
|
|
|
|
rw_info (0, 0, __LINE__, "std::ios::hex | std::ios::showbase");
|
|
|
|
TEST (T, 0L, hex | showbase, 0, 0, ' ', "", "%#lx");
|
|
TEST (T, 1L, hex | showbase, 0, 0, ' ', "", "%#lx");
|
|
TEST (T, 0xdef1L, hex | showbase, 0, 0, ' ', "", "%#lx");
|
|
|
|
rw_info (0, 0, __LINE__,
|
|
"std::ios::hex | std::ios::uppercase | std::ios::showbase");
|
|
|
|
TEST (T, 0L, hex | uppercase | showbase, 0, 0, ' ', "", "%#lX");
|
|
TEST (T, 1L, hex | uppercase | showbase, 0, 0, ' ', "", "%#lX");
|
|
TEST (T, 0XEF02L, hex | uppercase | showbase, 0, 0, ' ', "", "%#lX");
|
|
|
|
rw_info (0, 0, __LINE__, "std::ios::hex | std::ios::oct");
|
|
|
|
TEST (T, 0L, oct | hex, 0, 0, ' ', "", "%ld");
|
|
TEST (T, 97531L, oct | hex, 0, 0, ' ', "", "%ld");
|
|
|
|
rw_info (0, 0, __LINE__, "std::ios::hex | std::ios::dec");
|
|
|
|
TEST (T, 86420L, dec | hex, 0, 0, ' ', "", "%ld");
|
|
|
|
rw_info (0, 0, __LINE__, "std::ios::hex | std::ios::dec | std::ios::oct");
|
|
|
|
TEST (T, 11111111L, oct | dec | hex, 0, 0, ' ', "", "%ld");
|
|
|
|
#ifndef _RWSTD_NO_EXT_BIN_IO
|
|
|
|
rw_info (0, 0, __LINE__, "std::ios::hex | std::ios::bin [extension]");
|
|
|
|
TEST (T, 44444444L, bin | hex, 0, 0, ' ', "", "%ld");
|
|
|
|
rw_info (0, 0, __LINE__, "std::ios::hex | std::ios::dec | "
|
|
"std::ios::oct | std::ios::bin [extension]");
|
|
|
|
TEST (T, 55555555L, bin | oct | dec | hex, 0, 0, ' ', "", "%ld");
|
|
|
|
#endif // _RWSTD_NO_EXT_BIN_IO
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// extension: fixed and negative precision
|
|
|
|
rw_info (0, 0, __LINE__,
|
|
"std::ios::fixed with negative precision [extension]");
|
|
|
|
TEST (T, 987654321L, 0, -1, 0, ' ', "", "987654321");
|
|
TEST (T, 987654322L, fixed, 0, 0, ' ', "", "987654322");
|
|
TEST (T, 987654323L, fixed, -1, 0, ' ', "", "98765432*3");
|
|
TEST (T, -987654323L, fixed, -1, 0, ' ', "", "-98765432*3");
|
|
TEST (T, 987654324L, fixed, -2, 0, ' ', "", "9876543*24");
|
|
TEST (T, -987654324L, fixed, -2, 0, ' ', "", "-9876543*24");
|
|
TEST (T, 987654325L, fixed, -3, 0, ' ', "", "987654*325");
|
|
TEST (T, -987654325L, fixed, -3, 0, ' ', "", "-987654*325");
|
|
TEST (T, 987654326L, fixed, -4, 0, ' ', "", "98765*4326");
|
|
TEST (T, -987654326L, fixed, -4, 0, ' ', "", "-98765*4326");
|
|
TEST (T, 987654327L, fixed, -5, 0, ' ', "", "9876*54327");
|
|
TEST (T, -987654327L, fixed, -5, 0, ' ', "", "-9876*54327");
|
|
TEST (T, 987654328L, fixed, -6, 0, ' ', "", "987*654328");
|
|
TEST (T, -987654328L, fixed, -6, 0, ' ', "", "-987*654328");
|
|
TEST (T, 987654329L, fixed, -7, 0, ' ', "", "98*7654329");
|
|
TEST (T, -987654329L, fixed, -7, 0, ' ', "", "-98*7654329");
|
|
TEST (T, 987654330L, fixed, -8, 0, ' ', "", "9*87654330");
|
|
TEST (T, -987654330L, fixed, -8, 0, ' ', "", "-9*87654330");
|
|
TEST (T, 987654331L, fixed, -9, 0, ' ', "", "0*987654331");
|
|
TEST (T, -987654331L, fixed, -9, 0, ' ', "", "-0*987654331");
|
|
TEST (T, 987654332L, fixed, -10, 0, ' ', "", "0*0987654332");
|
|
TEST (T, -987654332L, fixed, -10, 0, ' ', "", "-0*0987654332");
|
|
TEST (T, 987654333L, fixed, -11, 0, ' ', "", "0*00987654333");
|
|
TEST (T, -987654333L, fixed, -11, 0, ' ', "", "-0*00987654333");
|
|
TEST (T, 0L, fixed, -12, 0, ' ', "", "0*000000000000");
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
// second group is the last group (i.e., prevent repetition)
|
|
#if CHAR_MAX == UCHAR_MAX
|
|
# define GROUPING "\2\1\xff"
|
|
#else
|
|
# define GROUPING "\2\1\x7f"
|
|
#endif
|
|
|
|
TEST (T, 123456789L, dec | left, 0, 0, ' ', GROUPING, "123456,7,89");
|
|
TEST (T, -123456789L, dec | left, 0, 0, ' ', GROUPING, "-123456,7,89");
|
|
|
|
#undef GROUPING
|
|
|
|
#if CHAR_MAX == UCHAR_MAX
|
|
# define GROUPING "\2\3\xff"
|
|
#else
|
|
# define GROUPING "\2\3\x7f"
|
|
#endif
|
|
|
|
TEST (T, 123456789L, dec | left, 0, 0, ' ', GROUPING, "1234,567,89");
|
|
TEST (T, -123456789L, dec | left, 0, 0, ' ', GROUPING, "-1234,567,89");
|
|
|
|
TEST (T, 0x12345678L, hex | showbase, 0, 0, ' ', GROUPING, "0x123,456,78");
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// right justfication
|
|
rw_info (0, 0, __LINE__, "std::ios::right");
|
|
|
|
TEST (T, 1L, dec | right, 0, 10, ' ', "", " 1");
|
|
TEST (T, 12L, dec | right, 0, 10, ' ', "", " 12");
|
|
TEST (T, 123L, dec | right, 0, 10, ' ', "", " 123");
|
|
TEST (T, 1234L, dec | right, 0, 10, ' ', "", " 1234");
|
|
TEST (T, 12345L, dec | right, 0, 10, ' ', "", " 12345");
|
|
TEST (T, 123456L, dec | right, 0, 10, ' ', "", " 123456");
|
|
TEST (T, 1234567L, dec | right, 0, 10, ' ', "", " 1234567");
|
|
TEST (T, 12345678L, dec | right, 0, 10, ' ', "", " 12345678");
|
|
TEST (T, 123456789L, dec | right, 0, 10, ' ', "", " 123456789");
|
|
TEST (T, 123456789L, dec | right, 0, 10, '0', "", "0123456789");
|
|
TEST (T, 123456789L, dec | right, 0, 10, '+', "", "+123456789");
|
|
TEST (T, 123456789L, dec | right, 0, 10, '-', "", "-123456789");
|
|
|
|
// right justification, oct
|
|
TEST (T, 0L, oct | right, 0, 10, ' ', "", " 0");
|
|
TEST (T, 01L, oct | right, 0, 10, ' ', "", " 1");
|
|
TEST (T, 012L, oct | right, 0, 10, ' ', "", " 12");
|
|
TEST (T, 0123L, oct | right, 0, 10, ' ', "", " 123");
|
|
TEST (T, 01234L, oct | right, 0, 10, ' ', "", " 1234");
|
|
TEST (T, 012345L, oct | right, 0, 10, ' ', "", " 12345");
|
|
TEST (T, 0123456L, oct | right, 0, 10, ' ', "", " 123456");
|
|
TEST (T, 01234567L, oct | right, 0, 10, ' ', "", " 1234567");
|
|
TEST (T, 012345670L, oct | right, 0, 10, ' ', "", " 12345670");
|
|
TEST (T, 012345670L, oct | right, 0, 10, '1', "", "1112345670");
|
|
|
|
// right justification with grouping
|
|
TEST (T, 0L, oct | right, 0, 10, ' ', "\2", " 0");
|
|
TEST (T, 01L, oct | right, 0, 10, ' ', "\2", " 1");
|
|
TEST (T, 012L, oct | right, 0, 10, ' ', "\2", " 12");
|
|
TEST (T, 0123L, oct | right, 0, 10, ' ', "\2", " 1,23");
|
|
TEST (T, 01234L, oct | right, 0, 10, ' ', "\2", " 12,34");
|
|
TEST (T, 012345L, oct | right, 0, 10, ' ', "\2", " 1,23,45");
|
|
TEST (T, 0123456L, oct | right, 0, 10, ' ', "\2", " 12,34,56");
|
|
TEST (T, 01234567L, oct | right, 0, 10, ' ', "\2", "1,23,45,67");
|
|
TEST (T, 012345670L, oct | right, 0, 10, ' ', "\2", "12,34,56,70");
|
|
|
|
#undef FLAGS
|
|
#define flags hex | showbase | internal
|
|
#define FLAGS flags | uppercase
|
|
|
|
// internal justfication, hex
|
|
rw_info (0, 0, __LINE__, "std::ios::internal");
|
|
TEST (T, 0X1L, FLAGS, 0, 10, ' ', "", "0X 1");
|
|
TEST (T, 0x12L, flags, 0, 10, ' ', "", "0x 12");
|
|
TEST (T, 0X123L, FLAGS, 0, 10, ' ', "", "0X 123");
|
|
TEST (T, 0x1234L, flags, 0, 10, ' ', "", "0x 1234");
|
|
TEST (T, 0X12345L, FLAGS, 0, 10, ' ', "", "0X 12345");
|
|
TEST (T, 0x123abcL, flags, 0, 10, ' ', "", "0x 123abc");
|
|
TEST (T, 0x123abcL, flags, 0, 10, '0', "", "0x00123abc");
|
|
TEST (T, 0X1234ABCL, FLAGS, 0, 10, ' ', "", "0X 1234ABC");
|
|
TEST (T, 0X12345678L, FLAGS, 0, 10, ' ', "", "0X12345678");
|
|
TEST (T, 0X12345678L, FLAGS, 0, 10, '0', "", "0X12345678");
|
|
|
|
// internal justfication, hex, grouping
|
|
TEST (T, 0X1L, FLAGS, 0, 10, ' ', "\1\2", "0X 1");
|
|
TEST (T, 0x12L, flags, 0, 10, ' ', "\1\2", "0x 1,2");
|
|
TEST (T, 0X123L, FLAGS, 0, 10, ' ', "\1\2", "0X 12,3");
|
|
TEST (T, 0x1234L, flags, 0, 10, ' ', "\1\2", "0x 1,23,4");
|
|
TEST (T, 0X12345L, FLAGS, 0, 10, ' ', "\1\2", "0X 12,34,5");
|
|
TEST (T, 0X12345L, FLAGS, 0, 10, ',', "\1\2", "0X,12,34,5");
|
|
TEST (T, 0x123abcL, flags, 0, 10, ' ', "\1\2", "0x1,23,ab,c");
|
|
TEST (T, 0X1234ABCL, FLAGS, 0, 10, ' ', "\1\2", "0X12,34,AB,C");
|
|
TEST (T, 0X12345678L, FLAGS, 0, 10, ' ', "\1\2", "0X1,23,45,67,8");
|
|
TEST (T, 0X12345678L, FLAGS, 0, 10, '0', "\1\2", "0X1,23,45,67,8");
|
|
|
|
#undef flags
|
|
#undef FLAGS
|
|
#define FLAGS dec | showpos | internal
|
|
|
|
// internal justfication, signed dec
|
|
TEST (T, 0L, FLAGS, 0, 10, ' ', "", "+ 0");
|
|
TEST (T, -1L, FLAGS, 0, 10, ' ', "", "- 1");
|
|
TEST (T, +12L, FLAGS, 0, 10, ' ', "", "+ 12");
|
|
TEST (T, -123L, FLAGS, 0, 10, ' ', "", "- 123");
|
|
TEST (T, +1234L, FLAGS, 0, 10, ' ', "", "+ 1234");
|
|
TEST (T, -12345L, FLAGS, 0, 10, ' ', "", "- 12345");
|
|
TEST (T, +123456L, FLAGS, 0, 10, ' ', "", "+ 123456");
|
|
TEST (T, -1234567L, FLAGS, 0, 10, ' ', "", "- 1234567");
|
|
TEST (T, +12345678L, FLAGS, 0, 10, ' ', "", "+ 12345678");
|
|
TEST (T, -123456789L, FLAGS, 0, 10, '0', "", "-123456789");
|
|
|
|
TEST (T, +1L, FLAGS, 0, 10, '-', "", "+--------1");
|
|
TEST (T, -12L, FLAGS, 0, 10, '-', "", "--------12");
|
|
TEST (T, +123L, FLAGS, 0, 10, '+', "", "+++++++123");
|
|
TEST (T, -1234L, FLAGS, 0, 10, '+', "", "-+++++1234");
|
|
TEST (T, +12345L, FLAGS, 0, 10, '0', "", "+000012345");
|
|
TEST (T, -123456L, FLAGS, 0, 10, '1', "", "-111123456");
|
|
TEST (T, +1234567L, FLAGS, 0, 10, '2', "", "+221234567");
|
|
TEST (T, -12345678L, FLAGS, 0, 10, '3', "", "-312345678");
|
|
TEST (T, +123456789L, FLAGS, 0, 10, '4', "", "+123456789");
|
|
|
|
#ifndef _RWSTD_NO_EXT_BIN_IO
|
|
|
|
// bin
|
|
rw_info (0, 0, __LINE__, "std::ios::bin [extension]");
|
|
|
|
TEST (T, 0L, bin, 0, 16, '.', "\4", "...............0");
|
|
TEST (T, 1L, bin, 0, 16, '.', "\4", "...............1");
|
|
TEST (T, 2L, bin, 0, 16, '.', "\4", "..............10");
|
|
TEST (T, 3L, bin, 0, 16, '.', "\4", "..............11");
|
|
TEST (T, 4L, bin, 0, 16, '.', "\4", ".............100");
|
|
TEST (T, 5L, bin, 0, 16, '.', "\4", ".............101");
|
|
TEST (T, 6L, bin, 0, 16, '.', "\4", ".............110");
|
|
TEST (T, 7L, bin, 0, 16, '.', "\4", ".............111");
|
|
TEST (T, 8L, bin, 0, 16, '.', "\4", "............1000");
|
|
TEST (T, 9L, bin, 0, 16, '.', "\4", "............1001");
|
|
TEST (T, 0x0aL, bin, 0, 16, '.', "\4", "............1010");
|
|
TEST (T, 0x0bL, bin, 0, 16, '.', "\4", "............1011");
|
|
TEST (T, 0x0cL, bin, 0, 16, '.', "\4", "............1100");
|
|
TEST (T, 0x0dL, bin, 0, 16, '.', "\4", "............1101");
|
|
TEST (T, 0x0eL, bin, 0, 16, '.', "\4", "............1110");
|
|
TEST (T, 0x0fL, bin, 0, 16, '.', "\4", "............1111");
|
|
|
|
TEST (T, 0xf0L, bin, 0, 16, '.', "\4", ".......1111,0000");
|
|
TEST (T, 0xf1L, bin, 0, 16, '.', "\4", ".......1111,0001");
|
|
TEST (T, 0xf2L, bin, 0, 16, '.', "\4", ".......1111,0010");
|
|
TEST (T, 0xf3L, bin, 0, 16, '.', "\4", ".......1111,0011");
|
|
TEST (T, 0xf4L, bin, 0, 16, '.', "\4", ".......1111,0100");
|
|
TEST (T, 0xf5L, bin, 0, 16, '.', "\4", ".......1111,0101");
|
|
|
|
TEST (T, 0x12345678L, bin, 0, 0, '.', "\4",
|
|
"1,0010,0011,0100,0101,0110,0111,1000");
|
|
|
|
TEST (T, 0xfedcba98L, bin, 0, 0, '\0', "\010",
|
|
"11111110,11011100,10111010,10011000");
|
|
|
|
#endif // _RWSTD_NO_EXT_BIN_IO
|
|
|
|
// locale 3.0 extension
|
|
|
|
#define BASE(n) ((n) << _RWSTD_IOS_BASEOFF)
|
|
|
|
// bases 0 and 10 are both base 10
|
|
// base 1 is roman (values 1 through 4999)
|
|
// bases 2 through 36 are what they are
|
|
// anything else is unspecified
|
|
|
|
rw_info (0, 0, __LINE__, "base 1 (Roman), and 2 through 36 [extension]");
|
|
|
|
TEST (T, 1234L, BASE ( 0), 0, 0, '\0', "", "1234");
|
|
TEST (T, 1234L, BASE ( 1), 0, 0, '\0', "", "mccxxxiv");
|
|
TEST (T, 0x1234L, BASE ( 2), 0, 0, '\0', "", "1001000110100");
|
|
|
|
TEST (T, 01234L, oct | BASE ( 8), 0, 0, '\0', "", "1234");
|
|
TEST (T, 1234L, dec | BASE (10), 0, 0, '\0', "", "1234");
|
|
TEST (T, 0x1234L, hex | BASE (16), 0, 0, '\0', "", "1234");
|
|
|
|
TEST (T, 1234L, BASE ( 2), 0, 0, '\0', "", "10011010010");
|
|
TEST (T, 1234L, BASE ( 3), 0, 0, '\0', "", "1200201");
|
|
TEST (T, 1234L, BASE ( 4), 0, 0, '\0', "", "103102");
|
|
TEST (T, 1234L, BASE ( 5), 0, 0, '\0', "", "14414");
|
|
TEST (T, 1234L, BASE ( 6), 0, 0, '\0', "", "5414");
|
|
TEST (T, 1234L, BASE ( 7), 0, 0, '\0', "", "3412");
|
|
TEST (T, 1234L, BASE ( 9), 0, 0, '\0', "", "1621");
|
|
|
|
TEST (T, 1234L, dec | BASE (10), 0, 0, '\0', "", "1234");
|
|
|
|
TEST (T, 1234L, BASE (11), 0, 0, '\0', "", "a22");
|
|
TEST (T, 1234L, BASE (12), 0, 0, '\0', "", "86a");
|
|
TEST (T, 1234L, BASE (13), 0, 0, '\0', "", "73c");
|
|
TEST (T, 1234L, BASE (14), 0, 0, '\0', "", "642");
|
|
TEST (T, 1234L, BASE (15), 0, 0, '\0', "", "574");
|
|
|
|
TEST (T, 1234L, hex | BASE (16), 0, 0, '\0', "", "4d2");
|
|
|
|
TEST (T, 1234L, BASE (17), 0, 0, '\0', "", "44a");
|
|
TEST (T, 1234L, BASE (18), 0, 0, '\0', "", "3ea");
|
|
TEST (T, 1234L, BASE (19), 0, 0, '\0', "", "37i");
|
|
TEST (T, 1234L, BASE (20), 0, 0, '\0', "", "31e");
|
|
TEST (T, 1234L, BASE (21), 0, 0, '\0', "", "2gg");
|
|
TEST (T, 1234L, BASE (22), 0, 0, '\0', "", "2c2");
|
|
TEST (T, 1234L, BASE (23), 0, 0, '\0', "", "27f");
|
|
TEST (T, 1234L, BASE (24), 0, 0, '\0', "", "23a");
|
|
TEST (T, 1234L, BASE (25), 0, 0, '\0', "", "1o9");
|
|
TEST (T, 1234L, BASE (26), 0, 0, '\0', "", "1lc");
|
|
TEST (T, 1234L, BASE (27), 0, 0, '\0', "", "1ij");
|
|
TEST (T, 1234L, BASE (28), 0, 0, '\0', "", "1g2");
|
|
TEST (T, 1234L, BASE (29), 0, 0, '\0', "", "1dg");
|
|
TEST (T, 1234L, BASE (30), 0, 0, '\0', "", "1b4");
|
|
TEST (T, 1234L, BASE (31), 0, 0, '\0', "", "18p");
|
|
TEST (T, 1234L, BASE (32), 0, 0, '\0', "", "16i");
|
|
TEST (T, 1234L, BASE (33), 0, 0, '\0', "", "14d");
|
|
TEST (T, 1234L, BASE (34), 0, 0, '\0', "", "12a");
|
|
TEST (T, 1234L, BASE (35), 0, 0, '\0', "", "109");
|
|
TEST (T, 1234L, BASE (36), 0, 0, '\0', "", "ya");
|
|
|
|
// effect of non-empty grouping is unspecified
|
|
TEST (T, 0L, BASE (1), 0, 0, '\0', "", "0");
|
|
TEST (T, 1L, BASE (1), 0, 0, '\0', "", "i");
|
|
TEST (T, 2L, BASE (1), 0, 0, '\0', "", "ii");
|
|
TEST (T, 3L, BASE (1), 0, 0, '\0', "", "iii");
|
|
TEST (T, 4L, BASE (1), 0, 0, '\0', "", "iv");
|
|
TEST (T, 5L, BASE (1), 0, 0, '\0', "", "v");
|
|
TEST (T, 6L, BASE (1), 0, 0, '\0', "", "vi");
|
|
TEST (T, 7L, BASE (1), 0, 0, '\0', "", "vii");
|
|
TEST (T, 8L, BASE (1), 0, 0, '\0', "", "viii");
|
|
TEST (T, 9L, BASE (1), 0, 0, '\0', "", "ix");
|
|
TEST (T, 10L, BASE (1), 0, 0, '\0', "", "x");
|
|
TEST (T, 50L, BASE (1), 0, 0, '\0', "", "l");
|
|
TEST (T, 100L, BASE (1), 0, 0, '\0', "", "c");
|
|
TEST (T, 500L, BASE (1), 0, 0, '\0', "", "d");
|
|
TEST (T, 1000L, BASE (1), 0, 0, '\0', "", "m");
|
|
TEST (T, 49L, BASE (1), 0, 0, '\0', "", "xlix");
|
|
TEST (T, 88L, BASE (1), 0, 0, '\0', "", "lxxxviii");
|
|
TEST (T, 99L, BASE (1), 0, 0, '\0', "", "xcix");
|
|
TEST (T, 1999L, BASE (1), 0, 0, '\0', "", "mcmxcix");
|
|
TEST (T, 2000L, BASE (1), 0, 0, '\0', "", "mm");
|
|
TEST (T, 2001L, BASE (1), 0, 0, '\0', "", "mmi");
|
|
TEST (T, 4999L, BASE (1), 0, 0, '\0', "", "mmmmcmxcix");
|
|
TEST (T, 5000L, BASE (1), 0, 0, '\0', "", "5000");
|
|
|
|
TEST (T, 1492L, BASE (1), 0, 10, '*', "", "***mcdxcii");
|
|
|
|
TEST (T, 1776L, BASE (1) | uppercase, 0, 0, '\0', "", "MDCCLXXVI");
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
|
|
template <class charT>
|
|
void ulong_test (charT, const char *cname)
|
|
{
|
|
const char* const tname = "unsigned long";
|
|
|
|
rw_info (0, 0, __LINE__, "std::num_put<%s>::put (..., %s)", cname, tname);
|
|
|
|
typedef unsigned long ULong;
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
rw_info (0, 0, __LINE__, "std::ios::dec");
|
|
|
|
TEST (T, 0UL, dec, 0, 0, ' ', "", "%lu");
|
|
TEST (T, ULong (LONG_MAX), dec, 0, 0, ' ', "", "%lu");
|
|
|
|
rw_info (0, 0, __LINE__, "std::ios::dec | std::ios::shopos");
|
|
|
|
TEST (T, 0UL, dec | showpos, 0, 0, ' ', "", "%+lu");
|
|
TEST (T, 1UL, dec | showpos, 0, 0, ' ', "", "%+lu");
|
|
TEST (T, ULong (LONG_MAX), dec | showpos, 0, 0, ' ', "", "%+lu");
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
rw_info (0, 0, __LINE__, "std::ios::oct");
|
|
|
|
TEST (T, ULong (CHAR_MAX), oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, ULong (UCHAR_MAX), oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, ULong (SCHAR_MAX), oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, ULong (SHRT_MAX), oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, ULong (USHRT_MAX), oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, ULong (INT_MAX), oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, ULong (UINT_MAX), oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, ULong (LONG_MAX), oct, 0, 0, ' ', "", "%lo");
|
|
|
|
TEST (T, ULong (CHAR_MIN), oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, ULong (SCHAR_MIN), oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, ULong (SHRT_MIN), oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, ULong (INT_MIN), oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, ULong (LONG_MIN), oct, 0, 0, ' ', "", "%lo");
|
|
|
|
// no overflow
|
|
TEST (T, 1UL, oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, ~0UL, oct, 0, 0, ' ', "", "%lo");
|
|
TEST (T, ULong (ULONG_MAX), oct, 0, 0, ' ', "", "%lo");
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
rw_info (0, 0, __LINE__, "std::ios::hex");
|
|
|
|
TEST (T, ULong (CHAR_MAX), hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, ULong (UCHAR_MAX), hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, ULong (SCHAR_MAX), hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, ULong (SHRT_MAX), hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, ULong (USHRT_MAX), hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, ULong (INT_MAX), hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, ULong (UINT_MAX), hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, ULong (LONG_MAX), hex, 0, 0, ' ', "", "%lx");
|
|
|
|
TEST (T, ULong (CHAR_MIN), hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, ULong (SCHAR_MIN), hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, ULong (SHRT_MIN), hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, ULong (INT_MIN), hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, ULong (LONG_MIN), hex, 0, 0, ' ', "", "%lx");
|
|
|
|
TEST (T, 1UL, hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, ~0UL, hex, 0, 0, ' ', "", "%lx");
|
|
TEST (T, ULong (ULONG_MAX), hex, 0, 0, ' ', "", "%lx");
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
|
|
template <class charT>
|
|
void llong_test (charT, const char *cname)
|
|
{
|
|
const char* const tname = "long long";
|
|
|
|
rw_info (0, 0, 0, "std::num_put<%s>::put (..., %s)", cname, tname);
|
|
|
|
#ifndef _RWSTD_NO_LONG_LONG
|
|
|
|
# define STDIO_FMAT "%" _RWSTD_LLONG_PRINTF_PREFIX "d"
|
|
|
|
# ifndef _MSC_VER
|
|
# define LL(number) number ## LL
|
|
# else // if defined (_MSC_VER)
|
|
// MSVC 7.0 doesn't recognize the LL suffix
|
|
# define LL(number) number ## I64
|
|
# endif // _MSC_VER
|
|
|
|
TEST (T, LL (0), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
TEST (T, LL (1), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
TEST (T, LL (21), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
TEST (T, LL (321), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
TEST (T, LL (4321), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
TEST (T, LL (54321), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
TEST (T, LL (654321), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
TEST (T, LL (7654321), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
TEST (T, LL (87654321), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
TEST (T, LL (987654321), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
|
|
TEST (T, ~LL (0), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
TEST (T, -LL (1), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
TEST (T, -LL (21), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
TEST (T, -LL (321), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
TEST (T, -LL (4321), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
TEST (T, -LL (54321), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
TEST (T, -LL (654321), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
TEST (T, -LL (7654321), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
TEST (T, -LL (87654321), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
TEST (T, -LL (987654321), dec, 0, 0, ' ', "", STDIO_FMAT);
|
|
|
|
# undef FLAGS
|
|
# define FLAGS hex | showbase | internal
|
|
|
|
# undef OPTS
|
|
# define OPTS FLAGS, 0, 20, ' ', "\1\2\3\4\1\2\3\4"
|
|
|
|
// internal justfication, hex format, grouping
|
|
TEST (T, LL (0), OPTS, " 0");
|
|
TEST (T, LL (0x1), OPTS, "0x 1");
|
|
TEST (T, LL (0x12), OPTS, "0x 1,2");
|
|
TEST (T, LL (0x123), OPTS, "0x 12,3");
|
|
TEST (T, LL (0x1234), OPTS, "0x 1,23,4");
|
|
TEST (T, LL (0x12345), OPTS, "0x 12,34,5");
|
|
TEST (T, LL (0x123456), OPTS, "0x 123,45,6");
|
|
TEST (T, LL (0x1234567), OPTS, "0x 1,234,56,7");
|
|
TEST (T, LL (0x12345678), OPTS, "0x 12,345,67,8");
|
|
TEST (T, LL (0x123456789), OPTS, "0x 123,456,78,9");
|
|
TEST (T, LL (0x123456789a), OPTS, "0x 1234,567,89,a");
|
|
TEST (T, LL (0x123456789ab), OPTS, "0x 1,2345,678,9a,b");
|
|
TEST (T, LL (0x123456789abc), OPTS, "0x 1,2,3456,789,ab,c");
|
|
TEST (T, LL (0x123456789abcd), OPTS, "0x12,3,4567,89a,bc,d");
|
|
TEST (T, LL (0x123456789abcde), OPTS, "0x1,23,4,5678,9ab,cd,e");
|
|
TEST (T, LL (0x123456789abcdef), OPTS, "0x12,34,5,6789,abc,de,f");
|
|
TEST (T, LL (0x123456789abcdef0), OPTS, "0x123,45,6,789a,bcd,ef,0");
|
|
|
|
#else // if defined (_RWSTD_NO_LONG_LONG)
|
|
|
|
rw_note (0, 0, __LINE__, "num_put<%s>::put (..., %s) not exercised, "
|
|
"macro _RWSTD_NO_LONG_LONG #defined",
|
|
cname, tname);
|
|
|
|
#endif // _RWSTD_LONG_LONG
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
|
|
template <class charT>
|
|
void ullong_test (charT, const char *cname)
|
|
{
|
|
const char* const tname = "unsigned long long";
|
|
|
|
rw_info (0, 0, 0, "std::num_put<%s>::put (..., %s)", cname, tname);
|
|
|
|
#ifndef _RWSTD_NO_LONG_LONG
|
|
|
|
rw_warn (0, 0, __LINE__, "num_put<%s>::put (..., %s) not exercised",
|
|
cname, tname);
|
|
|
|
#else // if defined (_RWSTD_NO_LONG_LONG)
|
|
|
|
rw_note (0, 0, __LINE__, "num_put<%s>::put (..., %s) not exercised, "
|
|
"macro _RWSTD_NO_LONG_LONG #defined",
|
|
cname, tname);
|
|
|
|
#endif // _RWSTD_NO_LONG_LONG
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
// use a volatile variable to fool optimizers into not issuing
|
|
// warnings about division by zero
|
|
volatile double zero;
|
|
|
|
|
|
template <class charT, class floatT>
|
|
void inf_nan_test (charT, floatT, const char *cname, const char *tname)
|
|
{
|
|
rw_info (0, 0, 0, "std::num_put<%s>::put (..., %s) formatting "
|
|
"infinities", cname, tname);
|
|
|
|
// compute infinity
|
|
const floatT inf = 1 / zero;
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// exercise the formatting of positive and negative infinities
|
|
|
|
// +-- value to format
|
|
// | +-- fmtflags
|
|
// | | +-- precision
|
|
// | | | +-- field width
|
|
// | | | | +-- fill character
|
|
// | | | | | +-- grouping
|
|
// | | | | | | +-- expected output
|
|
// | | | | | | |
|
|
// V V V V V V V
|
|
TEST (T, inf, 0, 0, 0, ' ', "", "inf");
|
|
TEST (T, inf, showpos, 0, 0, ' ', "", "+inf");
|
|
TEST (T, inf, uppercase, 0, 0, ' ', "", "INF");
|
|
TEST (T, inf, showpos | uppercase, 0, 0, ' ', "", "+INF");
|
|
|
|
TEST (T, -inf, 0, 0, 0, ' ', "", "-inf");
|
|
TEST (T, -inf, showpos, 0, 0, ' ', "", "-inf");
|
|
TEST (T, -inf, uppercase, 0, 0, ' ', "", "-INF");
|
|
TEST (T, -inf, showpos | uppercase, 0, 0, ' ', "", "-INF");
|
|
|
|
TEST (T, inf, 0, 1, 0, ' ', "", "inf");
|
|
TEST (T, inf, showpos, 1, 0, ' ', "", "+inf");
|
|
TEST (T, inf, uppercase, 1, 0, ' ', "", "INF");
|
|
TEST (T, inf, showpos | uppercase, 1, 0, ' ', "", "+INF");
|
|
|
|
TEST (T, -inf, 0, 1, 0, ' ', "", "-inf");
|
|
TEST (T, -inf, showpos, 1, 0, ' ', "", "-inf");
|
|
TEST (T, -inf, uppercase, 1, 0, ' ', "", "-INF");
|
|
TEST (T, -inf, showpos | uppercase, 1, 0, ' ', "", "-INF");
|
|
|
|
TEST (T, inf, 0, 3, 0, ' ', "", "inf");
|
|
TEST (T, inf, showpos, 3, 0, ' ', "", "+inf");
|
|
TEST (T, inf, uppercase, 3, 0, ' ', "", "INF");
|
|
TEST (T, inf, showpos | uppercase, 3, 0, ' ', "", "+INF");
|
|
|
|
TEST (T, -inf, 0, 3, 0, ' ', "", "-inf");
|
|
TEST (T, -inf, showpos, 3, 0, ' ', "", "-inf");
|
|
TEST (T, -inf, uppercase, 3, 0, ' ', "", "-INF");
|
|
TEST (T, -inf, showpos | uppercase, 3, 0, ' ', "", "-INF");
|
|
|
|
TEST (T, inf, 0, 4, 0, ' ', "", "inf");
|
|
TEST (T, inf, showpos, 4, 0, ' ', "", "+inf");
|
|
TEST (T, inf, uppercase, 4, 0, ' ', "", "INF");
|
|
TEST (T, inf, showpos | uppercase, 4, 0, ' ', "", "+INF");
|
|
|
|
TEST (T, -inf, 0, 4, 0, ' ', "", "-inf");
|
|
TEST (T, -inf, showpos, 4, 0, ' ', "", "-inf");
|
|
TEST (T, -inf, uppercase, 4, 0, ' ', "", "-INF");
|
|
TEST (T, -inf, showpos | uppercase, 4, 0, ' ', "", "-INF");
|
|
|
|
TEST (T, inf, 0, 9, 0, ' ', "", "inf");
|
|
TEST (T, inf, showpos, 9, 0, ' ', "", "+inf");
|
|
TEST (T, inf, uppercase, 9, 0, ' ', "", "INF");
|
|
TEST (T, inf, showpos | uppercase, 9, 0, ' ', "", "+INF");
|
|
|
|
TEST (T, -inf, 0, 9, 0, ' ', "", "-inf");
|
|
TEST (T, -inf, showpos, 9, 0, ' ', "", "-inf");
|
|
TEST (T, -inf, uppercase, 9, 0, ' ', "", "-INF");
|
|
TEST (T, -inf, showpos | uppercase, 9, 0, ' ', "", "-INF");
|
|
|
|
TEST (T, inf, 0, 0, 1, ' ', "", "inf");
|
|
TEST (T, inf, showpos, 0, 1, ' ', "", "+inf");
|
|
TEST (T, inf, uppercase, 0, 1, ' ', "", "INF");
|
|
TEST (T, inf, showpos | uppercase, 0, 1, ' ', "", "+INF");
|
|
|
|
TEST (T, -inf, 0, 0, 1, ' ', "", "-inf");
|
|
TEST (T, -inf, showpos, 0, 1, ' ', "", "-inf");
|
|
TEST (T, -inf, uppercase, 0, 1, ' ', "", "-INF");
|
|
TEST (T, -inf, showpos | uppercase, 0, 1, ' ', "", "-INF");
|
|
|
|
TEST (T, inf, 0, 0, 3, ' ', "", "inf");
|
|
TEST (T, inf, showpos, 0, 3, ' ', "", "+inf");
|
|
TEST (T, inf, uppercase, 0, 3, ' ', "", "INF");
|
|
TEST (T, inf, showpos | uppercase, 0, 3, ' ', "", "+INF");
|
|
|
|
TEST (T, -inf, 0, 0, 3, ' ', "", "-inf");
|
|
TEST (T, -inf, showpos, 0, 3, ' ', "", "-inf");
|
|
TEST (T, -inf, uppercase, 0, 3, ' ', "", "-INF");
|
|
TEST (T, -inf, showpos | uppercase, 0, 3, ' ', "", "-INF");
|
|
|
|
TEST (T, inf, 0, 0, 4, ' ', "", " inf");
|
|
TEST (T, inf, showpos, 0, 4, ' ', "", "+inf");
|
|
TEST (T, inf, uppercase, 0, 4, ' ', "", " INF");
|
|
TEST (T, inf, showpos | uppercase, 0, 4, ' ', "", "+INF");
|
|
|
|
TEST (T, -inf, 0, 0, 4, ' ', "", "-inf");
|
|
TEST (T, -inf, showpos, 0, 4, ' ', "", "-inf");
|
|
TEST (T, -inf, uppercase, 0, 4, ' ', "", "-INF");
|
|
TEST (T, -inf, showpos | uppercase, 0, 4, ' ', "", "-INF");
|
|
|
|
TEST (T, inf, 0, 0, 8, ' ', "", " inf");
|
|
TEST (T, inf, showpos, 0, 8, ' ', "", " +inf");
|
|
TEST (T, inf, uppercase, 0, 8, ' ', "", " INF");
|
|
TEST (T, inf, showpos | uppercase, 0, 8, ' ', "", " +INF");
|
|
|
|
TEST (T, -inf, 0, 0, 8, ' ', "", " -inf");
|
|
TEST (T, -inf, showpos, 0, 8, ' ', "", " -inf");
|
|
TEST (T, -inf, uppercase, 0, 8, ' ', "", " -INF");
|
|
TEST (T, -inf, showpos | uppercase, 0, 8, ' ', "", " -INF");
|
|
|
|
TEST (T, inf, left, 0, 9, ' ', "", "inf ");
|
|
TEST (T, inf, left | showpos, 0, 9, ' ', "", "+inf ");
|
|
TEST (T, inf, left | uppercase, 0, 9, ' ', "", "INF ");
|
|
TEST (T, inf, left | showpos | uppercase, 0, 9, ' ', "", "+INF ");
|
|
|
|
TEST (T, -inf, left, 0, 9, ' ', "", "-inf ");
|
|
TEST (T, -inf, left | showpos, 0, 9, ' ', "", "-inf ");
|
|
TEST (T, -inf, left | uppercase, 0, 9, ' ', "", "-INF ");
|
|
TEST (T, -inf, left | showpos | uppercase, 0, 9, ' ', "", "-INF ");
|
|
|
|
TEST (T, inf, right, 0, 9, ' ', "", " inf");
|
|
TEST (T, inf, right | showpos, 0, 9, ' ', "", " +inf");
|
|
TEST (T, inf, right | uppercase, 0, 9, ' ', "", " INF");
|
|
TEST (T, inf, right | showpos | uppercase, 0, 9, ' ', "", " +INF");
|
|
|
|
TEST (T, -inf, right, 0, 9, ' ', "", " -inf");
|
|
TEST (T, -inf, right | showpos, 0, 9, ' ', "", " -inf");
|
|
TEST (T, -inf, right | uppercase, 0, 9, ' ', "", " -INF");
|
|
TEST (T, -inf, right | showpos | uppercase, 0, 9, ' ', "", " -INF");
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// exercise the formatting of positive and negative (quiet) NaNs
|
|
|
|
rw_info (0, 0, 0, "std::num_put<%s>::put (..., %s) formatting "
|
|
"NaN's", cname, tname);
|
|
|
|
// compute a quiet NaN
|
|
#if 0
|
|
|
|
// temporarily disabled (NAN format is platform specific
|
|
// and subject to bugs -- see for example STDCXX-464)
|
|
|
|
const floatT nan = 0 / zero;
|
|
|
|
TEST (T, nan, 0, 0, 0, ' ', "", "nan");
|
|
TEST (T, nan, showpos, 0, 0, ' ', "", "+nan");
|
|
TEST (T, nan, uppercase, 0, 0, ' ', "", "NAN");
|
|
TEST (T, nan, showpos | uppercase, 0, 0, ' ', "", "+NAN");
|
|
|
|
TEST (T, -nan, 0, 0, 0, ' ', "", "-nan");
|
|
TEST (T, -nan, showpos, 0, 0, ' ', "", "-nan");
|
|
TEST (T, -nan, uppercase, 0, 0, ' ', "", "-NAN");
|
|
TEST (T, -nan, showpos | uppercase, 0, 0, ' ', "", "-NAN");
|
|
|
|
TEST (T, nan, 0, 1, 0, ' ', "", "nan");
|
|
TEST (T, nan, showpos, 1, 0, ' ', "", "+nan");
|
|
TEST (T, nan, uppercase, 1, 0, ' ', "", "NAN");
|
|
TEST (T, nan, showpos | uppercase, 1, 0, ' ', "", "+NAN");
|
|
|
|
TEST (T, -nan, 0, 1, 0, ' ', "", "-nan");
|
|
TEST (T, -nan, showpos, 1, 0, ' ', "", "-nan");
|
|
TEST (T, -nan, uppercase, 1, 0, ' ', "", "-NAN");
|
|
TEST (T, -nan, showpos | uppercase, 1, 0, ' ', "", "-NAN");
|
|
|
|
TEST (T, nan, 0, 3, 0, ' ', "", "nan");
|
|
TEST (T, nan, showpos, 3, 0, ' ', "", "+nan");
|
|
TEST (T, nan, uppercase, 3, 0, ' ', "", "NAN");
|
|
TEST (T, nan, showpos | uppercase, 3, 0, ' ', "", "+NAN");
|
|
|
|
TEST (T, -nan, 0, 3, 0, ' ', "", "-nan");
|
|
TEST (T, -nan, showpos, 3, 0, ' ', "", "-nan");
|
|
TEST (T, -nan, uppercase, 3, 0, ' ', "", "-NAN");
|
|
TEST (T, -nan, showpos | uppercase, 3, 0, ' ', "", "-NAN");
|
|
|
|
TEST (T, nan, 0, 4, 0, ' ', "", "nan");
|
|
TEST (T, nan, showpos, 4, 0, ' ', "", "+nan");
|
|
TEST (T, nan, uppercase, 4, 0, ' ', "", "NAN");
|
|
TEST (T, nan, showpos | uppercase, 4, 0, ' ', "", "+NAN");
|
|
|
|
TEST (T, -nan, 0, 4, 0, ' ', "", "-nan");
|
|
TEST (T, -nan, showpos, 4, 0, ' ', "", "-nan");
|
|
TEST (T, -nan, uppercase, 4, 0, ' ', "", "-NAN");
|
|
TEST (T, -nan, showpos | uppercase, 4, 0, ' ', "", "-NAN");
|
|
|
|
TEST (T, nan, 0, 9, 0, ' ', "", "nan");
|
|
TEST (T, nan, showpos, 9, 0, ' ', "", "+nan");
|
|
TEST (T, nan, uppercase, 9, 0, ' ', "", "NAN");
|
|
TEST (T, nan, showpos | uppercase, 9, 0, ' ', "", "+NAN");
|
|
|
|
TEST (T, -nan, 0, 9, 0, ' ', "", "-nan");
|
|
TEST (T, -nan, showpos, 9, 0, ' ', "", "-nan");
|
|
TEST (T, -nan, uppercase, 9, 0, ' ', "", "-NAN");
|
|
TEST (T, -nan, showpos | uppercase, 9, 0, ' ', "", "-NAN");
|
|
|
|
TEST (T, nan, 0, 0, 1, ' ', "", "nan");
|
|
TEST (T, nan, showpos, 0, 1, ' ', "", "+nan");
|
|
TEST (T, nan, uppercase, 0, 1, ' ', "", "NAN");
|
|
TEST (T, nan, showpos | uppercase, 0, 1, ' ', "", "+NAN");
|
|
|
|
TEST (T, -nan, 0, 0, 1, ' ', "", "-nan");
|
|
TEST (T, -nan, showpos, 0, 1, ' ', "", "-nan");
|
|
TEST (T, -nan, uppercase, 0, 1, ' ', "", "-NAN");
|
|
TEST (T, -nan, showpos | uppercase, 0, 1, ' ', "", "-NAN");
|
|
|
|
TEST (T, nan, 0, 0, 3, ' ', "", "nan");
|
|
TEST (T, nan, showpos, 0, 3, ' ', "", "+nan");
|
|
TEST (T, nan, uppercase, 0, 3, ' ', "", "NAN");
|
|
TEST (T, nan, showpos | uppercase, 0, 3, ' ', "", "+NAN");
|
|
|
|
TEST (T, -nan, 0, 0, 3, ' ', "", "-nan");
|
|
TEST (T, -nan, showpos, 0, 3, ' ', "", "-nan");
|
|
TEST (T, -nan, uppercase, 0, 3, ' ', "", "-NAN");
|
|
TEST (T, -nan, showpos | uppercase, 0, 3, ' ', "", "-NAN");
|
|
|
|
TEST (T, nan, 0, 0, 4, ' ', "", " nan");
|
|
TEST (T, nan, showpos, 0, 4, ' ', "", "+nan");
|
|
TEST (T, nan, uppercase, 0, 4, ' ', "", " NAN");
|
|
TEST (T, nan, showpos | uppercase, 0, 4, ' ', "", "+NAN");
|
|
|
|
TEST (T, -nan, 0, 0, 4, ' ', "", "-nan");
|
|
TEST (T, -nan, showpos, 0, 4, ' ', "", "-nan");
|
|
TEST (T, -nan, uppercase, 0, 4, ' ', "", "-NAN");
|
|
TEST (T, -nan, showpos | uppercase, 0, 4, ' ', "", "-NAN");
|
|
|
|
TEST (T, nan, 0, 0, 5, ' ', "", " nan");
|
|
TEST (T, nan, showpos, 0, 5, ' ', "", " +nan");
|
|
TEST (T, nan, uppercase, 0, 5, ' ', "", " NAN");
|
|
TEST (T, nan, showpos | uppercase, 0, 5, ' ', "", " +NAN");
|
|
|
|
TEST (T, -nan, 0, 0, 5, ' ', "", " -nan");
|
|
TEST (T, -nan, showpos, 0, 5, ' ', "", " -nan");
|
|
TEST (T, -nan, uppercase, 0, 5, ' ', "", " -NAN");
|
|
TEST (T, -nan, showpos | uppercase, 0, 5, ' ', "", " -NAN");
|
|
|
|
TEST (T, nan, 0, 0, 8, ' ', "", " nan");
|
|
TEST (T, nan, showpos, 0, 8, ' ', "", " +nan");
|
|
TEST (T, nan, uppercase, 0, 8, ' ', "", " NAN");
|
|
TEST (T, nan, showpos | uppercase, 0, 8, ' ', "", " +NAN");
|
|
|
|
TEST (T, -nan, 0, 0, 8, ' ', "", " -nan");
|
|
TEST (T, -nan, showpos, 0, 8, ' ', "", " -nan");
|
|
TEST (T, -nan, uppercase, 0, 8, ' ', "", " -NAN");
|
|
TEST (T, -nan, showpos | uppercase, 0, 8, ' ', "", " -NAN");
|
|
|
|
TEST (T, nan, left, 0, 9, ' ', "", "nan ");
|
|
TEST (T, nan, left | showpos, 0, 9, ' ', "", "+nan ");
|
|
TEST (T, nan, left | uppercase, 0, 9, ' ', "", "NAN ");
|
|
TEST (T, nan, left | showpos | uppercase, 0, 9, ' ', "", "+NAN ");
|
|
|
|
TEST (T, -nan, left, 0, 9, ' ', "", "-nan ");
|
|
TEST (T, -nan, left | showpos, 0, 9, ' ', "", "-nan ");
|
|
TEST (T, -nan, left | uppercase, 0, 9, ' ', "", "-NAN ");
|
|
TEST (T, -nan, left | showpos | uppercase, 0, 9, ' ', "", "-NAN ");
|
|
|
|
TEST (T, nan, right, 0, 9, ' ', "", " nan");
|
|
TEST (T, nan, right | showpos, 0, 9, ' ', "", " +nan");
|
|
TEST (T, nan, right | uppercase, 0, 9, ' ', "", " NAN");
|
|
TEST (T, nan, right | showpos | uppercase, 0, 9, ' ', "", " +NAN");
|
|
|
|
TEST (T, -nan, right, 0, 9, ' ', "", " -nan");
|
|
TEST (T, -nan, right | showpos, 0, 9, ' ', "", " -nan");
|
|
TEST (T, -nan, right | uppercase, 0, 9, ' ', "", " -NAN");
|
|
TEST (T, -nan, right | showpos | uppercase, 0, 9, ' ', "", " -NAN");
|
|
|
|
#else
|
|
|
|
rw_info (0, 0, 0, "std::num_put<%s>::put (..., %s) formatting "
|
|
"NaN's disabled due to platform bugs", cname, tname);
|
|
|
|
#endif // 0/1
|
|
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
template <class charT>
|
|
void dbl_test (charT, const char *cname)
|
|
{
|
|
const char* const tname = "double";
|
|
|
|
rw_info (0, 0, 0, "std::num_put<%s>::put (..., %s)", cname, tname);
|
|
|
|
Punct<charT>::decimal_point_ = '.';
|
|
|
|
TEST (T, 0.0, 0, 0, 0, ' ', "", "%.0g");
|
|
TEST (T, -0.0, 0, 0, 0, ' ', "", "%.0g");
|
|
TEST (T, 1.0, 0, 0, 0, ' ', "", "%.0g");
|
|
TEST (T, 1.0, 0, 0, 0, ' ', "", "1");
|
|
TEST (T, -1.0, 0, 0, 0, ' ', "", "%.0g");
|
|
TEST (T, -1.0, 0, 0, 0, ' ', "", "-1");
|
|
TEST (T, 1.1, 0, 0, 0, ' ', "", "%.0g");
|
|
TEST (T, 1.1, 0, 0, 0, ' ', "", "1");
|
|
TEST (T, -1.1, 0, 0, 0, ' ', "", "%.0g");
|
|
TEST (T, -1.1, 0, 0, 0, ' ', "", "-1");
|
|
|
|
|
|
// exercise formatting of very large numbers in a fixed notation
|
|
// using '+' as the fill character to disable num_get tests
|
|
TEST (T, 1.0e+128, fixed, 0, 0, '+', "", "%.0f", Eof);
|
|
TEST (T, 1.0e+256, fixed, 0, 0, '+', "", "%.0f", Eof);
|
|
|
|
|
|
#undef CAT
|
|
#undef CONCAT
|
|
|
|
#define CAT(a, b) CONCAT (a, b)
|
|
#define CONCAT(a, b) a ## b
|
|
|
|
const double d = CAT (1.0e+, _RWSTD_DBL_MAX_10_EXP);
|
|
|
|
TEST (T, d, fixed, 0, 0, '+', "", "%.0f", Eof);
|
|
|
|
|
|
{
|
|
char stdiofmt [8];
|
|
const std::streamsize prec = std::streamsize (DBL_DIG + 3);
|
|
std::sprintf (stdiofmt, "%%.%dg", int (prec));
|
|
|
|
TEST (T, DBL_MIN, 0, prec, 0, ' ', "", stdiofmt);
|
|
TEST (T, DBL_MAX, 0, prec, 0, ' ', "", stdiofmt);
|
|
}
|
|
|
|
if (1) {
|
|
// verify that the global LC_NUMERIC setting has no impact on the facet
|
|
for (const char *name = rw_locales (LC_NUMERIC, 0); name && *name;
|
|
name += std::strlen (name) + 1) {
|
|
|
|
// find the first locale whose decimal_point character
|
|
// is different than in the classic C locale (i.e., than '.')
|
|
if (0 == std::setlocale (LC_NUMERIC, name))
|
|
continue;
|
|
|
|
const std::lconv* const conv = std::localeconv ();
|
|
|
|
if (!conv)
|
|
continue;
|
|
|
|
if (conv->decimal_point && '.' != *conv->decimal_point)
|
|
break;
|
|
}
|
|
|
|
Punct<charT>::decimal_point_ = '*';
|
|
Punct<charT>::thousands_sep_ = '/';
|
|
|
|
TEST (T, 12345.678900, fixed, 6, 0, ' ', "\000", "12345*678900");
|
|
TEST (T, 123456.78900, fixed, 5, 0, ' ', "\002", "12/34/56*78900");
|
|
TEST (T, 1234567.8900, fixed, 4, 0, ' ', "\003", "1/234/567*8900");
|
|
|
|
Punct<charT>::decimal_point_ = '.';
|
|
|
|
TEST (T, 12345678.900, fixed, 3, 0, ' ', "\004", "1234/5678.900");
|
|
|
|
// reset the global locale
|
|
std::setlocale (LC_NUMERIC, "C");
|
|
}
|
|
|
|
inf_nan_test (charT (), double (), cname, tname);
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
template <class charT>
|
|
void ldbl_test (charT, const char *cname)
|
|
{
|
|
#ifndef _RWSTD_NO_LONG_DOUBLE
|
|
|
|
const char* const tname = "long double";
|
|
|
|
rw_info (0, 0, 0, "std::num_put<%s>::put (..., %s) "
|
|
"[sizeof (long double) = %u]",
|
|
cname, tname, sizeof (long double));
|
|
|
|
typedef long double LDbl;
|
|
|
|
Punct<charT>::decimal_point_ = '.';
|
|
|
|
TEST (T, 0.0L, 0, 0, 0, ' ', "", "%.0Lg");
|
|
TEST (T, 1.0L, 0, 0, 0, ' ', "", "%.0Lg");
|
|
TEST (T, 2.1L, 0, 0, 0, ' ', "", "%.0Lg");
|
|
TEST (T, -3.2L, 0, 0, 0, ' ', "", "%.0Lg");
|
|
TEST (T, -4.3L, 0, 0, 0, ' ', "", "%.0Lg");
|
|
|
|
TEST (T, 1.0e+10L, 0, 0, 0, ' ', "", "%.0Lg");
|
|
TEST (T, 2.0e+20L, 0, 0, 0, ' ', "", "%.0Lg");
|
|
TEST (T, 4.0e+30L, 0, 0, 0, ' ', "", "%.0Lg");
|
|
|
|
TEST (T, 1.0e-10L, 0, 0, 0, ' ', "", "%.0Lg");
|
|
TEST (T, 2.0e-20L, 0, 0, 0, ' ', "", "%.0Lg");
|
|
TEST (T, 4.0e-30L, 0, 0, 0, ' ', "", "%.0Lg");
|
|
|
|
TEST (T, LDbl (CHAR_MAX), 0, 0, 0, ' ', "", "%.0Lg");
|
|
TEST (T, LDbl (UCHAR_MAX), 0, 0, 0, ' ', "", "%.0Lg");
|
|
TEST (T, LDbl (SCHAR_MAX), 0, 0, 0, ' ', "", "%.0Lg");
|
|
TEST (T, LDbl (SHRT_MAX), 0, 0, 0, ' ', "", "%.0Lg");
|
|
TEST (T, LDbl (USHRT_MAX), 0, 0, 0, ' ', "", "%.0Lg");
|
|
|
|
// specify greater precision than the default 6 for large numbers
|
|
TEST (T, LDbl (INT_MAX), 0, 32, 0, ' ', "", "%.32Lg");
|
|
TEST (T, LDbl (UINT_MAX), 0, 32, 0, ' ', "", "%.32Lg");
|
|
|
|
TEST (T, LDbl (LONG_MAX), 0, 32, 0, ' ', "", "%.32Lg");
|
|
TEST (T, LDbl (ULONG_MAX), 0, 32, 0, ' ', "", "%.32Lg");
|
|
|
|
TEST (T, LDbl (FLT_MIN), 0, 32, 0, ' ', "", "%.32Lg");
|
|
TEST (T, LDbl (FLT_MAX), 0, 32, 0, ' ', "", "%.32Lg");
|
|
TEST (T, LDbl (DBL_MIN), 0, 32, 0, ' ', "", "%.32Lg");
|
|
TEST (T, LDbl (DBL_MAX), 0, 32, 0, ' ', "", "%.32Lg");
|
|
|
|
{
|
|
char stdiofmt [8];
|
|
const std::streamsize prec = std::streamsize (LDBL_DIG + 3);
|
|
std::sprintf (stdiofmt, "%%.%d" _RWSTD_LDBL_PRINTF_PREFIX "g",
|
|
int (prec));
|
|
|
|
TEST (T, LDbl (LDBL_MIN), 0, prec, 0, ' ', "", stdiofmt);
|
|
TEST (T, LDbl (LDBL_MAX), 0, prec, 0, ' ', "", stdiofmt);
|
|
}
|
|
|
|
const long double Pi = 3.14159265358979323846L;
|
|
|
|
// some test cases below that use precision in conjuction with
|
|
// scientific in the libc format specifier in order to exercise
|
|
// the proposed resolution of lwg issue 231
|
|
TEST (T, Pi, 0, 32, 0, ' ', "", "%.32Lg");
|
|
TEST (T, Pi, fixed, 0, 0, ' ', "", "%.0Lf", Eof, 3.0L);
|
|
TEST (T, Pi, scientific, 0, 0, ' ', "", "%.0Le", Eof, 3.0L);
|
|
TEST (T, Pi, fixed, 0, 0, ' ', "", "3", Eof, 3.0L);
|
|
TEST (T, Pi, scientific, 0, 0, ' ', "", "3e+00", Eof, 3.0L);
|
|
|
|
TEST (T, Pi, uppercase, 32, 0, ' ', "", "%.32LG");
|
|
TEST (T, Pi, uppercase | fixed, 0, 0, ' ', "", "%.0Lf", Eof, 3.0L);
|
|
TEST (T, Pi, uppercase | scientific, 0, 0, ' ', "", "%.0LE", Eof, 3.0L);
|
|
TEST (T, Pi, uppercase | scientific, 0, 0, ' ', "", "3E+00", Eof, 3.0L);
|
|
|
|
#define Showpos(f) (showpos | f)
|
|
|
|
TEST (T, Pi, Showpos (0), 32, 0, ' ', "", "%+.32Lg");
|
|
TEST (T, Pi, Showpos (fixed), 0, 0, ' ', "", "%+.0Lf", Eof, 3.0L);
|
|
TEST (T, Pi, Showpos (scientific), 0, 0, ' ', "", "%+.0Le", Eof, 3.0L);
|
|
TEST (T, Pi, Showpos (fixed), 0, 0, ' ', "", "+3", Eof, 3.0L);
|
|
TEST (T, Pi, Showpos (scientific), 0, 0, ' ', "", "+3e+00", Eof, 3.0L);
|
|
|
|
#define SHOWPOS(f) (showpos | uppercase | f)
|
|
|
|
TEST (T, Pi, SHOWPOS (0), 32, 0, ' ', "", "%+.32LG");
|
|
TEST (T, Pi, SHOWPOS (fixed), 0, 0, ' ', "", "%+.0Lf", Eof, 3.0L);
|
|
TEST (T, Pi, SHOWPOS (scientific), 0, 0, ' ', "", "%+.0LE", Eof, 3.0L);
|
|
TEST (T, Pi, SHOWPOS (fixed), 0, 0, ' ', "", "+3", Eof, 3.0L);
|
|
TEST (T, Pi, SHOWPOS (scientific), 0, 0, ' ', "", "+3E+00", Eof, 3.0L);
|
|
|
|
#define Showpoint(f) (showpoint | f)
|
|
|
|
TEST (T, Pi, Showpoint (0), 32, 0, ' ', "", "%#.32Lg");
|
|
TEST (T, Pi, Showpoint (fixed), 0, 0, ' ', "", "%#.0Lf", Eof, 3.0L);
|
|
TEST (T, Pi, Showpoint (scientific), 0, 0, ' ', "", "%#.0Le", Eof, 3.0L);
|
|
TEST (T, Pi, Showpoint (fixed), 0, 0, ' ', "", "3.", Eof, 3.0L);
|
|
TEST (T, Pi, Showpoint (scientific), 0, 0, ' ', "", "3.e+00", Eof, 3.0L);
|
|
|
|
#define SHOWPOINT(f) (showpoint | uppercase | f)
|
|
|
|
TEST (T, Pi, SHOWPOINT (0), 32, 0, ' ', "", "%#.32LG");
|
|
TEST (T, Pi, SHOWPOINT (fixed), 0, 0, ' ', "", "%#.0Lf", Eof, 3.0L);
|
|
TEST (T, Pi, SHOWPOINT (scientific), 0, 0, ' ', "", "%#.0LE", Eof, 3.0L);
|
|
TEST (T, Pi, SHOWPOINT (scientific), 0, 0, ' ', "", "3.E+00", Eof, 3.0L);
|
|
|
|
#define Showall(f) (showpoint | showpos | f)
|
|
|
|
TEST (T, Pi, Showall (0), 32, 0, ' ', "", "%#+.32Lg");
|
|
TEST (T, Pi, Showall (fixed), 0, 0, ' ', "", "%#+.0Lf", Eof, 3.0L);
|
|
TEST (T, Pi, Showall (scientific), 0, 0, ' ', "", "%#+.0Le", Eof, 3.0L);
|
|
TEST (T, Pi, Showall (fixed), 0, 0, ' ', "", "+3.", Eof, 3.0L);
|
|
TEST (T, Pi, Showall (scientific), 0, 0, ' ', "", "+3.e+00", Eof, 3.0L);
|
|
|
|
#define SHOWALL(f) (showpoint | showpos | uppercase | f)
|
|
|
|
TEST (T, Pi, SHOWALL (0), 32, 0, ' ', "", "%#+.32LG");
|
|
TEST (T, Pi, SHOWALL (fixed), 0, 0, ' ', "", "%#+.0Lf", Eof, 3.0L);
|
|
TEST (T, Pi, SHOWALL (scientific), 0, 0, ' ', "", "%#+.0LE", Eof, 3.0L);
|
|
TEST (T, Pi, SHOWALL (scientific), 0, 0, ' ', "", "+3.E+00", Eof, 3.0L);
|
|
|
|
// with {g,G}, precision indicates the number of significant digits
|
|
// the precision == 0 should have the same effect as precision == 1
|
|
TEST (T, Pi, 0, 0, 0, ' ', "", "%.0Lg", Eof, 3.0L);
|
|
TEST (T, Pi, 0, 1, 0, ' ', "", "%.1Lg", Eof, 3.0L);
|
|
TEST (T, Pi, 0, 2, 0, ' ', "", "%.2Lg", Eof, 3.1L);
|
|
TEST (T, Pi, 0, 3, 0, ' ', "", "%.3Lg", Eof, 3.14L);
|
|
TEST (T, Pi, 0, 10, 0, ' ', "", "%.10Lg", Eof, 3.141592654L);
|
|
|
|
// C89 and C99 both specify that (only if specified using the asterisk)
|
|
// negative precision is treated the same as no precision at all; verify
|
|
// that num_put handles negative precision gracefully (i.e., ignores it)
|
|
TEST (T, Pi, 0, -1, 0, ' ', "", "%Lg");
|
|
TEST (T, Pi, 0, -9, 0, ' ', "", "%Lg");
|
|
|
|
// with {e,E,f,F}, precision indicates the number of fractional digits
|
|
TEST (T, Pi, fixed, 1, 0, ' ', "", "%.1Lf", Eof, 3.1L);
|
|
TEST (T, Pi, fixed, 2, 0, ' ', "", "%.2Lf", Eof, 3.14L);
|
|
TEST (T, Pi, fixed, 3, 0, ' ', "", "%.3Lf", Eof, 3.142L);
|
|
TEST (T, Pi, fixed, 10, 0, ' ', "", "%.10Lf", Eof, 3.1415926536L);
|
|
|
|
|
|
// exercise formatting of very large numbers in a fixed notation
|
|
// using '-' as the fill character to disable num_get tests
|
|
TEST (T, 2.0e+128L, fixed, 0, 0, '-', "", "%.0Lf", Eof);
|
|
TEST (T, 3.0e+256L, fixed, 0, 0, '-', "", "%.0Lf", Eof);
|
|
TEST (T, 4.0e+300L, fixed, 0, 0, '-', "", "%.0Lf", Eof);
|
|
|
|
// extension: fixed format and negative precision
|
|
TEST (T, Pi, fixed, -2, 0, ' ', "", "0.03");
|
|
TEST (T, Pi, fixed, -8, 0, ' ', "", "0.00000003");
|
|
|
|
#undef CAT
|
|
#undef CONCAT
|
|
|
|
#define CAT(a, b) CONCAT (a, b)
|
|
#define CONCAT(a, b) a ## b
|
|
|
|
const long double ld = CAT (CAT (1.0e+, _RWSTD_LDBL_MAX_10_EXP), L);
|
|
|
|
TEST (T, ld, fixed, 0, 0, '-', "", "%.0Lf", Eof);
|
|
|
|
TEST (T, Pi, scientific, 2, 0, ' ', "", "%.2Le", Eof, 3.14L);
|
|
TEST (T, Pi, scientific, 4, 0, ' ', "", "%.4Le", Eof, 3.1416L);
|
|
TEST (T, Pi, scientific, 6, 0, ' ', "", "%.6Le", Eof, 3.141593L);
|
|
TEST (T, Pi, scientific, 12, 0, ' ', "", "%.12Le", Eof, 3.14159265359L);
|
|
TEST (T, Pi, scientific, -3, 0, ' ', "", "%Le");
|
|
TEST (T, Pi, scientific, -7, 0, ' ', "", "%Le");
|
|
|
|
inf_nan_test (charT (), (long double)0, cname, tname);
|
|
|
|
#endif // _RWSTD_NO_LONG_DOUBLE
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
|
|
template <class charT>
|
|
void pvoid_test (charT, const char *cname)
|
|
{
|
|
const char* const tname = "const void*";
|
|
|
|
rw_info (0, 0, 0, "std::num_put<%s>::put (..., %s)", cname, tname);
|
|
|
|
typedef void* PVoid;
|
|
|
|
int foo = 0;
|
|
int bar = 0;
|
|
|
|
// use "0" rather than "%p" for null pointers to avoid
|
|
// having to deal with GNU libc's "(nil)" format
|
|
TEST (T, PVoid ( 0), 0, 0, 0, ' ', "", "0");
|
|
TEST (T, PVoid ( 1), 0, 0, 0, ' ', "", "%p");
|
|
TEST (T, PVoid ( &foo), 0, 0, 0, ' ', "", "%p");
|
|
TEST (T, PVoid ( &bar), 0, 0, 0, ' ', "", "%p");
|
|
TEST (T, PVoid ( ~0L), 0, 0, 0, ' ', "", "%p");
|
|
|
|
// 22.2.2.2.2, p16 and lwg issue 282: grouping and thousands_sep
|
|
// is only used in arithmetic types
|
|
TEST (T, PVoid ( 0), 0, 0, 0, ' ', "\1", "0");
|
|
TEST (T, PVoid ( 1), 0, 0, 0, ' ', "\1", "%p");
|
|
TEST (T, PVoid ( &foo), 0, 0, 0, ' ', "\1\1", "%p");
|
|
TEST (T, PVoid ( &bar), 0, 0, 0, ' ', "\1\2", "%p");
|
|
TEST (T, PVoid ( ~0L), 0, 0, 0, ' ', "\1\3", "%p");
|
|
|
|
TEST (T, PVoid ( SHRT_MAX), 0, 0, 0, ' ', "", "%p");
|
|
TEST (T, PVoid ( SHRT_MIN), 0, 0, 0, ' ', "", "%p");
|
|
TEST (T, PVoid (USHRT_MAX), 0, 0, 0, ' ', "", "%p");
|
|
TEST (T, PVoid ( INT_MAX), 0, 0, 0, ' ', "", "%p");
|
|
TEST (T, PVoid ( INT_MIN), 0, 0, 0, ' ', "", "%p");
|
|
TEST (T, PVoid ( UINT_MAX), 0, 0, 0, ' ', "", "%p");
|
|
TEST (T, PVoid ( LONG_MAX), 0, 0, 0, ' ', "", "%p");
|
|
TEST (T, PVoid ( LONG_MIN), 0, 0, 0, ' ', "", "%p");
|
|
TEST (T, PVoid (ULONG_MAX), 0, 0, 0, ' ', "", "%p");
|
|
|
|
#ifdef _RWSTD_LLONG_MAX
|
|
# if _RWSTD_LLONG_SIZE <= _RWSTD_PTR_SIZE
|
|
|
|
TEST (T, PVoid (_RWSTD_LLONG_MAX), 0, 0, 0, ' ', "", "%p");
|
|
TEST (T, PVoid (_RWSTD_ULLONG_MAX), 0, 0, 0, ' ', "", "%p");
|
|
|
|
# endif // LLONG_MAX
|
|
#endif // _RWSTD_LLONG_MAX
|
|
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
|
|
template <class charT>
|
|
void errno_test (charT, const char *cname)
|
|
{
|
|
const char* const tname = "long";
|
|
|
|
rw_info (0, 0, 0,
|
|
"std::num_put<%s>::put (..., %s) and errno", cname, tname);
|
|
|
|
// verify that errno doesn't change after, or adversely affect
|
|
// successful insertion; and that the insertion doesn't change
|
|
// the value of errno
|
|
|
|
errno = -1;
|
|
TEST (T, 12345L, 0, 0, 0, ' ', "", "12345");
|
|
rw_assert (-1 == errno, 0, __LINE__,
|
|
"errno unexpectedly changed from %d to %{#m} (%m)", -1);
|
|
|
|
errno = 0;
|
|
TEST (T, 12346L, 0, 0, 0, ' ', "", "12346");
|
|
rw_assert (0 == errno, 0, __LINE__,
|
|
"errno unexpectedly changed from %d to %{#m} (%m)", -0);
|
|
|
|
errno = 1;
|
|
TEST (T, 12347L, 0, 0, 0, ' ', "", "12347");
|
|
rw_assert (1 == errno, 0, __LINE__,
|
|
"errno unexpectedly changed from %d to %{#m} (%m)", 1);
|
|
|
|
errno = 2;
|
|
TEST (T, 12348L, 0, 0, 0, ' ', "", "12348");
|
|
rw_assert (2 == errno, 0, __LINE__,
|
|
"errno unexpectedly changed from %d to %{#m} (%m)", 2);
|
|
|
|
errno = 3;
|
|
TEST (T, 12349L, 0, 0, 0, ' ', "", "12349");
|
|
rw_assert (3 == errno, 0, __LINE__,
|
|
"errno unexpectedly changed from %d to %{#m} (%m)", 3);
|
|
|
|
errno = 4;
|
|
TEST (T, 12350L, 0, 0, 0, ' ', "", "12350");
|
|
rw_assert (4 == errno, 0, __LINE__,
|
|
"errno unexpectedly changed from %d to %{#m} (%m)", 4);
|
|
|
|
errno = ERANGE;
|
|
TEST (T, 12351L, 0, 0, 0, ' ', "", "12351");
|
|
rw_assert (ERANGE == errno, 0, __LINE__,
|
|
"errno unexpectedly changed from %{#m} to %{#m} (%m)", ERANGE);
|
|
|
|
errno = Bad;
|
|
TEST (T, 12352L, 0, 0, 0, ' ', "", "12352");
|
|
rw_assert (Bad == errno, 0, __LINE__,
|
|
"errno unexpectedly changed from %d to %{#m} (%m)", Bad);
|
|
|
|
errno = Eof;
|
|
TEST (T, 12353L, 0, 0, 0, ' ', "", "12353");
|
|
rw_assert (Eof == errno, 0, __LINE__,
|
|
"errno unexpectedly changed from %d to %{#m} (%m)", Eof);
|
|
|
|
errno = Fail;
|
|
TEST (T, 12354L, 0, 0, 0, ' ', "", "12354");
|
|
rw_assert (Fail == errno, 0, __LINE__,
|
|
"errno unexpectedly changed from %d to %{#m} (%m)", Fail);
|
|
|
|
errno = 0;
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
|
|
// verify that std::ctype<>::widen() is called at least once
|
|
// for every distinct narow character (not for fill characters)
|
|
// note that an implementation is allowed to cache the results
|
|
// of facet virtual functions() called with the same arguments
|
|
// (including the implicit this pointer), so the numbers here
|
|
// are minimum required values but not exact or maximums
|
|
void widen_test ()
|
|
{
|
|
rw_info (0, 0, 0,
|
|
"std::num_put<char>::put (..., long) calls ctype<char>::widen()");
|
|
|
|
static const struct {
|
|
long val;
|
|
std::streamsize width;
|
|
int flags;
|
|
int n_widen;
|
|
const char *str;
|
|
} data[] = {
|
|
{ 0, 0, 0, 1, "9" },
|
|
{ 1, 0, 0, 1, "8" },
|
|
{ 11, 0, 0, 1, "88" },
|
|
{ 12, 0, 0, 2, "87" },
|
|
{ 123, 0, 0, 3, "876" },
|
|
{ 111, 0, 0, 1, "888" },
|
|
{ -1234, 0, 0, 5, "-8765" },
|
|
{ 12121, 0, 0, 2, "87878" },
|
|
{ 12345, 0, showpos, 6, "+87654" },
|
|
{ 0123456, 0, oct | showbase, 7, "9876543" },
|
|
{ 0x234567, 0, hex | showbase, 8, "9x765432" },
|
|
{ 0x2345678, 10, hex | showbase, 9, " 9x7654321" },
|
|
{ 9, 5, showpos | internal, 2, "+ 0" }
|
|
};
|
|
|
|
for (unsigned i = 0; i != sizeof data / sizeof *data; ++i) {
|
|
|
|
const Ctype<char> ctp;
|
|
|
|
// construct and initialize a basic_ios-derived object
|
|
Ios<char> ios;
|
|
|
|
// construct a num_put-derived facet to exercise
|
|
const NumPut<char> np;
|
|
|
|
// imbue a stream object with a custom locale
|
|
// containing the replacement ctype facet
|
|
ios.imbue (std::locale (ios.getloc (), (const std::ctype<char>*)&ctp));
|
|
|
|
ios.flags (std::ios_base::fmtflags (data [i].flags));
|
|
ios.width (data [i].width);
|
|
|
|
char buf [40];
|
|
|
|
// reset function call counter
|
|
Ctype<char>::n_widen_ = 0;
|
|
|
|
*np.put (buf, ios, ' ', data [i].val) = '\0';
|
|
|
|
rw_assert (data [i].n_widen <= Ctype<char>::n_widen_, 0, __LINE__,
|
|
"%d. num_put<char>::do_put (..., %d) called "
|
|
"ctype<char>::do_widen() %d times, %d expected; "
|
|
"flags = %{If}, width = %d", i, data [i].val,
|
|
Ctype<char>::n_widen_, data [i].n_widen,
|
|
data [i].flags, data [i].width);
|
|
|
|
rw_assert (0 == rw_strncmp (buf, data [i].str), 0, __LINE__,
|
|
"%d. num_put<char>::do_put (..., %d) produced %s, "
|
|
"expected \"%{#*s}\"; "
|
|
"flags = %{If}, width = %d",
|
|
i, data [i].val, buf,
|
|
int (sizeof data [i].str [0]), data [i].str,
|
|
data [i].flags, data [i].width);
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
|
|
// verify that std::numpunct<>::grouping() is called and used correctly
|
|
void grouping_test ()
|
|
{
|
|
// construct a "replacement" numpunct-derived facet
|
|
const Punct<char> pun (1);
|
|
|
|
// construct and initialize a basic_ios-derived object
|
|
Ios<char> ios;
|
|
|
|
// construct a num_put-derived facet to exercise
|
|
const NumPut<char> np;
|
|
|
|
// imbue a stream object with a custom locale
|
|
// containing the replacement punctuation facet
|
|
ios.imbue (std::locale (ios.getloc (), (const std::numpunct<char>*)&pun));
|
|
|
|
rw_assert (1 == Punct<char>::n_objs_, 0, __LINE__,
|
|
"%d facets exist, 1 expected", Punct<char>::n_objs_);
|
|
|
|
// decimal output, no special formatting
|
|
ios.setf (std::ios::fmtflags ());
|
|
|
|
char buf [40];
|
|
|
|
// group after every digit
|
|
Punct<char>::grouping_ = "\1";
|
|
|
|
// reset the do_thousands_sep()-call counter
|
|
Punct<char>::n_thousands_sep_ = 0;
|
|
|
|
*np.put (buf, ios, '\0', 123456789L) = '\0';
|
|
|
|
// verify that the number was formatted correctly
|
|
rw_assert (0 == std::strcmp (buf, "1,2,3,4,5,6,7,8,9"), 0, __LINE__,
|
|
"num_put<char>::do_put (..., 123456789) produced \"%s\", "
|
|
"expected \"%s\"", buf, "1,2,3,4,5,6,7,8,9");
|
|
|
|
// verify that do_thousands_sep() was called at least once
|
|
rw_assert (0 < Punct<char>::n_thousands_sep_, 0, __LINE__,
|
|
"num_put<char>::do_put (..., 123456789) failed to call "
|
|
"numpunct<char>::do_thousands_sep()");
|
|
|
|
// repeat test to verify that distinct instances
|
|
// of the same facet do not cache each other's data
|
|
{
|
|
// nested scope works around a SunPro bug (PR #27543)
|
|
ios.imbue (std::locale (ios.getloc (),
|
|
(const std::numpunct<char>*)new Punct<char>(0)));
|
|
}
|
|
|
|
rw_assert (2 == Punct<char>::n_objs_, 0, __LINE__,
|
|
"%d facets exist, 2 expected", Punct<char>::n_objs_);
|
|
|
|
// now group after every other digit
|
|
Punct<char>::grouping_ = "\2";
|
|
|
|
// reset the do_thousands_sep()-call counter
|
|
Punct<char>::n_thousands_sep_ = 0;
|
|
|
|
*np.put (buf, ios, '\0', 123456790L) = '\0';
|
|
|
|
// again verify that the number was formatted correctly
|
|
rw_assert (0 == std::strcmp (buf, "1,23,45,67,90"), 0, __LINE__,
|
|
"num_put<char>::do_put (..., 123456790) produced \"%s\", "
|
|
"expected \"%s\"", buf, "1,23,45,67,90");
|
|
|
|
// verify that do_thousands_sep() was called at least once
|
|
// (i.e., that there is no unwarranted caching going on)
|
|
rw_assert (0 < Punct<char>::n_thousands_sep_, 0, __LINE__,
|
|
"num_put<char>::do_put (..., 123456790) failed to call "
|
|
"numpunct<char>::do_thousands_sep()");
|
|
|
|
// replace imbued locale with a copy of the classic locale
|
|
// and remove the previously installed locale containing
|
|
// the user-defined facet; this must destroy the dynamically
|
|
// created facet leaving only the local facet on the stack
|
|
{
|
|
// nested scope works around a SunPro bug (PR #27543)
|
|
ios.imbue (std::locale::classic ());
|
|
}
|
|
|
|
rw_assert (1 == Punct<char>::n_objs_, 0, __LINE__,
|
|
"%d facets exist, 1 expected", Punct<char>::n_objs_);
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
template <class charT>
|
|
void numput_virtuals_test (charT, const char *cname)
|
|
{
|
|
const NumPut<charT> put (1);
|
|
const std::num_put<charT, charT*> &np = put;
|
|
|
|
Ios<charT> ios;
|
|
|
|
ios.flags (std::ios_base::fmtflags ());
|
|
|
|
#define Abs(i) ((i) < 0 ? (-i) : (i))
|
|
|
|
#define ASSERT(T, N, T2, tname, t2name) \
|
|
do { \
|
|
/* number of expected calls to the do_put() member */ \
|
|
const int expect = N + put.ncalls_ [put.test_ ## T]; \
|
|
const int expect_2 = !N + put.ncalls_ [put.test_ ## T2]; \
|
|
charT buf [80]; \
|
|
const charT* const end = np.put (buf, ios, charT (), (T)0); \
|
|
rw_assert (end == buf + 1, 0, __LINE__, \
|
|
"line %d: num_put<%s>::put (..., %s = 0) " \
|
|
"return value", __LINE__, cname, tname); \
|
|
const int ncalls = put.ncalls_ [put.test_ ## T]; \
|
|
const int ncalls_2 = put.ncalls_ [put.test_ ## T2]; \
|
|
rw_assert (expect == ncalls, 0, __LINE__, \
|
|
"line %d: num_put<%s>::put (..., %s) called " \
|
|
"do_put(..., %s) %d times, expected %d", \
|
|
__LINE__, cname, tname, \
|
|
tname, Abs (ncalls - expect - N), N); \
|
|
/* make sure extensions, if any, are implemented in */ \
|
|
/* terms of and call the standard virtual functions */ \
|
|
/* bogus addressof operator prevents warnings about */ \
|
|
/* unreachable code when T is the same as T2 */ \
|
|
if (put.test_ ## T != put.test_ ## T2) \
|
|
rw_assert (expect_2 == ncalls_2, 0, __LINE__, \
|
|
"line %d: num_put<%s>::put (..., %s) called " \
|
|
"do_put(..., %s) %d times, expected %d", \
|
|
__LINE__, cname, tname, \
|
|
t2name, Abs (expect_2 - ncalls_2 - !N), !N); \
|
|
} while (0)
|
|
|
|
typedef unsigned short ushort;
|
|
typedef unsigned int uint;
|
|
typedef unsigned long ulong;
|
|
|
|
// verify that each public member function calls each corresponding
|
|
// implementation do_xxx() member functions exactly once
|
|
|
|
// in the case of extensions, verify that each extended public member
|
|
// function calls the appropriate implementation standard do_xxx()
|
|
// member function
|
|
|
|
#ifndef _RWSTD_NO_BOOL
|
|
ASSERT (bool, 1, bool, "bool", "bool");
|
|
#endif // _RWSTD_NO_BOOL
|
|
|
|
ASSERT (long, 1, long, "long", "long");
|
|
ASSERT (ulong, 1, ulong, "unsigned long", "unsigned long");
|
|
|
|
#if defined (_RWSTD_LONG_LONG) && !defined (_RWSTD_NO_EXT_NUM_PUT)
|
|
|
|
typedef _RWSTD_LONG_LONG llong;
|
|
typedef unsigned _RWSTD_LONG_LONG ullong;
|
|
|
|
ASSERT (llong, 1, llong, "long long", "long long");
|
|
ASSERT (ullong, 1, ullong, "unsigned long long", "unsigned long long");
|
|
|
|
#endif // _RWSTD_LONG_LONG && !_RWSTD_NO_EXT_NUM_PUT
|
|
|
|
ASSERT (double, 1, double, "double", "double");
|
|
|
|
#ifndef _RWSTD_NO_LONG_DOUBLE
|
|
|
|
typedef long double ldouble;
|
|
|
|
ASSERT (ldouble, 1, ldouble, "long double", "long double");
|
|
|
|
#endif // _RWSTD_NO_LONG_DOUBLE
|
|
|
|
typedef const void* pvoid;
|
|
ASSERT (pvoid, 1, pvoid, "const void*", "const void*");
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
template <class charT>
|
|
void run_tests (charT, const char *cname)
|
|
{
|
|
numput_virtuals_test (charT (), cname);
|
|
|
|
direct_use_test (charT (), cname);
|
|
|
|
#undef TEST
|
|
#define TEST(T, tname) \
|
|
if (rw_enabled (#T)) \
|
|
T ## _test (charT (), cname); \
|
|
else \
|
|
rw_note (0, __FILE__, __LINE__, "%s test disabled", \
|
|
tname && *tname ? tname : #T)
|
|
|
|
#ifndef _RWSTD_NO_BOOL
|
|
|
|
TEST (bool, "");
|
|
|
|
#endif // _RWSTD_NO_BOOL
|
|
|
|
|
|
// NOTE: there is no num_put::put(..., short)
|
|
// TEST (shrt, "short");
|
|
// TEST (ushrt, "unsigned short");
|
|
|
|
// NOTE: there is no num_put::put(..., int)
|
|
// TEST (int, "");
|
|
// TEST (uint, "unsigned int");
|
|
|
|
TEST (long, "");
|
|
TEST (ulong, "unsigned long");
|
|
|
|
#ifndef _RWSTD_NO_LONG_LONG
|
|
|
|
TEST (llong, "long long");
|
|
TEST (ullong, "unsigned long long");
|
|
|
|
#endif // _RWSTD_NO_LONG_LONG
|
|
|
|
// NOTE: there is no num_put::put(..., float)
|
|
// TEST (flt, "float");
|
|
|
|
TEST (dbl, "dbouble");
|
|
|
|
#ifndef _RWSTD_NO_LONG_DOUBLE
|
|
|
|
TEST (ldbl, "long double");
|
|
|
|
#endif // _RWSTD_NO_LONG_DOUBLE
|
|
|
|
TEST (pvoid, "void*");
|
|
|
|
if (rw_opt_no_errno)
|
|
rw_note (0, __FILE__, __LINE__, "errno test disabled");
|
|
else
|
|
errno_test (charT (), cname);
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
static int
|
|
run_test (int, char*[])
|
|
{
|
|
if (rw_opt_no_widen) {
|
|
rw_note (0, 0, 0, "widen test disabled");
|
|
}
|
|
else {
|
|
widen_test ();
|
|
}
|
|
|
|
if (rw_opt_no_grouping) {
|
|
rw_note (0, 0, 0, "grouping test disabled");
|
|
}
|
|
else {
|
|
grouping_test ();
|
|
}
|
|
|
|
if (rw_enabled ("char"))
|
|
run_tests (char (), "char");
|
|
else
|
|
rw_note (0, __FILE__, __LINE__, "char test disabled");
|
|
|
|
#ifndef _RWSTD_NO_WCHAR_T
|
|
|
|
if (rw_enabled ("wchar_t"))
|
|
run_tests (wchar_t (), "wchar_t");
|
|
else
|
|
rw_note (0, __FILE__, __LINE__, "wchar_t test disabled");
|
|
|
|
#endif // _RWSTD_NO_WCHAR_T
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
int main (int argc, char *argv[])
|
|
{
|
|
return rw_test (argc, argv, __FILE__,
|
|
"lib.locale.num.put",
|
|
0 /* no comment */, run_test,
|
|
"|-enable-num_get# "
|
|
"|-no-errno# "
|
|
"|-no-grouping# "
|
|
"|-no-widen# ",
|
|
&rw_opt_enable_num_get,
|
|
&rw_opt_no_errno,
|
|
&rw_opt_no_grouping,
|
|
&rw_opt_no_widen);
|
|
}
|