first commit
This commit is contained in:
108
extern/stdcxx/4.2.1/tests/support/18.csetjmp.cpp
vendored
Normal file
108
extern/stdcxx/4.2.1/tests/support/18.csetjmp.cpp
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 18.csetjmp.cpp - test exercising [support.runtime], header <csetjmp>
|
||||
*
|
||||
* $Id: 18.csetjmp.cpp 593007 2007-11-08 04:30:45Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* 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 2007 Rogue Wave Software, Inc.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <csetjmp>
|
||||
#include <driver.h>
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
std::jmp_buf env;
|
||||
|
||||
void test_longjmp (int arg)
|
||||
{
|
||||
std::longjmp (env, arg);
|
||||
|
||||
rw_assert (0, 0, __LINE__,
|
||||
"call to std::longjmp(..., %d) returned", arg);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static int
|
||||
run_test (int, char**)
|
||||
{
|
||||
#ifdef longjmp
|
||||
|
||||
// longjmp must not be #defined as a macro
|
||||
rw_assert (0, 0, __LINE__, "longjmp #defined as a macro");
|
||||
|
||||
#endif // longjmp
|
||||
|
||||
#ifdef jmp_buf
|
||||
|
||||
//jmp_buf must not be #defined as a macro
|
||||
rw_assert (0, 0, __LINE__, "jmp_buf #defined as a macro");
|
||||
|
||||
#endif // jmp_buf
|
||||
|
||||
#ifndef setjmp
|
||||
|
||||
//setjmp must be #defined as a macro
|
||||
rw_assert (0, 0, __LINE__, "macro setjmp not #defined");
|
||||
|
||||
#endif // setjmp
|
||||
|
||||
// verify that setjmp works
|
||||
// using volatile to work around a gcc optimizer bug:
|
||||
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34024
|
||||
volatile int arg = 1;
|
||||
int result;
|
||||
|
||||
result = setjmp (env);
|
||||
|
||||
if (0 == result) {
|
||||
|
||||
test_longjmp (arg);
|
||||
|
||||
rw_assert (0, 0, __LINE__,
|
||||
"call to std::longjmp(..., %d) returned", arg);
|
||||
}
|
||||
else {
|
||||
rw_assert (arg == result, 0, __LINE__,
|
||||
"std::longjmp(..., %d) returned %d from setjmp()",
|
||||
arg, result);
|
||||
|
||||
// repeat a couple more times
|
||||
if (arg < 3)
|
||||
test_longjmp (++arg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
return rw_test (argc, argv, __FILE__,
|
||||
"support.runtime",
|
||||
"header <csetjmp>",
|
||||
run_test,
|
||||
"",
|
||||
(void*)0);
|
||||
}
|
||||
1075
extern/stdcxx/4.2.1/tests/support/18.exception.cpp
vendored
Normal file
1075
extern/stdcxx/4.2.1/tests/support/18.exception.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
204
extern/stdcxx/4.2.1/tests/support/18.limits.cvqual.cpp
vendored
Normal file
204
extern/stdcxx/4.2.1/tests/support/18.limits.cvqual.cpp
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 18.limits.cvqual.cpp:
|
||||
*
|
||||
* Test exercising lib.numeric.limits, numeric_limits specializations
|
||||
* on cv-qualified scalar types. See DR 559 for details:
|
||||
* http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#559
|
||||
*
|
||||
* $Id: 18.limits.cvqual.cpp 580483 2007-09-28 20:55:52Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* 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 2006-2007 Rogue Wave Software, Inc.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <limits>
|
||||
#include <driver.h>
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
template <class T>
|
||||
struct UserType
|
||||
{
|
||||
const T val_;
|
||||
|
||||
UserType (T val = T ()): val_ (val) { /* empty */}
|
||||
|
||||
operator T () const { return val_; }
|
||||
};
|
||||
|
||||
|
||||
template <class T, class CVQualifiedT>
|
||||
void test_limits (const volatile T*, CVQualifiedT*,
|
||||
const char *tname,
|
||||
const char *quals)
|
||||
{
|
||||
#ifndef _RWSTD_NO_EXT_CV_QUALIFIED_LIMITS
|
||||
|
||||
typedef std::numeric_limits<T> limits;
|
||||
typedef std::numeric_limits<CVQualifiedT> cv_limits;
|
||||
|
||||
// verify that the member has the same value as the same member
|
||||
// of a specialization of numeric_limits on the cv-qualified T
|
||||
# define TEST(member) \
|
||||
rw_assert (limits::member == cv_limits::member, 0, __LINE__, \
|
||||
"numeric_limits<%s>::%s == numeric_limits<%s %1$s>::%2$s", \
|
||||
tname, #member, quals)
|
||||
#else // if defined (_RWSTD_NO_EXT_CV_QUALIFIED_LIMITS)
|
||||
|
||||
typedef std::numeric_limits<UserType<T> > limits;
|
||||
typedef std::numeric_limits<CVQualifiedT> cv_limits;
|
||||
|
||||
// verify that the member has the same value as the same member
|
||||
// of a specialization of numeric_limits on some user-defined T
|
||||
// (i.e., the primary template)
|
||||
# define TEST(member) \
|
||||
rw_assert (limits::member == cv_limits::member, 0, __LINE__, \
|
||||
"numeric_limits<%s>::%s == numeric_limits<%s %1$s>::%2$s", \
|
||||
tname, #member, quals)
|
||||
#endif // _RWSTD_NO_EXT_CV_QUALIFIED_LIMITS
|
||||
|
||||
TEST (is_specialized);
|
||||
TEST (min ());
|
||||
TEST (max ());
|
||||
TEST (digits);
|
||||
TEST (digits10);
|
||||
TEST (is_signed);
|
||||
TEST (is_integer);
|
||||
TEST (is_exact);
|
||||
TEST (radix);
|
||||
|
||||
TEST (epsilon ());
|
||||
TEST (round_error ());
|
||||
|
||||
TEST (min_exponent);
|
||||
TEST (min_exponent10);
|
||||
TEST (max_exponent);
|
||||
TEST (max_exponent10);
|
||||
|
||||
TEST (has_infinity);
|
||||
TEST (has_quiet_NaN);
|
||||
TEST (has_signaling_NaN);
|
||||
TEST (has_denorm);
|
||||
TEST (has_denorm_loss);
|
||||
|
||||
TEST (infinity ());
|
||||
|
||||
if (limits::is_integer) {
|
||||
TEST (quiet_NaN ());
|
||||
TEST (signaling_NaN ());
|
||||
}
|
||||
else {
|
||||
const bool expect = limits::has_quiet_NaN;
|
||||
|
||||
rw_assert (expect == (limits::quiet_NaN () != cv_limits::quiet_NaN ()),
|
||||
0, __LINE__,
|
||||
"numeric_limits<%s>::qNaN() %{?}!=%{:}==%{;} "
|
||||
"numeric_limits<%s %1$s>::qNaN ()",
|
||||
tname, expect, quals);
|
||||
}
|
||||
|
||||
TEST (denorm_min ());
|
||||
|
||||
TEST (is_iec559);
|
||||
TEST (is_bounded);
|
||||
TEST (is_modulo);
|
||||
TEST (traps);
|
||||
TEST (tinyness_before);
|
||||
TEST (round_style);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
template <class T>
|
||||
void test_limits (const volatile T*, const char *tname)
|
||||
{
|
||||
typedef const T const_T;
|
||||
typedef volatile T volatile_T;
|
||||
typedef const volatile T const_volatile_T;
|
||||
|
||||
rw_info (0, 0, __LINE__,
|
||||
"std::numeric_limits<T> with T = cv-qualified %s", tname);
|
||||
|
||||
test_limits ((T*)0, (const_T*)0, tname, "const");
|
||||
test_limits ((T*)0, (volatile_T*)0, tname, "volatile");
|
||||
test_limits ((T*)0, (const_volatile_T*)0, tname, "const volatile");
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static int
|
||||
run_test (int, char*[])
|
||||
{
|
||||
#undef TEST
|
||||
#define TEST(T) test_limits ((T*)0, _RWSTD_STRSTR (T))
|
||||
|
||||
#ifndef _RWSTD_NO_NATIVE_BOOL
|
||||
TEST (bool);
|
||||
#endif // _RWSTD_NO_NATIVE_BOOL
|
||||
|
||||
TEST (char);
|
||||
TEST (signed char);
|
||||
TEST (unsigned char);
|
||||
|
||||
TEST (short);
|
||||
TEST (unsigned short);
|
||||
|
||||
TEST (int);
|
||||
TEST (unsigned);
|
||||
|
||||
TEST (long);
|
||||
TEST (unsigned long);
|
||||
|
||||
#ifdef _RWSTD_LONG_LONG
|
||||
TEST (_RWSTD_LONG_LONG);
|
||||
TEST (unsigned _RWSTD_LONG_LONG);
|
||||
#endif
|
||||
|
||||
TEST (float);
|
||||
TEST (double);
|
||||
|
||||
#ifndef _RWSTD_NO_LONG_DOUBLE
|
||||
TEST (long double);
|
||||
#endif // _RWSTD_NO_LONG_DOUBLE
|
||||
|
||||
#ifndef _RWSTD_NO_NATIVE_WCHAR_T
|
||||
TEST (wchar_t);
|
||||
#endif // _RWSTD_NO_NATIVE_WCHAR_T
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
return rw_test (argc, argv, __FILE__,
|
||||
"lib.numeric.limits",
|
||||
|
||||
#ifdef _RWSTD_NO_EXT_CV_QUALIFIED_LIMITS
|
||||
"testing the absence of "
|
||||
#endif // _RWSTD_NO_EXT_CV_QUALIFIED_LIMITS
|
||||
"specializations on cv-qualifed types",
|
||||
run_test,
|
||||
0,
|
||||
(void*)0);
|
||||
}
|
||||
216
extern/stdcxx/4.2.1/tests/support/18.limits.traps.cpp
vendored
Normal file
216
extern/stdcxx/4.2.1/tests/support/18.limits.traps.cpp
vendored
Normal file
@@ -0,0 +1,216 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 18.limits_traps.cpp - test exercising std::numeric_limits::traps
|
||||
*
|
||||
* $Id: 18.limits.traps.cpp 515262 2007-03-06 19:28:51Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* 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 2005-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include <csignal> // for SIGFPE, signal
|
||||
|
||||
#include <any.h> // for rw_any_t
|
||||
#include <cmdopt.h> // for rw_enabled()
|
||||
#include <driver.h> // for rw_test(), ...
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
#ifdef _RWSTD_OS_LINUX
|
||||
|
||||
// use siglongjmp() and sigsetjmp() on Linux to avoid
|
||||
// http://sourceware.org/bugzilla/show_bug.cgi?id=2351
|
||||
# include <setjmp.h> // for siglongjmp, sigsetjmp
|
||||
|
||||
jmp_buf jmp_env;
|
||||
|
||||
extern "C" {
|
||||
|
||||
void handle_fpe (int)
|
||||
{
|
||||
siglongjmp (jmp_env, 1);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
# define RW_SIGSETJMP(env, signo) sigsetjmp (env, signo)
|
||||
#else // if !defined (_RWSTD_OS_LINUX)
|
||||
|
||||
# include <csetjmp> // for longjmp, setjmp
|
||||
|
||||
std::jmp_buf jmp_env;
|
||||
|
||||
extern "C" {
|
||||
|
||||
void handle_fpe (int)
|
||||
{
|
||||
std::longjmp (jmp_env, 1);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
# define RW_SIGSETJMP(env, ignore) setjmp (env)
|
||||
#endif // _RWSTD_OS_LINUX
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// silence useless MSVC warnings:
|
||||
// 4800: 'int' : forcing value to bool 'true' or 'false'
|
||||
// 4804: '/' : unsafe use of type 'bool' in operation
|
||||
# pragma warning (disable: 4800 4804)
|
||||
|
||||
// use Structured Exception Handling to detect arithmetic exceptions
|
||||
# define TRY __try
|
||||
# define EXCEPT(arg) __except (arg)
|
||||
#else
|
||||
# define TRY if (1)
|
||||
# define EXCEPT(ignore) else if (0)
|
||||
#endif // _MSC_VER
|
||||
|
||||
|
||||
template <class numT>
|
||||
inline void
|
||||
try_trap (const volatile numT &one, const volatile numT &zero,
|
||||
numT &result, bool &trapped)
|
||||
{
|
||||
TRY {
|
||||
result = one / zero;
|
||||
}
|
||||
EXCEPT (1) {
|
||||
// Windows SEH hackery
|
||||
trapped = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class numT>
|
||||
numT test_traps (numT, int lineno, bool)
|
||||
{
|
||||
static const char* const tname = rw_any_t (numT ()).type_name ();
|
||||
|
||||
if (!rw_enabled (tname)) {
|
||||
rw_note (0, 0, 0, "numeric_limits<%s>::traps test disabled", tname);
|
||||
return numT ();
|
||||
}
|
||||
|
||||
const bool traps = std::numeric_limits<numT>::traps;
|
||||
|
||||
rw_info (0, 0, 0, "std::numeric_limits<%s>::traps = %b", tname, traps);
|
||||
|
||||
#ifdef SIGFPE
|
||||
std::signal (SIGFPE, handle_fpe);
|
||||
#else // if !defined (SIGFPE)
|
||||
if (!rw_warn (!traps, 0, lineno,
|
||||
"SIGFPE not #defined and numeric_limits<%s>::traps == %b, "
|
||||
"cannot test", tname, traps)) {
|
||||
return numT ();
|
||||
}
|
||||
#endif // SIGFPE
|
||||
|
||||
numT result = numT ();
|
||||
|
||||
// set the environment
|
||||
const int jumped = RW_SIGSETJMP (jmp_env, SIGFPE);
|
||||
|
||||
volatile numT zero = numT (jumped);
|
||||
volatile numT one = numT (1);
|
||||
|
||||
bool trapped = false;
|
||||
|
||||
if (jumped) {
|
||||
// setjmp() call above returned from the SIGFPE handler
|
||||
// as a result of a floating point exception triggered
|
||||
// by the division by zero in the else block below
|
||||
result = zero / one;
|
||||
|
||||
trapped = true;
|
||||
}
|
||||
else {
|
||||
// setjmp() call above returned after setting up the jump
|
||||
// environment; see of division by zero traps (if so, it
|
||||
// will generate a SIGFPE which will be caught by the
|
||||
// signal hanlder above and execution will resume by
|
||||
// returning from setjmp() above again, but this time
|
||||
// with a non-zero value
|
||||
try_trap (one, zero, result, trapped);
|
||||
}
|
||||
|
||||
rw_assert (trapped == traps, 0, lineno,
|
||||
"numeric_limits<%s>::traps == %b, got %b",
|
||||
tname, trapped, traps);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static int
|
||||
run_test (int, char*[])
|
||||
{
|
||||
#define TEST(T, floating) test_traps ((T)0, __LINE__, floating)
|
||||
|
||||
#ifndef _RWSTD_NO_NATIVE_BOOL
|
||||
TEST (bool, false);
|
||||
#endif // _RWSTD_NO_NATIVE_BOOL
|
||||
|
||||
TEST (char, false);
|
||||
TEST (signed char, false);
|
||||
TEST (unsigned char, false);
|
||||
|
||||
TEST (short, false);
|
||||
TEST (unsigned short, false);
|
||||
TEST (int, false);
|
||||
TEST (unsigned int, false);
|
||||
TEST (long, false);
|
||||
TEST (unsigned long, false);
|
||||
|
||||
#ifndef _RWSTD_NO_LONG_LONG
|
||||
TEST (_RWSTD_LONG_LONG, false);
|
||||
TEST (unsigned _RWSTD_LONG_LONG, false);
|
||||
#endif // _RWSTD_NO_LONG_LONG
|
||||
|
||||
#ifndef _RWSTD_NO_NATIVE_WCHAR_T
|
||||
TEST (wchar_t, false);
|
||||
#endif // _RWSTD_NO_NATIVE_WCHAR_T
|
||||
|
||||
TEST (float, true);
|
||||
TEST (double, true);
|
||||
|
||||
#ifndef _RWSTD_NO_LONG_DOUBLE
|
||||
TEST (long double, true);
|
||||
#endif // _RWSTD_NO_LONG_DOUBLE
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
return rw_test (argc, argv, __FILE__,
|
||||
"lib.numeric.limits.members",
|
||||
"traps data member",
|
||||
run_test,
|
||||
0, 0);
|
||||
}
|
||||
1427
extern/stdcxx/4.2.1/tests/support/18.numeric.special.float.cpp
vendored
Normal file
1427
extern/stdcxx/4.2.1/tests/support/18.numeric.special.float.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
654
extern/stdcxx/4.2.1/tests/support/18.numeric.special.int.cpp
vendored
Normal file
654
extern/stdcxx/4.2.1/tests/support/18.numeric.special.int.cpp
vendored
Normal file
@@ -0,0 +1,654 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 18.numeric.special.int.cpp - tests specializations of the numeric_limits
|
||||
* class template on integer types
|
||||
*
|
||||
* $Id: 18.numeric.special.int.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 2004-2008 Rogue Wave Software, Inc.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <limits> // for numeric_limits
|
||||
#include <climits> // for {CHAR,SHRT,INT,LONG}_{MIN,MAX}, etc.
|
||||
#include <cstdio> // for sprintf()
|
||||
|
||||
#include <driver.h>
|
||||
|
||||
|
||||
template <class T>
|
||||
struct Limits
|
||||
{
|
||||
enum { is_specialized = false };
|
||||
|
||||
static T (min) () { return 0; }
|
||||
static T (max) () { return 0; }
|
||||
|
||||
enum { digits };
|
||||
enum { digits10 };
|
||||
enum { is_signed };
|
||||
enum { is_integer };
|
||||
enum { is_exact };
|
||||
enum { radix };
|
||||
enum { is_bounded = false };
|
||||
|
||||
static bool is_modulo () { return false; }
|
||||
|
||||
static int compute_digits10 () {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// edg (DEC cxx and others) gives an error in strict ANSI mode
|
||||
// for things like INT_MAX + 1; this works around that error...
|
||||
template <class T>
|
||||
inline bool is_modulo (T _max)
|
||||
{
|
||||
// avoid MSVC warning C4800: 'int' :
|
||||
// forcing value to bool 'true' or 'false' (performance warning)
|
||||
T max_plus_one = _max;
|
||||
|
||||
return ++max_plus_one < _max;
|
||||
}
|
||||
|
||||
_RWSTD_SPECIALIZED_FUNCTION
|
||||
inline bool is_modulo (bool)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
_RWSTD_SPECIALIZED_CLASS
|
||||
struct Limits<int>
|
||||
{
|
||||
enum { is_specialized = true };
|
||||
static int (min) () { return INT_MIN; }
|
||||
static int (max) () { return INT_MAX; }
|
||||
|
||||
enum { digits = CHAR_BIT * sizeof (int) - 1 };
|
||||
enum { digits10 = (digits * 301) / 1000 };
|
||||
enum { is_signed = true };
|
||||
enum { is_integer = true };
|
||||
enum { is_exact = true };
|
||||
enum { radix = 2 };
|
||||
enum { is_bounded = true };
|
||||
|
||||
static bool is_modulo () { return ::is_modulo ((max)()); }
|
||||
|
||||
static int compute_digits10 () {
|
||||
char buf [80];
|
||||
return std::sprintf (buf, "%d", INT_MAX) - 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#ifndef _RWSTD_NO_BOOL
|
||||
_RWSTD_SPECIALIZED_CLASS
|
||||
struct Limits<bool>
|
||||
{
|
||||
enum { is_specialized = true };
|
||||
static bool (min) () { return false; }
|
||||
static bool (max) () { return true; }
|
||||
|
||||
enum { digits = 1 };
|
||||
enum { digits10 = (digits * 301) / 1000 };
|
||||
enum { is_signed = false };
|
||||
enum { is_integer = true };
|
||||
enum { is_exact = true };
|
||||
enum { radix = 2 };
|
||||
enum { is_bounded = true };
|
||||
|
||||
static bool is_modulo () { return ::is_modulo ((max)()); }
|
||||
|
||||
static int compute_digits10 () {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //_RWSTD_NO_BOOL
|
||||
|
||||
|
||||
_RWSTD_SPECIALIZED_CLASS
|
||||
struct Limits<char>
|
||||
{
|
||||
enum { is_specialized = true };
|
||||
static char (min) () { return CHAR_MIN; }
|
||||
static char (max) () { return CHAR_MAX; }
|
||||
|
||||
enum { is_signed = CHAR_MAX == SCHAR_MAX ? true : false };
|
||||
enum {
|
||||
digits = is_signed ? CHAR_BIT * sizeof (char) -1
|
||||
: CHAR_BIT * sizeof (char)
|
||||
};
|
||||
enum { digits10 = (digits * 301) / 1000 };
|
||||
enum { is_integer = true };
|
||||
enum { is_exact = true };
|
||||
enum { radix = 2 };
|
||||
enum { is_bounded = true };
|
||||
|
||||
static bool is_modulo () { return ::is_modulo ((max)()); }
|
||||
|
||||
static int compute_digits10 () {
|
||||
char buf [80];
|
||||
return std::sprintf (buf, "%d", (unsigned char)CHAR_MAX) - 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
_RWSTD_SPECIALIZED_CLASS
|
||||
struct Limits<signed char>
|
||||
{
|
||||
|
||||
enum { is_specialized = true };
|
||||
static signed char (min) () { return SCHAR_MIN; }
|
||||
static signed char (max) () { return SCHAR_MAX; }
|
||||
|
||||
enum { digits = CHAR_BIT * sizeof (signed char) - 1 };
|
||||
enum { digits10 = (digits * 301) / 1000 };
|
||||
enum { is_signed = true };
|
||||
enum { is_integer = true };
|
||||
enum { is_exact = true };
|
||||
enum { radix = 2 };
|
||||
enum { is_bounded = true };
|
||||
|
||||
static bool is_modulo () { return ::is_modulo ((max)()); }
|
||||
|
||||
static int compute_digits10 () {
|
||||
char buf [80];
|
||||
return std::sprintf (buf, "%d", (unsigned char)SCHAR_MAX) - 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
_RWSTD_SPECIALIZED_CLASS
|
||||
struct Limits<unsigned char>
|
||||
{
|
||||
enum { is_specialized = true };
|
||||
static unsigned char (min) () { return 0; }
|
||||
static unsigned char (max) () { return UCHAR_MAX; }
|
||||
|
||||
enum { digits = CHAR_BIT * sizeof (unsigned char) };
|
||||
enum { digits10 = (digits * 301) / 1000 };
|
||||
|
||||
enum { is_signed = false };
|
||||
enum { is_integer = true };
|
||||
enum { is_exact = true };
|
||||
enum { radix = 2 };
|
||||
enum { is_bounded = true };
|
||||
|
||||
static bool is_modulo () { return ::is_modulo ((max)()); }
|
||||
|
||||
static int compute_digits10 () {
|
||||
char buf [80];
|
||||
return std::sprintf (buf, "%d", (unsigned char)UCHAR_MAX) - 1;
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef _RWSTD_NO_NATIVE_WCHAR_T
|
||||
|
||||
_RWSTD_SPECIALIZED_CLASS
|
||||
struct Limits<wchar_t>
|
||||
{
|
||||
enum { is_specialized = true };
|
||||
|
||||
static wchar_t (min) () {
|
||||
return wchar_t (-1) > wchar_t (0) ? 0
|
||||
: sizeof (wchar_t) == sizeof (short) ? wchar_t (SHRT_MIN)
|
||||
: sizeof (wchar_t) == sizeof (int) ? wchar_t (INT_MIN)
|
||||
: sizeof (wchar_t) == sizeof (long) ? wchar_t (LONG_MIN)
|
||||
: wchar_t (SCHAR_MIN);
|
||||
}
|
||||
|
||||
static wchar_t (max) () {
|
||||
return wchar_t (-1) > wchar_t (0) ?
|
||||
( sizeof (wchar_t) == sizeof (short) ? wchar_t (USHRT_MAX)
|
||||
: sizeof (wchar_t) == sizeof (int) ? wchar_t (UINT_MAX)
|
||||
: sizeof (wchar_t) == sizeof (long) ? wchar_t (ULONG_MAX)
|
||||
: wchar_t (SCHAR_MAX))
|
||||
: ( sizeof (wchar_t) == sizeof (short) ? wchar_t (SHRT_MAX)
|
||||
: sizeof (wchar_t) == sizeof (int) ? wchar_t (INT_MAX)
|
||||
: sizeof (wchar_t) == sizeof (long) ? wchar_t (LONG_MAX)
|
||||
: wchar_t (UCHAR_MAX));
|
||||
}
|
||||
|
||||
enum { is_signed = wchar_t (0) > wchar_t (~0) };
|
||||
|
||||
enum {
|
||||
digits = is_signed ? CHAR_BIT * sizeof (wchar_t) - 1
|
||||
: CHAR_BIT*sizeof(wchar_t)
|
||||
};
|
||||
enum { digits10 = (digits * 301) / 1000 };
|
||||
enum { is_integer = true };
|
||||
enum { is_exact = true };
|
||||
enum { radix = 2 };
|
||||
enum { is_bounded = true };
|
||||
|
||||
static bool is_modulo () { return ::is_modulo ((max)()); }
|
||||
|
||||
static int compute_digits10 () {
|
||||
char buf [80];
|
||||
return std::sprintf (buf, "%u", wchar_t (~0)) - 1;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //_RWSTD_NO_NATIVE_WCHAR_T
|
||||
|
||||
|
||||
_RWSTD_SPECIALIZED_CLASS
|
||||
struct Limits<short>
|
||||
{
|
||||
enum { is_specialized = true };
|
||||
static short (min) () { return SHRT_MIN; }
|
||||
static short (max) () { return SHRT_MAX; }
|
||||
|
||||
enum { digits = CHAR_BIT * sizeof (short) - 1 };
|
||||
enum { digits10 = (digits * 301) / 1000 };
|
||||
enum { is_signed = true };
|
||||
enum { is_integer = true };
|
||||
enum { is_exact = true };
|
||||
enum { radix = 2 };
|
||||
enum { is_bounded = true };
|
||||
|
||||
static bool is_modulo () { return ::is_modulo ((max)()); }
|
||||
|
||||
static int compute_digits10 () {
|
||||
char buf [80];
|
||||
return std::sprintf (buf, "%d", (int)SHRT_MAX) - 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
_RWSTD_SPECIALIZED_CLASS
|
||||
struct Limits<long>
|
||||
{
|
||||
enum { is_specialized = true };
|
||||
static long (min) () { return LONG_MIN; }
|
||||
static long (max) () { return LONG_MAX; }
|
||||
|
||||
enum { digits = CHAR_BIT * sizeof(long)-1 };
|
||||
enum { digits10 = (digits * 301) / 1000 };
|
||||
enum { is_signed = true };
|
||||
enum { is_integer = true };
|
||||
enum { is_exact = true };
|
||||
enum { radix = 2 };
|
||||
enum { is_bounded = true };
|
||||
|
||||
static bool is_modulo () { return ::is_modulo ((max)()); }
|
||||
|
||||
static int compute_digits10 () {
|
||||
char buf [80];
|
||||
return std::sprintf (buf, "%ld", LONG_MAX) - 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
_RWSTD_SPECIALIZED_CLASS
|
||||
struct Limits <unsigned short>
|
||||
{
|
||||
enum { is_specialized = true };
|
||||
static unsigned short (min) () { return 0; }
|
||||
static unsigned short (max) () { return USHRT_MAX; }
|
||||
|
||||
enum { digits = CHAR_BIT * sizeof(unsigned short) };
|
||||
enum { digits10 = (digits * 301) / 1000 };
|
||||
enum { is_signed = false };
|
||||
enum { is_integer = true };
|
||||
enum { is_exact = true };
|
||||
enum { radix = 2 };
|
||||
enum { is_bounded = true };
|
||||
|
||||
static bool is_modulo () { return ::is_modulo ((max)()); }
|
||||
|
||||
static int compute_digits10 () {
|
||||
char buf [80];
|
||||
return std::sprintf (buf, "%u", unsigned (USHRT_MAX)) - 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
_RWSTD_SPECIALIZED_CLASS
|
||||
struct Limits<unsigned int>
|
||||
{
|
||||
enum { is_specialized = true };
|
||||
static unsigned int (min) () { return 0; }
|
||||
static unsigned int (max) () { return UINT_MAX; }
|
||||
|
||||
enum { digits = CHAR_BIT * sizeof(unsigned int) };
|
||||
enum { digits10 = (digits * 301) / 1000 };
|
||||
enum { is_signed = false };
|
||||
enum { is_integer = true };
|
||||
enum { is_exact = true };
|
||||
enum { radix = 2 };
|
||||
enum { is_bounded = true };
|
||||
|
||||
static bool is_modulo () { return ::is_modulo ((max)()); }
|
||||
|
||||
static int compute_digits10 () {
|
||||
char buf [80];
|
||||
return std::sprintf (buf, "%u", UINT_MAX) - 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
_RWSTD_SPECIALIZED_CLASS
|
||||
struct Limits<unsigned long>
|
||||
{
|
||||
enum { is_specialized = true };
|
||||
|
||||
static unsigned long (min) () { return 0; }
|
||||
static unsigned long (max) () { return ULONG_MAX; }
|
||||
|
||||
enum { digits = CHAR_BIT * sizeof(unsigned long) };
|
||||
enum { digits10 = (digits * 301) / 1000 };
|
||||
enum { is_signed = false };
|
||||
enum { is_integer = true };
|
||||
enum { is_exact = true };
|
||||
enum { radix = 2 };
|
||||
enum { is_bounded = true };
|
||||
|
||||
static bool is_modulo () { return ::is_modulo ((max)()); }
|
||||
|
||||
static int compute_digits10 () {
|
||||
char buf [80];
|
||||
return std::sprintf (buf, "%lu", ULONG_MAX) - 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#ifdef _RWSTD_LONG_LONG
|
||||
|
||||
_RWSTD_SPECIALIZED_CLASS
|
||||
struct Limits<_RWSTD_LONG_LONG>
|
||||
{
|
||||
typedef _RWSTD_LONG_LONG LLong;
|
||||
|
||||
enum { is_specialized = true };
|
||||
|
||||
static LLong (min) () {
|
||||
typedef unsigned _RWSTD_LONG_LONG ULLong;
|
||||
ULLong zero = 0; // prevent an EDG eccp warning #68-D
|
||||
return ~zero / ULLong (2) + ULLong (1);
|
||||
}
|
||||
|
||||
static LLong (max) () {
|
||||
typedef unsigned _RWSTD_LONG_LONG ULLong;
|
||||
return ~ULLong (0) / ULLong (2);
|
||||
}
|
||||
|
||||
enum { digits = CHAR_BIT * sizeof (LLong) - 1 };
|
||||
enum { digits10 = (digits * 301) / 1000 };
|
||||
enum { is_signed = true };
|
||||
enum { is_integer = true };
|
||||
enum { is_exact = true };
|
||||
enum { radix = 2 };
|
||||
enum { is_bounded = true };
|
||||
|
||||
static bool is_modulo () { return ::is_modulo ((max)()); }
|
||||
|
||||
static int compute_digits10 () {
|
||||
char buf [80];
|
||||
const char fmt[] = "%" _RWSTD_LLONG_PRINTF_PREFIX "u";
|
||||
return std::sprintf (buf, fmt, (max) ()) - 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
_RWSTD_SPECIALIZED_CLASS
|
||||
struct Limits<unsigned _RWSTD_LONG_LONG>
|
||||
{
|
||||
typedef unsigned _RWSTD_LONG_LONG ULLong;
|
||||
|
||||
enum { is_specialized = true };
|
||||
|
||||
static ULLong (min) () { return 0; }
|
||||
static ULLong (max) () { return ~ULLong (0); }
|
||||
|
||||
enum { digits = CHAR_BIT * sizeof (ULLong) };
|
||||
enum { digits10 = (digits * 301) / 1000 };
|
||||
enum { is_signed = false };
|
||||
enum { is_integer = true };
|
||||
enum { is_exact = true };
|
||||
enum { radix = 2 };
|
||||
enum { is_bounded = true };
|
||||
|
||||
static bool is_modulo () { return ::is_modulo ((max)()); }
|
||||
|
||||
static int compute_digits10 () {
|
||||
char buf [80];
|
||||
const char fmt[] = "%" _RWSTD_LLONG_PRINTF_PREFIX "i";
|
||||
|
||||
// work around libc bugs (e.g., glibc on Linux)
|
||||
const int n = std::sprintf (buf, fmt, (max) ());
|
||||
|
||||
if (n < Limits<unsigned>::digits10)
|
||||
return digits10;
|
||||
|
||||
return n - 1;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _RWSTD_LONG_LONG
|
||||
|
||||
|
||||
template <class T>
|
||||
void run_test (T*, const char *tname, const char *fmt)
|
||||
{
|
||||
typedef std::numeric_limits<T> limT;
|
||||
typedef Limits<T> Traits;
|
||||
|
||||
RW_ASSERT (0 != tname);
|
||||
RW_ASSERT (0 != fmt);
|
||||
|
||||
#if !defined (__EDG__) || __EDG_VERSION__ > 245
|
||||
|
||||
# define ASSERT(expr, fmt) \
|
||||
/* verify that `expr' is a constant integral expression */ \
|
||||
{ enum { is_const_integral_expression = limT::expr }; } \
|
||||
rw_assert (limT::expr == int (Traits::expr), 0, __LINE__, \
|
||||
"std::numeric_limits<%s>::" #expr \
|
||||
" == %{@}, got %{@}", \
|
||||
tname, fmt, Traits::expr, fmt, limT::expr)
|
||||
|
||||
#else // if EDG eccp < 3.0
|
||||
// working around an EDG eccp 2.4x ICE
|
||||
# define ASSERT(expr) \
|
||||
/* verify that `expr' is a constant integral expression */ \
|
||||
switch (limT::expr) { case limT::expr: break; }; \
|
||||
rw_assert (limT::expr == int (Traits::expr), 0, __LINE__, \
|
||||
"std::numeric_limits<%s>::" #expr \
|
||||
"== %{@}, got %{@}", \
|
||||
tname, fmt, Traits::expr, fmt, limT::expr)
|
||||
#endif // EDG eccp < 3.0
|
||||
|
||||
#define ASSERT_0(expr, fmt) \
|
||||
rw_assert (!limT::expr, 0, __LINE__, \
|
||||
"std::numeric_limits<%s>::" #expr " == 0, got %{@}", \
|
||||
tname, fmt, limT::expr)
|
||||
|
||||
ASSERT (is_specialized, "%#b");
|
||||
|
||||
// 18.2.1.2, p1
|
||||
rw_info (0, 0, __LINE__,
|
||||
"std::numeric_limits<%s>::min() == %{@}",
|
||||
tname, fmt, (Traits::min ()));
|
||||
|
||||
rw_assert ((limT::min)() == (Traits::min)(), 0, __LINE__,
|
||||
"std::numeric_limits<%s>::min() == %{@}, got %{@}",
|
||||
tname, fmt, (Traits::min)(), fmt, (limT::min)());
|
||||
|
||||
// 18.2.1.2, p4
|
||||
rw_info (0, 0, __LINE__,
|
||||
"std::numeric_limits<%s>::max() == %{@}",
|
||||
tname, fmt, (Traits::max ()));
|
||||
|
||||
rw_assert ((limT::max)() == (Traits::max)(), 0, __LINE__,
|
||||
"std::numeric_limits<%s>::max() == %{@}, got %{@}",
|
||||
tname, fmt, (Traits::max)(), fmt, (limT::max)());
|
||||
|
||||
// 18.2.1.2, p6
|
||||
ASSERT (digits, "%d");
|
||||
|
||||
// 18.2.1.2, p9
|
||||
ASSERT (digits10, "%d");
|
||||
|
||||
rw_assert (limT::digits10 == Traits::compute_digits10 (), 0, __LINE__,
|
||||
"std::numeric_limits<%s>::digits10 == %d (computed), got %d",
|
||||
tname, Traits::compute_digits10 (), limT::digits10);
|
||||
|
||||
// 18.2.1.2, p11
|
||||
ASSERT (is_signed, "%b");
|
||||
|
||||
// 18.2.1.2, p13
|
||||
ASSERT (is_integer, "%b");
|
||||
|
||||
// 18.2.1.2, p15
|
||||
ASSERT (is_exact, "%b");
|
||||
|
||||
// 18.2.1.2, p17
|
||||
ASSERT (radix, "%i");
|
||||
|
||||
// 18.2.1.2, p20
|
||||
ASSERT_0 (epsilon (), fmt);
|
||||
|
||||
// 18.2.1.2, p22
|
||||
ASSERT_0 (round_error (), fmt);
|
||||
|
||||
// 18.2.1.2, p23
|
||||
ASSERT_0 (min_exponent, "%i");
|
||||
|
||||
// 18.2.1.2, p25
|
||||
ASSERT_0 (min_exponent10, "%i");
|
||||
|
||||
// 18.2.1.2, p27
|
||||
ASSERT_0 (max_exponent, "%i");
|
||||
|
||||
// 18.2.1.2, p29
|
||||
ASSERT_0 (max_exponent10, "%i");
|
||||
|
||||
// 18.2.1.2, p31
|
||||
ASSERT_0 (has_infinity, "%b");
|
||||
|
||||
// 18.2.1.2, p34
|
||||
ASSERT_0 (has_quiet_NaN, "%b");
|
||||
|
||||
// 18.2.1.2, p37
|
||||
ASSERT_0 (has_signaling_NaN, "%b");
|
||||
|
||||
// 18.2.1.2, p40
|
||||
ASSERT_0 (has_denorm, "%b");
|
||||
|
||||
// 18.2.1.2, p42
|
||||
ASSERT_0 (has_denorm_loss, "%b");
|
||||
|
||||
// 18.2.1.2, p43
|
||||
ASSERT_0 (infinity (), fmt);
|
||||
|
||||
// 18.2.1.2, p45
|
||||
ASSERT_0 (quiet_NaN (), fmt);
|
||||
|
||||
// 18.2.1.2, p47
|
||||
ASSERT_0 (signaling_NaN (), fmt);
|
||||
|
||||
// 18.2.1.2, p49
|
||||
ASSERT_0 (denorm_min (), fmt);
|
||||
|
||||
// 18.2.1.2, p52
|
||||
ASSERT_0 (is_iec559, "%b");
|
||||
|
||||
// 18.2.1.2, p54
|
||||
ASSERT (is_bounded, "%b");
|
||||
|
||||
// 18.2.1.2, p56
|
||||
rw_assert (limT::is_modulo == Traits::is_modulo (), 0, __LINE__,
|
||||
"std::numeric_limits<%s>::is_modulo == %#b",
|
||||
tname, Traits::is_modulo ());
|
||||
|
||||
// 18.2.1.2, p59
|
||||
ASSERT_0 (traps, "%b");
|
||||
|
||||
// 18.2.1.2, p61
|
||||
ASSERT_0 (tinyness_before, "%b");
|
||||
|
||||
// 18.2.1.2, p63
|
||||
rw_assert (limT::round_style == int (std::round_toward_zero), 0, __LINE__,
|
||||
"std::numeric_limits<%s>::round_style == %d",
|
||||
tname, std::round_toward_zero);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
run_test (int, char**)
|
||||
{
|
||||
#define TEST(T, fmt) run_test ((T*)0, #T, fmt)
|
||||
|
||||
|
||||
#ifndef _RWSTD_NO_BOOL
|
||||
|
||||
TEST (bool, "%#b");
|
||||
|
||||
#endif //_RWSTD_NO_BOOL
|
||||
|
||||
|
||||
TEST (char, "%{#c}");
|
||||
TEST (signed char, "%{#c}");
|
||||
TEST (unsigned char, "%{#c}");
|
||||
|
||||
TEST (short, "%hi");
|
||||
TEST (unsigned short, "%hu");
|
||||
|
||||
TEST (int, "%i");
|
||||
TEST (unsigned int, "%u");
|
||||
|
||||
TEST (long, "%li");
|
||||
TEST (unsigned long, "%lu");
|
||||
|
||||
#ifdef _RWSTD_LONG_LONG
|
||||
|
||||
TEST (_RWSTD_LONG_LONG, "%lli");
|
||||
TEST (unsigned _RWSTD_LONG_LONG, "%llu");
|
||||
|
||||
#endif // _RWSTD_LONG_LONG
|
||||
|
||||
#ifndef _RWSTD_NO_NATIVE_WCHAR_T
|
||||
|
||||
TEST (wchar_t, "%{#lc}");
|
||||
|
||||
#endif //_RWSTD_NO_NATIVE_WCHAR_T
|
||||
|
||||
TEST (void*, "%#p");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
return rw_test (argc, argv, __FILE__,
|
||||
"numeric.special",
|
||||
"integer specializations",
|
||||
run_test,
|
||||
"",
|
||||
(void*)0);
|
||||
}
|
||||
110
extern/stdcxx/4.2.1/tests/support/18.setjmp.cpp
vendored
Normal file
110
extern/stdcxx/4.2.1/tests/support/18.setjmp.cpp
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 18.setjmp.cpp - test exercising [support.runtime], header <setjmp.h>
|
||||
*
|
||||
* $Id: 18.setjmp.cpp 593007 2007-11-08 04:30:45Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* 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 2007 Rogue Wave Software, Inc.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <driver.h>
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
jmp_buf env;
|
||||
|
||||
void test_longjmp (int arg)
|
||||
{
|
||||
longjmp (env, arg);
|
||||
|
||||
rw_assert (0, 0, __LINE__,
|
||||
"call to longjmp(..., %d) returned", arg);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static int
|
||||
run_test (int, char**)
|
||||
{
|
||||
#ifdef longjmp
|
||||
|
||||
// longjmp must not be #defined as a macro
|
||||
rw_assert (0, 0, __LINE__, "longjmp #defined as a macro");
|
||||
|
||||
#endif // longjmp
|
||||
|
||||
#ifdef jmp_buf
|
||||
|
||||
//jmp_buf must not be #defined as a macro
|
||||
rw_assert (0, 0, __LINE__, "jmp_buf #defined as a macro");
|
||||
|
||||
#endif // jmp_buf
|
||||
|
||||
#ifndef setjmp
|
||||
|
||||
//setjmp must be #defined as a macro
|
||||
rw_assert (0, 0, __LINE__, "macro setjmp not #defined");
|
||||
|
||||
#endif // setjmp
|
||||
|
||||
// verify that setjmp works
|
||||
|
||||
// using volatile to work around a gcc optimizer bug:
|
||||
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34024
|
||||
volatile int arg = 1;
|
||||
|
||||
int result;
|
||||
|
||||
result = setjmp (env);
|
||||
|
||||
if (0 == result) {
|
||||
|
||||
test_longjmp (arg);
|
||||
|
||||
rw_assert (0, 0, __LINE__,
|
||||
"call to longjmp(..., %d) returned", arg);
|
||||
}
|
||||
else {
|
||||
rw_assert (arg == result, 0, __LINE__,
|
||||
"longjmp(..., %d) returned %d from setjmp()",
|
||||
arg, result);
|
||||
|
||||
// repeat a couple more times
|
||||
if (arg < 3)
|
||||
test_longjmp (++arg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
return rw_test (argc, argv, __FILE__,
|
||||
"support.runtime",
|
||||
"header <setjmp.h>",
|
||||
run_test,
|
||||
"",
|
||||
(void*)0);
|
||||
}
|
||||
478
extern/stdcxx/4.2.1/tests/support/18.support.dynamic.cpp
vendored
Normal file
478
extern/stdcxx/4.2.1/tests/support/18.support.dynamic.cpp
vendored
Normal file
@@ -0,0 +1,478 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 18.support.dynamic.cpp - test exercising [lib.support.dynamic]
|
||||
*
|
||||
* $Id: 18.support.dynamic.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-2008 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <new>
|
||||
#include <memory>
|
||||
#include <driver.h>
|
||||
|
||||
#include <rw/_defs.h>
|
||||
#include <rw/_error.h>
|
||||
|
||||
#include <cstdlib> // for malloc() and free()
|
||||
#include <cstring> // for strlen()
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// verify that <new> et al can coexist with MSVC's <new.h>
|
||||
# include <new.h>
|
||||
#endif
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
// detects recursive implementation of operator new (size_t, nothrow_t)
|
||||
static int recursive_new_nothrow = 0;
|
||||
static int recursive_delete_nothrow = 0;
|
||||
|
||||
// MemoryAllocator is used to replace the global new and delete
|
||||
// in order to test conformance of of the other operators that
|
||||
// might be defined in <new>
|
||||
|
||||
struct MemoryAllocator
|
||||
{
|
||||
MemoryAllocator () {
|
||||
init ();
|
||||
}
|
||||
|
||||
void* operatorNew (std::size_t n) _THROWS ((std::bad_alloc)) {
|
||||
_allocPtr = 0;
|
||||
_newCalled = true;
|
||||
_bytesRequested = n;
|
||||
if (_failAlloc) {
|
||||
_failAlloc = false;
|
||||
_THROW (std::bad_alloc ());
|
||||
}
|
||||
#if !defined (_RWSTD_NO_EXT_OPERATOR_NEW) && \
|
||||
defined (_RWSTD_NO_OPERATOR_NEW_NOTHROW)
|
||||
|
||||
// test our implementation of
|
||||
// ::operator new(size_t, const std::nothrow)
|
||||
// this operator must not be implemented in terms
|
||||
// of ::operator new(size_t) to prevent recursion
|
||||
|
||||
if (recursive_new_nothrow++)
|
||||
_allocPtr = std::malloc (_bytesRequested);
|
||||
else
|
||||
_allocPtr = ::operator new (_bytesRequested, std::nothrow);
|
||||
|
||||
--recursive_new_nothrow;
|
||||
|
||||
#else
|
||||
_allocPtr = std::malloc (_bytesRequested);
|
||||
#endif
|
||||
return _allocPtr;
|
||||
}
|
||||
|
||||
void operatorDelete (void* ptr) _THROWS (()) {
|
||||
_deallocPtr = ptr;
|
||||
#if !defined (_RWSTD_NO_EXT_OPERATOR_NEW) && \
|
||||
defined (_RWSTD_NO_OPERATOR_NEW_NOTHROW)
|
||||
// memory allocated by our nothrow operator new()
|
||||
if (recursive_delete_nothrow++ || recursive_new_nothrow)
|
||||
std::free (ptr);
|
||||
else
|
||||
::operator delete (ptr, std::nothrow);
|
||||
|
||||
--recursive_delete_nothrow;
|
||||
#else
|
||||
std::free (ptr);
|
||||
#endif
|
||||
_deleteCalled = true;
|
||||
}
|
||||
|
||||
void init () {
|
||||
_newCalled = _deleteCalled = _failAlloc = false;
|
||||
_bytesRequested = 0;
|
||||
_deallocPtr = _allocPtr = 0;
|
||||
}
|
||||
|
||||
bool newCalled () {
|
||||
bool tmp = _newCalled;
|
||||
_newCalled = 0;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool deleteCalled () {
|
||||
bool tmp = _deleteCalled;
|
||||
_deleteCalled = 0;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
std::size_t _bytesRequested;
|
||||
bool _newCalled;
|
||||
bool _deleteCalled;
|
||||
bool _failAlloc;
|
||||
void* _allocPtr;
|
||||
void* _deallocPtr;
|
||||
};
|
||||
|
||||
|
||||
// static instance of memory allocator
|
||||
static MemoryAllocator alloc;
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
// replace the global operators with MemoryAllocator versions
|
||||
void* operator new (std::size_t size) _THROWS ((std::bad_alloc))
|
||||
{
|
||||
return alloc.operatorNew (size);
|
||||
}
|
||||
|
||||
void operator delete (void* p) _THROWS (())
|
||||
{
|
||||
alloc.operatorDelete (p);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
#define TEST_OP_THROWS(expr,cond,tag) \
|
||||
_TRY { \
|
||||
alloc._failAlloc = true; \
|
||||
expr; \
|
||||
rw_assert (cond, 0, __LINE__, tag); \
|
||||
} \
|
||||
_CATCH (std::bad_alloc) { \
|
||||
RW_ASSERT (!cond, 0, __LINE__, tag); \
|
||||
} \
|
||||
_CATCH (...) { \
|
||||
rw_assert (!cond, 0, __LINE__, tag); \
|
||||
} \
|
||||
(void)0
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
// provide a handler for unexpected exceptions so that at least the
|
||||
// test will log the event rather than just aborting
|
||||
void my_unexpected_handler ()
|
||||
{
|
||||
rw_assert (false, 0, __LINE__, "caught an unexpected exception\n");
|
||||
}
|
||||
|
||||
// used in exists_set_new_handler below
|
||||
void my_new_handler ()
|
||||
{
|
||||
}
|
||||
|
||||
// grab default throw procedure
|
||||
void (*default_throw_proc)(int, char*) = _RW::__rw_throw_proc;
|
||||
|
||||
bool my_throw_proc_called = false;
|
||||
|
||||
// my_throw_proc just sets a global flag to indicate
|
||||
// that it was called, and then dispatches the call
|
||||
// to the default throw procedure
|
||||
static void my_throw_proc (int id, char* what)
|
||||
{
|
||||
my_throw_proc_called = true;
|
||||
default_throw_proc (id, what);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
static
|
||||
int run_test (int, char* [])
|
||||
{
|
||||
std::set_unexpected (&my_unexpected_handler);
|
||||
|
||||
if (1) {
|
||||
// exists_std_nothrow
|
||||
const std::nothrow_t* p = &std::nothrow;
|
||||
rw_assert (p != 0, 0, __LINE__, "std::nothrow defined");
|
||||
}
|
||||
|
||||
if (1) {
|
||||
// exists_bad_alloc
|
||||
std::bad_alloc ba1; // default ctor
|
||||
std::bad_alloc ba2 = ba1; // copy ctor
|
||||
|
||||
std::exception* e = &ba1; // derived from exception
|
||||
(void) &e;
|
||||
ba1 = ba2; // assignment operator
|
||||
|
||||
// verify that a member function is accessible and has the
|
||||
// appropriate signature, including return type and exception
|
||||
// specification
|
||||
|
||||
std::bad_alloc& (std::bad_alloc::*p_op_assign)
|
||||
(const std::bad_alloc&) _PTR_THROWS (())
|
||||
= &std::bad_alloc::operator=;
|
||||
_RWSTD_UNUSED (p_op_assign);
|
||||
|
||||
const char*
|
||||
(std::bad_alloc::*p_what_fn)() const _PTR_THROWS (())
|
||||
= &std::bad_alloc::what;
|
||||
_RWSTD_UNUSED (p_what_fn);
|
||||
|
||||
const char* s = ba1.what ();
|
||||
rw_assert (s && 0 != std::strlen (s), 0, __LINE__,
|
||||
"std::bad_alloc::what() returned bad string");
|
||||
}
|
||||
|
||||
if (1) {
|
||||
// set_new_handler
|
||||
typedef void (*new_handler_t) ();
|
||||
|
||||
new_handler_t (*f) (new_handler_t) _PTR_THROWS (());
|
||||
f = &std::set_new_handler;
|
||||
|
||||
rw_assert (f != 0, 0, __LINE__,
|
||||
"std::set_new_handler() defined");
|
||||
|
||||
new_handler_t original_handler
|
||||
= std::set_new_handler (my_new_handler);
|
||||
|
||||
#if !defined (__EDG__) || __EDG_VERSION__ > 245 || defined (__DECCXX)
|
||||
|
||||
// EDG eccp 2.45 standalone demo is known to fail
|
||||
rw_assert (original_handler == 0, 0, __LINE__,
|
||||
"std::set_new_handler() unexpectedly returned "
|
||||
"installed handler");
|
||||
|
||||
#define _RWSTD_NO_EXT_OPERATOR_NEW
|
||||
|
||||
#endif // !__EDG__ || __EDG_VERSION__ > 245 || __DECCXX
|
||||
|
||||
new_handler_t replacement_handler
|
||||
= std::set_new_handler (original_handler);
|
||||
rw_assert (my_new_handler == replacement_handler, 0, __LINE__,
|
||||
"std::set_new_handler() failed to return previously "
|
||||
"installed handler");
|
||||
}
|
||||
|
||||
// test all operators that we have provided definitions for
|
||||
// in <new>; exercises the operators by setting the
|
||||
// replacement allocator to fail, and asserting that an
|
||||
// exception is thrown or not as appropriate for the operator
|
||||
if (1) {
|
||||
// operator new throws
|
||||
void* ptr = 0;
|
||||
_RWSTD_UNUSED (ptr);
|
||||
|
||||
alloc.init (); // reset the allocator
|
||||
|
||||
#ifdef _RWSTD_NO_OPERATOR_NEW_NOTHROW
|
||||
|
||||
// verify that the nothrow version of operator new provided
|
||||
// by our library doesn't call the ordinary operator new
|
||||
// (if it did it would cause recursion if a replacement operator
|
||||
// new were to be implemented in terms of the nothrow version)
|
||||
|
||||
// also verify that it returns 0 on failure
|
||||
|
||||
// force a failure by requesting too large a block of storage
|
||||
// size_t (~0) alone isn't good enough since it causes annoying
|
||||
// dialog boxes to be popped up by the MSVCRTD, the MSVC runtime
|
||||
TEST_OP_THROWS ((ptr = operator new (~0U - 4096U, std::nothrow)),
|
||||
(ptr == 0),
|
||||
"operator new(size_t, nothrow_t) returns 0");
|
||||
|
||||
rw_assert (!alloc.newCalled (), 0, __LINE__,
|
||||
"operator new called by operator new(size_t, nothrow)");
|
||||
|
||||
#endif // defined _RWSTD_NO_OPERATOR_NEW_NOTHROW
|
||||
|
||||
#if defined (_RWSTD_NO_OPERATOR_DELETE_NOTHROW) && \
|
||||
!defined (_RWSTD_NO_PLACEMENT_DELETE)
|
||||
|
||||
// verify that the nothrow version of operator delete provided
|
||||
// by our library prevents exceptions from propagating
|
||||
TEST_OP_THROWS ((operator delete (0, std::nothrow)), true,
|
||||
"operator delete(void*, nothrow_t) doesn't throw");
|
||||
|
||||
// verify that the nothrow version of operator delete provided
|
||||
// by our library doesn't call the ordinary operator delete
|
||||
// (if it did it might cause recursion if a replacement operator
|
||||
// delete were to be implemented in terms of the nothrow version)
|
||||
rw_assert (!alloc.deleteCalled (), 0, __LINE__,
|
||||
"operator delete(void*) called by "
|
||||
"operator delete(void*, nothrow_t)");
|
||||
|
||||
#endif // _RWSTD_NO_OPERATOR_DELETE_NOTHROW && _RWSTD_NO_PLACEMENT_DELETE
|
||||
|
||||
#ifdef _RWSTD_NO_OPERATOR_NEW_ARRAY
|
||||
|
||||
// verify that the array form of operator new throws bad_alloc on
|
||||
// failure
|
||||
TEST_OP_THROWS ((operator new[] (1)), false,
|
||||
"operator new[] (size_t) throws bad_alloc");
|
||||
|
||||
// verify that the array form of operator new provided by our
|
||||
// library calls the ordinary operator new
|
||||
rw_assert (alloc.newCalled (), 0, __LINE__,
|
||||
"operator new called by operator new[](size_t)");
|
||||
|
||||
#endif // defined _RWSTD_NO_OPERATOR_NEW_ARRAY
|
||||
|
||||
#ifdef _RWSTD_NO_OPERATOR_NEW_ARRAY_NOTHROW
|
||||
|
||||
TEST_OP_THROWS ((ptr = operator new[](1, std::nothrow)),
|
||||
(ptr == 0),
|
||||
"operator new[] (size_t, nothrow_t) returns 0");
|
||||
|
||||
rw_assert (alloc.newCalled (), 0, __LINE__,
|
||||
"operator new(size_t) called by "
|
||||
"operator new[](size_t, nothrow_t)");
|
||||
|
||||
#endif // defined _RWSTD_NO_OPERATOR_NEW_ARRAY_NOTHROW
|
||||
|
||||
#ifdef _RWSTD_NO_OPERATOR_DELETE_ARRAY
|
||||
|
||||
TEST_OP_THROWS ((operator delete[] (0)), true,
|
||||
"operator delete[] (void*) doesn't throw");
|
||||
|
||||
rw_assert (alloc.deleteCalled (), 0, __LINE__,
|
||||
"operator delete called by operator delete[](void*)");
|
||||
|
||||
#endif // defined _RWSTD_NO_OPERATOR_DELETE_ARRAY
|
||||
|
||||
#if defined (_RWSTD_NO_OPERATOR_DELETE_ARRAY_NOTHROW) && \
|
||||
!defined ( _RWSTD_NO_PLACEMENT_DELETE)
|
||||
|
||||
TEST_OP_THROWS ((operator delete[] (0, std::nothrow)), true,
|
||||
"operator delete[] (void*, nothrow_t) doesn't "
|
||||
"throw");
|
||||
|
||||
rw_assert (alloc.deleteCalled (), 0, __LINE__,
|
||||
"operator delete(void*) called by "
|
||||
"operator delete[](void*, nothrow_t)");
|
||||
|
||||
#endif // _RWSTD_NO_OPERATOR_DELETE_ARRAY_NOTHROW &&
|
||||
// !_RWSTD_NO_PLACEMENT_DELETE
|
||||
|
||||
// verify that the nothrow form of operator new provided by our
|
||||
// library isn't recursively implemented in terms of the ordinary
|
||||
// operator new
|
||||
rw_assert (0 == recursive_new_nothrow, 0, __LINE__,
|
||||
"operator new (size_t, nothrow_t) causes recursion");
|
||||
|
||||
rw_assert (0 == recursive_delete_nothrow, 0, __LINE__,
|
||||
"operator delete (void*, nothrow_t) causes recursion");
|
||||
}
|
||||
|
||||
// __rw_allocate() is like ::operator new() except that it calls
|
||||
// __rw_throw() on failure (which may throw std::bad_alloc).
|
||||
// This test checks that __rw_throw() is called,
|
||||
// that it properly calls __rw_throw_proc(), and that bad_alloc
|
||||
// is thrown. We'll use the replaced ::operator new() to
|
||||
// control when a memory allocation request will fail.
|
||||
|
||||
#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
|
||||
|
||||
const bool test_rw_allocate = true;
|
||||
|
||||
#else // if defined (_RWSTD_NO_REPLACEABLE_NEW_DELETE)
|
||||
|
||||
// avoid tests that depend on the replacement operators new
|
||||
// and delete on platforms like AIX or Win32 where they cannot
|
||||
// be reliably replaced
|
||||
const bool test_rw_allocate = false;
|
||||
|
||||
#endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE
|
||||
|
||||
if (test_rw_allocate) {
|
||||
|
||||
alloc.init (); // reset the allocator
|
||||
|
||||
_RW::__rw_throw_proc = my_throw_proc; // set the throw func
|
||||
my_throw_proc_called = false;
|
||||
|
||||
for (std::size_t i = 0; i < 10; ++i) {
|
||||
|
||||
char* ptr = 0;
|
||||
|
||||
const bool doFail = !!(i % 2); // prevent MSVC warning 4800
|
||||
if (doFail)
|
||||
alloc._failAlloc = true;
|
||||
|
||||
try {
|
||||
// allocation
|
||||
alloc._bytesRequested = ~i; // reset
|
||||
|
||||
ptr = _RWSTD_STATIC_CAST (char*, _RW::__rw_allocate (i));
|
||||
rw_assert (alloc._bytesRequested == i, 0, __LINE__,
|
||||
"__rw_allocate (%u) requested %u bytes",
|
||||
i, alloc._bytesRequested);
|
||||
|
||||
rw_assert (alloc.newCalled (), 0, __LINE__,
|
||||
"operator new() called");
|
||||
rw_assert (!doFail, 0, __LINE__,
|
||||
"allocation succeeded");
|
||||
rw_assert (my_throw_proc_called == false,
|
||||
0, __LINE__,
|
||||
"my_throw_proc called");
|
||||
|
||||
// deallocation
|
||||
_RW::__rw_deallocate (ptr, i);
|
||||
|
||||
rw_assert (alloc.deleteCalled (),
|
||||
0, __LINE__,
|
||||
"operator delete() called");
|
||||
rw_assert (alloc._deallocPtr == ptr,
|
||||
0, __LINE__,
|
||||
"allocated memory deallocated");
|
||||
|
||||
}
|
||||
catch (std::bad_alloc) {
|
||||
rw_assert (doFail, 0, __LINE__,
|
||||
"expected bad_alloc exception");
|
||||
|
||||
rw_assert (my_throw_proc_called == true, 0, __LINE__,
|
||||
"my_throw_proc called");
|
||||
}
|
||||
catch (...) {
|
||||
rw_assert (false, 0, __LINE__,
|
||||
"expected std::bad_alloc exception");
|
||||
}
|
||||
|
||||
my_throw_proc_called = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
rw_warn (false, 0, __LINE__,
|
||||
"__rw::__rw_allocate() not exercised: "
|
||||
"_RWSTD_NO_REPLACEABLE_NEW_DELETE #defined");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
int main (int argc, char* argv [])
|
||||
{
|
||||
return rw_test (argc, argv, __FILE__,
|
||||
"lib.support.dynamic",
|
||||
0 /* no comment */,
|
||||
run_test,
|
||||
"",
|
||||
(void*)0);
|
||||
}
|
||||
439
extern/stdcxx/4.2.1/tests/support/18.support.rtti.cpp
vendored
Normal file
439
extern/stdcxx/4.2.1/tests/support/18.support.rtti.cpp
vendored
Normal file
@@ -0,0 +1,439 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 18.support.rtti.cpp - test exercising 18.5 [lib.support.rtti]
|
||||
*
|
||||
* $Id: 18.support.rtti.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-2008 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <rw/_defs.h>
|
||||
#if defined (__IBMCPP__) && !defined (_RWSTD_NO_IMPLICIT_INCLUSION)
|
||||
// Disable implicit inclusion to work around
|
||||
// a limitation in IBM's VisualAge 5.0.2.0 (see PR#26959)
|
||||
|
||||
# define _RWSTD_NO_IMPLICIT_INCLUSION
|
||||
#endif
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
// verifies that typeid is correctly declared for MSVC (see PR #25603)
|
||||
void foo ()
|
||||
{
|
||||
_THROW (0); // must appear before #include <typeinfo>
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
#include <typeinfo>
|
||||
#include <driver.h>
|
||||
#include <valcmp.h>
|
||||
|
||||
// polymorphic classes (10.3, p1) used in tests below
|
||||
struct B { virtual ~B () { } };
|
||||
struct D1: B { };
|
||||
struct D2: B { };
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static int
|
||||
run_test (int, char* [])
|
||||
{
|
||||
if (1) {
|
||||
// exercise 18.5, the synopsis of <typeinfo>
|
||||
|
||||
std::type_info *ti = 0;
|
||||
std::bad_cast *bc = 0;
|
||||
std::bad_typeid *bt = 0;
|
||||
|
||||
_RWSTD_UNUSED (ti);
|
||||
_RWSTD_UNUSED (bc);
|
||||
_RWSTD_UNUSED (bt);
|
||||
}
|
||||
|
||||
if (1) {
|
||||
// exercise 18.5.1, class type_info interface
|
||||
|
||||
// 18.5.1, p2
|
||||
bool (std::type_info::*p_op_eq)(const std::type_info&) const =
|
||||
&std::type_info::operator==;
|
||||
|
||||
// 18.5.1, p3
|
||||
bool (std::type_info::*p_op_neq)(const std::type_info&) const =
|
||||
&std::type_info::operator!=;
|
||||
|
||||
// 18.5.1, p5
|
||||
bool (std::type_info::*p_before)(const std::type_info&) const =
|
||||
&std::type_info::before;
|
||||
|
||||
// 18.5.1, p7
|
||||
const char* (std::type_info::*p_name)() const = &std::type_info::name;
|
||||
|
||||
_RWSTD_UNUSED (p_op_eq);
|
||||
_RWSTD_UNUSED (p_op_neq);
|
||||
_RWSTD_UNUSED (p_before);
|
||||
_RWSTD_UNUSED (p_name);
|
||||
}
|
||||
|
||||
if (1) {
|
||||
// exercise 18.5.1, class type_info functionality
|
||||
D1 d1;
|
||||
D2 d2;
|
||||
|
||||
const std::type_info &ti_D1 = typeid (D1);
|
||||
const std::type_info &ti_D2 = typeid (D2);
|
||||
|
||||
const std::type_info &ti_d1 = typeid (d1);
|
||||
const std::type_info &ti_d2 = typeid (d2);
|
||||
|
||||
|
||||
const char *D1_name = ti_D1.name () ? ti_D1.name () : "(D1 null)";
|
||||
const char *D2_name = ti_D2.name () ? ti_D2.name () : "(D2 null)";
|
||||
const char *d1_name = ti_d1.name () ? ti_d1.name () : "(d1 null)";
|
||||
const char *d2_name = ti_d2.name () ? ti_d2.name () : "(d2 null)";
|
||||
|
||||
// 18.5.1, p2
|
||||
rw_assert (ti_D1 == ti_D1, 0, __LINE__,
|
||||
"std::type_info::operator==(): \"%s\" != \"%s\"",
|
||||
D1_name, D1_name);
|
||||
rw_assert (ti_D1 == ti_d1, 0, __LINE__,
|
||||
"std::type_info::operator==(): \"%s\" != \"%s\"",
|
||||
D1_name, d1_name);
|
||||
rw_assert (!(ti_D1 == ti_D2), 0, __LINE__,
|
||||
"std::type_info::operator==(): \"%s\" == \"%s\"",
|
||||
D1_name, D2_name);
|
||||
rw_assert (ti_d1 == ti_d1, 0, __LINE__,
|
||||
"std::type_info::operator==(): \"%s\" != \"%s\"",
|
||||
d1_name, d1_name);
|
||||
rw_assert (ti_d1 == ti_D1, 0, __LINE__,
|
||||
"std::type_info::operator==(): \"%s\" != \"%s\"",
|
||||
d1_name, D1_name);
|
||||
rw_assert (!(ti_d1 == ti_d2), 0, __LINE__,
|
||||
"std::type_info::operator==(): \"%s\" == \"%s\"",
|
||||
d1_name, d2_name);
|
||||
|
||||
// 18.5.1, p3
|
||||
rw_assert (ti_D1 != ti_D2, 0, __LINE__,
|
||||
"std::type_info::operator!=(): \"%s\" == \"%s\"",
|
||||
D1_name, D2_name);
|
||||
rw_assert (ti_D1 != ti_d2, 0, __LINE__,
|
||||
"std::type_info::operator!=(): \"%s\" == \"%s\"",
|
||||
D1_name, d2_name);
|
||||
rw_assert (!(ti_D1 != ti_D1), 0, __LINE__,
|
||||
"std::type_info::operator!=(): \"%s\" != \"%s\"",
|
||||
D1_name, D1_name);
|
||||
rw_assert (ti_d1 != ti_d2, 0, __LINE__,
|
||||
"std::type_info::operator!=(): \"%s\" == \"%s\"",
|
||||
d1_name, d2_name);
|
||||
rw_assert (ti_d1 != ti_D2, 0, __LINE__,
|
||||
"std::type_info::operator!=(): \"%s\" == \"%s\"",
|
||||
d1_name, D2_name);
|
||||
rw_assert (!(ti_d1 != ti_d1), 0, __LINE__,
|
||||
"std::type_info::operator!=(): \"%s\" != \"%s\"",
|
||||
d1_name, d1_name);
|
||||
|
||||
// 18.5.1, p5
|
||||
rw_assert (!ti_D1.before (ti_D1) && !ti_D2.before (ti_D2),
|
||||
0, __LINE__, "std::type_info::before ()");
|
||||
rw_assert (ti_D1.before (ti_D2) || ti_D2.before (ti_D1),
|
||||
0, __LINE__, "std::type_info::before ()");
|
||||
rw_assert (ti_d1.before (ti_d2) || ti_d2.before (ti_d1),
|
||||
0, __LINE__, "std::type_info::before ()");
|
||||
rw_assert (!ti_d1.before (ti_d1) && !ti_d2.before (ti_d2),
|
||||
0, __LINE__, "std::type_info::before ()");
|
||||
|
||||
// 18.5.1, p7
|
||||
rw_assert (0 == rw_strncmp (D1_name, d1_name), 0, __LINE__,
|
||||
"std::type_info::name (): \"%s\" != \"%s\"",
|
||||
D1_name, d1_name);
|
||||
rw_assert (0 != rw_strncmp (D1_name, D2_name), 0, __LINE__,
|
||||
"std::type_info::name (): \"%s\" == \"%s\"",
|
||||
D1_name, D2_name);
|
||||
rw_assert (0 == rw_strncmp (D2_name, d2_name), 0, __LINE__,
|
||||
"std::type_info::name (): \"%s\" != \"%s\"",
|
||||
D2_name, d2_name);
|
||||
rw_assert (0 != rw_strncmp (d1_name, d2_name), 0, __LINE__,
|
||||
"std::type_info::name (): \"%s\" == \"%s\"",
|
||||
d1_name, d2_name);
|
||||
}
|
||||
|
||||
if (1) {
|
||||
// exercise 18.5.2, class bad_cast interface
|
||||
|
||||
// std::bad_cast must publicly derive from std::exception
|
||||
const std::bad_cast *pbc = 0;
|
||||
const std::exception *pe = pbc;
|
||||
|
||||
// 18.5.2, p2
|
||||
std::bad_cast bc;
|
||||
|
||||
// 18.5.2, p4 - copy ctor
|
||||
std::bad_cast bc2 (bc);
|
||||
|
||||
// 18.5.2, p4 - assignment
|
||||
std::bad_cast& (std::bad_cast::*p_op_assign)(const std::bad_cast&)
|
||||
_PTR_THROWS (()) = &std::bad_cast::operator=;
|
||||
|
||||
// 18.5.2, p5
|
||||
const char* (std::bad_cast::*p_what)() const _PTR_THROWS (()) =
|
||||
&std::bad_cast::what;
|
||||
|
||||
_RWSTD_UNUSED (pbc);
|
||||
_RWSTD_UNUSED (pe);
|
||||
_RWSTD_UNUSED (bc);
|
||||
_RWSTD_UNUSED (bc2);
|
||||
_RWSTD_UNUSED (p_op_assign);
|
||||
_RWSTD_UNUSED (p_what);
|
||||
}
|
||||
|
||||
if (1) {
|
||||
// exercise 18.5.2, class bad_cast functionality
|
||||
|
||||
#ifndef _RWSTD_NO_EXCEPTIONS
|
||||
# ifndef _RWSTD_NO_DYNAMIC_CAST
|
||||
|
||||
const char *caught = "no exception";
|
||||
|
||||
D1 d1;
|
||||
B &b = d1;
|
||||
|
||||
try {
|
||||
D2 &d2 = dynamic_cast<D2&>(b);
|
||||
|
||||
_RWSTD_UNUSED (d2);
|
||||
}
|
||||
catch (const std::bad_cast &bc) {
|
||||
caught = "std::bad_cast";
|
||||
|
||||
// 18.5.2, p2
|
||||
std::bad_cast bc2;
|
||||
|
||||
// 18.5.2, p4 - copy ctor
|
||||
std::bad_cast bc3 (bc);
|
||||
|
||||
const char* const bc_what = bc.what ();
|
||||
const char* bc2_what = bc2.what ();
|
||||
const char* const bc3_what = bc3.what ();
|
||||
|
||||
if (0 == bc2_what)
|
||||
rw_assert (false, 0, __LINE__, "bad_cast().what() != 0");
|
||||
|
||||
if (0 == bc3_what)
|
||||
rw_assert (false, 0, __LINE__,
|
||||
"bad_cast::what() != 0 failed "
|
||||
"for a copy of a caught exception object");
|
||||
|
||||
if (bc2_what && bc3_what)
|
||||
rw_warn (0 == rw_strncmp (bc2_what, bc3_what),
|
||||
0, __LINE__,
|
||||
"bad_cast::bad_cast (const bad_cast&): "
|
||||
"\"%s\" != \"%s\"", bc_what, bc3_what);
|
||||
|
||||
// 18.5.2, p4 - assignment
|
||||
bc2 = bc;
|
||||
|
||||
bc2_what = bc2.what ();
|
||||
|
||||
if (0 == bc_what)
|
||||
rw_assert (false, 0, __LINE__,
|
||||
"bad_cast::what() != 0 failed "
|
||||
"for a caught exception object");
|
||||
|
||||
if (0 == bc2_what)
|
||||
rw_assert (false, 0, __LINE__,
|
||||
"bad_cast::what() != 0 failed "
|
||||
"for an assigned exception object");
|
||||
|
||||
if (bc_what && bc2_what)
|
||||
rw_warn (0 == rw_strncmp (bc_what, bc2_what),
|
||||
0, __LINE__,
|
||||
"bad_cast::operator=(const bad_cast&): "
|
||||
"\"%s\" != \"%s\"", bc_what, bc2_what);
|
||||
|
||||
// 18.5.2, p5
|
||||
if (bc_what)
|
||||
rw_assert (0 == rw_strncmp (bc.what (), bc.what ()),
|
||||
0, __LINE__,
|
||||
"bad_cast::what() const: \"%s\" != \"%s\"",
|
||||
bc.what (), bc.what ());
|
||||
}
|
||||
catch (const std::exception&) {
|
||||
caught = "std::exception";
|
||||
}
|
||||
catch (...) {
|
||||
caught = "unknown exception";
|
||||
}
|
||||
|
||||
#if !defined (_RWSTD_NO_STD_BAD_CAST) \
|
||||
|| !defined (_RWSTD_NO_RUNTIME_IN_STD)
|
||||
|
||||
const char expect[] = "std::bad_cast";
|
||||
|
||||
#else
|
||||
|
||||
const char expect[] = "std::bad_cast (alias for ::bad_cast)";
|
||||
|
||||
#endif // !NO_STD_BAD_CAST || !NO_RUNTIME_IN_STD
|
||||
|
||||
rw_assert (0 == rw_strncmp (caught, "std::bad_cast"),
|
||||
0, __LINE__,
|
||||
"dynamic_cast<>() threw %s, expected %s; this suggests "
|
||||
"that bad_cast might be defined in the wrong namespace",
|
||||
caught, expect);
|
||||
|
||||
_RWSTD_UNUSED (d1);
|
||||
_RWSTD_UNUSED (b);
|
||||
|
||||
# endif // _RWSTD_NO_DYNAMIC_CAST
|
||||
#endif // _RWSTD_NO_EXCEPTIONS
|
||||
}
|
||||
|
||||
if (1) {
|
||||
// exercise 18.5.3, class bad_typeid interface
|
||||
|
||||
// std::bad_cast must publicly derive from std::exception
|
||||
const std::bad_typeid *pbt = 0;
|
||||
const std::exception *pe = pbt;
|
||||
|
||||
// 18.5.2, p2
|
||||
std::bad_typeid bt;
|
||||
|
||||
// 18.5.2, p4 - copy ctor
|
||||
std::bad_typeid bt2 (bt);
|
||||
|
||||
// 18.5.2, p4 - assignment
|
||||
std::bad_typeid& (std::bad_typeid::*p_op_assign)(const std::bad_typeid&)
|
||||
_PTR_THROWS (()) = &std::bad_typeid::operator=;
|
||||
|
||||
// 18.5.2, p5
|
||||
const char* (std::bad_typeid::*p_what)() const _PTR_THROWS (()) =
|
||||
&std::bad_typeid::what;
|
||||
|
||||
_RWSTD_UNUSED (pbt);
|
||||
_RWSTD_UNUSED (pe);
|
||||
_RWSTD_UNUSED (bt);
|
||||
_RWSTD_UNUSED (bt2);
|
||||
_RWSTD_UNUSED (p_op_assign);
|
||||
_RWSTD_UNUSED (p_what);
|
||||
}
|
||||
|
||||
if (1) {
|
||||
// exercise 18.5.3, class bad_typeid functionality
|
||||
|
||||
#ifndef _RWSTD_NO_EXCEPTIONS
|
||||
|
||||
const char *caught = "no exception";
|
||||
|
||||
try {
|
||||
|
||||
#if !defined (__GNUG__) || __GNUG__ > 2
|
||||
|
||||
B *b = 0;
|
||||
|
||||
// 5.2.8, p2 - typeid(0) throws std::bad_typeid
|
||||
const std::type_info &ti = typeid (*b);
|
||||
|
||||
_RWSTD_UNUSED (b);
|
||||
_RWSTD_UNUSED (ti);
|
||||
|
||||
#else
|
||||
|
||||
// working around a gcc 2.x bug
|
||||
caught = "SIGSEGV (program dumps core)";
|
||||
|
||||
#endif // gcc < 3.0
|
||||
|
||||
}
|
||||
catch (const std::bad_typeid &bt) {
|
||||
caught = "std::bad_typeid";
|
||||
|
||||
// 18.5.2, p2
|
||||
std::bad_typeid bt2;
|
||||
|
||||
// 18.5.2, p4 - copy ctor
|
||||
std::bad_typeid bt3 (bt);
|
||||
|
||||
// verify that what() returns the same string
|
||||
// after copy construction
|
||||
rw_warn (0 == rw_strncmp (bt.what (), bt3.what ()),
|
||||
0, __LINE__,
|
||||
"std::bad_typeid::bad_typeid (const bad_typeid&): "
|
||||
"\"%s\" != \"%s\"", bt.what (), bt3.what ());
|
||||
|
||||
// 18.5.2, p4 - assignment
|
||||
bt2 = bt;
|
||||
|
||||
// verify that what() returns the same string
|
||||
// after assignment
|
||||
rw_warn (0 == rw_strncmp (bt.what (), bt2.what ()),
|
||||
0, __LINE__,
|
||||
"std::bad_typeid::operator=(const bad_typeid&): "
|
||||
"\"%s\" != \"%s\"", bt.what (), bt2.what ());
|
||||
|
||||
// 18.5.2, p5
|
||||
rw_assert (0 == rw_strncmp (bt.what (), bt.what ()),
|
||||
0, __LINE__,
|
||||
"std::bad_typeid::what() const: "
|
||||
"\"%s\" != \"%s\"", bt.what (), bt.what ());
|
||||
}
|
||||
catch (const std::exception&) {
|
||||
caught = "std::exception";
|
||||
}
|
||||
catch (...) {
|
||||
caught = "unknown exception";
|
||||
}
|
||||
|
||||
#if !defined (_RWSTD_NO_STD_BAD_TYPEID) \
|
||||
|| !defined (_RWSTD_NO_RUNTIME_IN_STD)
|
||||
|
||||
const char expect[] = "std::bad_typeid";
|
||||
|
||||
#else
|
||||
|
||||
const char expect[] = "std::bad_typeid (alias for ::bad_typeid)";
|
||||
|
||||
#endif // !NO_STD_BAD_TYPEID || !NO_RUNTIME_IN_STD
|
||||
|
||||
|
||||
rw_assert (0 == rw_strncmp (caught, "std::bad_typeid"),
|
||||
0, __LINE__,
|
||||
"typeid ((T*)0) threw %s, expected %s; this suggests "
|
||||
"that bad_typeid might be defined in the wrong namespace",
|
||||
caught, expect);
|
||||
|
||||
#endif // _RWSTD_NO_EXCEPTIONS
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main (int argc, char* argv [])
|
||||
{
|
||||
return rw_test (argc, argv, __FILE__,
|
||||
"lib.support.rtti",
|
||||
0 /* no comment */,
|
||||
run_test,
|
||||
"",
|
||||
(void*)0);
|
||||
}
|
||||
382
extern/stdcxx/4.2.1/tests/support/atomic_add.cpp
vendored
Normal file
382
extern/stdcxx/4.2.1/tests/support/atomic_add.cpp
vendored
Normal file
@@ -0,0 +1,382 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 18.atomic.add.cpp - test exercising the __rw_atomic_preincrement()
|
||||
* and __rw_atomic_predecrement function templates
|
||||
*
|
||||
* $Id: atomic_add.cpp 425530 2006-07-25 21:39:50Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* 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 2003-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rw/_mutex.h>
|
||||
|
||||
#include <any.h>
|
||||
#include <cmdopt.h>
|
||||
#include <driver.h>
|
||||
#include <rw_thread.h> // for rw_thread_create()
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
struct thr_args_base
|
||||
{
|
||||
static enum tag_t {
|
||||
Char, SChar, UChar,
|
||||
Short, UShort, Int, UInt, Long, ULong,
|
||||
LLong, ULLong
|
||||
} type_tag_;
|
||||
};
|
||||
|
||||
thr_args_base::tag_t thr_args_base::type_tag_;
|
||||
|
||||
template <class intT>
|
||||
struct thr_args: thr_args_base
|
||||
{
|
||||
unsigned threadno_; // thread ordinal number
|
||||
static int inc_; // increment, decrement, or both
|
||||
static unsigned nincr_; // number of increments
|
||||
static intT *shared_; // shared variables
|
||||
static unsigned nthreads_; // number of threads
|
||||
|
||||
static intT* get_array ();
|
||||
};
|
||||
|
||||
template <class intT>
|
||||
int thr_args<intT>::inc_;
|
||||
|
||||
template <class intT>
|
||||
unsigned thr_args<intT>::nincr_;
|
||||
|
||||
template <class intT>
|
||||
intT* thr_args<intT>::shared_ = thr_args<intT>::get_array ();
|
||||
|
||||
template <class intT>
|
||||
unsigned thr_args<intT>::nthreads_;
|
||||
|
||||
// working around compiler bugs that prevent us from defining
|
||||
// a static array data member of a class template (PR #30009)
|
||||
template <class intT>
|
||||
intT* thr_args<intT>::get_array ()
|
||||
{
|
||||
static intT array [2];
|
||||
return array;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
template <class T>
|
||||
T preincrement (T &x)
|
||||
{
|
||||
#ifndef _RWSTD_REENTRANT
|
||||
|
||||
return ++x;
|
||||
|
||||
#else // if defined (_RWSTD_REENTRANT)
|
||||
|
||||
return _RW::__rw_atomic_preincrement (x, false);
|
||||
|
||||
#endif // _RWSTD_REENTRANT
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
T predecrement (T &x)
|
||||
{
|
||||
#ifndef _RWSTD_REENTRANT
|
||||
|
||||
return --x;
|
||||
|
||||
#else // if defined (_RWSTD_REENTRANT)
|
||||
|
||||
return _RW::__rw_atomic_predecrement (x, false);
|
||||
|
||||
#endif // _RWSTD_REENTRANT
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
template <class intT>
|
||||
void* thread_routine (thr_args<intT> *args)
|
||||
{
|
||||
printf ("thread %u starting to %screment\n",
|
||||
args->threadno_,
|
||||
args->inc_ < 0 ? "de"
|
||||
: args->inc_ > 0 ? "in"
|
||||
: "decrement and in");
|
||||
|
||||
if (args->inc_ > 0) {
|
||||
|
||||
// exercise atomic_preincrement() in a tight loop
|
||||
|
||||
for (unsigned i = 0; i != args->nincr_; ++i) {
|
||||
preincrement (args->shared_ [0]);
|
||||
preincrement (args->shared_ [1]);
|
||||
}
|
||||
}
|
||||
else if (args->inc_ < 0) {
|
||||
|
||||
// exercise atomic_predecrement() in a tight loop
|
||||
|
||||
for (unsigned i = 0; i != args->nincr_; ++i) {
|
||||
predecrement (args->shared_ [0]);
|
||||
predecrement (args->shared_ [1]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
// exercise both atomic_preincrement() and atomic_predecrement()
|
||||
|
||||
for (unsigned i = 0; i != args->nincr_; ++i) {
|
||||
preincrement (args->shared_ [0]);
|
||||
predecrement (args->shared_ [0]);
|
||||
preincrement (args->shared_ [1]);
|
||||
predecrement (args->shared_ [1]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
extern "C" void* thread_routine (void *arg)
|
||||
{
|
||||
thr_args_base* const args = (thr_args_base*)arg;
|
||||
|
||||
switch (args->type_tag_) {
|
||||
|
||||
case thr_args_base::Char:
|
||||
return thread_routine ((thr_args<char>*)(arg));
|
||||
case thr_args_base::SChar:
|
||||
return thread_routine ((thr_args<signed char>*)(arg));
|
||||
case thr_args_base::UChar:
|
||||
return thread_routine ((thr_args<unsigned char>*)(arg));
|
||||
|
||||
case thr_args_base::Short:
|
||||
return thread_routine ((thr_args<short>*)(arg));
|
||||
case thr_args_base::UShort:
|
||||
return thread_routine ((thr_args<unsigned short>*)(arg));
|
||||
|
||||
case thr_args_base::Int:
|
||||
return thread_routine ((thr_args<int>*)(arg));
|
||||
case thr_args_base::UInt:
|
||||
return thread_routine ((thr_args<unsigned int>*)(arg));
|
||||
|
||||
case thr_args_base::Long:
|
||||
return thread_routine ((thr_args<long>*)(arg));
|
||||
case thr_args_base::ULong:
|
||||
return thread_routine ((thr_args<unsigned long>*)(arg));
|
||||
|
||||
#ifdef _RWSTD_LONG_LONG
|
||||
|
||||
case thr_args_base::LLong:
|
||||
return thread_routine ((thr_args<_RWSTD_LONG_LONG>*)(arg));
|
||||
case thr_args_base::ULLong:
|
||||
return thread_routine ((thr_args<unsigned _RWSTD_LONG_LONG>*)(arg));
|
||||
|
||||
#endif // _RWSTD_LONG_LONG
|
||||
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
/* extern */ int rw_opt_nloops = 1024 * 1024;
|
||||
/* extern */ int rw_opt_nthreads = 4;
|
||||
|
||||
#define MAX_THREADS 32
|
||||
|
||||
|
||||
template <class intT>
|
||||
void run_test (intT, thr_args_base::tag_t tag, int inc)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
#if defined (_RWSTD_REENTRANT)
|
||||
|
||||
static const char* const fun =
|
||||
inc < 0 ? "__rw_atomic_predecrement"
|
||||
: inc > 0 ? ":__rw_atomic_preincrement"
|
||||
: "__rw_atomic_pre{in,de}crement";
|
||||
|
||||
rw_info (0, 0, 0, "__rw::%s (%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_ = rw_opt_nthreads;
|
||||
Args::type_tag_ = tag;
|
||||
Args::inc_ = inc;
|
||||
Args::nincr_ = unsigned (rw_opt_nloops);
|
||||
Args::shared_ [0] = intT ();
|
||||
Args::shared_ [1] = intT ();
|
||||
|
||||
_RWSTD_ASSERT (Args::nthreads_ < sizeof tid / sizeof *tid);
|
||||
|
||||
Args args [sizeof tid / sizeof *tid];
|
||||
|
||||
memset (args, 0, sizeof args);
|
||||
|
||||
for (unsigned i = 0; i != Args::nthreads_; ++i) {
|
||||
|
||||
args [i].threadno_ = i;
|
||||
|
||||
rw_fatal (0 == rw_thread_create (tid + i, 0, thread_routine, args + i),
|
||||
0, __LINE__, "thread_create() failed");
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i != Args::nthreads_; ++i) {
|
||||
|
||||
rw_error (0 == rw_thread_join (tid [i], 0), 0, __LINE__,
|
||||
"thread_join() failed");
|
||||
}
|
||||
|
||||
// compute the expected result
|
||||
intT expect = intT ();
|
||||
|
||||
if (inc < 0) {
|
||||
for (unsigned i = 0; i != Args::nthreads_ * Args::nincr_; ++i)
|
||||
--expect;
|
||||
}
|
||||
else if (inc > 0) {
|
||||
for (unsigned i = 0; i != Args::nthreads_ * Args::nincr_; ++i)
|
||||
++expect;
|
||||
}
|
||||
|
||||
// verify that the final value of the variable shared among all
|
||||
// threads equals the number of increments or decrements performed
|
||||
// by all threads
|
||||
rw_assert (Args::shared_ [0] == expect, 0, __LINE__,
|
||||
"1. %s (%s&); %s == %s failed",
|
||||
fun, tname, TOSTR (Args::shared_ [0]), TOSTR (expect));
|
||||
|
||||
rw_assert (Args::shared_ [1] == expect, 0, __LINE__,
|
||||
"2. %s (%s&); %s == %s failed",
|
||||
fun, tname, TOSTR (Args::shared_ [1]), TOSTR (expect));
|
||||
|
||||
#else // if !defined (_RWSTD_REENTRANT)
|
||||
|
||||
_RWSTD_UNUSED (tag);
|
||||
_RWSTD_UNUSED (inc);
|
||||
|
||||
#endif // _RWSTD_REENTRANT
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static int
|
||||
run_test (int, char**)
|
||||
{
|
||||
// exercise atomic subtract
|
||||
run_test ((char)0, thr_args_base::Char, -1);
|
||||
run_test ((signed char)0, thr_args_base::SChar, -1);
|
||||
run_test ((unsigned char)0, thr_args_base::UChar, -1);
|
||||
|
||||
run_test ((short)0, thr_args_base::Short, -1);
|
||||
run_test ((unsigned short)0, thr_args_base::UShort, -1);
|
||||
|
||||
run_test ((int)0, thr_args_base::Int, -1);
|
||||
run_test ((unsigned int)0, thr_args_base::UInt, -1);
|
||||
|
||||
run_test ((long)0, thr_args_base::Long, -1);
|
||||
run_test ((unsigned long)0, thr_args_base::ULong, -1);
|
||||
|
||||
#ifdef _RWSTD_LONG_LONG
|
||||
|
||||
run_test ((_RWSTD_LONG_LONG)0, thr_args_base::LLong, -1);
|
||||
run_test ((unsigned _RWSTD_LONG_LONG)0, thr_args_base::ULLong, -1);
|
||||
|
||||
#endif // _RWSTD_LONG_LONG
|
||||
|
||||
// exercise atomic add
|
||||
run_test ((char)0, thr_args_base::Char, +1);
|
||||
run_test ((signed char)0, thr_args_base::SChar, +1);
|
||||
run_test ((unsigned char)0, thr_args_base::UChar, +1);
|
||||
|
||||
run_test ((short)0, thr_args_base::Short, +1);
|
||||
run_test ((unsigned short)0, thr_args_base::UShort, +1);
|
||||
|
||||
run_test ((int)0, thr_args_base::Int, +1);
|
||||
run_test ((unsigned int)0, thr_args_base::UInt, +1);
|
||||
|
||||
run_test ((long)0, thr_args_base::Long, +1);
|
||||
run_test ((unsigned long)0, thr_args_base::ULong, +1);
|
||||
|
||||
#ifdef _RWSTD_LONG_LONG
|
||||
|
||||
run_test ((_RWSTD_LONG_LONG)0, thr_args_base::LLong, +1);
|
||||
run_test ((unsigned _RWSTD_LONG_LONG)0, thr_args_base::ULLong, +1);
|
||||
|
||||
#endif // _RWSTD_LONG_LONG
|
||||
|
||||
|
||||
// exercise both atomic add and subtract
|
||||
run_test ((char)0, thr_args_base::Char, 0);
|
||||
run_test ((signed char)0, thr_args_base::SChar, 0);
|
||||
run_test ((unsigned char)0, thr_args_base::UChar, 0);
|
||||
|
||||
run_test ((short)0, thr_args_base::Short, 0);
|
||||
run_test ((unsigned short)0, thr_args_base::UShort, 0);
|
||||
|
||||
run_test ((int)0, thr_args_base::Int, 0);
|
||||
run_test ((unsigned int)0, thr_args_base::UInt, 0);
|
||||
|
||||
run_test ((long)0, thr_args_base::Long, 0);
|
||||
run_test ((unsigned long)0, thr_args_base::ULong, 0);
|
||||
|
||||
#ifdef _RWSTD_LONG_LONG
|
||||
|
||||
run_test ((_RWSTD_LONG_LONG)0, thr_args_base::LLong, 0);
|
||||
run_test ((unsigned _RWSTD_LONG_LONG)0, thr_args_base::ULLong, 0);
|
||||
|
||||
#endif // _RWSTD_LONG_LONG
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
return rw_test (argc, argv, __FILE__,
|
||||
0 /* no clause */,
|
||||
0 /* no comment */,
|
||||
run_test,
|
||||
"|-nloops#0 " // must be non-negative
|
||||
"|-nthreads#0-*" , // must be in [0, MAX_THREADS]
|
||||
&rw_opt_nloops,
|
||||
int (MAX_THREADS),
|
||||
&rw_opt_nthreads);
|
||||
}
|
||||
368
extern/stdcxx/4.2.1/tests/support/atomic_xchg.cpp
vendored
Normal file
368
extern/stdcxx/4.2.1/tests/support/atomic_xchg.cpp
vendored
Normal file
@@ -0,0 +1,368 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 18.atomic.xchg.cpp - test exercising the __rw_atomic_exchange() function
|
||||
* template
|
||||
*
|
||||
* $Id: atomic_xchg.cpp 580483 2007-09-28 20:55:52Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* 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 2003-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rw/_mutex.h>
|
||||
|
||||
#include <any.h>
|
||||
#include <cmdopt.h>
|
||||
#include <driver.h>
|
||||
#include <rw_thread.h> // for rw_thread_create()
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
struct thr_args_base
|
||||
{
|
||||
static enum tag_t {
|
||||
Char, SChar, UChar,
|
||||
Short, UShort, Int, UInt, Long, ULong,
|
||||
LLong, ULLong
|
||||
} type_tag_;
|
||||
|
||||
unsigned long threadno_; // thread ordinal number
|
||||
unsigned long niter_; // number of iterations
|
||||
unsigned long nxchg_; // number of exchanges
|
||||
};
|
||||
|
||||
thr_args_base::tag_t thr_args_base::type_tag_;
|
||||
|
||||
template <class intT>
|
||||
struct thr_args: thr_args_base
|
||||
{
|
||||
static unsigned long nincr_; // number of increments
|
||||
static intT *shared_; // shared variables
|
||||
static unsigned long nthreads_; // number of threads
|
||||
|
||||
static intT* get_array ();
|
||||
};
|
||||
|
||||
template <class intT>
|
||||
unsigned long thr_args<intT>::nincr_;
|
||||
|
||||
template <class intT>
|
||||
intT* thr_args<intT>::shared_ = thr_args<intT>::get_array ();
|
||||
|
||||
template <class intT>
|
||||
unsigned long thr_args<intT>::nthreads_;
|
||||
|
||||
// working around compiler bugs that prevent us from defining
|
||||
// a static array data member of a class template (PR #30009)
|
||||
template <class intT>
|
||||
/* static */ intT* thr_args<intT>::get_array ()
|
||||
{
|
||||
static intT array [2];
|
||||
return array;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
template <class intT>
|
||||
intT exchange (intT &x, intT y)
|
||||
{
|
||||
#ifndef _RWSTD_REENTRANT
|
||||
|
||||
intT save (x);
|
||||
|
||||
x = y;
|
||||
|
||||
return save;
|
||||
|
||||
#else // if defined (_RWSTD_REENTRANT)
|
||||
|
||||
return _RW::__rw_atomic_exchange (x, y, false);
|
||||
|
||||
#endif // _RWSTD_REENTRANT
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
template <class intT>
|
||||
void* thread_routine (thr_args<intT> *args)
|
||||
{
|
||||
// each thread operates on one of two shared values to exercise
|
||||
// problems due to operating on adjacent bytes or half-words
|
||||
const unsigned long inx = args->threadno_ % 2;
|
||||
|
||||
static volatile int failed;
|
||||
|
||||
// exercise atomic_exchange() in a tight loop
|
||||
|
||||
// perform the requested number increments, or until the
|
||||
// shared `failed' variable is set to a non-zero value
|
||||
|
||||
for (unsigned long i = 0; i != args->nincr_ && !failed; ++i) {
|
||||
|
||||
for (unsigned long j = 0; !failed; ++j) {
|
||||
|
||||
// increment the number of iterations of this thread
|
||||
++args->niter_;
|
||||
|
||||
// use intT() as a special "lock" value
|
||||
const intT old = exchange (args->shared_ [inx], intT ());
|
||||
|
||||
// increment the number of exchanges performed by this thread
|
||||
++args->nxchg_;
|
||||
|
||||
if (intT () != old) {
|
||||
|
||||
// shared variable was not locked by any other thread
|
||||
|
||||
// increment the value of the shared variable, taking
|
||||
// care to avoid the special "lock" value of intT()
|
||||
intT newval = intT (old + 1);
|
||||
|
||||
if (intT () == newval)
|
||||
++newval;
|
||||
|
||||
const intT lock = exchange (args->shared_ [inx], newval);
|
||||
|
||||
// increment the number of exchanges
|
||||
++args->nxchg_;
|
||||
|
||||
// the returned value must be the special "lock" value
|
||||
if (intT () == lock)
|
||||
break;
|
||||
|
||||
// fail by setting the shared failed variable (to
|
||||
// prevent deadlock) if the returned value is not
|
||||
// the special "lock" value
|
||||
|
||||
printf ("*** line %d: error: thread %lu failed "
|
||||
"at increment %lu after %lu iterations\n",
|
||||
__LINE__, args->threadno_, i, args->niter_);
|
||||
failed = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (100UL * args->nincr_ == j) {
|
||||
|
||||
// fail by setting the shared failed variable (to
|
||||
// prevent deadlock) if the number of failed attempts
|
||||
// to lock the shared variable reaches the requested
|
||||
// number of increments * 100 (an arbitrary number)
|
||||
|
||||
printf ("*** line %d: error thread %lu \"timed out\" after "
|
||||
"%lu increments and %lu iterations\n",
|
||||
__LINE__, args->threadno_, i, args->niter_);
|
||||
failed = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
extern "C" void* thread_routine (void *arg)
|
||||
{
|
||||
thr_args_base* const args = (thr_args_base*)arg;
|
||||
|
||||
printf ("thread %lu starting\n", args->threadno_);
|
||||
|
||||
switch (args->type_tag_) {
|
||||
|
||||
case thr_args_base::Char:
|
||||
return thread_routine ((thr_args<char>*)(arg));
|
||||
case thr_args_base::SChar:
|
||||
return thread_routine ((thr_args<signed char>*)(arg));
|
||||
case thr_args_base::UChar:
|
||||
return thread_routine ((thr_args<unsigned char>*)(arg));
|
||||
|
||||
case thr_args_base::Short:
|
||||
return thread_routine ((thr_args<short>*)(arg));
|
||||
case thr_args_base::UShort:
|
||||
return thread_routine ((thr_args<unsigned short>*)(arg));
|
||||
|
||||
case thr_args_base::Int:
|
||||
return thread_routine ((thr_args<int>*)(arg));
|
||||
case thr_args_base::UInt:
|
||||
return thread_routine ((thr_args<unsigned int>*)(arg));
|
||||
|
||||
case thr_args_base::Long:
|
||||
return thread_routine ((thr_args<long>*)(arg));
|
||||
case thr_args_base::ULong:
|
||||
return thread_routine ((thr_args<unsigned long>*)(arg));
|
||||
|
||||
#ifdef _RWSTD_LONG_LONG
|
||||
|
||||
case thr_args_base::LLong:
|
||||
return thread_routine ((thr_args<_RWSTD_LONG_LONG>*)(arg));
|
||||
case thr_args_base::ULLong:
|
||||
return thread_routine ((thr_args<unsigned _RWSTD_LONG_LONG>*)(arg));
|
||||
|
||||
#endif // _RWSTD_LONG_LONG
|
||||
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
/* extern */ int rw_opt_nloops = 1024 * 1024;
|
||||
/* extern */ int rw_opt_nthreads = 4;
|
||||
|
||||
#define MAX_THREADS 32
|
||||
|
||||
|
||||
template <class intT>
|
||||
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
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static int
|
||||
run_test (int, char**)
|
||||
{
|
||||
// exercise atomic exchange
|
||||
run_test ((char)0, thr_args_base::Char);
|
||||
run_test ((signed char)0, thr_args_base::SChar);
|
||||
run_test ((unsigned char)0, thr_args_base::UChar);
|
||||
|
||||
run_test ((short)0, thr_args_base::Short);
|
||||
run_test ((unsigned short)0, thr_args_base::UShort);
|
||||
|
||||
run_test ((int)0, thr_args_base::Int);
|
||||
run_test ((unsigned int)0, thr_args_base::UInt);
|
||||
|
||||
run_test ((long)0, thr_args_base::Long);
|
||||
run_test ((unsigned long)0, thr_args_base::ULong);
|
||||
|
||||
#ifdef _RWSTD_LONG_LONG
|
||||
|
||||
run_test ((_RWSTD_LONG_LONG)0, thr_args_base::LLong);
|
||||
run_test ((unsigned _RWSTD_LONG_LONG)0, thr_args_base::ULLong);
|
||||
|
||||
#endif // _RWSTD_LONG_LONG
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
return rw_test (argc, argv, __FILE__,
|
||||
0 /* no clause */,
|
||||
0 /* no comment */, run_test,
|
||||
"|-nloops#0 " // must be non-negative
|
||||
"|-nthreads#0-*", // must be in [0, MAX_THREADS]
|
||||
&rw_opt_nloops,
|
||||
int (MAX_THREADS),
|
||||
&rw_opt_nthreads);
|
||||
}
|
||||
Reference in New Issue
Block a user