mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-03 10:54:42 +00:00
Merge gtest-1.4.0.
llvm-svn: 105353
This commit is contained in:
parent
82e5e91f69
commit
fa12ea38cc
@ -204,15 +204,7 @@ void DeathTestAbort(const String& message) {
|
||||
const InternalRunDeathTestFlag* const flag =
|
||||
GetUnitTestImpl()->internal_run_death_test_flag();
|
||||
if (flag != NULL) {
|
||||
// Suppress MSVC complaints about POSIX functions.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4996)
|
||||
#endif // _MSC_VER
|
||||
FILE* parent = fdopen(flag->status_fd(), "w");
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif // _MSC_VER
|
||||
FILE* parent = posix::FDOpen(flag->write_fd(), "w");
|
||||
fputc(kDeathTestInternalError, parent);
|
||||
fprintf(parent, "%s", message.c_str());
|
||||
fflush(parent);
|
||||
@ -228,12 +220,12 @@ void DeathTestAbort(const String& message) {
|
||||
// fails.
|
||||
#define GTEST_DEATH_TEST_CHECK_(expression) \
|
||||
do { \
|
||||
if (!(expression)) { \
|
||||
DeathTestAbort(::testing::internal::String::Format(\
|
||||
if (!::testing::internal::IsTrue(expression)) { \
|
||||
DeathTestAbort(::testing::internal::String::Format( \
|
||||
"CHECK failed: File %s, line %d: %s", \
|
||||
__FILE__, __LINE__, #expression)); \
|
||||
} \
|
||||
} while (0)
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for
|
||||
// evaluating any system call that fulfills two conditions: it must return
|
||||
@ -249,53 +241,41 @@ void DeathTestAbort(const String& message) {
|
||||
gtest_retval = (expression); \
|
||||
} while (gtest_retval == -1 && errno == EINTR); \
|
||||
if (gtest_retval == -1) { \
|
||||
DeathTestAbort(::testing::internal::String::Format(\
|
||||
DeathTestAbort(::testing::internal::String::Format( \
|
||||
"CHECK failed: File %s, line %d: %s != -1", \
|
||||
__FILE__, __LINE__, #expression)); \
|
||||
} \
|
||||
} while (0)
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
// Returns the message describing the last system error, regardless of the
|
||||
// platform.
|
||||
String GetLastSystemErrorMessage() {
|
||||
#if GTEST_OS_WINDOWS
|
||||
const DWORD error_num = ::GetLastError();
|
||||
|
||||
if (error_num == NULL)
|
||||
return String("");
|
||||
|
||||
char* message_ptr;
|
||||
|
||||
::FormatMessageA(
|
||||
// The caller does not provide a buffer. The function will allocate one.
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
// The function must look up an error message in its system error
|
||||
// message table.
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
// Do not expand insert sequences in the message definition.
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, // Message source. Ignored in this call.
|
||||
error_num,
|
||||
0x0, // Use system-default language.
|
||||
reinterpret_cast<LPSTR>(&message_ptr),
|
||||
0, // Buffer size. Ignored in this call.
|
||||
NULL); // Message arguments. Ignored in this call.
|
||||
|
||||
const String message = message_ptr;
|
||||
::LocalFree(message_ptr);
|
||||
return message;
|
||||
#else
|
||||
return errno == 0 ? String("") : String(strerror(errno));
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
// Returns the message describing the last system error in errno.
|
||||
String GetLastErrnoDescription() {
|
||||
return String(errno == 0 ? "" : posix::StrError(errno));
|
||||
}
|
||||
|
||||
// TODO(vladl@google.com): Move the definition of FailFromInternalError
|
||||
// here.
|
||||
#if GTEST_OS_WINDOWS
|
||||
static void FailFromInternalError(HANDLE handle);
|
||||
#else
|
||||
static void FailFromInternalError(int fd);
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
// This is called from a death test parent process to read a failure
|
||||
// message from the death test child process and log it with the FATAL
|
||||
// severity. On Windows, the message is read from a pipe handle. On other
|
||||
// platforms, it is read from a file descriptor.
|
||||
static void FailFromInternalError(int fd) {
|
||||
Message error;
|
||||
char buffer[256];
|
||||
int num_read;
|
||||
|
||||
do {
|
||||
while ((num_read = posix::Read(fd, buffer, 255)) > 0) {
|
||||
buffer[num_read] = '\0';
|
||||
error << buffer;
|
||||
}
|
||||
} while (num_read == -1 && errno == EINTR);
|
||||
|
||||
if (num_read == 0) {
|
||||
GTEST_LOG_(FATAL) << error.GetString();
|
||||
} else {
|
||||
const int last_error = errno;
|
||||
GTEST_LOG_(FATAL) << "Error while reading death test internal: "
|
||||
<< GetLastErrnoDescription() << " [" << last_error << "]";
|
||||
}
|
||||
}
|
||||
|
||||
// Death test constructor. Increments the running death test count
|
||||
// for the current test.
|
||||
@ -326,8 +306,6 @@ void DeathTest::set_last_death_test_message(const String& message) {
|
||||
String DeathTest::last_death_test_message_;
|
||||
|
||||
// Provides cross platform implementation for some death functionality.
|
||||
// TODO(vladl@google.com): Merge this class with DeathTest in
|
||||
// gtest-death-test-internal.h.
|
||||
class DeathTestImpl : public DeathTest {
|
||||
protected:
|
||||
DeathTestImpl(const char* statement, const RE* regex)
|
||||
@ -335,8 +313,14 @@ class DeathTestImpl : public DeathTest {
|
||||
regex_(regex),
|
||||
spawned_(false),
|
||||
status_(-1),
|
||||
outcome_(IN_PROGRESS) {}
|
||||
outcome_(IN_PROGRESS),
|
||||
read_fd_(-1),
|
||||
write_fd_(-1) {}
|
||||
|
||||
// read_fd_ is expected to be closed and cleared by a derived class.
|
||||
~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); }
|
||||
|
||||
void Abort(AbortReason reason);
|
||||
virtual bool Passed(bool status_ok);
|
||||
|
||||
const char* statement() const { return statement_; }
|
||||
@ -347,6 +331,16 @@ class DeathTestImpl : public DeathTest {
|
||||
void set_status(int status) { status_ = status; }
|
||||
DeathTestOutcome outcome() const { return outcome_; }
|
||||
void set_outcome(DeathTestOutcome outcome) { outcome_ = outcome; }
|
||||
int read_fd() const { return read_fd_; }
|
||||
void set_read_fd(int fd) { read_fd_ = fd; }
|
||||
int write_fd() const { return write_fd_; }
|
||||
void set_write_fd(int fd) { write_fd_ = fd; }
|
||||
|
||||
// Called in the parent process only. Reads the result code of the death
|
||||
// test child process via a pipe, interprets it to set the outcome_
|
||||
// member, and closes read_fd_. Outputs diagnostics and terminates in
|
||||
// case of unexpected codes.
|
||||
void ReadAndInterpretStatusByte();
|
||||
|
||||
private:
|
||||
// The textual content of the code this object is testing. This class
|
||||
@ -361,9 +355,138 @@ class DeathTestImpl : public DeathTest {
|
||||
int status_;
|
||||
// How the death test concluded.
|
||||
DeathTestOutcome outcome_;
|
||||
// Descriptor to the read end of the pipe to the child process. It is
|
||||
// always -1 in the child process. The child keeps its write end of the
|
||||
// pipe in write_fd_.
|
||||
int read_fd_;
|
||||
// Descriptor to the child's write end of the pipe to the parent process.
|
||||
// It is always -1 in the parent process. The parent keeps its end of the
|
||||
// pipe in read_fd_.
|
||||
int write_fd_;
|
||||
};
|
||||
|
||||
// TODO(vladl@google.com): Move definition of DeathTestImpl::Passed() here.
|
||||
// Called in the parent process only. Reads the result code of the death
|
||||
// test child process via a pipe, interprets it to set the outcome_
|
||||
// member, and closes read_fd_. Outputs diagnostics and terminates in
|
||||
// case of unexpected codes.
|
||||
void DeathTestImpl::ReadAndInterpretStatusByte() {
|
||||
char flag;
|
||||
int bytes_read;
|
||||
|
||||
// The read() here blocks until data is available (signifying the
|
||||
// failure of the death test) or until the pipe is closed (signifying
|
||||
// its success), so it's okay to call this in the parent before
|
||||
// the child process has exited.
|
||||
do {
|
||||
bytes_read = posix::Read(read_fd(), &flag, 1);
|
||||
} while (bytes_read == -1 && errno == EINTR);
|
||||
|
||||
if (bytes_read == 0) {
|
||||
set_outcome(DIED);
|
||||
} else if (bytes_read == 1) {
|
||||
switch (flag) {
|
||||
case kDeathTestReturned:
|
||||
set_outcome(RETURNED);
|
||||
break;
|
||||
case kDeathTestLived:
|
||||
set_outcome(LIVED);
|
||||
break;
|
||||
case kDeathTestInternalError:
|
||||
FailFromInternalError(read_fd()); // Does not return.
|
||||
break;
|
||||
default:
|
||||
GTEST_LOG_(FATAL) << "Death test child process reported "
|
||||
<< "unexpected status byte ("
|
||||
<< static_cast<unsigned int>(flag) << ")";
|
||||
}
|
||||
} else {
|
||||
GTEST_LOG_(FATAL) << "Read from death test child process failed: "
|
||||
<< GetLastErrnoDescription();
|
||||
}
|
||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd()));
|
||||
set_read_fd(-1);
|
||||
}
|
||||
|
||||
// Signals that the death test code which should have exited, didn't.
|
||||
// Should be called only in a death test child process.
|
||||
// Writes a status byte to the child's status file descriptor, then
|
||||
// calls _exit(1).
|
||||
void DeathTestImpl::Abort(AbortReason reason) {
|
||||
// The parent process considers the death test to be a failure if
|
||||
// it finds any data in our pipe. So, here we write a single flag byte
|
||||
// to the pipe, then exit.
|
||||
const char status_ch =
|
||||
reason == TEST_DID_NOT_DIE ? kDeathTestLived : kDeathTestReturned;
|
||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));
|
||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(write_fd()));
|
||||
_exit(1); // Exits w/o any normal exit hooks (we were supposed to crash)
|
||||
}
|
||||
|
||||
// Assesses the success or failure of a death test, using both private
|
||||
// members which have previously been set, and one argument:
|
||||
//
|
||||
// Private data members:
|
||||
// outcome: An enumeration describing how the death test
|
||||
// concluded: DIED, LIVED, or RETURNED. The death test fails
|
||||
// in the latter two cases.
|
||||
// status: The exit status of the child process. On *nix, it is in the
|
||||
// in the format specified by wait(2). On Windows, this is the
|
||||
// value supplied to the ExitProcess() API or a numeric code
|
||||
// of the exception that terminated the program.
|
||||
// regex: A regular expression object to be applied to
|
||||
// the test's captured standard error output; the death test
|
||||
// fails if it does not match.
|
||||
//
|
||||
// Argument:
|
||||
// status_ok: true if exit_status is acceptable in the context of
|
||||
// this particular death test, which fails if it is false
|
||||
//
|
||||
// Returns true iff all of the above conditions are met. Otherwise, the
|
||||
// first failing condition, in the order given above, is the one that is
|
||||
// reported. Also sets the last death test message string.
|
||||
bool DeathTestImpl::Passed(bool status_ok) {
|
||||
if (!spawned())
|
||||
return false;
|
||||
|
||||
const String error_message = GetCapturedStderr();
|
||||
|
||||
bool success = false;
|
||||
Message buffer;
|
||||
|
||||
buffer << "Death test: " << statement() << "\n";
|
||||
switch (outcome()) {
|
||||
case LIVED:
|
||||
buffer << " Result: failed to die.\n"
|
||||
<< " Error msg: " << error_message;
|
||||
break;
|
||||
case RETURNED:
|
||||
buffer << " Result: illegal return in test statement.\n"
|
||||
<< " Error msg: " << error_message;
|
||||
break;
|
||||
case DIED:
|
||||
if (status_ok) {
|
||||
const bool matched = RE::PartialMatch(error_message.c_str(), *regex());
|
||||
if (matched) {
|
||||
success = true;
|
||||
} else {
|
||||
buffer << " Result: died but not with expected error.\n"
|
||||
<< " Expected: " << regex()->pattern() << "\n"
|
||||
<< "Actual msg: " << error_message;
|
||||
}
|
||||
} else {
|
||||
buffer << " Result: died but not with expected exit code:\n"
|
||||
<< " " << ExitSummary(status()) << "\n";
|
||||
}
|
||||
break;
|
||||
case IN_PROGRESS:
|
||||
default:
|
||||
GTEST_LOG_(FATAL)
|
||||
<< "DeathTest::Passed somehow called before conclusion of test";
|
||||
}
|
||||
|
||||
DeathTest::set_last_death_test_message(buffer.GetString());
|
||||
return success;
|
||||
}
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
// WindowsDeathTest implements death tests on Windows. Due to the
|
||||
@ -404,7 +527,6 @@ class WindowsDeathTest : public DeathTestImpl {
|
||||
|
||||
// All of these virtual functions are inherited from DeathTest.
|
||||
virtual int Wait();
|
||||
virtual void Abort(AbortReason reason);
|
||||
virtual TestRole AssumeRole();
|
||||
|
||||
private:
|
||||
@ -412,10 +534,6 @@ class WindowsDeathTest : public DeathTestImpl {
|
||||
const char* const file_;
|
||||
// The line number on which the death test is located.
|
||||
const int line_;
|
||||
// Handle to the read end of the pipe to the child process.
|
||||
// The child keeps its write end of the pipe in the status_handle_
|
||||
// field of its InternalRunDeathTestFlag class.
|
||||
AutoHandle read_handle_;
|
||||
// Handle to the write end of the pipe to the child process.
|
||||
AutoHandle write_handle_;
|
||||
// Child process handle.
|
||||
@ -430,9 +548,6 @@ class WindowsDeathTest : public DeathTestImpl {
|
||||
// Waits for the child in a death test to exit, returning its exit
|
||||
// status, or 0 if no child process exists. As a side effect, sets the
|
||||
// outcome data member.
|
||||
// TODO(vladl@google.com): Outcome classification logic is common with
|
||||
// ForkingDeathTes::Wait(). Refactor it into a
|
||||
// common function.
|
||||
int WindowsDeathTest::Wait() {
|
||||
if (!spawned())
|
||||
return 0;
|
||||
@ -456,44 +571,7 @@ int WindowsDeathTest::Wait() {
|
||||
write_handle_.Reset();
|
||||
event_handle_.Reset();
|
||||
|
||||
// ReadFile() blocks until data is available (signifying the
|
||||
// failure of the death test) or until the pipe is closed (signifying
|
||||
// its success), so it's okay to call this in the parent before or
|
||||
// after the child process has exited.
|
||||
char flag;
|
||||
DWORD bytes_read;
|
||||
GTEST_DEATH_TEST_CHECK_(::ReadFile(read_handle_.Get(),
|
||||
&flag,
|
||||
1,
|
||||
&bytes_read,
|
||||
NULL) ||
|
||||
::GetLastError() == ERROR_BROKEN_PIPE);
|
||||
|
||||
if (bytes_read == 0) {
|
||||
set_outcome(DIED);
|
||||
} else if (bytes_read == 1) {
|
||||
switch (flag) {
|
||||
case kDeathTestReturned:
|
||||
set_outcome(RETURNED);
|
||||
break;
|
||||
case kDeathTestLived:
|
||||
set_outcome(LIVED);
|
||||
break;
|
||||
case kDeathTestInternalError:
|
||||
FailFromInternalError(read_handle_.Get()); // Does not return.
|
||||
break;
|
||||
default:
|
||||
GTEST_LOG_(FATAL,
|
||||
Message() << "Death test child process reported "
|
||||
<< " unexpected status byte ("
|
||||
<< static_cast<unsigned int>(flag) << ")");
|
||||
}
|
||||
} else {
|
||||
GTEST_LOG_(FATAL,
|
||||
Message() << "Read from death test child process failed: "
|
||||
<< GetLastSystemErrorMessage());
|
||||
}
|
||||
read_handle_.Reset(); // Done with reading.
|
||||
ReadAndInterpretStatusByte();
|
||||
|
||||
// Waits for the child process to exit if it haven't already. This
|
||||
// returns immediately if the child has already exited, regardless of
|
||||
@ -503,41 +581,13 @@ int WindowsDeathTest::Wait() {
|
||||
WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(),
|
||||
INFINITE));
|
||||
DWORD status;
|
||||
GTEST_DEATH_TEST_CHECK_(::GetExitCodeProcess(child_handle_.Get(),
|
||||
&status));
|
||||
GTEST_DEATH_TEST_CHECK_(::GetExitCodeProcess(child_handle_.Get(), &status)
|
||||
!= FALSE);
|
||||
child_handle_.Reset();
|
||||
set_status(static_cast<int>(status));
|
||||
return this->status();
|
||||
}
|
||||
|
||||
// TODO(vladl@google.com): define a cross-platform way to write to
|
||||
// status_fd to be used both here and in ForkingDeathTest::Abort().
|
||||
//
|
||||
// Signals that the death test did not die as expected. This is called
|
||||
// from the child process only.
|
||||
void WindowsDeathTest::Abort(AbortReason reason) {
|
||||
const InternalRunDeathTestFlag* const internal_flag =
|
||||
GetUnitTestImpl()->internal_run_death_test_flag();
|
||||
// The parent process considers the death test to be a failure if
|
||||
// it finds any data in our pipe. So, here we write a single flag byte
|
||||
// to the pipe, then exit.
|
||||
const char status_ch =
|
||||
reason == TEST_DID_NOT_DIE ? kDeathTestLived : kDeathTestReturned;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4996)
|
||||
#endif // _MSC_VER
|
||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(write(internal_flag->status_fd(),
|
||||
&status_ch, 1));
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif // _MSC_VER
|
||||
|
||||
// The write handle will be closed when the child terminates in _exit().
|
||||
_exit(1); // Exits w/o any normal exit hooks (we were supposed to crash)
|
||||
}
|
||||
|
||||
// The AssumeRole process for a Windows death test. It creates a child
|
||||
// process with the same executable as the current process to run the
|
||||
// death test. The child process is given the --gtest_filter and
|
||||
@ -553,6 +603,7 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
|
||||
if (flag != NULL) {
|
||||
// ParseInternalRunDeathTestFlag() has performed all the necessary
|
||||
// processing.
|
||||
set_write_fd(flag->write_fd());
|
||||
return EXECUTE_TEST;
|
||||
}
|
||||
|
||||
@ -561,10 +612,12 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
|
||||
SECURITY_ATTRIBUTES handles_are_inheritable = {
|
||||
sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
|
||||
HANDLE read_handle, write_handle;
|
||||
GTEST_DEATH_TEST_CHECK_(::CreatePipe(&read_handle, &write_handle,
|
||||
&handles_are_inheritable,
|
||||
0)); // Default buffer size.
|
||||
read_handle_.Reset(read_handle);
|
||||
GTEST_DEATH_TEST_CHECK_(
|
||||
::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable,
|
||||
0) // Default buffer size.
|
||||
!= FALSE);
|
||||
set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle),
|
||||
O_RDONLY));
|
||||
write_handle_.Reset(write_handle);
|
||||
event_handle_.Reset(::CreateEvent(
|
||||
&handles_are_inheritable,
|
||||
@ -625,7 +678,7 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
|
||||
NULL, // Inherit the parent's environment.
|
||||
UnitTest::GetInstance()->original_working_dir(),
|
||||
&startup_info,
|
||||
&process_info));
|
||||
&process_info) != FALSE);
|
||||
child_handle_.Reset(process_info.hProcess);
|
||||
::CloseHandle(process_info.hThread);
|
||||
set_spawned(true);
|
||||
@ -642,92 +695,20 @@ class ForkingDeathTest : public DeathTestImpl {
|
||||
|
||||
// All of these virtual functions are inherited from DeathTest.
|
||||
virtual int Wait();
|
||||
virtual void Abort(AbortReason reason);
|
||||
|
||||
protected:
|
||||
void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }
|
||||
void set_read_fd(int fd) { read_fd_ = fd; }
|
||||
void set_write_fd(int fd) { write_fd_ = fd; }
|
||||
|
||||
private:
|
||||
// PID of child process during death test; 0 in the child process itself.
|
||||
pid_t child_pid_;
|
||||
// File descriptors for communicating the death test's status byte.
|
||||
int read_fd_; // Always -1 in the child process.
|
||||
int write_fd_; // Always -1 in the parent process.
|
||||
};
|
||||
|
||||
// Constructs a ForkingDeathTest.
|
||||
ForkingDeathTest::ForkingDeathTest(const char* statement, const RE* regex)
|
||||
: DeathTestImpl(statement, regex),
|
||||
child_pid_(-1),
|
||||
read_fd_(-1),
|
||||
write_fd_(-1) {
|
||||
}
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
child_pid_(-1) {}
|
||||
|
||||
// This is called from a death test parent process to read a failure
|
||||
// message from the death test child process and log it with the FATAL
|
||||
// severity. On Windows, the message is read from a pipe handle. On other
|
||||
// platforms, it is read from a file descriptor.
|
||||
// TODO(vladl@google.com): Re-factor the code to merge common parts after
|
||||
// the reading code is abstracted.
|
||||
#if GTEST_OS_WINDOWS
|
||||
static void FailFromInternalError(HANDLE handle) {
|
||||
Message error;
|
||||
char buffer[256];
|
||||
|
||||
bool read_succeeded = true;
|
||||
DWORD bytes_read;
|
||||
do {
|
||||
// ERROR_BROKEN_PIPE arises when the other end of the pipe has been
|
||||
// closed. This is a normal condition for us.
|
||||
bytes_read = 0;
|
||||
read_succeeded = ::ReadFile(handle,
|
||||
buffer,
|
||||
sizeof(buffer) - 1,
|
||||
&bytes_read,
|
||||
NULL) || ::GetLastError() == ERROR_BROKEN_PIPE;
|
||||
buffer[bytes_read] = 0;
|
||||
error << buffer;
|
||||
} while (read_succeeded && bytes_read > 0);
|
||||
|
||||
if (read_succeeded) {
|
||||
GTEST_LOG_(FATAL, error);
|
||||
} else {
|
||||
const DWORD last_error = ::GetLastError();
|
||||
const String message = GetLastSystemErrorMessage();
|
||||
GTEST_LOG_(FATAL,
|
||||
Message() << "Error while reading death test internal: "
|
||||
<< message << " [" << last_error << "]");
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void FailFromInternalError(int fd) {
|
||||
Message error;
|
||||
char buffer[256];
|
||||
ssize_t num_read;
|
||||
|
||||
do {
|
||||
while ((num_read = read(fd, buffer, 255)) > 0) {
|
||||
buffer[num_read] = '\0';
|
||||
error << buffer;
|
||||
}
|
||||
} while (num_read == -1 && errno == EINTR);
|
||||
|
||||
if (num_read == 0) {
|
||||
GTEST_LOG_(FATAL, error);
|
||||
} else {
|
||||
const int last_error = errno;
|
||||
const String message = GetLastSystemErrorMessage();
|
||||
GTEST_LOG_(FATAL,
|
||||
Message() << "Error while reading death test internal: "
|
||||
<< message << " [" << last_error << "]");
|
||||
}
|
||||
}
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
#if !GTEST_OS_WINDOWS
|
||||
// Waits for the child in a death test to exit, returning its exit
|
||||
// status, or 0 if no child process exists. As a side effect, sets the
|
||||
// outcome data member.
|
||||
@ -735,135 +716,13 @@ int ForkingDeathTest::Wait() {
|
||||
if (!spawned())
|
||||
return 0;
|
||||
|
||||
// The read() here blocks until data is available (signifying the
|
||||
// failure of the death test) or until the pipe is closed (signifying
|
||||
// its success), so it's okay to call this in the parent before
|
||||
// the child process has exited.
|
||||
char flag;
|
||||
ssize_t bytes_read;
|
||||
ReadAndInterpretStatusByte();
|
||||
|
||||
do {
|
||||
bytes_read = read(read_fd_, &flag, 1);
|
||||
} while (bytes_read == -1 && errno == EINTR);
|
||||
|
||||
if (bytes_read == 0) {
|
||||
set_outcome(DIED);
|
||||
} else if (bytes_read == 1) {
|
||||
switch (flag) {
|
||||
case kDeathTestReturned:
|
||||
set_outcome(RETURNED);
|
||||
break;
|
||||
case kDeathTestLived:
|
||||
set_outcome(LIVED);
|
||||
break;
|
||||
case kDeathTestInternalError:
|
||||
FailFromInternalError(read_fd_); // Does not return.
|
||||
break;
|
||||
default:
|
||||
GTEST_LOG_(FATAL,
|
||||
Message() << "Death test child process reported unexpected "
|
||||
<< "status byte (" << static_cast<unsigned int>(flag)
|
||||
<< ")");
|
||||
}
|
||||
} else {
|
||||
const String error_message = GetLastSystemErrorMessage();
|
||||
GTEST_LOG_(FATAL,
|
||||
Message() << "Read from death test child process failed: "
|
||||
<< error_message);
|
||||
}
|
||||
|
||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(read_fd_));
|
||||
int status;
|
||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status, 0));
|
||||
set_status(status);
|
||||
return status;
|
||||
}
|
||||
#endif // !GTEST_OS_WINDOWS
|
||||
|
||||
// Assesses the success or failure of a death test, using both private
|
||||
// members which have previously been set, and one argument:
|
||||
//
|
||||
// Private data members:
|
||||
// outcome: An enumeration describing how the death test
|
||||
// concluded: DIED, LIVED, or RETURNED. The death test fails
|
||||
// in the latter two cases.
|
||||
// status: The exit status of the child process. On *nix, it is in the
|
||||
// in the format specified by wait(2). On Windows, this is the
|
||||
// value supplied to the ExitProcess() API or a numeric code
|
||||
// of the exception that terminated the program.
|
||||
// regex: A regular expression object to be applied to
|
||||
// the test's captured standard error output; the death test
|
||||
// fails if it does not match.
|
||||
//
|
||||
// Argument:
|
||||
// status_ok: true if exit_status is acceptable in the context of
|
||||
// this particular death test, which fails if it is false
|
||||
//
|
||||
// Returns true iff all of the above conditions are met. Otherwise, the
|
||||
// first failing condition, in the order given above, is the one that is
|
||||
// reported. Also sets the last death test message string.
|
||||
bool DeathTestImpl::Passed(bool status_ok) {
|
||||
if (!spawned())
|
||||
return false;
|
||||
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
const ::string error_message = GetCapturedStderr();
|
||||
#else
|
||||
const ::std::string error_message = GetCapturedStderr();
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
bool success = false;
|
||||
Message buffer;
|
||||
|
||||
buffer << "Death test: " << statement() << "\n";
|
||||
switch (outcome()) {
|
||||
case LIVED:
|
||||
buffer << " Result: failed to die.\n"
|
||||
<< " Error msg: " << error_message;
|
||||
break;
|
||||
case RETURNED:
|
||||
buffer << " Result: illegal return in test statement.\n"
|
||||
<< " Error msg: " << error_message;
|
||||
break;
|
||||
case DIED:
|
||||
if (status_ok) {
|
||||
if (RE::PartialMatch(error_message, *regex())) {
|
||||
success = true;
|
||||
} else {
|
||||
buffer << " Result: died but not with expected error.\n"
|
||||
<< " Expected: " << regex()->pattern() << "\n"
|
||||
<< "Actual msg: " << error_message;
|
||||
}
|
||||
} else {
|
||||
buffer << " Result: died but not with expected exit code:\n"
|
||||
<< " " << ExitSummary(status()) << "\n";
|
||||
}
|
||||
break;
|
||||
case IN_PROGRESS:
|
||||
default:
|
||||
GTEST_LOG_(FATAL,
|
||||
"DeathTest::Passed somehow called before conclusion of test");
|
||||
}
|
||||
|
||||
DeathTest::set_last_death_test_message(buffer.GetString());
|
||||
return success;
|
||||
}
|
||||
|
||||
#if !GTEST_OS_WINDOWS
|
||||
// Signals that the death test code which should have exited, didn't.
|
||||
// Should be called only in a death test child process.
|
||||
// Writes a status byte to the child's status file descriptor, then
|
||||
// calls _exit(1).
|
||||
void ForkingDeathTest::Abort(AbortReason reason) {
|
||||
// The parent process considers the death test to be a failure if
|
||||
// it finds any data in our pipe. So, here we write a single flag byte
|
||||
// to the pipe, then exit.
|
||||
const char flag =
|
||||
reason == TEST_DID_NOT_DIE ? kDeathTestLived : kDeathTestReturned;
|
||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(write(write_fd_, &flag, 1));
|
||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(write_fd_));
|
||||
_exit(1); // Exits w/o any normal exit hooks (we were supposed to crash)
|
||||
}
|
||||
|
||||
// A concrete death test class that forks, then immediately runs the test
|
||||
// in the child process.
|
||||
@ -879,7 +738,7 @@ class NoExecDeathTest : public ForkingDeathTest {
|
||||
DeathTest::TestRole NoExecDeathTest::AssumeRole() {
|
||||
const size_t thread_count = GetThreadCount();
|
||||
if (thread_count != 1) {
|
||||
GTEST_LOG_(WARNING, DeathTestThreadWarning(thread_count));
|
||||
GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count);
|
||||
}
|
||||
|
||||
int pipe_fd[2];
|
||||
@ -906,6 +765,9 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() {
|
||||
// concurrent writes to the log files. We capture stderr in the parent
|
||||
// process and append the child process' output to a log.
|
||||
LogToStderr();
|
||||
// Event forwarding to the listeners of event listener API mush be shut
|
||||
// down in death test subprocesses.
|
||||
GetUnitTestImpl()->listeners()->SuppressEventForwarding();
|
||||
return EXECUTE_TEST;
|
||||
} else {
|
||||
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
|
||||
@ -945,7 +807,7 @@ class Arguments {
|
||||
}
|
||||
}
|
||||
void AddArgument(const char* argument) {
|
||||
args_.insert(args_.end() - 1, strdup(argument));
|
||||
args_.insert(args_.end() - 1, posix::StrDup(argument));
|
||||
}
|
||||
|
||||
template <typename Str>
|
||||
@ -953,7 +815,7 @@ class Arguments {
|
||||
for (typename ::std::vector<Str>::const_iterator i = arguments.begin();
|
||||
i != arguments.end();
|
||||
++i) {
|
||||
args_.insert(args_.end() - 1, strdup(i->c_str()));
|
||||
args_.insert(args_.end() - 1, posix::StrDup(i->c_str()));
|
||||
}
|
||||
}
|
||||
char* const* Argv() {
|
||||
@ -978,12 +840,10 @@ inline char** GetEnviron() {
|
||||
return *_NSGetEnviron();
|
||||
}
|
||||
#else
|
||||
extern "C" char** environ; // Some POSIX platforms expect you
|
||||
// to declare environ. extern "C" makes
|
||||
// it reside in the global namespace.
|
||||
inline char** GetEnviron() {
|
||||
return environ;
|
||||
}
|
||||
// Some POSIX platforms expect you to declare environ. extern "C" makes
|
||||
// it reside in the global namespace.
|
||||
extern "C" char** environ;
|
||||
inline char** GetEnviron() { return environ; }
|
||||
#endif // GTEST_OS_MAC
|
||||
|
||||
// The main function for a threadsafe-style death test child process.
|
||||
@ -1002,7 +862,7 @@ static int ExecDeathTestChildMain(void* child_arg) {
|
||||
if (chdir(original_dir) != 0) {
|
||||
DeathTestAbort(String::Format("chdir(\"%s\") failed: %s",
|
||||
original_dir,
|
||||
GetLastSystemErrorMessage().c_str()));
|
||||
GetLastErrnoDescription().c_str()));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@ -1015,7 +875,7 @@ static int ExecDeathTestChildMain(void* child_arg) {
|
||||
DeathTestAbort(String::Format("execve(%s, ...) in %s failed: %s",
|
||||
args->argv[0],
|
||||
original_dir,
|
||||
GetLastSystemErrorMessage().c_str()));
|
||||
GetLastErrnoDescription().c_str()));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@ -1039,7 +899,7 @@ bool StackGrowsDown() {
|
||||
// wrong.
|
||||
static pid_t ExecDeathTestFork(char* const* argv, int close_fd) {
|
||||
ExecDeathTestArgs args = { argv, close_fd };
|
||||
pid_t child_pid;
|
||||
pid_t child_pid = -1;
|
||||
|
||||
#if GTEST_HAS_CLONE
|
||||
const bool use_fork = GTEST_FLAG(death_test_use_fork);
|
||||
@ -1083,7 +943,7 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
|
||||
const int death_test_index = info->result()->death_test_count();
|
||||
|
||||
if (flag != NULL) {
|
||||
set_write_fd(flag->status_fd());
|
||||
set_write_fd(flag->write_fd());
|
||||
return EXECUTE_TEST;
|
||||
}
|
||||
|
||||
@ -1183,7 +1043,7 @@ static void SplitString(const ::std::string& str, char delimiter,
|
||||
::std::vector< ::std::string>* dest) {
|
||||
::std::vector< ::std::string> parsed;
|
||||
::std::string::size_type pos = 0;
|
||||
while (true) {
|
||||
while (::testing::internal::AlwaysTrue()) {
|
||||
const ::std::string::size_type colon = str.find(delimiter, pos);
|
||||
if (colon == ::std::string::npos) {
|
||||
parsed.push_back(str.substr(pos));
|
||||
@ -1201,7 +1061,7 @@ static void SplitString(const ::std::string& str, char delimiter,
|
||||
// signals the event, and returns a file descriptor wrapped around the pipe
|
||||
// handle. This function is called in the child process only.
|
||||
int GetStatusFileDescriptor(unsigned int parent_process_id,
|
||||
size_t status_handle_as_size_t,
|
||||
size_t write_handle_as_size_t,
|
||||
size_t event_handle_as_size_t) {
|
||||
AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,
|
||||
FALSE, // Non-inheritable.
|
||||
@ -1215,22 +1075,22 @@ int GetStatusFileDescriptor(unsigned int parent_process_id,
|
||||
// compile-time assertion when available.
|
||||
GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t));
|
||||
|
||||
const HANDLE status_handle =
|
||||
reinterpret_cast<HANDLE>(status_handle_as_size_t);
|
||||
HANDLE dup_status_handle;
|
||||
const HANDLE write_handle =
|
||||
reinterpret_cast<HANDLE>(write_handle_as_size_t);
|
||||
HANDLE dup_write_handle;
|
||||
|
||||
// The newly initialized handle is accessible only in in the parent
|
||||
// process. To obtain one accessible within the child, we need to use
|
||||
// DuplicateHandle.
|
||||
if (!::DuplicateHandle(parent_process_handle.Get(), status_handle,
|
||||
::GetCurrentProcess(), &dup_status_handle,
|
||||
if (!::DuplicateHandle(parent_process_handle.Get(), write_handle,
|
||||
::GetCurrentProcess(), &dup_write_handle,
|
||||
0x0, // Requested privileges ignored since
|
||||
// DUPLICATE_SAME_ACCESS is used.
|
||||
FALSE, // Request non-inheritable handler.
|
||||
DUPLICATE_SAME_ACCESS)) {
|
||||
DeathTestAbort(String::Format(
|
||||
"Unable to duplicate the pipe handle %Iu from the parent process %u",
|
||||
status_handle_as_size_t, parent_process_id));
|
||||
write_handle_as_size_t, parent_process_id));
|
||||
}
|
||||
|
||||
const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t);
|
||||
@ -1246,20 +1106,19 @@ int GetStatusFileDescriptor(unsigned int parent_process_id,
|
||||
event_handle_as_size_t, parent_process_id));
|
||||
}
|
||||
|
||||
const int status_fd =
|
||||
::_open_osfhandle(reinterpret_cast<intptr_t>(dup_status_handle),
|
||||
O_APPEND | O_TEXT);
|
||||
if (status_fd == -1) {
|
||||
const int write_fd =
|
||||
::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND);
|
||||
if (write_fd == -1) {
|
||||
DeathTestAbort(String::Format(
|
||||
"Unable to convert pipe handle %Iu to a file descriptor",
|
||||
status_handle_as_size_t));
|
||||
write_handle_as_size_t));
|
||||
}
|
||||
|
||||
// Signals the parent that the write end of the pipe has been acquired
|
||||
// so the parent can release its own write end.
|
||||
::SetEvent(dup_event_handle);
|
||||
|
||||
return status_fd;
|
||||
return write_fd;
|
||||
}
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
@ -1275,37 +1134,37 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
|
||||
int index = -1;
|
||||
::std::vector< ::std::string> fields;
|
||||
SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields);
|
||||
int status_fd = -1;
|
||||
int write_fd = -1;
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
unsigned int parent_process_id = 0;
|
||||
size_t status_handle_as_size_t = 0;
|
||||
size_t write_handle_as_size_t = 0;
|
||||
size_t event_handle_as_size_t = 0;
|
||||
|
||||
if (fields.size() != 6
|
||||
|| !ParseNaturalNumber(fields[1], &line)
|
||||
|| !ParseNaturalNumber(fields[2], &index)
|
||||
|| !ParseNaturalNumber(fields[3], &parent_process_id)
|
||||
|| !ParseNaturalNumber(fields[4], &status_handle_as_size_t)
|
||||
|| !ParseNaturalNumber(fields[4], &write_handle_as_size_t)
|
||||
|| !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) {
|
||||
DeathTestAbort(String::Format(
|
||||
"Bad --gtest_internal_run_death_test flag: %s",
|
||||
GTEST_FLAG(internal_run_death_test).c_str()));
|
||||
}
|
||||
status_fd = GetStatusFileDescriptor(parent_process_id,
|
||||
status_handle_as_size_t,
|
||||
event_handle_as_size_t);
|
||||
write_fd = GetStatusFileDescriptor(parent_process_id,
|
||||
write_handle_as_size_t,
|
||||
event_handle_as_size_t);
|
||||
#else
|
||||
if (fields.size() != 4
|
||||
|| !ParseNaturalNumber(fields[1], &line)
|
||||
|| !ParseNaturalNumber(fields[2], &index)
|
||||
|| !ParseNaturalNumber(fields[3], &status_fd)) {
|
||||
|| !ParseNaturalNumber(fields[3], &write_fd)) {
|
||||
DeathTestAbort(String::Format(
|
||||
"Bad --gtest_internal_run_death_test flag: %s",
|
||||
GTEST_FLAG(internal_run_death_test).c_str()));
|
||||
}
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
return new InternalRunDeathTestFlag(fields[0], line, index, status_fd);
|
||||
return new InternalRunDeathTestFlag(fields[0], line, index, write_fd);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
@ -34,22 +34,18 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
#include <windows.h>
|
||||
#elif GTEST_OS_WINDOWS
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#include <sys/stat.h>
|
||||
#elif GTEST_OS_SYMBIAN
|
||||
// Symbian OpenC has PATH_MAX in sys/syslimits.h
|
||||
#include <sys/syslimits.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h> // NOLINT
|
||||
#include <unistd.h> // NOLINT
|
||||
#include <climits> // Some Linux distributions define PATH_MAX here.
|
||||
#endif // _WIN32_WCE or _WIN32
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#define GTEST_PATH_MAX_ _MAX_PATH
|
||||
@ -69,7 +65,7 @@ namespace internal {
|
||||
#if GTEST_OS_WINDOWS
|
||||
const char kPathSeparator = '\\';
|
||||
const char kPathSeparatorString[] = "\\";
|
||||
#ifdef _WIN32_WCE
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
// Windows CE doesn't have a current directory. You should not use
|
||||
// the current directory in tests on Windows CE, but this at least
|
||||
// provides a reasonable fallback.
|
||||
@ -78,7 +74,7 @@ const char kCurrentDirectoryString[] = "\\";
|
||||
const DWORD kInvalidFileAttributes = 0xffffffff;
|
||||
#else
|
||||
const char kCurrentDirectoryString[] = ".\\";
|
||||
#endif // _WIN32_WCE
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
#else
|
||||
const char kPathSeparator = '/';
|
||||
const char kPathSeparatorString[] = "/";
|
||||
@ -87,17 +83,17 @@ const char kCurrentDirectoryString[] = "./";
|
||||
|
||||
// Returns the current working directory, or "" if unsuccessful.
|
||||
FilePath FilePath::GetCurrentDir() {
|
||||
#ifdef _WIN32_WCE
|
||||
// Windows CE doesn't have a current directory, so we just return
|
||||
// something reasonable.
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
// Windows CE doesn't have a current directory, so we just return
|
||||
// something reasonable.
|
||||
return FilePath(kCurrentDirectoryString);
|
||||
#elif GTEST_OS_WINDOWS
|
||||
char cwd[GTEST_PATH_MAX_ + 1] = {};
|
||||
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
|
||||
return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
|
||||
#else
|
||||
char cwd[GTEST_PATH_MAX_ + 1] = {};
|
||||
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
|
||||
return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
|
||||
#endif
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
}
|
||||
|
||||
// Returns a copy of the FilePath with the case-insensitive extension removed.
|
||||
@ -107,7 +103,7 @@ FilePath FilePath::GetCurrentDir() {
|
||||
FilePath FilePath::RemoveExtension(const char* extension) const {
|
||||
String dot_extension(String::Format(".%s", extension));
|
||||
if (pathname_.EndsWithCaseInsensitive(dot_extension.c_str())) {
|
||||
return FilePath(String(pathname_.c_str(), pathname_.GetLength() - 4));
|
||||
return FilePath(String(pathname_.c_str(), pathname_.length() - 4));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -131,8 +127,13 @@ FilePath FilePath::RemoveDirectoryName() const {
|
||||
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||
FilePath FilePath::RemoveFileName() const {
|
||||
const char* const last_sep = strrchr(c_str(), kPathSeparator);
|
||||
return FilePath(last_sep ? String(c_str(), last_sep + 1 - c_str())
|
||||
: String(kCurrentDirectoryString));
|
||||
String dir;
|
||||
if (last_sep) {
|
||||
dir = String(c_str(), last_sep + 1 - c_str());
|
||||
} else {
|
||||
dir = kCurrentDirectoryString;
|
||||
}
|
||||
return FilePath(dir);
|
||||
}
|
||||
|
||||
// Helper functions for naming files in a directory for xml output.
|
||||
@ -145,11 +146,13 @@ FilePath FilePath::MakeFileName(const FilePath& directory,
|
||||
const FilePath& base_name,
|
||||
int number,
|
||||
const char* extension) {
|
||||
const FilePath file_name(
|
||||
(number == 0) ?
|
||||
String::Format("%s.%s", base_name.c_str(), extension) :
|
||||
String::Format("%s_%d.%s", base_name.c_str(), number, extension));
|
||||
return ConcatPaths(directory, file_name);
|
||||
String file;
|
||||
if (number == 0) {
|
||||
file = String::Format("%s.%s", base_name.c_str(), extension);
|
||||
} else {
|
||||
file = String::Format("%s_%d.%s", base_name.c_str(), number, extension);
|
||||
}
|
||||
return ConcatPaths(directory, FilePath(file));
|
||||
}
|
||||
|
||||
// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml".
|
||||
@ -166,20 +169,15 @@ FilePath FilePath::ConcatPaths(const FilePath& directory,
|
||||
// Returns true if pathname describes something findable in the file-system,
|
||||
// either a file, directory, or whatever.
|
||||
bool FilePath::FileOrDirectoryExists() const {
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifdef _WIN32_WCE
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
|
||||
const DWORD attributes = GetFileAttributes(unicode);
|
||||
delete [] unicode;
|
||||
return attributes != kInvalidFileAttributes;
|
||||
#else
|
||||
struct _stat file_stat = {};
|
||||
return _stat(pathname_.c_str(), &file_stat) == 0;
|
||||
#endif // _WIN32_WCE
|
||||
#else
|
||||
struct stat file_stat;
|
||||
return stat(pathname_.c_str(), &file_stat) == 0;
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
posix::StatStruct file_stat;
|
||||
return posix::Stat(pathname_.c_str(), &file_stat) == 0;
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
}
|
||||
|
||||
// Returns true if pathname describes a directory in the file-system
|
||||
@ -191,7 +189,11 @@ bool FilePath::DirectoryExists() const {
|
||||
// Windows (like "C:\\").
|
||||
const FilePath& path(IsRootDirectory() ? *this :
|
||||
RemoveTrailingPathSeparator());
|
||||
#ifdef _WIN32_WCE
|
||||
#else
|
||||
const FilePath& path(*this);
|
||||
#endif
|
||||
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
|
||||
const DWORD attributes = GetFileAttributes(unicode);
|
||||
delete [] unicode;
|
||||
@ -200,15 +202,11 @@ bool FilePath::DirectoryExists() const {
|
||||
result = true;
|
||||
}
|
||||
#else
|
||||
struct _stat file_stat = {};
|
||||
result = _stat(path.c_str(), &file_stat) == 0 &&
|
||||
(_S_IFDIR & file_stat.st_mode) != 0;
|
||||
#endif // _WIN32_WCE
|
||||
#else
|
||||
struct stat file_stat;
|
||||
result = stat(pathname_.c_str(), &file_stat) == 0 &&
|
||||
S_ISDIR(file_stat.st_mode);
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
posix::StatStruct file_stat;
|
||||
result = posix::Stat(path.c_str(), &file_stat) == 0 &&
|
||||
posix::IsDir(file_stat);
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -219,7 +217,7 @@ bool FilePath::IsRootDirectory() const {
|
||||
// TODO(wan@google.com): on Windows a network share like
|
||||
// \\server\share can be a root directory, although it cannot be the
|
||||
// current directory. Handle this properly.
|
||||
return pathname_.GetLength() == 3 && IsAbsolutePath();
|
||||
return pathname_.length() == 3 && IsAbsolutePath();
|
||||
#else
|
||||
return pathname_ == kPathSeparatorString;
|
||||
#endif
|
||||
@ -229,7 +227,7 @@ bool FilePath::IsRootDirectory() const {
|
||||
bool FilePath::IsAbsolutePath() const {
|
||||
const char* const name = pathname_.c_str();
|
||||
#if GTEST_OS_WINDOWS
|
||||
return pathname_.GetLength() >= 3 &&
|
||||
return pathname_.length() >= 3 &&
|
||||
((name[0] >= 'a' && name[0] <= 'z') ||
|
||||
(name[0] >= 'A' && name[0] <= 'Z')) &&
|
||||
name[1] == ':' &&
|
||||
@ -273,7 +271,7 @@ bool FilePath::CreateDirectoriesRecursively() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pathname_.GetLength() == 0 || this->DirectoryExists()) {
|
||||
if (pathname_.length() == 0 || this->DirectoryExists()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -286,18 +284,17 @@ bool FilePath::CreateDirectoriesRecursively() const {
|
||||
// directory for any reason, including if the parent directory does not
|
||||
// exist. Not named "CreateDirectory" because that's a macro on Windows.
|
||||
bool FilePath::CreateFolder() const {
|
||||
#if GTEST_OS_WINDOWS
|
||||
#ifdef _WIN32_WCE
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
FilePath removed_sep(this->RemoveTrailingPathSeparator());
|
||||
LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
|
||||
int result = CreateDirectory(unicode, NULL) ? 0 : -1;
|
||||
delete [] unicode;
|
||||
#else
|
||||
#elif GTEST_OS_WINDOWS
|
||||
int result = _mkdir(pathname_.c_str());
|
||||
#endif // !WIN32_WCE
|
||||
#else
|
||||
int result = mkdir(pathname_.c_str(), 0777);
|
||||
#endif // _WIN32
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
if (result == -1) {
|
||||
return this->DirectoryExists(); // An error is OK if the directory exists.
|
||||
}
|
||||
@ -309,7 +306,7 @@ bool FilePath::CreateFolder() const {
|
||||
// On Windows platform, uses \ as the separator, other platforms use /.
|
||||
FilePath FilePath::RemoveTrailingPathSeparator() const {
|
||||
return pathname_.EndsWith(kPathSeparatorString)
|
||||
? FilePath(String(pathname_.c_str(), pathname_.GetLength() - 1))
|
||||
? FilePath(String(pathname_.c_str(), pathname_.length() - 1))
|
||||
: *this;
|
||||
}
|
||||
|
||||
@ -322,9 +319,9 @@ void FilePath::Normalize() {
|
||||
return;
|
||||
}
|
||||
const char* src = pathname_.c_str();
|
||||
char* const dest = new char[pathname_.GetLength() + 1];
|
||||
char* const dest = new char[pathname_.length() + 1];
|
||||
char* dest_ptr = dest;
|
||||
memset(dest_ptr, 0, pathname_.GetLength() + 1);
|
||||
memset(dest_ptr, 0, pathname_.length() + 1);
|
||||
|
||||
while (*src != '\0') {
|
||||
*dest_ptr++ = *src;
|
||||
|
@ -35,20 +35,20 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
#include <windows.h> // For TerminateProcess()
|
||||
#elif GTEST_OS_WINDOWS
|
||||
#include <io.h>
|
||||
#include <sys/stat.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
#if GTEST_USES_SIMPLE_RE
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
#include <windows.h> // For TerminateProcess()
|
||||
#endif // _WIN32_WCE
|
||||
#if GTEST_OS_MAC
|
||||
#include <mach/mach_init.h>
|
||||
#include <mach/task.h>
|
||||
#include <mach/vm_map.h>
|
||||
#endif // GTEST_OS_MAC
|
||||
|
||||
#include <gtest/gtest-spi.h>
|
||||
#include <gtest/gtest-message.h>
|
||||
@ -66,12 +66,43 @@
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
// Microsoft does not provide a definition of STDERR_FILENO.
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
// MSVC and C++Builder do not provide a definition of STDERR_FILENO.
|
||||
const int kStdErrFileno = 2;
|
||||
#else
|
||||
const int kStdErrFileno = STDERR_FILENO;
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
#endif // _MSC_VER
|
||||
|
||||
#if GTEST_OS_MAC
|
||||
|
||||
// Returns the number of threads running in the process, or 0 to indicate that
|
||||
// we cannot detect it.
|
||||
size_t GetThreadCount() {
|
||||
const task_t task = mach_task_self();
|
||||
mach_msg_type_number_t thread_count;
|
||||
thread_act_array_t thread_list;
|
||||
const kern_return_t status = task_threads(task, &thread_list, &thread_count);
|
||||
if (status == KERN_SUCCESS) {
|
||||
// task_threads allocates resources in thread_list and we need to free them
|
||||
// to avoid leaks.
|
||||
vm_deallocate(task,
|
||||
reinterpret_cast<vm_address_t>(thread_list),
|
||||
sizeof(thread_t) * thread_count);
|
||||
return static_cast<size_t>(thread_count);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
size_t GetThreadCount() {
|
||||
// There's no portable way to detect the number of threads, so we just
|
||||
// return 0 to indicate that we cannot detect it.
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // GTEST_OS_MAC
|
||||
|
||||
#if GTEST_USES_POSIX_RE
|
||||
|
||||
@ -102,7 +133,7 @@ bool RE::PartialMatch(const char* str, const RE& re) {
|
||||
|
||||
// Initializes an RE from its string representation.
|
||||
void RE::Init(const char* regex) {
|
||||
pattern_ = strdup(regex);
|
||||
pattern_ = posix::StrDup(regex);
|
||||
|
||||
// Reserves enough bytes to hold the regular expression used for a
|
||||
// full match.
|
||||
@ -350,11 +381,7 @@ bool RE::PartialMatch(const char* str, const RE& re) {
|
||||
void RE::Init(const char* regex) {
|
||||
pattern_ = full_pattern_ = NULL;
|
||||
if (regex != NULL) {
|
||||
#if GTEST_OS_WINDOWS
|
||||
pattern_ = _strdup(regex);
|
||||
#else
|
||||
pattern_ = strdup(regex);
|
||||
#endif
|
||||
pattern_ = posix::StrDup(regex);
|
||||
}
|
||||
|
||||
is_valid_ = ValidateRegex(regex);
|
||||
@ -386,22 +413,25 @@ void RE::Init(const char* regex) {
|
||||
|
||||
#endif // GTEST_USES_POSIX_RE
|
||||
|
||||
// Logs a message at the given severity level.
|
||||
void GTestLog(GTestLogSeverity severity, const char* file,
|
||||
int line, const char* msg) {
|
||||
|
||||
GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)
|
||||
: severity_(severity) {
|
||||
const char* const marker =
|
||||
severity == GTEST_INFO ? "[ INFO ]" :
|
||||
severity == GTEST_WARNING ? "[WARNING]" :
|
||||
severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]";
|
||||
fprintf(stderr, "\n%s %s:%d: %s\n", marker, file, line, msg);
|
||||
if (severity == GTEST_FATAL) {
|
||||
fflush(NULL); // abort() is not guaranteed to flush open file streams.
|
||||
abort();
|
||||
}
|
||||
GetStream() << ::std::endl << marker << " "
|
||||
<< FormatFileLocation(file, line).c_str() << ": ";
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STD_STRING
|
||||
|
||||
// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
|
||||
GTestLog::~GTestLog() {
|
||||
GetStream() << ::std::endl;
|
||||
if (severity_ == GTEST_FATAL) {
|
||||
fflush(stderr);
|
||||
posix::Abort();
|
||||
}
|
||||
}
|
||||
// Disable Microsoft deprecation warnings for POSIX functions called from
|
||||
// this class (creat, dup, dup2, and close)
|
||||
#ifdef _MSC_VER
|
||||
@ -415,6 +445,10 @@ class CapturedStderr {
|
||||
public:
|
||||
// The ctor redirects stderr to a temporary file.
|
||||
CapturedStderr() {
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
// Not supported on Windows CE.
|
||||
posix::Abort();
|
||||
#else
|
||||
uncaptured_fd_ = dup(kStdErrFileno);
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
@ -436,19 +470,24 @@ class CapturedStderr {
|
||||
fflush(NULL);
|
||||
dup2(captured_fd, kStdErrFileno);
|
||||
close(captured_fd);
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
}
|
||||
|
||||
~CapturedStderr() {
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
remove(filename_.c_str());
|
||||
#endif // !GTEST_OS_WINDOWS_MOBILE
|
||||
}
|
||||
|
||||
// Stops redirecting stderr.
|
||||
void StopCapture() {
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
// Restores the original stream.
|
||||
fflush(NULL);
|
||||
dup2(uncaptured_fd_, kStdErrFileno);
|
||||
close(uncaptured_fd_);
|
||||
uncaptured_fd_ = -1;
|
||||
#endif // !GTEST_OS_WINDOWS_MOBILE
|
||||
}
|
||||
|
||||
// Returns the name of the temporary file holding the stderr output.
|
||||
@ -474,7 +513,7 @@ static size_t GetFileSize(FILE * file) {
|
||||
}
|
||||
|
||||
// Reads the entire content of a file as a string.
|
||||
static ::std::string ReadEntireFile(FILE * file) {
|
||||
static String ReadEntireFile(FILE * file) {
|
||||
const size_t file_size = GetFileSize(file);
|
||||
char* const buffer = new char[file_size];
|
||||
|
||||
@ -490,7 +529,7 @@ static ::std::string ReadEntireFile(FILE * file) {
|
||||
bytes_read += bytes_last_read;
|
||||
} while (bytes_last_read > 0 && bytes_read < file_size);
|
||||
|
||||
const ::std::string content(buffer, buffer+bytes_read);
|
||||
const String content(buffer, bytes_read);
|
||||
delete[] buffer;
|
||||
|
||||
return content;
|
||||
@ -499,7 +538,7 @@ static ::std::string ReadEntireFile(FILE * file) {
|
||||
// Starts capturing stderr.
|
||||
void CaptureStderr() {
|
||||
if (g_captured_stderr != NULL) {
|
||||
GTEST_LOG_(FATAL, "Only one stderr capturer can exist at one time.");
|
||||
GTEST_LOG_(FATAL) << "Only one stderr capturer can exist at one time.";
|
||||
}
|
||||
g_captured_stderr = new CapturedStderr;
|
||||
}
|
||||
@ -507,20 +546,12 @@ void CaptureStderr() {
|
||||
// Stops capturing stderr and returns the captured string.
|
||||
// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can
|
||||
// use it here.
|
||||
::std::string GetCapturedStderr() {
|
||||
String GetCapturedStderr() {
|
||||
g_captured_stderr->StopCapture();
|
||||
|
||||
// Disables Microsoft deprecation warning for fopen and fclose.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4996)
|
||||
#endif // _MSC_VER
|
||||
FILE* const file = fopen(g_captured_stderr->filename().c_str(), "r");
|
||||
const ::std::string content = ReadEntireFile(file);
|
||||
fclose(file);
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif // _MSC_VER
|
||||
FILE* const file = posix::FOpen(g_captured_stderr->filename().c_str(), "r");
|
||||
const String content = ReadEntireFile(file);
|
||||
posix::FClose(file);
|
||||
|
||||
delete g_captured_stderr;
|
||||
g_captured_stderr = NULL;
|
||||
@ -528,8 +559,6 @@ void CaptureStderr() {
|
||||
return content;
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_STD_STRING
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
// A copy of all command line arguments. Set by InitGoogleTest().
|
||||
@ -540,12 +569,14 @@ const ::std::vector<String>& GetArgvs() { return g_argvs; }
|
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
void abort() {
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
namespace posix {
|
||||
void Abort() {
|
||||
DebugBreak();
|
||||
TerminateProcess(GetCurrentProcess(), 1);
|
||||
}
|
||||
#endif // _WIN32_WCE
|
||||
} // namespace posix
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
// Returns the name of the environment variable corresponding to the
|
||||
// given flag. For example, FlagToEnvVar("foo") will return
|
||||
@ -555,7 +586,7 @@ static String FlagToEnvVar(const char* flag) {
|
||||
(Message() << GTEST_FLAG_PREFIX_ << flag).GetString();
|
||||
|
||||
Message env_var;
|
||||
for (int i = 0; i != full_flag.GetLength(); i++) {
|
||||
for (size_t i = 0; i != full_flag.length(); i++) {
|
||||
env_var << static_cast<char>(toupper(full_flag.c_str()[i]));
|
||||
}
|
||||
|
||||
@ -609,7 +640,7 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
|
||||
// The value is considered true iff it's not "0".
|
||||
bool BoolFromGTestEnv(const char* flag, bool default_value) {
|
||||
const String env_var = FlagToEnvVar(flag);
|
||||
const char* const string_value = GetEnv(env_var.c_str());
|
||||
const char* const string_value = posix::GetEnv(env_var.c_str());
|
||||
return string_value == NULL ?
|
||||
default_value : strcmp(string_value, "0") != 0;
|
||||
}
|
||||
@ -619,7 +650,7 @@ bool BoolFromGTestEnv(const char* flag, bool default_value) {
|
||||
// doesn't represent a valid 32-bit integer, returns default_value.
|
||||
Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
|
||||
const String env_var = FlagToEnvVar(flag);
|
||||
const char* const string_value = GetEnv(env_var.c_str());
|
||||
const char* const string_value = posix::GetEnv(env_var.c_str());
|
||||
if (string_value == NULL) {
|
||||
// The environment variable is not set.
|
||||
return default_value;
|
||||
@ -641,7 +672,7 @@ Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
|
||||
// the given flag; if it's not set, returns default_value.
|
||||
const char* StringFromGTestEnv(const char* flag, const char* default_value) {
|
||||
const String env_var = FlagToEnvVar(flag);
|
||||
const char* const value = GetEnv(env_var.c_str());
|
||||
const char* const value = posix::GetEnv(env_var.c_str());
|
||||
return value == NULL ? default_value : value;
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,8 @@
|
||||
|
||||
namespace testing {
|
||||
|
||||
using internal::GetUnitTestImpl;
|
||||
|
||||
// Gets the summary of the failure message by omitting the stack trace
|
||||
// in it.
|
||||
internal::String TestPartResult::ExtractSummary(const char* message) {
|
||||
@ -54,61 +56,55 @@ internal::String TestPartResult::ExtractSummary(const char* message) {
|
||||
|
||||
// Prints a TestPartResult object.
|
||||
std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
|
||||
return os << result.file_name() << ":"
|
||||
<< result.line_number() << ": "
|
||||
<< (result.type() == TPRT_SUCCESS ? "Success" :
|
||||
result.type() == TPRT_FATAL_FAILURE ? "Fatal failure" :
|
||||
"Non-fatal failure") << ":\n"
|
||||
<< result.message() << std::endl;
|
||||
return os
|
||||
<< result.file_name() << ":" << result.line_number() << ": "
|
||||
<< (result.type() == TestPartResult::kSuccess ? "Success" :
|
||||
result.type() == TestPartResult::kFatalFailure ? "Fatal failure" :
|
||||
"Non-fatal failure") << ":\n"
|
||||
<< result.message() << std::endl;
|
||||
}
|
||||
|
||||
// Constructs an empty TestPartResultArray.
|
||||
TestPartResultArray::TestPartResultArray()
|
||||
: list_(new internal::List<TestPartResult>) {
|
||||
: array_(new internal::Vector<TestPartResult>) {
|
||||
}
|
||||
|
||||
// Destructs a TestPartResultArray.
|
||||
TestPartResultArray::~TestPartResultArray() {
|
||||
delete list_;
|
||||
delete array_;
|
||||
}
|
||||
|
||||
// Appends a TestPartResult to the array.
|
||||
void TestPartResultArray::Append(const TestPartResult& result) {
|
||||
list_->PushBack(result);
|
||||
array_->PushBack(result);
|
||||
}
|
||||
|
||||
// Returns the TestPartResult at the given index (0-based).
|
||||
const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
|
||||
if (index < 0 || index >= size()) {
|
||||
printf("\nInvalid index (%d) into TestPartResultArray.\n", index);
|
||||
internal::abort();
|
||||
internal::posix::Abort();
|
||||
}
|
||||
|
||||
const internal::ListNode<TestPartResult>* p = list_->Head();
|
||||
for (int i = 0; i < index; i++) {
|
||||
p = p->next();
|
||||
}
|
||||
|
||||
return p->element();
|
||||
return array_->GetElement(index);
|
||||
}
|
||||
|
||||
// Returns the number of TestPartResult objects in the array.
|
||||
int TestPartResultArray::size() const {
|
||||
return list_->size();
|
||||
return array_->size();
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
HasNewFatalFailureHelper::HasNewFatalFailureHelper()
|
||||
: has_new_fatal_failure_(false),
|
||||
original_reporter_(UnitTest::GetInstance()->impl()->
|
||||
original_reporter_(GetUnitTestImpl()->
|
||||
GetTestPartResultReporterForCurrentThread()) {
|
||||
UnitTest::GetInstance()->impl()->SetTestPartResultReporterForCurrentThread(
|
||||
this);
|
||||
GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);
|
||||
}
|
||||
|
||||
HasNewFatalFailureHelper::~HasNewFatalFailureHelper() {
|
||||
UnitTest::GetInstance()->impl()->SetTestPartResultReporterForCurrentThread(
|
||||
GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(
|
||||
original_reporter_);
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ const char* TypedTestCasePState::VerifyRegisteredTestNames(
|
||||
fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
|
||||
errors_str.c_str());
|
||||
fflush(stderr);
|
||||
abort();
|
||||
posix::Abort();
|
||||
}
|
||||
|
||||
return registered_tests;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -181,6 +181,9 @@ class ExitedWithCode {
|
||||
explicit ExitedWithCode(int exit_code);
|
||||
bool operator()(int exit_status) const;
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ExitedWithCode& other);
|
||||
|
||||
const int exit_code_;
|
||||
};
|
||||
|
||||
@ -242,10 +245,10 @@ class KilledBySignal {
|
||||
#ifdef NDEBUG
|
||||
|
||||
#define EXPECT_DEBUG_DEATH(statement, regex) \
|
||||
do { statement; } while (false)
|
||||
do { statement; } while (::testing::internal::AlwaysFalse())
|
||||
|
||||
#define ASSERT_DEBUG_DEATH(statement, regex) \
|
||||
do { statement; } while (false)
|
||||
do { statement; } while (::testing::internal::AlwaysFalse())
|
||||
|
||||
#else
|
||||
|
||||
@ -257,6 +260,24 @@ class KilledBySignal {
|
||||
|
||||
#endif // NDEBUG for EXPECT_DEBUG_DEATH
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
|
||||
// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
|
||||
// death tests are supported; otherwise they just issue a warning. This is
|
||||
// useful when you are combining death test assertions with normal test
|
||||
// assertions in one test.
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
EXPECT_DEATH(statement, regex)
|
||||
#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
ASSERT_DEATH(statement, regex)
|
||||
#else
|
||||
#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )
|
||||
#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return)
|
||||
#endif
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||
|
@ -193,7 +193,7 @@ class Message {
|
||||
// decide between class template specializations for T and T*, so a
|
||||
// tr1::type_traits-like is_pointer works, and we can overload on that.
|
||||
template <typename T>
|
||||
inline void StreamHelper(internal::true_type dummy, T* pointer) {
|
||||
inline void StreamHelper(internal::true_type /*dummy*/, T* pointer) {
|
||||
if (pointer == NULL) {
|
||||
*ss_ << "(null)";
|
||||
} else {
|
||||
@ -201,7 +201,7 @@ class Message {
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
inline void StreamHelper(internal::false_type dummy, const T& value) {
|
||||
inline void StreamHelper(internal::false_type /*dummy*/, const T& value) {
|
||||
::GTestStreamToHelper(ss_, value);
|
||||
}
|
||||
#endif // GTEST_OS_SYMBIAN
|
||||
|
@ -146,11 +146,12 @@ INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
|
||||
|
||||
#endif // 0
|
||||
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <gtest/internal/gtest-port.h>
|
||||
|
||||
#if !GTEST_OS_SYMBIAN
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
#if GTEST_HAS_PARAM_TEST
|
||||
|
||||
#include <gtest/internal/gtest-internal.h>
|
||||
|
@ -97,12 +97,12 @@ class SingleFailureChecker {
|
||||
public:
|
||||
// The constructor remembers the arguments.
|
||||
SingleFailureChecker(const TestPartResultArray* results,
|
||||
TestPartResultType type,
|
||||
TestPartResult::Type type,
|
||||
const char* substr);
|
||||
~SingleFailureChecker();
|
||||
private:
|
||||
const TestPartResultArray* const results_;
|
||||
const TestPartResultType type_;
|
||||
const TestPartResult::Type type_;
|
||||
const String substr_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
|
||||
@ -143,14 +143,14 @@ class SingleFailureChecker {
|
||||
};\
|
||||
::testing::TestPartResultArray gtest_failures;\
|
||||
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||
>est_failures, ::testing::TPRT_FATAL_FAILURE, (substr));\
|
||||
>est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
|
||||
{\
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||
::testing::ScopedFakeTestPartResultReporter:: \
|
||||
INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\
|
||||
GTestExpectFatalFailureHelper::Execute();\
|
||||
}\
|
||||
} while (false)
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
|
||||
do { \
|
||||
@ -160,14 +160,14 @@ class SingleFailureChecker {
|
||||
};\
|
||||
::testing::TestPartResultArray gtest_failures;\
|
||||
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||
>est_failures, ::testing::TPRT_FATAL_FAILURE, (substr));\
|
||||
>est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
|
||||
{\
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||
::testing::ScopedFakeTestPartResultReporter:: \
|
||||
INTERCEPT_ALL_THREADS, >est_failures);\
|
||||
GTestExpectFatalFailureHelper::Execute();\
|
||||
}\
|
||||
} while (false)
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
// A macro for testing Google Test assertions or code that's expected to
|
||||
// generate Google Test non-fatal failures. It asserts that the given
|
||||
@ -190,32 +190,43 @@ class SingleFailureChecker {
|
||||
// Note that even though the implementations of the following two
|
||||
// macros are much alike, we cannot refactor them to use a common
|
||||
// helper macro, due to some peculiarity in how the preprocessor
|
||||
// works. The AcceptsMacroThatExpandsToUnprotectedComma test in
|
||||
// gtest_unittest.cc will fail to compile if we do that.
|
||||
// works. If we do that, the code won't compile when the user gives
|
||||
// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that
|
||||
// expands to code containing an unprotected comma. The
|
||||
// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc
|
||||
// catches that.
|
||||
//
|
||||
// For the same reason, we have to write
|
||||
// if (::testing::internal::AlwaysTrue()) { statement; }
|
||||
// instead of
|
||||
// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
|
||||
// to avoid an MSVC warning on unreachable code.
|
||||
#define EXPECT_NONFATAL_FAILURE(statement, substr) \
|
||||
do {\
|
||||
::testing::TestPartResultArray gtest_failures;\
|
||||
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||
>est_failures, ::testing::TPRT_NONFATAL_FAILURE, (substr));\
|
||||
>est_failures, ::testing::TestPartResult::kNonFatalFailure, \
|
||||
(substr));\
|
||||
{\
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||
::testing::ScopedFakeTestPartResultReporter:: \
|
||||
INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\
|
||||
statement;\
|
||||
if (::testing::internal::AlwaysTrue()) { statement; }\
|
||||
}\
|
||||
} while (false)
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
|
||||
do {\
|
||||
::testing::TestPartResultArray gtest_failures;\
|
||||
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||
>est_failures, ::testing::TPRT_NONFATAL_FAILURE, (substr));\
|
||||
>est_failures, ::testing::TestPartResult::kNonFatalFailure, \
|
||||
(substr));\
|
||||
{\
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||
::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS,\
|
||||
>est_failures);\
|
||||
statement;\
|
||||
if (::testing::internal::AlwaysTrue()) { statement; }\
|
||||
}\
|
||||
} while (false)
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||
|
@ -39,24 +39,24 @@
|
||||
|
||||
namespace testing {
|
||||
|
||||
// The possible outcomes of a test part (i.e. an assertion or an
|
||||
// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
|
||||
enum TestPartResultType {
|
||||
TPRT_SUCCESS, // Succeeded.
|
||||
TPRT_NONFATAL_FAILURE, // Failed but the test can continue.
|
||||
TPRT_FATAL_FAILURE // Failed and the test should be terminated.
|
||||
};
|
||||
|
||||
// A copyable object representing the result of a test part (i.e. an
|
||||
// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
|
||||
//
|
||||
// Don't inherit from TestPartResult as its destructor is not virtual.
|
||||
class TestPartResult {
|
||||
public:
|
||||
// The possible outcomes of a test part (i.e. an assertion or an
|
||||
// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
|
||||
enum Type {
|
||||
kSuccess, // Succeeded.
|
||||
kNonFatalFailure, // Failed but the test can continue.
|
||||
kFatalFailure // Failed and the test should be terminated.
|
||||
};
|
||||
|
||||
// C'tor. TestPartResult does NOT have a default constructor.
|
||||
// Always use this constructor (with parameters) to create a
|
||||
// TestPartResult object.
|
||||
TestPartResult(TestPartResultType type,
|
||||
TestPartResult(Type type,
|
||||
const char* file_name,
|
||||
int line_number,
|
||||
const char* message)
|
||||
@ -68,7 +68,7 @@ class TestPartResult {
|
||||
}
|
||||
|
||||
// Gets the outcome of the test part.
|
||||
TestPartResultType type() const { return type_; }
|
||||
Type type() const { return type_; }
|
||||
|
||||
// Gets the name of the source file where the test part took place, or
|
||||
// NULL if it's unknown.
|
||||
@ -85,18 +85,18 @@ class TestPartResult {
|
||||
const char* message() const { return message_.c_str(); }
|
||||
|
||||
// Returns true iff the test part passed.
|
||||
bool passed() const { return type_ == TPRT_SUCCESS; }
|
||||
bool passed() const { return type_ == kSuccess; }
|
||||
|
||||
// Returns true iff the test part failed.
|
||||
bool failed() const { return type_ != TPRT_SUCCESS; }
|
||||
bool failed() const { return type_ != kSuccess; }
|
||||
|
||||
// Returns true iff the test part non-fatally failed.
|
||||
bool nonfatally_failed() const { return type_ == TPRT_NONFATAL_FAILURE; }
|
||||
bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
|
||||
|
||||
// Returns true iff the test part fatally failed.
|
||||
bool fatally_failed() const { return type_ == TPRT_FATAL_FAILURE; }
|
||||
bool fatally_failed() const { return type_ == kFatalFailure; }
|
||||
private:
|
||||
TestPartResultType type_;
|
||||
Type type_;
|
||||
|
||||
// Gets the summary of the failure message by omitting the stack
|
||||
// trace in it.
|
||||
@ -136,9 +136,8 @@ class TestPartResultArray {
|
||||
// Returns the number of TestPartResult objects in the array.
|
||||
int size() const;
|
||||
private:
|
||||
// Internally we use a list to simulate the array. Yes, this means
|
||||
// that random access is O(N) in time, but it's OK for its purpose.
|
||||
internal::List<TestPartResult>* const list_;
|
||||
// Internally we use a Vector to implement the array.
|
||||
internal::Vector<TestPartResult>* const array_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);
|
||||
};
|
||||
|
@ -51,16 +51,6 @@
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_H_
|
||||
|
||||
// The following platform macros are used throughout Google Test:
|
||||
// _WIN32_WCE Windows CE (set in project files)
|
||||
//
|
||||
// Note that even though _MSC_VER and _WIN32_WCE really indicate a compiler
|
||||
// and a Win32 implementation, respectively, we use them to indicate the
|
||||
// combination of compiler - Win 32 API - C library, since the code currently
|
||||
// only supports:
|
||||
// Windows proper with Visual C++ and MS C library (_MSC_VER && !_WIN32_WCE) and
|
||||
// Windows Mobile with Visual C++ and no C library (_WIN32_WCE).
|
||||
|
||||
#include <limits>
|
||||
#include <gtest/internal/gtest-internal.h>
|
||||
#include <gtest/internal/gtest-string.h>
|
||||
@ -126,6 +116,9 @@ GTEST_DECLARE_string_(output);
|
||||
// test.
|
||||
GTEST_DECLARE_bool_(print_time);
|
||||
|
||||
// This flag specifies the random number seed.
|
||||
GTEST_DECLARE_int32_(random_seed);
|
||||
|
||||
// This flag sets how many times the tests are repeated. The default value
|
||||
// is 1. If the value is -1 the tests are repeating forever.
|
||||
GTEST_DECLARE_int32_(repeat);
|
||||
@ -134,6 +127,9 @@ GTEST_DECLARE_int32_(repeat);
|
||||
// stack frames in failure stack traces.
|
||||
GTEST_DECLARE_bool_(show_internal_stack_frames);
|
||||
|
||||
// When this flag is specified, tests' order is randomized on every iteration.
|
||||
GTEST_DECLARE_bool_(shuffle);
|
||||
|
||||
// This flag specifies the maximum number of stack frames to be
|
||||
// printed in a failure message.
|
||||
GTEST_DECLARE_int32_(stack_trace_depth);
|
||||
@ -148,7 +144,22 @@ const int kMaxStackTraceDepth = 100;
|
||||
|
||||
namespace internal {
|
||||
|
||||
class AssertHelper;
|
||||
class DefaultGlobalTestPartResultReporter;
|
||||
class ExecDeathTest;
|
||||
class NoExecDeathTest;
|
||||
class FinalSuccessChecker;
|
||||
class GTestFlagSaver;
|
||||
class TestInfoImpl;
|
||||
class TestResultAccessor;
|
||||
class TestEventListenersAccessor;
|
||||
class TestEventRepeater;
|
||||
class WindowsDeathTest;
|
||||
class UnitTestImpl* GetUnitTestImpl();
|
||||
void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
|
||||
const String& message);
|
||||
class PrettyUnitTestResultPrinter;
|
||||
class XmlUnitTestResultPrinter;
|
||||
|
||||
// Converts a streamable value to a String. A NULL pointer is
|
||||
// converted to "(null)". When the input value is a ::string,
|
||||
@ -279,6 +290,13 @@ class Test {
|
||||
// Returns true iff the current test has a fatal failure.
|
||||
static bool HasFatalFailure();
|
||||
|
||||
// Returns true iff the current test has a non-fatal failure.
|
||||
static bool HasNonfatalFailure();
|
||||
|
||||
// Returns true iff the current test has a (either fatal or
|
||||
// non-fatal) failure.
|
||||
static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); }
|
||||
|
||||
// Logs a property for the current test. Only the last value for a given
|
||||
// key is remembered.
|
||||
// These are public static so they can be called from utility functions
|
||||
@ -346,6 +364,155 @@ class Test {
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(Test);
|
||||
};
|
||||
|
||||
typedef internal::TimeInMillis TimeInMillis;
|
||||
|
||||
// A copyable object representing a user specified test property which can be
|
||||
// output as a key/value string pair.
|
||||
//
|
||||
// Don't inherit from TestProperty as its destructor is not virtual.
|
||||
class TestProperty {
|
||||
public:
|
||||
// C'tor. TestProperty does NOT have a default constructor.
|
||||
// Always use this constructor (with parameters) to create a
|
||||
// TestProperty object.
|
||||
TestProperty(const char* key, const char* value) :
|
||||
key_(key), value_(value) {
|
||||
}
|
||||
|
||||
// Gets the user supplied key.
|
||||
const char* key() const {
|
||||
return key_.c_str();
|
||||
}
|
||||
|
||||
// Gets the user supplied value.
|
||||
const char* value() const {
|
||||
return value_.c_str();
|
||||
}
|
||||
|
||||
// Sets a new value, overriding the one supplied in the constructor.
|
||||
void SetValue(const char* new_value) {
|
||||
value_ = new_value;
|
||||
}
|
||||
|
||||
private:
|
||||
// The key supplied by the user.
|
||||
internal::String key_;
|
||||
// The value supplied by the user.
|
||||
internal::String value_;
|
||||
};
|
||||
|
||||
// The result of a single Test. This includes a list of
|
||||
// TestPartResults, a list of TestProperties, a count of how many
|
||||
// death tests there are in the Test, and how much time it took to run
|
||||
// the Test.
|
||||
//
|
||||
// TestResult is not copyable.
|
||||
class TestResult {
|
||||
public:
|
||||
// Creates an empty TestResult.
|
||||
TestResult();
|
||||
|
||||
// D'tor. Do not inherit from TestResult.
|
||||
~TestResult();
|
||||
|
||||
// Gets the number of all test parts. This is the sum of the number
|
||||
// of successful test parts and the number of failed test parts.
|
||||
int total_part_count() const;
|
||||
|
||||
// Returns the number of the test properties.
|
||||
int test_property_count() const;
|
||||
|
||||
// Returns true iff the test passed (i.e. no test part failed).
|
||||
bool Passed() const { return !Failed(); }
|
||||
|
||||
// Returns true iff the test failed.
|
||||
bool Failed() const;
|
||||
|
||||
// Returns true iff the test fatally failed.
|
||||
bool HasFatalFailure() const;
|
||||
|
||||
// Returns true iff the test has a non-fatal failure.
|
||||
bool HasNonfatalFailure() const;
|
||||
|
||||
// Returns the elapsed time, in milliseconds.
|
||||
TimeInMillis elapsed_time() const { return elapsed_time_; }
|
||||
|
||||
// Returns the i-th test part result among all the results. i can range
|
||||
// from 0 to test_property_count() - 1. If i is not in that range, aborts
|
||||
// the program.
|
||||
const TestPartResult& GetTestPartResult(int i) const;
|
||||
|
||||
// Returns the i-th test property. i can range from 0 to
|
||||
// test_property_count() - 1. If i is not in that range, aborts the
|
||||
// program.
|
||||
const TestProperty& GetTestProperty(int i) const;
|
||||
|
||||
private:
|
||||
friend class TestInfo;
|
||||
friend class UnitTest;
|
||||
friend class internal::DefaultGlobalTestPartResultReporter;
|
||||
friend class internal::ExecDeathTest;
|
||||
friend class internal::TestInfoImpl;
|
||||
friend class internal::TestResultAccessor;
|
||||
friend class internal::UnitTestImpl;
|
||||
friend class internal::WindowsDeathTest;
|
||||
|
||||
// Gets the vector of TestPartResults.
|
||||
const internal::Vector<TestPartResult>& test_part_results() const {
|
||||
return *test_part_results_;
|
||||
}
|
||||
|
||||
// Gets the vector of TestProperties.
|
||||
const internal::Vector<TestProperty>& test_properties() const {
|
||||
return *test_properties_;
|
||||
}
|
||||
|
||||
// Sets the elapsed time.
|
||||
void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; }
|
||||
|
||||
// Adds a test property to the list. The property is validated and may add
|
||||
// a non-fatal failure if invalid (e.g., if it conflicts with reserved
|
||||
// key names). If a property is already recorded for the same key, the
|
||||
// value will be updated, rather than storing multiple values for the same
|
||||
// key.
|
||||
void RecordProperty(const TestProperty& test_property);
|
||||
|
||||
// Adds a failure if the key is a reserved attribute of Google Test
|
||||
// testcase tags. Returns true if the property is valid.
|
||||
// TODO(russr): Validate attribute names are legal and human readable.
|
||||
static bool ValidateTestProperty(const TestProperty& test_property);
|
||||
|
||||
// Adds a test part result to the list.
|
||||
void AddTestPartResult(const TestPartResult& test_part_result);
|
||||
|
||||
// Returns the death test count.
|
||||
int death_test_count() const { return death_test_count_; }
|
||||
|
||||
// Increments the death test count, returning the new count.
|
||||
int increment_death_test_count() { return ++death_test_count_; }
|
||||
|
||||
// Clears the test part results.
|
||||
void ClearTestPartResults();
|
||||
|
||||
// Clears the object.
|
||||
void Clear();
|
||||
|
||||
// Protects mutable state of the property vector and of owned
|
||||
// properties, whose values may be updated.
|
||||
internal::Mutex test_properites_mutex_;
|
||||
|
||||
// The vector of TestPartResults
|
||||
internal::scoped_ptr<internal::Vector<TestPartResult> > test_part_results_;
|
||||
// The vector of TestProperties
|
||||
internal::scoped_ptr<internal::Vector<TestProperty> > test_properties_;
|
||||
// Running count of death tests.
|
||||
int death_test_count_;
|
||||
// The elapsed time, in milliseconds.
|
||||
TimeInMillis elapsed_time_;
|
||||
|
||||
// We disallow copying TestResult.
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult);
|
||||
}; // class TestResult
|
||||
|
||||
// A TestInfo object stores the following information about a test:
|
||||
//
|
||||
@ -376,7 +543,9 @@ class TestInfo {
|
||||
// Returns the test comment.
|
||||
const char* comment() const;
|
||||
|
||||
// Returns true if this test should run.
|
||||
// Returns true if this test should run, that is if the test is not disabled
|
||||
// (or it is disabled but the also_run_disabled_tests flag has been specified)
|
||||
// and its full name matches the user-specified filter.
|
||||
//
|
||||
// Google Test allows the user to filter the tests by their full names.
|
||||
// The full name of a test Bar in test case Foo is defined as
|
||||
@ -393,15 +562,16 @@ class TestInfo {
|
||||
bool should_run() const;
|
||||
|
||||
// Returns the result of the test.
|
||||
const internal::TestResult* result() const;
|
||||
const TestResult* result() const;
|
||||
|
||||
private:
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
friend class internal::DefaultDeathTestFactory;
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
friend class internal::TestInfoImpl;
|
||||
friend class internal::UnitTestImpl;
|
||||
friend class Test;
|
||||
friend class TestCase;
|
||||
friend class internal::TestInfoImpl;
|
||||
friend class internal::UnitTestImpl;
|
||||
friend TestInfo* internal::MakeAndRegisterTestInfo(
|
||||
const char* test_case_name, const char* name,
|
||||
const char* test_case_comment, const char* comment,
|
||||
@ -410,6 +580,9 @@ class TestInfo {
|
||||
Test::TearDownTestCaseFunc tear_down_tc,
|
||||
internal::TestFactoryBase* factory);
|
||||
|
||||
// Returns true if this test matches the user-specified filter.
|
||||
bool matches_filter() const;
|
||||
|
||||
// Increments the number of death tests encountered in this test so
|
||||
// far.
|
||||
int increment_death_test_count();
|
||||
@ -431,6 +604,141 @@ class TestInfo {
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo);
|
||||
};
|
||||
|
||||
// A test case, which consists of a vector of TestInfos.
|
||||
//
|
||||
// TestCase is not copyable.
|
||||
class TestCase {
|
||||
public:
|
||||
// Creates a TestCase with the given name.
|
||||
//
|
||||
// TestCase does NOT have a default constructor. Always use this
|
||||
// constructor to create a TestCase object.
|
||||
//
|
||||
// Arguments:
|
||||
//
|
||||
// name: name of the test case
|
||||
// set_up_tc: pointer to the function that sets up the test case
|
||||
// tear_down_tc: pointer to the function that tears down the test case
|
||||
TestCase(const char* name, const char* comment,
|
||||
Test::SetUpTestCaseFunc set_up_tc,
|
||||
Test::TearDownTestCaseFunc tear_down_tc);
|
||||
|
||||
// Destructor of TestCase.
|
||||
virtual ~TestCase();
|
||||
|
||||
// Gets the name of the TestCase.
|
||||
const char* name() const { return name_.c_str(); }
|
||||
|
||||
// Returns the test case comment.
|
||||
const char* comment() const { return comment_.c_str(); }
|
||||
|
||||
// Returns true if any test in this test case should run.
|
||||
bool should_run() const { return should_run_; }
|
||||
|
||||
// Gets the number of successful tests in this test case.
|
||||
int successful_test_count() const;
|
||||
|
||||
// Gets the number of failed tests in this test case.
|
||||
int failed_test_count() const;
|
||||
|
||||
// Gets the number of disabled tests in this test case.
|
||||
int disabled_test_count() const;
|
||||
|
||||
// Get the number of tests in this test case that should run.
|
||||
int test_to_run_count() const;
|
||||
|
||||
// Gets the number of all tests in this test case.
|
||||
int total_test_count() const;
|
||||
|
||||
// Returns true iff the test case passed.
|
||||
bool Passed() const { return !Failed(); }
|
||||
|
||||
// Returns true iff the test case failed.
|
||||
bool Failed() const { return failed_test_count() > 0; }
|
||||
|
||||
// Returns the elapsed time, in milliseconds.
|
||||
TimeInMillis elapsed_time() const { return elapsed_time_; }
|
||||
|
||||
// Returns the i-th test among all the tests. i can range from 0 to
|
||||
// total_test_count() - 1. If i is not in that range, returns NULL.
|
||||
const TestInfo* GetTestInfo(int i) const;
|
||||
|
||||
private:
|
||||
friend class Test;
|
||||
friend class internal::UnitTestImpl;
|
||||
|
||||
// Gets the (mutable) vector of TestInfos in this TestCase.
|
||||
internal::Vector<TestInfo*>& test_info_list() { return *test_info_list_; }
|
||||
|
||||
// Gets the (immutable) vector of TestInfos in this TestCase.
|
||||
const internal::Vector<TestInfo *> & test_info_list() const {
|
||||
return *test_info_list_;
|
||||
}
|
||||
|
||||
// Returns the i-th test among all the tests. i can range from 0 to
|
||||
// total_test_count() - 1. If i is not in that range, returns NULL.
|
||||
TestInfo* GetMutableTestInfo(int i);
|
||||
|
||||
// Sets the should_run member.
|
||||
void set_should_run(bool should) { should_run_ = should; }
|
||||
|
||||
// Adds a TestInfo to this test case. Will delete the TestInfo upon
|
||||
// destruction of the TestCase object.
|
||||
void AddTestInfo(TestInfo * test_info);
|
||||
|
||||
// Clears the results of all tests in this test case.
|
||||
void ClearResult();
|
||||
|
||||
// Clears the results of all tests in the given test case.
|
||||
static void ClearTestCaseResult(TestCase* test_case) {
|
||||
test_case->ClearResult();
|
||||
}
|
||||
|
||||
// Runs every test in this TestCase.
|
||||
void Run();
|
||||
|
||||
// Returns true iff test passed.
|
||||
static bool TestPassed(const TestInfo * test_info);
|
||||
|
||||
// Returns true iff test failed.
|
||||
static bool TestFailed(const TestInfo * test_info);
|
||||
|
||||
// Returns true iff test is disabled.
|
||||
static bool TestDisabled(const TestInfo * test_info);
|
||||
|
||||
// Returns true if the given test should run.
|
||||
static bool ShouldRunTest(const TestInfo *test_info);
|
||||
|
||||
// Shuffles the tests in this test case.
|
||||
void ShuffleTests(internal::Random* random);
|
||||
|
||||
// Restores the test order to before the first shuffle.
|
||||
void UnshuffleTests();
|
||||
|
||||
// Name of the test case.
|
||||
internal::String name_;
|
||||
// Comment on the test case.
|
||||
internal::String comment_;
|
||||
// The vector of TestInfos in their original order. It owns the
|
||||
// elements in the vector.
|
||||
const internal::scoped_ptr<internal::Vector<TestInfo*> > test_info_list_;
|
||||
// Provides a level of indirection for the test list to allow easy
|
||||
// shuffling and restoring the test order. The i-th element in this
|
||||
// vector is the index of the i-th test in the shuffled test list.
|
||||
const internal::scoped_ptr<internal::Vector<int> > test_indices_;
|
||||
// Pointer to the function that sets up the test case.
|
||||
Test::SetUpTestCaseFunc set_up_tc_;
|
||||
// Pointer to the function that tears down the test case.
|
||||
Test::TearDownTestCaseFunc tear_down_tc_;
|
||||
// True iff any test in this test case should run.
|
||||
bool should_run_;
|
||||
// Elapsed time, in milliseconds.
|
||||
TimeInMillis elapsed_time_;
|
||||
|
||||
// We disallow copying TestCases.
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase);
|
||||
};
|
||||
|
||||
// An Environment object is capable of setting up and tearing down an
|
||||
// environment. The user should subclass this to define his own
|
||||
// environment(s).
|
||||
@ -462,7 +770,159 @@ class Environment {
|
||||
virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
|
||||
};
|
||||
|
||||
// A UnitTest consists of a list of TestCases.
|
||||
// The interface for tracing execution of tests. The methods are organized in
|
||||
// the order the corresponding events are fired.
|
||||
class TestEventListener {
|
||||
public:
|
||||
virtual ~TestEventListener() {}
|
||||
|
||||
// Fired before any test activity starts.
|
||||
virtual void OnTestProgramStart(const UnitTest& unit_test) = 0;
|
||||
|
||||
// Fired before each iteration of tests starts. There may be more than
|
||||
// one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration
|
||||
// index, starting from 0.
|
||||
virtual void OnTestIterationStart(const UnitTest& unit_test,
|
||||
int iteration) = 0;
|
||||
|
||||
// Fired before environment set-up for each iteration of tests starts.
|
||||
virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0;
|
||||
|
||||
// Fired after environment set-up for each iteration of tests ends.
|
||||
virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0;
|
||||
|
||||
// Fired before the test case starts.
|
||||
virtual void OnTestCaseStart(const TestCase& test_case) = 0;
|
||||
|
||||
// Fired before the test starts.
|
||||
virtual void OnTestStart(const TestInfo& test_info) = 0;
|
||||
|
||||
// Fired after a failed assertion or a SUCCESS().
|
||||
virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0;
|
||||
|
||||
// Fired after the test ends.
|
||||
virtual void OnTestEnd(const TestInfo& test_info) = 0;
|
||||
|
||||
// Fired after the test case ends.
|
||||
virtual void OnTestCaseEnd(const TestCase& test_case) = 0;
|
||||
|
||||
// Fired before environment tear-down for each iteration of tests starts.
|
||||
virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0;
|
||||
|
||||
// Fired after environment tear-down for each iteration of tests ends.
|
||||
virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0;
|
||||
|
||||
// Fired after each iteration of tests finishes.
|
||||
virtual void OnTestIterationEnd(const UnitTest& unit_test,
|
||||
int iteration) = 0;
|
||||
|
||||
// Fired after all test activities have ended.
|
||||
virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0;
|
||||
};
|
||||
|
||||
// The convenience class for users who need to override just one or two
|
||||
// methods and are not concerned that a possible change to a signature of
|
||||
// the methods they override will not be caught during the build. For
|
||||
// comments about each method please see the definition of TestEventListener
|
||||
// above.
|
||||
class EmptyTestEventListener : public TestEventListener {
|
||||
public:
|
||||
virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
|
||||
virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
|
||||
int /*iteration*/) {}
|
||||
virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {}
|
||||
virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
|
||||
virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
|
||||
virtual void OnTestStart(const TestInfo& /*test_info*/) {}
|
||||
virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {}
|
||||
virtual void OnTestEnd(const TestInfo& /*test_info*/) {}
|
||||
virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}
|
||||
virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {}
|
||||
virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
|
||||
virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
|
||||
int /*iteration*/) {}
|
||||
virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
|
||||
};
|
||||
|
||||
// TestEventListeners lets users add listeners to track events in Google Test.
|
||||
class TestEventListeners {
|
||||
public:
|
||||
TestEventListeners();
|
||||
~TestEventListeners();
|
||||
|
||||
// Appends an event listener to the end of the list. Google Test assumes
|
||||
// the ownership of the listener (i.e. it will delete the listener when
|
||||
// the test program finishes).
|
||||
void Append(TestEventListener* listener);
|
||||
|
||||
// Removes the given event listener from the list and returns it. It then
|
||||
// becomes the caller's responsibility to delete the listener. Returns
|
||||
// NULL if the listener is not found in the list.
|
||||
TestEventListener* Release(TestEventListener* listener);
|
||||
|
||||
// Returns the standard listener responsible for the default console
|
||||
// output. Can be removed from the listeners list to shut down default
|
||||
// console output. Note that removing this object from the listener list
|
||||
// with Release transfers its ownership to the caller and makes this
|
||||
// function return NULL the next time.
|
||||
TestEventListener* default_result_printer() const {
|
||||
return default_result_printer_;
|
||||
}
|
||||
|
||||
// Returns the standard listener responsible for the default XML output
|
||||
// controlled by the --gtest_output=xml flag. Can be removed from the
|
||||
// listeners list by users who want to shut down the default XML output
|
||||
// controlled by this flag and substitute it with custom one. Note that
|
||||
// removing this object from the listener list with Release transfers its
|
||||
// ownership to the caller and makes this function return NULL the next
|
||||
// time.
|
||||
TestEventListener* default_xml_generator() const {
|
||||
return default_xml_generator_;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class TestCase;
|
||||
friend class internal::DefaultGlobalTestPartResultReporter;
|
||||
friend class internal::NoExecDeathTest;
|
||||
friend class internal::TestEventListenersAccessor;
|
||||
friend class internal::TestInfoImpl;
|
||||
friend class internal::UnitTestImpl;
|
||||
|
||||
// Returns repeater that broadcasts the TestEventListener events to all
|
||||
// subscribers.
|
||||
TestEventListener* repeater();
|
||||
|
||||
// Sets the default_result_printer attribute to the provided listener.
|
||||
// The listener is also added to the listener list and previous
|
||||
// default_result_printer is removed from it and deleted. The listener can
|
||||
// also be NULL in which case it will not be added to the list. Does
|
||||
// nothing if the previous and the current listener objects are the same.
|
||||
void SetDefaultResultPrinter(TestEventListener* listener);
|
||||
|
||||
// Sets the default_xml_generator attribute to the provided listener. The
|
||||
// listener is also added to the listener list and previous
|
||||
// default_xml_generator is removed from it and deleted. The listener can
|
||||
// also be NULL in which case it will not be added to the list. Does
|
||||
// nothing if the previous and the current listener objects are the same.
|
||||
void SetDefaultXmlGenerator(TestEventListener* listener);
|
||||
|
||||
// Controls whether events will be forwarded by the repeater to the
|
||||
// listeners in the list.
|
||||
bool EventForwardingEnabled() const;
|
||||
void SuppressEventForwarding();
|
||||
|
||||
// The actual list of listeners.
|
||||
internal::TestEventRepeater* repeater_;
|
||||
// Listener responsible for the standard result output.
|
||||
TestEventListener* default_result_printer_;
|
||||
// Listener responsible for the creation of the XML output file.
|
||||
TestEventListener* default_xml_generator_;
|
||||
|
||||
// We disallow copying TestEventListeners.
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners);
|
||||
};
|
||||
|
||||
// A UnitTest consists of a vector of TestCases.
|
||||
//
|
||||
// This is a singleton class. The only instance of UnitTest is
|
||||
// created when UnitTest::GetInstance() is first called. This
|
||||
@ -479,33 +939,6 @@ class UnitTest {
|
||||
// Consecutive calls will return the same object.
|
||||
static UnitTest* GetInstance();
|
||||
|
||||
// Registers and returns a global test environment. When a test
|
||||
// program is run, all global test environments will be set-up in
|
||||
// the order they were registered. After all tests in the program
|
||||
// have finished, all global test environments will be torn-down in
|
||||
// the *reverse* order they were registered.
|
||||
//
|
||||
// The UnitTest object takes ownership of the given environment.
|
||||
//
|
||||
// This method can only be called from the main thread.
|
||||
Environment* AddEnvironment(Environment* env);
|
||||
|
||||
// Adds a TestPartResult to the current TestResult object. All
|
||||
// Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc)
|
||||
// eventually call this to report their results. The user code
|
||||
// should use the assertion macros instead of calling this directly.
|
||||
//
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
void AddTestPartResult(TestPartResultType result_type,
|
||||
const char* file_name,
|
||||
int line_number,
|
||||
const internal::String& message,
|
||||
const internal::String& os_stack_trace);
|
||||
|
||||
// Adds a TestProperty to the current TestResult object. If the result already
|
||||
// contains a property with the same key, the value will be updated.
|
||||
void RecordPropertyForCurrentTest(const char* key, const char* value);
|
||||
|
||||
// Runs all tests in this UnitTest object and prints the result.
|
||||
// Returns 0 if successful, or 1 otherwise.
|
||||
//
|
||||
@ -526,19 +959,107 @@ class UnitTest {
|
||||
// or NULL if no test is running.
|
||||
const TestInfo* current_test_info() const;
|
||||
|
||||
// Returns the random seed used at the start of the current test run.
|
||||
int random_seed() const;
|
||||
|
||||
#if GTEST_HAS_PARAM_TEST
|
||||
// Returns the ParameterizedTestCaseRegistry object used to keep track of
|
||||
// value-parameterized tests and instantiate and register them.
|
||||
//
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
internal::ParameterizedTestCaseRegistry& parameterized_test_registry();
|
||||
#endif // GTEST_HAS_PARAM_TEST
|
||||
|
||||
// Gets the number of successful test cases.
|
||||
int successful_test_case_count() const;
|
||||
|
||||
// Gets the number of failed test cases.
|
||||
int failed_test_case_count() const;
|
||||
|
||||
// Gets the number of all test cases.
|
||||
int total_test_case_count() const;
|
||||
|
||||
// Gets the number of all test cases that contain at least one test
|
||||
// that should run.
|
||||
int test_case_to_run_count() const;
|
||||
|
||||
// Gets the number of successful tests.
|
||||
int successful_test_count() const;
|
||||
|
||||
// Gets the number of failed tests.
|
||||
int failed_test_count() const;
|
||||
|
||||
// Gets the number of disabled tests.
|
||||
int disabled_test_count() const;
|
||||
|
||||
// Gets the number of all tests.
|
||||
int total_test_count() const;
|
||||
|
||||
// Gets the number of tests that should run.
|
||||
int test_to_run_count() const;
|
||||
|
||||
// Gets the elapsed time, in milliseconds.
|
||||
TimeInMillis elapsed_time() const;
|
||||
|
||||
// Returns true iff the unit test passed (i.e. all test cases passed).
|
||||
bool Passed() const;
|
||||
|
||||
// Returns true iff the unit test failed (i.e. some test case failed
|
||||
// or something outside of all tests failed).
|
||||
bool Failed() const;
|
||||
|
||||
// Gets the i-th test case among all the test cases. i can range from 0 to
|
||||
// total_test_case_count() - 1. If i is not in that range, returns NULL.
|
||||
const TestCase* GetTestCase(int i) const;
|
||||
|
||||
// Returns the list of event listeners that can be used to track events
|
||||
// inside Google Test.
|
||||
TestEventListeners& listeners();
|
||||
|
||||
private:
|
||||
// Registers and returns a global test environment. When a test
|
||||
// program is run, all global test environments will be set-up in
|
||||
// the order they were registered. After all tests in the program
|
||||
// have finished, all global test environments will be torn-down in
|
||||
// the *reverse* order they were registered.
|
||||
//
|
||||
// The UnitTest object takes ownership of the given environment.
|
||||
//
|
||||
// This method can only be called from the main thread.
|
||||
Environment* AddEnvironment(Environment* env);
|
||||
|
||||
// Adds a TestPartResult to the current TestResult object. All
|
||||
// Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc)
|
||||
// eventually call this to report their results. The user code
|
||||
// should use the assertion macros instead of calling this directly.
|
||||
void AddTestPartResult(TestPartResult::Type result_type,
|
||||
const char* file_name,
|
||||
int line_number,
|
||||
const internal::String& message,
|
||||
const internal::String& os_stack_trace);
|
||||
|
||||
// Adds a TestProperty to the current TestResult object. If the result already
|
||||
// contains a property with the same key, the value will be updated.
|
||||
void RecordPropertyForCurrentTest(const char* key, const char* value);
|
||||
|
||||
// Gets the i-th test case among all the test cases. i can range from 0 to
|
||||
// total_test_case_count() - 1. If i is not in that range, returns NULL.
|
||||
TestCase* GetMutableTestCase(int i);
|
||||
|
||||
// Accessors for the implementation object.
|
||||
internal::UnitTestImpl* impl() { return impl_; }
|
||||
const internal::UnitTestImpl* impl() const { return impl_; }
|
||||
private:
|
||||
// ScopedTrace is a friend as it needs to modify the per-thread
|
||||
// trace stack, which is a private member of UnitTest.
|
||||
|
||||
// These classes and funcions are friends as they need to access private
|
||||
// members of UnitTest.
|
||||
friend class Test;
|
||||
friend class internal::AssertHelper;
|
||||
friend class internal::ScopedTrace;
|
||||
friend Environment* AddGlobalTestEnvironment(Environment* env);
|
||||
friend internal::UnitTestImpl* internal::GetUnitTestImpl();
|
||||
friend void internal::ReportFailureInUnknownLocation(
|
||||
TestPartResult::Type result_type,
|
||||
const internal::String& message);
|
||||
|
||||
// Creates an empty UnitTest.
|
||||
UnitTest();
|
||||
@ -929,16 +1450,38 @@ AssertionResult DoubleNearPredFormat(const char* expr1,
|
||||
class AssertHelper {
|
||||
public:
|
||||
// Constructor.
|
||||
AssertHelper(TestPartResultType type, const char* file, int line,
|
||||
AssertHelper(TestPartResult::Type type,
|
||||
const char* file,
|
||||
int line,
|
||||
const char* message);
|
||||
~AssertHelper();
|
||||
|
||||
// Message assignment is a semantic trick to enable assertion
|
||||
// streaming; see the GTEST_MESSAGE_ macro below.
|
||||
void operator=(const Message& message) const;
|
||||
|
||||
private:
|
||||
TestPartResultType const type_;
|
||||
const char* const file_;
|
||||
int const line_;
|
||||
String const message_;
|
||||
// We put our data in a struct so that the size of the AssertHelper class can
|
||||
// be as small as possible. This is important because gcc is incapable of
|
||||
// re-using stack space even for temporary variables, so every EXPECT_EQ
|
||||
// reserves stack space for another AssertHelper.
|
||||
struct AssertHelperData {
|
||||
AssertHelperData(TestPartResult::Type t,
|
||||
const char* srcfile,
|
||||
int line_num,
|
||||
const char* msg)
|
||||
: type(t), file(srcfile), line(line_num), message(msg) { }
|
||||
|
||||
TestPartResult::Type const type;
|
||||
const char* const file;
|
||||
int const line;
|
||||
String const message;
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData);
|
||||
};
|
||||
|
||||
AssertHelperData* const data_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper);
|
||||
};
|
||||
|
@ -39,10 +39,6 @@
|
||||
|
||||
#include <gtest/internal/gtest-internal.h>
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST && GTEST_OS_WINDOWS
|
||||
#include <io.h>
|
||||
#endif // GTEST_HAS_DEATH_TEST && GTEST_OS_WINDOWS
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
@ -157,7 +153,7 @@ bool ExitedUnsuccessfully(int exit_status);
|
||||
// ASSERT_EXIT*, and EXPECT_EXIT*.
|
||||
#define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (true) { \
|
||||
if (::testing::internal::AlwaysTrue()) { \
|
||||
const ::testing::internal::RE& gtest_regex = (regex); \
|
||||
::testing::internal::DeathTest* gtest_dt; \
|
||||
if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \
|
||||
@ -176,7 +172,7 @@ bool ExitedUnsuccessfully(int exit_status);
|
||||
case ::testing::internal::DeathTest::EXECUTE_TEST: { \
|
||||
::testing::internal::DeathTest::ReturnSentinel \
|
||||
gtest_sentinel(gtest_dt); \
|
||||
GTEST_HIDE_UNREACHABLE_CODE_(statement); \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
|
||||
break; \
|
||||
} \
|
||||
@ -196,32 +192,24 @@ class InternalRunDeathTestFlag {
|
||||
InternalRunDeathTestFlag(const String& file,
|
||||
int line,
|
||||
int index,
|
||||
int status_fd)
|
||||
: file_(file), line_(line), index_(index), status_fd_(status_fd) {}
|
||||
int write_fd)
|
||||
: file_(file), line_(line), index_(index), write_fd_(write_fd) {}
|
||||
|
||||
~InternalRunDeathTestFlag() {
|
||||
if (status_fd_ >= 0)
|
||||
// Suppress MSVC complaints about POSIX functions.
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4996)
|
||||
#endif // _MSC_VER
|
||||
close(status_fd_);
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif // _MSC_VER
|
||||
if (write_fd_ >= 0)
|
||||
posix::Close(write_fd_);
|
||||
}
|
||||
|
||||
String file() const { return file_; }
|
||||
int line() const { return line_; }
|
||||
int index() const { return index_; }
|
||||
int status_fd() const { return status_fd_; }
|
||||
int write_fd() const { return write_fd_; }
|
||||
|
||||
private:
|
||||
String file_;
|
||||
int line_;
|
||||
int index_;
|
||||
int status_fd_;
|
||||
int write_fd_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
|
||||
};
|
||||
@ -231,6 +219,53 @@ class InternalRunDeathTestFlag {
|
||||
// the flag is specified; otherwise returns NULL.
|
||||
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
|
||||
|
||||
#else // GTEST_HAS_DEATH_TEST
|
||||
|
||||
// This macro is used for implementing macros such as
|
||||
// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
|
||||
// death tests are not supported. Those macros must compile on such systems
|
||||
// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on
|
||||
// systems that support death tests. This allows one to write such a macro
|
||||
// on a system that does not support death tests and be sure that it will
|
||||
// compile on a death-test supporting system.
|
||||
//
|
||||
// Parameters:
|
||||
// statement - A statement that a macro such as EXPECT_DEATH would test
|
||||
// for program termination. This macro has to make sure this
|
||||
// statement is compiled but not executed, to ensure that
|
||||
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
|
||||
// parameter iff EXPECT_DEATH compiles with it.
|
||||
// regex - A regex that a macro such as EXPECT_DEATH would use to test
|
||||
// the output of statement. This parameter has to be
|
||||
// compiled but not evaluated by this macro, to ensure that
|
||||
// this macro only accepts expressions that a macro such as
|
||||
// EXPECT_DEATH would accept.
|
||||
// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
|
||||
// and a return statement for ASSERT_DEATH_IF_SUPPORTED.
|
||||
// This ensures that ASSERT_DEATH_IF_SUPPORTED will not
|
||||
// compile inside functions where ASSERT_DEATH doesn't
|
||||
// compile.
|
||||
//
|
||||
// The branch that has an always false condition is used to ensure that
|
||||
// statement and regex are compiled (and thus syntactically correct) but
|
||||
// never executed. The unreachable code macro protects the terminator
|
||||
// statement from generating an 'unreachable code' warning in case
|
||||
// statement unconditionally returns or throws. The Message constructor at
|
||||
// the end allows the syntax of streaming additional messages into the
|
||||
// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
|
||||
#define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (::testing::internal::AlwaysTrue()) { \
|
||||
GTEST_LOG_(WARNING) \
|
||||
<< "Death tests are not supported on this platform.\n" \
|
||||
<< "Statement '" #statement "' cannot be verified."; \
|
||||
} else if (::testing::internal::AlwaysFalse()) { \
|
||||
::testing::internal::RE::PartialMatch(".*", (regex)); \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
terminator; \
|
||||
} else \
|
||||
::testing::Message()
|
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
} // namespace internal
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -121,25 +121,20 @@ namespace testing {
|
||||
|
||||
// Forward declaration of classes.
|
||||
|
||||
class AssertionResult; // Result of an assertion.
|
||||
class Message; // Represents a failure message.
|
||||
class Test; // Represents a test.
|
||||
class TestCase; // A collection of related tests.
|
||||
class TestPartResult; // Result of a test part.
|
||||
class TestInfo; // Information about a test.
|
||||
class TestPartResult; // Result of a test part.
|
||||
class UnitTest; // A collection of test cases.
|
||||
class UnitTestEventListenerInterface; // Listens to Google Test events.
|
||||
class AssertionResult; // Result of an assertion.
|
||||
|
||||
namespace internal {
|
||||
|
||||
struct TraceInfo; // Information about a trace point.
|
||||
class ScopedTrace; // Implements scoped trace.
|
||||
class TestInfoImpl; // Opaque implementation of TestInfo
|
||||
class TestResult; // Result of a single Test.
|
||||
class UnitTestImpl; // Opaque implementation of UnitTest
|
||||
|
||||
template <typename E> class List; // A generic list.
|
||||
template <typename E> class ListNode; // A node in a generic list.
|
||||
template <typename E> class Vector; // A generic vector.
|
||||
|
||||
// How many times InitGoogleTest() has been called.
|
||||
extern int g_init_gtest_count;
|
||||
@ -231,13 +226,13 @@ String StreamableToString(const T& streamable);
|
||||
// This overload makes sure that all pointers (including
|
||||
// those to char or wchar_t) are printed as raw pointers.
|
||||
template <typename T>
|
||||
inline String FormatValueForFailureMessage(internal::true_type dummy,
|
||||
inline String FormatValueForFailureMessage(internal::true_type /*dummy*/,
|
||||
T* pointer) {
|
||||
return StreamableToString(static_cast<const void*>(pointer));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline String FormatValueForFailureMessage(internal::false_type dummy,
|
||||
inline String FormatValueForFailureMessage(internal::false_type /*dummy*/,
|
||||
const T& value) {
|
||||
return StreamableToString(value);
|
||||
}
|
||||
@ -403,7 +398,7 @@ class FloatingPoint {
|
||||
// around may change its bits, although the new value is guaranteed
|
||||
// to be also a NAN. Therefore, don't expect this constructor to
|
||||
// preserve the bits in x when x is a NAN.
|
||||
explicit FloatingPoint(const RawType& x) : value_(x) {}
|
||||
explicit FloatingPoint(const RawType& x) { u_.value_ = x; }
|
||||
|
||||
// Static methods
|
||||
|
||||
@ -412,8 +407,8 @@ class FloatingPoint {
|
||||
// This function is needed to test the AlmostEquals() method.
|
||||
static RawType ReinterpretBits(const Bits bits) {
|
||||
FloatingPoint fp(0);
|
||||
fp.bits_ = bits;
|
||||
return fp.value_;
|
||||
fp.u_.bits_ = bits;
|
||||
return fp.u_.value_;
|
||||
}
|
||||
|
||||
// Returns the floating-point number that represent positive infinity.
|
||||
@ -424,16 +419,16 @@ class FloatingPoint {
|
||||
// Non-static methods
|
||||
|
||||
// Returns the bits that represents this number.
|
||||
const Bits &bits() const { return bits_; }
|
||||
const Bits &bits() const { return u_.bits_; }
|
||||
|
||||
// Returns the exponent bits of this number.
|
||||
Bits exponent_bits() const { return kExponentBitMask & bits_; }
|
||||
Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }
|
||||
|
||||
// Returns the fraction bits of this number.
|
||||
Bits fraction_bits() const { return kFractionBitMask & bits_; }
|
||||
Bits fraction_bits() const { return kFractionBitMask & u_.bits_; }
|
||||
|
||||
// Returns the sign bit of this number.
|
||||
Bits sign_bit() const { return kSignBitMask & bits_; }
|
||||
Bits sign_bit() const { return kSignBitMask & u_.bits_; }
|
||||
|
||||
// Returns true iff this is NAN (not a number).
|
||||
bool is_nan() const {
|
||||
@ -453,10 +448,17 @@ class FloatingPoint {
|
||||
// a NAN must return false.
|
||||
if (is_nan() || rhs.is_nan()) return false;
|
||||
|
||||
return DistanceBetweenSignAndMagnitudeNumbers(bits_, rhs.bits_) <= kMaxUlps;
|
||||
return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_)
|
||||
<= kMaxUlps;
|
||||
}
|
||||
|
||||
private:
|
||||
// The data type used to store the actual floating-point number.
|
||||
union FloatingPointUnion {
|
||||
RawType value_; // The raw floating-point number.
|
||||
Bits bits_; // The bits that represent the number.
|
||||
};
|
||||
|
||||
// Converts an integer from the sign-and-magnitude representation to
|
||||
// the biased representation. More precisely, let N be 2 to the
|
||||
// power of (kBitCount - 1), an integer x is represented by the
|
||||
@ -491,10 +493,7 @@ class FloatingPoint {
|
||||
return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
|
||||
}
|
||||
|
||||
union {
|
||||
RawType value_; // The raw floating-point number.
|
||||
Bits bits_; // The bits that represent the number.
|
||||
};
|
||||
FloatingPointUnion u_;
|
||||
};
|
||||
|
||||
// Typedefs the instances of the FloatingPoint template class that we
|
||||
@ -637,7 +636,7 @@ class TypedTestCasePState {
|
||||
"REGISTER_TYPED_TEST_CASE_P(%s, ...).\n",
|
||||
FormatFileLocation(file, line).c_str(), test_name, case_name);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
posix::Abort();
|
||||
}
|
||||
defined_test_names_.insert(test_name);
|
||||
return true;
|
||||
@ -746,8 +745,8 @@ class TypeParameterizedTestCase {
|
||||
template <GTEST_TEMPLATE_ Fixture, typename Types>
|
||||
class TypeParameterizedTestCase<Fixture, Templates0, Types> {
|
||||
public:
|
||||
static bool Register(const char* prefix, const char* case_name,
|
||||
const char* test_names) {
|
||||
static bool Register(const char* /*prefix*/, const char* /*case_name*/,
|
||||
const char* /*test_names*/) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -766,12 +765,37 @@ class TypeParameterizedTestCase<Fixture, Templates0, Types> {
|
||||
// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
|
||||
String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, int skip_count);
|
||||
|
||||
// Returns the number of failed test parts in the given test result object.
|
||||
int GetFailedPartCount(const TestResult* result);
|
||||
// Helpers for suppressing warnings on unreachable code or constant
|
||||
// condition.
|
||||
|
||||
// A helper for suppressing warnings on unreachable code in some macros.
|
||||
// Always returns true.
|
||||
bool AlwaysTrue();
|
||||
|
||||
// Always returns false.
|
||||
inline bool AlwaysFalse() { return !AlwaysTrue(); }
|
||||
|
||||
// A simple Linear Congruential Generator for generating random
|
||||
// numbers with a uniform distribution. Unlike rand() and srand(), it
|
||||
// doesn't use global state (and therefore can't interfere with user
|
||||
// code). Unlike rand_r(), it's portable. An LCG isn't very random,
|
||||
// but it's good enough for our purposes.
|
||||
class Random {
|
||||
public:
|
||||
static const UInt32 kMaxRange = 1u << 31;
|
||||
|
||||
explicit Random(UInt32 seed) : state_(seed) {}
|
||||
|
||||
void Reseed(UInt32 seed) { state_ = seed; }
|
||||
|
||||
// Generates a random number from [0, range). Crashes if 'range' is
|
||||
// 0 or greater than kMaxRange.
|
||||
UInt32 Generate(UInt32 range);
|
||||
|
||||
private:
|
||||
UInt32 state_;
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(Random);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
@ -780,18 +804,18 @@ bool AlwaysTrue();
|
||||
= ::testing::Message()
|
||||
|
||||
#define GTEST_FATAL_FAILURE_(message) \
|
||||
return GTEST_MESSAGE_(message, ::testing::TPRT_FATAL_FAILURE)
|
||||
return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)
|
||||
|
||||
#define GTEST_NONFATAL_FAILURE_(message) \
|
||||
GTEST_MESSAGE_(message, ::testing::TPRT_NONFATAL_FAILURE)
|
||||
GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)
|
||||
|
||||
#define GTEST_SUCCESS_(message) \
|
||||
GTEST_MESSAGE_(message, ::testing::TPRT_SUCCESS)
|
||||
GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)
|
||||
|
||||
// Suppresses MSVC warnings 4072 (unreachable code) for the code following
|
||||
// statement if it returns or throws (or doesn't return or throw in some
|
||||
// situations).
|
||||
#define GTEST_HIDE_UNREACHABLE_CODE_(statement) \
|
||||
#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \
|
||||
if (::testing::internal::AlwaysTrue()) { statement; }
|
||||
|
||||
#define GTEST_TEST_THROW_(statement, expected_exception, fail) \
|
||||
@ -799,7 +823,7 @@ bool AlwaysTrue();
|
||||
if (const char* gtest_msg = "") { \
|
||||
bool gtest_caught_expected = false; \
|
||||
try { \
|
||||
GTEST_HIDE_UNREACHABLE_CODE_(statement); \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
} \
|
||||
catch (expected_exception const&) { \
|
||||
gtest_caught_expected = true; \
|
||||
@ -823,7 +847,7 @@ bool AlwaysTrue();
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (const char* gtest_msg = "") { \
|
||||
try { \
|
||||
GTEST_HIDE_UNREACHABLE_CODE_(statement); \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
} \
|
||||
catch (...) { \
|
||||
gtest_msg = "Expected: " #statement " doesn't throw an exception.\n" \
|
||||
@ -839,7 +863,7 @@ bool AlwaysTrue();
|
||||
if (const char* gtest_msg = "") { \
|
||||
bool gtest_caught_any = false; \
|
||||
try { \
|
||||
GTEST_HIDE_UNREACHABLE_CODE_(statement); \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
} \
|
||||
catch (...) { \
|
||||
gtest_caught_any = true; \
|
||||
@ -856,7 +880,7 @@ bool AlwaysTrue();
|
||||
|
||||
#define GTEST_TEST_BOOLEAN_(boolexpr, booltext, actual, expected, fail) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (boolexpr) \
|
||||
if (::testing::internal::IsTrue(boolexpr)) \
|
||||
; \
|
||||
else \
|
||||
fail("Value of: " booltext "\n Actual: " #actual "\nExpected: " #expected)
|
||||
@ -865,7 +889,7 @@ bool AlwaysTrue();
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (const char* gtest_msg = "") { \
|
||||
::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \
|
||||
GTEST_HIDE_UNREACHABLE_CODE_(statement); \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \
|
||||
gtest_msg = "Expected: " #statement " doesn't generate new fatal " \
|
||||
"failures in the current thread.\n" \
|
||||
|
@ -63,6 +63,9 @@ class ValueArray1 {
|
||||
operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray1& other);
|
||||
|
||||
const T1 v1_;
|
||||
};
|
||||
|
||||
@ -78,6 +81,9 @@ class ValueArray2 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray2& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
};
|
||||
@ -94,6 +100,9 @@ class ValueArray3 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray3& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -112,6 +121,9 @@ class ValueArray4 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray4& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -131,6 +143,9 @@ class ValueArray5 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray5& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -152,6 +167,9 @@ class ValueArray6 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray6& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -174,6 +192,9 @@ class ValueArray7 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray7& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -198,6 +219,9 @@ class ValueArray8 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray8& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -223,6 +247,9 @@ class ValueArray9 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray9& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -249,6 +276,9 @@ class ValueArray10 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray10& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -277,6 +307,9 @@ class ValueArray11 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray11& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -307,6 +340,9 @@ class ValueArray12 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray12& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -339,6 +375,9 @@ class ValueArray13 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray13& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -372,6 +411,9 @@ class ValueArray14 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray14& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -406,6 +448,9 @@ class ValueArray15 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray15& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -443,6 +488,9 @@ class ValueArray16 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray16& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -481,6 +529,9 @@ class ValueArray17 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray17& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -520,6 +571,9 @@ class ValueArray18 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray18& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -560,6 +614,9 @@ class ValueArray19 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray19& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -602,6 +659,9 @@ class ValueArray20 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray20& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -646,6 +706,9 @@ class ValueArray21 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray21& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -691,6 +754,9 @@ class ValueArray22 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray22& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -739,6 +805,9 @@ class ValueArray23 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray23& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -788,6 +857,9 @@ class ValueArray24 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray24& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -838,6 +910,9 @@ class ValueArray25 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray25& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -890,6 +965,9 @@ class ValueArray26 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray26& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -944,6 +1022,9 @@ class ValueArray27 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray27& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -999,6 +1080,9 @@ class ValueArray28 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray28& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -1055,6 +1139,9 @@ class ValueArray29 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray29& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -1113,6 +1200,9 @@ class ValueArray30 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray30& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -1173,6 +1263,9 @@ class ValueArray31 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray31& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -1234,6 +1327,9 @@ class ValueArray32 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray32& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -1297,6 +1393,9 @@ class ValueArray33 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray33& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -1361,6 +1460,9 @@ class ValueArray34 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray34& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -1427,6 +1529,9 @@ class ValueArray35 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray35& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -1495,6 +1600,9 @@ class ValueArray36 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray36& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -1565,6 +1673,9 @@ class ValueArray37 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray37& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -1636,6 +1747,9 @@ class ValueArray38 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray38& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -1708,6 +1822,9 @@ class ValueArray39 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray39& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -1782,6 +1899,9 @@ class ValueArray40 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray40& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -1858,6 +1978,9 @@ class ValueArray41 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray41& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -1935,6 +2058,9 @@ class ValueArray42 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray42& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -2013,6 +2139,9 @@ class ValueArray43 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray43& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -2093,6 +2222,9 @@ class ValueArray44 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray44& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -2174,6 +2306,9 @@ class ValueArray45 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray45& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -2257,6 +2392,9 @@ class ValueArray46 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray46& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -2343,6 +2481,9 @@ class ValueArray47 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray47& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -2430,6 +2571,9 @@ class ValueArray48 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray48& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -2518,6 +2662,9 @@ class ValueArray49 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray49& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -2607,6 +2754,9 @@ class ValueArray50 {
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValueArray50& other);
|
||||
|
||||
const T1 v1_;
|
||||
const T2 v2_;
|
||||
const T3 v3_;
|
||||
@ -2757,6 +2907,9 @@ class CartesianProductGenerator2
|
||||
current2_ == end2_;
|
||||
}
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const Iterator& other);
|
||||
|
||||
const ParamGeneratorInterface<ParamType>* const base_;
|
||||
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
|
||||
// current[i]_ is the actual traversing iterator.
|
||||
@ -2767,11 +2920,14 @@ class CartesianProductGenerator2
|
||||
const typename ParamGenerator<T2>::iterator end2_;
|
||||
typename ParamGenerator<T2>::iterator current2_;
|
||||
ParamType current_value_;
|
||||
};
|
||||
}; // class CartesianProductGenerator2::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductGenerator2& other);
|
||||
|
||||
const ParamGenerator<T1> g1_;
|
||||
const ParamGenerator<T2> g2_;
|
||||
};
|
||||
}; // class CartesianProductGenerator2
|
||||
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
@ -2879,6 +3035,9 @@ class CartesianProductGenerator3
|
||||
current3_ == end3_;
|
||||
}
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const Iterator& other);
|
||||
|
||||
const ParamGeneratorInterface<ParamType>* const base_;
|
||||
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
|
||||
// current[i]_ is the actual traversing iterator.
|
||||
@ -2892,12 +3051,15 @@ class CartesianProductGenerator3
|
||||
const typename ParamGenerator<T3>::iterator end3_;
|
||||
typename ParamGenerator<T3>::iterator current3_;
|
||||
ParamType current_value_;
|
||||
};
|
||||
}; // class CartesianProductGenerator3::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductGenerator3& other);
|
||||
|
||||
const ParamGenerator<T1> g1_;
|
||||
const ParamGenerator<T2> g2_;
|
||||
const ParamGenerator<T3> g3_;
|
||||
};
|
||||
}; // class CartesianProductGenerator3
|
||||
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
@ -3020,6 +3182,9 @@ class CartesianProductGenerator4
|
||||
current4_ == end4_;
|
||||
}
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const Iterator& other);
|
||||
|
||||
const ParamGeneratorInterface<ParamType>* const base_;
|
||||
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
|
||||
// current[i]_ is the actual traversing iterator.
|
||||
@ -3036,13 +3201,16 @@ class CartesianProductGenerator4
|
||||
const typename ParamGenerator<T4>::iterator end4_;
|
||||
typename ParamGenerator<T4>::iterator current4_;
|
||||
ParamType current_value_;
|
||||
};
|
||||
}; // class CartesianProductGenerator4::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductGenerator4& other);
|
||||
|
||||
const ParamGenerator<T1> g1_;
|
||||
const ParamGenerator<T2> g2_;
|
||||
const ParamGenerator<T3> g3_;
|
||||
const ParamGenerator<T4> g4_;
|
||||
};
|
||||
}; // class CartesianProductGenerator4
|
||||
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
@ -3177,6 +3345,9 @@ class CartesianProductGenerator5
|
||||
current5_ == end5_;
|
||||
}
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const Iterator& other);
|
||||
|
||||
const ParamGeneratorInterface<ParamType>* const base_;
|
||||
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
|
||||
// current[i]_ is the actual traversing iterator.
|
||||
@ -3196,14 +3367,17 @@ class CartesianProductGenerator5
|
||||
const typename ParamGenerator<T5>::iterator end5_;
|
||||
typename ParamGenerator<T5>::iterator current5_;
|
||||
ParamType current_value_;
|
||||
};
|
||||
}; // class CartesianProductGenerator5::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductGenerator5& other);
|
||||
|
||||
const ParamGenerator<T1> g1_;
|
||||
const ParamGenerator<T2> g2_;
|
||||
const ParamGenerator<T3> g3_;
|
||||
const ParamGenerator<T4> g4_;
|
||||
const ParamGenerator<T5> g5_;
|
||||
};
|
||||
}; // class CartesianProductGenerator5
|
||||
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
@ -3353,6 +3527,9 @@ class CartesianProductGenerator6
|
||||
current6_ == end6_;
|
||||
}
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const Iterator& other);
|
||||
|
||||
const ParamGeneratorInterface<ParamType>* const base_;
|
||||
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
|
||||
// current[i]_ is the actual traversing iterator.
|
||||
@ -3375,7 +3552,10 @@ class CartesianProductGenerator6
|
||||
const typename ParamGenerator<T6>::iterator end6_;
|
||||
typename ParamGenerator<T6>::iterator current6_;
|
||||
ParamType current_value_;
|
||||
};
|
||||
}; // class CartesianProductGenerator6::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductGenerator6& other);
|
||||
|
||||
const ParamGenerator<T1> g1_;
|
||||
const ParamGenerator<T2> g2_;
|
||||
@ -3383,7 +3563,7 @@ class CartesianProductGenerator6
|
||||
const ParamGenerator<T4> g4_;
|
||||
const ParamGenerator<T5> g5_;
|
||||
const ParamGenerator<T6> g6_;
|
||||
};
|
||||
}; // class CartesianProductGenerator6
|
||||
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
@ -3546,6 +3726,9 @@ class CartesianProductGenerator7
|
||||
current7_ == end7_;
|
||||
}
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const Iterator& other);
|
||||
|
||||
const ParamGeneratorInterface<ParamType>* const base_;
|
||||
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
|
||||
// current[i]_ is the actual traversing iterator.
|
||||
@ -3571,7 +3754,10 @@ class CartesianProductGenerator7
|
||||
const typename ParamGenerator<T7>::iterator end7_;
|
||||
typename ParamGenerator<T7>::iterator current7_;
|
||||
ParamType current_value_;
|
||||
};
|
||||
}; // class CartesianProductGenerator7::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductGenerator7& other);
|
||||
|
||||
const ParamGenerator<T1> g1_;
|
||||
const ParamGenerator<T2> g2_;
|
||||
@ -3580,7 +3766,7 @@ class CartesianProductGenerator7
|
||||
const ParamGenerator<T5> g5_;
|
||||
const ParamGenerator<T6> g6_;
|
||||
const ParamGenerator<T7> g7_;
|
||||
};
|
||||
}; // class CartesianProductGenerator7
|
||||
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
@ -3758,6 +3944,9 @@ class CartesianProductGenerator8
|
||||
current8_ == end8_;
|
||||
}
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const Iterator& other);
|
||||
|
||||
const ParamGeneratorInterface<ParamType>* const base_;
|
||||
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
|
||||
// current[i]_ is the actual traversing iterator.
|
||||
@ -3786,7 +3975,10 @@ class CartesianProductGenerator8
|
||||
const typename ParamGenerator<T8>::iterator end8_;
|
||||
typename ParamGenerator<T8>::iterator current8_;
|
||||
ParamType current_value_;
|
||||
};
|
||||
}; // class CartesianProductGenerator8::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductGenerator8& other);
|
||||
|
||||
const ParamGenerator<T1> g1_;
|
||||
const ParamGenerator<T2> g2_;
|
||||
@ -3796,7 +3988,7 @@ class CartesianProductGenerator8
|
||||
const ParamGenerator<T6> g6_;
|
||||
const ParamGenerator<T7> g7_;
|
||||
const ParamGenerator<T8> g8_;
|
||||
};
|
||||
}; // class CartesianProductGenerator8
|
||||
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
@ -3987,6 +4179,9 @@ class CartesianProductGenerator9
|
||||
current9_ == end9_;
|
||||
}
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const Iterator& other);
|
||||
|
||||
const ParamGeneratorInterface<ParamType>* const base_;
|
||||
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
|
||||
// current[i]_ is the actual traversing iterator.
|
||||
@ -4018,7 +4213,10 @@ class CartesianProductGenerator9
|
||||
const typename ParamGenerator<T9>::iterator end9_;
|
||||
typename ParamGenerator<T9>::iterator current9_;
|
||||
ParamType current_value_;
|
||||
};
|
||||
}; // class CartesianProductGenerator9::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductGenerator9& other);
|
||||
|
||||
const ParamGenerator<T1> g1_;
|
||||
const ParamGenerator<T2> g2_;
|
||||
@ -4029,7 +4227,7 @@ class CartesianProductGenerator9
|
||||
const ParamGenerator<T7> g7_;
|
||||
const ParamGenerator<T8> g8_;
|
||||
const ParamGenerator<T9> g9_;
|
||||
};
|
||||
}; // class CartesianProductGenerator9
|
||||
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
@ -4233,6 +4431,9 @@ class CartesianProductGenerator10
|
||||
current10_ == end10_;
|
||||
}
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const Iterator& other);
|
||||
|
||||
const ParamGeneratorInterface<ParamType>* const base_;
|
||||
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
|
||||
// current[i]_ is the actual traversing iterator.
|
||||
@ -4267,7 +4468,10 @@ class CartesianProductGenerator10
|
||||
const typename ParamGenerator<T10>::iterator end10_;
|
||||
typename ParamGenerator<T10>::iterator current10_;
|
||||
ParamType current_value_;
|
||||
};
|
||||
}; // class CartesianProductGenerator10::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductGenerator10& other);
|
||||
|
||||
const ParamGenerator<T1> g1_;
|
||||
const ParamGenerator<T2> g2_;
|
||||
@ -4279,7 +4483,7 @@ class CartesianProductGenerator10
|
||||
const ParamGenerator<T8> g8_;
|
||||
const ParamGenerator<T9> g9_;
|
||||
const ParamGenerator<T10> g10_;
|
||||
};
|
||||
}; // class CartesianProductGenerator10
|
||||
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
@ -4302,9 +4506,12 @@ CartesianProductHolder2(const Generator1& g1, const Generator2& g2)
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductHolder2& other);
|
||||
|
||||
const Generator1 g1_;
|
||||
const Generator2 g2_;
|
||||
};
|
||||
}; // class CartesianProductHolder2
|
||||
|
||||
template <class Generator1, class Generator2, class Generator3>
|
||||
class CartesianProductHolder3 {
|
||||
@ -4322,10 +4529,13 @@ CartesianProductHolder3(const Generator1& g1, const Generator2& g2,
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductHolder3& other);
|
||||
|
||||
const Generator1 g1_;
|
||||
const Generator2 g2_;
|
||||
const Generator3 g3_;
|
||||
};
|
||||
}; // class CartesianProductHolder3
|
||||
|
||||
template <class Generator1, class Generator2, class Generator3,
|
||||
class Generator4>
|
||||
@ -4345,11 +4555,14 @@ CartesianProductHolder4(const Generator1& g1, const Generator2& g2,
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductHolder4& other);
|
||||
|
||||
const Generator1 g1_;
|
||||
const Generator2 g2_;
|
||||
const Generator3 g3_;
|
||||
const Generator4 g4_;
|
||||
};
|
||||
}; // class CartesianProductHolder4
|
||||
|
||||
template <class Generator1, class Generator2, class Generator3,
|
||||
class Generator4, class Generator5>
|
||||
@ -4370,12 +4583,15 @@ CartesianProductHolder5(const Generator1& g1, const Generator2& g2,
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductHolder5& other);
|
||||
|
||||
const Generator1 g1_;
|
||||
const Generator2 g2_;
|
||||
const Generator3 g3_;
|
||||
const Generator4 g4_;
|
||||
const Generator5 g5_;
|
||||
};
|
||||
}; // class CartesianProductHolder5
|
||||
|
||||
template <class Generator1, class Generator2, class Generator3,
|
||||
class Generator4, class Generator5, class Generator6>
|
||||
@ -4399,13 +4615,16 @@ CartesianProductHolder6(const Generator1& g1, const Generator2& g2,
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductHolder6& other);
|
||||
|
||||
const Generator1 g1_;
|
||||
const Generator2 g2_;
|
||||
const Generator3 g3_;
|
||||
const Generator4 g4_;
|
||||
const Generator5 g5_;
|
||||
const Generator6 g6_;
|
||||
};
|
||||
}; // class CartesianProductHolder6
|
||||
|
||||
template <class Generator1, class Generator2, class Generator3,
|
||||
class Generator4, class Generator5, class Generator6, class Generator7>
|
||||
@ -4431,6 +4650,9 @@ CartesianProductHolder7(const Generator1& g1, const Generator2& g2,
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductHolder7& other);
|
||||
|
||||
const Generator1 g1_;
|
||||
const Generator2 g2_;
|
||||
const Generator3 g3_;
|
||||
@ -4438,7 +4660,7 @@ CartesianProductHolder7(const Generator1& g1, const Generator2& g2,
|
||||
const Generator5 g5_;
|
||||
const Generator6 g6_;
|
||||
const Generator7 g7_;
|
||||
};
|
||||
}; // class CartesianProductHolder7
|
||||
|
||||
template <class Generator1, class Generator2, class Generator3,
|
||||
class Generator4, class Generator5, class Generator6, class Generator7,
|
||||
@ -4467,6 +4689,9 @@ CartesianProductHolder8(const Generator1& g1, const Generator2& g2,
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductHolder8& other);
|
||||
|
||||
const Generator1 g1_;
|
||||
const Generator2 g2_;
|
||||
const Generator3 g3_;
|
||||
@ -4475,7 +4700,7 @@ CartesianProductHolder8(const Generator1& g1, const Generator2& g2,
|
||||
const Generator6 g6_;
|
||||
const Generator7 g7_;
|
||||
const Generator8 g8_;
|
||||
};
|
||||
}; // class CartesianProductHolder8
|
||||
|
||||
template <class Generator1, class Generator2, class Generator3,
|
||||
class Generator4, class Generator5, class Generator6, class Generator7,
|
||||
@ -4507,6 +4732,9 @@ CartesianProductHolder9(const Generator1& g1, const Generator2& g2,
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductHolder9& other);
|
||||
|
||||
const Generator1 g1_;
|
||||
const Generator2 g2_;
|
||||
const Generator3 g3_;
|
||||
@ -4516,7 +4744,7 @@ CartesianProductHolder9(const Generator1& g1, const Generator2& g2,
|
||||
const Generator7 g7_;
|
||||
const Generator8 g8_;
|
||||
const Generator9 g9_;
|
||||
};
|
||||
}; // class CartesianProductHolder9
|
||||
|
||||
template <class Generator1, class Generator2, class Generator3,
|
||||
class Generator4, class Generator5, class Generator6, class Generator7,
|
||||
@ -4550,6 +4778,9 @@ CartesianProductHolder10(const Generator1& g1, const Generator2& g2,
|
||||
}
|
||||
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const CartesianProductHolder10& other);
|
||||
|
||||
const Generator1 g1_;
|
||||
const Generator2 g2_;
|
||||
const Generator3 g3_;
|
||||
@ -4560,7 +4791,7 @@ CartesianProductHolder10(const Generator1& g1, const Generator2& g2,
|
||||
const Generator8 g8_;
|
||||
const Generator9 g9_;
|
||||
const Generator10 g10_;
|
||||
};
|
||||
}; // class CartesianProductHolder10
|
||||
|
||||
#endif // GTEST_HAS_COMBINE
|
||||
|
||||
|
@ -248,6 +248,9 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
|
||||
: base_(other.base_), value_(other.value_), index_(other.index_),
|
||||
step_(other.step_) {}
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const Iterator& other);
|
||||
|
||||
const ParamGeneratorInterface<T>* const base_;
|
||||
T value_;
|
||||
int index_;
|
||||
@ -263,6 +266,9 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
|
||||
return end_index;
|
||||
}
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const RangeGenerator& other);
|
||||
|
||||
const T begin_;
|
||||
const T end_;
|
||||
const IncrementT step_;
|
||||
@ -349,7 +355,10 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
|
||||
// Use of scoped_ptr helps manage cached value's lifetime,
|
||||
// which is bound by the lifespan of the iterator itself.
|
||||
mutable scoped_ptr<const T> value_;
|
||||
};
|
||||
}; // class ValuesInIteratorRangeGenerator::Iterator
|
||||
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ValuesInIteratorRangeGenerator& other);
|
||||
|
||||
const ContainerType container_;
|
||||
}; // class ValuesInIteratorRangeGenerator
|
||||
@ -483,8 +492,8 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
|
||||
// about a generator.
|
||||
int AddTestCaseInstantiation(const char* instantiation_name,
|
||||
GeneratorCreationFunc* func,
|
||||
const char* file,
|
||||
int line) {
|
||||
const char* /* file */,
|
||||
int /* line */) {
|
||||
instantiations_.push_back(::std::make_pair(instantiation_name, func));
|
||||
return 0; // Return value used only to run this method in namespace scope.
|
||||
}
|
||||
|
@ -58,8 +58,15 @@
|
||||
// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that
|
||||
// std::wstring does/doesn't work (Google Test can
|
||||
// be used where std::wstring is unavailable).
|
||||
// GTEST_HAS_TR1_TUPLE 1 - Define it to 1/0 to indicate tr1::tuple
|
||||
// GTEST_HAS_TR1_TUPLE - Define it to 1/0 to indicate tr1::tuple
|
||||
// is/isn't available.
|
||||
// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the
|
||||
// compiler supports Microsoft's "Structured
|
||||
// Exception Handling".
|
||||
// GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google
|
||||
// Test's own tr1 tuple implementation should be
|
||||
// used. Unused when the user sets
|
||||
// GTEST_HAS_TR1_TUPLE to 0.
|
||||
|
||||
// This header defines the following utilities:
|
||||
//
|
||||
@ -70,7 +77,10 @@
|
||||
// GTEST_OS_MAC - Mac OS X
|
||||
// GTEST_OS_SOLARIS - Sun Solaris
|
||||
// GTEST_OS_SYMBIAN - Symbian
|
||||
// GTEST_OS_WINDOWS - Windows
|
||||
// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile)
|
||||
// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop
|
||||
// GTEST_OS_WINDOWS_MINGW - MinGW
|
||||
// GTEST_OS_WINODWS_MOBILE - Windows Mobile
|
||||
// GTEST_OS_ZOS - z/OS
|
||||
//
|
||||
// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the
|
||||
@ -96,8 +106,8 @@
|
||||
//
|
||||
// Macros for basic C++ coding:
|
||||
// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
|
||||
// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances don't have to
|
||||
// be used.
|
||||
// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a
|
||||
// variable don't have to be used.
|
||||
// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=.
|
||||
// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used.
|
||||
//
|
||||
@ -147,9 +157,15 @@
|
||||
// Int32FromGTestEnv() - parses an Int32 environment variable.
|
||||
// StringFromGTestEnv() - parses a string environment variable.
|
||||
|
||||
#include <stddef.h> // For ptrdiff_t
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <iostream> // Used for GTEST_CHECK_
|
||||
#include <string.h>
|
||||
#ifndef _WIN32_WCE
|
||||
#include <sys/stat.h>
|
||||
#endif // !_WIN32_WCE
|
||||
|
||||
#include <iostream> // NOLINT
|
||||
|
||||
#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com"
|
||||
#define GTEST_FLAG_PREFIX_ "gtest_"
|
||||
@ -167,14 +183,17 @@
|
||||
// Determines the platform on which Google Test is compiled.
|
||||
#ifdef __CYGWIN__
|
||||
#define GTEST_OS_CYGWIN 1
|
||||
#elif __SYMBIAN32__
|
||||
#elif defined __SYMBIAN32__
|
||||
#define GTEST_OS_SYMBIAN 1
|
||||
#elif defined _MSC_VER
|
||||
// TODO(kenton@google.com): GTEST_OS_WINDOWS is currently used to mean
|
||||
// both "The OS is Windows" and "The compiler is MSVC". These
|
||||
// meanings really should be separated in order to better support
|
||||
// Windows compilers other than MSVC.
|
||||
#elif defined _WIN32
|
||||
#define GTEST_OS_WINDOWS 1
|
||||
#ifdef _WIN32_WCE
|
||||
#define GTEST_OS_WINDOWS_MOBILE 1
|
||||
#elif defined(__MINGW__) || defined(__MINGW32__)
|
||||
#define GTEST_OS_WINDOWS_MINGW 1
|
||||
#else
|
||||
#define GTEST_OS_WINDOWS_DESKTOP 1
|
||||
#endif // _WIN32_WCE
|
||||
#elif defined __APPLE__
|
||||
#define GTEST_OS_MAC 1
|
||||
#elif defined __linux__
|
||||
@ -185,35 +204,54 @@
|
||||
#define GTEST_OS_SOLARIS 1
|
||||
#elif defined(__HAIKU__)
|
||||
#define GTEST_OS_HAIKU
|
||||
#endif // _MSC_VER
|
||||
#endif // __CYGWIN__
|
||||
|
||||
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
|
||||
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_SYMBIAN || \
|
||||
GTEST_OS_SOLARIS
|
||||
|
||||
// On some platforms, <regex.h> needs someone to define size_t, and
|
||||
// won't compile otherwise. We can #include it here as we already
|
||||
// included <stdlib.h>, which is guaranteed to define size_t through
|
||||
// <stddef.h>.
|
||||
#include <regex.h> // NOLINT
|
||||
#include <strings.h> // NOLINT
|
||||
#include <sys/types.h> // NOLINT
|
||||
#include <unistd.h> // NOLINT
|
||||
|
||||
#define GTEST_USES_POSIX_RE 1
|
||||
|
||||
#elif GTEST_OS_WINDOWS
|
||||
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
#include <direct.h> // NOLINT
|
||||
#include <io.h> // NOLINT
|
||||
#endif
|
||||
|
||||
// <regex.h> is not available on Windows. Use our own simple regex
|
||||
// implementation instead.
|
||||
#define GTEST_USES_SIMPLE_RE 1
|
||||
|
||||
#else
|
||||
|
||||
// <regex.h> may not be available on this platform. Use our own
|
||||
// simple regex implementation instead.
|
||||
#define GTEST_USES_SIMPLE_RE 1
|
||||
|
||||
#endif // GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
|
||||
#endif // GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC ||
|
||||
// GTEST_OS_SYMBIAN || GTEST_OS_SOLARIS
|
||||
|
||||
// Defines GTEST_HAS_EXCEPTIONS to 1 if exceptions are enabled, or 0
|
||||
// otherwise.
|
||||
|
||||
#ifdef _MSC_VER // Compiled by MSVC?
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS
|
||||
// macro to enable exceptions, so we'll do the same.
|
||||
// Assumes that exceptions are enabled by default.
|
||||
#ifndef _HAS_EXCEPTIONS // MSVC uses this macro to enable exceptions.
|
||||
#ifndef _HAS_EXCEPTIONS
|
||||
#define _HAS_EXCEPTIONS 1
|
||||
#endif // _HAS_EXCEPTIONS
|
||||
#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS
|
||||
#else // The compiler is not MSVC.
|
||||
#else // The compiler is not MSVC or C++Builder.
|
||||
// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. For
|
||||
// other compilers, we assume exceptions are disabled to be
|
||||
// conservative.
|
||||
@ -222,7 +260,7 @@
|
||||
#else
|
||||
#define GTEST_HAS_EXCEPTIONS 0
|
||||
#endif // defined(__GNUC__) && __EXCEPTIONS
|
||||
#endif // _MSC_VER
|
||||
#endif // defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
|
||||
// Determines whether ::std::string and ::string are available.
|
||||
|
||||
@ -325,35 +363,80 @@
|
||||
#define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC)
|
||||
#endif // GTEST_HAS_PTHREAD
|
||||
|
||||
// Determines whether tr1/tuple is available. If you have tr1/tuple
|
||||
// on your platform, define GTEST_HAS_TR1_TUPLE=1 for both the Google
|
||||
// Test project and your tests. If you would like Google Test to detect
|
||||
// tr1/tuple on your platform automatically, please open an issue
|
||||
// ticket at http://code.google.com/p/googletest.
|
||||
// Determines whether Google Test can use tr1/tuple. You can define
|
||||
// this macro to 0 to prevent Google Test from using tuple (any
|
||||
// feature depending on tuple with be disabled in this mode).
|
||||
#ifndef GTEST_HAS_TR1_TUPLE
|
||||
// The user didn't tell us not to do it, so we assume it's OK.
|
||||
#define GTEST_HAS_TR1_TUPLE 1
|
||||
#endif // GTEST_HAS_TR1_TUPLE
|
||||
|
||||
// Determines whether Google Test's own tr1 tuple implementation
|
||||
// should be used.
|
||||
#ifndef GTEST_USE_OWN_TR1_TUPLE
|
||||
// The user didn't tell us, so we need to figure it out.
|
||||
|
||||
// GCC provides <tr1/tuple> since 4.0.0.
|
||||
// We use our own tr1 tuple if we aren't sure the user has an
|
||||
// implementation of it already. At this time, GCC 4.0.0+ is the only
|
||||
// mainstream compiler that comes with a TR1 tuple implementation.
|
||||
// MSVC 2008 (9.0) provides TR1 tuple in a 323 MB Feature Pack
|
||||
// download, which we cannot assume the user has. MSVC 2010 isn't
|
||||
// released yet.
|
||||
#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
|
||||
#define GTEST_HAS_TR1_TUPLE 1
|
||||
#define GTEST_USE_OWN_TR1_TUPLE 0
|
||||
#else
|
||||
#define GTEST_HAS_TR1_TUPLE 0
|
||||
#endif // __GNUC__
|
||||
#endif // GTEST_HAS_TR1_TUPLE
|
||||
#define GTEST_USE_OWN_TR1_TUPLE 1
|
||||
#endif // defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
|
||||
|
||||
#endif // GTEST_USE_OWN_TR1_TUPLE
|
||||
|
||||
// To avoid conditional compilation everywhere, we make it
|
||||
// gtest-port.h's responsibility to #include the header implementing
|
||||
// tr1/tuple.
|
||||
#if GTEST_HAS_TR1_TUPLE
|
||||
#if defined(__GNUC__)
|
||||
// GCC implements tr1/tuple in the <tr1/tuple> header. This does not
|
||||
// conform to the TR1 spec, which requires the header to be <tuple>.
|
||||
|
||||
#if GTEST_USE_OWN_TR1_TUPLE
|
||||
#include <gtest/internal/gtest-tuple.h>
|
||||
#elif GTEST_OS_SYMBIAN
|
||||
|
||||
// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to
|
||||
// use STLport's tuple implementation, which unfortunately doesn't
|
||||
// work as the copy of STLport distributed with Symbian is incomplete.
|
||||
// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to
|
||||
// use its own tuple implementation.
|
||||
#ifdef BOOST_HAS_TR1_TUPLE
|
||||
#undef BOOST_HAS_TR1_TUPLE
|
||||
#endif // BOOST_HAS_TR1_TUPLE
|
||||
|
||||
// This prevents <boost/tr1/detail/config.hpp>, which defines
|
||||
// BOOST_HAS_TR1_TUPLE, from being #included by Boost's <tuple>.
|
||||
#define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED
|
||||
#include <tuple>
|
||||
|
||||
#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
|
||||
// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header. This does
|
||||
// not conform to the TR1 spec, which requires the header to be <tuple>.
|
||||
|
||||
#if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302
|
||||
// Until version 4.3.2, gcc has a bug that causes <tr1/functional>,
|
||||
// which is #included by <tr1/tuple>, to not compile when RTTI is
|
||||
// disabled. _TR1_FUNCTIONAL is the header guard for
|
||||
// <tr1/functional>. Hence the following #define is a hack to prevent
|
||||
// <tr1/functional> from being included.
|
||||
#define _TR1_FUNCTIONAL 1
|
||||
#include <tr1/tuple>
|
||||
#undef _TR1_FUNCTIONAL // Allows the user to #include
|
||||
// <tr1/functional> if he chooses to.
|
||||
#else
|
||||
// If the compiler is not GCC, we assume the user is using a
|
||||
#include <tr1/tuple>
|
||||
#endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302
|
||||
|
||||
#else
|
||||
// If the compiler is not GCC 4.0+, we assume the user is using a
|
||||
// spec-conforming TR1 implementation.
|
||||
#include <tuple>
|
||||
#endif // __GNUC__
|
||||
#endif // GTEST_USE_OWN_TR1_TUPLE
|
||||
|
||||
#endif // GTEST_HAS_TR1_TUPLE
|
||||
|
||||
// Determines whether clone(2) is supported.
|
||||
@ -379,12 +462,11 @@
|
||||
// (this is covered by GTEST_HAS_STD_STRING guard).
|
||||
// 3. abort() in a VC 7.1 application compiled as GUI in debug config
|
||||
// pops up a dialog window that cannot be suppressed programmatically.
|
||||
#if GTEST_HAS_STD_STRING && (GTEST_OS_LINUX || \
|
||||
GTEST_OS_MAC || \
|
||||
GTEST_OS_CYGWIN || \
|
||||
(GTEST_OS_WINDOWS && _MSC_VER >= 1400))
|
||||
#if GTEST_HAS_STD_STRING && \
|
||||
(GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || \
|
||||
(GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || GTEST_OS_WINDOWS_MINGW)
|
||||
#define GTEST_HAS_DEATH_TEST 1
|
||||
#include <vector>
|
||||
#include <vector> // NOLINT
|
||||
#endif
|
||||
|
||||
// Determines whether to support value-parameterized tests.
|
||||
@ -430,7 +512,7 @@
|
||||
#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: // NOLINT
|
||||
#endif
|
||||
|
||||
// Use this annotation at the end of a struct / class definition to
|
||||
// Use this annotation at the end of a struct/class definition to
|
||||
// prevent the compiler from optimizing away instances that are never
|
||||
// used. This is useful when all interesting logic happens inside the
|
||||
// c'tor and / or d'tor. Example:
|
||||
@ -438,6 +520,9 @@
|
||||
// struct Foo {
|
||||
// Foo() { ... }
|
||||
// } GTEST_ATTRIBUTE_UNUSED_;
|
||||
//
|
||||
// Also use it after a variable or parameter declaration to tell the
|
||||
// compiler the variable/parameter does not have to be used.
|
||||
#if defined(__GNUC__) && !defined(COMPILER_ICC)
|
||||
#define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused))
|
||||
#else
|
||||
@ -461,6 +546,22 @@
|
||||
#define GTEST_MUST_USE_RESULT_
|
||||
#endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC
|
||||
|
||||
// Determine whether the compiler supports Microsoft's Structured Exception
|
||||
// Handling. This is supported by several Windows compilers but generally
|
||||
// does not exist on any other system.
|
||||
#ifndef GTEST_HAS_SEH
|
||||
// The user didn't tell us, so we need to figure it out.
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
// These two compilers are known to support SEH.
|
||||
#define GTEST_HAS_SEH 1
|
||||
#else
|
||||
// Assume no SEH.
|
||||
#define GTEST_HAS_SEH 0
|
||||
#endif
|
||||
|
||||
#endif // GTEST_HAS_SEH
|
||||
|
||||
namespace testing {
|
||||
|
||||
class Message;
|
||||
@ -479,6 +580,10 @@ typedef ::std::stringstream StrStream;
|
||||
typedef ::std::strstream StrStream;
|
||||
#endif // GTEST_HAS_STD_STRING
|
||||
|
||||
// A helper for suppressing warnings on constant condition. It just
|
||||
// returns 'condition'.
|
||||
bool IsTrue(bool condition);
|
||||
|
||||
// Defines scoped_ptr.
|
||||
|
||||
// This implementation of scoped_ptr is PARTIAL - it only contains
|
||||
@ -501,7 +606,7 @@ class scoped_ptr {
|
||||
|
||||
void reset(T* p = NULL) {
|
||||
if (p != ptr_) {
|
||||
if (sizeof(T) > 0) { // Makes sure T is a complete type.
|
||||
if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type.
|
||||
delete ptr_;
|
||||
}
|
||||
ptr_ = p;
|
||||
@ -582,7 +687,8 @@ class RE {
|
||||
};
|
||||
|
||||
// Defines logging utilities:
|
||||
// GTEST_LOG_() - logs messages at the specified severity level.
|
||||
// GTEST_LOG_(severity) - logs messages at the specified severity level. The
|
||||
// message itself is streamed into the macro.
|
||||
// LogToStderr() - directs all log messages to stderr.
|
||||
// FlushInfoLog() - flushes informational log messages.
|
||||
|
||||
@ -593,13 +699,27 @@ enum GTestLogSeverity {
|
||||
GTEST_FATAL
|
||||
};
|
||||
|
||||
void GTestLog(GTestLogSeverity severity, const char* file,
|
||||
int line, const char* msg);
|
||||
// Formats log entry severity, provides a stream object for streaming the
|
||||
// log message, and terminates the message with a newline when going out of
|
||||
// scope.
|
||||
class GTestLog {
|
||||
public:
|
||||
GTestLog(GTestLogSeverity severity, const char* file, int line);
|
||||
|
||||
#define GTEST_LOG_(severity, msg)\
|
||||
::testing::internal::GTestLog(\
|
||||
::testing::internal::GTEST_##severity, __FILE__, __LINE__, \
|
||||
(::testing::Message() << (msg)).GetString().c_str())
|
||||
// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
|
||||
~GTestLog();
|
||||
|
||||
::std::ostream& GetStream() { return ::std::cerr; }
|
||||
|
||||
private:
|
||||
const GTestLogSeverity severity_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog);
|
||||
};
|
||||
|
||||
#define GTEST_LOG_(severity) \
|
||||
::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \
|
||||
__FILE__, __LINE__).GetStream()
|
||||
|
||||
inline void LogToStderr() {}
|
||||
inline void FlushInfoLog() { fflush(NULL); }
|
||||
@ -608,10 +728,8 @@ inline void FlushInfoLog() { fflush(NULL); }
|
||||
// CaptureStderr - starts capturing stderr.
|
||||
// GetCapturedStderr - stops capturing stderr and returns the captured string.
|
||||
|
||||
#if GTEST_HAS_STD_STRING
|
||||
void CaptureStderr();
|
||||
::std::string GetCapturedStderr();
|
||||
#endif // GTEST_HAS_STD_STRING
|
||||
String GetCapturedStderr();
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
@ -661,9 +779,9 @@ class ThreadLocal {
|
||||
T value_;
|
||||
};
|
||||
|
||||
// There's no portable way to detect the number of threads, so we just
|
||||
// return 0 to indicate that we cannot detect it.
|
||||
inline size_t GetThreadCount() { return 0; }
|
||||
// Returns the number of threads running in the process, or 0 to indicate that
|
||||
// we cannot detect it.
|
||||
size_t GetThreadCount();
|
||||
|
||||
// The above synchronization primitives have dummy implementations.
|
||||
// Therefore Google Test is not thread-safe.
|
||||
@ -704,18 +822,142 @@ struct is_pointer<T*> : public true_type {};
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
#define GTEST_PATH_SEP_ "\\"
|
||||
#else
|
||||
#define GTEST_PATH_SEP_ "/"
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
// Defines BiggestInt as the biggest signed integer type the compiler
|
||||
// supports.
|
||||
#if GTEST_OS_WINDOWS
|
||||
// The biggest signed integer type the compiler supports.
|
||||
typedef __int64 BiggestInt;
|
||||
#else
|
||||
#define GTEST_PATH_SEP_ "/"
|
||||
typedef long long BiggestInt; // NOLINT
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
// The testing::internal::posix namespace holds wrappers for common
|
||||
// POSIX functions. These wrappers hide the differences between
|
||||
// Windows/MSVC and POSIX systems. Since some compilers define these
|
||||
// standard functions as macros, the wrapper cannot have the same name
|
||||
// as the wrapped function.
|
||||
|
||||
namespace posix {
|
||||
|
||||
// Functions with a different name on Windows.
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
|
||||
typedef struct _stat StatStruct;
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
inline int IsATTY(int fd) { return isatty(fd); }
|
||||
inline int StrCaseCmp(const char* s1, const char* s2) {
|
||||
return stricmp(s1, s2);
|
||||
}
|
||||
inline char* StrDup(const char* src) { return strdup(src); }
|
||||
#else // !__BORLANDC__
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
inline int IsATTY(int /* fd */) { return 0; }
|
||||
#else
|
||||
inline int IsATTY(int fd) { return _isatty(fd); }
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
inline int StrCaseCmp(const char* s1, const char* s2) {
|
||||
return _stricmp(s1, s2);
|
||||
}
|
||||
inline char* StrDup(const char* src) { return _strdup(src); }
|
||||
#endif // __BORLANDC__
|
||||
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
inline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); }
|
||||
// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this
|
||||
// time and thus not defined there.
|
||||
#else
|
||||
inline int FileNo(FILE* file) { return _fileno(file); }
|
||||
inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); }
|
||||
inline int RmDir(const char* dir) { return _rmdir(dir); }
|
||||
inline bool IsDir(const StatStruct& st) {
|
||||
return (_S_IFDIR & st.st_mode) != 0;
|
||||
}
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
#else
|
||||
|
||||
typedef struct stat StatStruct;
|
||||
|
||||
inline int FileNo(FILE* file) { return fileno(file); }
|
||||
inline int IsATTY(int fd) { return isatty(fd); }
|
||||
inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); }
|
||||
inline int StrCaseCmp(const char* s1, const char* s2) {
|
||||
return strcasecmp(s1, s2);
|
||||
}
|
||||
inline char* StrDup(const char* src) { return strdup(src); }
|
||||
inline int RmDir(const char* dir) { return rmdir(dir); }
|
||||
inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
|
||||
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
|
||||
// Functions deprecated by MSVC 8.0.
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// Temporarily disable warning 4996 (deprecated function).
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4996)
|
||||
#endif
|
||||
|
||||
inline const char* StrNCpy(char* dest, const char* src, size_t n) {
|
||||
return strncpy(dest, src, n);
|
||||
}
|
||||
|
||||
// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and
|
||||
// StrError() aren't needed on Windows CE at this time and thus not
|
||||
// defined there.
|
||||
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
inline int ChDir(const char* dir) { return chdir(dir); }
|
||||
#endif
|
||||
inline FILE* FOpen(const char* path, const char* mode) {
|
||||
return fopen(path, mode);
|
||||
}
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
inline FILE *FReopen(const char* path, const char* mode, FILE* stream) {
|
||||
return freopen(path, mode, stream);
|
||||
}
|
||||
inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); }
|
||||
#endif
|
||||
inline int FClose(FILE* fp) { return fclose(fp); }
|
||||
#if !GTEST_OS_WINDOWS_MOBILE
|
||||
inline int Read(int fd, void* buf, unsigned int count) {
|
||||
return static_cast<int>(read(fd, buf, count));
|
||||
}
|
||||
inline int Write(int fd, const void* buf, unsigned int count) {
|
||||
return static_cast<int>(write(fd, buf, count));
|
||||
}
|
||||
inline int Close(int fd) { return close(fd); }
|
||||
inline const char* StrError(int errnum) { return strerror(errnum); }
|
||||
#endif
|
||||
inline const char* GetEnv(const char* name) {
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
// We are on Windows CE, which has no environment variables.
|
||||
return NULL;
|
||||
#elif defined(__BORLANDC__)
|
||||
// Environment variables which we programmatically clear will be set to the
|
||||
// empty string rather than unset (NULL). Handle that case.
|
||||
const char* const env = getenv(name);
|
||||
return (env != NULL && env[0] != '\0') ? env : NULL;
|
||||
#else
|
||||
return getenv(name);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop) // Restores the warning state.
|
||||
#endif
|
||||
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
// Windows CE has no C library. The abort() function is used in
|
||||
// several places in Google Test. This implementation provides a reasonable
|
||||
// imitation of standard behaviour.
|
||||
void Abort();
|
||||
#else
|
||||
inline void Abort() { abort(); }
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
} // namespace posix
|
||||
|
||||
// The maximum number a BiggestInt can represent. This definition
|
||||
// works no matter BiggestInt is represented in one's complement or
|
||||
// two's complement.
|
||||
@ -786,32 +1028,6 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds.
|
||||
|
||||
// Utilities for command line flags and environment variables.
|
||||
|
||||
// A wrapper for getenv() that works on Linux, Windows, and Mac OS.
|
||||
inline const char* GetEnv(const char* name) {
|
||||
#ifdef _WIN32_WCE // We are on Windows CE.
|
||||
// CE has no environment variables.
|
||||
return NULL;
|
||||
#elif GTEST_OS_WINDOWS // We are on Windows proper.
|
||||
// MSVC 8 deprecates getenv(), so we want to suppress warning 4996
|
||||
// (deprecated function) there.
|
||||
#pragma warning(push) // Saves the current warning state.
|
||||
#pragma warning(disable:4996) // Temporarily disables warning 4996.
|
||||
return getenv(name);
|
||||
#pragma warning(pop) // Restores the warning state.
|
||||
#else // We are on Linux or Mac OS.
|
||||
return getenv(name);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
// Windows CE has no C library. The abort() function is used in
|
||||
// several places in Google Test. This implementation provides a reasonable
|
||||
// imitation of standard behaviour.
|
||||
void abort();
|
||||
#else
|
||||
inline void abort() { ::abort(); }
|
||||
#endif // _WIN32_WCE
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE.
|
||||
//
|
||||
// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
|
||||
@ -826,38 +1042,12 @@ inline void abort() { ::abort(); }
|
||||
// condition itself, plus additional message streamed into it, if any,
|
||||
// and then it aborts the program. It aborts the program irrespective of
|
||||
// whether it is built in the debug mode or not.
|
||||
class GTestCheckProvider {
|
||||
public:
|
||||
GTestCheckProvider(const char* condition, const char* file, int line) {
|
||||
FormatFileLocation(file, line);
|
||||
::std::cerr << " ERROR: Condition " << condition << " failed. ";
|
||||
}
|
||||
~GTestCheckProvider() {
|
||||
::std::cerr << ::std::endl;
|
||||
abort();
|
||||
}
|
||||
void FormatFileLocation(const char* file, int line) {
|
||||
if (file == NULL)
|
||||
file = "unknown file";
|
||||
if (line < 0) {
|
||||
::std::cerr << file << ":";
|
||||
} else {
|
||||
#if _MSC_VER
|
||||
::std::cerr << file << "(" << line << "):";
|
||||
#else
|
||||
::std::cerr << file << ":" << line << ":";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
::std::ostream& GetStream() { return ::std::cerr; }
|
||||
};
|
||||
#define GTEST_CHECK_(condition) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (condition) \
|
||||
if (::testing::internal::IsTrue(condition)) \
|
||||
; \
|
||||
else \
|
||||
::testing::internal::GTestCheckProvider(\
|
||||
#condition, __FILE__, __LINE__).GetStream()
|
||||
GTEST_LOG_(FATAL) << "Condition " #condition " failed. "
|
||||
|
||||
// Macro for referencing flags.
|
||||
#define GTEST_FLAG(name) FLAGS_gtest_##name
|
||||
|
@ -80,19 +80,6 @@ class String {
|
||||
public:
|
||||
// Static utility methods
|
||||
|
||||
// Returns the input if it's not NULL, otherwise returns "(null)".
|
||||
// This function serves two purposes:
|
||||
//
|
||||
// 1. ShowCString(NULL) has type 'const char *', instead of the
|
||||
// type of NULL (which is int).
|
||||
//
|
||||
// 2. In MSVC, streaming a null char pointer to StrStream generates
|
||||
// an access violation, so we need to convert NULL to "(null)"
|
||||
// before streaming it.
|
||||
static inline const char* ShowCString(const char* c_str) {
|
||||
return c_str ? c_str : "(null)";
|
||||
}
|
||||
|
||||
// Returns the input enclosed in double quotes if it's not NULL;
|
||||
// otherwise returns "(null)". For example, "\"Hello\"" is returned
|
||||
// for input "Hello".
|
||||
@ -111,7 +98,7 @@ class String {
|
||||
// memory using malloc().
|
||||
static const char* CloneCString(const char* c_str);
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
// Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
|
||||
// able to pass strings to Win32 APIs on CE we need to convert them
|
||||
// to 'Unicode', UTF-16.
|
||||
@ -200,22 +187,29 @@ class String {
|
||||
// C'tors
|
||||
|
||||
// The default c'tor constructs a NULL string.
|
||||
String() : c_str_(NULL) {}
|
||||
String() : c_str_(NULL), length_(0) {}
|
||||
|
||||
// Constructs a String by cloning a 0-terminated C string.
|
||||
String(const char* c_str) : c_str_(NULL) { // NOLINT
|
||||
*this = c_str;
|
||||
String(const char* c_str) { // NOLINT
|
||||
if (c_str == NULL) {
|
||||
c_str_ = NULL;
|
||||
length_ = 0;
|
||||
} else {
|
||||
ConstructNonNull(c_str, strlen(c_str));
|
||||
}
|
||||
}
|
||||
|
||||
// Constructs a String by copying a given number of chars from a
|
||||
// buffer. E.g. String("hello", 3) will create the string "hel".
|
||||
String(const char* buffer, size_t len);
|
||||
// buffer. E.g. String("hello", 3) creates the string "hel",
|
||||
// String("a\0bcd", 4) creates "a\0bc", String(NULL, 0) creates "",
|
||||
// and String(NULL, 1) results in access violation.
|
||||
String(const char* buffer, size_t length) {
|
||||
ConstructNonNull(buffer, length);
|
||||
}
|
||||
|
||||
// The copy c'tor creates a new copy of the string. The two
|
||||
// String objects do not share content.
|
||||
String(const String& str) : c_str_(NULL) {
|
||||
*this = str;
|
||||
}
|
||||
String(const String& str) : c_str_(NULL), length_(0) { *this = str; }
|
||||
|
||||
// D'tor. String is intended to be a final class, so the d'tor
|
||||
// doesn't need to be virtual.
|
||||
@ -228,21 +222,23 @@ class String {
|
||||
// character to a String will result in the prefix up to the first
|
||||
// NUL character.
|
||||
#if GTEST_HAS_STD_STRING
|
||||
String(const ::std::string& str) : c_str_(NULL) { *this = str.c_str(); }
|
||||
String(const ::std::string& str) {
|
||||
ConstructNonNull(str.c_str(), str.length());
|
||||
}
|
||||
|
||||
operator ::std::string() const { return ::std::string(c_str_); }
|
||||
operator ::std::string() const { return ::std::string(c_str(), length()); }
|
||||
#endif // GTEST_HAS_STD_STRING
|
||||
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
String(const ::string& str) : c_str_(NULL) { *this = str.c_str(); }
|
||||
String(const ::string& str) {
|
||||
ConstructNonNull(str.c_str(), str.length());
|
||||
}
|
||||
|
||||
operator ::string() const { return ::string(c_str_); }
|
||||
operator ::string() const { return ::string(c_str(), length()); }
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
// Returns true iff this is an empty string (i.e. "").
|
||||
bool empty() const {
|
||||
return (c_str_ != NULL) && (*c_str_ == '\0');
|
||||
}
|
||||
bool empty() const { return (c_str() != NULL) && (length() == 0); }
|
||||
|
||||
// Compares this with another String.
|
||||
// Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0
|
||||
@ -251,19 +247,15 @@ class String {
|
||||
|
||||
// Returns true iff this String equals the given C string. A NULL
|
||||
// string and a non-NULL string are considered not equal.
|
||||
bool operator==(const char* c_str) const {
|
||||
return CStringEquals(c_str_, c_str);
|
||||
}
|
||||
bool operator==(const char* c_str) const { return Compare(c_str) == 0; }
|
||||
|
||||
// Returns true iff this String is less than the given C string. A NULL
|
||||
// string is considered less than "".
|
||||
// Returns true iff this String is less than the given String. A
|
||||
// NULL string is considered less than "".
|
||||
bool operator<(const String& rhs) const { return Compare(rhs) < 0; }
|
||||
|
||||
// Returns true iff this String doesn't equal the given C string. A NULL
|
||||
// string and a non-NULL string are considered not equal.
|
||||
bool operator!=(const char* c_str) const {
|
||||
return !CStringEquals(c_str_, c_str);
|
||||
}
|
||||
bool operator!=(const char* c_str) const { return !(*this == c_str); }
|
||||
|
||||
// Returns true iff this String ends with the given suffix. *Any*
|
||||
// String is considered to end with a NULL or empty suffix.
|
||||
@ -273,45 +265,66 @@ class String {
|
||||
// case. Any String is considered to end with a NULL or empty suffix.
|
||||
bool EndsWithCaseInsensitive(const char* suffix) const;
|
||||
|
||||
// Returns the length of the encapsulated string, or -1 if the
|
||||
// Returns the length of the encapsulated string, or 0 if the
|
||||
// string is NULL.
|
||||
int GetLength() const {
|
||||
return c_str_ ? static_cast<int>(strlen(c_str_)) : -1;
|
||||
}
|
||||
size_t length() const { return length_; }
|
||||
|
||||
// Gets the 0-terminated C string this String object represents.
|
||||
// The String object still owns the string. Therefore the caller
|
||||
// should NOT delete the return value.
|
||||
const char* c_str() const { return c_str_; }
|
||||
|
||||
// Sets the 0-terminated C string this String object represents.
|
||||
// The old string in this object is deleted, and this object will
|
||||
// own a clone of the input string. This function copies only up to
|
||||
// length bytes (plus a terminating null byte), or until the first
|
||||
// null byte, whichever comes first.
|
||||
//
|
||||
// This function works even when the c_str parameter has the same
|
||||
// value as that of the c_str_ field.
|
||||
void Set(const char* c_str, size_t length);
|
||||
|
||||
// Assigns a C string to this object. Self-assignment works.
|
||||
const String& operator=(const char* c_str);
|
||||
const String& operator=(const char* c_str) { return *this = String(c_str); }
|
||||
|
||||
// Assigns a String object to this object. Self-assignment works.
|
||||
const String& operator=(const String &rhs) {
|
||||
*this = rhs.c_str_;
|
||||
const String& operator=(const String& rhs) {
|
||||
if (this != &rhs) {
|
||||
delete[] c_str_;
|
||||
if (rhs.c_str() == NULL) {
|
||||
c_str_ = NULL;
|
||||
length_ = 0;
|
||||
} else {
|
||||
ConstructNonNull(rhs.c_str(), rhs.length());
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* c_str_;
|
||||
};
|
||||
// Constructs a non-NULL String from the given content. This
|
||||
// function can only be called when data_ has not been allocated.
|
||||
// ConstructNonNull(NULL, 0) results in an empty string ("").
|
||||
// ConstructNonNull(NULL, non_zero) is undefined behavior.
|
||||
void ConstructNonNull(const char* buffer, size_t length) {
|
||||
char* const str = new char[length + 1];
|
||||
memcpy(str, buffer, length);
|
||||
str[length] = '\0';
|
||||
c_str_ = str;
|
||||
length_ = length;
|
||||
}
|
||||
|
||||
// Streams a String to an ostream.
|
||||
inline ::std::ostream& operator <<(::std::ostream& os, const String& str) {
|
||||
// We call String::ShowCString() to convert NULL to "(null)".
|
||||
// Otherwise we'll get an access violation on Windows.
|
||||
return os << String::ShowCString(str.c_str());
|
||||
const char* c_str_;
|
||||
size_t length_;
|
||||
}; // class String
|
||||
|
||||
// Streams a String to an ostream. Each '\0' character in the String
|
||||
// is replaced with "\\0".
|
||||
inline ::std::ostream& operator<<(::std::ostream& os, const String& str) {
|
||||
if (str.c_str() == NULL) {
|
||||
os << "(null)";
|
||||
} else {
|
||||
const char* const c_str = str.c_str();
|
||||
for (size_t i = 0; i != str.length(); i++) {
|
||||
if (c_str[i] == '\0') {
|
||||
os << "\\0";
|
||||
} else {
|
||||
os << c_str[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
// Gets the content of the StrStream's buffer as a String. Each '\0'
|
||||
|
966
utils/unittest/googletest/include/gtest/internal/gtest-tuple.h
Normal file
966
utils/unittest/googletest/include/gtest/internal/gtest-tuple.h
Normal file
@ -0,0 +1,966 @@
|
||||
// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
|
||||
|
||||
// Copyright 2009 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Implements a subset of TR1 tuple needed by Google Test and Google Mock.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
|
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
|
||||
|
||||
#include <utility> // For ::std::pair.
|
||||
|
||||
// The compiler used in Symbian has a bug that prevents us from declaring the
|
||||
// tuple template as a friend (it complains that tuple is redefined). This
|
||||
// hack bypasses the bug by declaring the members that should otherwise be
|
||||
// private as public.
|
||||
#if defined(__SYMBIAN32__)
|
||||
#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
|
||||
#else
|
||||
#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
|
||||
template <GTEST_10_TYPENAMES_(U)> friend class tuple; \
|
||||
private:
|
||||
#endif
|
||||
|
||||
// GTEST_n_TUPLE_(T) is the type of an n-tuple.
|
||||
#define GTEST_0_TUPLE_(T) tuple<>
|
||||
#define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \
|
||||
void, void, void>
|
||||
#define GTEST_2_TUPLE_(T) tuple<T##0, T##1, void, void, void, void, void, \
|
||||
void, void, void>
|
||||
#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2, void, void, void, void, \
|
||||
void, void, void>
|
||||
#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, void, void, void, \
|
||||
void, void, void>
|
||||
#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, void, void, \
|
||||
void, void, void>
|
||||
#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, void, \
|
||||
void, void, void>
|
||||
#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
|
||||
void, void, void>
|
||||
#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
|
||||
T##7, void, void>
|
||||
#define GTEST_9_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
|
||||
T##7, T##8, void>
|
||||
#define GTEST_10_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
|
||||
T##7, T##8, T##9>
|
||||
|
||||
// GTEST_n_TYPENAMES_(T) declares a list of n typenames.
|
||||
#define GTEST_0_TYPENAMES_(T)
|
||||
#define GTEST_1_TYPENAMES_(T) typename T##0
|
||||
#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1
|
||||
#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2
|
||||
#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
|
||||
typename T##3
|
||||
#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
|
||||
typename T##3, typename T##4
|
||||
#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
|
||||
typename T##3, typename T##4, typename T##5
|
||||
#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
|
||||
typename T##3, typename T##4, typename T##5, typename T##6
|
||||
#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
|
||||
typename T##3, typename T##4, typename T##5, typename T##6, typename T##7
|
||||
#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
|
||||
typename T##3, typename T##4, typename T##5, typename T##6, \
|
||||
typename T##7, typename T##8
|
||||
#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
|
||||
typename T##3, typename T##4, typename T##5, typename T##6, \
|
||||
typename T##7, typename T##8, typename T##9
|
||||
|
||||
// In theory, defining stuff in the ::std namespace is undefined
|
||||
// behavior. We can do this as we are playing the role of a standard
|
||||
// library vendor.
|
||||
namespace std {
|
||||
namespace tr1 {
|
||||
|
||||
template <typename T0 = void, typename T1 = void, typename T2 = void,
|
||||
typename T3 = void, typename T4 = void, typename T5 = void,
|
||||
typename T6 = void, typename T7 = void, typename T8 = void,
|
||||
typename T9 = void>
|
||||
class tuple;
|
||||
|
||||
// Anything in namespace gtest_internal is Google Test's INTERNAL
|
||||
// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
|
||||
namespace gtest_internal {
|
||||
|
||||
// ByRef<T>::type is T if T is a reference; otherwise it's const T&.
|
||||
template <typename T>
|
||||
struct ByRef { typedef const T& type; }; // NOLINT
|
||||
template <typename T>
|
||||
struct ByRef<T&> { typedef T& type; }; // NOLINT
|
||||
|
||||
// A handy wrapper for ByRef.
|
||||
#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
|
||||
|
||||
// AddRef<T>::type is T if T is a reference; otherwise it's T&. This
|
||||
// is the same as tr1::add_reference<T>::type.
|
||||
template <typename T>
|
||||
struct AddRef { typedef T& type; }; // NOLINT
|
||||
template <typename T>
|
||||
struct AddRef<T&> { typedef T& type; }; // NOLINT
|
||||
|
||||
// A handy wrapper for AddRef.
|
||||
#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
|
||||
|
||||
// A helper for implementing get<k>().
|
||||
template <int k> class Get;
|
||||
|
||||
// A helper for implementing tuple_element<k, T>. kIndexValid is true
|
||||
// iff k < the number of fields in tuple type T.
|
||||
template <bool kIndexValid, int kIndex, class Tuple>
|
||||
struct TupleElement;
|
||||
|
||||
template <GTEST_10_TYPENAMES_(T)>
|
||||
struct TupleElement<true, 0, GTEST_10_TUPLE_(T)> { typedef T0 type; };
|
||||
|
||||
template <GTEST_10_TYPENAMES_(T)>
|
||||
struct TupleElement<true, 1, GTEST_10_TUPLE_(T)> { typedef T1 type; };
|
||||
|
||||
template <GTEST_10_TYPENAMES_(T)>
|
||||
struct TupleElement<true, 2, GTEST_10_TUPLE_(T)> { typedef T2 type; };
|
||||
|
||||
template <GTEST_10_TYPENAMES_(T)>
|
||||
struct TupleElement<true, 3, GTEST_10_TUPLE_(T)> { typedef T3 type; };
|
||||
|
||||
template <GTEST_10_TYPENAMES_(T)>
|
||||
struct TupleElement<true, 4, GTEST_10_TUPLE_(T)> { typedef T4 type; };
|
||||
|
||||
template <GTEST_10_TYPENAMES_(T)>
|
||||
struct TupleElement<true, 5, GTEST_10_TUPLE_(T)> { typedef T5 type; };
|
||||
|
||||
template <GTEST_10_TYPENAMES_(T)>
|
||||
struct TupleElement<true, 6, GTEST_10_TUPLE_(T)> { typedef T6 type; };
|
||||
|
||||
template <GTEST_10_TYPENAMES_(T)>
|
||||
struct TupleElement<true, 7, GTEST_10_TUPLE_(T)> { typedef T7 type; };
|
||||
|
||||
template <GTEST_10_TYPENAMES_(T)>
|
||||
struct TupleElement<true, 8, GTEST_10_TUPLE_(T)> { typedef T8 type; };
|
||||
|
||||
template <GTEST_10_TYPENAMES_(T)>
|
||||
struct TupleElement<true, 9, GTEST_10_TUPLE_(T)> { typedef T9 type; };
|
||||
|
||||
} // namespace gtest_internal
|
||||
|
||||
template <>
|
||||
class tuple<> {
|
||||
public:
|
||||
tuple() {}
|
||||
tuple(const tuple& /* t */) {}
|
||||
tuple& operator=(const tuple& /* t */) { return *this; }
|
||||
};
|
||||
|
||||
template <GTEST_1_TYPENAMES_(T)>
|
||||
class GTEST_1_TUPLE_(T) {
|
||||
public:
|
||||
template <int k> friend class gtest_internal::Get;
|
||||
|
||||
tuple() {}
|
||||
|
||||
explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {}
|
||||
|
||||
tuple(const tuple& t) : f0_(t.f0_) {}
|
||||
|
||||
template <GTEST_1_TYPENAMES_(U)>
|
||||
tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {}
|
||||
|
||||
tuple& operator=(const tuple& t) { return CopyFrom(t); }
|
||||
|
||||
template <GTEST_1_TYPENAMES_(U)>
|
||||
tuple& operator=(const GTEST_1_TUPLE_(U)& t) {
|
||||
return CopyFrom(t);
|
||||
}
|
||||
|
||||
GTEST_DECLARE_TUPLE_AS_FRIEND_
|
||||
|
||||
template <GTEST_1_TYPENAMES_(U)>
|
||||
tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) {
|
||||
f0_ = t.f0_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T0 f0_;
|
||||
};
|
||||
|
||||
template <GTEST_2_TYPENAMES_(T)>
|
||||
class GTEST_2_TUPLE_(T) {
|
||||
public:
|
||||
template <int k> friend class gtest_internal::Get;
|
||||
|
||||
tuple() {}
|
||||
|
||||
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0),
|
||||
f1_(f1) {}
|
||||
|
||||
tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {}
|
||||
|
||||
template <GTEST_2_TYPENAMES_(U)>
|
||||
tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {}
|
||||
template <typename U0, typename U1>
|
||||
tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
|
||||
|
||||
tuple& operator=(const tuple& t) { return CopyFrom(t); }
|
||||
|
||||
template <GTEST_2_TYPENAMES_(U)>
|
||||
tuple& operator=(const GTEST_2_TUPLE_(U)& t) {
|
||||
return CopyFrom(t);
|
||||
}
|
||||
template <typename U0, typename U1>
|
||||
tuple& operator=(const ::std::pair<U0, U1>& p) {
|
||||
f0_ = p.first;
|
||||
f1_ = p.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
GTEST_DECLARE_TUPLE_AS_FRIEND_
|
||||
|
||||
template <GTEST_2_TYPENAMES_(U)>
|
||||
tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) {
|
||||
f0_ = t.f0_;
|
||||
f1_ = t.f1_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T0 f0_;
|
||||
T1 f1_;
|
||||
};
|
||||
|
||||
template <GTEST_3_TYPENAMES_(T)>
|
||||
class GTEST_3_TUPLE_(T) {
|
||||
public:
|
||||
template <int k> friend class gtest_internal::Get;
|
||||
|
||||
tuple() {}
|
||||
|
||||
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
|
||||
GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {}
|
||||
|
||||
tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
|
||||
|
||||
template <GTEST_3_TYPENAMES_(U)>
|
||||
tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
|
||||
|
||||
tuple& operator=(const tuple& t) { return CopyFrom(t); }
|
||||
|
||||
template <GTEST_3_TYPENAMES_(U)>
|
||||
tuple& operator=(const GTEST_3_TUPLE_(U)& t) {
|
||||
return CopyFrom(t);
|
||||
}
|
||||
|
||||
GTEST_DECLARE_TUPLE_AS_FRIEND_
|
||||
|
||||
template <GTEST_3_TYPENAMES_(U)>
|
||||
tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) {
|
||||
f0_ = t.f0_;
|
||||
f1_ = t.f1_;
|
||||
f2_ = t.f2_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T0 f0_;
|
||||
T1 f1_;
|
||||
T2 f2_;
|
||||
};
|
||||
|
||||
template <GTEST_4_TYPENAMES_(T)>
|
||||
class GTEST_4_TUPLE_(T) {
|
||||
public:
|
||||
template <int k> friend class gtest_internal::Get;
|
||||
|
||||
tuple() {}
|
||||
|
||||
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
|
||||
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2),
|
||||
f3_(f3) {}
|
||||
|
||||
tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {}
|
||||
|
||||
template <GTEST_4_TYPENAMES_(U)>
|
||||
tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
|
||||
f3_(t.f3_) {}
|
||||
|
||||
tuple& operator=(const tuple& t) { return CopyFrom(t); }
|
||||
|
||||
template <GTEST_4_TYPENAMES_(U)>
|
||||
tuple& operator=(const GTEST_4_TUPLE_(U)& t) {
|
||||
return CopyFrom(t);
|
||||
}
|
||||
|
||||
GTEST_DECLARE_TUPLE_AS_FRIEND_
|
||||
|
||||
template <GTEST_4_TYPENAMES_(U)>
|
||||
tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) {
|
||||
f0_ = t.f0_;
|
||||
f1_ = t.f1_;
|
||||
f2_ = t.f2_;
|
||||
f3_ = t.f3_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T0 f0_;
|
||||
T1 f1_;
|
||||
T2 f2_;
|
||||
T3 f3_;
|
||||
};
|
||||
|
||||
template <GTEST_5_TYPENAMES_(T)>
|
||||
class GTEST_5_TUPLE_(T) {
|
||||
public:
|
||||
template <int k> friend class gtest_internal::Get;
|
||||
|
||||
tuple() {}
|
||||
|
||||
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
|
||||
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3,
|
||||
GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {}
|
||||
|
||||
tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
|
||||
f4_(t.f4_) {}
|
||||
|
||||
template <GTEST_5_TYPENAMES_(U)>
|
||||
tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
|
||||
f3_(t.f3_), f4_(t.f4_) {}
|
||||
|
||||
tuple& operator=(const tuple& t) { return CopyFrom(t); }
|
||||
|
||||
template <GTEST_5_TYPENAMES_(U)>
|
||||
tuple& operator=(const GTEST_5_TUPLE_(U)& t) {
|
||||
return CopyFrom(t);
|
||||
}
|
||||
|
||||
GTEST_DECLARE_TUPLE_AS_FRIEND_
|
||||
|
||||
template <GTEST_5_TYPENAMES_(U)>
|
||||
tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) {
|
||||
f0_ = t.f0_;
|
||||
f1_ = t.f1_;
|
||||
f2_ = t.f2_;
|
||||
f3_ = t.f3_;
|
||||
f4_ = t.f4_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T0 f0_;
|
||||
T1 f1_;
|
||||
T2 f2_;
|
||||
T3 f3_;
|
||||
T4 f4_;
|
||||
};
|
||||
|
||||
template <GTEST_6_TYPENAMES_(T)>
|
||||
class GTEST_6_TUPLE_(T) {
|
||||
public:
|
||||
template <int k> friend class gtest_internal::Get;
|
||||
|
||||
tuple() {}
|
||||
|
||||
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
|
||||
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
|
||||
GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
|
||||
f5_(f5) {}
|
||||
|
||||
tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
|
||||
f4_(t.f4_), f5_(t.f5_) {}
|
||||
|
||||
template <GTEST_6_TYPENAMES_(U)>
|
||||
tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
|
||||
f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {}
|
||||
|
||||
tuple& operator=(const tuple& t) { return CopyFrom(t); }
|
||||
|
||||
template <GTEST_6_TYPENAMES_(U)>
|
||||
tuple& operator=(const GTEST_6_TUPLE_(U)& t) {
|
||||
return CopyFrom(t);
|
||||
}
|
||||
|
||||
GTEST_DECLARE_TUPLE_AS_FRIEND_
|
||||
|
||||
template <GTEST_6_TYPENAMES_(U)>
|
||||
tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) {
|
||||
f0_ = t.f0_;
|
||||
f1_ = t.f1_;
|
||||
f2_ = t.f2_;
|
||||
f3_ = t.f3_;
|
||||
f4_ = t.f4_;
|
||||
f5_ = t.f5_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T0 f0_;
|
||||
T1 f1_;
|
||||
T2 f2_;
|
||||
T3 f3_;
|
||||
T4 f4_;
|
||||
T5 f5_;
|
||||
};
|
||||
|
||||
template <GTEST_7_TYPENAMES_(T)>
|
||||
class GTEST_7_TUPLE_(T) {
|
||||
public:
|
||||
template <int k> friend class gtest_internal::Get;
|
||||
|
||||
tuple() {}
|
||||
|
||||
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
|
||||
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
|
||||
GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2),
|
||||
f3_(f3), f4_(f4), f5_(f5), f6_(f6) {}
|
||||
|
||||
tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
|
||||
f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
|
||||
|
||||
template <GTEST_7_TYPENAMES_(U)>
|
||||
tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
|
||||
f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
|
||||
|
||||
tuple& operator=(const tuple& t) { return CopyFrom(t); }
|
||||
|
||||
template <GTEST_7_TYPENAMES_(U)>
|
||||
tuple& operator=(const GTEST_7_TUPLE_(U)& t) {
|
||||
return CopyFrom(t);
|
||||
}
|
||||
|
||||
GTEST_DECLARE_TUPLE_AS_FRIEND_
|
||||
|
||||
template <GTEST_7_TYPENAMES_(U)>
|
||||
tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) {
|
||||
f0_ = t.f0_;
|
||||
f1_ = t.f1_;
|
||||
f2_ = t.f2_;
|
||||
f3_ = t.f3_;
|
||||
f4_ = t.f4_;
|
||||
f5_ = t.f5_;
|
||||
f6_ = t.f6_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T0 f0_;
|
||||
T1 f1_;
|
||||
T2 f2_;
|
||||
T3 f3_;
|
||||
T4 f4_;
|
||||
T5 f5_;
|
||||
T6 f6_;
|
||||
};
|
||||
|
||||
template <GTEST_8_TYPENAMES_(T)>
|
||||
class GTEST_8_TUPLE_(T) {
|
||||
public:
|
||||
template <int k> friend class gtest_internal::Get;
|
||||
|
||||
tuple() {}
|
||||
|
||||
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
|
||||
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
|
||||
GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6,
|
||||
GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
|
||||
f5_(f5), f6_(f6), f7_(f7) {}
|
||||
|
||||
tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
|
||||
f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
|
||||
|
||||
template <GTEST_8_TYPENAMES_(U)>
|
||||
tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
|
||||
f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
|
||||
|
||||
tuple& operator=(const tuple& t) { return CopyFrom(t); }
|
||||
|
||||
template <GTEST_8_TYPENAMES_(U)>
|
||||
tuple& operator=(const GTEST_8_TUPLE_(U)& t) {
|
||||
return CopyFrom(t);
|
||||
}
|
||||
|
||||
GTEST_DECLARE_TUPLE_AS_FRIEND_
|
||||
|
||||
template <GTEST_8_TYPENAMES_(U)>
|
||||
tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) {
|
||||
f0_ = t.f0_;
|
||||
f1_ = t.f1_;
|
||||
f2_ = t.f2_;
|
||||
f3_ = t.f3_;
|
||||
f4_ = t.f4_;
|
||||
f5_ = t.f5_;
|
||||
f6_ = t.f6_;
|
||||
f7_ = t.f7_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T0 f0_;
|
||||
T1 f1_;
|
||||
T2 f2_;
|
||||
T3 f3_;
|
||||
T4 f4_;
|
||||
T5 f5_;
|
||||
T6 f6_;
|
||||
T7 f7_;
|
||||
};
|
||||
|
||||
template <GTEST_9_TYPENAMES_(T)>
|
||||
class GTEST_9_TUPLE_(T) {
|
||||
public:
|
||||
template <int k> friend class gtest_internal::Get;
|
||||
|
||||
tuple() {}
|
||||
|
||||
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
|
||||
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
|
||||
GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
|
||||
GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
|
||||
f5_(f5), f6_(f6), f7_(f7), f8_(f8) {}
|
||||
|
||||
tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
|
||||
f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
|
||||
|
||||
template <GTEST_9_TYPENAMES_(U)>
|
||||
tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
|
||||
f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
|
||||
|
||||
tuple& operator=(const tuple& t) { return CopyFrom(t); }
|
||||
|
||||
template <GTEST_9_TYPENAMES_(U)>
|
||||
tuple& operator=(const GTEST_9_TUPLE_(U)& t) {
|
||||
return CopyFrom(t);
|
||||
}
|
||||
|
||||
GTEST_DECLARE_TUPLE_AS_FRIEND_
|
||||
|
||||
template <GTEST_9_TYPENAMES_(U)>
|
||||
tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) {
|
||||
f0_ = t.f0_;
|
||||
f1_ = t.f1_;
|
||||
f2_ = t.f2_;
|
||||
f3_ = t.f3_;
|
||||
f4_ = t.f4_;
|
||||
f5_ = t.f5_;
|
||||
f6_ = t.f6_;
|
||||
f7_ = t.f7_;
|
||||
f8_ = t.f8_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T0 f0_;
|
||||
T1 f1_;
|
||||
T2 f2_;
|
||||
T3 f3_;
|
||||
T4 f4_;
|
||||
T5 f5_;
|
||||
T6 f6_;
|
||||
T7 f7_;
|
||||
T8 f8_;
|
||||
};
|
||||
|
||||
template <GTEST_10_TYPENAMES_(T)>
|
||||
class tuple {
|
||||
public:
|
||||
template <int k> friend class gtest_internal::Get;
|
||||
|
||||
tuple() {}
|
||||
|
||||
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
|
||||
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
|
||||
GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
|
||||
GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2),
|
||||
f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {}
|
||||
|
||||
tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
|
||||
f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {}
|
||||
|
||||
template <GTEST_10_TYPENAMES_(U)>
|
||||
tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
|
||||
f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_),
|
||||
f9_(t.f9_) {}
|
||||
|
||||
tuple& operator=(const tuple& t) { return CopyFrom(t); }
|
||||
|
||||
template <GTEST_10_TYPENAMES_(U)>
|
||||
tuple& operator=(const GTEST_10_TUPLE_(U)& t) {
|
||||
return CopyFrom(t);
|
||||
}
|
||||
|
||||
GTEST_DECLARE_TUPLE_AS_FRIEND_
|
||||
|
||||
template <GTEST_10_TYPENAMES_(U)>
|
||||
tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) {
|
||||
f0_ = t.f0_;
|
||||
f1_ = t.f1_;
|
||||
f2_ = t.f2_;
|
||||
f3_ = t.f3_;
|
||||
f4_ = t.f4_;
|
||||
f5_ = t.f5_;
|
||||
f6_ = t.f6_;
|
||||
f7_ = t.f7_;
|
||||
f8_ = t.f8_;
|
||||
f9_ = t.f9_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T0 f0_;
|
||||
T1 f1_;
|
||||
T2 f2_;
|
||||
T3 f3_;
|
||||
T4 f4_;
|
||||
T5 f5_;
|
||||
T6 f6_;
|
||||
T7 f7_;
|
||||
T8 f8_;
|
||||
T9 f9_;
|
||||
};
|
||||
|
||||
// 6.1.3.2 Tuple creation functions.
|
||||
|
||||
// Known limitations: we don't support passing an
|
||||
// std::tr1::reference_wrapper<T> to make_tuple(). And we don't
|
||||
// implement tie().
|
||||
|
||||
inline tuple<> make_tuple() { return tuple<>(); }
|
||||
|
||||
template <GTEST_1_TYPENAMES_(T)>
|
||||
inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) {
|
||||
return GTEST_1_TUPLE_(T)(f0);
|
||||
}
|
||||
|
||||
template <GTEST_2_TYPENAMES_(T)>
|
||||
inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) {
|
||||
return GTEST_2_TUPLE_(T)(f0, f1);
|
||||
}
|
||||
|
||||
template <GTEST_3_TYPENAMES_(T)>
|
||||
inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) {
|
||||
return GTEST_3_TUPLE_(T)(f0, f1, f2);
|
||||
}
|
||||
|
||||
template <GTEST_4_TYPENAMES_(T)>
|
||||
inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
|
||||
const T3& f3) {
|
||||
return GTEST_4_TUPLE_(T)(f0, f1, f2, f3);
|
||||
}
|
||||
|
||||
template <GTEST_5_TYPENAMES_(T)>
|
||||
inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
|
||||
const T3& f3, const T4& f4) {
|
||||
return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4);
|
||||
}
|
||||
|
||||
template <GTEST_6_TYPENAMES_(T)>
|
||||
inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
|
||||
const T3& f3, const T4& f4, const T5& f5) {
|
||||
return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5);
|
||||
}
|
||||
|
||||
template <GTEST_7_TYPENAMES_(T)>
|
||||
inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
|
||||
const T3& f3, const T4& f4, const T5& f5, const T6& f6) {
|
||||
return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6);
|
||||
}
|
||||
|
||||
template <GTEST_8_TYPENAMES_(T)>
|
||||
inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
|
||||
const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) {
|
||||
return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7);
|
||||
}
|
||||
|
||||
template <GTEST_9_TYPENAMES_(T)>
|
||||
inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
|
||||
const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
|
||||
const T8& f8) {
|
||||
return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8);
|
||||
}
|
||||
|
||||
template <GTEST_10_TYPENAMES_(T)>
|
||||
inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
|
||||
const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
|
||||
const T8& f8, const T9& f9) {
|
||||
return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9);
|
||||
}
|
||||
|
||||
// 6.1.3.3 Tuple helper classes.
|
||||
|
||||
template <typename Tuple> struct tuple_size;
|
||||
|
||||
template <GTEST_0_TYPENAMES_(T)>
|
||||
struct tuple_size<GTEST_0_TUPLE_(T)> { static const int value = 0; };
|
||||
|
||||
template <GTEST_1_TYPENAMES_(T)>
|
||||
struct tuple_size<GTEST_1_TUPLE_(T)> { static const int value = 1; };
|
||||
|
||||
template <GTEST_2_TYPENAMES_(T)>
|
||||
struct tuple_size<GTEST_2_TUPLE_(T)> { static const int value = 2; };
|
||||
|
||||
template <GTEST_3_TYPENAMES_(T)>
|
||||
struct tuple_size<GTEST_3_TUPLE_(T)> { static const int value = 3; };
|
||||
|
||||
template <GTEST_4_TYPENAMES_(T)>
|
||||
struct tuple_size<GTEST_4_TUPLE_(T)> { static const int value = 4; };
|
||||
|
||||
template <GTEST_5_TYPENAMES_(T)>
|
||||
struct tuple_size<GTEST_5_TUPLE_(T)> { static const int value = 5; };
|
||||
|
||||
template <GTEST_6_TYPENAMES_(T)>
|
||||
struct tuple_size<GTEST_6_TUPLE_(T)> { static const int value = 6; };
|
||||
|
||||
template <GTEST_7_TYPENAMES_(T)>
|
||||
struct tuple_size<GTEST_7_TUPLE_(T)> { static const int value = 7; };
|
||||
|
||||
template <GTEST_8_TYPENAMES_(T)>
|
||||
struct tuple_size<GTEST_8_TUPLE_(T)> { static const int value = 8; };
|
||||
|
||||
template <GTEST_9_TYPENAMES_(T)>
|
||||
struct tuple_size<GTEST_9_TUPLE_(T)> { static const int value = 9; };
|
||||
|
||||
template <GTEST_10_TYPENAMES_(T)>
|
||||
struct tuple_size<GTEST_10_TUPLE_(T)> { static const int value = 10; };
|
||||
|
||||
template <int k, class Tuple>
|
||||
struct tuple_element {
|
||||
typedef typename gtest_internal::TupleElement<
|
||||
k < (tuple_size<Tuple>::value), k, Tuple>::type type;
|
||||
};
|
||||
|
||||
#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
|
||||
|
||||
// 6.1.3.4 Element access.
|
||||
|
||||
namespace gtest_internal {
|
||||
|
||||
template <>
|
||||
class Get<0> {
|
||||
public:
|
||||
template <class Tuple>
|
||||
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
|
||||
Field(Tuple& t) { return t.f0_; } // NOLINT
|
||||
|
||||
template <class Tuple>
|
||||
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
|
||||
ConstField(const Tuple& t) { return t.f0_; }
|
||||
};
|
||||
|
||||
template <>
|
||||
class Get<1> {
|
||||
public:
|
||||
template <class Tuple>
|
||||
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
|
||||
Field(Tuple& t) { return t.f1_; } // NOLINT
|
||||
|
||||
template <class Tuple>
|
||||
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
|
||||
ConstField(const Tuple& t) { return t.f1_; }
|
||||
};
|
||||
|
||||
template <>
|
||||
class Get<2> {
|
||||
public:
|
||||
template <class Tuple>
|
||||
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
|
||||
Field(Tuple& t) { return t.f2_; } // NOLINT
|
||||
|
||||
template <class Tuple>
|
||||
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
|
||||
ConstField(const Tuple& t) { return t.f2_; }
|
||||
};
|
||||
|
||||
template <>
|
||||
class Get<3> {
|
||||
public:
|
||||
template <class Tuple>
|
||||
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
|
||||
Field(Tuple& t) { return t.f3_; } // NOLINT
|
||||
|
||||
template <class Tuple>
|
||||
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
|
||||
ConstField(const Tuple& t) { return t.f3_; }
|
||||
};
|
||||
|
||||
template <>
|
||||
class Get<4> {
|
||||
public:
|
||||
template <class Tuple>
|
||||
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
|
||||
Field(Tuple& t) { return t.f4_; } // NOLINT
|
||||
|
||||
template <class Tuple>
|
||||
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
|
||||
ConstField(const Tuple& t) { return t.f4_; }
|
||||
};
|
||||
|
||||
template <>
|
||||
class Get<5> {
|
||||
public:
|
||||
template <class Tuple>
|
||||
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
|
||||
Field(Tuple& t) { return t.f5_; } // NOLINT
|
||||
|
||||
template <class Tuple>
|
||||
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
|
||||
ConstField(const Tuple& t) { return t.f5_; }
|
||||
};
|
||||
|
||||
template <>
|
||||
class Get<6> {
|
||||
public:
|
||||
template <class Tuple>
|
||||
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
|
||||
Field(Tuple& t) { return t.f6_; } // NOLINT
|
||||
|
||||
template <class Tuple>
|
||||
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
|
||||
ConstField(const Tuple& t) { return t.f6_; }
|
||||
};
|
||||
|
||||
template <>
|
||||
class Get<7> {
|
||||
public:
|
||||
template <class Tuple>
|
||||
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
|
||||
Field(Tuple& t) { return t.f7_; } // NOLINT
|
||||
|
||||
template <class Tuple>
|
||||
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
|
||||
ConstField(const Tuple& t) { return t.f7_; }
|
||||
};
|
||||
|
||||
template <>
|
||||
class Get<8> {
|
||||
public:
|
||||
template <class Tuple>
|
||||
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
|
||||
Field(Tuple& t) { return t.f8_; } // NOLINT
|
||||
|
||||
template <class Tuple>
|
||||
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
|
||||
ConstField(const Tuple& t) { return t.f8_; }
|
||||
};
|
||||
|
||||
template <>
|
||||
class Get<9> {
|
||||
public:
|
||||
template <class Tuple>
|
||||
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
|
||||
Field(Tuple& t) { return t.f9_; } // NOLINT
|
||||
|
||||
template <class Tuple>
|
||||
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
|
||||
ConstField(const Tuple& t) { return t.f9_; }
|
||||
};
|
||||
|
||||
} // namespace gtest_internal
|
||||
|
||||
template <int k, GTEST_10_TYPENAMES_(T)>
|
||||
GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T)))
|
||||
get(GTEST_10_TUPLE_(T)& t) {
|
||||
return gtest_internal::Get<k>::Field(t);
|
||||
}
|
||||
|
||||
template <int k, GTEST_10_TYPENAMES_(T)>
|
||||
GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T)))
|
||||
get(const GTEST_10_TUPLE_(T)& t) {
|
||||
return gtest_internal::Get<k>::ConstField(t);
|
||||
}
|
||||
|
||||
// 6.1.3.5 Relational operators
|
||||
|
||||
// We only implement == and !=, as we don't have a need for the rest yet.
|
||||
|
||||
namespace gtest_internal {
|
||||
|
||||
// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
|
||||
// first k fields of t1 equals the first k fields of t2.
|
||||
// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
|
||||
// k1 != k2.
|
||||
template <int kSize1, int kSize2>
|
||||
struct SameSizeTuplePrefixComparator;
|
||||
|
||||
template <>
|
||||
struct SameSizeTuplePrefixComparator<0, 0> {
|
||||
template <class Tuple1, class Tuple2>
|
||||
static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <int k>
|
||||
struct SameSizeTuplePrefixComparator<k, k> {
|
||||
template <class Tuple1, class Tuple2>
|
||||
static bool Eq(const Tuple1& t1, const Tuple2& t2) {
|
||||
return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
|
||||
::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gtest_internal
|
||||
|
||||
template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
|
||||
inline bool operator==(const GTEST_10_TUPLE_(T)& t,
|
||||
const GTEST_10_TUPLE_(U)& u) {
|
||||
return gtest_internal::SameSizeTuplePrefixComparator<
|
||||
tuple_size<GTEST_10_TUPLE_(T)>::value,
|
||||
tuple_size<GTEST_10_TUPLE_(U)>::value>::Eq(t, u);
|
||||
}
|
||||
|
||||
template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
|
||||
inline bool operator!=(const GTEST_10_TUPLE_(T)& t,
|
||||
const GTEST_10_TUPLE_(U)& u) { return !(t == u); }
|
||||
|
||||
// 6.1.4 Pairs.
|
||||
// Unimplemented.
|
||||
|
||||
} // namespace tr1
|
||||
} // namespace std
|
||||
|
||||
#undef GTEST_0_TUPLE_
|
||||
#undef GTEST_1_TUPLE_
|
||||
#undef GTEST_2_TUPLE_
|
||||
#undef GTEST_3_TUPLE_
|
||||
#undef GTEST_4_TUPLE_
|
||||
#undef GTEST_5_TUPLE_
|
||||
#undef GTEST_6_TUPLE_
|
||||
#undef GTEST_7_TUPLE_
|
||||
#undef GTEST_8_TUPLE_
|
||||
#undef GTEST_9_TUPLE_
|
||||
#undef GTEST_10_TUPLE_
|
||||
|
||||
#undef GTEST_0_TYPENAMES_
|
||||
#undef GTEST_1_TYPENAMES_
|
||||
#undef GTEST_2_TYPENAMES_
|
||||
#undef GTEST_3_TYPENAMES_
|
||||
#undef GTEST_4_TYPENAMES_
|
||||
#undef GTEST_5_TYPENAMES_
|
||||
#undef GTEST_6_TYPENAMES_
|
||||
#undef GTEST_7_TYPENAMES_
|
||||
#undef GTEST_8_TYPENAMES_
|
||||
#undef GTEST_9_TYPENAMES_
|
||||
#undef GTEST_10_TYPENAMES_
|
||||
|
||||
#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
|
||||
#undef GTEST_BY_REF_
|
||||
#undef GTEST_ADD_REF_
|
||||
#undef GTEST_TUPLE_ELEMENT_
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
|
@ -47,9 +47,11 @@
|
||||
|
||||
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
|
||||
|
||||
#ifdef __GNUC__
|
||||
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using
|
||||
// libstdc++ (which is where cxxabi.h comes from).
|
||||
#ifdef __GLIBCXX__
|
||||
#include <cxxabi.h>
|
||||
#endif // __GNUC__
|
||||
#endif // __GLIBCXX__
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
@ -74,7 +76,7 @@ String GetTypeName() {
|
||||
#if GTEST_HAS_RTTI
|
||||
|
||||
const char* const name = typeid(T).name();
|
||||
#ifdef __GNUC__
|
||||
#ifdef __GLIBCXX__
|
||||
int status = 0;
|
||||
// gcc's implementation of typeid(T).name() mangles the type name,
|
||||
// so we have to demangle it.
|
||||
@ -84,7 +86,7 @@ String GetTypeName() {
|
||||
return name_str;
|
||||
#else
|
||||
return name;
|
||||
#endif // __GNUC__
|
||||
#endif // __GLIBCXX__
|
||||
|
||||
#else
|
||||
return "<type>";
|
||||
|
Loading…
x
Reference in New Issue
Block a user