void test_tolower (charT*, const char *cname) { rw_info (0, 0, __LINE__, "UserCtype<%s>::tolower" "(char_type) const", cname); rw_warn (0, 0, __LINE__, "UserCtype<%s>::tolower" "(char_type) const not exercised", cname); rw_info (0, 0, __LINE__, "UserCtype<%s>::tolower" "(char_type*, const char_type) const", cname); rw_warn (0, 0, __LINE__, "UserCtype<%s>::tolower" "(char_type*, const char_type) const not exercised", cname); }
void test_widen (charT*, const char *cname) { rw_info (0, 0, __LINE__, "UserCtype<%s>::widen" "(char) const", cname); rw_warn (0, 0, __LINE__, "UserCtype<%s>::widen" "(char) const not exercised", cname); rw_info (0, 0, __LINE__, "UserCtype<%s>::widen" "(const char*, const char*, char_type*) const", cname); rw_warn (0, 0, __LINE__, "UserCtype<%s>::widen" "(const char*, const char*, char_type*) const not exercised", cname); }
static int run_test (int, char*[]) { const int new_0 = new_calls; const int delete_0 = delete_calls; do_test (char ()); const int new_1 = new_calls - new_0; const int delete_1 = delete_calls - delete_0; // verify that test doesn't leak any dynamically allocated storage rw_assert (0 == new_1 - delete_1, 0, __LINE__, "test leaked %d blocks of memory", new_1 - delete_1); rw_assert (0 == init_new_calls, 0, __LINE__, "iostream initialization called operator new() %d times, " "0 expected", init_new_calls); #ifdef _RWSTD_NO_REPLACEABLE_NEW_DELETE rw_warn (0, 0, __LINE__, "replacement operators new and delete not tested: " "_RWSTD_NO_REPLACEABLE_NEW_DELETE #defined"); #endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE return 0; }
static int run_test (int, char**) { #undef TEST #define TEST(T) test_op_assign ((const T*)0, #T) TEST (int); TEST (double); #if 0x04020100 >= _RWSTD_VER // test fails to compile with stdcxx 4.2.1 and prior due to // STDCXX-512: http://issues.apache.org/jira/browse/STDCXX-512 rw_warn (0, 0, __LINE__, "test of UserClass disabled in stdcxx 4.2.0 and prior " "due to STDCXX-512"); #else // stdcxx >= 4.2.1 TEST (UserClass); #endif // stdcxx version return 0; }
static int run_test (int, char*[]) { #if defined (_RWSTD_NO_EXT_CXX_0X) rw_warn (0, 0, __LINE__, "test disabled because _RWSTD_NO_EXT_CXX_0X is defined"); #elif defined (_RWSTD_NO_RVALUE_REFERENCES) rw_warn (0, 0, __LINE__, "test disabled because _RWSTD_NO_RVALUE_REFERENCES is " "defined"); #endif return 0; }
void test_narrow (charT*, const char *cname) { rw_info (0, 0, __LINE__, "UserCtype<%s>::narrow" "(char_type, char) const", cname); rw_warn (0, 0, __LINE__, "UserCtype<%s>::narrow" "(char_type, char) const not exercised", cname); rw_info (0, 0, __LINE__, "UserCtype<%s>::narrow" "(const char_type*, const char_type*, char, char*) const", cname); rw_warn (0, 0, __LINE__, "UserCtype<%s>::narrow" "(const char_type*, const char_type*, char, char*) const" " not exercised", cname); }
void test_scan_not (charT*, const char *cname) { rw_info (0, 0, __LINE__, "UserCtype<%s>::scan_not" "(mask, const char_type*, const char_type*) const", cname); rw_warn (0, 0, __LINE__, "UserCtype<%s>::scan_not" "(mask, const char_type*, const char_type*) const " "not exercised", cname); }
static int run_test (int /*unused*/, char* /*unused*/ []) { test_identity (); #if !defined _RWSTD_NO_RVALUE_REFERENCES test_forward (); test_move (); #else // no rvalue references rw_warn (0, 0, __LINE__, "No compiler support for rvalue references; tests disabled."); #endif // !defined _RWSTD_NO_RVALUE_REFERENCES return 0; }
static void test_wcodecvt () { rw_info (0, 0, 0, "std::codecvt<wchar_t, char, mbstate_t>::length " "(state_type&, const extern_type*, const extern_type*, " "size_t)"); #ifndef _RWSTD_NO_WCHAR_T const std::locale classic = std::locale::classic (); const WCodecvt &cvt = std::use_facet<WCodecvt>(classic); #undef TEST #define TEST(from, nchars, maxi, result) \ test_length (wchar_t (), __LINE__, 0, cvt, from, nchars, maxi, result) // +--------------- source sequence of externT characters // | +-------- size of sequence in externT characters // | | +----- maximum number of internT characters // | | | +-- expected result // | | | | // V V V V TEST (0, 0, 0, 0); TEST ("", 0, 0, 0); TEST ("a", 1, 0, 0); TEST ("ab", 2, 1, 1); TEST ("ab", 2, 2, 2); TEST ("ab", 2, 3, 2); TEST ("abc", 3, 0, 0); TEST ("abc", 3, 1, 1); TEST ("abc", 3, 2, 2); TEST ("abc", 3, 3, 3); TEST ("abc", 3, 4, 3); #else // if defined (_RWSTD_NO_WCHAR_T) rw_warn (0, 0, __LINE__, "_RWSTD_NO_WCHAR_T #defined, cannot test"); #endif // _RWSTD_NO_WCHAR_T }
void test_ldbl (CharT*, Traits*, const char *cname, const char *tname) { const char fmt[] = "%Lg"; const char fname[] = "long double"; info (cname, tname, fname); test_floating ((CharT*)0, (Traits*)0, (long double*)0, cname, tname, fname, fmt); #define TEST_LDBL(ss, fl, is, ex, ee, es, ne, fw, iv, ev) \ TEST (long double, fmt, ss, fl, is, ex, ee, es, ne, fw, iv, ev) LocaleData locale_data = { 0, -1, -1, 0, 0, 0 }; locale_data.whitespace = ""; TEST_LDBL ("", -1, -1, -1, 0, _ef, 0, 0, 1.0L, 1.0L); rw_warn (0, 0, __LINE__, "%{$CLASS}::operator>>(%s&) insufficiently exercised", fname); }
void test_failure (T*, const char *tname) { if (0 == tname) { static char buf [40]; rw_sprintf (buf, "char[%zu]", sizeof (T)); tname = buf; } rw_info (0, 0, __LINE__, "std::get_temporary_buffer<%s>(ptrdiff_t) on arithmetic overflow", tname); std::ptrdiff_t nelems = -1; std::pair<T*, std::ptrdiff_t> pa; pa = std::get_temporary_buffer<T>(nelems); rw_assert (0 == pa.first && 0 == pa.second, 0, __LINE__, "std::get_temporary_buffer<%s>(%td) == { 0, 0 }, " "got { %#p, %td }", tname, nelems, pa.first, pa.second); for (std::size_t i = 2; i && i < sizeof (T); i <<= 1) { // exercise arithmetic overflow (not to be confused // with the out-of-memory tests below) // attempts to allocate space for an array of elements // with a total size that exceeds SIZE_MAX must fail nelems = (_RWSTD_PTRDIFF_MAX / i) + 1; pa = std::get_temporary_buffer<T>(nelems); rw_assert (0 == pa.first && 0 == pa.second, 0, __LINE__, "get_temporary_buffer<%s>(%ld) == { 0, 0 }, " "got { %#p, %td }", tname, nelems, pa.first, pa.second); } #ifndef _RWSTD_NO_SETRLIMIT // exercise get_temporary_buffer in the presence of allocation // failure (caused by setting the soft data limit to the current // value) // retrieve the current soft (rlim_cur) and hard (rlim_max) limits struct rlimit rlim_old; if (getrlimit (RLIMIT_DATA, &rlim_old)) { rw_warn (0, 0, __LINE__, "getrlimit(RLIMIT_DATA, { .rlim_max=%zu, .rlim_cur=%zu}) " "failed: %{#m}: %m", rlim_old.rlim_max, rlim_old.rlim_cur); return; } // set the soft limit to 0, leaving the hard limit unchanged struct rlimit rlim_new = rlim_old; #ifdef _AIX { // AIX setrlimit() fails to lower the limit for resource // whose current usage is already higher than the new limit. // Instead of setting the limit to 0, compute the current // usage and use it to set the soft limit const char* const brk_min = (char*)_edata; const char* const brk_cur = (char*)sbrk (0); rlim_new.rlim_cur = brk_cur - brk_min; } #else // if !defined (_AIX) rlim_new.rlim_cur = 0; #endif // _AIX errno = 0; // IEEE Std 1003.1, 2004 Edition (SUSv3): // RLIMIT_DATA // ...is the maximum size of a process' data segment, in bytes. // If this limit is exceeded, the malloc() function shall fail // with errno set to [ENOMEM]. if (setrlimit (RLIMIT_DATA, &rlim_new)) { rw_warn (0, 0, __LINE__, "setrlimit(RLIMIT_DATA, { .rlim_max=%zu, .rlim_cur=%zu}) " "failed to lower the soft limit: %{#m}: %m", rlim_new.rlim_max, rlim_new.rlim_cur); return; } std::size_t nbytes = rlim_old.rlim_max; #if 0 < _RWSTD_TMPBUF_SIZE // make sure the size is larger than the size of the temp buff if (nbytes <= _RWSTD_TMPBUF_SIZE) nbytes = _RWSTD_TMPBUF_SIZE + 1; #else // if _RWSTD_TMPBUF_SIZE <= 0 nbytes = 65536; #endif // _RWSTD_TMPBUF_SIZE if (nbytes < _RWSTD_SIZE_MAX) ++nbytes; if (nbytes <= std::size_t (_RWSTD_PTRDIFF_MAX)) nelems = std::ptrdiff_t (nbytes); else nelems = _RWSTD_PTRDIFF_MAX; nelems /= sizeof (T); // retrieve the current limit just to show it in the info message // ignore any errors getrlimit (RLIMIT_DATA, &rlim_new); rw_info (0, 0, __LINE__, "std::get_temporary_buffer<%s>(%td) in low memory conditions " ": { .rlim_max = %zu, .rlim_cur = %zu }", tname, nelems, rlim_new.rlim_max, rlim_new.rlim_cur); // expect the function to fail pa = std::get_temporary_buffer<T>(nelems); // reset the soft limit to the original value (do it before any // test output in case memory needs to be allocated during the // output) if (setrlimit (RLIMIT_DATA, &rlim_old)) { rw_warn (0, 0, __LINE__, "setrlimit(RLIMIT_DATA, { .rlim_max=%zu, .rlim_cur=%zu }) " "failed to restore the soft limit: %{#m}: %m", rlim_old.rlim_max, rlim_old.rlim_cur); } rw_assert (0 == pa.first && 0 == pa.second, 0, __LINE__, "get_temporary_buffer<%s>(%td) == { 0, 0 } " "in low memory conditions, got { %#p, %td }", tname, nbytes, pa.first, pa.second); #endif // _RWSTD_NO_SETRLIMIT }
static int run_test (int, char**) { // find all installed locales for which setlocale(LC_ALL) succeeds const char* const locale_list = rw_opt_locales ? rw_opt_locales : rw_locales (_RWSTD_LC_ALL); // array of locale names to use for testing const char* locales [sizeof punct_data / sizeof *punct_data]; const std::size_t maxinx = sizeof locales / sizeof *locales; // iterate over locales, initializing a global punct_data array for (const char *name = locale_list; *name; name += std::strlen (name) +1) { std::locale loc; MoneypunctData* const pdata = punct_data + nlocales; pdata->locale_name_ = name; locales [nlocales] = name; try { loc = std::locale (name); typedef std::moneypunct<char, false> Punct; const Punct &mp = std::use_facet<Punct>(loc); const char dp = mp.decimal_point (); const char ts = mp.thousands_sep (); const std::string grp = mp.grouping (); const std::string cur = mp.curr_symbol (); const std::string pos = mp.positive_sign (); const std::string neg = mp.negative_sign (); const int fd = mp.frac_digits (); const Punct::pattern pfm = mp.pos_format (); const Punct::pattern nfm = mp.neg_format (); pdata->decimal_point_ = dp; pdata->thousands_sep_ = ts; pdata->frac_digits_ = fd; std::strcpy (pdata->grouping_, grp.c_str ()); std::strcpy (pdata->curr_symbol_, cur.c_str ()); std::strcpy (pdata->positive_sign_, pos.c_str ()); std::strcpy (pdata->negative_sign_, neg.c_str ()); std::memcpy (pdata->pos_format_, &pfm, sizeof pfm); std::memcpy (pdata->neg_format_, &nfm, sizeof nfm); } catch (...) { rw_warn (0, 0, __LINE__, "std::locale(%#s) threw an exception, skipping", name); continue; } try { typedef std::moneypunct<char, true> Punct; const Punct &mp = std::use_facet<Punct>(loc); const std::string cur = mp.curr_symbol (); const int fd = mp.frac_digits (); const Punct::pattern pfm = mp.pos_format (); const Punct::pattern nfm = mp.neg_format (); pdata->int_frac_digits_ = fd; std::strcpy (pdata->int_curr_symbol_, cur.c_str ()); std::memcpy (pdata->int_pos_format_, &pfm, sizeof pfm); std::memcpy (pdata->int_neg_format_, &nfm, sizeof nfm); } catch (...) { rw_warn (0, 0, __LINE__, "std::locale(%#s) threw an exception, skipping", name); continue; } #ifndef _RWSTD_NO_WCHAR_T try { typedef std::moneypunct<wchar_t, false> Punct; const Punct &mp = std::use_facet<Punct>(loc); const wchar_t dp = mp.decimal_point (); const wchar_t ts = mp.thousands_sep (); const std::wstring cur = mp.curr_symbol (); const std::wstring pos = mp.positive_sign (); const std::wstring neg = mp.negative_sign (); pdata->wdecimal_point_ = dp; pdata->wthousands_sep_ = ts; typedef std::wstring::traits_type Traits; Traits::copy (pdata->wcurr_symbol_, cur.data (), cur.size ()); Traits::copy (pdata->wpositive_sign_, pos.data (), pos.size ()); Traits::copy (pdata->wnegative_sign_, neg.data (), neg.size ()); } catch (...) { rw_warn (0, 0, __LINE__, "std::locale(%#s) threw an exception, skipping", name); continue; } try { typedef std::moneypunct<wchar_t, true> Punct; const Punct &mp = std::use_facet<Punct>(loc); const std::wstring cur = mp.curr_symbol (); const std::wstring pos = mp.positive_sign (); const std::wstring neg = mp.negative_sign (); typedef std::wstring::traits_type Traits; Traits::copy (pdata->wint_curr_symbol_, cur.data (), cur.size ()); } catch (...) { rw_warn (0, 0, __LINE__, "std::locale(%#s) threw an exception, skipping", name); continue; } #endif // _RWSTD_NO_WCHAR_T ++nlocales; if (nlocales == maxinx) break; } // unless the number of iterations was explicitly specified // on the command line, decrease the number to equal the number // of excericsed locales when only one thread is being tested if (1 == opt_nthreads && opt_nloops < 0) opt_nloops = int (nlocales); // when the number of iterations wasn't explicitly specified // on the command line set it to the default value if (opt_nloops < 0) opt_nloops = DFLT_LOOPS; rw_fatal (0 < nlocales, 0, __LINE__, "must have at least one valid locale to test"); rw_info (0, 0, 0, "testing std::moneypunct<charT> with %d thread%{?}s%{;}, " "%d iteration%{?}s%{;} each, in %zu locales { %{ .*A@} }", opt_nthreads, 1 != opt_nthreads, opt_nloops, 1 != opt_nloops, nlocales, int (nlocales), "%#s", locales); rw_info (0, 0, 0, "exercising std::moneypunct<char>"); test_char = true; test_wchar = false; // create and start a pool of threads and wait for them to finish int result = rw_thread_pool (0, std::size_t (opt_nthreads), 0, thread_func, 0, std::size_t (opt_timeout)); rw_error (result == 0, 0, __LINE__, "rw_thread_pool(0, %d, 0, %{#f}, 0) failed", opt_nthreads, thread_func); #ifndef _RWSTD_NO_WCHAR_T rw_info (0, 0, 0, "exercising std::moneypunct<wchar_t>"); test_char = false; test_wchar = true; // start a pool of threads to exercise the thread safety // of the wchar_t specialization result = rw_thread_pool (0, std::size_t (opt_nthreads), 0, thread_func, 0, std::size_t (opt_timeout)); rw_error (result == 0, 0, __LINE__, "rw_thread_pool(0, %d, 0, %{#f}, 0) failed", opt_nthreads, thread_func); // exercise both the char and the wchar_t specializations // at the same time rw_info (0, 0, 0, "exercising both std::moneypunct<char> " "and std::moneypunct<wchar_t>"); test_char = true; test_wchar = true; // start a pool of threads to exercise wstring thread safety result = rw_thread_pool (0, std::size_t (opt_nthreads), 0, thread_func, 0, std::size_t (opt_timeout)); rw_error (result == 0, 0, __LINE__, "rw_thread_pool(0, %d, 0, %{#f}, 0) failed", opt_nthreads, thread_func); #endif // _RWSTD_NO_WCHAR_T return result; }
static int run_test (int, char**) { MyIos<char, std::char_traits<char> > nio; MyStreambuf<char, std::char_traits<char> > nsb; nio.rdbuf (&nsb); #ifndef _RWSTD_NO_WCHAR_T MyIos<wchar_t, std::char_traits<wchar_t> > wio; MyStreambuf<wchar_t, std::char_traits<wchar_t> > wsb; wio.rdbuf (&wsb); #endif // _RWSTD_NO_WCHAR_T // find all installed locales for which setlocale(LC_ALL) succeeds const char* const locale_list = rw_opt_locales ? rw_opt_locales : rw_locales (_RWSTD_LC_ALL); const std::size_t maxinx = RW_COUNT_OF (locales); for (const char *name = locale_list; *name; name += std::strlen (name) + 1) { const std::size_t inx = nlocales; locales [inx] = name; // fill in the value and results for this locale MyNumData& data = my_num_data [nlocales]; data.locale_name_ = name; try { const std::locale loc (data.locale_name_); data.value_ = nlocales & 1 ? -1 * nlocales : nlocales; data.type_ = MyNumData::PutId (nlocales % MyNumData::put_max); // format data into buffers const std::num_put<char> &np = std::use_facet<std::num_put<char> >(loc); nio.imbue (loc); nsb.pubsetp (data.ncs_, RW_COUNT_OF (data.ncs_)); put_data (data, np, std::ostreambuf_iterator<char>(&nsb), nio, ' ', '\0'); rw_fatal (!nio.fail (), __FILE__, __LINE__, "num_put<char>::put(...) failed for locale(%#s)", data.locale_name_); #ifndef _RWSTD_NO_WCHAR_T const std::num_put<wchar_t> &wp = std::use_facet<std::num_put<wchar_t> >(loc); wio.imbue (loc); wsb.pubsetp (data.wcs_, RW_COUNT_OF (data.wcs_)); put_data (data, wp, std::ostreambuf_iterator<wchar_t>(&wsb), wio, L' ', L'\0'); rw_fatal (!wio.fail (), __FILE__, __LINE__, "num_put<wchar_t>::put(...) failed for locale(%#s)", data.locale_name_); #endif // _RWSTD_NO_WCHAR_T if (opt_shared_locale) data.locale_ = loc; nlocales += 1; } catch (...) { rw_warn (!rw_opt_locales, 0, __LINE__, "failed to create locale(%#s)", name); } if (nlocales == maxinx || nlocales == std::size_t (opt_nlocales)) break; } // avoid divide by zero in thread if there are no locales to test rw_fatal (nlocales != 0, 0, __LINE__, "failed to create one or more usable locales!"); rw_info (0, 0, 0, "testing std::num_put<charT> with %d thread%{?}s%{;}, " "%d iteration%{?}s%{;} each, in %zu locales { %{ .*A@} }", opt_nthreads, 1 != opt_nthreads, opt_nloops, 1 != opt_nloops, nlocales, int (nlocales), "%#s", locales); rw_info (0, 0, 0, "exercising std::num_put<char>"); test_char = true; test_wchar = false; // create and start a pool of threads and wait for them to finish int result = rw_thread_pool (0, std::size_t (opt_nthreads), 0, thread_func, 0); rw_error (result == 0, 0, __LINE__, "rw_thread_pool(0, %d, 0, %{#f}, 0) failed", opt_nthreads, thread_func); #ifndef _RWSTD_NO_WCHAR_T rw_info (0, 0, 0, "exercising std::num_put<wchar_t>"); test_char = false; test_wchar = true; // start a pool of threads to exercise wstring thread safety result = rw_thread_pool (0, std::size_t (opt_nthreads), 0, thread_func, 0); rw_error (result == 0, 0, __LINE__, "rw_thread_pool(0, %d, 0, %{#f}, 0) failed", opt_nthreads, thread_func); // exercise both the char and the wchar_t specializations // at the same time rw_info (0, 0, 0, "exercising both std::num_put<char> and std::num_put<wchar_t>"); test_char = true; test_wchar = true; // start a pool of threads to exercise wstring thread safety result = rw_thread_pool (0, std::size_t (opt_nthreads), 0, thread_func, 0); rw_error (result == 0, 0, __LINE__, "rw_thread_pool(0, %d, 0, %{#f}, 0) failed", opt_nthreads, thread_func); #endif // _RWSTD_NO_WCHAR_T return result; }
_TEST_EXPORT rw_pid_t rw_waitpid (rw_pid_t pid, int* presult, int timeout/* = -1*/) { #ifdef _RWSTD_EDG_ECCP # define _RWSTD_NO_SIGACTION #endif #ifndef _RWSTD_NO_SIGACTION struct sigaction prev_alarm_action; #else signal_handler_t prev_alarm_handler = 0; #endif int prev_alarm_timeout = 0; alarm_timeout = 0; if (0 < timeout) { #ifndef _RWSTD_NO_SIGACTION struct sigaction alarm_action; memset (&alarm_action, 0, sizeof alarm_action); const signal_handler_t handler_fun = handle_alarm_signal; memcpy (&alarm_action.sa_handler, &handler_fun, sizeof alarm_action.sa_handler); sigaction (SIGALRM, &alarm_action, &prev_alarm_action); #else prev_alarm_handler = signal (SIGALRM, handle_alarm_signal); #endif prev_alarm_timeout = alarm (timeout); } int result = 0; if (!presult) presult = &result; const time_t start = time(0); int status = 0; rw_pid_t ret = 0; do { ret = waitpid (pid, &status, 0); if (-1 == ret) { if (EINTR == errno && alarm_timeout) { // we are expected to return 0 on timeout ret = 0; } else if (EINTR == errno) { rw_warn (0, __FILE__, __LINE__, "waitpid (%{P}, %#p, 0) interrupted: " "errno = %{#m} (%{m})", pid, &status); continue; // try again } else { rw_error (0, __FILE__, __LINE__, "waitpid (%{P}, %#p, 0) failed: " "errno = %{#m} (%{m})", pid, &status); } } else if (ret == pid) { if (WIFSIGNALED (status)) { // process exited with a signal const int signo = WTERMSIG (status); rw_error (0, __FILE__, __LINE__, "the process (pid=%{P}) exited with signal %d (%{K})", pid, signo, signo); *presult = signo; } else if (WIFEXITED (status)) { // process exited with a status const int retcode = WEXITSTATUS (status); if (retcode) rw_error (0, __FILE__, __LINE__, "the process (pid=%{P}) exited with return code %d", pid, retcode); *presult = retcode; } else { *presult = -1; } } else { *presult = -1; } } while(false); if (0 < timeout) { if (prev_alarm_timeout) { const int delta = time(0) - start; if (delta < prev_alarm_timeout) prev_alarm_timeout -= delta; else prev_alarm_timeout = 1; } alarm (prev_alarm_timeout); #ifndef _RWSTD_NO_SIGACTION sigaction (SIGALRM, &prev_alarm_action, 0); #else signal (SIGALRM, prev_alarm_handler); #endif } return ret; }
static int run_test (int, char**) { for (std::size_t i = 0; i != opt_nfacets; ++i) { if (0 < opt_facets [i]) { for (std::size_t j = 0; j != opt_nfacets; ++j) { if (opt_facets [j] == 0) opt_facets [j] = -1; } break; } } rw_note (0 <= opt_facets [opt_inx_codecvt], 0, __LINE__, "std::codecvt tests disabled"); rw_note (0 <= opt_facets [opt_inx_collate], 0, __LINE__, "std::collate tests disabled"); rw_note (0 <= opt_facets [opt_inx_ctype], 0, __LINE__, "std::ctype tests disabled"); rw_note (0 <= opt_facets [opt_inx_messages], 0, __LINE__, "std::messages tests disabled"); rw_note (0 <= opt_facets [opt_inx_moneypunct], 0, __LINE__, "std::moneypunct<charT, false> tests disabled"); rw_note (0 <= opt_facets [opt_inx_moneypunct_intl], 0, __LINE__, "std::moneypunct<charT, true> tests disabled"); rw_note (0 <= opt_facets [opt_inx_money_get], 0, __LINE__, "std::money_get tests disabled"); rw_note (0 <= opt_facets [opt_inx_money_put], 0, __LINE__, "std::money_put tests disabled"); rw_note (0 <= opt_facets [opt_inx_numpunct], 0, __LINE__, "std::numpunct tests disabled"); rw_note (0 <= opt_facets [opt_inx_num_get], 0, __LINE__, "std::num_get tests disabled"); rw_note (0 <= opt_facets [opt_inx_num_put], 0, __LINE__, "std::num_put tests disabled"); rw_note (0 <= opt_facets [opt_inx_time_get], 0, __LINE__, "std::time_get tests disabled"); rw_note (0 <= opt_facets [opt_inx_time_put], 0, __LINE__, "std::time_put tests disabled"); rw_note (0 == opt_no_exceptions, 0, __LINE__, "tests involving exceptions disabled"); // find all installed locales for which setlocale(LC_ALL) succeeds const char* const locale_list = rw_opt_locales ? rw_opt_locales : rw_locales (_RWSTD_LC_ALL); const std::size_t maxinx = sizeof locales / sizeof *locales; // set to true if the classic "C" locale is on the lost bool has_classic = false; for (const char *name = locale_list; *name; name += std::strlen (name) +1) { locales [nlocales++] = name; if (!has_classic && 0 == std::strcmp ("C", name)) has_classic = true; if (nlocales == maxinx) break; } // when the classic "C" locale isn't on the list put it there // unless the list was explicitly specified on the command line if (1 < nlocales && !has_classic && 0 == rw_opt_locales) locales [0] = "C"; int result; rw_info (0, 0, 0, "testing std::locale globals with %d thread%{?}s%{;}, " "%d iteration%{?}s%{;} each, in %zu locales { %{ .*A@} }", opt_nthreads, 1 != opt_nthreads, opt_nloops, 1 != opt_nloops, nlocales, int (nlocales), "%#s", locales); if (opt_has_facet >= 0) { rw_info (0, 0, 0, "template <class T> bool std::has_facet (const locale&)"); // create and start a pool of threads and wait for them to finish result = rw_thread_pool (0, std::size_t (opt_nthreads), 0, test_has_facet, 0); rw_error (result == 0, 0, __LINE__, "rw_thread_pool(0, %d, 0, %{#f}, 0) failed", opt_nthreads, test_has_facet); } else { rw_note (0, 0, 0, "std::has_facet test disabled"); } if (opt_use_facet >= 0) { rw_info (0, 0, 0, "template <class T> const T& std::use_facet (const locale&)"); #ifdef _RWSTD_NO_DYNAMIC_CAST // if dynamic_cast isn't supported, then [has,use]_facet() // can't reliably detect if a facet is installed or not. rw_warn (0 != opt_no_exceptions, 0, __LINE__, "dynamic_cast not supported " "(macro _RWSTD_NO_DYNAMIC_CAST is #defined), " "disabling exceptions tests"); opt_no_exceptions = 1; #endif // _RWSTD_NO_DYNAMIC_CAST #ifdef _RWSTD_NO_THREAD_SAFE_EXCEPTIONS // avoid exercising exceptions (triggered by use_facet) if // their implementation in the runtime isn't thread-safe rw_warn (0, 0, 0, "exceptions not thread safe (macro " "_RWSTD_NO_THREAD_SAFE_EXCEPTIONS is #defined), " "disabling exceptions tests"); opt_no_exceptions = 1; #endif // _RWSTD_NO_THREAD_SAFE_EXCEPTIONS // create and start a pool of threads and wait for them to finish result = rw_thread_pool (0, std::size_t (opt_nthreads), 0, test_use_facet, 0); rw_error (result == 0, 0, __LINE__, "rw_thread_pool(0, %d, 0, %{#f}, 0) failed", opt_nthreads, test_use_facet); } else { rw_note (0, 0, 0, "std::use_facet test disabled"); } return result; }
static void test_is_base_of () { TEST (std::is_base_of, bool, bool, false); TEST (std::is_base_of, char, char, false); TEST (std::is_base_of, short, short, false); TEST (std::is_base_of, int, int, false); TEST (std::is_base_of, long, long, false); TEST (std::is_base_of, float, float, false); TEST (std::is_base_of, double, double, false); TEST (std::is_base_of, enum_A, enum_A, false); TEST (std::is_base_of, enum_B, enum_B, false); TEST (std::is_base_of, struct_A, struct_A, true); TEST (std::is_base_of, derived_t<struct_A>, derived_t<struct_A>, true); TEST (std::is_base_of, class_B, class_B, true); TEST (std::is_base_of, derived_t<class_B>, derived_t<class_B>, true); #if defined (_RWSTD_TT_IS_BASE_OF) \ || defined (_RWSTD_TT_IS_CLASS) \ || defined (_RWSTD_TT_IS_UNION) // without one of the above, we can't reliably implement // this trait for union type TEST (std::is_base_of, union_C, union_C, false); #else rw_warn (0, 0, __LINE__, "portions of test_is_base_of() have been disabled due " "to lack of compiler support."); #endif // public inheritance TEST (std::is_base_of, struct_A, derived_t<struct_A>, true); TEST (std::is_base_of, class_B, derived_t<class_B>, true); #if defined (__SUNPRO_CC) && (__SUNPRO_CC <= 0x590) // for some reason the trick used to detect private and protected // inheritance doesn't work on sunpro-5.9 rw_warn (0, 0, __LINE__, "unable to detect private or protected base classes."); #else // protected inheritance TEST (std::is_base_of, struct_A, derived_protected_t<struct_A>, true); // private inheritance TEST (std::is_base_of, struct_A, derived_private_t<struct_A>, true); #endif // cv-qualified TEST (std::is_base_of, const struct_A, struct_A, true); TEST (std::is_base_of, struct_A, const struct_A, true); TEST (std::is_base_of, volatile struct_A, struct_A, true); TEST (std::is_base_of, struct_A, volatile struct_A, true); TEST (std::is_base_of, const volatile struct_A, struct_A, true); TEST (std::is_base_of, struct_A, const volatile struct_A, true); TEST (std::is_base_of, const struct_A, derived_t<struct_A>, true); TEST (std::is_base_of, struct_A, const derived_t<struct_A>, true); TEST (std::is_base_of, volatile struct_A, derived_t<struct_A>, true); TEST (std::is_base_of, struct_A, volatile derived_t<struct_A>, true); TEST (std::is_base_of, const volatile struct_A, derived_t<struct_A>, true); TEST (std::is_base_of, struct_A, const volatile derived_t<struct_A>, true); // other combinations should fail TEST (std::is_base_of, signed char, char, false); TEST (std::is_base_of, char, signed char, false); TEST (std::is_base_of, unsigned char, char, false); TEST (std::is_base_of, char, unsigned char, false); TEST (std::is_base_of, signed char, unsigned char, false); TEST (std::is_base_of, unsigned char, signed char, false); TEST (std::is_base_of, signed short, unsigned short, false); TEST (std::is_base_of, unsigned short, signed short, false); TEST (std::is_base_of, signed int, unsigned int, false); TEST (std::is_base_of, unsigned int, signed int, false); TEST (std::is_base_of, signed long, unsigned long, false); TEST (std::is_base_of, unsigned long, signed long, false); TEST (std::is_base_of, enum_A, char, false); TEST (std::is_base_of, enum_A, short, false); TEST (std::is_base_of, enum_A, int, false); TEST (std::is_base_of, enum_A, long, false); TEST (std::is_base_of, enum_A, unsigned char, false); TEST (std::is_base_of, enum_A, unsigned short, false); TEST (std::is_base_of, enum_A, unsigned int, false); TEST (std::is_base_of, enum_A, unsigned long, false); TEST (std::is_base_of, int[], int*, false); TEST (std::is_base_of, int*, int[], false); TEST (std::is_base_of, struct_A, class_B, false); TEST (std::is_base_of, class_B, struct_A, false); TEST (std::is_base_of, derived_t<struct_A>, struct_A, false); TEST (std::is_base_of, derived_t<class_B>, class_B, false); }
static int run_test (int, char**) { // find all installed locales for which setlocale(LC_ALL) succeeds const char* const locale_list = rw_opt_locales ? rw_opt_locales : rw_locales (_RWSTD_LC_ALL); const std::size_t maxinx = sizeof punct_data / sizeof *punct_data; // iterate over locales, initializing a global punct_data array for (const char *name = locale_list; *name; name += std::strlen (name) +1) { const std::size_t inx = nlocales; locales [inx] = name; NumPunctData& data = punct_data [inx]; try { std::locale loc(name); data.locale_name_ = name; const std::numpunct<char> &np = std::use_facet<std::numpunct<char> >(loc); data.grouping_ = np.grouping (); data.decimal_point_ = np.decimal_point (); data.thousands_sep_ = np.thousands_sep (); data.truename_ = np.truename (); data.falsename_ = np.falsename (); #ifndef _RWSTD_NO_WCHAR_T const std::numpunct<wchar_t> &wp = std::use_facet<std::numpunct<wchar_t> >(loc); data.wdecimal_point_ = wp.decimal_point (); data.wthousands_sep_ = wp.thousands_sep (); data.wtruename_ = wp.truename (); data.wfalsename_ = wp.falsename (); #endif if (opt_shared_locale) data.locale_ = loc; nlocales += 1; } catch (...) { rw_warn (!rw_opt_locales, 0, __LINE__, "failed to create locale(%#s)", name); } if (nlocales == maxinx || nlocales == std::size_t (opt_nlocales)) break; } // avoid divide by zero in thread if there are no locales to test rw_fatal (nlocales != 0, 0, __LINE__, "failed to create one or more usable locales!"); rw_info (0, 0, 0, "testing std::numpunct<charT> with %d thread%{?}s%{;}, " "%d iteration%{?}s%{;} each, in %zu locales { %{ .*A@} }", opt_nthreads, 1 != opt_nthreads, opt_nloops, 1 != opt_nloops, nlocales, int (nlocales), "%#s", locales); rw_info (0, 0, 0, "exercising std::numpunct<char>"); test_char = true; test_wchar = false; // create and start a pool of threads and wait for them to finish int result = rw_thread_pool (0, std::size_t (opt_nthreads), 0, thread_func, 0, std::size_t (opt_timeout)); rw_error (result == 0, 0, __LINE__, "rw_thread_pool(0, %d, 0, %{#f}, 0) failed", opt_nthreads, thread_func); #ifndef _RWSTD_NO_WCHAR_T rw_info (0, 0, 0, "exercising std::numpunct<wchar_t>"); test_char = false; test_wchar = true; // start a pool of threads to exercise the thread safety // of the wchar_t specialization result = rw_thread_pool (0, std::size_t (opt_nthreads), 0, thread_func, 0, std::size_t (opt_timeout)); rw_error (result == 0, 0, __LINE__, "rw_thread_pool(0, %d, 0, %{#f}, 0) failed", opt_nthreads, thread_func); // exercise both the char and the wchar_t specializations // at the same time rw_info (0, 0, 0, "exercising both std::numpunct<char> and std::numpunct<wchar_t>"); test_char = true; test_wchar = true; // start a pool of threads to exercise wstring thread safety result = rw_thread_pool (0, std::size_t (opt_nthreads), 0, thread_func, 0, std::size_t (opt_timeout)); rw_error (result == 0, 0, __LINE__, "rw_thread_pool(0, %d, 0, %{#f}, 0) failed", opt_nthreads, thread_func); #endif // _RWSTD_NO_WCHAR_T return result; }
static int run_test (int, char*[]) { rw_warn (0, 0, __LINE__, "test disabled because _RWSTD_NO_EXT_CXX_0X is defined"); return 0; }
static int run_test (int, char**) { MyIos<char, std::char_traits<char> > nio; MyStreambuf<char, std::char_traits<char> > nsb; nio.rdbuf (&nsb); #ifndef _RWSTD_NO_WCHAR_T MyIos<wchar_t, std::char_traits<wchar_t> > wio; MyStreambuf<wchar_t, std::char_traits<wchar_t> > wsb; wio.rdbuf (&wsb); #endif // _RWSTD_NO_WCHAR_T // find all installed locales for which setlocale (LC_ALL) succeeds const char* const locale_list = rw_opt_locales ? rw_opt_locales : rw_locales (_RWSTD_LC_ALL); const std::size_t maxinx = RW_COUNT_OF (locales); for (const char* name = locale_list; *name; name += std::strlen (name) + 1) { const std::size_t inx = nlocales; locales [inx] = name; // fill in the money and results for this locale MyMoneyData& data = my_money_data [inx]; data.locale_name_ = name; try { const std::locale loc (data.locale_name_); // initialize with random but valid values data.money_value_ = inx; data.type_ = MyMoneyData::PutId (nlocales % MyMoneyData::put_max); data.money_index_ = inx % RW_COUNT_OF (n_money_vals); // exercise domestic formats every other iteration // and international formats the rest data.intl_ = 0 == (inx & 1); // exercise postive and negative values if (inx & 1) data.money_value_ *= -1.; // add some random fractional digits if (inx & 2) data.money_value_ += data.money_value_ / 3.14; const std::money_put<char> &np = std::use_facet<std::money_put<char> >(loc); nio.imbue (loc); nsb.pubsetp (data.ncs_, RW_COUNT_OF (data.ncs_)); switch (data.type_) { case MyMoneyData::put_ldbl: *np.put (std::ostreambuf_iterator<char>(&nsb), data.intl_, nio, ' ', data.money_value_) = '\0'; break; case MyMoneyData::put_string: *np.put (std::ostreambuf_iterator<char>(&nsb), data.intl_, nio, ' ', n_money_vals [data.money_index_]) = '\0'; break; case MyMoneyData::put_max: // avoid enumeration value `put_max' not handled in switch // this case should never happen break; } rw_assert (!nio.fail (), __FILE__, __LINE__, "money_put<char>::put(...) " "failed for locale(%#s)", data.locale_name_); #ifndef _RWSTD_NO_WCHAR_T const std::money_put<wchar_t> &wp = std::use_facet<std::money_put<wchar_t> >(loc); wio.imbue (loc); wsb.pubsetp (data.wcs_, RW_COUNT_OF (data.wcs_)); switch (data.type_) { case MyMoneyData::put_ldbl: *wp.put (std::ostreambuf_iterator<wchar_t>(&wsb), data.intl_, wio, L' ', data.money_value_) = '\0'; break; case MyMoneyData::put_string: *wp.put (std::ostreambuf_iterator<wchar_t>(&wsb), data.intl_, wio, L' ', w_money_vals [data.money_index_]) = L'\0'; break; case MyMoneyData::put_max: // avoid enumeration value `put_max' not handled in switch // this case should never happen break; } rw_assert (!nio.fail (), __FILE__, __LINE__, "money_put<wchar_t>::put(...) " "failed for locale(%#s)", data.locale_name_); #endif // _RWSTD_NO_WCHAR_T if (opt_shared_locale) data.locale_ = loc; nlocales += 1; } catch (...) { rw_warn (!rw_opt_locales, 0, __LINE__, "failed to create locale(%#s)", name); } if (nlocales == maxinx || nlocales == std::size_t (opt_nlocales)) break; } // avoid divide by zero in thread if there are no locales to test rw_fatal (nlocales != 0, 0, __LINE__, "failed to create one or more usable locales!"); rw_info (0, 0, 0, "testing std::money_put<charT> with %d thread%{?}s%{;}, " "%d iteration%{?}s%{;} each, in %zu locales { %{ .*A@} }", opt_nthreads, 1 != opt_nthreads, opt_nloops, 1 != opt_nloops, nlocales, int (nlocales), "%#s", locales); rw_info (0, 0, 0, "exercising std::money_put<char>"); test_char = true; test_wchar = false; // create and start a pool of threads and wait for them to finish int result = rw_thread_pool (0, std::size_t (opt_nthreads), 0, thread_func, 0, std::size_t (opt_timeout)); rw_error (result == 0, 0, __LINE__, "rw_thread_pool(0, %d, 0, %{#f}, 0) failed", opt_nthreads, thread_func); #ifndef _RWSTD_NO_WCHAR_T rw_info (0, 0, 0, "exercising std::money_put<wchar_t>"); test_char = false; test_wchar = true; // start a pool of threads to exercise wstring thread safety result = rw_thread_pool (0, std::size_t (opt_nthreads), 0, thread_func, 0, std::size_t (opt_timeout)); rw_error (result == 0, 0, __LINE__, "rw_thread_pool(0, %d, 0, %{#f}, 0) failed", opt_nthreads, thread_func); // exercise both the char and the wchar_t specializations // at the same time rw_info (0, 0, 0, "exercising both std::money_put<char> " "and std::money_put<wchar_t>"); test_char = true; test_wchar = true; // start a pool of threads to exercise wstring thread safety result = rw_thread_pool (0, std::size_t (opt_nthreads), 0, thread_func, 0, std::size_t (opt_timeout)); rw_error (result == 0, 0, __LINE__, "rw_thread_pool(0, %d, 0, %{#f}, 0) failed", opt_nthreads, thread_func); #endif // _RWSTD_NO_WCHAR_T return result; }
static int run_test (int, char**) { test_get_temporary_buffer ((char*)0, "char"); test_get_temporary_buffer ((int*)0, "int"); #ifdef _RWSTD_LONG_LONG test_get_temporary_buffer ((_RWSTD_LONG_LONG*)0, "long long"); #else // if !defined (_RWSTD_LONG_LONG) test_get_temporary_buffer ((long*)0, "long"); #endif // _RWSTD_LONG_LONG #ifndef _RWSTD_NO_LONG_DOUBLE test_get_temporary_buffer ((long double*)0, "long double"); #else // if defined (_RWSTD_NO_LONG_DOUBLE) test_get_temporary_buffer ((double*)0, "double"); #endif // _RWSTD_NO_LONG_DOUBLE // exercise ordinary pointers test_get_temporary_buffer ((void**)0, "void*"); // exercise function pointers test_get_temporary_buffer ((FunctionPointer*)0, "void (*)()"); // exercise pointers to members test_get_temporary_buffer ((MemberPointer*)0, "void (struct::*)()"); #if (!defined (__IBMCPP__) || __IBMCPP__ > 700) \ && !defined (__HP_aCC) # ifndef _MSC_VER const std::size_t MAX_SIZE = _RWSTD_PTRDIFF_MAX; # else // the MSVC and ICC/Windows has maximum size of // the array equal to 0x7fffffff bytes const std::size_t MAX_SIZE = INT_MAX; # endif // avoid instantiating test on very large structs // to prevent failures (at compile or run-time) due // to compiler bugs test_failure ((BigStruct<MAX_SIZE / 2>*)0, 0); test_failure ((BigStruct<MAX_SIZE - 1>*)0, 0); test_failure ((BigStruct<MAX_SIZE>*)0, 0); #else // work around VAC++ 7.0 (and prior) bug #549 // work around HP aCC 3,5,6 bug #565 rw_warn (0, 0, __LINE__, "get_temp_buffer<large-struct>() " "not tested due to a compiler bug"); #endif // VAC++ > 7.0 return 0; }