stdcxx-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From se...@apache.org
Subject svn commit: r386909 - /incubator/stdcxx/trunk/tests/localization/22.locale.num.get.cpp
Date Sun, 19 Mar 2006 02:09:51 GMT
Author: sebor
Date: Sat Mar 18 18:09:49 2006
New Revision: 386909

URL: http://svn.apache.org/viewcvs?rev=386909&view=rev
Log:
2006-03-18  Martin Sebor  <sebor@roguewave.com>

	* 22.locale.num.get.cpp (<cstddef>): Removed an unnecessary #include
	directive.
	(PunctData): New base class of the Punct<charT> template to reduce
	code bloat.
	(Punct): Derived from PunctData and simplified.
	(Streambuf): New class template.
	(Ios, NumGet): Added a template parameter.
	(do_test): Exercised std::num_get specializations on istreambuf_iterator
	and user-defined InputIterator type in addition to character pointer.
	(do_test): New helper to dispatch to the appropriate specialization of
	the main do_test function.
	(test_errno, test_bool, test_shrt, ...): Removed the charT template
	parameter to reduce code bloat.
	(test_llong, test_ullong): Guarded with _RWSTD_NO_LONG_LONG.
	(run_tests): New dispatch function on iterator type.

Modified:
    incubator/stdcxx/trunk/tests/localization/22.locale.num.get.cpp

Modified: incubator/stdcxx/trunk/tests/localization/22.locale.num.get.cpp
URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/localization/22.locale.num.get.cpp?rev=386909&r1=386908&r2=386909&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/localization/22.locale.num.get.cpp (original)
+++ incubator/stdcxx/trunk/tests/localization/22.locale.num.get.cpp Sat Mar 18 18:09:49 2006
@@ -55,21 +55,22 @@
 
 /**************************************************************************/
 
-#include <cfloat>
-#include <climits>   // XXX_MAX, XXX_MIN
+#include <cfloat>    // FLT_MAX, FLT_MIN, etc.
+#include <climits>   // INT_MAX, INT_MIN, etc.
 #include <clocale>   // for localeconv(), setlocale()
 #include <cstdio>    // for sprintf(), sscanf()
 #include <cstring>   // for memset(), strerror(), strlen()
-#include <cstddef>
 #include <cerrno>    // for ERANGE, errno
 
 #include <ios>
 #include <limits>
 #include <locale>
 
+#include <alg_test.h>    // for InputIter
 #include <any.h>         // for rw_any_t
 #include <cmdopt.h>      // for rw_enabled()
 #include <driver.h>      // for rw_test(), ...
+#include <rw_char.h>     // for rw_widen()
 #include <rw_locale.h>   // for rw_locales()
 #include <valcmp.h>      // for rw_equal()
 
@@ -128,23 +129,44 @@
 
 /**************************************************************************/
 
-// replacement numpunct facet
+struct PunctData
+{
+    static       char  decimal_point_;
+    static       char  thousands_sep_;
+    static const char* grouping_;
+    static const char* falsename_;
+    static const char* truename_;
+
+    // number of facet objects in existence
+    static int n_objs_;
+
+    // number of calls to do_thousands_sep()
+    static int n_thousands_sep_;
+
+    static void set_names (const char *fname, const char *tname) {
+        falsename_ = fname;
+        truename_  = tname;
+    }
+};
 
+char        PunctData::decimal_point_    = '.';
+char        PunctData::thousands_sep_    = ',';
+const char* PunctData::grouping_  = "";
+const char* PunctData::falsename_ = 0;
+const char* PunctData::truename_  = 0;
+
+int         PunctData::n_thousands_sep_;
+int         PunctData::n_objs_;
+
+
+// replacement numpunct facet
 template <class charT>
-struct Punct: std::numpunct<charT>
+struct Punct: PunctData, std::numpunct<charT>
 {
+    typedef unsigned char                              UChar;
     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_;
@@ -155,7 +177,7 @@
     }
 
     virtual char_type do_decimal_point () const {
-        return decimal_point_;
+        return char_type (UChar (decimal_point_));
     }
 
     virtual std::string do_grouping () const {
@@ -164,60 +186,53 @@
 
     virtual char_type do_thousands_sep () const {
         ++n_thousands_sep_;
-        return thousands_sep_;
+        return char_type (UChar (thousands_sep_));
     }
 
     virtual string_type do_truename () const {
-        return truename_ ? string_type (truename_) : string_type ();
+        char_type name [40];
+        return rw_widen (name, truename_, sizeof name / sizeof *name);
     }
 
     virtual string_type do_falsename () const {
-        return falsename_ ? string_type (falsename_) : string_type ();
+        char_type name [40];
+        return rw_widen (name, falsename_, sizeof name / sizeof *name);
     }
 };
 
-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>
+template <class charT, class Traits>
+struct Ios: std::basic_ios<charT, Traits>
 {
     Ios () { this->init (0); }
 };
 
+template <class charT, class Traits>
+struct Streambuf: std::basic_streambuf<charT, Traits>
+{
+    typedef std::basic_streambuf<charT, Traits> Base;
 
-template <class charT>
-struct NumGet: std::num_get<charT, const charT*>
+    Streambuf (const charT *gbeg, const charT *gend)
+        : Base () {
+        this->setg (_RWSTD_CONST_CAST (charT*, gbeg),
+                    _RWSTD_CONST_CAST (charT*, gbeg),
+                    _RWSTD_CONST_CAST (charT*, gend));
+    }
+
+    int gptr_off () const {
+        return this->gptr () - this->eback ();
+    }
+};
+
+template <class charT, class InputIterator>
+struct NumGet: std::num_get<charT, InputIterator>
 {
     NumGet () { /* working around a bug in older versions of EDG eccp */ }
 };
 
