void test_long_double (charT, const char *cname) { if (rw_enabled ("long double")) test_get (charT (0 /* long double argument */), cname, "long double"); else rw_note (0, __FILE__, __LINE__, "long double test disabled"); }
void test_string (charT, const char *cname) { if (rw_enabled ("basic_string")) test_get (charT (1 /* basic_string argument */), cname, "basic_string"); else rw_note (0, __FILE__, __LINE__, "basic_string<%s> test disabled", cname); }
int run_test (int, char*[]) { if (rw_enabled ("char")) test_assign (char (), "char"); else rw_note (0, __FILE__, __LINE__, "char test disabled"); #ifndef _RWSTD_NO_WCHAR_T if (rw_enabled ("wchar_t")) test_assign (wchar_t (), "wchar_t"); else rw_note (0, __FILE__, __LINE__, "wchar_t test disabled"); #endif // _RWSTD_NO_WCHAR_T return 0; }
static int run_test (int, char*[]) { // check the prescribed values of the required constants rw_fatal ('\0' == std::money_base::none, 0, 0, "'\\0' == money_base::none, got %d", std::money_base::none); rw_fatal ('\1' == std::money_base::space, 0, 0, "'\\1' == money_base::space, got %d", std::money_base::space); rw_fatal ('\2' == std::money_base::symbol, 0, 0, "'\\2' == money_base::symbol, got %d", std::money_base::symbol); rw_fatal ('\3' == std::money_base::sign, 0, 0, "'\\3' == money_base::sign, got %d", std::money_base::sign); rw_fatal ('\4' == std::money_base::value, 0, 0, "'\\4' == money_base::value, got %d", std::money_base::value); if (rw_enabled ("char")) { test_long_double (char (), "char"); test_string (char (), "char"); } else rw_note (0, __FILE__, __LINE__, "char test disabled"); #ifndef _RWSTD_NO_WCHAR_T if (rw_enabled ("wchar_t")) { test_long_double (wchar_t (), "wchar_t"); test_string (wchar_t (), "wchar_t"); } else rw_note (0, __FILE__, __LINE__, "wchar_t test disabled"); #endif // _RWSTD_NO_WCHAR_T return 0; }
void do_test (bool intl, // international? charT which, // which overload to exercise const char *cname, // the name of the charT type const char *tname, // the name of the floating point type int lineno, // line number LongDouble val, // the expected extracted value const char *str, // the sequence to extract from int consumed = -1, // expected number extractions int flags = 0, // initial ios flags int err_expect = -1, // expected final state int frac_digits = 0, // fractional digits const char *fmat = 0, // money_base::pattern const char *cursym = 0, // currency symbol const char *grouping = "") // grouping string { if (!rw_enabled (lineno)) { rw_note (0, __FILE__, __LINE__, "test on line %d disabled", lineno); return; } if (!fmat) { // if fmat isn't set, use the default pattern static const std::money_base::pattern pat = { { std::money_base::symbol, std::money_base::sign, std::money_base::none, std::money_base::value } }; fmat = pat.field; } else fmat = set_pattern (fmat).field; // local format? (the opposite of interantional) const bool locl = !intl; // take care to initialize Punct static data before installing // the facet in case locale or the base facet calls the overridden // virtuals early to cache the results PunctData<charT>::format_ [intl][1].field [0] = fmat [0]; PunctData<charT>::format_ [intl][1].field [1] = fmat [1]; PunctData<charT>::format_ [intl][1].field [2] = fmat [2]; PunctData<charT>::format_ [intl][1].field [3] = fmat [3]; PunctData<charT>::format_ [locl][1].field [0] = fmat [3]; PunctData<charT>::format_ [locl][1].field [1] = fmat [2]; PunctData<charT>::format_ [locl][1].field [2] = fmat [1]; PunctData<charT>::format_ [locl][1].field [3] = fmat [0]; // zero out positive format (not used by money_get) PunctData<charT>::format_ [intl][0] = std::money_base::pattern (); PunctData<charT>::format_ [locl][0] = std::money_base::pattern (); // expand (widen) currency symbol PunctData<charT>::curr_symbol_ [intl] = rw_expand ((charT*)0, cursym); PunctData<charT>::curr_symbol_ [locl] = 0; PunctData<charT>::grouping_ [intl] = grouping; PunctData<charT>::grouping_ [locl] = 0; PunctData<charT>::frac_digits_ [intl] = frac_digits; PunctData<charT>::frac_digits_ [locl] = frac_digits + 1; Ios<charT> io; MoneyGet<charT> mg; // create distinct punctuation facets for each iteration to make sure // any data cached in between successive calls to the facet's public // member functions are flushed if (intl) { const std::moneypunct<charT, true> *pf = new Punct<charT, true>(0); io.imbue (std::locale (io.getloc (), pf)); } else { const std::moneypunct<charT, false> *pf = new Punct<charT, false>(0); io.imbue (std::locale (io.getloc (), pf)); } io.flags (std::ios_base::fmtflags (flags)); // expand (widen) input sequence const charT* const next = rw_expand ((charT*)0, str); std::ios_base::iostate err = std::ios_base::goodbit; const charT *last; if (0 == which) { // exercise get (..., long double) last = next + std::char_traits<charT>::length (next); LongDouble x = 0; last = mg.get (next, last, intl, io, err, x); if (-1 == err_expect) err_expect = err; const int success = !(-1 != consumed && last - next != consumed || err != err_expect); rw_assert (success, __FILE__, lineno, "money_get<%s>::get (%{*Ac}, ..., %b, ..., %s&), " "ate %d, expected %d, frac_digits = %d, " "flags = %{If}, grouping = %#s, pattern = %{LM}, " "state = %{Is}, expected %{Is}", cname, int (sizeof *next), next, intl, tname, last - next, consumed, frac_digits, flags, grouping, fmat, err, err_expect); rw_assert (2 > rw_ldblcmp (x, val), __FILE__, lineno, "money_get<%s>::get (%{*Ac}, ..., %b, ..., %s&), " "got %Lg, expected %Lg, frac_digits = %d, " "flags = %{If}s, grouping = %#s, pattern = %{LM}, " "state = %{Is}, expected %{Is}", cname, int (sizeof *next), next, intl, tname, x, val, frac_digits, flags, grouping, fmat, err, err_expect); } else { // exercise get (..., string_type) static const charT initial[] = { '*', '*', '*', '\0' }; typename std::money_get<charT, const charT*>::string_type bs (initial); last = next + std::char_traits<charT>::length (next); last = mg.get (next, last, intl, io, err, bs); int success = !(-1 != consumed && last - next != consumed || err != err_expect); rw_assert (success, __FILE__, lineno, "money_get<%s>::get (%{*Ac}, ..., %b, ..., " "basic_string<%s>&), ate %d, expected %d, " "frac_digits = %d, flags = %{If}, grouping = %#s" ", format = %{LM}, state = %{Is}, expected %{Is}", cname, int (sizeof *next), next, intl, cname, last - next, consumed, frac_digits, flags, grouping, fmat, err, err_expect); if (success) { char narrow_buf [4096]; rw_narrow (narrow_buf, bs.c_str ()); LongDouble x = 0; // prevent gcc warning: ANSI C does not support // the `L' length modifier const char fmt[] = "%" _RWSTD_LDBL_PRINTF_PREFIX "g"; int n = std::sscanf (narrow_buf, fmt, &x); success = !( err_expect & std::ios::failbit && !*grouping && (1 == n || bs != initial) || !(err_expect & std::ios::failbit) && 1 < rw_ldblcmp (x, val)); rw_assert (success, __FILE__, lineno, "money_get<%s>::get (%{*Ac}, ..., %b, ..., " "basic_string<%s>&), got %s, expected %Lg, " "frac_digits = %d, flags = %{If}, grouping = %#s," " pattern = %{LM}, iostate = %{Is}, expected %{Is}", cname, int (sizeof *next), next, intl, cname, bs.c_str (), val, frac_digits, flags, grouping, fmat, err, err_expect); } } delete[] PunctData<charT>::curr_symbol_ [intl]; delete[] next; }
void run_test (intT, thr_args_base::tag_t tag) { static const char* const tname = rw_any_t (intT ()).type_name (); if (!rw_enabled (tname)) { rw_note (0, 0, 0, "%s test disabled", tname); return; } #ifdef _RWSTD_REENTRANT static const char* const fun = "__rw_atomic_exchange"; rw_info (0, 0, 0, "__rw::%s (%s&, %2$s): %d iterations in %d threads", fun, tname, rw_opt_nloops, rw_opt_nthreads); rw_thread_t tid [MAX_THREADS]; typedef thr_args<intT> Args; Args::nthreads_ = unsigned (rw_opt_nthreads); Args::type_tag_ = tag; Args::nincr_ = unsigned (rw_opt_nloops); Args::shared_ [0] = intT (1); Args::shared_ [1] = intT (1); _RWSTD_ASSERT (Args::nthreads_ < sizeof tid / sizeof *tid); Args args [sizeof tid / sizeof *tid]; for (unsigned long i = 0; i != Args::nthreads_; ++i) { args [i].threadno_ = i; args [i].niter_ = 0; args [i].nxchg_ = 0; rw_fatal (0 == rw_thread_create (tid + i, 0, thread_routine, args + i), 0, __LINE__, "thread_create() failed"); } for (unsigned long i = 0; i != Args::nthreads_; ++i) { rw_error (0 == rw_thread_join (tid [i], 0), 0, __LINE__, "thread_join() failed"); if (args [i].niter_) { // compute the percantage of thread iterations that resulted // in increments of one of the shared variables const unsigned long incrpcnt = (100U * Args::nincr_) / args [i].niter_; printf ("thread %lu performed %lu exchanges in %lu iterations " "(%lu%% increments)\n", args [i].threadno_, args [i].nxchg_, args [i].niter_, incrpcnt); } } // compute the expected result, "skipping" zeros by incrementing // expect twice when it overflows and wraps around to 0 (zero is // used as the lock variable in thread_routine() above) intT expect = intT (1); const unsigned long nincr = (Args::nthreads_ * Args::nincr_) / 2U; for (unsigned long i = 0; i != nincr; ++i) { if (intT () == ++expect) ++expect; } // verify that the final value of the variables shared among all // threads equals the number of increments performed by the threads rw_assert (Args::shared_ [0] == expect, 0, __LINE__, "1. %s (%s&, %2$s); %s == %s failed", fun, tname, TOSTR (Args::shared_ [0]), TOSTR (expect)); rw_assert (Args::shared_ [1] == expect, 0, __LINE__, "2. %s (%s&, %2$s); %s == %s failed", fun, tname, TOSTR (Args::shared_ [1]), TOSTR (expect)); #else // if !defined (_RWSTD_REENTRANT) _RWSTD_UNUSED (tag); #endif // _RWSTD_REENTRANT }