diff options
Diffstat (limited to 'utils/unittest/googletest/include/gtest/internal')
9 files changed, 2071 insertions, 752 deletions
diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h b/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h index ff2e490efe..5aba1a0d68 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h @@ -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 diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h b/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h index d079a3e1f3..47aec22d16 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h @@ -45,9 +45,12 @@ #error "It must not be included except by Google Test itself." #endif // GTEST_IMPLEMENTATION_ +#ifndef _WIN32_WCE #include <errno.h> +#endif // !_WIN32_WCE #include <stddef.h> -#include <stdlib.h> // For strtoll/_strtoul64. +#include <stdlib.h> // For strtoll/_strtoul64/malloc/free. +#include <string.h> // For memmove. #include <string> @@ -84,9 +87,43 @@ const char kFilterFlag[] = "filter"; const char kListTestsFlag[] = "list_tests"; const char kOutputFlag[] = "output"; const char kPrintTimeFlag[] = "print_time"; +const char kRandomSeedFlag[] = "random_seed"; const char kRepeatFlag[] = "repeat"; +const char kShuffleFlag[] = "shuffle"; const char kThrowOnFailureFlag[] = "throw_on_failure"; +// A valid random seed must be in [1, kMaxRandomSeed]. +const int kMaxRandomSeed = 99999; + +// Returns the current time in milliseconds. +TimeInMillis GetTimeInMillis(); + +// Returns a random seed in range [1, kMaxRandomSeed] based on the +// given --gtest_random_seed flag value. +inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { + const unsigned int raw_seed = (random_seed_flag == 0) ? + static_cast<unsigned int>(GetTimeInMillis()) : + static_cast<unsigned int>(random_seed_flag); + + // Normalizes the actual seed to range [1, kMaxRandomSeed] such that + // it's easy to type. + const int normalized_seed = + static_cast<int>((raw_seed - 1U) % + static_cast<unsigned int>(kMaxRandomSeed)) + 1; + return normalized_seed; +} + +// Returns the first valid random seed after 'seed'. The behavior is +// undefined if 'seed' is invalid. The seed after kMaxRandomSeed is +// considered to be 1. +inline int GetNextRandomSeed(int seed) { + GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) + << "Invalid random seed " << seed << " - must be in [1, " + << kMaxRandomSeed << "]."; + const int next_seed = seed + 1; + return (next_seed > kMaxRandomSeed) ? 1 : next_seed; +} + // This class saves the values of all Google Test flags in its c'tor, and // restores them in its d'tor. class GTestFlagSaver { @@ -104,7 +141,9 @@ class GTestFlagSaver { list_tests_ = GTEST_FLAG(list_tests); output_ = GTEST_FLAG(output); print_time_ = GTEST_FLAG(print_time); + random_seed_ = GTEST_FLAG(random_seed); repeat_ = GTEST_FLAG(repeat); + shuffle_ = GTEST_FLAG(shuffle); throw_on_failure_ = GTEST_FLAG(throw_on_failure); } @@ -121,7 +160,9 @@ class GTestFlagSaver { GTEST_FLAG(list_tests) = list_tests_; GTEST_FLAG(output) = output_; GTEST_FLAG(print_time) = print_time_; + GTEST_FLAG(random_seed) = random_seed_; GTEST_FLAG(repeat) = repeat_; + GTEST_FLAG(shuffle) = shuffle_; GTEST_FLAG(throw_on_failure) = throw_on_failure_; } private: @@ -138,7 +179,9 @@ class GTestFlagSaver { String output_; bool print_time_; bool pretty_; + internal::Int32 random_seed_; internal::Int32 repeat_; + bool shuffle_; bool throw_on_failure_; } GTEST_ATTRIBUTE_UNUSED_; @@ -196,176 +239,84 @@ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); // method. Assumes that 0 <= shard_index < total_shards. bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id); -// List is a simple singly-linked list container. +// Vector is an ordered container that supports random access to the +// elements. // -// We cannot use std::list as Microsoft's implementation of STL has -// problems when exception is disabled. There is a hack to work -// around this, but we've seen cases where the hack fails to work. +// We cannot use std::vector, as Visual C++ 7.1's implementation of +// STL has problems compiling when exceptions are disabled. There is +// a hack to work around the problems, but we've seen cases where the +// hack fails to work. // -// TODO(wan): switch to std::list when we have a reliable fix for the -// STL problem, e.g. when we upgrade to the next version of Visual -// C++, or (more likely) switch to STLport. -// -// The element type must support copy constructor. - -// Forward declare List +// The element type must support copy constructor and operator=. template <typename E> // E is the element type. -class List; - -// ListNode is a node in a singly-linked list. It consists of an -// element and a pointer to the next node. The last node in the list -// has a NULL value for its next pointer. -template <typename E> // E is the element type. -class ListNode { - friend class List<E>; - - private: - - E element_; - ListNode * next_; - - // The c'tor is private s.t. only in the ListNode class and in its - // friend class List we can create a ListNode object. - // - // Creates a node with a given element value. The next pointer is - // set to NULL. - // - // ListNode does NOT have a default constructor. Always use this - // constructor (with parameter) to create a ListNode object. - explicit ListNode(const E & element) : element_(element), next_(NULL) {} - - // We disallow copying ListNode - GTEST_DISALLOW_COPY_AND_ASSIGN_(ListNode); - - public: - - // Gets the element in this node. - E & element() { return element_; } - const E & element() const { return element_; } - - // Gets the next node in the list. - ListNode * next() { return next_; } - const ListNode * next() const { return next_; } -}; - - -// List is a simple singly-linked list container. -template <typename E> // E is the element type. -class List { +class Vector { public: - - // Creates an empty list. - List() : head_(NULL), last_(NULL), size_(0) {} + // Creates an empty Vector. + Vector() : elements_(NULL), capacity_(0), size_(0) {} // D'tor. - virtual ~List(); + virtual ~Vector() { Clear(); } - // Clears the list. + // Clears the Vector. void Clear() { - if ( size_ > 0 ) { - // 1. Deletes every node. - ListNode<E> * node = head_; - ListNode<E> * next = node->next(); - for ( ; ; ) { - delete node; - node = next; - if ( node == NULL ) break; - next = node->next(); + if (elements_ != NULL) { + for (int i = 0; i < size_; i++) { + delete elements_[i]; } - // 2. Resets the member variables. - head_ = last_ = NULL; - size_ = 0; + free(elements_); + elements_ = NULL; + capacity_ = size_ = 0; } } // Gets the number of elements. int size() const { return size_; } - // Returns true if the list is empty. - bool IsEmpty() const { return size() == 0; } - - // Gets the first element of the list, or NULL if the list is empty. - ListNode<E> * Head() { return head_; } - const ListNode<E> * Head() const { return head_; } - - // Gets the last element of the list, or NULL if the list is empty. - ListNode<E> * Last() { return last_; } - const ListNode<E> * Last() const { return last_; } - - // Adds an element to the end of the list. A copy of the element is - // created using the copy constructor, and then stored in the list. - // Changes made to the element in the list doesn't affect the source - // object, and vice versa. - void PushBack(const E & element) { - ListNode<E> * new_node = new ListNode<E>(element); - - if ( size_ == 0 ) { - head_ = last_ = new_node; - size_ = 1; - } else { - last_->next_ = new_node; - last_ = new_node; - size_++; - } - } + // Adds an element to the end of the Vector. A copy of the element + // is created using the copy constructor, and then stored in the + // Vector. Changes made to the element in the Vector doesn't affect + // the source object, and vice versa. + void PushBack(const E& element) { Insert(element, size_); } - // Adds an element to the beginning of this list. - void PushFront(const E& element) { - ListNode<E>* const new_node = new ListNode<E>(element); - - if ( size_ == 0 ) { - head_ = last_ = new_node; - size_ = 1; - } else { - new_node->next_ = head_; - head_ = new_node; - size_++; - } - } + // Adds an element to the beginning of this Vector. + void PushFront(const E& element) { Insert(element, 0); } - // Removes an element from the beginning of this list. If the + // Removes an element from the beginning of this Vector. If the // result argument is not NULL, the removed element is stored in the // memory it points to. Otherwise the element is thrown away. - // Returns true iff the list wasn't empty before the operation. + // Returns true iff the vector wasn't empty before the operation. bool PopFront(E* result) { - if (size_ == 0) return false; + if (size_ == 0) + return false; - if (result != NULL) { - *result = head_->element_; - } - - ListNode<E>* const old_head = head_; - size_--; - if (size_ == 0) { - head_ = last_ = NULL; - } else { - head_ = head_->next_; - } - delete old_head; + if (result != NULL) + *result = GetElement(0); + Erase(0); return true; } - // Inserts an element after a given node in the list. It's the - // caller's responsibility to ensure that the given node is in the - // list. If the given node is NULL, inserts the element at the - // front of the list. - ListNode<E>* InsertAfter(ListNode<E>* node, const E& element) { - if (node == NULL) { - PushFront(element); - return Head(); - } - - ListNode<E>* const new_node = new ListNode<E>(element); - new_node->next_ = node->next_; - node->next_ = new_node; + // Inserts an element at the given index. It's the caller's + // responsibility to ensure that the given index is in the range [0, + // size()]. + void Insert(const E& element, int index) { + GrowIfNeeded(); + MoveElements(index, size_ - index, index + 1); + elements_[index] = new E(element); size_++; - if (node == last_) { - last_ = new_node; - } + } + + // Erases the element at the specified index, or aborts the program if the + // index is not in range [0, size()). + void Erase(int index) { + GTEST_CHECK_(0 <= index && index < size_) + << "Invalid Vector index " << index << ": must be in range [0, " + << (size_ - 1) << "]."; - return new_node; + delete elements_[index]; + MoveElements(index + 1, size_ - index - 1, index); + size_--; } // Returns the number of elements that satisfy a given predicate. @@ -374,10 +325,8 @@ class List { template <typename P> // P is the type of the predicate function/functor int CountIf(P predicate) const { int count = 0; - for ( const ListNode<E> * node = Head(); - node != NULL; - node = node->next() ) { - if ( predicate(node->element()) ) { + for (int i = 0; i < size_; i++) { + if (predicate(*(elements_[i]))) { count++; } } @@ -385,16 +334,14 @@ class List { return count; } - // Applies a function/functor to each element in the list. The + // Applies a function/functor to each element in the Vector. The // parameter 'functor' is a function/functor that accepts a 'const // E &', where E is the element type. This method does not change // the elements. template <typename F> // F is the type of the function/functor void ForEach(F functor) const { - for ( const ListNode<E> * node = Head(); - node != NULL; - node = node->next() ) { - functor(node->element()); + for (int i = 0; i < size_; i++) { + functor(*(elements_[i])); } } @@ -403,87 +350,146 @@ class List { // function/functor that accepts a 'const E &', where E is the // element type. This method does not change the elements. template <typename P> // P is the type of the predicate function/functor. - const ListNode<E> * FindIf(P predicate) const { - for ( const ListNode<E> * node = Head(); - node != NULL; - node = node->next() ) { - if ( predicate(node->element()) ) { - return node; + const E* FindIf(P predicate) const { + for (int i = 0; i < size_; i++) { + if (predicate(*elements_[i])) { + return elements_[i]; } } - return NULL; } template <typename P> - ListNode<E> * FindIf(P predicate) { - for ( ListNode<E> * node = Head(); - node != NULL; - node = node->next() ) { - if ( predicate(node->element() ) ) { - return node; + E* FindIf(P predicate) { + for (int i = 0; i < size_; i++) { + if (predicate(*elements_[i])) { + return elements_[i]; } } - return NULL; } - private: - ListNode<E>* head_; // The first node of the list. - ListNode<E>* last_; // The last node of the list. - int size_; // The number of elements in the list. + // Returns the i-th element of the Vector, or aborts the program if i + // is not in range [0, size()). + const E& GetElement(int i) const { + GTEST_CHECK_(0 <= i && i < size_) + << "Invalid Vector index " << i << ": must be in range [0, " + << (size_ - 1) << "]."; - // We disallow copying List. - GTEST_DISALLOW_COPY_AND_ASSIGN_(List); -}; + return *(elements_[i]); + } -// The virtual destructor of List. -template <typename E> -List<E>::~List() { - Clear(); -} + // Returns a mutable reference to the i-th element of the Vector, or + // aborts the program if i is not in range [0, size()). + E& GetMutableElement(int i) { + GTEST_CHECK_(0 <= i && i < size_) + << "Invalid Vector index " << i << ": must be in range [0, " + << (size_ - 1) << "]."; -// A function for deleting an object. Handy for being used as a -// functor. -template <typename T> -static void Delete(T * x) { - delete x; -} + return *(elements_[i]); + } -// 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) { + // Returns the i-th element of the Vector, or default_value if i is not + // in range [0, size()). + E GetElementOr(int i, E default_value) const { + return (i < 0 || i >= size_) ? default_value : *(elements_[i]); } - // Gets the user supplied key. - const char* key() const { - return key_.c_str(); + // Swaps the i-th and j-th elements of the Vector. Crashes if i or + // j is invalid. + void Swap(int i, int j) { + GTEST_CHECK_(0 <= i && i < size_) + << "Invalid first swap element " << i << ": must be in range [0, " + << (size_ - 1) << "]."; + GTEST_CHECK_(0 <= j && j < size_) + << "Invalid second swap element " << j << ": must be in range [0, " + << (size_ - 1) << "]."; + + E* const temp = elements_[i]; + elements_[i] = elements_[j]; + elements_[j] = temp; } - // Gets the user supplied value. - const char* value() const { - return value_.c_str(); + // Performs an in-place shuffle of a range of this Vector's nodes. + // 'begin' and 'end' are element indices as an STL-style range; + // i.e. [begin, end) are shuffled, where 'end' == size() means to + // shuffle to the end of the Vector. + void ShuffleRange(internal::Random* random, int begin, int end) { + GTEST_CHECK_(0 <= begin && begin <= size_) + << "Invalid shuffle range start " << begin << ": must be in range [0, " + << size_ << "]."; + GTEST_CHECK_(begin <= end && end <= size_) + << "Invalid shuffle range finish " << end << ": must be in range [" + << begin << ", " << size_ << "]."; + + // Fisher-Yates shuffle, from + // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle + for (int range_width = end - begin; range_width >= 2; range_width--) { + const int last_in_range = begin + range_width - 1; + const int selected = begin + random->Generate(range_width); + Swap(selected, last_in_range); + } } - // Sets a new value, overriding the one supplied in the constructor. - void SetValue(const char* new_value) { - value_ = new_value; + // Performs an in-place shuffle of this Vector's nodes. + void Shuffle(internal::Random* random) { + ShuffleRange(random, 0, size()); + } + + // Returns a copy of this Vector. + Vector* Clone() const { + Vector* const clone = new Vector; + clone->Reserve(size_); + for (int i = 0; i < size_; i++) { + clone->PushBack(GetElement(i)); + } + return clone; } private: - // The key supplied by the user. - String key_; - // The value supplied by the user. - String value_; -}; + // Makes sure this Vector's capacity is at least the given value. + void Reserve(int new_capacity) { + if (new_capacity <= capacity_) + return; + + capacity_ = new_capacity; + elements_ = static_cast<E**>( + realloc(elements_, capacity_*sizeof(elements_[0]))); + } + + // Grows the buffer if it is not big enough to hold one more element. + void GrowIfNeeded() { + if (size_ < capacity_) + return; + + // Exponential bump-up is necessary to ensure that inserting N + // elements is O(N) instead of O(N^2). The factor 3/2 means that + // no more than 1/3 of the slots are wasted. + const int new_capacity = 3*(capacity_/2 + 1); + GTEST_CHECK_(new_capacity > capacity_) // Does the new capacity overflow? + << "Cannot grow a Vector with " << capacity_ << " elements already."; + Reserve(new_capacity); + } + + // Moves the give consecutive elements to a new index in the Vector. + void MoveElements(int source, int count, int dest) { + memmove(elements_ + dest, elements_ + source, count*sizeof(elements_[0])); + } + + E** elements_; + int capacity_; // The number of elements allocated for elements_. + int size_; // The number of elements; in the range [0, capacity_]. + + // We disallow copying Vector. + GTEST_DISALLOW_COPY_AND_ASSIGN_(Vector); +}; // class Vector + +// A function for deleting an object. Handy for being used as a +// functor. +template <typename T> +static void Delete(T * x) { + delete x; +} // A predicate that checks the key of a TestProperty against a known key. // @@ -505,96 +511,6 @@ class TestPropertyKeyIs { String key_; }; -// 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 list of TestPartResults. - const internal::List<TestPartResult> & test_part_results() const { - return test_part_results_; - } - - // Gets the list of TestProperties. - const internal::List<internal::TestProperty> & test_properties() const { - return test_properties_; - } - - // Gets the number of successful test parts. - int successful_part_count() const; - - // Gets the number of failed test parts. - int failed_part_count() const; - - // 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 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 { return failed_part_count() > 0; } - - // Returns true iff the test fatally failed. - bool HasFatalFailure() const; - - // Returns the elapsed time, in milliseconds. - TimeInMillis elapsed_time() const { return elapsed_time_; } - - // Sets the elapsed time. - void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } - - // Adds a test part result to the list. - void AddTestPartResult(const TestPartResult& test_part_result); - - // 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 internal::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 internal::TestProperty& test_property); - - // 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 object. - void Clear(); - private: - // Protects mutable state of the property list and of owned properties, whose - // values may be updated. - internal::Mutex test_properites_mutex_; - - // The list of TestPartResults - internal::List<TestPartResult> test_part_results_; - // The list of TestProperties - internal::List<internal::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 - class TestInfoImpl { public: TestInfoImpl(TestInfo* parent, const char* test_case_name, @@ -615,6 +531,12 @@ class TestInfoImpl { // Sets the is_disabled member. void set_is_disabled(bool is) { is_disabled_ = is; } + // Returns true if this test matches the filter specified by the user. + bool matches_filter() const { return matches_filter_; } + + // Sets the matches_filter member. + void set_matches_filter(bool matches) { matches_filter_ = matches; } + // Returns the test case name. const char* test_case_name() const { return test_case_name_.c_str(); } @@ -631,18 +553,13 @@ class TestInfoImpl { TypeId fixture_class_id() const { return fixture_class_id_; } // Returns the test result. - internal::TestResult* result() { return &result_; } - const internal::TestResult* result() const { return &result_; } + TestResult* result() { return &result_; } + const TestResult* result() const { return &result_; } // Creates the test object, runs it, records its result, and then // deletes it. void Run(); - // Calls the given TestInfo object's Run() method. - static void RunTest(TestInfo * test_info) { - test_info->impl()->Run(); - } - // Clears the test result. void ClearResult() { result_.Clear(); } @@ -661,150 +578,18 @@ class TestInfoImpl { const TypeId fixture_class_id_; // ID of the test fixture class bool should_run_; // True iff this test should run bool is_disabled_; // True iff this test is disabled + bool matches_filter_; // True if this test matches the + // user-specified filter. internal::TestFactoryBase* const factory_; // The factory that creates // the test object // This field is mutable and needs to be reset before running the // test for the second time. - internal::TestResult result_; + TestResult result_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfoImpl); }; -} // namespace internal - -// A test case, which consists of a list 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_; } - - // Sets the should_run member. - void set_should_run(bool should) { should_run_ = should; } - - // Gets the (mutable) list of TestInfos in this TestCase. - internal::List<TestInfo*>& test_info_list() { return *test_info_list_; } - - // Gets the (immutable) list of TestInfos in this TestCase. - const internal::List<TestInfo *> & test_info_list() const { - return *test_info_list_; - } - - // 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. - internal::TimeInMillis elapsed_time() const { return elapsed_time_; } - - // Adds a TestInfo to this test case. Will delete the TestInfo upon - // destruction of the TestCase object. - void AddTestInfo(TestInfo * test_info); - - // Finds and returns a TestInfo with the given name. If one doesn't - // exist, returns NULL. - TestInfo* GetTestInfo(const char* test_name); - - // 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(); - - // Runs every test in the given TestCase. - static void RunTestCase(TestCase * test_case) { test_case->Run(); } - - // Returns true iff test passed. - static bool TestPassed(const TestInfo * test_info) { - const internal::TestInfoImpl* const impl = test_info->impl(); - return impl->should_run() && impl->result()->Passed(); - } - - // Returns true iff test failed. - static bool TestFailed(const TestInfo * test_info) { - const internal::TestInfoImpl* const impl = test_info->impl(); - return impl->should_run() && impl->result()->Failed(); - } - - // Returns true iff test is disabled. - static bool TestDisabled(const TestInfo * test_info) { - return test_info->impl()->is_disabled(); - } - - // Returns true if the given test should run. - static bool ShouldRunTest(const TestInfo *test_info) { - return test_info->impl()->should_run(); - } - - private: - // Name of the test case. - internal::String name_; - // Comment on the test case. - internal::String comment_; - // List of TestInfos. - internal::List<TestInfo*>* test_info_list_; - // 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. - internal::TimeInMillis elapsed_time_; - - // We disallow copying TestCases. - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); -}; - -namespace internal { - // Class UnitTestOptions. // // This class contains functions for processing options the user @@ -885,7 +670,7 @@ class OsStackTraceGetterInterface { // A working implementation of the OsStackTraceGetterInterface interface. class OsStackTraceGetter : public OsStackTraceGetterInterface { public: - OsStackTraceGetter() {} + OsStackTraceGetter() : caller_frame_(NULL) {} virtual String CurrentStackTrace(int max_depth, int skip_count); virtual void UponLeavingGTest(); @@ -1014,26 +799,29 @@ class UnitTestImpl { return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); } - // Returns the TestResult for the test that's currently running, or - // the TestResult for the ad hoc test if no test is running. - internal::TestResult* current_test_result(); + // 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 { + const int index = test_case_indices_.GetElementOr(i, -1); + return index < 0 ? NULL : test_cases_.GetElement(i); + } - // Returns the TestResult for the ad hoc test. - const internal::TestResult* ad_hoc_test_result() const { - return &ad_hoc_test_result_; + // 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) { + const int index = test_case_indices_.GetElementOr(i, -1); + return index < 0 ? NULL : test_cases_.GetElement(index); } - // Sets the unit test result printer. - // - // Does nothing if the input and the current printer object are the - // same; otherwise, deletes the old printer object and makes the - // input the current printer. - void set_result_printer(UnitTestEventListenerInterface * result_printer); + // Provides access to the event listener list. + TestEventListeners* listeners() { return &listeners_; } + + // Returns the TestResult for the test that's currently running, or + // the TestResult for the ad hoc test if no test is running. + TestResult* current_test_result(); - // Returns the current unit test result printer if it is not NULL; - // otherwise, creates an appropriate result printer, makes it the - // current printer, and returns it. - UnitTestEventListenerInterface* result_printer(); + // Returns the TestResult for the ad hoc test. + const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } // Sets the OS stack trace getter. // @@ -1091,10 +879,8 @@ class UnitTestImpl { // before main() is reached. if (original_working_dir_.IsEmpty()) { original_working_dir_.Set(FilePath::GetCurrentDir()); - if (original_working_dir_.IsEmpty()) { - printf("%s\n", "Failed to get the current working directory."); - abort(); - } + GTEST_CHECK_(!original_working_dir_.IsEmpty()) + << "Failed to get the current working directory."; } GetTestCase(test_info->test_case_name(), @@ -1158,35 +944,36 @@ class UnitTestImpl { // Returns the number of tests that should run. int FilterTests(ReactionToSharding shard_tests); - // Lists all the tests by name. - void ListAllTests(); + // Prints the names of the tests matching the user-specified filter flag. + void ListTestsMatchingFilter(); const TestCase* current_test_case() const { return current_test_case_; } TestInfo* current_test_info() { return current_test_info_; } const TestInfo* current_test_info() const { return current_test_info_; } - // Returns the list of environments that need to be set-up/torn-down + // Returns the vector of environments that need to be set-up/torn-down // before/after the tests are run. - internal::List<Environment*>* environments() { return &environments_; } - internal::List<Environment*>* environments_in_reverse_order() { + internal::Vector<Environment*>* environments() { return &environments_; } + internal::Vector<Environment*>* environments_in_reverse_order() { return &environments_in_reverse_order_; } - internal::List<TestCase*>* test_cases() { return &test_cases_; } - const internal::List<TestCase*>* test_cases() const { return &test_cases_; } - // Getters for the per-thread Google Test trace stack. - internal::List<TraceInfo>* gtest_trace_stack() { + internal::Vector<TraceInfo>* gtest_trace_stack() { return gtest_trace_stack_.pointer(); } - const internal::List<TraceInfo>* gtest_trace_stack() const { + const internal::Vector<TraceInfo>* gtest_trace_stack() const { return gtest_trace_stack_.pointer(); } #if GTEST_HAS_DEATH_TEST + void InitDeathTestSubprocessControlInfo() { + internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); + } // Returns a pointer to the parsed --gtest_internal_run_death_test // flag, or NULL if that flag was not specified. // This information is useful only in a death test child process. + // Must not be called before a call to InitGoogleTest. const InternalRunDeathTestFlag* internal_run_death_test_flag() const { return internal_run_death_test_flag_.get(); } @@ -1196,9 +983,35 @@ class UnitTestImpl { return death_test_factory_.get(); } + void SuppressTestEventsIfInSubprocess(); + friend class ReplaceDeathTestFactory; #endif // GTEST_HAS_DEATH_TEST + // Initializes the event listener performing XML output as specified by + // UnitTestOptions. Must not be called before InitGoogleTest. + void ConfigureXmlOutput(); + + // Performs initialization dependent upon flag values obtained in + // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to + // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest + // this function is also called from RunAllTests. Since this function can be + // called more than once, it has to be idempotent. + void PostFlagParsingInit(); + + // Gets the random seed used at the start of the current test iteration. + int random_seed() const { return random_seed_; } + + // Gets the random number generator. + internal::Random* random() { return &random_; } + + // Shuffles all test cases, and the tests within each test case, + // making sure that death tests are still run first. + void ShuffleTests(); + + // Restores the test cases and tests to their order before the first shuffle. + void UnshuffleTests(); + private: friend class ::testing::UnitTest; @@ -1224,13 +1037,21 @@ class UnitTestImpl { internal::ThreadLocal<TestPartResultReporterInterface*> per_thread_test_part_result_reporter_; - // The list of environments that need to be set-up/torn-down + // The vector of environments that need to be set-up/torn-down // before/after the tests are run. environments_in_reverse_order_ // simply mirrors environments_ in reverse order. - internal::List<Environment*> environments_; - internal::List<Environment*> environments_in_reverse_order_; + internal::Vector<Environment*> environments_; + internal::Vector<Environment*> environments_in_reverse_order_; + + // The vector of TestCases in their original order. It owns the + // elements in the vector. + internal::Vector<TestCase*> test_cases_; - internal::List<TestCase*> test_cases_; // The list of TestCases. + // Provides a level of indirection for the test case list to allow + // easy shuffling and restoring the test case order. The i-th + // element of this vector is the index of the i-th test case in the + // shuffled order. + internal::Vector<int> test_case_indices_; #if GTEST_HAS_PARAM_TEST // ParameterizedTestRegistry object used to register value-parameterized @@ -1241,13 +1062,13 @@ class UnitTestImpl { bool parameterized_tests_registered_; #endif // GTEST_HAS_PARAM_TEST - // Points to the last death test case registered. Initially NULL. - internal::ListNode<TestCase*>* last_death_test_case_; + // Index of the last death test case registered. Initially -1. + int last_death_test_case_; // This points to the TestCase for the currently running test. It // changes as Google Test goes through one test case after another. // When no test is running, this is set to NULL and Google Test - // stores assertion results in ad_hoc_test_result_. Initally NULL. + // stores assertion results in ad_hoc_test_result_. Initially NULL. TestCase* current_test_case_; // This points to the TestInfo for the currently running test. It @@ -1264,13 +1085,11 @@ class UnitTestImpl { // If an assertion is encountered when no TEST or TEST_F is running, // Google Test attributes the assertion result to an imaginary "ad hoc" // test, and records the result in ad_hoc_test_result_. - internal::TestResult ad_hoc_test_result_; + TestResult ad_hoc_test_result_; - // The unit test result printer. Will be deleted when the UnitTest - // object is destructed. By default, a plain text printer is used, - // but the user can set this field to use a custom printer if that - // is desired. - UnitTestEventListenerInterface* result_printer_; + // The list of event listeners that can be used to track events inside + // Google Test. + TestEventListeners listeners_; // The OS stack trace getter. Will be deleted when the UnitTest // object is destructed. By default, an OsStackTraceGetter is used, @@ -1278,6 +1097,15 @@ class UnitTestImpl { // desired. OsStackTraceGetterInterface* os_stack_trace_getter_; + // True iff PostFlagParsingInit() has been called. + bool post_flag_parse_init_performed_; + + // The random number seed used at the beginning of the test run. + int random_seed_; + + // Our random number generator. + internal::Random random_; + // How long the test took to run, in milliseconds. TimeInMillis elapsed_time_; @@ -1289,7 +1117,7 @@ class UnitTestImpl { #endif // GTEST_HAS_DEATH_TEST // A per-thread stack of traces created by the SCOPED_TRACE() macro. - internal::ThreadLocal<internal::List<TraceInfo> > gtest_trace_stack_; + internal::ThreadLocal<internal::Vector<TraceInfo> > gtest_trace_stack_; GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); }; // class UnitTestImpl @@ -1325,7 +1153,7 @@ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); // Returns the message describing the last system error, regardless of the // platform. -String GetLastSystemErrorMessage(); +String GetLastErrnoDescription(); #if GTEST_OS_WINDOWS // Provides leak-safe Windows kernel handle ownership. @@ -1370,13 +1198,14 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) { char* end; // BiggestConvertible is the largest integer type that system-provided // string-to-number conversion routines can return. -#if GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS && !defined(__GNUC__) + // MSVC and C++ Builder define __int64 instead of the standard long long. typedef unsigned __int64 BiggestConvertible; const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); #else typedef unsigned long long BiggestConvertible; // NOLINT const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); -#endif // GTEST_OS_WINDOWS +#endif // GTEST_OS_WINDOWS && !defined(__GNUC__) const bool parse_success = *end == '\0' && errno == 0; // TODO(vladl@google.com): Convert this to compile time assertion when it is @@ -1392,6 +1221,26 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) { } #endif // GTEST_HAS_DEATH_TEST +// TestResult contains some private methods that should be hidden from +// Google Test user but are required for testing. This class allow our tests +// to access them. +class TestResultAccessor { + public: + static void RecordProperty(TestResult* test_result, + const TestProperty& property) { + test_result->RecordProperty(property); + } + + static void ClearTestPartResults(TestResult* test_result) { + test_result->ClearTestPartResults(); + } + + static const Vector<testing::TestPartResult>& test_part_results( + const TestResult& test_result) { + return test_result.test_part_results(); + } +}; + } // namespace internal } // namespace testing diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-internal.h b/utils/unittest/googletest/include/gtest/internal/gtest-internal.h index def4b5970a..20c32340d7 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-internal.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-internal.h @@ -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" \ diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h b/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h index ad06e02477..1358c329f4 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h @@ -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 diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h b/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h index 5559ab4492..dcc5494745 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h @@ -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. } diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-port.h b/utils/unittest/googletest/include/gtest/internal/gtest-port.h index d949ec1aa9..e346cde848 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-port.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-port.h @@ -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_ "\\" +// 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 -// Defines BiggestInt as the biggest signed integer type the compiler -// supports. +// 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 __int64 BiggestInt; + +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 -typedef long long BiggestInt; // NOLINT +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 diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-string.h b/utils/unittest/googletest/include/gtest/internal/gtest-string.h index 566a6b57e2..4bc824130b 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-string.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-string.h @@ -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' diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h b/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h new file mode 100644 index 0000000000..86b200be0f --- /dev/null +++ b/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h @@ -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_ diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h b/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h index 1ea7d18e3b..f1b1bedd86 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-type-util.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>"; |