-
 /**************************************************************************/
 
-#define TEST   do_test
-#define T      __LINE__, charT ()
-
 // if non-zero expected to point to a maximum valid value
 // of type T that's being tested below (used for floating
 // point ranges)
@@ -226,17 +241,23 @@
 void *pmax = 0;
 
 
+enum IterType { iter_pointer, iter_istreambuf, iter_input };
+
 template <class charT, class nativeT>
 int do_test (int         lineno,          // line number
              charT       /* dummy */,
+             const char *cname,           // name of character type
+             IterType    itype,           // type of input iterator
+             const char *iname,           // name of input iterator
              nativeT     val,             // value expected to be extracted
              const char *str,             // input sequence
-             int         consumed = -1,   // number of consumed characters
+             int         eat_expect = -1, // number of consumed characters
              int         flags = 0,       // initial set of flags
              int         err_expect = -1, // expected iostate
              const char *grouping = "")   // optional grouping string
 {
-    static const char* const cname = rw_any_t (charT ()).type_name ();
+    typedef std::char_traits<charT> Traits;
+
     static const char* const tname = rw_any_t (nativeT ()).type_name ();
 
     if (!rw_enabled (lineno /*, cname, tname */)) {
@@ -249,8 +270,8 @@
     // member functions are flushed
     const Punct<charT> pun (1);
 
-    Ios<charT> io;
-    NumGet<charT> ng;
+    Ios<charT, Traits> io;
+    std::ios_base &iob = io;
 
     io.imbue (std::locale (io.getloc (),
                            (const std::numpunct<charT>*)&pun));
@@ -268,12 +289,13 @@
     nativeT x =
         err_expect & std::ios::failbit || *grouping ? val : nativeT (!val);
 
-    charT wstr_buf [256];   // small buffer to widen `str' to
-    charT *wstr = 0;        // points to wstr_buf if large enough
+    // large buffer to widen `str' to
+    static charT wstr_buf [32767];
 
-    const charT *next;    // iterator to the next character where to parse
+    const charT *pnext;    // iterator to the next character where to parse
 
-    char nbuf [4096];    // narrow character buffer
+    // narrow character buffer
+    static char nbuf [sizeof wstr_buf / sizeof *wstr_buf];
 
     // if the string `str' starts with a '%', treat it as a printf()
     // format specifier and take the string produced by sprintf()
@@ -282,53 +304,65 @@
     if ('%' == *str && 0 < std::sprintf (nbuf, str, val))
         str = nbuf;
 
-    // convert the narrow character string `str' to a wide character
-    // string `wstr' if charT is wider than char
-    const std::size_t str_len = std::strlen (str);
+    pnext = rw_widen (wstr_buf, str);
 
-    if (sizeof (charT) > sizeof (char)) {
+    std::ios_base::iostate err = std::ios_base::goodbit;
 
-        // widen `str' to the wide character buffer if the latter
-        // is large enough, or to a dynamically allocated buffer
-        // otherwise
-        wstr = str_len < sizeof wstr_buf / sizeof *wstr_buf ?
-            wstr_buf : new charT [str_len + 1];
+    const charT *plast = pnext + std::char_traits<charT>::length (pnext);
 
-        typedef unsigned char UChar;
+    int consumed;
 
-        for (std::size_t j = 0; j != str_len + 1; ++j)
-            wstr [j] = charT (UChar (str [j]));
+    switch (itype) {
+    case iter_pointer: {
+        NumGet<charT, const charT*> ng;
+        plast    = ng.get (pnext, plast, iob, err, x);
+        consumed = plast - pnext;
+        break;
+    }
 
-        next = wstr;
+    case iter_istreambuf: {
+        typedef std::istreambuf_iterator<charT, Traits> IStreambufIter;
 
-    }
-    else {
+        Streambuf<charT, Traits> sb (pnext, plast);
+
+        IStreambufIter sbitnext (&sb);
+        IStreambufIter sbitlast; 
 
-        // charT == char, just point next at `str'
-        next = (const charT*)str;
+        NumGet<charT, IStreambufIter> ng;
+        sbitlast = ng.get (sbitnext, sbitlast, iob, err, x);
+        consumed = sb.gptr_off ();
+        break;
     }
 
-    std::ios_base::iostate err = std::ios_base::goodbit;
+    case iter_input: {
+        typedef InputIter<charT> UserIter;
+
+        UserIter uitnext (pnext, pnext, plast);
+        UserIter uitlast (plast, pnext, plast);
 
-    const charT *last = next + std::char_traits<charT>::length (next);
+        NumGet<charT, UserIter> ng;
+        uitlast  = ng.get (uitnext, uitlast, iob, err, x);
+        consumed = uitlast.cur_ - uitnext.cur_;
+        break;
+    }
 
-    last = ng.get (next, last, io, err, x);
+    }
 
     // do not test the number of extracted characters
-    // if (consumed == -1) holds
-    int success = -1 == consumed || last - next == consumed;
+    // if (eat_expect == -1) holds
+    int success = -1 == eat_expect || consumed == eat_expect;
 
     int nfailures = !success;
 
     rw_assert (success, 0, lineno,
-               "line %d: num_get<%s>::get (%#s, ..., %s&); "
+               "line %d: num_get<%s, %s>::get (%#s, ..., %s&); "
                "fmtflags = %{If}; "
                "%{?}grouping = %#s; %{;}"
                "ate %td, expected %d",
-               __LINE__, cname, str, tname,
+               __LINE__, cname, iname, str, tname,
                flags,
                *grouping && '%' != *grouping, grouping,
-               last - next, consumed);
+               consumed, eat_expect);
 
     const nativeT val_max = pmax ? *(nativeT*)pmax : val;
     // if pmax is non-zero it points to the upper bound of the range
@@ -340,13 +374,13 @@
     nfailures += !success;
 
     rw_assert (success, 0, lineno,
-               "line %d: num_get<%s>::get (%{*Ac}, ..., %s&); "
+               "line %d: num_get<%s, %s>::get (%{*Ac}, ..., %s&); "
                "fmtflags = %{If}; "
                "%{?}grouping = %#s; %{;}"
                "got %s (%{Is}); "
                "expected %s%{?} <= %s %{;} "
                "(%{Is})",
-               __LINE__, cname, sizeof *str, str, tname,
+               __LINE__, cname, iname, int (sizeof *str), str, tname,
                flags,
                *grouping && '%' != *grouping, grouping,
                TOSTR (x), err,
@@ -378,22 +412,54 @@
         nfailures += !success;
 
         rw_assert (success, 0, lineno,
-                   "line %d: num_get<%s>::get (%#s, ..., %s&); "
+                   "line %d: num_get<%s, %s>::get (%#s, ..., %s&); "
                    "got %s, but scanf (..., \"%s\", ...) extracted %s "
                    "and returned %d; fmtflags = %{If}, iostate = %{Is}",
-                   __LINE__, cname, str, tname,
+                   __LINE__, cname, iname, str, tname,
                    TOSTR (x), scanspec, TOSTR (y),
                    n, flags, err);
     }
 
-    if (wstr != wstr_buf)
-        delete[] wstr;
-
     return nfailures;
 }
 
 /**************************************************************************/
 
+enum CharType { narrow_char, wide_char, user_char };
+
+template <class nativeT>
+int do_test (int         lineno,          // line number
+             CharType    ctype,           // character type
+             const char *cname,           // name of character type
+             IterType    itype,           // iterator type
+             const char *iname,           // name of iterator type
+             nativeT     val,             // value expected to be extracted
+             const char *str,             // input sequence
+             int         eat_expect = -1,   // number of consumed characters
+             int         flags = 0,       // initial set of flags
+             int         err_expect = -1, // expected iostate
+             const char *grouping = "")   // optional grouping string
+{
+    switch (ctype) {
+    case narrow_char:
+        return do_test (lineno, char (), cname, itype, iname,
+                        val, str, eat_expect, flags, err_expect, grouping);
+    case wide_char:
+        return do_test (lineno, wchar_t (), cname, itype, iname,
+                        val, str, eat_expect, flags, err_expect, grouping);
+    case user_char:
+        break;
+#if 0   // disabled
+        return do_test (lineno, UserChar (), cname, itype, iname,
+                        val, str, eat_expect, flags, err_expect, grouping);
+#endif   // disabled
+    }
+
+    return 1;
+}
+
+/**************************************************************************/
+
 // for convenience
 #define boolalpha   std::ios_base::boolalpha
 #define dec         std::ios_base::dec
@@ -424,17 +490,21 @@
 
 /*************************************************************************/
 
-template <class charT, class numT>
-void test_errno (charT, numT)
+#define TEST   do_test
+#define T      __LINE__, ctype, cname, itype, iname
+
+
+template <class numT>
+void test_errno (CharType ctype, const char *cname,
+                 IterType itype, const char *iname, numT)
 {
     // verify that errno doesn't change after, or affects
     // a successful extraction
 
-    const char* const cname = rw_any_t (charT ()).type_name ();
     const char* const tname = rw_any_t (numT ()).type_name ();
 
-    rw_info (0, 0, 0, "std::num_get<%s>::get (..., %s&) and errno",
-             cname, tname);
+    rw_info (0, 0, 0, "std::num_get<%s, %s>::get (..., %s&) and errno",
+             cname, iname, tname);
 
     const int errnos[] = {
         ERANGE, -4, -3, -2, -1, 0, 1, 2, 3, 4,
@@ -484,27 +554,20 @@
 
 /**************************************************************************/
 
-template <class charT>
-void test_bool (charT, const char *cname)
+static void
+test_bool (CharType ctype, const char *cname,
+           IterType itype, const char *iname)
 {
 #ifndef NO_GET_BOOL
 
     const char* const tname = "bool";
 
-    rw_info (0, 0, 0, "std::num_get<%s>::get (..., %s&)", cname, tname);
-
-    Punct<charT>::decimal_point_ = '.';
-    Punct<charT>::thousands_sep_ = ',';
-
-    {
-        static const charT names[][6] = {
-            { 'f', 'a', 'l', 's', 'e', '\0' },
-            { 't', 'r', 'u', 'e', '\0' }
-        };
+    rw_info (0, 0, 0, "std::num_get<%s, %s>::get (..., %s&)",
+             cname, iname, tname);
 
-        Punct<charT>::falsename_ = names [0];
-        Punct<charT>::truename_  = names [1];
-    }
+    PunctData::decimal_point_ = '.';
+    PunctData::thousands_sep_ = ',';
+    PunctData::set_names ("false", "true");
 
     // lwg issue 17: special treatment for bool:
 
@@ -587,7 +650,7 @@
 
     // bool, numeric parsing with grouping
 
-    Punct<charT>::thousands_sep_ = ';';
+    PunctData::thousands_sep_ = ';';
 
     TEST (T, false,        "0;0",  3, 0, Eof, "\1");
     TEST (T, false,       "+0;0",  4, 0, Eof, "\1");
@@ -668,15 +731,7 @@
     TEST (T, false, "f", 1, boolalpha, Eof | Fail);
     TEST (T, false, "",  0, boolalpha, Eof | Fail);
 
-    {
-        static const charT names[][7] = {
-            { 'b', 'o', 'o', 'l', ':', '-', '\0' },
-            { 'b', 'o', 'o', 'l', ':', '+', '\0' }
-        };
-
-        Punct<charT>::falsename_ = names [0];
-        Punct<charT>::truename_  = names [1];
-    }
+    PunctData::set_names ("bool:-", "bool:+");
 
     TEST (T, false, "false", 0, boolalpha, Fail);
     TEST (T, false, "true",  0, boolalpha, Fail);
@@ -687,15 +742,7 @@
     TEST (T, false, "bool: ", 5, boolalpha, Fail);
     TEST (T, false, "bool: ", 5, boolalpha, Fail);
 
-    {
-        static const charT names[][8] = {
-            { 'B', 'o', 'o', 'l', '\0' },
-            { 'B', 'o', 'o', 'l', 'e', 'a', 'n', '\0' }
-        };
-
-        Punct<charT>::falsename_ = names [0];
-        Punct<charT>::truename_  = names [1];
-    }
+    PunctData::set_names ("Bool", "Boolean");
 
     TEST (T, false, "false", 0, boolalpha, Fail);
     TEST (T, false, "true",  0, boolalpha, Fail);
@@ -706,16 +753,7 @@
     TEST (T, false, "Boole",  5, boolalpha, Eof | Fail);
     TEST (T, false, "Boolea", 6, boolalpha, Eof | Fail);
 
-
-    {
-        static const charT names[][8] = {
-            { 'B', 'O', 'O', 'L', 'E', 'A', 'N', '\0' },
-            { 'B', 'O', 'O', 'L', '\0' }
-        };
-
-        Punct<charT>::falsename_ = names [0];
-        Punct<charT>::truename_  = names [1];
-    }
+    PunctData::set_names ("BOOLEAN", "BOOL");
 
     TEST (T, false, "false", 0, boolalpha, Fail);
     TEST (T, false, "true",  0, boolalpha, Fail);
@@ -730,16 +768,7 @@
     TEST (T, false, "BOOLEA", 6, boolalpha, Eof | Fail);
     TEST (T, false, "BOOLE",  5, boolalpha, Eof | Fail);
 
-
-    {
-        static const charT names[][8] = {
-            { '1', '\0' },
-            { '0', '\0' }
-        };
-
-        Punct<charT>::falsename_ = names [0];
-        Punct<charT>::truename_  = names [1];
-    }
+    PunctData::set_names ("1", "0");
 
     TEST (T, false, "false", 0, boolalpha, Fail);
     TEST (T, false, "true",  0, boolalpha, Fail);
@@ -767,17 +796,17 @@
 
 /**************************************************************************/
 
-
-template <class charT>
-void test_shrt (charT, const char *cname)
+static void
+test_shrt (CharType ctype, const char *cname,
+           IterType itype, const char *iname)
 {
 #ifndef _RWSTD_NO_EXT_NUM_GET
 #  ifndef NO_GET_SHRT
 
     const char* const tname = "short";
 
-    rw_info (0, 0, 0, "extension: std::num_get<%s>::get (..., %s&)",
-             cname, tname);
+    rw_info (0, 0, 0, "extension: std::num_get<%s, %s>::get (..., %s&)",
+             cname, iname, tname);
 
     // short parsing of 0, no base specified
     TEST (T, short (0), "%hi",  1, 0, Eof, "%hi");
@@ -868,7 +897,7 @@
         rw_note (0, 0, 0, "errno test disabled");
     }
     else {
-        test_errno (charT (), short ());
+        test_errno (ctype, cname, itype, iname, short ());
     }
 
 #  else   // if defined (NO_GET_SHRT)
@@ -882,17 +911,17 @@
 
 /**************************************************************************/
 
-
-template <class charT>
-void test_int (charT, const char *cname)
+static void
+test_int (CharType ctype, const char *cname,
+          IterType itype, const char *iname)
 {
 #ifndef _RWSTD_NO_EXT_NUM_GET
 #  ifndef NO_GET_INT
 
     const char* const tname = "int";
 
-    rw_info (0, 0, 0, "extension: std::num_get<%s>::get (..., %s&)",
-             cname, tname);
+    rw_info (0, 0, 0, "extension: std::num_get<%s, %s>::get (..., %s&)",
+             cname, iname, tname);
 
     TEST (T, 0, "%i",  1, 0, Eof, "%i");
     TEST (T, 0, "%o",  1, 0, Eof, "%i");
@@ -903,7 +932,7 @@
         rw_note (0, 0, 0, "errno test disabled");
     }
     else {
-        test_errno (charT (), int ());
+        test_errno (ctype, cname, itype, iname, int ());
     }
 
 #  else   // if defined (NO_GET_INT)
@@ -917,16 +946,16 @@
 
 /**************************************************************************/
 
-
-template <class charT>
-void test_long (charT, const char *cname)
+static void
+test_long (CharType ctype, const char *cname,
+           IterType itype, const char *iname)
 {
 #ifndef NO_GET_LONG
 
     const char* const tname = "long";
 
-    rw_info (0, 0, 0, "std::num_get<%s>::get (..., %s&)",
-             cname, tname);
+    rw_info (0, 0, 0, "std::num_get<%s, %s>::get (..., %s&)",
+             cname, iname, tname);
 
     // 22.2.3.1, p2 -- integer grammar:
     // 
@@ -1073,7 +1102,7 @@
     TEST (T,     4567890L,   "4567890.1",   7, dec, Good, "%ld");
     TEST (T,      567890L,   "567890e+1",   6, dec, Good, "%ld");
 
-    Punct<charT>::thousands_sep_ = ';';
+    PunctData::thousands_sep_ = ';';
 
     // long parsing, dec base, with grouping (which is optional, empty
     // grouping, "", causes extraction to terminate at the first occurrence
@@ -1194,10 +1223,10 @@
     TEST (T, 2147483620L,   "+214;;7483620 ",  5, dec, Fail, "\7\4");
 
     // unusual thousands_sep
-    Punct<charT>::thousands_sep_ = '.';
+    PunctData::thousands_sep_ = '.';
     TEST (T, 2147483618L, "214.74836.18", 12, dec, Eof, "\2\5");
 
-    Punct<charT>::thousands_sep_ = 'A';
+    PunctData::thousands_sep_ = 'A';
     TEST (T, 2147483617L, "2A14A7483A617", 13, dec, Eof, "\3\4\2");
 
     // Stage 2 parsing algorithm in 22.2.2.1.2, p8 removes thousands_sep
@@ -1206,21 +1235,21 @@
     // may not appear first, when the leading thousands_sep matches
     // the sign character it is taken as the sign
     // (these are totally anal-retentive tests)
-    Punct<charT>::thousands_sep_ = '-';
+    PunctData::thousands_sep_ = '-';
     TEST (T,  2147483617L, "21-47-4-83-617", 14, dec, Eof, "\3\2\1\2");
     TEST (T, -2147483616L, "-214-748-3616 ", 13, dec, Good, "\4\3\3");
 
-    Punct<charT>::thousands_sep_ = '+';
+    PunctData::thousands_sep_ = '+';
     TEST (T, 2147483615L, "2+147+48+3+615", 14, dec, Eof, "\3\1\2\3");
 
     // leading '+' taken as the plus sign and not a thousands_sep
     TEST (T, 2147483614L, "+21+4748361+4 ", 13, dec, Good, "\1\7\2");
 
     // a digit as a thousands_sep is removed from the input sequence
-    Punct<charT>::thousands_sep_ = '0';
+    PunctData::thousands_sep_ = '0';
     TEST (T, 2147483613L, "21047048306013", 14, dec, Eof, "\2\1\3\2");
 
-    Punct<charT>::thousands_sep_ = '1';
+    PunctData::thousands_sep_ = '1';
     TEST (T,   24748362L,     "2147483612", 10, dec, Eof, "\1\6");
 
     // exercise lwg issue 338 (whitespace after sign not allowed)
@@ -1421,7 +1450,7 @@
         rw_note (0, 0, 0, "errno test disabled");
     }
     else {
-        test_errno (charT (), long ());
+        test_errno (ctype, cname, itype, iname, long ());
     }
 
 #endif   // NO_GET_LONG
@@ -1430,16 +1459,16 @@
 
 /**************************************************************************/
 
-
-template <class charT>
-void test_ulong (charT, const char *cname)
+static void
+test_ulong (CharType ctype, const char *cname,
+            IterType itype, const char *iname)
 {
 #ifndef NO_GET_ULONG
 
     const char* const tname = "unsigned long";
 
-    rw_info (0, 0, 0, "std::num_get<%s>::get (..., %s&)",
-             cname, tname);
+    rw_info (0, 0, 0, "std::num_get<%s, %s>::get (..., %s&)",
+             cname, iname, tname);
 
     // negative numbers are conventionally parsed and interpreted
     // according to the following algorithm:
@@ -1514,7 +1543,7 @@
         rw_note (0, 0, 0, "errno test disabled");
     }
     else {
-        test_errno (charT (), (unsigned long)0);
+        test_errno (ctype, cname, itype, iname, (unsigned long)0);
     }
 
 #endif   // NO_GET_ULONG
@@ -1522,22 +1551,24 @@
 
 /**************************************************************************/
 
-template <class charT>
-void test_llong (charT, const char *cname)
+static void
+test_llong (CharType ctype, const char *cname,
+            IterType itype, const char *iname)
 {
 #ifndef NO_GET_LLONG
+#  ifndef _RWSTD_NO_LONG_LONG
 
     const char* const tname = "long long";
 
-    rw_info (0, 0, 0, "extension: std::num_get<%s>::get (..., %s&)",
-             cname, tname);
+    rw_info (0, 0, 0, "extension: std::num_get<%s, %s>::get (..., %s&)",
+             cname, iname, tname);
 
-#  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
+#    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),                    "0",  1, 0, Eof);
     TEST (T,  LL (   0),                   "+0",  2, 0, Eof);
@@ -1561,31 +1592,34 @@
         rw_note (0, 0, 0, "errno test disabled");
     }
     else {
-        test_errno (charT (), (long long)0);
+        test_errno (ctype, cname, itype, iname, (long long)0);
     }
 
+#  endif   // _RWSTD_NO_LONG_LONG
 #endif   // NO_GET_LLONG
 
 }
 
 /**************************************************************************/
 
-template <class charT>
-void test_ullong (charT, const char *cname)
+static void
+test_ullong (CharType ctype, const char *cname,
+             IterType itype, const char *iname)
 {
 #ifndef NO_GET_ULLONG
+#  ifndef _RWSTD_NO_LONG_LONG
 
     const char* const tname = "unsigned long long";
 
-    rw_info (0, 0, 0, "extension: std::num_get<%s>::get (..., %s&)",
-             cname, tname);
+    rw_info (0, 0, 0, "extension: std::num_get<%s, %s>::get (..., %s&)",
+             cname, iname, tname);
 
-#  ifndef _MSC_VER
-#    define ULL(number)   number ## ULL
-#  else   // if defined (_MSC_VER)
-     // MSVC 7.0 doesn't recognize the LL suffix
-#    define ULL(number)   number ## UI64
-#  endif   // _MSC_VER
+#    ifndef _MSC_VER
+#      define ULL(number)   number ## ULL
+#    else   // if defined (_MSC_VER)
+       // MSVC 7.0 doesn't recognize the LL suffix
+#      define ULL(number)   number ## UI64
+#    endif   // _MSC_VER
 
     TEST (T, ULL (                  0),                     "0",  1, 0, Eof);
     TEST (T, ULL (                  0),                    "+0",  2, 0, Eof);
@@ -1598,24 +1632,26 @@
         rw_note (0, 0, 0, "errno test disabled");
     }
     else {
-        test_errno (charT (), (unsigned long long)0);
+        test_errno (ctype, cname, itype, iname, (unsigned long long)0);
     }
 
+#  endif   // _RWSTD_NO_LONG_LONG
 #endif   // NO_GET_ULLONG
 
 }
 
 /**************************************************************************/
 
-template <class charT>
-void test_pvoid (charT, const char *cname)
+static void
+test_pvoid (CharType ctype, const char *cname,
+            IterType itype, const char *iname)
 {
 #ifndef NO_GET_PVOID
 
     const char* const tname = "void*";
 
-    rw_info (0, 0, 0, "std::num_get<%s>::get (..., %s&)",
-             cname, tname);
+    rw_info (0, 0, 0, "std::num_get<%s, %s>::get (..., %s&)",
+             cname, iname, tname);
 
     typedef void* PVoid;
 
@@ -1661,14 +1697,14 @@
 
 /**************************************************************************/
 
-
-template <class charT, class floatT>
-void test_floating_point (charT, floatT, bool test_locale)
+template <class floatT>
+void test_floating_point (CharType ctype, const char *cname,
+                          IterType itype, const char *iname,
+                          floatT, bool test_locale)
 {
-    const char* const cname = rw_any_t (charT ()).type_name ();
     const char* const tname = rw_any_t (floatT ()).type_name ();
 
-    Punct<charT>::thousands_sep_ = ';';
+    PunctData::thousands_sep_ = ';';
 
     typedef floatT F;
 
@@ -1884,7 +1920,7 @@
     // is the plus or minus character (e.g., on AIX, the Romanian locale,
     // "RO_RO" -- see bug #609)
 
-    Punct<charT>::thousands_sep_ = '+';
+    PunctData::thousands_sep_ = '+';
 
     TEST (T, F ( 123e+4),  "123e+4", 6, 0, Eof, "\1");
     TEST (T, F ( 124e+5),  "124e+5", 6, 0, Eof, "\1");
@@ -1892,7 +1928,7 @@
     TEST (T, F (-126e+7), "-126e+7", 7, 0, Eof, "\1");
     TEST (T, F (-127e-8), "-127e-8", 7, 0, Eof, "\1");
 
-    Punct<charT>::thousands_sep_ = '-';
+    PunctData::thousands_sep_ = '-';
 
     TEST (T, F ( 123e-4),  "123e-4", 6, 0, Eof, "\1");
     TEST (T, F ( 124e-5),  "124e-5", 6, 0, Eof, "\1");
@@ -1901,7 +1937,7 @@
     TEST (T, F (+127e+8), "+127e+8", 7, 0, Eof, "\1");
 
     // restore to a saner value
-    Punct<charT>::thousands_sep_ = ';';
+    PunctData::thousands_sep_ = ';';
 
     if (test_locale) {
         // verify that the global LC_NUMERIC locale setting
@@ -1921,8 +1957,9 @@
 
             if (conv->decimal_point && '.' != *conv->decimal_point) {
                 rw_info (0, 0, 0, 
-                         "num_get<%s>::get(..., %s&) when LC_NUMERIC=\"%s\"",
-                         cname, tname, name);
+                         "num_get<%s, %s>::get(..., %s&) when "
+                         "LC_NUMERIC=\"%s\"",
+                         cname, iname, tname, name);
                 break;
             }
         }
@@ -1939,9 +1976,9 @@
     }
     else
         rw_warn (0, 0, 0,
-                 "num_get<%s>::get (..., %s&) known to fail when LC_NUMERIC "
-                 "is set to a locale where decimal_point != '.'",
-                 cname, tname);
+                 "num_get<%s, %s>::get (..., %s&) known to fail when "
+                 "LC_NUMERIC is set to a locale where decimal_point != '.'",
+                 cname, iname, tname);
 
     //////////////////////////////////////////////////////////////////
     // exercise errno
@@ -1949,7 +1986,7 @@
         rw_note (0, 0, 0, "errno test disabled");
     }
     else {
-        test_errno (charT (), floatT ());
+        test_errno (ctype, cname, itype, iname, floatT ());
     }
 
 }
@@ -1957,13 +1994,15 @@
 
 /**************************************************************************/
 
-template <class charT>
-void test_flt_uflow (charT, const char *cname)
+static void
+test_flt_uflow (CharType ctype, const char *cname,
+                IterType itype, const char *iname)
 {
 #ifndef NO_GET_FLT
 
     rw_info (0, 0, 0,
-             "std::num_get<%s>::get (..., float&) on underflow", cname);
+             "std::num_get<%s, %s>::get (..., float&) on underflow",
+             cname, iname);
 
     // exercise bahvior on underflow
     float val = 0;
@@ -2009,7 +2048,8 @@
     pmax = 0;   // reset before next test
 
 
-    rw_info (0, 0, 0, "get (..., float&) on overflow");
+    rw_info (0, 0, 0, "std::num_get<%s, %s>::get (..., float&) on overflow",
+             cname, iname);
 
     const float inf = std::numeric_limits<float>::infinity ();
 
@@ -2068,17 +2108,18 @@
 
 /**************************************************************************/
 
-template <class charT>
-void test_flt (charT, const char *cname)
+static void
+test_flt (CharType ctype, const char *cname,
+          IterType itype, const char *iname)
 {
 #ifndef NO_GET_FLT
 
     const char* const tname = "float";
 
-    rw_info (0, 0, 0, "std::num_get<%s>::get (..., %s&)",
-             cname, tname);
+    rw_info (0, 0, 0, "std::num_get<%s, %s>::get (..., %s&)",
+             cname, iname, tname);
 
-    Punct<charT>::thousands_sep_ = ';';
+    PunctData::thousands_sep_ = ';';
 
 #  if    !defined (_RWSTD_NO_STRTOF) || !defined (_RWSTD_NO_STRTOF_IN_LIBC) \
       || !defined (_RWSTD_NO_STRTOD) || !defined (_RWSTD_NO_STRTOD_IN_LIBC)
@@ -2091,7 +2132,7 @@
 
 #  endif   // _RWSTD_NO_STRTO{D,F}(_IN_LIBC)
 
-    test_floating_point (charT (), float (), test_locale);
+    test_floating_point (ctype, cname, itype, iname, float (), test_locale);
 
     const char *str = _RWSTD_STRSTR (FLT_MAX);
 
@@ -2113,7 +2154,7 @@
         rw_note (0, 0, 0, "underflow test disabled");
     }
     else {
-        test_flt_uflow (charT (), cname);
+        test_flt_uflow (ctype, cname, itype, iname);
     }
 
 #else   // if defined (NO_GET_FLT)
@@ -2126,14 +2167,13 @@
 
 /**************************************************************************/
 
-
-template <class charT>
-void test_dbl_uflow (charT, const char *cname)
+void test_dbl_uflow (CharType ctype, const char *cname,
+                     IterType itype, const char *iname)
 {
 #ifndef NO_GET_DBL
 
-    rw_info (0, 0, 0, "std::num_get<%s>::get (..., double&) on underflow",
-             cname);
+    rw_info (0, 0, 0, "std::num_get<%s, %s>::get (..., double&) on underflow",
+             cname, iname);
 
     // exercise bahvior on underflow
     double val = DBL_MIN;
@@ -2171,7 +2211,8 @@
 
 #  ifdef _RWSTD_LDBL_MAX
 
-    rw_info (0, 0, 0, "get (..., double&) on overflow");
+    rw_info (0, 0, 0, "std::num_get<%s, %s>::get (..., double&) on overflow",
+             cname, iname);
 
     const double inf = std::numeric_limits<double>::infinity ();
 
@@ -2197,8 +2238,9 @@
 
 /**************************************************************************/
 
-template <class charT>
-void test_dbl (charT, const char *cname)
+static void
+test_dbl (CharType ctype, const char *cname,
+          IterType itype, const char *iname)
 {
 #ifndef NO_GET_DBL
 
@@ -2214,8 +2256,8 @@
 
     const char* const tname = "double";
 
-    rw_info (0, 0, 0, "std::num_get<%s>::get (..., %s&)",
-             cname, tname);
+    rw_info (0, 0, 0, "std::num_get<%s, %s>::get (..., %s&)",
+             cname, iname, tname);
 
 #  if !defined (_RWSTD_NO_STRTOD) || !defined (_RWSTD_NO_STRTOD_IN_LIBC)
 
@@ -2227,13 +2269,13 @@
 
 #  endif   // _RWSTD_NO_STRTOD(_IN_LIBC)
 
-    test_floating_point (charT (), double (), test_locale);
+    test_floating_point (ctype, cname, itype, iname, double (), test_locale);
 
     if (rw_opt_no_uflow) {
         rw_note (0, 0, 0, "underflow test disabled");
     }
     else {
-        test_dbl_uflow (charT (), cname);
+        test_dbl_uflow (ctype, cname, itype, iname);
     }
 
 #else   // if defined (NO_GET_DBL)
@@ -2246,14 +2288,15 @@
 
 /**************************************************************************/
 
-
-template <class charT>
-void test_ldbl_uflow (charT, const char *cname)
+static void
+test_ldbl_uflow (CharType ctype, const char *cname,
+                 IterType itype, const char *iname)
 {
 #ifndef NO_GET_LDBL
 
     rw_info (0, 0, 0,
-             "std::num_get<%s>::get (..., long double&) on underflow", cname);
+             "std::num_get<%s, %s>::get (..., long double&) on underflow",
+             cname, iname);
 
     // exercise bahvior on underflow
     long double val = LDBL_MIN;
@@ -2289,7 +2332,9 @@
 
 #  ifdef _RWSTD_LDBL_MAX
 
-    rw_info (0, 0, 0, "get (..., long double&) on overflow");
+    rw_info (0, 0, 0,
+             "std::num_get<%s, %s>::get (..., long double&) on overflow",
+             cname, iname);
 
     const double inf = std::numeric_limits<long double>::infinity ();
 
@@ -2308,8 +2353,9 @@
 
 /**************************************************************************/
 
-template <class charT>
-void test_ldbl (charT, const char *cname)
+static void
+test_ldbl (CharType ctype, const char *cname,
+           IterType itype, const char *iname)
 {
 #ifndef NO_GET_LDBL
 
@@ -2317,8 +2363,8 @@
 
     const char* const tname = "long double";
 
-    rw_info (0, 0, 0, "std::num_get<%s>::get (..., %s&)",
-             cname, tname);
+    rw_info (0, 0, 0, "std::num_get<%s, %s>::get (..., %s&)",
+             cname, iname, tname);
 
 #    if !defined (_RWSTD_NO_STRTOLD) || !defined (_RWSTD_NO_STRTOLD_IN_LIBC)
 
@@ -2330,7 +2376,7 @@
 
 #    endif   // _RWSTD_NO_STRTOLD(_IN_LIBC)
 
-    test_floating_point (charT (), (long double)0, test_locale);
+    test_floating_point (ctype, cname, itype, iname, 0.0L, test_locale);
 
     long double long_val;
 
@@ -2398,7 +2444,7 @@
         rw_note (0, 0, 0, "underflow test disabled");
     }
     else {
-        test_ldbl_uflow (charT (), cname);
+        test_ldbl_uflow (ctype, cname, itype, iname);
     }
 
 #else   // if defined (NO_GET_LDBL)
@@ -2411,13 +2457,14 @@
 
 /**************************************************************************/
 
-template <class charT>
-void run_tests (charT, const char *cname)
+static void
+run_tests (CharType ctype, const char *cname,
+           IterType itype, const char *iname)
 {
 #undef TEST
 #define TEST(T, tname)                                          \
     if (rw_enabled (tname))                                     \
-        test_ ## T (charT (), cname);                           \
+        test_ ## T (ctype, cname, itype, iname);                \
     else                                                        \
         rw_note (0, __FILE__, __LINE__, "%s test disabled", tname)
 
@@ -2446,18 +2493,28 @@
 
 /**************************************************************************/
 
-static int
-run_test (int, char*[])
+static void
+run_tests (IterType itype)
 {
-    if (rw_enabled ("char"))
-        run_tests (char (), "char");
+    RW_ASSERT (0 <= itype && itype < 3);
+
+    if (rw_enabled ("char")) {
+        static const char* const inames[] = {
+            "char*", "istreambuf_iterator<char>", "InputIter<char>"
+        };
+        run_tests (narrow_char, "char", itype, inames [itype]);
+    }
     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");
+    if (rw_enabled ("wchar_t")) {
+        static const char* const inames[] = {
+            "wchar_t*", "istreambuf_iterator<wchar_t>", "InputIter<wchar_t>"
+        };
+        run_tests (wide_char, "wchar_t", itype, inames [itype]);
+    }
     else
         rw_note (0, __FILE__, __LINE__, "wchar_t test disabled");
 
@@ -2467,6 +2524,30 @@
              "wchar_t test disabled: _RWSTD_NO_WCHAR_T #defined");
 
 #endif   // _RWSTD_NO_WCHAR_T
+
+#if 0   // disabled
+
+    if (rw_enabled ("UserChar")) {
+        static const char* const inames[] = {
+            "UserChar*", "istreambuf_iterator<UserChar>", "InputIter<UserChar>"
+        };
+        run_tests (narrow_char, "UserChar", itype, inames [itype]);
+    }
+    else
+        rw_note (0, __FILE__, __LINE__, "UserChar test disabled");
+
+#endif   // disabled
+
+}
+
+/**************************************************************************/
+
+static int
+run_test (int, char*[])
+{
+    run_tests (iter_pointer);
+    run_tests (iter_istreambuf);
+    run_tests (iter_input);
 
     return 0;
 }



Mime
View raw message