diff options
Diffstat (limited to 'llvm')
30 files changed, 22432 insertions, 2 deletions
diff --git a/llvm/LICENSE.TXT b/llvm/LICENSE.TXT index f5aca80cbff..36a42e82cac 100644 --- a/llvm/LICENSE.TXT +++ b/llvm/LICENSE.TXT @@ -66,5 +66,4 @@ Autoconf            llvm/autoconf                      llvm/projects/ModuleMaker/autoconf                      llvm/projects/sample/autoconf  CellSPU backend     llvm/lib/Target/CellSPU/README.txt - - +Google Test         llvm/utils/unittest/googletest/COPYING diff --git a/llvm/utils/unittest/googletest/COPYING b/llvm/utils/unittest/googletest/COPYING new file mode 100644 index 00000000000..1941a11f8ce --- /dev/null +++ b/llvm/utils/unittest/googletest/COPYING @@ -0,0 +1,28 @@ +Copyright 2008, 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. diff --git a/llvm/utils/unittest/googletest/README.LLVM b/llvm/utils/unittest/googletest/README.LLVM new file mode 100644 index 00000000000..87b810838bd --- /dev/null +++ b/llvm/utils/unittest/googletest/README.LLVM @@ -0,0 +1,14 @@ +LLVM notes +---------- + +This directory contains Google Test 1.2.1, with all elements removed except for +the actual source code, to minimize the addition to the LLVM distribution. + +Cleaned up as follows: +$ rm -f aclocal* configure* Makefile* CHANGES CONTRIBUTORS README +$ rm -rf build-aux m4 make msvc samples scons scripts test xcode + +# Clean up source files used for generating headers +$ rm -f `find . -name \*\.pump` + +For the license, see the file COPYING in this directory. diff --git a/llvm/utils/unittest/googletest/include/gtest/gtest-death-test.h b/llvm/utils/unittest/googletest/include/gtest/gtest-death-test.h new file mode 100644 index 00000000000..f0e109a3a3a --- /dev/null +++ b/llvm/utils/unittest/googletest/include/gtest/gtest-death-test.h @@ -0,0 +1,209 @@ +// Copyright 2005, 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) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the public API for death tests.  It is +// #included by gtest.h so a user doesn't need to include this +// directly. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ + +#include <gtest/internal/gtest-death-test-internal.h> + +namespace testing { + +// This flag controls the style of death tests.  Valid values are "threadsafe", +// meaning that the death test child process will re-execute the test binary +// from the start, running only a single death test, or "fast", +// meaning that the child process will execute the test logic immediately +// after forking. +GTEST_DECLARE_string_(death_test_style); + +#ifdef GTEST_HAS_DEATH_TEST + +// The following macros are useful for writing death tests. + +// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is +// executed: +// +//   1. It generates a warning if there is more than one active +//   thread.  This is because it's safe to fork() or clone() only +//   when there is a single thread. +// +//   2. The parent process clone()s a sub-process and runs the death +//   test in it; the sub-process exits with code 0 at the end of the +//   death test, if it hasn't exited already. +// +//   3. The parent process waits for the sub-process to terminate. +// +//   4. The parent process checks the exit code and error message of +//   the sub-process. +// +// Examples: +// +//   ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); +//   for (int i = 0; i < 5; i++) { +//     EXPECT_DEATH(server.ProcessRequest(i), +//                  "Invalid request .* in ProcessRequest()") +//         << "Failed to die on request " << i); +//   } +// +//   ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); +// +//   bool KilledBySIGHUP(int exit_code) { +//     return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; +//   } +// +//   ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); +// +// Known caveats: +// +//   A "threadsafe" style death test obtains the path to the test +//   program from argv[0] and re-executes it in the sub-process.  For +//   simplicity, the current implementation doesn't search the PATH +//   when launching the sub-process.  This means that the user must +//   invoke the test program via a path that contains at least one +//   path separator (e.g. path/to/foo_test and +//   /absolute/path/to/bar_test are fine, but foo_test is not).  This +//   is rarely a problem as people usually don't put the test binary +//   directory in PATH. +// +// TODO(wan@google.com): make thread-safe death tests search the PATH. + +// Asserts that a given statement causes the program to exit, with an +// integer exit status that satisfies predicate, and emitting error output +// that matches regex. +#define ASSERT_EXIT(statement, predicate, regex) \ +  GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) + +// Like ASSERT_EXIT, but continues on to successive tests in the +// test case, if any: +#define EXPECT_EXIT(statement, predicate, regex) \ +  GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) + +// Asserts that a given statement causes the program to exit, either by +// explicitly exiting with a nonzero exit code or being killed by a +// signal, and emitting error output that matches regex. +#define ASSERT_DEATH(statement, regex) \ +  ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Like ASSERT_DEATH, but continues on to successive tests in the +// test case, if any: +#define EXPECT_DEATH(statement, regex) \ +  EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: + +// Tests that an exit code describes a normal exit with a given exit code. +class ExitedWithCode { + public: +  explicit ExitedWithCode(int exit_code); +  bool operator()(int exit_status) const; + private: +  const int exit_code_; +}; + +// Tests that an exit code describes an exit due to termination by a +// given signal. +class KilledBySignal { + public: +  explicit KilledBySignal(int signum); +  bool operator()(int exit_status) const; + private: +  const int signum_; +}; + +// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. +// The death testing framework causes this to have interesting semantics, +// since the sideeffects of the call are only visible in opt mode, and not +// in debug mode. +// +// In practice, this can be used to test functions that utilize the +// LOG(DFATAL) macro using the following style: +// +// int DieInDebugOr12(int* sideeffect) { +//   if (sideeffect) { +//     *sideeffect = 12; +//   } +//   LOG(DFATAL) << "death"; +//   return 12; +// } +// +// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) { +//   int sideeffect = 0; +//   // Only asserts in dbg. +//   EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); +// +// #ifdef NDEBUG +//   // opt-mode has sideeffect visible. +//   EXPECT_EQ(12, sideeffect); +// #else +//   // dbg-mode no visible sideeffect. +//   EXPECT_EQ(0, sideeffect); +// #endif +// } +// +// This will assert that DieInDebugReturn12InOpt() crashes in debug +// mode, usually due to a DCHECK or LOG(DFATAL), but returns the +// appropriate fallback value (12 in this case) in opt mode. If you +// need to test that a function has appropriate side-effects in opt +// mode, include assertions against the side-effects.  A general +// pattern for this is: +// +// EXPECT_DEBUG_DEATH({ +//   // Side-effects here will have an effect after this statement in +//   // opt mode, but none in debug mode. +//   EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); +// }, "death"); +// +#ifdef NDEBUG + +#define EXPECT_DEBUG_DEATH(statement, regex) \ +  do { statement; } while (false) + +#define ASSERT_DEBUG_DEATH(statement, regex) \ +  do { statement; } while (false) + +#else + +#define EXPECT_DEBUG_DEATH(statement, regex) \ +  EXPECT_DEATH(statement, regex) + +#define ASSERT_DEBUG_DEATH(statement, regex) \ +  ASSERT_DEATH(statement, regex) + +#endif  // NDEBUG for EXPECT_DEBUG_DEATH +#endif  // GTEST_HAS_DEATH_TEST +}  // namespace testing + +#endif  // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ diff --git a/llvm/utils/unittest/googletest/include/gtest/gtest-message.h b/llvm/utils/unittest/googletest/include/gtest/gtest-message.h new file mode 100644 index 00000000000..7effd086478 --- /dev/null +++ b/llvm/utils/unittest/googletest/include/gtest/gtest-message.h @@ -0,0 +1,224 @@ +// Copyright 2005, 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) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the Message class. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +//   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user +// program! + +#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ +#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ + +#include <gtest/internal/gtest-string.h> +#include <gtest/internal/gtest-internal.h> + +namespace testing { + +// The Message class works like an ostream repeater. +// +// Typical usage: +// +//   1. You stream a bunch of values to a Message object. +//      It will remember the text in a StrStream. +//   2. Then you stream the Message object to an ostream. +//      This causes the text in the Message to be streamed +//      to the ostream. +// +// For example; +// +//   testing::Message foo; +//   foo << 1 << " != " << 2; +//   std::cout << foo; +// +// will print "1 != 2". +// +// Message is not intended to be inherited from.  In particular, its +// destructor is not virtual. +// +// Note that StrStream behaves differently in gcc and in MSVC.  You +// can stream a NULL char pointer to it in the former, but not in the +// latter (it causes an access violation if you do).  The Message +// class hides this difference by treating a NULL char pointer as +// "(null)". +class Message { + private: +  // The type of basic IO manipulators (endl, ends, and flush) for +  // narrow streams. +  typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); + + public: +  // Constructs an empty Message. +  // We allocate the StrStream separately because it otherwise each use of +  // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's +  // stack frame leading to huge stack frames in some cases; gcc does not reuse +  // the stack space. +  Message() : ss_(new internal::StrStream) {} + +  // Copy constructor. +  Message(const Message& msg) : ss_(new internal::StrStream) {  // NOLINT +    *ss_ << msg.GetString(); +  } + +  // Constructs a Message from a C-string. +  explicit Message(const char* str) : ss_(new internal::StrStream) { +    *ss_ << str; +  } + +  ~Message() { delete ss_; } +#ifdef GTEST_OS_SYMBIAN +  // Streams a value (either a pointer or not) to this object. +  template <typename T> +  inline Message& operator <<(const T& value) { +    StreamHelper(typename internal::is_pointer<T>::type(), value); +    return *this; +  } +#else +  // Streams a non-pointer value to this object. +  template <typename T> +  inline Message& operator <<(const T& val) { +    ::GTestStreamToHelper(ss_, val); +    return *this; +  } + +  // Streams a pointer value to this object. +  // +  // This function is an overload of the previous one.  When you +  // stream a pointer to a Message, this definition will be used as it +  // is more specialized.  (The C++ Standard, section +  // [temp.func.order].)  If you stream a non-pointer, then the +  // previous definition will be used. +  // +  // The reason for this overload is that streaming a NULL pointer to +  // ostream is undefined behavior.  Depending on the compiler, you +  // may get "0", "(nil)", "(null)", or an access violation.  To +  // ensure consistent result across compilers, we always treat NULL +  // as "(null)". +  template <typename T> +  inline Message& operator <<(T* const& pointer) {  // NOLINT +    if (pointer == NULL) { +      *ss_ << "(null)"; +    } else { +      ::GTestStreamToHelper(ss_, pointer); +    } +    return *this; +  } +#endif  // GTEST_OS_SYMBIAN + +  // Since the basic IO manipulators are overloaded for both narrow +  // and wide streams, we have to provide this specialized definition +  // of operator <<, even though its body is the same as the +  // templatized version above.  Without this definition, streaming +  // endl or other basic IO manipulators to Message will confuse the +  // compiler. +  Message& operator <<(BasicNarrowIoManip val) { +    *ss_ << val; +    return *this; +  } + +  // Instead of 1/0, we want to see true/false for bool values. +  Message& operator <<(bool b) { +    return *this << (b ? "true" : "false"); +  } + +  // These two overloads allow streaming a wide C string to a Message +  // using the UTF-8 encoding. +  Message& operator <<(const wchar_t* wide_c_str) { +    return *this << internal::String::ShowWideCString(wide_c_str); +  } +  Message& operator <<(wchar_t* wide_c_str) { +    return *this << internal::String::ShowWideCString(wide_c_str); +  } + +#if GTEST_HAS_STD_WSTRING +  // Converts the given wide string to a narrow string using the UTF-8 +  // encoding, and streams the result to this Message object. +  Message& operator <<(const ::std::wstring& wstr); +#endif  // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING +  // Converts the given wide string to a narrow string using the UTF-8 +  // encoding, and streams the result to this Message object. +  Message& operator <<(const ::wstring& wstr); +#endif  // GTEST_HAS_GLOBAL_WSTRING + +  // Gets the text streamed to this object so far as a String. +  // Each '\0' character in the buffer is replaced with "\\0". +  // +  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +  internal::String GetString() const { +    return internal::StrStreamToString(ss_); +  } + + private: +#ifdef GTEST_OS_SYMBIAN +  // These are needed as the Nokia Symbian Compiler cannot decide between +  // const T& and const T* in a function template. The Nokia compiler _can_ +  // decide between class template specializations for T and T*, so a +  // tr1::type_traits-like is_pointer works, and we can overload on that. +  template <typename T> +  inline void StreamHelper(internal::true_type dummy, T* pointer) { +    if (pointer == NULL) { +      *ss_ << "(null)"; +    } else { +      ::GTestStreamToHelper(ss_, pointer); +    } +  } +  template <typename T> +  inline void StreamHelper(internal::false_type dummy, const T& value) { +    ::GTestStreamToHelper(ss_, value); +  } +#endif  // GTEST_OS_SYMBIAN + +  // We'll hold the text streamed to this object here. +  internal::StrStream* const ss_; + +  // We declare (but don't implement) this to prevent the compiler +  // from implementing the assignment operator. +  void operator=(const Message&); +}; + +// Streams a Message to an ostream. +inline std::ostream& operator <<(std::ostream& os, const Message& sb) { +  return os << sb.GetString(); +} + +}  // namespace testing + +#endif  // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ diff --git a/llvm/utils/unittest/googletest/include/gtest/gtest-param-test.h b/llvm/utils/unittest/googletest/include/gtest/gtest-param-test.h new file mode 100644 index 00000000000..2d63237f562 --- /dev/null +++ b/llvm/utils/unittest/googletest/include/gtest/gtest-param-test.h @@ -0,0 +1,1385 @@ +// This file was GENERATED by a script.  DO NOT EDIT BY HAND!!! + +// Copyright 2008, 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. +// +// Authors: vladl@google.com (Vlad Losev) +// +// Macros and functions for implementing parameterized tests +// in Google C++ Testing Framework (Google Test) +// +// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND! +// +#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ + + +// Value-parameterized tests allow you to test your code with different +// parameters without writing multiple copies of the same test. +// +// Here is how you use value-parameterized tests: + +#if 0 + +// To write value-parameterized tests, first you should define a fixture +// class. It must be derived from testing::TestWithParam<T>, where T is +// the type of your parameter values. TestWithParam<T> is itself derived +// from testing::Test. T can be any copyable type. If it's a raw pointer, +// you are responsible for managing the lifespan of the pointed values. + +class FooTest : public ::testing::TestWithParam<const char*> { +  // You can implement all the usual class fixture members here. +}; + +// Then, use the TEST_P macro to define as many parameterized tests +// for this fixture as you want. The _P suffix is for "parameterized" +// or "pattern", whichever you prefer to think. + +TEST_P(FooTest, DoesBlah) { +  // Inside a test, access the test parameter with the GetParam() method +  // of the TestWithParam<T> class: +  EXPECT_TRUE(foo.Blah(GetParam())); +  ... +} + +TEST_P(FooTest, HasBlahBlah) { +  ... +} + +// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test +// case with any set of parameters you want. Google Test defines a number +// of functions for generating test parameters. They return what we call +// (surprise!) parameter generators. Here is a  summary of them, which +// are all in the testing namespace: +// +// +//  Range(begin, end [, step]) - Yields values {begin, begin+step, +//                               begin+step+step, ...}. The values do not +//                               include end. step defaults to 1. +//  Values(v1, v2, ..., vN)    - Yields values {v1, v2, ..., vN}. +//  ValuesIn(container)        - Yields values from a C-style array, an STL +//  ValuesIn(begin,end)          container, or an iterator range [begin, end). +//  Bool()                     - Yields sequence {false, true}. +//  Combine(g1, g2, ..., gN)   - Yields all combinations (the Cartesian product +//                               for the math savvy) of the values generated +//                               by the N generators. +// +// For more details, see comments at the definitions of these functions below +// in this file. +// +// The following statement will instantiate tests from the FooTest test case +// each with parameter values "meeny", "miny", and "moe". + +INSTANTIATE_TEST_CASE_P(InstantiationName, +                        FooTest, +                        Values("meeny", "miny", "moe")); + +// To distinguish different instances of the pattern, (yes, you +// can instantiate it more then once) the first argument to the +// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the +// actual test case name. Remember to pick unique prefixes for different +// instantiations. The tests from the instantiation above will have +// these names: +// +//    * InstantiationName/FooTest.DoesBlah/0 for "meeny" +//    * InstantiationName/FooTest.DoesBlah/1 for "miny" +//    * InstantiationName/FooTest.DoesBlah/2 for "moe" +//    * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" +//    * InstantiationName/FooTest.HasBlahBlah/1 for "miny" +//    * InstantiationName/FooTest.HasBlahBlah/2 for "moe" +// +// You can use these names in --gtest_filter. +// +// This statement will instantiate all tests from FooTest again, each +// with parameter values "cat" and "dog": + +const char* pets[] = {"cat", "dog"}; +INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); + +// The tests from the instantiation above will have these names: +// +//    * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" +//    * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" +//    * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" +//    * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" +// +// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests +// in the given test case, whether their definitions come before or +// AFTER the INSTANTIATE_TEST_CASE_P statement. +// +// Please also note that generator expressions are evaluated in +// RUN_ALL_TESTS(), after main() has started. This allows evaluation of +// parameter list based on command line parameters. +// +// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc +// for more examples. +// +// In the future, we plan to publish the API for defining new parameter +// generators. But for now this interface remains part of the internal +// implementation and is subject to change. + +#endif  // 0 + + +#include <utility> + +#include <gtest/internal/gtest-port.h> + +#ifdef GTEST_HAS_PARAM_TEST + +#include <gtest/internal/gtest-internal.h> +#include <gtest/internal/gtest-param-util.h> +#include <gtest/internal/gtest-param-util-generated.h> + +namespace testing { + +// Functions producing parameter generators. +// +// Google Test uses these generators to produce parameters for value- +// parameterized tests. When a parameterized test case is instantiated +// with a particular generator, Google Test creates and runs tests +// for each element in the sequence produced by the generator. +// +// In the following sample, tests from test case FooTest are instantiated +// each three times with parameter values 3, 5, and 8: +// +// class FooTest : public TestWithParam<int> { ... }; +// +// TEST_P(FooTest, TestThis) { +// } +// TEST_P(FooTest, TestThat) { +// } +// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); +// + +// Range() returns generators providing sequences of values in a range. +// +// Synopsis: +// Range(start, end) +//   - returns a generator producing a sequence of values {start, start+1, +//     start+2, ..., }. +// Range(start, end, step) +//   - returns a generator producing a sequence of values {start, start+step, +//     start+step+step, ..., }. +// Notes: +//   * The generated sequences never include end. For example, Range(1, 5) +//     returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) +//     returns a generator producing {1, 3, 5, 7}. +//   * start and end must have the same type. That type may be any integral or +//     floating-point type or a user defined type satisfying these conditions: +//     * It must be assignable (have operator=() defined). +//     * It must have operator+() (operator+(int-compatible type) for +//       two-operand version). +//     * It must have operator<() defined. +//     Elements in the resulting sequences will also have that type. +//   * Condition start < end must be satisfied in order for resulting sequences +//     to contain any elements. +// +template <typename T, typename IncrementT> +internal::ParamGenerator<T> Range(T start, T end, IncrementT step) { +  return internal::ParamGenerator<T>( +      new internal::RangeGenerator<T, IncrementT>(start, end, step)); +} + +template <typename T> +internal::ParamGenerator<T> Range(T start, T end) { +  return Range(start, end, 1); +} + +// ValuesIn() function allows generation of tests with parameters coming from +// a container. +// +// Synopsis: +// ValuesIn(const T (&array)[N]) +//   - returns a generator producing sequences with elements from +//     a C-style array. +// ValuesIn(const Container& container) +//   - returns a generator producing sequences with elements from +//     an STL-style container. +// ValuesIn(Iterator begin, Iterator end) +//   - returns a generator producing sequences with elements from +//     a range [begin, end) defined by a pair of STL-style iterators. These +//     iterators can also be plain C pointers. +// +// Please note that ValuesIn copies the values from the containers +// passed in and keeps them to generate tests in RUN_ALL_TESTS(). +// +// Examples: +// +// This instantiates tests from test case StringTest +// each with C-string values of "foo", "bar", and "baz": +// +// const char* strings[] = {"foo", "bar", "baz"}; +// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); +// +// This instantiates tests from test case StlStringTest +// each with STL strings with values "a" and "b": +// +// ::std::vector< ::std::string> GetParameterStrings() { +//   ::std::vector< ::std::string> v; +//   v.push_back("a"); +//   v.push_back("b"); +//   return v; +// } +// +// INSTANTIATE_TEST_CASE_P(CharSequence, +//                         StlStringTest, +//                         ValuesIn(GetParameterStrings())); +// +// +// This will also instantiate tests from CharTest +// each with parameter values 'a' and 'b': +// +// ::std::list<char> GetParameterChars() { +//   ::std::list<char> list; +//   list.push_back('a'); +//   list.push_back('b'); +//   return list; +// } +// ::std::list<char> l = GetParameterChars(); +// INSTANTIATE_TEST_CASE_P(CharSequence2, +//                         CharTest, +//                         ValuesIn(l.begin(), l.end())); +// +template <typename ForwardIterator> +internal::ParamGenerator< +    typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn( +  ForwardIterator begin, +  ForwardIterator end) { +  typedef typename ::std::iterator_traits<ForwardIterator>::value_type +      ParamType; +  return internal::ParamGenerator<ParamType>( +      new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end)); +} + +template <typename T, size_t N> +internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) { +  return ValuesIn(array, array + N); +} + +template <class Container> +internal::ParamGenerator<typename Container::value_type> ValuesIn( +    const Container& container) { +  return ValuesIn(container.begin(), container.end()); +} + +// Values() allows generating tests from explicitly specified list of +// parameters. +// +// Synopsis: +// Values(T v1, T v2, ..., T vN) +//   - returns a generator producing sequences with elements v1, v2, ..., vN. +// +// For example, this instantiates tests from test case BarTest each +// with values "one", "two", and "three": +// +// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); +// +// This instantiates tests from test case BazTest each with values 1, 2, 3.5. +// The exact type of values will depend on the type of parameter in BazTest. +// +// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); +// +// Currently, Values() supports from 1 to 50 parameters. +// +template <typename T1> +internal::ValueArray1<T1> Values(T1 v1) { +  return internal::ValueArray1<T1>(v1); +} + +template <typename T1, typename T2> +internal::ValueArray2<T1, T2> Values(T1 v1, T2 v2) { +  return internal::ValueArray2<T1, T2>(v1, v2); +} + +template <typename T1, typename T2, typename T3> +internal::ValueArray3<T1, T2, T3> Values(T1 v1, T2 v2, T3 v3) { +  return internal::ValueArray3<T1, T2, T3>(v1, v2, v3); +} + +template <typename T1, typename T2, typename T3, typename T4> +internal::ValueArray4<T1, T2, T3, T4> Values(T1 v1, T2 v2, T3 v3, T4 v4) { +  return internal::ValueArray4<T1, T2, T3, T4>(v1, v2, v3, v4); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5> +internal::ValueArray5<T1, T2, T3, T4, T5> Values(T1 v1, T2 v2, T3 v3, T4 v4, +    T5 v5) { +  return internal::ValueArray5<T1, T2, T3, T4, T5>(v1, v2, v3, v4, v5); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6> +internal::ValueArray6<T1, T2, T3, T4, T5, T6> Values(T1 v1, T2 v2, T3 v3, +    T4 v4, T5 v5, T6 v6) { +  return internal::ValueArray6<T1, T2, T3, T4, T5, T6>(v1, v2, v3, v4, v5, v6); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7> +internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7> Values(T1 v1, T2 v2, T3 v3, +    T4 v4, T5 v5, T6 v6, T7 v7) { +  return internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7>(v1, v2, v3, v4, v5, +      v6, v7); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8> +internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8> Values(T1 v1, T2 v2, +    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) { +  return internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8>(v1, v2, v3, v4, +      v5, v6, v7, v8); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9> +internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9> Values(T1 v1, T2 v2, +    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) { +  return internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(v1, v2, v3, +      v4, v5, v6, v7, v8, v9); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10> +internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Values(T1 v1, +    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) { +  return internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(v1, +      v2, v3, v4, v5, v6, v7, v8, v9, v10); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11> +internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, +    T11> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +    T10 v10, T11 v11) { +  return internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, +      T11>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12> +internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +    T12> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +    T10 v10, T11 v11, T12 v12) { +  return internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13> +internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +    T13> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +    T10 v10, T11 v11, T12 v12, T13 v13) { +  return internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14> +internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) { +  return internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, +      v14); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15> +internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, +    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) { +  return internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, +      v13, v14, v15); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16> +internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, +    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, +    T16 v16) { +  return internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, +      v12, v13, v14, v15, v16); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17> +internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, +    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, +    T16 v16, T17 v17) { +  return internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, +      v11, v12, v13, v14, v15, v16, v17); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18> +internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, +    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, +    T16 v16, T17 v17, T18 v18) { +  return internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18>(v1, v2, v3, v4, v5, v6, v7, v8, v9, +      v10, v11, v12, v13, v14, v15, v16, v17, v18); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19> +internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, +    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, +    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) { +  return internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19>(v1, v2, v3, v4, v5, v6, v7, v8, +      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20> +internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20> Values(T1 v1, T2 v2, T3 v3, T4 v4, +    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, +    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) { +  return internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20>(v1, v2, v3, v4, v5, v6, v7, +      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21> +internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21> Values(T1 v1, T2 v2, T3 v3, T4 v4, +    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, +    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) { +  return internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(v1, v2, v3, v4, v5, v6, +      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22> +internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22> Values(T1 v1, T2 v2, T3 v3, +    T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, +    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, +    T21 v21, T22 v22) { +  return internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>(v1, v2, v3, v4, +      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, +      v20, v21, v22); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23> +internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> Values(T1 v1, T2 v2, +    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, +    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, +    T21 v21, T22 v22, T23 v23) { +  return internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>(v1, v2, v3, +      v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, +      v20, v21, v22, v23); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24> +internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Values(T1 v1, T2 v2, +    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, +    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, +    T21 v21, T22 v22, T23 v23, T24 v24) { +  return internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>(v1, v2, +      v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, +      v19, v20, v21, v22, v23, v24); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25> +internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Values(T1 v1, +    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, +    T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, +    T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) { +  return internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25>(v1, +      v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, +      v18, v19, v20, v21, v22, v23, v24, v25); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26> +internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +    T26> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +    T26 v26) { +  return internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, +      v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27> +internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +    T27> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +    T26 v26, T27 v27) { +  return internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, +      v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28> +internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +    T28> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +    T26 v26, T27 v27, T28 v28) { +  return internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, +      v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, +      v28); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29> +internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +    T26 v26, T27 v27, T28 v28, T29 v29) { +  return internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, +      v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, +      v27, v28, v29); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30> +internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, +    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, +    T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, +    T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) { +  return internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, +      v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, +      v26, v27, v28, v29, v30); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31> +internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, +    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, +    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, +    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) { +  return internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, +      v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, +      v25, v26, v27, v28, v29, v30, v31); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32> +internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, +    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, +    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, +    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, +    T32 v32) { +  return internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32>(v1, v2, v3, v4, v5, v6, v7, v8, v9, +      v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, +      v24, v25, v26, v27, v28, v29, v30, v31, v32); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33> +internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, +    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, +    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, +    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, +    T32 v32, T33 v33) { +  return internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32, T33>(v1, v2, v3, v4, v5, v6, v7, v8, +      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, +      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34> +internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33, T34> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, +    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, +    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, +    T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, +    T31 v31, T32 v32, T33 v33, T34 v34) { +  return internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32, T33, T34>(v1, v2, v3, v4, v5, v6, v7, +      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, +      v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35> +internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33, T34, T35> Values(T1 v1, T2 v2, T3 v3, T4 v4, +    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, +    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, +    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, +    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) { +  return internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35>(v1, v2, v3, v4, v5, v6, +      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, +      v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36> +internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33, T34, T35, T36> Values(T1 v1, T2 v2, T3 v3, T4 v4, +    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, +    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, +    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, +    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) { +  return internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36>(v1, v2, v3, v4, +      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, +      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, +      v34, v35, v36); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37> +internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33, T34, T35, T36, T37> Values(T1 v1, T2 v2, T3 v3, +    T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, +    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, +    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, +    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, +    T37 v37) { +  return internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37>(v1, v2, v3, +      v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, +      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, +      v34, v35, v36, v37); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38> +internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Values(T1 v1, T2 v2, +    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, +    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, +    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, +    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, +    T37 v37, T38 v38) { +  return internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38>(v1, v2, +      v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, +      v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, +      v33, v34, v35, v36, v37, v38); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39> +internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Values(T1 v1, T2 v2, +    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, +    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, +    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, +    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, +    T37 v37, T38 v38, T39 v39) { +  return internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39>(v1, +      v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, +      v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, +      v32, v33, v34, v35, v36, v37, v38, v39); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40> +internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Values(T1 v1, +    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, +    T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, +    T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, +    T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, +    T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) { +  return internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, +      T40>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, +      v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, +      v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41> +internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, +    T41> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) { +  return internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, +      T40, T41>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, +      v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, +      v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42> +internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, +    T42> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, +    T42 v42) { +  return internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, +      T40, T41, T42>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, +      v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, +      v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, +      v42); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43> +internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, +    T43> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, +    T42 v42, T43 v43) { +  return internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, +      T40, T41, T42, T43>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, +      v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, +      v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, +      v41, v42, v43); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44> +internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, +    T44> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, +    T42 v42, T43 v43, T44 v44) { +  return internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, +      T40, T41, T42, T43, T44>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, +      v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, +      v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, +      v40, v41, v42, v43, v44); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45> +internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, +    T44, T45> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, +    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, +    T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, +    T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, +    T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, +    T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) { +  return internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, +      T40, T41, T42, T43, T44, T45>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, +      v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, +      v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, +      v39, v40, v41, v42, v43, v44, v45); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46> +internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, +    T44, T45, T46> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, +    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, +    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, +    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, +    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, +    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) { +  return internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, +      T40, T41, T42, T43, T44, T45, T46>(v1, v2, v3, v4, v5, v6, v7, v8, v9, +      v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, +      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, +      v38, v39, v40, v41, v42, v43, v44, v45, v46); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46, typename T47> +internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, +    T44, T45, T46, T47> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, +    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, +    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, +    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, +    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, +    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) { +  return internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, +      T40, T41, T42, T43, T44, T45, T46, T47>(v1, v2, v3, v4, v5, v6, v7, v8, +      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, +      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, +      v38, v39, v40, v41, v42, v43, v44, v45, v46, v47); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46, typename T47, typename T48> +internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, +    T44, T45, T46, T47, T48> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, +    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, +    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, +    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, +    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, +    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, +    T48 v48) { +  return internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, +      T40, T41, T42, T43, T44, T45, T46, T47, T48>(v1, v2, v3, v4, v5, v6, v7, +      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, +      v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, +      v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46, typename T47, typename T48, typename T49> +internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, +    T44, T45, T46, T47, T48, T49> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, +    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, +    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, +    T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, +    T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, +    T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, +    T47 v47, T48 v48, T49 v49) { +  return internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, +      T40, T41, T42, T43, T44, T45, T46, T47, T48, T49>(v1, v2, v3, v4, v5, v6, +      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, +      v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, +      v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46, typename T47, typename T48, typename T49, typename T50> +internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, +    T44, T45, T46, T47, T48, T49, T50> Values(T1 v1, T2 v2, T3 v3, T4 v4, +    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, +    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, +    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, +    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, +    T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, +    T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) { +  return internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, +      T40, T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>(v1, v2, v3, v4, +      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, +      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, +      v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, +      v48, v49, v50); +} + +// Bool() allows generating tests with parameters in a set of (false, true). +// +// Synopsis: +// Bool() +//   - returns a generator producing sequences with elements {false, true}. +// +// It is useful when testing code that depends on Boolean flags. Combinations +// of multiple flags can be tested when several Bool()'s are combined using +// Combine() function. +// +// In the following example all tests in the test case FlagDependentTest +// will be instantiated twice with parameters false and true. +// +// class FlagDependentTest : public testing::TestWithParam<bool> { +//   virtual void SetUp() { +//     external_flag = GetParam(); +//   } +// } +// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); +// +inline internal::ParamGenerator<bool> Bool() { +  return Values(false, true); +} + +#ifdef GTEST_HAS_COMBINE +// Combine() allows the user to combine two or more sequences to produce +// values of a Cartesian product of those sequences' elements. +// +// Synopsis: +// Combine(gen1, gen2, ..., genN) +//   - returns a generator producing sequences with elements coming from +//     the Cartesian product of elements from the sequences generated by +//     gen1, gen2, ..., genN. The sequence elements will have a type of +//     tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types +//     of elements from sequences produces by gen1, gen2, ..., genN. +// +// Combine can have up to 10 arguments. This number is currently limited +// by the maximum number of elements in the tuple implementation used by Google +// Test. +// +// Example: +// +// This will instantiate tests in test case AnimalTest each one with +// the parameter values tuple("cat", BLACK), tuple("cat", WHITE), +// tuple("dog", BLACK), and tuple("dog", WHITE): +// +// enum Color { BLACK, GRAY, WHITE }; +// class AnimalTest +//     : public testing::TestWithParam<tuple<const char*, Color> > {...}; +// +// TEST_P(AnimalTest, AnimalLooksNice) {...} +// +// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, +//                         Combine(Values("cat", "dog"), +//                                 Values(BLACK, WHITE))); +// +// This will instantiate tests in FlagDependentTest with all variations of two +// Boolean flags: +// +// class FlagDependentTest +//     : public testing::TestWithParam<tuple(bool, bool)> > { +//   virtual void SetUp() { +//     // Assigns external_flag_1 and external_flag_2 values from the tuple. +//     tie(external_flag_1, external_flag_2) = GetParam(); +//   } +// }; +// +// TEST_P(FlagDependentTest, TestFeature1) { +//   // Test your code using external_flag_1 and external_flag_2 here. +// } +// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, +//                         Combine(Bool(), Bool())); +// +template <typename Generator1, typename Generator2> +internal::CartesianProductHolder2<Generator1, Generator2> Combine( +    const Generator1& g1, const Generator2& g2) { +  return internal::CartesianProductHolder2<Generator1, Generator2>( +      g1, g2); +} + +template <typename Generator1, typename Generator2, typename Generator3> +internal::CartesianProductHolder3<Generator1, Generator2, Generator3> Combine( +    const Generator1& g1, const Generator2& g2, const Generator3& g3) { +  return internal::CartesianProductHolder3<Generator1, Generator2, Generator3>( +      g1, g2, g3); +} + +template <typename Generator1, typename Generator2, typename Generator3, +    typename Generator4> +internal::CartesianProductHolder4<Generator1, Generator2, Generator3, +    Generator4> Combine( +    const Generator1& g1, const Generator2& g2, const Generator3& g3, +        const Generator4& g4) { +  return internal::CartesianProductHolder4<Generator1, Generator2, Generator3, +      Generator4>( +      g1, g2, g3, g4); +} + +template <typename Generator1, typename Generator2, typename Generator3, +    typename Generator4, typename Generator5> +internal::CartesianProductHolder5<Generator1, Generator2, Generator3, +    Generator4, Generator5> Combine( +    const Generator1& g1, const Generator2& g2, const Generator3& g3, +        const Generator4& g4, const Generator5& g5) { +  return internal::CartesianProductHolder5<Generator1, Generator2, Generator3, +      Generator4, Generator5>( +      g1, g2, g3, g4, g5); +} + +template <typename Generator1, typename Generator2, typename Generator3, +    typename Generator4, typename Generator5, typename Generator6> +internal::CartesianProductHolder6<Generator1, Generator2, Generator3, +    Generator4, Generator5, Generator6> Combine( +    const Generator1& g1, const Generator2& g2, const Generator3& g3, +        const Generator4& g4, const Generator5& g5, const Generator6& g6) { +  return internal::CartesianProductHolder6<Generator1, Generator2, Generator3, +      Generator4, Generator5, Generator6>( +      g1, g2, g3, g4, g5, g6); +} + +template <typename Generator1, typename Generator2, typename Generator3, +    typename Generator4, typename Generator5, typename Generator6, +    typename Generator7> +internal::CartesianProductHolder7<Generator1, Generator2, Generator3, +    Generator4, Generator5, Generator6, Generator7> Combine( +    const Generator1& g1, const Generator2& g2, const Generator3& g3, +        const Generator4& g4, const Generator5& g5, const Generator6& g6, +        const Generator7& g7) { +  return internal::CartesianProductHolder7<Generator1, Generator2, Generator3, +      Generator4, Generator5, Generator6, Generator7>( +      g1, g2, g3, g4, g5, g6, g7); +} + +template <typename Generator1, typename Generator2, typename Generator3, +    typename Generator4, typename Generator5, typename Generator6, +    typename Generator7, typename Generator8> +internal::CartesianProductHolder8<Generator1, Generator2, Generator3, +    Generator4, Generator5, Generator6, Generator7, Generator8> Combine( +    const Generator1& g1, const Generator2& g2, const Generator3& g3, +        const Generator4& g4, const Generator5& g5, const Generator6& g6, +        const Generator7& g7, const Generator8& g8) { +  return internal::CartesianProductHolder8<Generator1, Generator2, Generator3, +      Generator4, Generator5, Generator6, Generator7, Generator8>( +      g1, g2, g3, g4, g5, g6, g7, g8); +} + +template <typename Generator1, typename Generator2, typename Generator3, +    typename Generator4, typename Generator5, typename Generator6, +    typename Generator7, typename Generator8, typename Generator9> +internal::CartesianProductHolder9<Generator1, Generator2, Generator3, +    Generator4, Generator5, Generator6, Generator7, Generator8, +    Generator9> Combine( +    const Generator1& g1, const Generator2& g2, const Generator3& g3, +        const Generator4& g4, const Generator5& g5, const Generator6& g6, +        const Generator7& g7, const Generator8& g8, const Generator9& g9) { +  return internal::CartesianProductHolder9<Generator1, Generator2, Generator3, +      Generator4, Generator5, Generator6, Generator7, Generator8, Generator9>( +      g1, g2, g3, g4, g5, g6, g7, g8, g9); +} + +template <typename Generator1, typename Generator2, typename Generator3, +    typename Generator4, typename Generator5, typename Generator6, +    typename Generator7, typename Generator8, typename Generator9, +    typename Generator10> +internal::CartesianProductHolder10<Generator1, Generator2, Generator3, +    Generator4, Generator5, Generator6, Generator7, Generator8, Generator9, +    Generator10> Combine( +    const Generator1& g1, const Generator2& g2, const Generator3& g3, +        const Generator4& g4, const Generator5& g5, const Generator6& g6, +        const Generator7& g7, const Generator8& g8, const Generator9& g9, +        const Generator10& g10) { +  return internal::CartesianProductHolder10<Generator1, Generator2, Generator3, +      Generator4, Generator5, Generator6, Generator7, Generator8, Generator9, +      Generator10>( +      g1, g2, g3, g4, g5, g6, g7, g8, g9, g10); +} +#endif  // GTEST_HAS_COMBINE + + + +#define TEST_P(test_case_name, test_name) \ +  class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ +      : public test_case_name { \ +   public: \ +    GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ +    virtual void TestBody(); \ +   private: \ +    static int AddToRegistry() { \ +      ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ +          GetTestCasePatternHolder<test_case_name>(\ +              #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ +                  #test_case_name, \ +                  #test_name, \ +                  new ::testing::internal::TestMetaFactory< \ +                      GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ +      return 0; \ +    } \ +    static int gtest_registering_dummy_; \ +    GTEST_DISALLOW_COPY_AND_ASSIGN_(\ +        GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ +  }; \ +  int GTEST_TEST_CLASS_NAME_(test_case_name, \ +                             test_name)::gtest_registering_dummy_ = \ +      GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ +  void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +#define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ +  ::testing::internal::ParamGenerator<test_case_name::ParamType> \ +      gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ +  int gtest_##prefix##test_case_name##_dummy_ = \ +      ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ +          GetTestCasePatternHolder<test_case_name>(\ +              #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ +                  #prefix, \ +                  >est_##prefix##test_case_name##_EvalGenerator_, \ +                  __FILE__, __LINE__) + +}  // namespace testing + +#endif  // GTEST_HAS_PARAM_TEST + +#endif  // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ diff --git a/llvm/utils/unittest/googletest/include/gtest/gtest-spi.h b/llvm/utils/unittest/googletest/include/gtest/gtest-spi.h new file mode 100644 index 00000000000..a4e387a3126 --- /dev/null +++ b/llvm/utils/unittest/googletest/include/gtest/gtest-spi.h @@ -0,0 +1,221 @@ +// Copyright 2007, 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) +// +// Utilities for testing Google Test itself and code that uses Google Test +// (e.g. frameworks built on top of Google Test). + +#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ +#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ + +#include <gtest/gtest.h> + +namespace testing { + +// This helper class can be used to mock out Google Test failure reporting +// so that we can test Google Test or code that builds on Google Test. +// +// An object of this class appends a TestPartResult object to the +// TestPartResultArray object given in the constructor whenever a Google Test +// failure is reported. It can either intercept only failures that are +// generated in the same thread that created this object or it can intercept +// all generated failures. The scope of this mock object can be controlled with +// the second argument to the two arguments constructor. +class ScopedFakeTestPartResultReporter +    : public TestPartResultReporterInterface { + public: +  // The two possible mocking modes of this object. +  enum InterceptMode { +    INTERCEPT_ONLY_CURRENT_THREAD,  // Intercepts only thread local failures. +    INTERCEPT_ALL_THREADS           // Intercepts all failures. +  }; + +  // The c'tor sets this object as the test part result reporter used +  // by Google Test.  The 'result' parameter specifies where to report the +  // results. This reporter will only catch failures generated in the current +  // thread. DEPRECATED +  explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); + +  // Same as above, but you can choose the interception scope of this object. +  ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, +                                   TestPartResultArray* result); + +  // The d'tor restores the previous test part result reporter. +  virtual ~ScopedFakeTestPartResultReporter(); + +  // Appends the TestPartResult object to the TestPartResultArray +  // received in the constructor. +  // +  // This method is from the TestPartResultReporterInterface +  // interface. +  virtual void ReportTestPartResult(const TestPartResult& result); + private: +  void Init(); + +  const InterceptMode intercept_mode_; +  TestPartResultReporterInterface* old_reporter_; +  TestPartResultArray* const result_; + +  GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); +}; + +namespace internal { + +// A helper class for implementing EXPECT_FATAL_FAILURE() and +// EXPECT_NONFATAL_FAILURE().  Its destructor verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring.  If that's not the case, a +// non-fatal failure will be generated. +class SingleFailureChecker { + public: +  // The constructor remembers the arguments. +  SingleFailureChecker(const TestPartResultArray* results, +                       TestPartResultType type, +                       const char* substr); +  ~SingleFailureChecker(); + private: +  const TestPartResultArray* const results_; +  const TestPartResultType type_; +  const String substr_; + +  GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); +}; + +}  // namespace internal + +}  // namespace testing + +// A set of macros for testing Google Test assertions or code that's expected +// to generate Google Test fatal failures.  It verifies that the given +// statement will cause exactly one fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_FATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +//   - 'statement' cannot reference local non-static variables or +//     non-static members of the current object. +//   - 'statement' cannot return a value. +//   - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works.  The AcceptsMacroThatExpandsToUnprotectedComma test in +// gtest_unittest.cc will fail to compile if we do that. +#define EXPECT_FATAL_FAILURE(statement, substr) \ +  do { \ +    class GTestExpectFatalFailureHelper {\ +     public:\ +      static void Execute() { statement; }\ +    };\ +    ::testing::TestPartResultArray gtest_failures;\ +    ::testing::internal::SingleFailureChecker gtest_checker(\ +        >est_failures, ::testing::TPRT_FATAL_FAILURE, (substr));\ +    {\ +      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ +          ::testing::ScopedFakeTestPartResultReporter:: \ +          INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ +      GTestExpectFatalFailureHelper::Execute();\ +    }\ +  } while (false) + +#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ +  do { \ +    class GTestExpectFatalFailureHelper {\ +     public:\ +      static void Execute() { statement; }\ +    };\ +    ::testing::TestPartResultArray gtest_failures;\ +    ::testing::internal::SingleFailureChecker gtest_checker(\ +        >est_failures, ::testing::TPRT_FATAL_FAILURE, (substr));\ +    {\ +      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ +          ::testing::ScopedFakeTestPartResultReporter:: \ +          INTERCEPT_ALL_THREADS, >est_failures);\ +      GTestExpectFatalFailureHelper::Execute();\ +    }\ +  } while (false) + +// A macro for testing Google Test assertions or code that's expected to +// generate Google Test non-fatal failures.  It asserts that the given +// statement will cause exactly one non-fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// 'statement' is allowed to reference local variables and members of +// the current object. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +//   - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works.  The AcceptsMacroThatExpandsToUnprotectedComma test in +// gtest_unittest.cc will fail to compile if we do that. +#define EXPECT_NONFATAL_FAILURE(statement, substr) \ +  do {\ +    ::testing::TestPartResultArray gtest_failures;\ +    ::testing::internal::SingleFailureChecker gtest_checker(\ +        >est_failures, ::testing::TPRT_NONFATAL_FAILURE, (substr));\ +    {\ +      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ +          ::testing::ScopedFakeTestPartResultReporter:: \ +          INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ +      statement;\ +    }\ +  } while (false) + +#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ +  do {\ +    ::testing::TestPartResultArray gtest_failures;\ +    ::testing::internal::SingleFailureChecker gtest_checker(\ +        >est_failures, ::testing::TPRT_NONFATAL_FAILURE, (substr));\ +    {\ +      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ +          ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS,\ +          >est_failures);\ +      statement;\ +    }\ +  } while (false) + +#endif  // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ diff --git a/llvm/utils/unittest/googletest/include/gtest/gtest-test-part.h b/llvm/utils/unittest/googletest/include/gtest/gtest-test-part.h new file mode 100644 index 00000000000..1a281afb32a --- /dev/null +++ b/llvm/utils/unittest/googletest/include/gtest/gtest-test-part.h @@ -0,0 +1,179 @@ +// Copyright 2008, 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: mheule@google.com (Markus Heule) +// + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ + +#include <iosfwd> +#include <gtest/internal/gtest-internal.h> +#include <gtest/internal/gtest-string.h> + +namespace testing { + +// The possible outcomes of a test part (i.e. an assertion or an +// explicit SUCCEED(), FAIL(), or ADD_FAILURE()). +enum TestPartResultType { +  TPRT_SUCCESS,           // Succeeded. +  TPRT_NONFATAL_FAILURE,  // Failed but the test can continue. +  TPRT_FATAL_FAILURE      // Failed and the test should be terminated. +}; + +// A copyable object representing the result of a test part (i.e. an +// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). +// +// Don't inherit from TestPartResult as its destructor is not virtual. +class TestPartResult { + public: +  // C'tor.  TestPartResult does NOT have a default constructor. +  // Always use this constructor (with parameters) to create a +  // TestPartResult object. +  TestPartResult(TestPartResultType type, +                 const char* file_name, +                 int line_number, +                 const char* message) +      : type_(type), +        file_name_(file_name), +        line_number_(line_number), +        summary_(ExtractSummary(message)), +        message_(message) { +  } + +  // Gets the outcome of the test part. +  TestPartResultType type() const { return type_; } + +  // Gets the name of the source file where the test part took place, or +  // NULL if it's unknown. +  const char* file_name() const { return file_name_.c_str(); } + +  // Gets the line in the source file where the test part took place, +  // or -1 if it's unknown. +  int line_number() const { return line_number_; } + +  // Gets the summary of the failure message. +  const char* summary() const { return summary_.c_str(); } + +  // Gets the message associated with the test part. +  const char* message() const { return message_.c_str(); } + +  // Returns true iff the test part passed. +  bool passed() const { return type_ == TPRT_SUCCESS; } + +  // Returns true iff the test part failed. +  bool failed() const { return type_ != TPRT_SUCCESS; } + +  // Returns true iff the test part non-fatally failed. +  bool nonfatally_failed() const { return type_ == TPRT_NONFATAL_FAILURE; } + +  // Returns true iff the test part fatally failed. +  bool fatally_failed() const { return type_ == TPRT_FATAL_FAILURE; } + private: +  TestPartResultType type_; + +  // Gets the summary of the failure message by omitting the stack +  // trace in it. +  static internal::String ExtractSummary(const char* message); + +  // The name of the source file where the test part took place, or +  // NULL if the source file is unknown. +  internal::String file_name_; +  // The line in the source file where the test part took place, or -1 +  // if the line number is unknown. +  int line_number_; +  internal::String summary_;  // The test failure summary. +  internal::String message_;  // The test failure message. +}; + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result); + +// An array of TestPartResult objects. +// +// We define this class as we cannot use STL containers when compiling +// Google Test with MSVC 7.1 and exceptions disabled. +// +// Don't inherit from TestPartResultArray as its destructor is not +// virtual. +class TestPartResultArray { + public: +  TestPartResultArray(); +  ~TestPartResultArray(); + +  // Appends the given TestPartResult to the array. +  void Append(const TestPartResult& result); + +  // Returns the TestPartResult at the given index (0-based). +  const TestPartResult& GetTestPartResult(int index) const; + +  // Returns the number of TestPartResult objects in the array. +  int size() const; + private: +  // Internally we use a list to simulate the array.  Yes, this means +  // that random access is O(N) in time, but it's OK for its purpose. +  internal::List<TestPartResult>* const list_; + +  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); +}; + +// This interface knows how to report a test part result. +class TestPartResultReporterInterface { + public: +  virtual ~TestPartResultReporterInterface() {} + +  virtual void ReportTestPartResult(const TestPartResult& result) = 0; +}; + +namespace internal { + +// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a +// statement generates new fatal failures. To do so it registers itself as the +// current test part result reporter. Besides checking if fatal failures were +// reported, it only delegates the reporting to the former result reporter. +// The original result reporter is restored in the destructor. +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +class HasNewFatalFailureHelper : public TestPartResultReporterInterface { + public: +  HasNewFatalFailureHelper(); +  virtual ~HasNewFatalFailureHelper(); +  virtual void ReportTestPartResult(const TestPartResult& result); +  bool has_new_fatal_failure() const { return has_new_fatal_failure_; } + private: +  bool has_new_fatal_failure_; +  TestPartResultReporterInterface* original_reporter_; + +  GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); +}; + +}  // namespace internal + +}  // namespace testing + +#endif  // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ diff --git a/llvm/utils/unittest/googletest/include/gtest/gtest-typed-test.h b/llvm/utils/unittest/googletest/include/gtest/gtest-typed-test.h new file mode 100644 index 00000000000..dec42cf4701 --- /dev/null +++ b/llvm/utils/unittest/googletest/include/gtest/gtest-typed-test.h @@ -0,0 +1,253 @@ +// Copyright 2008 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) + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ + +// This header implements typed tests and type-parameterized tests. + +// Typed (aka type-driven) tests repeat the same test for types in a +// list.  You must know which types you want to test with when writing +// typed tests. Here's how you do it: + +#if 0 + +// First, define a fixture class template.  It should be parameterized +// by a type.  Remember to derive it from testing::Test. +template <typename T> +class FooTest : public testing::Test { + public: +  ... +  typedef std::list<T> List; +  static T shared_; +  T value_; +}; + +// Next, associate a list of types with the test case, which will be +// repeated for each type in the list.  The typedef is necessary for +// the macro to parse correctly. +typedef testing::Types<char, int, unsigned int> MyTypes; +TYPED_TEST_CASE(FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +//   TYPED_TEST_CASE(FooTest, int); + +// Then, use TYPED_TEST() instead of TEST_F() to define as many typed +// tests for this test case as you want. +TYPED_TEST(FooTest, DoesBlah) { +  // Inside a test, refer to TypeParam to get the type parameter. +  // Since we are inside a derived class template, C++ requires use to +  // visit the members of FooTest via 'this'. +  TypeParam n = this->value_; + +  // To visit static members of the fixture, add the TestFixture:: +  // prefix. +  n += TestFixture::shared_; + +  // To refer to typedefs in the fixture, add the "typename +  // TestFixture::" prefix. +  typename TestFixture::List values; +  values.push_back(n); +  ... +} + +TYPED_TEST(FooTest, HasPropertyA) { ... } + +#endif  // 0 + +// Type-parameterized tests are abstract test patterns parameterized +// by a type.  Compared with typed tests, type-parameterized tests +// allow you to define the test pattern without knowing what the type +// parameters are.  The defined pattern can be instantiated with +// different types any number of times, in any number of translation +// units. +// +// If you are designing an interface or concept, you can define a +// suite of type-parameterized tests to verify properties that any +// valid implementation of the interface/concept should have.  Then, +// each implementation can easily instantiate the test suite to verify +// that it conforms to the requirements, without having to write +// similar tests repeatedly.  Here's an example: + +#if 0 + +// First, define a fixture class template.  It should be parameterized +// by a type.  Remember to derive it from testing::Test. +template <typename T> +class FooTest : public testing::Test { +  ... +}; + +// Next, declare that you will define a type-parameterized test case +// (the _P suffix is for "parameterized" or "pattern", whichever you +// prefer): +TYPED_TEST_CASE_P(FooTest); + +// Then, use TYPED_TEST_P() to define as many type-parameterized tests +// for this type-parameterized test case as you want. +TYPED_TEST_P(FooTest, DoesBlah) { +  // Inside a test, refer to TypeParam to get the type parameter. +  TypeParam n = 0; +  ... +} + +TYPED_TEST_P(FooTest, HasPropertyA) { ... } + +// Now the tricky part: you need to register all test patterns before +// you can instantiate them.  The first argument of the macro is the +// test case name; the rest are the names of the tests in this test +// case. +REGISTER_TYPED_TEST_CASE_P(FooTest, +                           DoesBlah, HasPropertyA); + +// Finally, you are free to instantiate the pattern with the types you +// want.  If you put the above code in a header file, you can #include +// it in multiple C++ source files and instantiate it multiple times. +// +// To distinguish different instances of the pattern, the first +// argument to the INSTANTIATE_* macro is a prefix that will be added +// to the actual test case name.  Remember to pick unique prefixes for +// different instances. +typedef testing::Types<char, int, unsigned int> MyTypes; +INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +//   INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int); + +#endif  // 0 + +#include <gtest/internal/gtest-port.h> +#include <gtest/internal/gtest-type-util.h> + +// Implements typed tests. + +#ifdef GTEST_HAS_TYPED_TEST + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the typedef for the type parameters of the +// given test case. +#define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ + +#define TYPED_TEST_CASE(CaseName, Types) \ +  typedef ::testing::internal::TypeList<Types>::type \ +      GTEST_TYPE_PARAMS_(CaseName) + +#define TYPED_TEST(CaseName, TestName) \ +  template <typename gtest_TypeParam_> \ +  class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ +      : public CaseName<gtest_TypeParam_> { \ +   private: \ +    typedef CaseName<gtest_TypeParam_> TestFixture; \ +    typedef gtest_TypeParam_ TypeParam; \ +    virtual void TestBody(); \ +  }; \ +  bool gtest_##CaseName##_##TestName##_registered_ = \ +      ::testing::internal::TypeParameterizedTest< \ +          CaseName, \ +          ::testing::internal::TemplateSel< \ +              GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ +          GTEST_TYPE_PARAMS_(CaseName)>::Register(\ +              "", #CaseName, #TestName, 0); \ +  template <typename gtest_TypeParam_> \ +  void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody() + +#endif  // GTEST_HAS_TYPED_TEST + +// Implements type-parameterized tests. + +#ifdef GTEST_HAS_TYPED_TEST_P + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the namespace name that the type-parameterized tests for +// the given type-parameterized test case are defined in.  The exact +// name of the namespace is subject to change without notice. +#define GTEST_CASE_NAMESPACE_(TestCaseName) \ +  gtest_case_##TestCaseName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the variable used to remember the names of +// the defined tests in the given test case. +#define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ +  gtest_typed_test_case_p_state_##TestCaseName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. +// +// Expands to the name of the variable used to remember the names of +// the registered tests in the given test case. +#define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ +  gtest_registered_test_names_##TestCaseName##_ + +// The variables defined in the type-parameterized test macros are +// static as typically these macros are used in a .h file that can be +// #included in multiple translation units linked together. +#define TYPED_TEST_CASE_P(CaseName) \ +  static ::testing::internal::TypedTestCasePState \ +      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) + +#define TYPED_TEST_P(CaseName, TestName) \ +  namespace GTEST_CASE_NAMESPACE_(CaseName) { \ +  template <typename gtest_TypeParam_> \ +  class TestName : public CaseName<gtest_TypeParam_> { \ +   private: \ +    typedef CaseName<gtest_TypeParam_> TestFixture; \ +    typedef gtest_TypeParam_ TypeParam; \ +    virtual void TestBody(); \ +  }; \ +  static bool gtest_##TestName##_defined_ = \ +      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ +          __FILE__, __LINE__, #CaseName, #TestName); \ +  } \ +  template <typename gtest_TypeParam_> \ +  void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody() + +#define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ +  namespace GTEST_CASE_NAMESPACE_(CaseName) { \ +  typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ +  } \ +  static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ +      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ +          __FILE__, __LINE__, #__VA_ARGS__) + +#define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ +  bool gtest_##Prefix##_##CaseName = \ +      ::testing::internal::TypeParameterizedTestCase<CaseName, \ +          GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \ +          ::testing::internal::TypeList<Types>::type>::Register(\ +              #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) + +#endif  // GTEST_HAS_TYPED_TEST_P + +#endif  // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ diff --git a/llvm/utils/unittest/googletest/include/gtest/gtest.h b/llvm/utils/unittest/googletest/include/gtest/gtest.h new file mode 100644 index 00000000000..ebd3123b043 --- /dev/null +++ b/llvm/utils/unittest/googletest/include/gtest/gtest.h @@ -0,0 +1,1317 @@ +// Copyright 2005, 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) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the public API for Google Test.  It should be +// included by any test program that uses Google Test. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +//   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user +// program! +// +// Acknowledgment: Google Test borrowed the idea of automatic test +// registration from Barthelemy Dagenais' (barthelemy@prologique.com) +// easyUnit framework. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_H_ + +// The following platform macros are used throughout Google Test: +//   _WIN32_WCE      Windows CE     (set in project files) +// +// Note that even though _MSC_VER and _WIN32_WCE really indicate a compiler +// and a Win32 implementation, respectively, we use them to indicate the +// combination of compiler - Win 32 API - C library, since the code currently +// only supports: +// Windows proper with Visual C++ and MS C library (_MSC_VER && !_WIN32_WCE) and +// Windows Mobile with Visual C++ and no C library (_WIN32_WCE). + +#include <limits> +#include <gtest/internal/gtest-internal.h> +#include <gtest/internal/gtest-string.h> +#include <gtest/gtest-death-test.h> +#include <gtest/gtest-message.h> +#include <gtest/gtest-param-test.h> +#include <gtest/gtest_prod.h> +#include <gtest/gtest-test-part.h> +#include <gtest/gtest-typed-test.h> + +// Depending on the platform, different string classes are available. +// On Windows, ::std::string compiles only when exceptions are +// enabled.  On Linux, in addition to ::std::string, Google also makes +// use of class ::string, which has the same interface as +// ::std::string, but has a different implementation. +// +// The user can tell us whether ::std::string is available in his +// environment by defining the macro GTEST_HAS_STD_STRING to either 1 +// or 0 on the compiler command line.  He can also define +// GTEST_HAS_GLOBAL_STRING to 1 to indicate that ::string is available +// AND is a distinct type to ::std::string, or define it to 0 to +// indicate otherwise. +// +// If the user's ::std::string and ::string are the same class due to +// aliasing, he should define GTEST_HAS_STD_STRING to 1 and +// GTEST_HAS_GLOBAL_STRING to 0. +// +// If the user doesn't define GTEST_HAS_STD_STRING and/or +// GTEST_HAS_GLOBAL_STRING, they are defined heuristically. + +namespace testing { + +// The upper limit for valid stack trace depths. +const int kMaxStackTraceDepth = 100; + +// This flag specifies the maximum number of stack frames to be +// printed in a failure message. +GTEST_DECLARE_int32_(stack_trace_depth); + +// This flag controls whether Google Test includes Google Test internal +// stack frames in failure stack traces. +GTEST_DECLARE_bool_(show_internal_stack_frames); + +namespace internal { + +class GTestFlagSaver; + +// Converts a streamable value to a String.  A NULL pointer is +// converted to "(null)".  When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". +// Declared in gtest-internal.h but defined here, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template <typename T> +String StreamableToString(const T& streamable) { +  return (Message() << streamable).GetString(); +} + +}  // namespace internal + +// A class for indicating whether an assertion was successful.  When +// the assertion wasn't successful, the AssertionResult object +// remembers a non-empty message that described how it failed. +// +// This class is useful for defining predicate-format functions to be +// used with predicate assertions (ASSERT_PRED_FORMAT*, etc). +// +// The constructor of AssertionResult is private.  To create an +// instance of this class, use one of the factory functions +// (AssertionSuccess() and AssertionFailure()). +// +// For example, in order to be able to write: +// +//   // Verifies that Foo() returns an even number. +//   EXPECT_PRED_FORMAT1(IsEven, Foo()); +// +// you just need to define: +// +//   testing::AssertionResult IsEven(const char* expr, int n) { +//     if ((n % 2) == 0) return testing::AssertionSuccess(); +// +//     Message msg; +//     msg << "Expected: " << expr << " is even\n" +//         << "  Actual: it's " << n; +//     return testing::AssertionFailure(msg); +//   } +// +// If Foo() returns 5, you will see the following message: +// +//   Expected: Foo() is even +//     Actual: it's 5 +class AssertionResult { + public: +  // Declares factory functions for making successful and failed +  // assertion results as friends. +  friend AssertionResult AssertionSuccess(); +  friend AssertionResult AssertionFailure(const Message&); + +  // Returns true iff the assertion succeeded. +  operator bool() const { return failure_message_.c_str() == NULL; }  // NOLINT + +  // Returns the assertion's failure message. +  const char* failure_message() const { return failure_message_.c_str(); } + + private: +  // The default constructor.  It is used when the assertion succeeded. +  AssertionResult() {} + +  // The constructor used when the assertion failed. +  explicit AssertionResult(const internal::String& failure_message); + +  // Stores the assertion's failure message. +  internal::String failure_message_; +}; + +// Makes a successful assertion result. +AssertionResult AssertionSuccess(); + +// Makes a failed assertion result with the given failure message. +AssertionResult AssertionFailure(const Message& msg); + +// The abstract class that all tests inherit from. +// +// In Google Test, a unit test program contains one or many TestCases, and +// each TestCase contains one or many Tests. +// +// When you define a test using the TEST macro, you don't need to +// explicitly derive from Test - the TEST macro automatically does +// this for you. +// +// The only time you derive from Test is when defining a test fixture +// to be used a TEST_F.  For example: +// +//   class FooTest : public testing::Test { +//    protected: +//     virtual void SetUp() { ... } +//     virtual void TearDown() { ... } +//     ... +//   }; +// +//   TEST_F(FooTest, Bar) { ... } +//   TEST_F(FooTest, Baz) { ... } +// +// Test is not copyable. +class Test { + public: +  friend class internal::TestInfoImpl; + +  // Defines types for pointers to functions that set up and tear down +  // a test case. +  typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc; +  typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc; + +  // The d'tor is virtual as we intend to inherit from Test. +  virtual ~Test(); + +  // Sets up the stuff shared by all tests in this test case. +  // +  // Google Test will call Foo::SetUpTestCase() before running the first +  // test in test case Foo.  Hence a sub-class can define its own +  // SetUpTestCase() method to shadow the one defined in the super +  // class. +  static void SetUpTestCase() {} + +  // Tears down the stuff shared by all tests in this test case. +  // +  // Google Test will call Foo::TearDownTestCase() after running the last +  // test in test case Foo.  Hence a sub-class can define its own +  // TearDownTestCase() method to shadow the one defined in the super +  // class. +  static void TearDownTestCase() {} + +  // Returns true iff the current test has a fatal failure. +  static bool HasFatalFailure(); + +  // Logs a property for the current test.  Only the last value for a given +  // key is remembered. +  // These are public static so they can be called from utility functions +  // that are not members of the test fixture. +  // The arguments are const char* instead strings, as Google Test is used +  // on platforms where string doesn't compile. +  // +  // Note that a driving consideration for these RecordProperty methods +  // was to produce xml output suited to the Greenspan charting utility, +  // which at present will only chart values that fit in a 32-bit int. It +  // is the user's responsibility to restrict their values to 32-bit ints +  // if they intend them to be used with Greenspan. +  static void RecordProperty(const char* key, const char* value); +  static void RecordProperty(const char* key, int value); + + protected: +  // Creates a Test object. +  Test(); + +  // Sets up the test fixture. +  virtual void SetUp(); + +  // Tears down the test fixture. +  virtual void TearDown(); + + private: +  // Returns true iff the current test has the same fixture class as +  // the first test in the current test case. +  static bool HasSameFixtureClass(); + +  // Runs the test after the test fixture has been set up. +  // +  // A sub-class must implement this to define the test logic. +  // +  // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. +  // Instead, use the TEST or TEST_F macro. +  virtual void TestBody() = 0; + +  // Sets up, executes, and tears down the test. +  void Run(); + +  // Uses a GTestFlagSaver to save and restore all Google Test flags. +  const internal::GTestFlagSaver* const gtest_flag_saver_; + +  // Often a user mis-spells SetUp() as Setup() and spends a long time +  // wondering why it is never called by Google Test.  The declaration of +  // the following method is solely for catching such an error at +  // compile time: +  // +  //   - The return type is deliberately chosen to be not void, so it +  //   will be a conflict if a user declares void Setup() in his test +  //   fixture. +  // +  //   - This method is private, so it will be another compiler error +  //   if a user calls it from his test fixture. +  // +  // DO NOT OVERRIDE THIS FUNCTION. +  // +  // If you see an error about overriding the following function or +  // about it being private, you have mis-spelled SetUp() as Setup(). +  struct Setup_should_be_spelled_SetUp {}; +  virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } + +  // We disallow copying Tests. +  GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); +}; + + +// A TestInfo object stores the following information about a test: +// +//   Test case name +//   Test name +//   Whether the test should be run +//   A function pointer that creates the test object when invoked +//   Test result +// +// The constructor of TestInfo registers itself with the UnitTest +// singleton such that the RUN_ALL_TESTS() macro knows which tests to +// run. +class TestInfo { + public: +  // Destructs a TestInfo object.  This function is not virtual, so +  // don't inherit from TestInfo. +  ~TestInfo(); + +  // Returns the test case name. +  const char* test_case_name() const; + +  // Returns the test name. +  const char* name() const; + +  // Returns the test case comment. +  const char* test_case_comment() const; + +  // Returns the test comment. +  const char* comment() const; + +  // Returns true if this test should run. +  // +  // Google Test allows the user to filter the tests by their full names. +  // The full name of a test Bar in test case Foo is defined as +  // "Foo.Bar".  Only the tests that match the filter will run. +  // +  // A filter is a colon-separated list of glob (not regex) patterns, +  // optionally followed by a '-' and a colon-separated list of +  // negative patterns (tests to exclude).  A test is run if it +  // matches one of the positive patterns and does not match any of +  // the negative patterns. +  // +  // For example, *A*:Foo.* is a filter that matches any string that +  // contains the character 'A' or starts with "Foo.". +  bool should_run() const; + +  // Returns the result of the test. +  const internal::TestResult* result() const; + private: +#ifdef GTEST_HAS_DEATH_TEST +  friend class internal::DefaultDeathTestFactory; +#endif  // GTEST_HAS_DEATH_TEST +  friend class internal::TestInfoImpl; +  friend class internal::UnitTestImpl; +  friend class Test; +  friend class TestCase; +  friend TestInfo* internal::MakeAndRegisterTestInfo( +      const char* test_case_name, const char* name, +      const char* test_case_comment, const char* comment, +      internal::TypeId fixture_class_id, +      Test::SetUpTestCaseFunc set_up_tc, +      Test::TearDownTestCaseFunc tear_down_tc, +      internal::TestFactoryBase* factory); + +  // Increments the number of death tests encountered in this test so +  // far. +  int increment_death_test_count(); + +  // Accessors for the implementation object. +  internal::TestInfoImpl* impl() { return impl_; } +  const internal::TestInfoImpl* impl() const { return impl_; } + +  // Constructs a TestInfo object. The newly constructed instance assumes +  // ownership of the factory object. +  TestInfo(const char* test_case_name, const char* name, +           const char* test_case_comment, const char* comment, +           internal::TypeId fixture_class_id, +           internal::TestFactoryBase* factory); + +  // An opaque implementation object. +  internal::TestInfoImpl* impl_; + +  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); +}; + +// An Environment object is capable of setting up and tearing down an +// environment.  The user should subclass this to define his own +// environment(s). +// +// An Environment object does the set-up and tear-down in virtual +// methods SetUp() and TearDown() instead of the constructor and the +// destructor, as: +// +//   1. You cannot safely throw from a destructor.  This is a problem +//      as in some cases Google Test is used where exceptions are enabled, and +//      we may want to implement ASSERT_* using exceptions where they are +//      available. +//   2. You cannot use ASSERT_* directly in a constructor or +//      destructor. +class Environment { + public: +  // The d'tor is virtual as we need to subclass Environment. +  virtual ~Environment() {} + +  // Override this to define how to set up the environment. +  virtual void SetUp() {} + +  // Override this to define how to tear down the environment. +  virtual void TearDown() {} + private: +  // If you see an error about overriding the following function or +  // about it being private, you have mis-spelled SetUp() as Setup(). +  struct Setup_should_be_spelled_SetUp {}; +  virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } +}; + +// A UnitTest consists of a list of TestCases. +// +// This is a singleton class.  The only instance of UnitTest is +// created when UnitTest::GetInstance() is first called.  This +// instance is never deleted. +// +// UnitTest is not copyable. +// +// This class is thread-safe as long as the methods are called +// according to their specification. +class UnitTest { + public: +  // Gets the singleton UnitTest object.  The first time this method +  // is called, a UnitTest object is constructed and returned. +  // Consecutive calls will return the same object. +  static UnitTest* GetInstance(); + +  // Registers and returns a global test environment.  When a test +  // program is run, all global test environments will be set-up in +  // the order they were registered.  After all tests in the program +  // have finished, all global test environments will be torn-down in +  // the *reverse* order they were registered. +  // +  // The UnitTest object takes ownership of the given environment. +  // +  // This method can only be called from the main thread. +  Environment* AddEnvironment(Environment* env); + +  // Adds a TestPartResult to the current TestResult object.  All +  // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) +  // eventually call this to report their results.  The user code +  // should use the assertion macros instead of calling this directly. +  // +  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +  void AddTestPartResult(TestPartResultType result_type, +                         const char* file_name, +                         int line_number, +                         const internal::String& message, +                         const internal::String& os_stack_trace); + +  // Adds a TestProperty to the current TestResult object. If the result already +  // contains a property with the same key, the value will be updated. +  void RecordPropertyForCurrentTest(const char* key, const char* value); + +  // Runs all tests in this UnitTest object and prints the result. +  // Returns 0 if successful, or 1 otherwise. +  // +  // This method can only be called from the main thread. +  // +  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +  int Run() GTEST_MUST_USE_RESULT_; + +  // Returns the working directory when the first TEST() or TEST_F() +  // was executed.  The UnitTest object owns the string. +  const char* original_working_dir() const; + +  // Returns the TestCase object for the test that's currently running, +  // or NULL if no test is running. +  const TestCase* current_test_case() const; + +  // Returns the TestInfo object for the test that's currently running, +  // or NULL if no test is running. +  const TestInfo* current_test_info() const; + +#ifdef GTEST_HAS_PARAM_TEST +  // Returns the ParameterizedTestCaseRegistry object used to keep track of +  // value-parameterized tests and instantiate and register them. +  internal::ParameterizedTestCaseRegistry& parameterized_test_registry(); +#endif  // GTEST_HAS_PARAM_TEST + +  // Accessors for the implementation object. +  internal::UnitTestImpl* impl() { return impl_; } +  const internal::UnitTestImpl* impl() const { return impl_; } + private: +  // ScopedTrace is a friend as it needs to modify the per-thread +  // trace stack, which is a private member of UnitTest. +  friend class internal::ScopedTrace; + +  // Creates an empty UnitTest. +  UnitTest(); + +  // D'tor +  virtual ~UnitTest(); + +  // Pushes a trace defined by SCOPED_TRACE() on to the per-thread +  // Google Test trace stack. +  void PushGTestTrace(const internal::TraceInfo& trace); + +  // Pops a trace from the per-thread Google Test trace stack. +  void PopGTestTrace(); + +  // Protects mutable state in *impl_.  This is mutable as some const +  // methods need to lock it too. +  mutable internal::Mutex mutex_; + +  // Opaque implementation object.  This field is never changed once +  // the object is constructed.  We don't mark it as const here, as +  // doing so will cause a warning in the constructor of UnitTest. +  // Mutable state in *impl_ is protected by mutex_. +  internal::UnitTestImpl* impl_; + +  // We disallow copying UnitTest. +  GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); +}; + +// A convenient wrapper for adding an environment for the test +// program. +// +// You should call this before RUN_ALL_TESTS() is called, probably in +// main().  If you use gtest_main, you need to call this before main() +// starts for it to take effect.  For example, you can define a global +// variable like this: +// +//   testing::Environment* const foo_env = +//       testing::AddGlobalTestEnvironment(new FooEnvironment); +// +// However, we strongly recommend you to write your own main() and +// call AddGlobalTestEnvironment() there, as relying on initialization +// of global variables makes the code harder to read and may cause +// problems when you register multiple environments from different +// translation units and the environments have dependencies among them +// (remember that the compiler doesn't guarantee the order in which +// global variables from different translation units are initialized). +inline Environment* AddGlobalTestEnvironment(Environment* env) { +  return UnitTest::GetInstance()->AddEnvironment(env); +} + +// Initializes Google Test.  This must be called before calling +// RUN_ALL_TESTS().  In particular, it parses a command line for the +// flags that Google Test recognizes.  Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned.  Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +void InitGoogleTest(int* argc, char** argv); + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +void InitGoogleTest(int* argc, wchar_t** argv); + +namespace internal { + +// These overloaded versions handle ::std::string and ::std::wstring. +#if GTEST_HAS_STD_STRING +inline String FormatForFailureMessage(const ::std::string& str) { +  return (Message() << '"' << str << '"').GetString(); +} +#endif  // GTEST_HAS_STD_STRING + +#if GTEST_HAS_STD_WSTRING +inline String FormatForFailureMessage(const ::std::wstring& wstr) { +  return (Message() << "L\"" << wstr << '"').GetString(); +} +#endif  // GTEST_HAS_STD_WSTRING + +// These overloaded versions handle ::string and ::wstring. +#if GTEST_HAS_GLOBAL_STRING +inline String FormatForFailureMessage(const ::string& str) { +  return (Message() << '"' << str << '"').GetString(); +} +#endif  // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_GLOBAL_WSTRING +inline String FormatForFailureMessage(const ::wstring& wstr) { +  return (Message() << "L\"" << wstr << '"').GetString(); +} +#endif  // GTEST_HAS_GLOBAL_WSTRING + +// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) +// operand to be used in a failure message.  The type (but not value) +// of the other operand may affect the format.  This allows us to +// print a char* as a raw pointer when it is compared against another +// char*, and print it as a C string when it is compared against an +// std::string object, for example. +// +// The default implementation ignores the type of the other operand. +// Some specialized versions are used to handle formatting wide or +// narrow C strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template <typename T1, typename T2> +String FormatForComparisonFailureMessage(const T1& value, +                                         const T2& /* other_operand */) { +  return FormatForFailureMessage(value); +} + +// The helper function for {ASSERT|EXPECT}_EQ. +template <typename T1, typename T2> +AssertionResult CmpHelperEQ(const char* expected_expression, +                            const char* actual_expression, +                            const T1& expected, +                            const T2& actual) { +  if (expected == actual) { +    return AssertionSuccess(); +  } + +  return EqFailure(expected_expression, +                   actual_expression, +                   FormatForComparisonFailureMessage(expected, actual), +                   FormatForComparisonFailureMessage(actual, expected), +                   false); +} + +// With this overloaded version, we allow anonymous enums to be used +// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums +// can be implicitly cast to BiggestInt. +AssertionResult CmpHelperEQ(const char* expected_expression, +                            const char* actual_expression, +                            BiggestInt expected, +                            BiggestInt actual); + +// The helper class for {ASSERT|EXPECT}_EQ.  The template argument +// lhs_is_null_literal is true iff the first argument to ASSERT_EQ() +// is a null pointer literal.  The following default implementation is +// for lhs_is_null_literal being false. +template <bool lhs_is_null_literal> +class EqHelper { + public: +  // This templatized version is for the general case. +  template <typename T1, typename T2> +  static AssertionResult Compare(const char* expected_expression, +                                 const char* actual_expression, +                                 const T1& expected, +                                 const T2& actual) { +    return CmpHelperEQ(expected_expression, actual_expression, expected, +                       actual); +  } + +  // With this overloaded version, we allow anonymous enums to be used +  // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous +  // enums can be implicitly cast to BiggestInt. +  // +  // Even though its body looks the same as the above version, we +  // cannot merge the two, as it will make anonymous enums unhappy. +  static AssertionResult Compare(const char* expected_expression, +                                 const char* actual_expression, +                                 BiggestInt expected, +                                 BiggestInt actual) { +    return CmpHelperEQ(expected_expression, actual_expression, expected, +                       actual); +  } +}; + +// This specialization is used when the first argument to ASSERT_EQ() +// is a null pointer literal. +template <> +class EqHelper<true> { + public: +  // We define two overloaded versions of Compare().  The first +  // version will be picked when the second argument to ASSERT_EQ() is +  // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or +  // EXPECT_EQ(false, a_bool). +  template <typename T1, typename T2> +  static AssertionResult Compare(const char* expected_expression, +                                 const char* actual_expression, +                                 const T1& expected, +                                 const T2& actual) { +    return CmpHelperEQ(expected_expression, actual_expression, expected, +                       actual); +  } + +  // This version will be picked when the second argument to +  // ASSERT_EQ() is a pointer, e.g. ASSERT_EQ(NULL, a_pointer). +  template <typename T1, typename T2> +  static AssertionResult Compare(const char* expected_expression, +                                 const char* actual_expression, +                                 const T1& expected, +                                 T2* actual) { +    // We already know that 'expected' is a null pointer. +    return CmpHelperEQ(expected_expression, actual_expression, +                       static_cast<T2*>(NULL), actual); +  } +}; + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_??.  It is here just to avoid copy-and-paste +// of similar code. +// +// For each templatized helper function, we also define an overloaded +// version for BiggestInt in order to reduce code bloat and allow +// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled +// with gcc 4. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +template <typename T1, typename T2>\ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ +                                   const T1& val1, const T2& val2) {\ +  if (val1 op val2) {\ +    return AssertionSuccess();\ +  } else {\ +    Message msg;\ +    msg << "Expected: (" << expr1 << ") " #op " (" << expr2\ +        << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ +        << " vs " << FormatForComparisonFailureMessage(val2, val1);\ +    return AssertionFailure(msg);\ +  }\ +}\ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ +                                   BiggestInt val1, BiggestInt val2); + +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + +// Implements the helper function for {ASSERT|EXPECT}_NE +GTEST_IMPL_CMP_HELPER_(NE, !=) +// Implements the helper function for {ASSERT|EXPECT}_LE +GTEST_IMPL_CMP_HELPER_(LE, <=) +// Implements the helper function for {ASSERT|EXPECT}_LT +GTEST_IMPL_CMP_HELPER_(LT, < ) +// Implements the helper function for {ASSERT|EXPECT}_GE +GTEST_IMPL_CMP_HELPER_(GE, >=) +// Implements the helper function for {ASSERT|EXPECT}_GT +GTEST_IMPL_CMP_HELPER_(GT, > ) + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +AssertionResult CmpHelperSTREQ(const char* expected_expression, +                               const char* actual_expression, +                               const char* expected, +                               const char* actual); + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, +                                   const char* actual_expression, +                                   const char* expected, +                                   const char* actual); + +// The helper function for {ASSERT|EXPECT}_STRNE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +AssertionResult CmpHelperSTRNE(const char* s1_expression, +                               const char* s2_expression, +                               const char* s1, +                               const char* s2); + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +AssertionResult CmpHelperSTRCASENE(const char* s1_expression, +                                   const char* s2_expression, +                                   const char* s1, +                                   const char* s2); + + +// Helper function for *_STREQ on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +AssertionResult CmpHelperSTREQ(const char* expected_expression, +                               const char* actual_expression, +                               const wchar_t* expected, +                               const wchar_t* actual); + +// Helper function for *_STRNE on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +AssertionResult CmpHelperSTRNE(const char* s1_expression, +                               const char* s2_expression, +                               const wchar_t* s1, +                               const wchar_t* s2); + +}  // namespace internal + +// IsSubstring() and IsNotSubstring() are intended to be used as the +// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by +// themselves.  They check whether needle is a substring of haystack +// (NULL is considered a substring of itself only), and return an +// appropriate error message when they fail. +// +// The {needle,haystack}_expr arguments are the stringified +// expressions that generated the two real arguments. +AssertionResult IsSubstring( +    const char* needle_expr, const char* haystack_expr, +    const char* needle, const char* haystack); +AssertionResult IsSubstring( +    const char* needle_expr, const char* haystack_expr, +    const wchar_t* needle, const wchar_t* haystack); +AssertionResult IsNotSubstring( +    const char* needle_expr, const char* haystack_expr, +    const char* needle, const char* haystack); +AssertionResult IsNotSubstring( +    const char* needle_expr, const char* haystack_expr, +    const wchar_t* needle, const wchar_t* haystack); +#if GTEST_HAS_STD_STRING +AssertionResult IsSubstring( +    const char* needle_expr, const char* haystack_expr, +    const ::std::string& needle, const ::std::string& haystack); +AssertionResult IsNotSubstring( +    const char* needle_expr, const char* haystack_expr, +    const ::std::string& needle, const ::std::string& haystack); +#endif  // GTEST_HAS_STD_STRING + +#if GTEST_HAS_STD_WSTRING +AssertionResult IsSubstring( +    const char* needle_expr, const char* haystack_expr, +    const ::std::wstring& needle, const ::std::wstring& haystack); +AssertionResult IsNotSubstring( +    const char* needle_expr, const char* haystack_expr, +    const ::std::wstring& needle, const ::std::wstring& haystack); +#endif  // GTEST_HAS_STD_WSTRING + +namespace internal { + +// Helper template function for comparing floating-points. +// +// Template parameter: +// +//   RawType: the raw floating-point type (either float or double) +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template <typename RawType> +AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression, +                                         const char* actual_expression, +                                         RawType expected, +                                         RawType actual) { +  const FloatingPoint<RawType> lhs(expected), rhs(actual); + +  if (lhs.AlmostEquals(rhs)) { +    return AssertionSuccess(); +  } + +  StrStream expected_ss; +  expected_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) +              << expected; + +  StrStream actual_ss; +  actual_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) +            << actual; + +  return EqFailure(expected_expression, +                   actual_expression, +                   StrStreamToString(&expected_ss), +                   StrStreamToString(&actual_ss), +                   false); +} + +// Helper function for implementing ASSERT_NEAR. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +AssertionResult DoubleNearPredFormat(const char* expr1, +                                     const char* expr2, +                                     const char* abs_error_expr, +                                     double val1, +                                     double val2, +                                     double abs_error); + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// A class that enables one to stream messages to assertion macros +class AssertHelper { + public: +  // Constructor. +  AssertHelper(TestPartResultType type, const char* file, int line, +               const char* message); +  // Message assignment is a semantic trick to enable assertion +  // streaming; see the GTEST_MESSAGE_ macro below. +  void operator=(const Message& message) const; + private: +  TestPartResultType const type_; +  const char*        const file_; +  int                const line_; +  String             const message_; + +  GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); +}; + +}  // namespace internal + +#ifdef GTEST_HAS_PARAM_TEST +// The abstract base class that all value-parameterized tests inherit from. +// +// This class adds support for accessing the test parameter value via +// the GetParam() method. +// +// Use it with one of the parameter generator defining functions, like Range(), +// Values(), ValuesIn(), Bool(), and Combine(). +// +// class FooTest : public ::testing::TestWithParam<int> { +//  protected: +//   FooTest() { +//     // Can use GetParam() here. +//   } +//   virtual ~FooTest() { +//     // Can use GetParam() here. +//   } +//   virtual void SetUp() { +//     // Can use GetParam() here. +//   } +//   virtual void TearDown { +//     // Can use GetParam() here. +//   } +// }; +// TEST_P(FooTest, DoesBar) { +//   // Can use GetParam() method here. +//   Foo foo; +//   ASSERT_TRUE(foo.DoesBar(GetParam())); +// } +// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); + +template <typename T> +class TestWithParam : public Test { + public: +  typedef T ParamType; + +  // The current parameter value. Is also available in the test fixture's +  // constructor. +  const ParamType& GetParam() const { return *parameter_; } + + private: +  // Sets parameter value. The caller is responsible for making sure the value +  // remains alive and unchanged throughout the current test. +  static void SetParam(const ParamType* parameter) { +    parameter_ = parameter; +  } + +  // Static value used for accessing parameter during a test lifetime. +  static const ParamType* parameter_; + +  // TestClass must be a subclass of TestWithParam<T>. +  template <class TestClass> friend class internal::ParameterizedTestFactory; +}; + +template <typename T> +const T* TestWithParam<T>::parameter_ = NULL; + +#endif  // GTEST_HAS_PARAM_TEST + +// Macros for indicating success/failure in test code. + +// ADD_FAILURE unconditionally adds a failure to the current test. +// SUCCEED generates a success - it doesn't automatically make the +// current test successful, as a test is only successful when it has +// no failure. +// +// EXPECT_* verifies that a certain condition is satisfied.  If not, +// it behaves like ADD_FAILURE.  In particular: +// +//   EXPECT_TRUE  verifies that a Boolean condition is true. +//   EXPECT_FALSE verifies that a Boolean condition is false. +// +// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except +// that they will also abort the current function on failure.  People +// usually want the fail-fast behavior of FAIL and ASSERT_*, but those +// writing data-driven tests often find themselves using ADD_FAILURE +// and EXPECT_* more. +// +// Examples: +// +//   EXPECT_TRUE(server.StatusIsOK()); +//   ASSERT_FALSE(server.HasPendingRequest(port)) +//       << "There are still pending requests " << "on port " << port; + +// Generates a nonfatal failure with a generic message. +#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") + +// Generates a fatal failure with a generic message. +#define FAIL() GTEST_FATAL_FAILURE_("Failed") + +// Generates a success with a generic message. +#define SUCCEED() GTEST_SUCCESS_("Succeeded") + +// Macros for testing exceptions. +// +//    * {ASSERT|EXPECT}_THROW(statement, expected_exception): +//         Tests that the statement throws the expected exception. +//    * {ASSERT|EXPECT}_NO_THROW(statement): +//         Tests that the statement doesn't throw any exception. +//    * {ASSERT|EXPECT}_ANY_THROW(statement): +//         Tests that the statement throws an exception. + +#define EXPECT_THROW(statement, expected_exception) \ +  GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_) +#define EXPECT_NO_THROW(statement) \ +  GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define EXPECT_ANY_THROW(statement) \ +  GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define ASSERT_THROW(statement, expected_exception) \ +  GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_) +#define ASSERT_NO_THROW(statement) \ +  GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) +#define ASSERT_ANY_THROW(statement) \ +  GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) + +// Boolean assertions. +#define EXPECT_TRUE(condition) \ +  GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ +                      GTEST_NONFATAL_FAILURE_) +#define EXPECT_FALSE(condition) \ +  GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ +                      GTEST_NONFATAL_FAILURE_) +#define ASSERT_TRUE(condition) \ +  GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ +                      GTEST_FATAL_FAILURE_) +#define ASSERT_FALSE(condition) \ +  GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ +                      GTEST_FATAL_FAILURE_) + +// Includes the auto-generated header that implements a family of +// generic predicate assertion macros. +#include <gtest/gtest_pred_impl.h> + +// Macros for testing equalities and inequalities. +// +//    * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual +//    * {ASSERT|EXPECT}_NE(v1, v2):           Tests that v1 != v2 +//    * {ASSERT|EXPECT}_LT(v1, v2):           Tests that v1 < v2 +//    * {ASSERT|EXPECT}_LE(v1, v2):           Tests that v1 <= v2 +//    * {ASSERT|EXPECT}_GT(v1, v2):           Tests that v1 > v2 +//    * {ASSERT|EXPECT}_GE(v1, v2):           Tests that v1 >= v2 +// +// When they are not, Google Test prints both the tested expressions and +// their actual values.  The values must be compatible built-in types, +// or you will get a compiler error.  By "compatible" we mean that the +// values can be compared by the respective operator. +// +// Note: +// +//   1. It is possible to make a user-defined type work with +//   {ASSERT|EXPECT}_??(), but that requires overloading the +//   comparison operators and is thus discouraged by the Google C++ +//   Usage Guide.  Therefore, you are advised to use the +//   {ASSERT|EXPECT}_TRUE() macro to assert that two objects are +//   equal. +// +//   2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on +//   pointers (in particular, C strings).  Therefore, if you use it +//   with two C strings, you are testing how their locations in memory +//   are related, not how their content is related.  To compare two C +//   strings by content, use {ASSERT|EXPECT}_STR*(). +// +//   3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to +//   {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you +//   what the actual value is when it fails, and similarly for the +//   other comparisons. +// +//   4. Do not depend on the order in which {ASSERT|EXPECT}_??() +//   evaluate their arguments, which is undefined. +// +//   5. These macros evaluate their arguments exactly once. +// +// Examples: +// +//   EXPECT_NE(5, Foo()); +//   EXPECT_EQ(NULL, a_pointer); +//   ASSERT_LT(i, array_size); +//   ASSERT_GT(records.size(), 0) << "There is no record left."; + +#define EXPECT_EQ(expected, actual) \ +  EXPECT_PRED_FORMAT2(::testing::internal:: \ +                      EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \ +                      expected, actual) +#define EXPECT_NE(expected, actual) \ +  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual) +#define EXPECT_LE(val1, val2) \ +  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define EXPECT_LT(val1, val2) \ +  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define EXPECT_GE(val1, val2) \ +  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define EXPECT_GT(val1, val2) \ +  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +#define ASSERT_EQ(expected, actual) \ +  ASSERT_PRED_FORMAT2(::testing::internal:: \ +                      EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \ +                      expected, actual) +#define ASSERT_NE(val1, val2) \ +  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) +#define ASSERT_LE(val1, val2) \ +  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define ASSERT_LT(val1, val2) \ +  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define ASSERT_GE(val1, val2) \ +  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define ASSERT_GT(val1, val2) \ +  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +// C String Comparisons.  All tests treat NULL and any non-NULL string +// as different.  Two NULLs are equal. +// +//    * {ASSERT|EXPECT}_STREQ(s1, s2):     Tests that s1 == s2 +//    * {ASSERT|EXPECT}_STRNE(s1, s2):     Tests that s1 != s2 +//    * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case +//    * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case +// +// For wide or narrow string objects, you can use the +// {ASSERT|EXPECT}_??() macros. +// +// Don't depend on the order in which the arguments are evaluated, +// which is undefined. +// +// These macros evaluate their arguments exactly once. + +#define EXPECT_STREQ(expected, actual) \ +  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) +#define EXPECT_STRNE(s1, s2) \ +  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define EXPECT_STRCASEEQ(expected, actual) \ +  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define EXPECT_STRCASENE(s1, s2)\ +  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +#define ASSERT_STREQ(expected, actual) \ +  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) +#define ASSERT_STRNE(s1, s2) \ +  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define ASSERT_STRCASEEQ(expected, actual) \ +  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define ASSERT_STRCASENE(s1, s2)\ +  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +// Macros for comparing floating-point numbers. +// +//    * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual): +//         Tests that two float values are almost equal. +//    * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual): +//         Tests that two double values are almost equal. +//    * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error): +//         Tests that v1 and v2 are within the given distance to each other. +// +// Google Test uses ULP-based comparison to automatically pick a default +// error bound that is appropriate for the operands.  See the +// FloatingPoint template class in gtest-internal.h if you are +// interested in the implementation details. + +#define EXPECT_FLOAT_EQ(expected, actual)\ +  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \ +                      expected, actual) + +#define EXPECT_DOUBLE_EQ(expected, actual)\ +  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \ +                      expected, actual) + +#define ASSERT_FLOAT_EQ(expected, actual)\ +  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \ +                      expected, actual) + +#define ASSERT_DOUBLE_EQ(expected, actual)\ +  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \ +                      expected, actual) + +#define EXPECT_NEAR(val1, val2, abs_error)\ +  EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ +                      val1, val2, abs_error) + +#define ASSERT_NEAR(val1, val2, abs_error)\ +  ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ +                      val1, val2, abs_error) + +// These predicate format functions work on floating-point values, and +// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. +// +//   EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0); + +// Asserts that val1 is less than, or almost equal to, val2.  Fails +// otherwise.  In particular, it fails if either val1 or val2 is NaN. +AssertionResult FloatLE(const char* expr1, const char* expr2, +                        float val1, float val2); +AssertionResult DoubleLE(const char* expr1, const char* expr2, +                         double val1, double val2); + + +#ifdef GTEST_OS_WINDOWS + +// Macros that test for HRESULT failure and success, these are only useful +// on Windows, and rely on Windows SDK macros and APIs to compile. +// +//    * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr) +// +// When expr unexpectedly fails or succeeds, Google Test prints the +// expected result and the actual result with both a human-readable +// string representation of the error, if available, as well as the +// hex result code. +#define EXPECT_HRESULT_SUCCEEDED(expr) \ +    EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +#define ASSERT_HRESULT_SUCCEEDED(expr) \ +    ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +#define EXPECT_HRESULT_FAILED(expr) \ +    EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +#define ASSERT_HRESULT_FAILED(expr) \ +    ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +#endif  // GTEST_OS_WINDOWS + +// Macros that execute statement and check that it doesn't generate new fatal +// failures in the current thread. +// +//   * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement); +// +// Examples: +// +//   EXPECT_NO_FATAL_FAILURE(Process()); +//   ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed"; +// +#define ASSERT_NO_FATAL_FAILURE(statement) \ +    GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) +#define EXPECT_NO_FATAL_FAILURE(statement) \ +    GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) + +// Causes a trace (including the source file path, the current line +// number, and the given message) to be included in every test failure +// message generated by code in the current scope.  The effect is +// undone when the control leaves the current scope. +// +// The message argument can be anything streamable to std::ostream. +// +// In the implementation, we include the current line number as part +// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s +// to appear in the same block - as long as they are on different +// lines. +#define SCOPED_TRACE(message) \ +  ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ +    __FILE__, __LINE__, ::testing::Message() << (message)) + + +// Defines a test. +// +// The first parameter is the name of the test case, and the second +// parameter is the name of the test within the test case. +// +// The convention is to end the test case name with "Test".  For +// example, a test case for the Foo class can be named FooTest. +// +// The user should put his test code between braces after using this +// macro.  Example: +// +//   TEST(FooTest, InitializesCorrectly) { +//     Foo foo; +//     EXPECT_TRUE(foo.StatusIsOK()); +//   } + +// Note that we call GetTestTypeId() instead of GetTypeId< +// ::testing::Test>() here to get the type ID of testing::Test.  This +// is to work around a suspected linker bug when using Google Test as +// a framework on Mac OS X.  The bug causes GetTypeId< +// ::testing::Test>() to return different values depending on whether +// the call is from the Google Test framework itself or from user test +// code.  GetTestTypeId() is guaranteed to always return the same +// value, as it always calls GetTypeId<>() from the Google Test +// framework. +#define TEST(test_case_name, test_name)\ +  GTEST_TEST_(test_case_name, test_name,\ +              ::testing::Test, ::testing::internal::GetTestTypeId()) + + +// Defines a test that uses a test fixture. +// +// The first parameter is the name of the test fixture class, which +// also doubles as the test case name.  The second parameter is the +// name of the test within the test case. +// +// A test fixture class must be declared earlier.  The user should put +// his test code between braces after using this macro.  Example: +// +//   class FooTest : public testing::Test { +//    protected: +//     virtual void SetUp() { b_.AddElement(3); } +// +//     Foo a_; +//     Foo b_; +//   }; +// +//   TEST_F(FooTest, InitializesCorrectly) { +//     EXPECT_TRUE(a_.StatusIsOK()); +//   } +// +//   TEST_F(FooTest, ReturnsElementCountCorrectly) { +//     EXPECT_EQ(0, a_.size()); +//     EXPECT_EQ(1, b_.size()); +//   } + +#define TEST_F(test_fixture, test_name)\ +  GTEST_TEST_(test_fixture, test_name, test_fixture,\ +              ::testing::internal::GetTypeId<test_fixture>()) + +// Use this macro in main() to run all tests.  It returns 0 if all +// tests are successful, or 1 otherwise. +// +// RUN_ALL_TESTS() should be invoked after the command line has been +// parsed by InitGoogleTest(). + +#define RUN_ALL_TESTS()\ +  (::testing::UnitTest::GetInstance()->Run()) + +}  // namespace testing + +#endif  // GTEST_INCLUDE_GTEST_GTEST_H_ diff --git a/llvm/utils/unittest/googletest/include/gtest/gtest_pred_impl.h b/llvm/utils/unittest/googletest/include/gtest/gtest_pred_impl.h new file mode 100644 index 00000000000..e1e2f8c4c88 --- /dev/null +++ b/llvm/utils/unittest/googletest/include/gtest/gtest_pred_impl.h @@ -0,0 +1,368 @@ +// Copyright 2006, 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. + +// This file is AUTOMATICALLY GENERATED on 10/02/2008 by command +// 'gen_gtest_pred_impl.py 5'.  DO NOT EDIT BY HAND! +// +// Implements a family of generic predicate assertion macros. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ + +// Makes sure this header is not included before gtest.h. +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +#error Do not include gtest_pred_impl.h directly.  Include gtest.h instead. +#endif  // GTEST_INCLUDE_GTEST_GTEST_H_ + +// This header implements a family of generic predicate assertion +// macros: +// +//   ASSERT_PRED_FORMAT1(pred_format, v1) +//   ASSERT_PRED_FORMAT2(pred_format, v1, v2) +//   ... +// +// where pred_format is a function or functor that takes n (in the +// case of ASSERT_PRED_FORMATn) values and their source expression +// text, and returns a testing::AssertionResult.  See the definition +// of ASSERT_EQ in gtest.h for an example. +// +// If you don't care about formatting, you can use the more +// restrictive version: +// +//   ASSERT_PRED1(pred, v1) +//   ASSERT_PRED2(pred, v1, v2) +//   ... +// +// where pred is an n-ary function or functor that returns bool, +// and the values v1, v2, ..., must support the << operator for +// streaming to std::ostream. +// +// We also define the EXPECT_* variations. +// +// For now we only support predicates whose arity is at most 5. +// Please email googletestframework@googlegroups.com if you need +// support for higher arities. + +// GTEST_ASSERT_ is the basic statement to which all of the assertions +// in this file reduce.  Don't use this in your code. + +#define GTEST_ASSERT_(expression, on_failure) \ +  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ +  if (const ::testing::AssertionResult gtest_ar = (expression)) \ +    ; \ +  else \ +    on_failure(gtest_ar.failure_message()) + + +// Helper function for implementing {EXPECT|ASSERT}_PRED1.  Don't use +// this in your code. +template <typename Pred, +          typename T1> +AssertionResult AssertPred1Helper(const char* pred_text, +                                  const char* e1, +                                  Pred pred, +                                  const T1& v1) { +  if (pred(v1)) return AssertionSuccess(); + +  Message msg; +  msg << pred_text << "(" +      << e1 << ") evaluates to false, where" +      << "\n" << e1 << " evaluates to " << v1; +  return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. +// Don't use this in your code. +#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ +  GTEST_ASSERT_(pred_format(#v1, v1),\ +                on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED1.  Don't use +// this in your code. +#define GTEST_PRED1_(pred, v1, on_failure)\ +  GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ +                                             #v1, \ +                                             pred, \ +                                             v1), on_failure) + +// Unary predicate assertion macros. +#define EXPECT_PRED_FORMAT1(pred_format, v1) \ +  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED1(pred, v1) \ +  GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT1(pred_format, v1) \ +  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED1(pred, v1) \ +  GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED2.  Don't use +// this in your code. +template <typename Pred, +          typename T1, +          typename T2> +AssertionResult AssertPred2Helper(const char* pred_text, +                                  const char* e1, +                                  const char* e2, +                                  Pred pred, +                                  const T1& v1, +                                  const T2& v2) { +  if (pred(v1, v2)) return AssertionSuccess(); + +  Message msg; +  msg << pred_text << "(" +      << e1 << ", " +      << e2 << ") evaluates to false, where" +      << "\n" << e1 << " evaluates to " << v1 +      << "\n" << e2 << " evaluates to " << v2; +  return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. +// Don't use this in your code. +#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ +  GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2),\ +                on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED2.  Don't use +// this in your code. +#define GTEST_PRED2_(pred, v1, v2, on_failure)\ +  GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ +                                             #v1, \ +                                             #v2, \ +                                             pred, \ +                                             v1, \ +                                             v2), on_failure) + +// Binary predicate assertion macros. +#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ +  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED2(pred, v1, v2) \ +  GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ +  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED2(pred, v1, v2) \ +  GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED3.  Don't use +// this in your code. +template <typename Pred, +          typename T1, +          typename T2, +          typename T3> +AssertionResult AssertPred3Helper(const char* pred_text, +                                  const char* e1, +                                  const char* e2, +                                  const char* e3, +                                  Pred pred, +                                  const T1& v1, +                                  const T2& v2, +                                  const T3& v3) { +  if (pred(v1, v2, v3)) return AssertionSuccess(); + +  Message msg; +  msg << pred_text << "(" +      << e1 << ", " +      << e2 << ", " +      << e3 << ") evaluates to false, where" +      << "\n" << e1 << " evaluates to " << v1 +      << "\n" << e2 << " evaluates to " << v2 +      << "\n" << e3 << " evaluates to " << v3; +  return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. +// Don't use this in your code. +#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ +  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3),\ +                on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED3.  Don't use +// this in your code. +#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ +  GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ +                                             #v1, \ +                                             #v2, \ +                                             #v3, \ +                                             pred, \ +                                             v1, \ +                                             v2, \ +                                             v3), on_failure) + +// Ternary predicate assertion macros. +#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ +  GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED3(pred, v1, v2, v3) \ +  GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ +  GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED3(pred, v1, v2, v3) \ +  GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED4.  Don't use +// this in your code. +template <typename Pred, +          typename T1, +          typename T2, +          typename T3, +          typename T4> +AssertionResult AssertPred4Helper(const char* pred_text, +                                  const char* e1, +                                  const char* e2, +                                  const char* e3, +                                  const char* e4, +                                  Pred pred, +                                  const T1& v1, +                                  const T2& v2, +                                  const T3& v3, +                                  const T4& v4) { +  if (pred(v1, v2, v3, v4)) return AssertionSuccess(); + +  Message msg; +  msg << pred_text << "(" +      << e1 << ", " +      << e2 << ", " +      << e3 << ", " +      << e4 << ") evaluates to false, where" +      << "\n" << e1 << " evaluates to " << v1 +      << "\n" << e2 << " evaluates to " << v2 +      << "\n" << e3 << " evaluates to " << v3 +      << "\n" << e4 << " evaluates to " << v4; +  return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. +// Don't use this in your code. +#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ +  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4),\ +                on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED4.  Don't use +// this in your code. +#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ +  GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ +                                             #v1, \ +                                             #v2, \ +                                             #v3, \ +                                             #v4, \ +                                             pred, \ +                                             v1, \ +                                             v2, \ +                                             v3, \ +                                             v4), on_failure) + +// 4-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ +  GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED4(pred, v1, v2, v3, v4) \ +  GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ +  GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED4(pred, v1, v2, v3, v4) \ +  GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED5.  Don't use +// this in your code. +template <typename Pred, +          typename T1, +          typename T2, +          typename T3, +          typename T4, +          typename T5> +AssertionResult AssertPred5Helper(const char* pred_text, +                                  const char* e1, +                                  const char* e2, +                                  const char* e3, +                                  const char* e4, +                                  const char* e5, +                                  Pred pred, +                                  const T1& v1, +                                  const T2& v2, +                                  const T3& v3, +                                  const T4& v4, +                                  const T5& v5) { +  if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); + +  Message msg; +  msg << pred_text << "(" +      << e1 << ", " +      << e2 << ", " +      << e3 << ", " +      << e4 << ", " +      << e5 << ") evaluates to false, where" +      << "\n" << e1 << " evaluates to " << v1 +      << "\n" << e2 << " evaluates to " << v2 +      << "\n" << e3 << " evaluates to " << v3 +      << "\n" << e4 << " evaluates to " << v4 +      << "\n" << e5 << " evaluates to " << v5; +  return AssertionFailure(msg); +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. +// Don't use this in your code. +#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ +  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5),\ +                on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED5.  Don't use +// this in your code. +#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ +  GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ +                                             #v1, \ +                                             #v2, \ +                                             #v3, \ +                                             #v4, \ +                                             #v5, \ +                                             pred, \ +                                             v1, \ +                                             v2, \ +                                             v3, \ +                                             v4, \ +                                             v5), on_failure) + +// 5-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ +  GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ +  GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ +  GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ +  GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) + + + +#endif  // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ diff --git a/llvm/utils/unittest/googletest/include/gtest/gtest_prod.h b/llvm/utils/unittest/googletest/include/gtest/gtest_prod.h new file mode 100644 index 00000000000..da80ddc6c70 --- /dev/null +++ b/llvm/utils/unittest/googletest/include/gtest/gtest_prod.h @@ -0,0 +1,58 @@ +// Copyright 2006, 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) +// +// Google C++ Testing Framework definitions useful in production code. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ + +// When you need to test the private or protected members of a class, +// use the FRIEND_TEST macro to declare your tests as friends of the +// class.  For example: +// +// class MyClass { +//  private: +//   void MyMethod(); +//   FRIEND_TEST(MyClassTest, MyMethod); +// }; +// +// class MyClassTest : public testing::Test { +//   // ... +// }; +// +// TEST_F(MyClassTest, MyMethod) { +//   // Can call MyClass::MyMethod() here. +// } + +#define FRIEND_TEST(test_case_name, test_name)\ +friend class test_case_name##_##test_name##_Test + +#endif  // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ diff --git a/llvm/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h new file mode 100644 index 00000000000..0769fcaa0e8 --- /dev/null +++ b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h @@ -0,0 +1,201 @@ +// Copyright 2005, 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. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines internal utilities needed for implementing +// death tests.  They are subject to change without notice. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ + +#include <gtest/internal/gtest-internal.h> + +namespace testing { +namespace internal { + +GTEST_DECLARE_string_(internal_run_death_test); + +// Names of the flags (needed for parsing Google Test flags). +const char kDeathTestStyleFlag[] = "death_test_style"; +const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; + +#ifdef GTEST_HAS_DEATH_TEST + +// DeathTest is a class that hides much of the complexity of the +// GTEST_DEATH_TEST_ macro.  It is abstract; its static Create method +// returns a concrete class that depends on the prevailing death test +// style, as defined by the --gtest_death_test_style and/or +// --gtest_internal_run_death_test flags. + +// In describing the results of death tests, these terms are used with +// the corresponding definitions: +// +// exit status:  The integer exit information in the format specified +//               by wait(2) +// exit code:    The integer code passed to exit(3), _exit(2), or +//               returned from main() +class DeathTest { + public: +  // Create returns false if there was an error determining the +  // appropriate action to take for the current death test; for example, +  // if the gtest_death_test_style flag is set to an invalid value. +  // The LastMessage method will return a more detailed message in that +  // case.  Otherwise, the DeathTest pointer pointed to by the "test" +  // argument is set.  If the death test should be skipped, the pointer +  // is set to NULL; otherwise, it is set to the address of a new concrete +  // DeathTest object that controls the execution of the current test. +  static bool Create(const char* statement, const RE* regex, +                     const char* file, int line, DeathTest** test); +  DeathTest(); +  virtual ~DeathTest() { } + +  // A helper class that aborts a death test when it's deleted. +  class ReturnSentinel { +   public: +    explicit ReturnSentinel(DeathTest* test) : test_(test) { } +    ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } +   private: +    DeathTest* const test_; +    GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); +  } GTEST_ATTRIBUTE_UNUSED_; + +  // An enumeration of possible roles that may be taken when a death +  // test is encountered.  EXECUTE means that the death test logic should +  // be executed immediately.  OVERSEE means that the program should prepare +  // the appropriate environment for a child process to execute the death +  // test, then wait for it to complete. +  enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; + +  // An enumeration of the two reasons that a test might be aborted. +  enum AbortReason { TEST_ENCOUNTERED_RETURN_STATEMENT, TEST_DID_NOT_DIE }; + +  // Assumes one of the above roles. +  virtual TestRole AssumeRole() = 0; + +  // Waits for the death test to finish and returns its status. +  virtual int Wait() = 0; + +  // Returns true if the death test passed; that is, the test process +  // exited during the test, its exit status matches a user-supplied +  // predicate, and its stderr output matches a user-supplied regular +  // expression. +  // The user-supplied predicate may be a macro expression rather +  // than a function pointer or functor, or else Wait and Passed could +  // be combined. +  virtual bool Passed(bool exit_status_ok) = 0; + +  // Signals that the death test did not die as expected. +  virtual void Abort(AbortReason reason) = 0; + +  // Returns a human-readable outcome message regarding the outcome of +  // the last death test. +  static const char* LastMessage(); + + private: +  GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); +}; + +// Factory interface for death tests.  May be mocked out for testing. +class DeathTestFactory { + public: +  virtual ~DeathTestFactory() { } +  virtual bool Create(const char* statement, const RE* regex, +                      const char* file, int line, DeathTest** test) = 0; +}; + +// A concrete DeathTestFactory implementation for normal use. +class DefaultDeathTestFactory : public DeathTestFactory { + public: +  virtual bool Create(const char* statement, const RE* regex, +                      const char* file, int line, DeathTest** test); +}; + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +bool ExitedUnsuccessfully(int exit_status); + +// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, +// ASSERT_EXIT*, and EXPECT_EXIT*. +#define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ +  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ +  if (true) { \ +    const ::testing::internal::RE& gtest_regex = (regex); \ +    ::testing::internal::DeathTest* gtest_dt; \ +    if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ +        __FILE__, __LINE__, >est_dt)) { \ +      goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ +    } \ +    if (gtest_dt != NULL) { \ +      ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ +          gtest_dt_ptr(gtest_dt); \ +      switch (gtest_dt->AssumeRole()) { \ +        case ::testing::internal::DeathTest::OVERSEE_TEST: \ +          if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ +            goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ +          } \ +          break; \ +        case ::testing::internal::DeathTest::EXECUTE_TEST: { \ +          ::testing::internal::DeathTest::ReturnSentinel \ +              gtest_sentinel(gtest_dt); \ +          { statement; } \ +          gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ +          break; \ +        } \ +      } \ +    } \ +  } else \ +    GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \ +      fail(::testing::internal::DeathTest::LastMessage()) +// The symbol "fail" here expands to something into which a message +// can be streamed. + +// A struct representing the parsed contents of the +// --gtest_internal_run_death_test flag, as it existed when +// RUN_ALL_TESTS was called. +struct InternalRunDeathTestFlag { +  String file; +  int line; +  int index; +  int status_fd; +}; + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); + +#endif  // GTEST_HAS_DEATH_TEST + +}  // namespace internal +}  // namespace testing + +#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ diff --git a/llvm/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h new file mode 100644 index 00000000000..9a0682af8b5 --- /dev/null +++ b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h @@ -0,0 +1,192 @@ +// Copyright 2008, 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: keith.ray@gmail.com (Keith Ray) +// +// Google Test filepath utilities +// +// This header file declares classes and functions used internally by +// Google Test.  They are subject to change without notice. +// +// This file is #included in testing/base/internal/gtest-internal.h +// Do not include this header file separately! + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ + +#include <gtest/internal/gtest-string.h> + +namespace testing { +namespace internal { + +// FilePath - a class for file and directory pathname manipulation which +// handles platform-specific conventions (like the pathname separator). +// Used for helper functions for naming files in a directory for xml output. +// Except for Set methods, all methods are const or static, which provides an +// "immutable value object" -- useful for peace of mind. +// A FilePath with a value ending in a path separator ("like/this/") represents +// a directory, otherwise it is assumed to represent a file. In either case, +// it may or may not represent an actual file or directory in the file system. +// Names are NOT checked for syntax correctness -- no checking for illegal +// characters, malformed paths, etc. + +class FilePath { + public: +  FilePath() : pathname_("") { } +  FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } + +  explicit FilePath(const char* pathname) : pathname_(pathname) { +    Normalize(); +  } + +  explicit FilePath(const String& pathname) : pathname_(pathname) { +    Normalize(); +  } + +  FilePath& operator=(const FilePath& rhs) { +    Set(rhs); +    return *this; +  } + +  void Set(const FilePath& rhs) { +    pathname_ = rhs.pathname_; +  } + +  String ToString() const { return pathname_; } +  const char* c_str() const { return pathname_.c_str(); } + +  // Returns the current working directory, or "" if unsuccessful. +  static FilePath GetCurrentDir(); + +  // Given directory = "dir", base_name = "test", number = 0, +  // extension = "xml", returns "dir/test.xml". If number is greater +  // than zero (e.g., 12), returns "dir/test_12.xml". +  // On Windows platform, uses \ as the separator rather than /. +  static FilePath MakeFileName(const FilePath& directory, +                               const FilePath& base_name, +                               int number, +                               const char* extension); + +  // Returns a pathname for a file that does not currently exist. The pathname +  // will be directory/base_name.extension or +  // directory/base_name_<number>.extension if directory/base_name.extension +  // already exists. The number will be incremented until a pathname is found +  // that does not already exist. +  // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. +  // There could be a race condition if two or more processes are calling this +  // function at the same time -- they could both pick the same filename. +  static FilePath GenerateUniqueFileName(const FilePath& directory, +                                         const FilePath& base_name, +                                         const char* extension); + +  // Returns true iff the path is NULL or "". +  bool IsEmpty() const { return c_str() == NULL || *c_str() == '\0'; } + +  // If input name has a trailing separator character, removes it and returns +  // the name, otherwise return the name string unmodified. +  // On Windows platform, uses \ as the separator, other platforms use /. +  FilePath RemoveTrailingPathSeparator() const; + +  // Returns a copy of the FilePath with the directory part removed. +  // Example: FilePath("path/to/file").RemoveDirectoryName() returns +  // FilePath("file"). If there is no directory part ("just_a_file"), it returns +  // the FilePath unmodified. If there is no file part ("just_a_dir/") it +  // returns an empty FilePath (""). +  // On Windows platform, '\' is the path separator, otherwise it is '/'. +  FilePath RemoveDirectoryName() const; + +  // RemoveFileName returns the directory path with the filename removed. +  // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". +  // If the FilePath is "a_file" or "/a_file", RemoveFileName returns +  // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does +  // not have a file, like "just/a/dir/", it returns the FilePath unmodified. +  // On Windows platform, '\' is the path separator, otherwise it is '/'. +  FilePath RemoveFileName() const; + +  // Returns a copy of the FilePath with the case-insensitive extension removed. +  // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns +  // FilePath("dir/file"). If a case-insensitive extension is not +  // found, returns a copy of the original FilePath. +  FilePath RemoveExtension(const char* extension) const; + +  // Creates directories so that path exists. Returns true if successful or if +  // the directories already exist; returns false if unable to create +  // directories for any reason. Will also return false if the FilePath does +  // not represent a directory (that is, it doesn't end with a path separator). +  bool CreateDirectoriesRecursively() const; + +  // Create the directory so that path exists. Returns true if successful or +  // if the directory already exists; returns false if unable to create the +  // directory for any reason, including if the parent directory does not +  // exist. Not named "CreateDirectory" because that's a macro on Windows. +  bool CreateFolder() const; + +  // Returns true if FilePath describes something in the file-system, +  // either a file, directory, or whatever, and that something exists. +  bool FileOrDirectoryExists() const; + +  // Returns true if pathname describes a directory in the file-system +  // that exists. +  bool DirectoryExists() const; + +  // Returns true if FilePath ends with a path separator, which indicates that +  // it is intended to represent a directory. Returns false otherwise. +  // This does NOT check that a directory (or file) actually exists. +  bool IsDirectory() const; + +  // Returns true if pathname describes a root directory. (Windows has one +  // root directory per disk drive.) +  bool IsRootDirectory() const; + + private: +  // Replaces multiple consecutive separators with a single separator. +  // For example, "bar///foo" becomes "bar/foo". Does not eliminate other +  // redundancies that might be in a pathname involving "." or "..". +  // +  // A pathname with multiple consecutive separators may occur either through +  // user error or as a result of some scripts or APIs that generate a pathname +  // with a trailing separator. On other platforms the same API or script +  // may NOT generate a pathname with a trailing "/". Then elsewhere that +  // pathname may have another "/" and pathname components added to it, +  // without checking for the separator already being there. +  // The script language and operating system may allow paths like "foo//bar" +  // but some of the functions in FilePath will not handle that correctly. In +  // particular, RemoveTrailingPathSeparator() only removes one separator, and +  // it is called in CreateDirectoriesRecursively() assuming that it will change +  // a pathname from directory syntax (trailing separator) to filename syntax. + +  void Normalize(); + +  String pathname_; +};  // class FilePath + +}  // namespace internal +}  // namespace testing + +#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ diff --git a/llvm/utils/unittest/googletest/include/gtest/internal/gtest-internal.h b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-internal.h new file mode 100644 index 00000000000..37faaaebea4 --- /dev/null +++ b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-internal.h @@ -0,0 +1,876 @@ +// Copyright 2005, 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. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file declares functions and macros used internally by +// Google Test.  They are subject to change without notice. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ + +#include <gtest/internal/gtest-port.h> + +#ifdef GTEST_OS_LINUX +#include <stdlib.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#endif  // GTEST_OS_LINUX + +#include <ctype.h> +#include <string.h> +#include <iomanip> +#include <limits> +#include <set> + +#include <gtest/internal/gtest-string.h> +#include <gtest/internal/gtest-filepath.h> +#include <gtest/internal/gtest-type-util.h> + +// Due to C++ preprocessor weirdness, we need double indirection to +// concatenate two tokens when one of them is __LINE__.  Writing +// +//   foo ## __LINE__ +// +// will result in the token foo__LINE__, instead of foo followed by +// the current line number.  For more details, see +// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 +#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) +#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar + +// Google Test defines the testing::Message class to allow construction of +// test messages via the << operator.  The idea is that anything +// streamable to std::ostream can be streamed to a testing::Message. +// This allows a user to use his own types in Google Test assertions by +// overloading the << operator. +// +// util/gtl/stl_logging-inl.h overloads << for STL containers.  These +// overloads cannot be defined in the std namespace, as that will be +// undefined behavior.  Therefore, they are defined in the global +// namespace instead. +// +// C++'s symbol lookup rule (i.e. Koenig lookup) says that these +// overloads are visible in either the std namespace or the global +// namespace, but not other namespaces, including the testing +// namespace which Google Test's Message class is in. +// +// To allow STL containers (and other types that has a << operator +// defined in the global namespace) to be used in Google Test assertions, +// testing::Message must access the custom << operator from the global +// namespace.  Hence this helper function. +// +// Note: Jeffrey Yasskin suggested an alternative fix by "using +// ::operator<<;" in the definition of Message's operator<<.  That fix +// doesn't require a helper function, but unfortunately doesn't +// compile with MSVC. +template <typename T> +inline void GTestStreamToHelper(std::ostream* os, const T& val) { +  *os << val; +} + +namespace testing { + +// Forward declaration of classes. + +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 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. + +// How many times InitGoogleTest() has been called. +extern int g_init_gtest_count; + +// The text used in failure messages to indicate the start of the +// stack trace. +extern const char kStackTraceMarker[]; + +// A secret type that Google Test users don't know about.  It has no +// definition on purpose.  Therefore it's impossible to create a +// Secret object, which is what we want. +class Secret; + +// Two overloaded helpers for checking at compile time whether an +// expression is a null pointer literal (i.e. NULL or any 0-valued +// compile-time integral constant).  Their return values have +// different sizes, so we can use sizeof() to test which version is +// picked by the compiler.  These helpers have no implementations, as +// we only need their signatures. +// +// Given IsNullLiteralHelper(x), the compiler will pick the first +// version if x can be implicitly converted to Secret*, and pick the +// second version otherwise.  Since Secret is a secret and incomplete +// type, the only expression a user can write that has type Secret* is +// a null pointer literal.  Therefore, we know that x is a null +// pointer literal if and only if the first version is picked by the +// compiler. +char IsNullLiteralHelper(Secret* p); +char (&IsNullLiteralHelper(...))[2];  // NOLINT + +// A compile-time bool constant that is true if and only if x is a +// null pointer literal (i.e. NULL or any 0-valued compile-time +// integral constant). +#ifdef GTEST_ELLIPSIS_NEEDS_COPY_ +// Passing non-POD classes through ellipsis (...) crashes the ARM +// compiler.  The Nokia Symbian and the IBM XL C/C++ compiler try to +// instantiate a copy constructor for objects passed through ellipsis +// (...), failing for uncopyable objects.  Hence we define this to +// false (and lose support for NULL detection). +#define GTEST_IS_NULL_LITERAL_(x) false +#else +#define GTEST_IS_NULL_LITERAL_(x) \ +    (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) +#endif  // GTEST_ELLIPSIS_NEEDS_COPY_ + +// Appends the user-supplied message to the Google-Test-generated message. +String AppendUserMessage(const String& gtest_msg, +                         const Message& user_msg); + +// A helper class for creating scoped traces in user programs. +class ScopedTrace { + public: +  // The c'tor pushes the given source file location and message onto +  // a trace stack maintained by Google Test. +  ScopedTrace(const char* file, int line, const Message& message); + +  // The d'tor pops the info pushed by the c'tor. +  // +  // Note that the d'tor is not virtual in order to be efficient. +  // Don't inherit from ScopedTrace! +  ~ScopedTrace(); + + private: +  GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); +} GTEST_ATTRIBUTE_UNUSED_;  // A ScopedTrace object does its job in its +                            // c'tor and d'tor.  Therefore it doesn't +                            // need to be used otherwise. + +// Converts a streamable value to a String.  A NULL pointer is +// converted to "(null)".  When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". +// Declared here but defined in gtest.h, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template <typename T> +String StreamableToString(const T& streamable); + +// Formats a value to be used in a failure message. + +#ifdef GTEST_NEEDS_IS_POINTER_ + +// These are needed as the Nokia Symbian and IBM XL C/C++ compilers +// cannot decide between const T& and const T* in a function template. +// These compilers _can_ decide between class template specializations +// for T and T*, so a tr1::type_traits-like is_pointer works, and we +// can overload on that. + +// 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, +                                           T* pointer) { +  return StreamableToString(static_cast<const void*>(pointer)); +} + +template <typename T> +inline String FormatValueForFailureMessage(internal::false_type dummy, +                                           const T& value) { +  return StreamableToString(value); +} + +template <typename T> +inline String FormatForFailureMessage(const T& value) { +  return FormatValueForFailureMessage( +      typename internal::is_pointer<T>::type(), value); +} + +#else + +// These are needed as the above solution using is_pointer has the +// limitation that T cannot be a type without external linkage, when +// compiled using MSVC. + +template <typename T> +inline String FormatForFailureMessage(const T& value) { +  return StreamableToString(value); +} + +// This overload makes sure that all pointers (including +// those to char or wchar_t) are printed as raw pointers. +template <typename T> +inline String FormatForFailureMessage(T* pointer) { +  return StreamableToString(static_cast<const void*>(pointer)); +} + +#endif  // GTEST_NEEDS_IS_POINTER_ + +// These overloaded versions handle narrow and wide characters. +String FormatForFailureMessage(char ch); +String FormatForFailureMessage(wchar_t wchar); + +// When this operand is a const char* or char*, and the other operand +// is a ::std::string or ::string, we print this operand as a C string +// rather than a pointer.  We do the same for wide strings. + +// This internal macro is used to avoid duplicated code. +#define GTEST_FORMAT_IMPL_(operand2_type, operand1_printer)\ +inline String FormatForComparisonFailureMessage(\ +    operand2_type::value_type* str, const operand2_type& /*operand2*/) {\ +  return operand1_printer(str);\ +}\ +inline String FormatForComparisonFailureMessage(\ +    const operand2_type::value_type* str, const operand2_type& /*operand2*/) {\ +  return operand1_printer(str);\ +} + +#if GTEST_HAS_STD_STRING +GTEST_FORMAT_IMPL_(::std::string, String::ShowCStringQuoted) +#endif  // GTEST_HAS_STD_STRING +#if GTEST_HAS_STD_WSTRING +GTEST_FORMAT_IMPL_(::std::wstring, String::ShowWideCStringQuoted) +#endif  // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_STRING +GTEST_FORMAT_IMPL_(::string, String::ShowCStringQuoted) +#endif  // GTEST_HAS_GLOBAL_STRING +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_FORMAT_IMPL_(::wstring, String::ShowWideCStringQuoted) +#endif  // GTEST_HAS_GLOBAL_WSTRING + +#undef GTEST_FORMAT_IMPL_ + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings.  For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +//   expected_expression: "foo" +//   actual_expression:   "bar" +//   expected_value:      "5" +//   actual_value:        "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*.  When it's true, the string " (ignoring case)" will +// be inserted into the message. +AssertionResult EqFailure(const char* expected_expression, +                          const char* actual_expression, +                          const String& expected_value, +                          const String& actual_value, +                          bool ignoring_case); + + +// This template class represents an IEEE floating-point number +// (either single-precision or double-precision, depending on the +// template parameters). +// +// The purpose of this class is to do more sophisticated number +// comparison.  (Due to round-off error, etc, it's very unlikely that +// two floating-points will be equal exactly.  Hence a naive +// comparison by the == operation often doesn't work.) +// +// Format of IEEE floating-point: +// +//   The most-significant bit being the leftmost, an IEEE +//   floating-point looks like +// +//     sign_bit exponent_bits fraction_bits +// +//   Here, sign_bit is a single bit that designates the sign of the +//   number. +// +//   For float, there are 8 exponent bits and 23 fraction bits. +// +//   For double, there are 11 exponent bits and 52 fraction bits. +// +//   More details can be found at +//   http://en.wikipedia.org/wiki/IEEE_floating-point_standard. +// +// Template parameter: +// +//   RawType: the raw floating-point type (either float or double) +template <typename RawType> +class FloatingPoint { + public: +  // Defines the unsigned integer type that has the same size as the +  // floating point number. +  typedef typename TypeWithSize<sizeof(RawType)>::UInt Bits; + +  // Constants. + +  // # of bits in a number. +  static const size_t kBitCount = 8*sizeof(RawType); + +  // # of fraction bits in a number. +  static const size_t kFractionBitCount = +    std::numeric_limits<RawType>::digits - 1; + +  // # of exponent bits in a number. +  static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; + +  // The mask for the sign bit. +  static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1); + +  // The mask for the fraction bits. +  static const Bits kFractionBitMask = +    ~static_cast<Bits>(0) >> (kExponentBitCount + 1); + +  // The mask for the exponent bits. +  static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); + +  // How many ULP's (Units in the Last Place) we want to tolerate when +  // comparing two numbers.  The larger the value, the more error we +  // allow.  A 0 value means that two numbers must be exactly the same +  // to be considered equal. +  // +  // The maximum error of a single floating-point operation is 0.5 +  // units in the last place.  On Intel CPU's, all floating-point +  // calculations are done with 80-bit precision, while double has 64 +  // bits.  Therefore, 4 should be enough for ordinary use. +  // +  // See the following article for more details on ULP: +  // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm. +  static const size_t kMaxUlps = 4; + +  // Constructs a FloatingPoint from a raw floating-point number. +  // +  // On an Intel CPU, passing a non-normalized NAN (Not a Number) +  // 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) {} + +  // Static methods + +  // Reinterprets a bit pattern as a floating-point number. +  // +  // This function is needed to test the AlmostEquals() method. +  static RawType ReinterpretBits(const Bits bits) { +    FloatingPoint fp(0); +    fp.bits_ = bits; +    return fp.value_; +  } + +  // Returns the floating-point number that represent positive infinity. +  static RawType Infinity() { +    return ReinterpretBits(kExponentBitMask); +  } + +  // Non-static methods + +  // Returns the bits that represents this number. +  const Bits &bits() const { return bits_; } + +  // Returns the exponent bits of this number. +  Bits exponent_bits() const { return kExponentBitMask & bits_; } + +  // Returns the fraction bits of this number. +  Bits fraction_bits() const { return kFractionBitMask & bits_; } + +  // Returns the sign bit of this number. +  Bits sign_bit() const { return kSignBitMask & bits_; } + +  // Returns true iff this is NAN (not a number). +  bool is_nan() const { +    // It's a NAN if the exponent bits are all ones and the fraction +    // bits are not entirely zeros. +    return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); +  } + +  // Returns true iff this number is at most kMaxUlps ULP's away from +  // rhs.  In particular, this function: +  // +  //   - returns false if either number is (or both are) NAN. +  //   - treats really large numbers as almost equal to infinity. +  //   - thinks +0.0 and -0.0 are 0 DLP's apart. +  bool AlmostEquals(const FloatingPoint& rhs) const { +    // The IEEE standard says that any comparison operation involving +    // a NAN must return false. +    if (is_nan() || rhs.is_nan()) return false; + +    return DistanceBetweenSignAndMagnitudeNumbers(bits_, rhs.bits_) <= kMaxUlps; +  } + + private: +  // 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 +  // unsigned number x + N. +  // +  // For instance, +  // +  //   -N + 1 (the most negative number representable using +  //          sign-and-magnitude) is represented by 1; +  //   0      is represented by N; and +  //   N - 1  (the biggest number representable using +  //          sign-and-magnitude) is represented by 2N - 1. +  // +  // Read http://en.wikipedia.org/wiki/Signed_number_representations +  // for more details on signed number representations. +  static Bits SignAndMagnitudeToBiased(const Bits &sam) { +    if (kSignBitMask & sam) { +      // sam represents a negative number. +      return ~sam + 1; +    } else { +      // sam represents a positive number. +      return kSignBitMask | sam; +    } +  } + +  // Given two numbers in the sign-and-magnitude representation, +  // returns the distance between them as an unsigned number. +  static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, +                                                     const Bits &sam2) { +    const Bits biased1 = SignAndMagnitudeToBiased(sam1); +    const Bits biased2 = SignAndMagnitudeToBiased(sam2); +    return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); +  } + +  union { +    RawType value_;  // The raw floating-point number. +    Bits bits_;      // The bits that represent the number. +  }; +}; + +// Typedefs the instances of the FloatingPoint template class that we +// care to use. +typedef FloatingPoint<float> Float; +typedef FloatingPoint<double> Double; + +// In order to catch the mistake of putting tests that use different +// test fixture classes in the same test case, we need to assign +// unique IDs to fixture classes and compare them.  The TypeId type is +// used to hold such IDs.  The user should treat TypeId as an opaque +// type: the only operation allowed on TypeId values is to compare +// them for equality using the == operator. +typedef const void* TypeId; + +template <typename T> +class TypeIdHelper { + public: +  // dummy_ must not have a const type.  Otherwise an overly eager +  // compiler (e.g. MSVC 7.1 & 8.0) may try to merge +  // TypeIdHelper<T>::dummy_ for different Ts as an "optimization". +  static bool dummy_; +}; + +template <typename T> +bool TypeIdHelper<T>::dummy_ = false; + +// GetTypeId<T>() returns the ID of type T.  Different values will be +// returned for different types.  Calling the function twice with the +// same type argument is guaranteed to return the same ID. +template <typename T> +TypeId GetTypeId() { +  // The compiler is required to allocate a different +  // TypeIdHelper<T>::dummy_ variable for each T used to instantiate +  // the template.  Therefore, the address of dummy_ is guaranteed to +  // be unique. +  return &(TypeIdHelper<T>::dummy_); +} + +// Returns the type ID of ::testing::Test.  Always call this instead +// of GetTypeId< ::testing::Test>() to get the type ID of +// ::testing::Test, as the latter may give the wrong result due to a +// suspected linker bug when compiling Google Test as a Mac OS X +// framework. +TypeId GetTestTypeId(); + +// Defines the abstract factory interface that creates instances +// of a Test object. +class TestFactoryBase { + public: +  virtual ~TestFactoryBase() {} + +  // Creates a test instance to run. The instance is both created and destroyed +  // within TestInfoImpl::Run() +  virtual Test* CreateTest() = 0; + + protected: +  TestFactoryBase() {} + + private: +  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); +}; + +// This class provides implementation of TeastFactoryBase interface. +// It is used in TEST and TEST_F macros. +template <class TestClass> +class TestFactoryImpl : public TestFactoryBase { + public: +  virtual Test* CreateTest() { return new TestClass; } +}; + +#ifdef GTEST_OS_WINDOWS + +// Predicate-formatters for implementing the HRESULT checking macros +// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} +// We pass a long instead of HRESULT to avoid causing an +// include dependency for the HRESULT type. +AssertionResult IsHRESULTSuccess(const char* expr, long hr);  // NOLINT +AssertionResult IsHRESULTFailure(const char* expr, long hr);  // NOLINT + +#endif  // GTEST_OS_WINDOWS + +// Formats a source file path and a line number as they would appear +// in a compiler error message. +inline String FormatFileLocation(const char* file, int line) { +  const char* const file_name = file == NULL ? "unknown file" : file; +  if (line < 0) { +    return String::Format("%s:", file_name); +  } +#ifdef _MSC_VER +  return String::Format("%s(%d):", file_name, line); +#else +  return String::Format("%s:%d:", file_name, line); +#endif  // _MSC_VER +} + +// Types of SetUpTestCase() and TearDownTestCase() functions. +typedef void (*SetUpTestCaseFunc)(); +typedef void (*TearDownTestCaseFunc)(); + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +//   test_case_name:   name of the test case +//   name:             name of the test +//   test_case_comment: a comment on the test case that will be included in +//                      the test output +//   comment:          a comment on the test that will be included in the +//                     test output +//   fixture_class_id: ID of the test fixture class +//   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 +//   factory:          pointer to the factory that creates a test object. +//                     The newly created TestInfo instance will assume +//                     ownership of the factory object. +TestInfo* MakeAndRegisterTestInfo( +    const char* test_case_name, const char* name, +    const char* test_case_comment, const char* comment, +    TypeId fixture_class_id, +    SetUpTestCaseFunc set_up_tc, +    TearDownTestCaseFunc tear_down_tc, +    TestFactoryBase* factory); + +#if defined(GTEST_HAS_TYPED_TEST) || defined(GTEST_HAS_TYPED_TEST_P) + +// State of the definition of a type-parameterized test case. +class TypedTestCasePState { + public: +  TypedTestCasePState() : registered_(false) {} + +  // Adds the given test name to defined_test_names_ and return true +  // if the test case hasn't been registered; otherwise aborts the +  // program. +  bool AddTestName(const char* file, int line, const char* case_name, +                   const char* test_name) { +    if (registered_) { +      fprintf(stderr, "%s Test %s must be defined before " +              "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n", +              FormatFileLocation(file, line).c_str(), test_name, case_name); +      abort(); +    } +    defined_test_names_.insert(test_name); +    return true; +  } + +  // Verifies that registered_tests match the test names in +  // defined_test_names_; returns registered_tests if successful, or +  // aborts the program otherwise. +  const char* VerifyRegisteredTestNames( +      const char* file, int line, const char* registered_tests); + + private: +  bool registered_; +  ::std::set<const char*> defined_test_names_; +}; + +// Skips to the first non-space char after the first comma in 'str'; +// returns NULL if no comma is found in 'str'. +inline const char* SkipComma(const char* str) { +  const char* comma = strchr(str, ','); +  if (comma == NULL) { +    return NULL; +  } +  while (isspace(*(++comma))) {} +  return comma; +} + +// Returns the prefix of 'str' before the first comma in it; returns +// the entire string if it contains no comma. +inline String GetPrefixUntilComma(const char* str) { +  const char* comma = strchr(str, ','); +  return comma == NULL ? String(str) : String(str, comma - str); +} + +// TypeParameterizedTest<Fixture, TestSel, Types>::Register() +// registers a list of type-parameterized tests with Google Test.  The +// return value is insignificant - we just need to return something +// such that we can call this function in a namespace scope. +// +// Implementation note: The GTEST_TEMPLATE_ macro declares a template +// template parameter.  It's defined in gtest-type-util.h. +template <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types> +class TypeParameterizedTest { + public: +  // 'index' is the index of the test in the type list 'Types' +  // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase, +  // Types).  Valid values for 'index' are [0, N - 1] where N is the +  // length of Types. +  static bool Register(const char* prefix, const char* case_name, +                       const char* test_names, int index) { +    typedef typename Types::Head Type; +    typedef Fixture<Type> FixtureClass; +    typedef typename GTEST_BIND_(TestSel, Type) TestClass; + +    // First, registers the first type-parameterized test in the type +    // list. +    MakeAndRegisterTestInfo( +        String::Format("%s%s%s/%d", prefix, prefix[0] == '\0' ? "" : "/", +                       case_name, index).c_str(), +        GetPrefixUntilComma(test_names).c_str(), +        String::Format("TypeParam = %s", GetTypeName<Type>().c_str()).c_str(), +        "", +        GetTypeId<FixtureClass>(), +        TestClass::SetUpTestCase, +        TestClass::TearDownTestCase, +        new TestFactoryImpl<TestClass>); + +    // Next, recurses (at compile time) with the tail of the type list. +    return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail> +        ::Register(prefix, case_name, test_names, index + 1); +  } +}; + +// The base case for the compile time recursion. +template <GTEST_TEMPLATE_ Fixture, class TestSel> +class TypeParameterizedTest<Fixture, TestSel, Types0> { + public: +  static bool Register(const char* /*prefix*/, const char* /*case_name*/, +                       const char* /*test_names*/, int /*index*/) { +    return true; +  } +}; + +// TypeParameterizedTestCase<Fixture, Tests, Types>::Register() +// registers *all combinations* of 'Tests' and 'Types' with Google +// Test.  The return value is insignificant - we just need to return +// something such that we can call this function in a namespace scope. +template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types> +class TypeParameterizedTestCase { + public: +  static bool Register(const char* prefix, const char* case_name, +                       const char* test_names) { +    typedef typename Tests::Head Head; + +    // First, register the first test in 'Test' for each type in 'Types'. +    TypeParameterizedTest<Fixture, Head, Types>::Register( +        prefix, case_name, test_names, 0); + +    // Next, recurses (at compile time) with the tail of the test list. +    return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types> +        ::Register(prefix, case_name, SkipComma(test_names)); +  } +}; + +// The base case for the compile time recursion. +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) { +    return true; +  } +}; + +#endif  // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// Returns the current OS stack trace as a String. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag.  The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// 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); + +}  // namespace internal +}  // namespace testing + +#define GTEST_MESSAGE_(message, result_type) \ +  ::testing::internal::AssertHelper(result_type, __FILE__, __LINE__, message) \ +    = ::testing::Message() + +#define GTEST_FATAL_FAILURE_(message) \ +  return GTEST_MESSAGE_(message, ::testing::TPRT_FATAL_FAILURE) + +#define GTEST_NONFATAL_FAILURE_(message) \ +  GTEST_MESSAGE_(message, ::testing::TPRT_NONFATAL_FAILURE) + +#define GTEST_SUCCESS_(message) \ +  GTEST_MESSAGE_(message, ::testing::TPRT_SUCCESS) + +#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ +  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ +  if (const char* gtest_msg = "") { \ +    bool gtest_caught_expected = false; \ +    try { \ +      statement; \ +    } \ +    catch (expected_exception const&) { \ +      gtest_caught_expected = true; \ +    } \ +    catch (...) { \ +      gtest_msg = "Expected: " #statement " throws an exception of type " \ +                  #expected_exception ".\n  Actual: it throws a different " \ +                  "type."; \ +      goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ +    } \ +    if (!gtest_caught_expected) { \ +      gtest_msg = "Expected: " #statement " throws an exception of type " \ +                  #expected_exception ".\n  Actual: it throws nothing."; \ +      goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ +    } \ +  } else \ +    GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ +      fail(gtest_msg) + +#define GTEST_TEST_NO_THROW_(statement, fail) \ +  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ +  if (const char* gtest_msg = "") { \ +    try { \ +      statement; \ +    } \ +    catch (...) { \ +      gtest_msg = "Expected: " #statement " doesn't throw an exception.\n" \ +                  "  Actual: it throws."; \ +      goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ +    } \ +  } else \ +    GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ +      fail(gtest_msg) + +#define GTEST_TEST_ANY_THROW_(statement, fail) \ +  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ +  if (const char* gtest_msg = "") { \ +    bool gtest_caught_any = false; \ +    try { \ +      statement; \ +    } \ +    catch (...) { \ +      gtest_caught_any = true; \ +    } \ +    if (!gtest_caught_any) { \ +      gtest_msg = "Expected: " #statement " throws an exception.\n" \ +                  "  Actual: it doesn't."; \ +      goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ +    } \ +  } else \ +    GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ +      fail(gtest_msg) + + +#define GTEST_TEST_BOOLEAN_(boolexpr, booltext, actual, expected, fail) \ +  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ +  if (boolexpr) \ +    ; \ +  else \ +    fail("Value of: " booltext "\n  Actual: " #actual "\nExpected: " #expected) + +#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ +  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ +  if (const char* gtest_msg = "") { \ +    ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ +    { 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" \ +                  "  Actual: it does."; \ +      goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ +    } \ +  } else \ +    GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ +      fail(gtest_msg) + +// Expands to the name of the class that implements the given test. +#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ +  test_case_name##_##test_name##_Test + +// Helper macro for defining tests. +#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\ +class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ + public:\ +  GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ + private:\ +  virtual void TestBody();\ +  static ::testing::TestInfo* const test_info_;\ +  GTEST_DISALLOW_COPY_AND_ASSIGN_(\ +      GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ +};\ +\ +::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ +  ::test_info_ =\ +    ::testing::internal::MakeAndRegisterTestInfo(\ +        #test_case_name, #test_name, "", "", \ +        (parent_id), \ +        parent_class::SetUpTestCase, \ +        parent_class::TearDownTestCase, \ +        new ::testing::internal::TestFactoryImpl<\ +            GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ +void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ diff --git a/llvm/utils/unittest/googletest/include/gtest/internal/gtest-linked_ptr.h b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-linked_ptr.h new file mode 100644 index 00000000000..f98af0b123b --- /dev/null +++ b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-linked_ptr.h @@ -0,0 +1,242 @@ +// Copyright 2003 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. +// +// Authors: Dan Egnor (egnor@google.com) +// +// A "smart" pointer type with reference tracking.  Every pointer to a +// particular object is kept on a circular linked list.  When the last pointer +// to an object is destroyed or reassigned, the object is deleted. +// +// Used properly, this deletes the object when the last reference goes away. +// There are several caveats: +// - Like all reference counting schemes, cycles lead to leaks. +// - Each smart pointer is actually two pointers (8 bytes instead of 4). +// - Every time a pointer is assigned, the entire list of pointers to that +//   object is traversed.  This class is therefore NOT SUITABLE when there +//   will often be more than two or three pointers to a particular object. +// - References are only tracked as long as linked_ptr<> objects are copied. +//   If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS +//   will happen (double deletion). +// +// A good use of this class is storing object references in STL containers. +// You can safely put linked_ptr<> in a vector<>. +// Other uses may not be as good. +// +// Note: If you use an incomplete type with linked_ptr<>, the class +// *containing* linked_ptr<> must have a constructor and destructor (even +// if they do nothing!). +// +// Bill Gibbons suggested we use something like this. +// +// Thread Safety: +//   Unlike other linked_ptr implementations, in this implementation +//   a linked_ptr object is thread-safe in the sense that: +//     - it's safe to copy linked_ptr objects concurrently, +//     - it's safe to copy *from* a linked_ptr and read its underlying +//       raw pointer (e.g. via get()) concurrently, and +//     - it's safe to write to two linked_ptrs that point to the same +//       shared object concurrently. +// TODO(wan@google.com): rename this to safe_linked_ptr to avoid +// confusion with normal linked_ptr. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ + +#include <stdlib.h> +#include <assert.h> + +#include <gtest/internal/gtest-port.h> + +namespace testing { +namespace internal { + +// Protects copying of all linked_ptr objects. +extern Mutex g_linked_ptr_mutex; + +// This is used internally by all instances of linked_ptr<>.  It needs to be +// a non-template class because different types of linked_ptr<> can refer to +// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)). +// So, it needs to be possible for different types of linked_ptr to participate +// in the same circular linked list, so we need a single class type here. +// +// DO NOT USE THIS CLASS DIRECTLY YOURSELF.  Use linked_ptr<T>. +class linked_ptr_internal { + public: +  // Create a new circle that includes only this instance. +  void join_new() { +    next_ = this; +  } + +  // Many linked_ptr operations may change p.link_ for some linked_ptr +  // variable p in the same circle as this object.  Therefore we need +  // to prevent two such operations from occurring concurrently. +  // +  // Note that different types of linked_ptr objects can coexist in a +  // circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and +  // linked_ptr<Derived2>).  Therefore we must use a single mutex to +  // protect all linked_ptr objects.  This can create serious +  // contention in production code, but is acceptable in a testing +  // framework. + +  // Join an existing circle. +  // L < g_linked_ptr_mutex +  void join(linked_ptr_internal const* ptr) { +    MutexLock lock(&g_linked_ptr_mutex); + +    linked_ptr_internal const* p = ptr; +    while (p->next_ != ptr) p = p->next_; +    p->next_ = this; +    next_ = ptr; +  } + +  // Leave whatever circle we're part of.  Returns true if we were the +  // last member of the circle.  Once this is done, you can join() another. +  // L < g_linked_ptr_mutex +  bool depart() { +    MutexLock lock(&g_linked_ptr_mutex); + +    if (next_ == this) return true; +    linked_ptr_internal const* p = next_; +    while (p->next_ != this) p = p->next_; +    p->next_ = next_; +    return false; +  } + + private: +  mutable linked_ptr_internal const* next_; +}; + +template <typename T> +class linked_ptr { + public: +  typedef T element_type; + +  // Take over ownership of a raw pointer.  This should happen as soon as +  // possible after the object is created. +  explicit linked_ptr(T* ptr = NULL) { capture(ptr); } +  ~linked_ptr() { depart(); } + +  // Copy an existing linked_ptr<>, adding ourselves to the list of references. +  template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); } +  linked_ptr(linked_ptr const& ptr) {  // NOLINT +    assert(&ptr != this); +    copy(&ptr); +  } + +  // Assignment releases the old value and acquires the new. +  template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) { +    depart(); +    copy(&ptr); +    return *this; +  } + +  linked_ptr& operator=(linked_ptr const& ptr) { +    if (&ptr != this) { +      depart(); +      copy(&ptr); +    } +    return *this; +  } + +  // Smart pointer members. +  void reset(T* ptr = NULL) { +    depart(); +    capture(ptr); +  } +  T* get() const { return value_; } +  T* operator->() const { return value_; } +  T& operator*() const { return *value_; } +  // Release ownership of the pointed object and returns it. +  // Sole ownership by this linked_ptr object is required. +  T* release() { +    bool last = link_.depart(); +    assert(last); +    T* v = value_; +    value_ = NULL; +    return v; +  } + +  bool operator==(T* p) const { return value_ == p; } +  bool operator!=(T* p) const { return value_ != p; } +  template <typename U> +  bool operator==(linked_ptr<U> const& ptr) const { +    return value_ == ptr.get(); +  } +  template <typename U> +  bool operator!=(linked_ptr<U> const& ptr) const { +    return value_ != ptr.get(); +  } + + private: +  template <typename U> +  friend class linked_ptr; + +  T* value_; +  linked_ptr_internal link_; + +  void depart() { +    if (link_.depart()) delete value_; +  } + +  void capture(T* ptr) { +    value_ = ptr; +    link_.join_new(); +  } + +  template <typename U> void copy(linked_ptr<U> const* ptr) { +    value_ = ptr->get(); +    if (value_) +      link_.join(&ptr->link_); +    else +      link_.join_new(); +  } +}; + +template<typename T> inline +bool operator==(T* ptr, const linked_ptr<T>& x) { +  return ptr == x.get(); +} + +template<typename T> inline +bool operator!=(T* ptr, const linked_ptr<T>& x) { +  return ptr != x.get(); +} + +// A function to convert T* into linked_ptr<T> +// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation +// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) +template <typename T> +linked_ptr<T> make_linked_ptr(T* ptr) { +  return linked_ptr<T>(ptr); +} + +}  // namespace internal +}  // namespace testing + +#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ diff --git a/llvm/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h new file mode 100644 index 00000000000..17f3f7bf97d --- /dev/null +++ b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h @@ -0,0 +1,4572 @@ +// This file was GENERATED by a script.  DO NOT EDIT BY HAND!!! + +// Copyright 2008 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: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. +// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND! +// +// Currently Google Test supports at most 50 arguments in Values, +// and at most 10 arguments in Combine. Please contact +// googletestframework@googlegroups.com if you need more. +// Please note that the number of arguments to Combine is limited +// by the maximum arity of the implementation of tr1::tuple which is +// currently set at 10. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ + +#include <gtest/internal/gtest-port.h> + +#ifdef GTEST_HAS_PARAM_TEST + +#include <gtest/internal/gtest-param-util.h> + +namespace testing { +namespace internal { + +// Used in the Values() function to provide polymorphic capabilities. +template <typename T1> +class ValueArray1 { + public: +  explicit ValueArray1(T1 v1) : v1_(v1) {} + +  template <typename T> +  operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); } + + private: +  const T1 v1_; +}; + +template <typename T1, typename T2> +class ValueArray2 { + public: +  ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +}; + +template <typename T1, typename T2, typename T3> +class ValueArray3 { + public: +  ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +}; + +template <typename T1, typename T2, typename T3, typename T4> +class ValueArray4 { + public: +  ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3), +      v4_(v4) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5> +class ValueArray5 { + public: +  ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3), +      v4_(v4), v5_(v5) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6> +class ValueArray6 { + public: +  ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2), +      v3_(v3), v4_(v4), v5_(v5), v6_(v6) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7> +class ValueArray7 { + public: +  ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1), +      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8> +class ValueArray8 { + public: +  ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, +      T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), +      v8_(v8) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9> +class ValueArray9 { + public: +  ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, +      T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), +      v8_(v8), v9_(v9) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10> +class ValueArray10 { + public: +  ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), +      v8_(v8), v9_(v9), v10_(v10) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11> +class ValueArray11 { + public: +  ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), +      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12> +class ValueArray12 { + public: +  ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), +      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13> +class ValueArray13 { + public: +  ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), +      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), +      v12_(v12), v13_(v13) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14> +class ValueArray14 { + public: +  ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3), +      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), +      v11_(v11), v12_(v12), v13_(v13), v14_(v14) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15> +class ValueArray15 { + public: +  ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2), +      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), +      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16> +class ValueArray16 { + public: +  ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1), +      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), +      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), +      v16_(v16) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17> +class ValueArray17 { + public: +  ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, +      T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), +      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), +      v15_(v15), v16_(v16), v17_(v17) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18> +class ValueArray18 { + public: +  ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), +      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), +      v15_(v15), v16_(v16), v17_(v17), v18_(v18) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19> +class ValueArray19 { + public: +  ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), +      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), +      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20> +class ValueArray20 { + public: +  ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), +      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), +      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), +      v19_(v19), v20_(v20) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21> +class ValueArray21 { + public: +  ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), +      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), +      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), +      v18_(v18), v19_(v19), v20_(v20), v21_(v21) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22> +class ValueArray22 { + public: +  ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3), +      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), +      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), +      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23> +class ValueArray23 { + public: +  ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2), +      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), +      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), +      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), +      v23_(v23) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, +        v23_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24> +class ValueArray24 { + public: +  ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1), +      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), +      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), +      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), +      v22_(v22), v23_(v23), v24_(v24) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25> +class ValueArray25 { + public: +  ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, +      T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), +      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), +      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), +      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26> +class ValueArray26 { + public: +  ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), +      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), +      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), +      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27> +class ValueArray27 { + public: +  ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), +      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), +      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), +      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), +      v26_(v26), v27_(v27) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28> +class ValueArray28 { + public: +  ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), +      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), +      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), +      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), +      v25_(v25), v26_(v26), v27_(v27), v28_(v28) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29> +class ValueArray29 { + public: +  ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), +      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), +      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), +      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), +      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30> +class ValueArray30 { + public: +  ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3), +      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), +      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), +      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), +      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), +      v29_(v29), v30_(v30) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31> +class ValueArray31 { + public: +  ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2), +      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), +      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), +      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), +      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), +      v29_(v29), v30_(v30), v31_(v31) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32> +class ValueArray32 { + public: +  ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1), +      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), +      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), +      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), +      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), +      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33> +class ValueArray33 { + public: +  ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, +      T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), +      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), +      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), +      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), +      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), +      v33_(v33) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +  const T33 v33_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34> +class ValueArray34 { + public: +  ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +      T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), +      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), +      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), +      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), +      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), +      v33_(v33), v34_(v34) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +  const T33 v33_; +  const T34 v34_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35> +class ValueArray35 { + public: +  ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +      T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), +      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), +      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), +      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), +      v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), +      v32_(v32), v33_(v33), v34_(v34), v35_(v35) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, +        v35_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +  const T33 v33_; +  const T34 v34_; +  const T35 v35_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36> +class ValueArray36 { + public: +  ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +      T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), +      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), +      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), +      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), +      v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), +      v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, +        v36_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +  const T33 v33_; +  const T34 v34_; +  const T35 v35_; +  const T36 v36_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37> +class ValueArray37 { + public: +  ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +      T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), +      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), +      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), +      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), +      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), +      v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), +      v36_(v36), v37_(v37) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, +        v36_, v37_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +  const T33 v33_; +  const T34 v34_; +  const T35 v35_; +  const T36 v36_; +  const T37 v37_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38> +class ValueArray38 { + public: +  ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3), +      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), +      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), +      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), +      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), +      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), +      v35_(v35), v36_(v36), v37_(v37), v38_(v38) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, +        v36_, v37_, v38_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +  const T33 v33_; +  const T34 v34_; +  const T35 v35_; +  const T36 v36_; +  const T37 v37_; +  const T38 v38_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39> +class ValueArray39 { + public: +  ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2), +      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), +      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), +      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), +      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), +      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), +      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, +        v36_, v37_, v38_, v39_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +  const T33 v33_; +  const T34 v34_; +  const T35 v35_; +  const T36 v36_; +  const T37 v37_; +  const T38 v38_; +  const T39 v39_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40> +class ValueArray40 { + public: +  ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1), +      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), +      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), +      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), +      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), +      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), +      v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), +      v40_(v40) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, +        v36_, v37_, v38_, v39_, v40_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +  const T33 v33_; +  const T34 v34_; +  const T35 v35_; +  const T36 v36_; +  const T37 v37_; +  const T38 v38_; +  const T39 v39_; +  const T40 v40_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41> +class ValueArray41 { + public: +  ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, +      T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), +      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), +      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), +      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), +      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), +      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), +      v39_(v39), v40_(v40), v41_(v41) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, +        v36_, v37_, v38_, v39_, v40_, v41_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +  const T33 v33_; +  const T34 v34_; +  const T35 v35_; +  const T36 v36_; +  const T37 v37_; +  const T38 v38_; +  const T39 v39_; +  const T40 v40_; +  const T41 v41_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42> +class ValueArray42 { + public: +  ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, +      T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), +      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), +      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), +      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), +      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), +      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), +      v39_(v39), v40_(v40), v41_(v41), v42_(v42) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, +        v36_, v37_, v38_, v39_, v40_, v41_, v42_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +  const T33 v33_; +  const T34 v34_; +  const T35 v35_; +  const T36 v36_; +  const T37 v37_; +  const T38 v38_; +  const T39 v39_; +  const T40 v40_; +  const T41 v41_; +  const T42 v42_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43> +class ValueArray43 { + public: +  ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, +      T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), +      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), +      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), +      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), +      v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), +      v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), +      v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, +        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +  const T33 v33_; +  const T34 v34_; +  const T35 v35_; +  const T36 v36_; +  const T37 v37_; +  const T38 v38_; +  const T39 v39_; +  const T40 v40_; +  const T41 v41_; +  const T42 v42_; +  const T43 v43_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44> +class ValueArray44 { + public: +  ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, +      T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), +      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), +      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), +      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), +      v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), +      v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), +      v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), +      v43_(v43), v44_(v44) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, +        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +  const T33 v33_; +  const T34 v34_; +  const T35 v35_; +  const T36 v36_; +  const T37 v37_; +  const T38 v38_; +  const T39 v39_; +  const T40 v40_; +  const T41 v41_; +  const T42 v42_; +  const T43 v43_; +  const T44 v44_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45> +class ValueArray45 { + public: +  ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, +      T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), +      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), +      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), +      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), +      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), +      v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), +      v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), +      v42_(v42), v43_(v43), v44_(v44), v45_(v45) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, +        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +  const T33 v33_; +  const T34 v34_; +  const T35 v35_; +  const T36 v36_; +  const T37 v37_; +  const T38 v38_; +  const T39 v39_; +  const T40 v40_; +  const T41 v41_; +  const T42 v42_; +  const T43 v43_; +  const T44 v44_; +  const T45 v45_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46> +class ValueArray46 { + public: +  ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, +      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3), +      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), +      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), +      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), +      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), +      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), +      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), +      v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, +        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +  const T33 v33_; +  const T34 v34_; +  const T35 v35_; +  const T36 v36_; +  const T37 v37_; +  const T38 v38_; +  const T39 v39_; +  const T40 v40_; +  const T41 v41_; +  const T42 v42_; +  const T43 v43_; +  const T44 v44_; +  const T45 v45_; +  const T46 v46_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46, typename T47> +class ValueArray47 { + public: +  ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, +      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2), +      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), +      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), +      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), +      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), +      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), +      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), +      v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), +      v47_(v47) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, +        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, +        v47_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +  const T33 v33_; +  const T34 v34_; +  const T35 v35_; +  const T36 v36_; +  const T37 v37_; +  const T38 v38_; +  const T39 v39_; +  const T40 v40_; +  const T41 v41_; +  const T42 v42_; +  const T43 v43_; +  const T44 v44_; +  const T45 v45_; +  const T46 v46_; +  const T47 v47_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46, typename T47, typename T48> +class ValueArray48 { + public: +  ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, +      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1), +      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), +      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), +      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), +      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), +      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), +      v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), +      v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), +      v46_(v46), v47_(v47), v48_(v48) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, +        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_, +        v48_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +  const T33 v33_; +  const T34 v34_; +  const T35 v35_; +  const T36 v36_; +  const T37 v37_; +  const T38 v38_; +  const T39 v39_; +  const T40 v40_; +  const T41 v41_; +  const T42 v42_; +  const T43 v43_; +  const T44 v44_; +  const T45 v45_; +  const T46 v46_; +  const T47 v47_; +  const T48 v48_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46, typename T47, typename T48, typename T49> +class ValueArray49 { + public: +  ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, +      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, +      T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), +      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), +      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), +      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), +      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), +      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), +      v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), +      v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, +        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_, +        v48_, v49_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +  const T33 v33_; +  const T34 v34_; +  const T35 v35_; +  const T36 v36_; +  const T37 v37_; +  const T38 v38_; +  const T39 v39_; +  const T40 v40_; +  const T41 v41_; +  const T42 v42_; +  const T43 v43_; +  const T44 v44_; +  const T45 v45_; +  const T46 v46_; +  const T47 v47_; +  const T48 v48_; +  const T49 v49_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46, typename T47, typename T48, typename T49, typename T50> +class ValueArray50 { + public: +  ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, +      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, +      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, +      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, +      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, +      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, +      T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), +      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), +      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), +      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), +      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), +      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), +      v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), +      v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {} + +  template <typename T> +  operator ParamGenerator<T>() const { +    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, +        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, +        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, +        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_, +        v48_, v49_, v50_}; +    return ValuesIn(array); +  } + + private: +  const T1 v1_; +  const T2 v2_; +  const T3 v3_; +  const T4 v4_; +  const T5 v5_; +  const T6 v6_; +  const T7 v7_; +  const T8 v8_; +  const T9 v9_; +  const T10 v10_; +  const T11 v11_; +  const T12 v12_; +  const T13 v13_; +  const T14 v14_; +  const T15 v15_; +  const T16 v16_; +  const T17 v17_; +  const T18 v18_; +  const T19 v19_; +  const T20 v20_; +  const T21 v21_; +  const T22 v22_; +  const T23 v23_; +  const T24 v24_; +  const T25 v25_; +  const T26 v26_; +  const T27 v27_; +  const T28 v28_; +  const T29 v29_; +  const T30 v30_; +  const T31 v31_; +  const T32 v32_; +  const T33 v33_; +  const T34 v34_; +  const T35 v35_; +  const T36 v36_; +  const T37 v37_; +  const T38 v38_; +  const T39 v39_; +  const T40 v40_; +  const T41 v41_; +  const T42 v42_; +  const T43 v43_; +  const T44 v44_; +  const T45 v45_; +  const T46 v46_; +  const T47 v47_; +  const T48 v48_; +  const T49 v49_; +  const T50 v50_; +}; + +#ifdef GTEST_HAS_COMBINE +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Generates values from the Cartesian product of values produced +// by the argument generators. +// +template <typename T1, typename T2> +class CartesianProductGenerator2 +    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2> > { + public: +  typedef ::std::tr1::tuple<T1, T2> ParamType; + +  CartesianProductGenerator2(const ParamGenerator<T1>& g1, +      const ParamGenerator<T2>& g2) +      : g1_(g1), g2_(g2) {} +  virtual ~CartesianProductGenerator2() {} + +  virtual ParamIteratorInterface<ParamType>* Begin() const { +    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin()); +  } +  virtual ParamIteratorInterface<ParamType>* End() const { +    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end()); +  } + + private: +  class Iterator : public ParamIteratorInterface<ParamType> { +   public: +    Iterator(const ParamGeneratorInterface<ParamType>* base, +      const ParamGenerator<T1>& g1, +      const typename ParamGenerator<T1>::iterator& current1, +      const ParamGenerator<T2>& g2, +      const typename ParamGenerator<T2>::iterator& current2) +        : base_(base), +          begin1_(g1.begin()), end1_(g1.end()), current1_(current1), +          begin2_(g2.begin()), end2_(g2.end()), current2_(current2)    { +      ComputeCurrentValue(); +    } +    virtual ~Iterator() {} + +    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { +      return base_; +    } +    // Advance should not be called on beyond-of-range iterators +    // so no component iterators must be beyond end of range, either. +    virtual void Advance() { +      assert(!AtEnd()); +      ++current2_; +      if (current2_ == end2_) { +        current2_ = begin2_; +        ++current1_; +      } +      ComputeCurrentValue(); +    } +    virtual ParamIteratorInterface<ParamType>* Clone() const { +      return new Iterator(*this); +    } +    virtual const ParamType* Current() const { return ¤t_value_; } +    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { +      // Having the same base generator guarantees that the other +      // iterator is of the same type and we can downcast. +      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) +          << "The program attempted to compare iterators " +          << "from different generators." << std::endl; +      const Iterator* typed_other = +          CheckedDowncastToActualType<const Iterator>(&other); +      // We must report iterators equal if they both point beyond their +      // respective ranges. That can happen in a variety of fashions, +      // so we have to consult AtEnd(). +      return (AtEnd() && typed_other->AtEnd()) || +         ( +          current1_ == typed_other->current1_ && +          current2_ == typed_other->current2_); +    } + +   private: +    Iterator(const Iterator& other) +        : base_(other.base_), +        begin1_(other.begin1_), +        end1_(other.end1_), +        current1_(other.current1_), +        begin2_(other.begin2_), +        end2_(other.end2_), +        current2_(other.current2_) { +      ComputeCurrentValue(); +    } + +    void ComputeCurrentValue() { +      if (!AtEnd()) +        current_value_ = ParamType(*current1_, *current2_); +    } +    bool AtEnd() const { +      // We must report iterator past the end of the range when either of the +      // component iterators has reached the end of its range. +      return +          current1_ == end1_ || +          current2_ == end2_; +    } + +    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. +    const typename ParamGenerator<T1>::iterator begin1_; +    const typename ParamGenerator<T1>::iterator end1_; +    typename ParamGenerator<T1>::iterator current1_; +    const typename ParamGenerator<T2>::iterator begin2_; +    const typename ParamGenerator<T2>::iterator end2_; +    typename ParamGenerator<T2>::iterator current2_; +    ParamType current_value_; +  }; + +  const ParamGenerator<T1> g1_; +  const ParamGenerator<T2> g2_; +}; + + +template <typename T1, typename T2, typename T3> +class CartesianProductGenerator3 +    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3> > { + public: +  typedef ::std::tr1::tuple<T1, T2, T3> ParamType; + +  CartesianProductGenerator3(const ParamGenerator<T1>& g1, +      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3) +      : g1_(g1), g2_(g2), g3_(g3) {} +  virtual ~CartesianProductGenerator3() {} + +  virtual ParamIteratorInterface<ParamType>* Begin() const { +    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, +        g3_.begin()); +  } +  virtual ParamIteratorInterface<ParamType>* End() const { +    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end()); +  } + + private: +  class Iterator : public ParamIteratorInterface<ParamType> { +   public: +    Iterator(const ParamGeneratorInterface<ParamType>* base, +      const ParamGenerator<T1>& g1, +      const typename ParamGenerator<T1>::iterator& current1, +      const ParamGenerator<T2>& g2, +      const typename ParamGenerator<T2>::iterator& current2, +      const ParamGenerator<T3>& g3, +      const typename ParamGenerator<T3>::iterator& current3) +        : base_(base), +          begin1_(g1.begin()), end1_(g1.end()), current1_(current1), +          begin2_(g2.begin()), end2_(g2.end()), current2_(current2), +          begin3_(g3.begin()), end3_(g3.end()), current3_(current3)    { +      ComputeCurrentValue(); +    } +    virtual ~Iterator() {} + +    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { +      return base_; +    } +    // Advance should not be called on beyond-of-range iterators +    // so no component iterators must be beyond end of range, either. +    virtual void Advance() { +      assert(!AtEnd()); +      ++current3_; +      if (current3_ == end3_) { +        current3_ = begin3_; +        ++current2_; +      } +      if (current2_ == end2_) { +        current2_ = begin2_; +        ++current1_; +      } +      ComputeCurrentValue(); +    } +    virtual ParamIteratorInterface<ParamType>* Clone() const { +      return new Iterator(*this); +    } +    virtual const ParamType* Current() const { return ¤t_value_; } +    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { +      // Having the same base generator guarantees that the other +      // iterator is of the same type and we can downcast. +      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) +          << "The program attempted to compare iterators " +          << "from different generators." << std::endl; +      const Iterator* typed_other = +          CheckedDowncastToActualType<const Iterator>(&other); +      // We must report iterators equal if they both point beyond their +      // respective ranges. That can happen in a variety of fashions, +      // so we have to consult AtEnd(). +      return (AtEnd() && typed_other->AtEnd()) || +         ( +          current1_ == typed_other->current1_ && +          current2_ == typed_other->current2_ && +          current3_ == typed_other->current3_); +    } + +   private: +    Iterator(const Iterator& other) +        : base_(other.base_), +        begin1_(other.begin1_), +        end1_(other.end1_), +        current1_(other.current1_), +        begin2_(other.begin2_), +        end2_(other.end2_), +        current2_(other.current2_), +        begin3_(other.begin3_), +        end3_(other.end3_), +        current3_(other.current3_) { +      ComputeCurrentValue(); +    } + +    void ComputeCurrentValue() { +      if (!AtEnd()) +        current_value_ = ParamType(*current1_, *current2_, *current3_); +    } +    bool AtEnd() const { +      // We must report iterator past the end of the range when either of the +      // component iterators has reached the end of its range. +      return +          current1_ == end1_ || +          current2_ == end2_ || +          current3_ == end3_; +    } + +    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. +    const typename ParamGenerator<T1>::iterator begin1_; +    const typename ParamGenerator<T1>::iterator end1_; +    typename ParamGenerator<T1>::iterator current1_; +    const typename ParamGenerator<T2>::iterator begin2_; +    const typename ParamGenerator<T2>::iterator end2_; +    typename ParamGenerator<T2>::iterator current2_; +    const typename ParamGenerator<T3>::iterator begin3_; +    const typename ParamGenerator<T3>::iterator end3_; +    typename ParamGenerator<T3>::iterator current3_; +    ParamType current_value_; +  }; + +  const ParamGenerator<T1> g1_; +  const ParamGenerator<T2> g2_; +  const ParamGenerator<T3> g3_; +}; + + +template <typename T1, typename T2, typename T3, typename T4> +class CartesianProductGenerator4 +    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4> > { + public: +  typedef ::std::tr1::tuple<T1, T2, T3, T4> ParamType; + +  CartesianProductGenerator4(const ParamGenerator<T1>& g1, +      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, +      const ParamGenerator<T4>& g4) +      : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} +  virtual ~CartesianProductGenerator4() {} + +  virtual ParamIteratorInterface<ParamType>* Begin() const { +    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, +        g3_.begin(), g4_, g4_.begin()); +  } +  virtual ParamIteratorInterface<ParamType>* End() const { +    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), +        g4_, g4_.end()); +  } + + private: +  class Iterator : public ParamIteratorInterface<ParamType> { +   public: +    Iterator(const ParamGeneratorInterface<ParamType>* base, +      const ParamGenerator<T1>& g1, +      const typename ParamGenerator<T1>::iterator& current1, +      const ParamGenerator<T2>& g2, +      const typename ParamGenerator<T2>::iterator& current2, +      const ParamGenerator<T3>& g3, +      const typename ParamGenerator<T3>::iterator& current3, +      const ParamGenerator<T4>& g4, +      const typename ParamGenerator<T4>::iterator& current4) +        : base_(base), +          begin1_(g1.begin()), end1_(g1.end()), current1_(current1), +          begin2_(g2.begin()), end2_(g2.end()), current2_(current2), +          begin3_(g3.begin()), end3_(g3.end()), current3_(current3), +          begin4_(g4.begin()), end4_(g4.end()), current4_(current4)    { +      ComputeCurrentValue(); +    } +    virtual ~Iterator() {} + +    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { +      return base_; +    } +    // Advance should not be called on beyond-of-range iterators +    // so no component iterators must be beyond end of range, either. +    virtual void Advance() { +      assert(!AtEnd()); +      ++current4_; +      if (current4_ == end4_) { +        current4_ = begin4_; +        ++current3_; +      } +      if (current3_ == end3_) { +        current3_ = begin3_; +        ++current2_; +      } +      if (current2_ == end2_) { +        current2_ = begin2_; +        ++current1_; +      } +      ComputeCurrentValue(); +    } +    virtual ParamIteratorInterface<ParamType>* Clone() const { +      return new Iterator(*this); +    } +    virtual const ParamType* Current() const { return ¤t_value_; } +    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { +      // Having the same base generator guarantees that the other +      // iterator is of the same type and we can downcast. +      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) +          << "The program attempted to compare iterators " +          << "from different generators." << std::endl; +      const Iterator* typed_other = +          CheckedDowncastToActualType<const Iterator>(&other); +      // We must report iterators equal if they both point beyond their +      // respective ranges. That can happen in a variety of fashions, +      // so we have to consult AtEnd(). +      return (AtEnd() && typed_other->AtEnd()) || +         ( +          current1_ == typed_other->current1_ && +          current2_ == typed_other->current2_ && +          current3_ == typed_other->current3_ && +          current4_ == typed_other->current4_); +    } + +   private: +    Iterator(const Iterator& other) +        : base_(other.base_), +        begin1_(other.begin1_), +        end1_(other.end1_), +        current1_(other.current1_), +        begin2_(other.begin2_), +        end2_(other.end2_), +        current2_(other.current2_), +        begin3_(other.begin3_), +        end3_(other.end3_), +        current3_(other.current3_), +        begin4_(other.begin4_), +        end4_(other.end4_), +        current4_(other.current4_) { +      ComputeCurrentValue(); +    } + +    void ComputeCurrentValue() { +      if (!AtEnd()) +        current_value_ = ParamType(*current1_, *current2_, *current3_, +            *current4_); +    } +    bool AtEnd() const { +      // We must report iterator past the end of the range when either of the +      // component iterators has reached the end of its range. +      return +          current1_ == end1_ || +          current2_ == end2_ || +          current3_ == end3_ || +          current4_ == end4_; +    } + +    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. +    const typename ParamGenerator<T1>::iterator begin1_; +    const typename ParamGenerator<T1>::iterator end1_; +    typename ParamGenerator<T1>::iterator current1_; +    const typename ParamGenerator<T2>::iterator begin2_; +    const typename ParamGenerator<T2>::iterator end2_; +    typename ParamGenerator<T2>::iterator current2_; +    const typename ParamGenerator<T3>::iterator begin3_; +    const typename ParamGenerator<T3>::iterator end3_; +    typename ParamGenerator<T3>::iterator current3_; +    const typename ParamGenerator<T4>::iterator begin4_; +    const typename ParamGenerator<T4>::iterator end4_; +    typename ParamGenerator<T4>::iterator current4_; +    ParamType current_value_; +  }; + +  const ParamGenerator<T1> g1_; +  const ParamGenerator<T2> g2_; +  const ParamGenerator<T3> g3_; +  const ParamGenerator<T4> g4_; +}; + + +template <typename T1, typename T2, typename T3, typename T4, typename T5> +class CartesianProductGenerator5 +    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5> > { + public: +  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5> ParamType; + +  CartesianProductGenerator5(const ParamGenerator<T1>& g1, +      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, +      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5) +      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} +  virtual ~CartesianProductGenerator5() {} + +  virtual ParamIteratorInterface<ParamType>* Begin() const { +    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, +        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin()); +  } +  virtual ParamIteratorInterface<ParamType>* End() const { +    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), +        g4_, g4_.end(), g5_, g5_.end()); +  } + + private: +  class Iterator : public ParamIteratorInterface<ParamType> { +   public: +    Iterator(const ParamGeneratorInterface<ParamType>* base, +      const ParamGenerator<T1>& g1, +      const typename ParamGenerator<T1>::iterator& current1, +      const ParamGenerator<T2>& g2, +      const typename ParamGenerator<T2>::iterator& current2, +      const ParamGenerator<T3>& g3, +      const typename ParamGenerator<T3>::iterator& current3, +      const ParamGenerator<T4>& g4, +      const typename ParamGenerator<T4>::iterator& current4, +      const ParamGenerator<T5>& g5, +      const typename ParamGenerator<T5>::iterator& current5) +        : base_(base), +          begin1_(g1.begin()), end1_(g1.end()), current1_(current1), +          begin2_(g2.begin()), end2_(g2.end()), current2_(current2), +          begin3_(g3.begin()), end3_(g3.end()), current3_(current3), +          begin4_(g4.begin()), end4_(g4.end()), current4_(current4), +          begin5_(g5.begin()), end5_(g5.end()), current5_(current5)    { +      ComputeCurrentValue(); +    } +    virtual ~Iterator() {} + +    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { +      return base_; +    } +    // Advance should not be called on beyond-of-range iterators +    // so no component iterators must be beyond end of range, either. +    virtual void Advance() { +      assert(!AtEnd()); +      ++current5_; +      if (current5_ == end5_) { +        current5_ = begin5_; +        ++current4_; +      } +      if (current4_ == end4_) { +        current4_ = begin4_; +        ++current3_; +      } +      if (current3_ == end3_) { +        current3_ = begin3_; +        ++current2_; +      } +      if (current2_ == end2_) { +        current2_ = begin2_; +        ++current1_; +      } +      ComputeCurrentValue(); +    } +    virtual ParamIteratorInterface<ParamType>* Clone() const { +      return new Iterator(*this); +    } +    virtual const ParamType* Current() const { return ¤t_value_; } +    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { +      // Having the same base generator guarantees that the other +      // iterator is of the same type and we can downcast. +      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) +          << "The program attempted to compare iterators " +          << "from different generators." << std::endl; +      const Iterator* typed_other = +          CheckedDowncastToActualType<const Iterator>(&other); +      // We must report iterators equal if they both point beyond their +      // respective ranges. That can happen in a variety of fashions, +      // so we have to consult AtEnd(). +      return (AtEnd() && typed_other->AtEnd()) || +         ( +          current1_ == typed_other->current1_ && +          current2_ == typed_other->current2_ && +          current3_ == typed_other->current3_ && +          current4_ == typed_other->current4_ && +          current5_ == typed_other->current5_); +    } + +   private: +    Iterator(const Iterator& other) +        : base_(other.base_), +        begin1_(other.begin1_), +        end1_(other.end1_), +        current1_(other.current1_), +        begin2_(other.begin2_), +        end2_(other.end2_), +        current2_(other.current2_), +        begin3_(other.begin3_), +        end3_(other.end3_), +        current3_(other.current3_), +        begin4_(other.begin4_), +        end4_(other.end4_), +        current4_(other.current4_), +        begin5_(other.begin5_), +        end5_(other.end5_), +        current5_(other.current5_) { +      ComputeCurrentValue(); +    } + +    void ComputeCurrentValue() { +      if (!AtEnd()) +        current_value_ = ParamType(*current1_, *current2_, *current3_, +            *current4_, *current5_); +    } +    bool AtEnd() const { +      // We must report iterator past the end of the range when either of the +      // component iterators has reached the end of its range. +      return +          current1_ == end1_ || +          current2_ == end2_ || +          current3_ == end3_ || +          current4_ == end4_ || +          current5_ == end5_; +    } + +    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. +    const typename ParamGenerator<T1>::iterator begin1_; +    const typename ParamGenerator<T1>::iterator end1_; +    typename ParamGenerator<T1>::iterator current1_; +    const typename ParamGenerator<T2>::iterator begin2_; +    const typename ParamGenerator<T2>::iterator end2_; +    typename ParamGenerator<T2>::iterator current2_; +    const typename ParamGenerator<T3>::iterator begin3_; +    const typename ParamGenerator<T3>::iterator end3_; +    typename ParamGenerator<T3>::iterator current3_; +    const typename ParamGenerator<T4>::iterator begin4_; +    const typename ParamGenerator<T4>::iterator end4_; +    typename ParamGenerator<T4>::iterator current4_; +    const typename ParamGenerator<T5>::iterator begin5_; +    const typename ParamGenerator<T5>::iterator end5_; +    typename ParamGenerator<T5>::iterator current5_; +    ParamType current_value_; +  }; + +  const ParamGenerator<T1> g1_; +  const ParamGenerator<T2> g2_; +  const ParamGenerator<T3> g3_; +  const ParamGenerator<T4> g4_; +  const ParamGenerator<T5> g5_; +}; + + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6> +class CartesianProductGenerator6 +    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, +        T6> > { + public: +  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> ParamType; + +  CartesianProductGenerator6(const ParamGenerator<T1>& g1, +      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, +      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5, +      const ParamGenerator<T6>& g6) +      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} +  virtual ~CartesianProductGenerator6() {} + +  virtual ParamIteratorInterface<ParamType>* Begin() const { +    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, +        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin()); +  } +  virtual ParamIteratorInterface<ParamType>* End() const { +    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), +        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end()); +  } + + private: +  class Iterator : public ParamIteratorInterface<ParamType> { +   public: +    Iterator(const ParamGeneratorInterface<ParamType>* base, +      const ParamGenerator<T1>& g1, +      const typename ParamGenerator<T1>::iterator& current1, +      const ParamGenerator<T2>& g2, +      const typename ParamGenerator<T2>::iterator& current2, +      const ParamGenerator<T3>& g3, +      const typename ParamGenerator<T3>::iterator& current3, +      const ParamGenerator<T4>& g4, +      const typename ParamGenerator<T4>::iterator& current4, +      const ParamGenerator<T5>& g5, +      const typename ParamGenerator<T5>::iterator& current5, +      const ParamGenerator<T6>& g6, +      const typename ParamGenerator<T6>::iterator& current6) +        : base_(base), +          begin1_(g1.begin()), end1_(g1.end()), current1_(current1), +          begin2_(g2.begin()), end2_(g2.end()), current2_(current2), +          begin3_(g3.begin()), end3_(g3.end()), current3_(current3), +          begin4_(g4.begin()), end4_(g4.end()), current4_(current4), +          begin5_(g5.begin()), end5_(g5.end()), current5_(current5), +          begin6_(g6.begin()), end6_(g6.end()), current6_(current6)    { +      ComputeCurrentValue(); +    } +    virtual ~Iterator() {} + +    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { +      return base_; +    } +    // Advance should not be called on beyond-of-range iterators +    // so no component iterators must be beyond end of range, either. +    virtual void Advance() { +      assert(!AtEnd()); +      ++current6_; +      if (current6_ == end6_) { +        current6_ = begin6_; +        ++current5_; +      } +      if (current5_ == end5_) { +        current5_ = begin5_; +        ++current4_; +      } +      if (current4_ == end4_) { +        current4_ = begin4_; +        ++current3_; +      } +      if (current3_ == end3_) { +        current3_ = begin3_; +        ++current2_; +      } +      if (current2_ == end2_) { +        current2_ = begin2_; +        ++current1_; +      } +      ComputeCurrentValue(); +    } +    virtual ParamIteratorInterface<ParamType>* Clone() const { +      return new Iterator(*this); +    } +    virtual const ParamType* Current() const { return ¤t_value_; } +    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { +      // Having the same base generator guarantees that the other +      // iterator is of the same type and we can downcast. +      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) +          << "The program attempted to compare iterators " +          << "from different generators." << std::endl; +      const Iterator* typed_other = +          CheckedDowncastToActualType<const Iterator>(&other); +      // We must report iterators equal if they both point beyond their +      // respective ranges. That can happen in a variety of fashions, +      // so we have to consult AtEnd(). +      return (AtEnd() && typed_other->AtEnd()) || +         ( +          current1_ == typed_other->current1_ && +          current2_ == typed_other->current2_ && +          current3_ == typed_other->current3_ && +          current4_ == typed_other->current4_ && +          current5_ == typed_other->current5_ && +          current6_ == typed_other->current6_); +    } + +   private: +    Iterator(const Iterator& other) +        : base_(other.base_), +        begin1_(other.begin1_), +        end1_(other.end1_), +        current1_(other.current1_), +        begin2_(other.begin2_), +        end2_(other.end2_), +        current2_(other.current2_), +        begin3_(other.begin3_), +        end3_(other.end3_), +        current3_(other.current3_), +        begin4_(other.begin4_), +        end4_(other.end4_), +        current4_(other.current4_), +        begin5_(other.begin5_), +        end5_(other.end5_), +        current5_(other.current5_), +        begin6_(other.begin6_), +        end6_(other.end6_), +        current6_(other.current6_) { +      ComputeCurrentValue(); +    } + +    void ComputeCurrentValue() { +      if (!AtEnd()) +        current_value_ = ParamType(*current1_, *current2_, *current3_, +            *current4_, *current5_, *current6_); +    } +    bool AtEnd() const { +      // We must report iterator past the end of the range when either of the +      // component iterators has reached the end of its range. +      return +          current1_ == end1_ || +          current2_ == end2_ || +          current3_ == end3_ || +          current4_ == end4_ || +          current5_ == end5_ || +          current6_ == end6_; +    } + +    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. +    const typename ParamGenerator<T1>::iterator begin1_; +    const typename ParamGenerator<T1>::iterator end1_; +    typename ParamGenerator<T1>::iterator current1_; +    const typename ParamGenerator<T2>::iterator begin2_; +    const typename ParamGenerator<T2>::iterator end2_; +    typename ParamGenerator<T2>::iterator current2_; +    const typename ParamGenerator<T3>::iterator begin3_; +    const typename ParamGenerator<T3>::iterator end3_; +    typename ParamGenerator<T3>::iterator current3_; +    const typename ParamGenerator<T4>::iterator begin4_; +    const typename ParamGenerator<T4>::iterator end4_; +    typename ParamGenerator<T4>::iterator current4_; +    const typename ParamGenerator<T5>::iterator begin5_; +    const typename ParamGenerator<T5>::iterator end5_; +    typename ParamGenerator<T5>::iterator current5_; +    const typename ParamGenerator<T6>::iterator begin6_; +    const typename ParamGenerator<T6>::iterator end6_; +    typename ParamGenerator<T6>::iterator current6_; +    ParamType current_value_; +  }; + +  const ParamGenerator<T1> g1_; +  const ParamGenerator<T2> g2_; +  const ParamGenerator<T3> g3_; +  const ParamGenerator<T4> g4_; +  const ParamGenerator<T5> g5_; +  const ParamGenerator<T6> g6_; +}; + + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7> +class CartesianProductGenerator7 +    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, +        T7> > { + public: +  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> ParamType; + +  CartesianProductGenerator7(const ParamGenerator<T1>& g1, +      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, +      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5, +      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7) +      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} +  virtual ~CartesianProductGenerator7() {} + +  virtual ParamIteratorInterface<ParamType>* Begin() const { +    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, +        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, +        g7_.begin()); +  } +  virtual ParamIteratorInterface<ParamType>* End() const { +    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), +        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end()); +  } + + private: +  class Iterator : public ParamIteratorInterface<ParamType> { +   public: +    Iterator(const ParamGeneratorInterface<ParamType>* base, +      const ParamGenerator<T1>& g1, +      const typename ParamGenerator<T1>::iterator& current1, +      const ParamGenerator<T2>& g2, +      const typename ParamGenerator<T2>::iterator& current2, +      const ParamGenerator<T3>& g3, +      const typename ParamGenerator<T3>::iterator& current3, +      const ParamGenerator<T4>& g4, +      const typename ParamGenerator<T4>::iterator& current4, +      const ParamGenerator<T5>& g5, +      const typename ParamGenerator<T5>::iterator& current5, +      const ParamGenerator<T6>& g6, +      const typename ParamGenerator<T6>::iterator& current6, +      const ParamGenerator<T7>& g7, +      const typename ParamGenerator<T7>::iterator& current7) +        : base_(base), +          begin1_(g1.begin()), end1_(g1.end()), current1_(current1), +          begin2_(g2.begin()), end2_(g2.end()), current2_(current2), +          begin3_(g3.begin()), end3_(g3.end()), current3_(current3), +          begin4_(g4.begin()), end4_(g4.end()), current4_(current4), +          begin5_(g5.begin()), end5_(g5.end()), current5_(current5), +          begin6_(g6.begin()), end6_(g6.end()), current6_(current6), +          begin7_(g7.begin()), end7_(g7.end()), current7_(current7)    { +      ComputeCurrentValue(); +    } +    virtual ~Iterator() {} + +    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { +      return base_; +    } +    // Advance should not be called on beyond-of-range iterators +    // so no component iterators must be beyond end of range, either. +    virtual void Advance() { +      assert(!AtEnd()); +      ++current7_; +      if (current7_ == end7_) { +        current7_ = begin7_; +        ++current6_; +      } +      if (current6_ == end6_) { +        current6_ = begin6_; +        ++current5_; +      } +      if (current5_ == end5_) { +        current5_ = begin5_; +        ++current4_; +      } +      if (current4_ == end4_) { +        current4_ = begin4_; +        ++current3_; +      } +      if (current3_ == end3_) { +        current3_ = begin3_; +        ++current2_; +      } +      if (current2_ == end2_) { +        current2_ = begin2_; +        ++current1_; +      } +      ComputeCurrentValue(); +    } +    virtual ParamIteratorInterface<ParamType>* Clone() const { +      return new Iterator(*this); +    } +    virtual const ParamType* Current() const { return ¤t_value_; } +    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { +      // Having the same base generator guarantees that the other +      // iterator is of the same type and we can downcast. +      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) +          << "The program attempted to compare iterators " +          << "from different generators." << std::endl; +      const Iterator* typed_other = +          CheckedDowncastToActualType<const Iterator>(&other); +      // We must report iterators equal if they both point beyond their +      // respective ranges. That can happen in a variety of fashions, +      // so we have to consult AtEnd(). +      return (AtEnd() && typed_other->AtEnd()) || +         ( +          current1_ == typed_other->current1_ && +          current2_ == typed_other->current2_ && +          current3_ == typed_other->current3_ && +          current4_ == typed_other->current4_ && +          current5_ == typed_other->current5_ && +          current6_ == typed_other->current6_ && +          current7_ == typed_other->current7_); +    } + +   private: +    Iterator(const Iterator& other) +        : base_(other.base_), +        begin1_(other.begin1_), +        end1_(other.end1_), +        current1_(other.current1_), +        begin2_(other.begin2_), +        end2_(other.end2_), +        current2_(other.current2_), +        begin3_(other.begin3_), +        end3_(other.end3_), +        current3_(other.current3_), +        begin4_(other.begin4_), +        end4_(other.end4_), +        current4_(other.current4_), +        begin5_(other.begin5_), +        end5_(other.end5_), +        current5_(other.current5_), +        begin6_(other.begin6_), +        end6_(other.end6_), +        current6_(other.current6_), +        begin7_(other.begin7_), +        end7_(other.end7_), +        current7_(other.current7_) { +      ComputeCurrentValue(); +    } + +    void ComputeCurrentValue() { +      if (!AtEnd()) +        current_value_ = ParamType(*current1_, *current2_, *current3_, +            *current4_, *current5_, *current6_, *current7_); +    } +    bool AtEnd() const { +      // We must report iterator past the end of the range when either of the +      // component iterators has reached the end of its range. +      return +          current1_ == end1_ || +          current2_ == end2_ || +          current3_ == end3_ || +          current4_ == end4_ || +          current5_ == end5_ || +          current6_ == end6_ || +          current7_ == end7_; +    } + +    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. +    const typename ParamGenerator<T1>::iterator begin1_; +    const typename ParamGenerator<T1>::iterator end1_; +    typename ParamGenerator<T1>::iterator current1_; +    const typename ParamGenerator<T2>::iterator begin2_; +    const typename ParamGenerator<T2>::iterator end2_; +    typename ParamGenerator<T2>::iterator current2_; +    const typename ParamGenerator<T3>::iterator begin3_; +    const typename ParamGenerator<T3>::iterator end3_; +    typename ParamGenerator<T3>::iterator current3_; +    const typename ParamGenerator<T4>::iterator begin4_; +    const typename ParamGenerator<T4>::iterator end4_; +    typename ParamGenerator<T4>::iterator current4_; +    const typename ParamGenerator<T5>::iterator begin5_; +    const typename ParamGenerator<T5>::iterator end5_; +    typename ParamGenerator<T5>::iterator current5_; +    const typename ParamGenerator<T6>::iterator begin6_; +    const typename ParamGenerator<T6>::iterator end6_; +    typename ParamGenerator<T6>::iterator current6_; +    const typename ParamGenerator<T7>::iterator begin7_; +    const typename ParamGenerator<T7>::iterator end7_; +    typename ParamGenerator<T7>::iterator current7_; +    ParamType current_value_; +  }; + +  const ParamGenerator<T1> g1_; +  const ParamGenerator<T2> g2_; +  const ParamGenerator<T3> g3_; +  const ParamGenerator<T4> g4_; +  const ParamGenerator<T5> g5_; +  const ParamGenerator<T6> g6_; +  const ParamGenerator<T7> g7_; +}; + + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8> +class CartesianProductGenerator8 +    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, +        T7, T8> > { + public: +  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> ParamType; + +  CartesianProductGenerator8(const ParamGenerator<T1>& g1, +      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, +      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5, +      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7, +      const ParamGenerator<T8>& g8) +      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), +          g8_(g8) {} +  virtual ~CartesianProductGenerator8() {} + +  virtual ParamIteratorInterface<ParamType>* Begin() const { +    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, +        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, +        g7_.begin(), g8_, g8_.begin()); +  } +  virtual ParamIteratorInterface<ParamType>* End() const { +    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), +        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, +        g8_.end()); +  } + + private: +  class Iterator : public ParamIteratorInterface<ParamType> { +   public: +    Iterator(const ParamGeneratorInterface<ParamType>* base, +      const ParamGenerator<T1>& g1, +      const typename ParamGenerator<T1>::iterator& current1, +      const ParamGenerator<T2>& g2, +      const typename ParamGenerator<T2>::iterator& current2, +      const ParamGenerator<T3>& g3, +      const typename ParamGenerator<T3>::iterator& current3, +      const ParamGenerator<T4>& g4, +      const typename ParamGenerator<T4>::iterator& current4, +      const ParamGenerator<T5>& g5, +      const typename ParamGenerator<T5>::iterator& current5, +      const ParamGenerator<T6>& g6, +      const typename ParamGenerator<T6>::iterator& current6, +      const ParamGenerator<T7>& g7, +      const typename ParamGenerator<T7>::iterator& current7, +      const ParamGenerator<T8>& g8, +      const typename ParamGenerator<T8>::iterator& current8) +        : base_(base), +          begin1_(g1.begin()), end1_(g1.end()), current1_(current1), +          begin2_(g2.begin()), end2_(g2.end()), current2_(current2), +          begin3_(g3.begin()), end3_(g3.end()), current3_(current3), +          begin4_(g4.begin()), end4_(g4.end()), current4_(current4), +          begin5_(g5.begin()), end5_(g5.end()), current5_(current5), +          begin6_(g6.begin()), end6_(g6.end()), current6_(current6), +          begin7_(g7.begin()), end7_(g7.end()), current7_(current7), +          begin8_(g8.begin()), end8_(g8.end()), current8_(current8)    { +      ComputeCurrentValue(); +    } +    virtual ~Iterator() {} + +    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { +      return base_; +    } +    // Advance should not be called on beyond-of-range iterators +    // so no component iterators must be beyond end of range, either. +    virtual void Advance() { +      assert(!AtEnd()); +      ++current8_; +      if (current8_ == end8_) { +        current8_ = begin8_; +        ++current7_; +      } +      if (current7_ == end7_) { +        current7_ = begin7_; +        ++current6_; +      } +      if (current6_ == end6_) { +        current6_ = begin6_; +        ++current5_; +      } +      if (current5_ == end5_) { +        current5_ = begin5_; +        ++current4_; +      } +      if (current4_ == end4_) { +        current4_ = begin4_; +        ++current3_; +      } +      if (current3_ == end3_) { +        current3_ = begin3_; +        ++current2_; +      } +      if (current2_ == end2_) { +        current2_ = begin2_; +        ++current1_; +      } +      ComputeCurrentValue(); +    } +    virtual ParamIteratorInterface<ParamType>* Clone() const { +      return new Iterator(*this); +    } +    virtual const ParamType* Current() const { return ¤t_value_; } +    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { +      // Having the same base generator guarantees that the other +      // iterator is of the same type and we can downcast. +      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) +          << "The program attempted to compare iterators " +          << "from different generators." << std::endl; +      const Iterator* typed_other = +          CheckedDowncastToActualType<const Iterator>(&other); +      // We must report iterators equal if they both point beyond their +      // respective ranges. That can happen in a variety of fashions, +      // so we have to consult AtEnd(). +      return (AtEnd() && typed_other->AtEnd()) || +         ( +          current1_ == typed_other->current1_ && +          current2_ == typed_other->current2_ && +          current3_ == typed_other->current3_ && +          current4_ == typed_other->current4_ && +          current5_ == typed_other->current5_ && +          current6_ == typed_other->current6_ && +          current7_ == typed_other->current7_ && +          current8_ == typed_other->current8_); +    } + +   private: +    Iterator(const Iterator& other) +        : base_(other.base_), +        begin1_(other.begin1_), +        end1_(other.end1_), +        current1_(other.current1_), +        begin2_(other.begin2_), +        end2_(other.end2_), +        current2_(other.current2_), +        begin3_(other.begin3_), +        end3_(other.end3_), +        current3_(other.current3_), +        begin4_(other.begin4_), +        end4_(other.end4_), +        current4_(other.current4_), +        begin5_(other.begin5_), +        end5_(other.end5_), +        current5_(other.current5_), +        begin6_(other.begin6_), +        end6_(other.end6_), +        current6_(other.current6_), +        begin7_(other.begin7_), +        end7_(other.end7_), +        current7_(other.current7_), +        begin8_(other.begin8_), +        end8_(other.end8_), +        current8_(other.current8_) { +      ComputeCurrentValue(); +    } + +    void ComputeCurrentValue() { +      if (!AtEnd()) +        current_value_ = ParamType(*current1_, *current2_, *current3_, +            *current4_, *current5_, *current6_, *current7_, *current8_); +    } +    bool AtEnd() const { +      // We must report iterator past the end of the range when either of the +      // component iterators has reached the end of its range. +      return +          current1_ == end1_ || +          current2_ == end2_ || +          current3_ == end3_ || +          current4_ == end4_ || +          current5_ == end5_ || +          current6_ == end6_ || +          current7_ == end7_ || +          current8_ == end8_; +    } + +    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. +    const typename ParamGenerator<T1>::iterator begin1_; +    const typename ParamGenerator<T1>::iterator end1_; +    typename ParamGenerator<T1>::iterator current1_; +    const typename ParamGenerator<T2>::iterator begin2_; +    const typename ParamGenerator<T2>::iterator end2_; +    typename ParamGenerator<T2>::iterator current2_; +    const typename ParamGenerator<T3>::iterator begin3_; +    const typename ParamGenerator<T3>::iterator end3_; +    typename ParamGenerator<T3>::iterator current3_; +    const typename ParamGenerator<T4>::iterator begin4_; +    const typename ParamGenerator<T4>::iterator end4_; +    typename ParamGenerator<T4>::iterator current4_; +    const typename ParamGenerator<T5>::iterator begin5_; +    const typename ParamGenerator<T5>::iterator end5_; +    typename ParamGenerator<T5>::iterator current5_; +    const typename ParamGenerator<T6>::iterator begin6_; +    const typename ParamGenerator<T6>::iterator end6_; +    typename ParamGenerator<T6>::iterator current6_; +    const typename ParamGenerator<T7>::iterator begin7_; +    const typename ParamGenerator<T7>::iterator end7_; +    typename ParamGenerator<T7>::iterator current7_; +    const typename ParamGenerator<T8>::iterator begin8_; +    const typename ParamGenerator<T8>::iterator end8_; +    typename ParamGenerator<T8>::iterator current8_; +    ParamType current_value_; +  }; + +  const ParamGenerator<T1> g1_; +  const ParamGenerator<T2> g2_; +  const ParamGenerator<T3> g3_; +  const ParamGenerator<T4> g4_; +  const ParamGenerator<T5> g5_; +  const ParamGenerator<T6> g6_; +  const ParamGenerator<T7> g7_; +  const ParamGenerator<T8> g8_; +}; + + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9> +class CartesianProductGenerator9 +    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, +        T7, T8, T9> > { + public: +  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9> ParamType; + +  CartesianProductGenerator9(const ParamGenerator<T1>& g1, +      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, +      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5, +      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7, +      const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9) +      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), +          g9_(g9) {} +  virtual ~CartesianProductGenerator9() {} + +  virtual ParamIteratorInterface<ParamType>* Begin() const { +    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, +        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, +        g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin()); +  } +  virtual ParamIteratorInterface<ParamType>* End() const { +    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), +        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, +        g8_.end(), g9_, g9_.end()); +  } + + private: +  class Iterator : public ParamIteratorInterface<ParamType> { +   public: +    Iterator(const ParamGeneratorInterface<ParamType>* base, +      const ParamGenerator<T1>& g1, +      const typename ParamGenerator<T1>::iterator& current1, +      const ParamGenerator<T2>& g2, +      const typename ParamGenerator<T2>::iterator& current2, +      const ParamGenerator<T3>& g3, +      const typename ParamGenerator<T3>::iterator& current3, +      const ParamGenerator<T4>& g4, +      const typename ParamGenerator<T4>::iterator& current4, +      const ParamGenerator<T5>& g5, +      const typename ParamGenerator<T5>::iterator& current5, +      const ParamGenerator<T6>& g6, +      const typename ParamGenerator<T6>::iterator& current6, +      const ParamGenerator<T7>& g7, +      const typename ParamGenerator<T7>::iterator& current7, +      const ParamGenerator<T8>& g8, +      const typename ParamGenerator<T8>::iterator& current8, +      const ParamGenerator<T9>& g9, +      const typename ParamGenerator<T9>::iterator& current9) +        : base_(base), +          begin1_(g1.begin()), end1_(g1.end()), current1_(current1), +          begin2_(g2.begin()), end2_(g2.end()), current2_(current2), +          begin3_(g3.begin()), end3_(g3.end()), current3_(current3), +          begin4_(g4.begin()), end4_(g4.end()), current4_(current4), +          begin5_(g5.begin()), end5_(g5.end()), current5_(current5), +          begin6_(g6.begin()), end6_(g6.end()), current6_(current6), +          begin7_(g7.begin()), end7_(g7.end()), current7_(current7), +          begin8_(g8.begin()), end8_(g8.end()), current8_(current8), +          begin9_(g9.begin()), end9_(g9.end()), current9_(current9)    { +      ComputeCurrentValue(); +    } +    virtual ~Iterator() {} + +    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { +      return base_; +    } +    // Advance should not be called on beyond-of-range iterators +    // so no component iterators must be beyond end of range, either. +    virtual void Advance() { +      assert(!AtEnd()); +      ++current9_; +      if (current9_ == end9_) { +        current9_ = begin9_; +        ++current8_; +      } +      if (current8_ == end8_) { +        current8_ = begin8_; +        ++current7_; +      } +      if (current7_ == end7_) { +        current7_ = begin7_; +        ++current6_; +      } +      if (current6_ == end6_) { +        current6_ = begin6_; +        ++current5_; +      } +      if (current5_ == end5_) { +        current5_ = begin5_; +        ++current4_; +      } +      if (current4_ == end4_) { +        current4_ = begin4_; +        ++current3_; +      } +      if (current3_ == end3_) { +        current3_ = begin3_; +        ++current2_; +      } +      if (current2_ == end2_) { +        current2_ = begin2_; +        ++current1_; +      } +      ComputeCurrentValue(); +    } +    virtual ParamIteratorInterface<ParamType>* Clone() const { +      return new Iterator(*this); +    } +    virtual const ParamType* Current() const { return ¤t_value_; } +    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { +      // Having the same base generator guarantees that the other +      // iterator is of the same type and we can downcast. +      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) +          << "The program attempted to compare iterators " +          << "from different generators." << std::endl; +      const Iterator* typed_other = +          CheckedDowncastToActualType<const Iterator>(&other); +      // We must report iterators equal if they both point beyond their +      // respective ranges. That can happen in a variety of fashions, +      // so we have to consult AtEnd(). +      return (AtEnd() && typed_other->AtEnd()) || +         ( +          current1_ == typed_other->current1_ && +          current2_ == typed_other->current2_ && +          current3_ == typed_other->current3_ && +          current4_ == typed_other->current4_ && +          current5_ == typed_other->current5_ && +          current6_ == typed_other->current6_ && +          current7_ == typed_other->current7_ && +          current8_ == typed_other->current8_ && +          current9_ == typed_other->current9_); +    } + +   private: +    Iterator(const Iterator& other) +        : base_(other.base_), +        begin1_(other.begin1_), +        end1_(other.end1_), +        current1_(other.current1_), +        begin2_(other.begin2_), +        end2_(other.end2_), +        current2_(other.current2_), +        begin3_(other.begin3_), +        end3_(other.end3_), +        current3_(other.current3_), +        begin4_(other.begin4_), +        end4_(other.end4_), +        current4_(other.current4_), +        begin5_(other.begin5_), +        end5_(other.end5_), +        current5_(other.current5_), +        begin6_(other.begin6_), +        end6_(other.end6_), +        current6_(other.current6_), +        begin7_(other.begin7_), +        end7_(other.end7_), +        current7_(other.current7_), +        begin8_(other.begin8_), +        end8_(other.end8_), +        current8_(other.current8_), +        begin9_(other.begin9_), +        end9_(other.end9_), +        current9_(other.current9_) { +      ComputeCurrentValue(); +    } + +    void ComputeCurrentValue() { +      if (!AtEnd()) +        current_value_ = ParamType(*current1_, *current2_, *current3_, +            *current4_, *current5_, *current6_, *current7_, *current8_, +            *current9_); +    } +    bool AtEnd() const { +      // We must report iterator past the end of the range when either of the +      // component iterators has reached the end of its range. +      return +          current1_ == end1_ || +          current2_ == end2_ || +          current3_ == end3_ || +          current4_ == end4_ || +          current5_ == end5_ || +          current6_ == end6_ || +          current7_ == end7_ || +          current8_ == end8_ || +          current9_ == end9_; +    } + +    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. +    const typename ParamGenerator<T1>::iterator begin1_; +    const typename ParamGenerator<T1>::iterator end1_; +    typename ParamGenerator<T1>::iterator current1_; +    const typename ParamGenerator<T2>::iterator begin2_; +    const typename ParamGenerator<T2>::iterator end2_; +    typename ParamGenerator<T2>::iterator current2_; +    const typename ParamGenerator<T3>::iterator begin3_; +    const typename ParamGenerator<T3>::iterator end3_; +    typename ParamGenerator<T3>::iterator current3_; +    const typename ParamGenerator<T4>::iterator begin4_; +    const typename ParamGenerator<T4>::iterator end4_; +    typename ParamGenerator<T4>::iterator current4_; +    const typename ParamGenerator<T5>::iterator begin5_; +    const typename ParamGenerator<T5>::iterator end5_; +    typename ParamGenerator<T5>::iterator current5_; +    const typename ParamGenerator<T6>::iterator begin6_; +    const typename ParamGenerator<T6>::iterator end6_; +    typename ParamGenerator<T6>::iterator current6_; +    const typename ParamGenerator<T7>::iterator begin7_; +    const typename ParamGenerator<T7>::iterator end7_; +    typename ParamGenerator<T7>::iterator current7_; +    const typename ParamGenerator<T8>::iterator begin8_; +    const typename ParamGenerator<T8>::iterator end8_; +    typename ParamGenerator<T8>::iterator current8_; +    const typename ParamGenerator<T9>::iterator begin9_; +    const typename ParamGenerator<T9>::iterator end9_; +    typename ParamGenerator<T9>::iterator current9_; +    ParamType current_value_; +  }; + +  const ParamGenerator<T1> g1_; +  const ParamGenerator<T2> g2_; +  const ParamGenerator<T3> g3_; +  const ParamGenerator<T4> g4_; +  const ParamGenerator<T5> g5_; +  const ParamGenerator<T6> g6_; +  const ParamGenerator<T7> g7_; +  const ParamGenerator<T8> g8_; +  const ParamGenerator<T9> g9_; +}; + + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10> +class CartesianProductGenerator10 +    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, +        T7, T8, T9, T10> > { + public: +  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ParamType; + +  CartesianProductGenerator10(const ParamGenerator<T1>& g1, +      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, +      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5, +      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7, +      const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9, +      const ParamGenerator<T10>& g10) +      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), +          g9_(g9), g10_(g10) {} +  virtual ~CartesianProductGenerator10() {} + +  virtual ParamIteratorInterface<ParamType>* Begin() const { +    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, +        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, +        g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin()); +  } +  virtual ParamIteratorInterface<ParamType>* End() const { +    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), +        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, +        g8_.end(), g9_, g9_.end(), g10_, g10_.end()); +  } + + private: +  class Iterator : public ParamIteratorInterface<ParamType> { +   public: +    Iterator(const ParamGeneratorInterface<ParamType>* base, +      const ParamGenerator<T1>& g1, +      const typename ParamGenerator<T1>::iterator& current1, +      const ParamGenerator<T2>& g2, +      const typename ParamGenerator<T2>::iterator& current2, +      const ParamGenerator<T3>& g3, +      const typename ParamGenerator<T3>::iterator& current3, +      const ParamGenerator<T4>& g4, +      const typename ParamGenerator<T4>::iterator& current4, +      const ParamGenerator<T5>& g5, +      const typename ParamGenerator<T5>::iterator& current5, +      const ParamGenerator<T6>& g6, +      const typename ParamGenerator<T6>::iterator& current6, +      const ParamGenerator<T7>& g7, +      const typename ParamGenerator<T7>::iterator& current7, +      const ParamGenerator<T8>& g8, +      const typename ParamGenerator<T8>::iterator& current8, +      const ParamGenerator<T9>& g9, +      const typename ParamGenerator<T9>::iterator& current9, +      const ParamGenerator<T10>& g10, +      const typename ParamGenerator<T10>::iterator& current10) +        : base_(base), +          begin1_(g1.begin()), end1_(g1.end()), current1_(current1), +          begin2_(g2.begin()), end2_(g2.end()), current2_(current2), +          begin3_(g3.begin()), end3_(g3.end()), current3_(current3), +          begin4_(g4.begin()), end4_(g4.end()), current4_(current4), +          begin5_(g5.begin()), end5_(g5.end()), current5_(current5), +          begin6_(g6.begin()), end6_(g6.end()), current6_(current6), +          begin7_(g7.begin()), end7_(g7.end()), current7_(current7), +          begin8_(g8.begin()), end8_(g8.end()), current8_(current8), +          begin9_(g9.begin()), end9_(g9.end()), current9_(current9), +          begin10_(g10.begin()), end10_(g10.end()), current10_(current10)    { +      ComputeCurrentValue(); +    } +    virtual ~Iterator() {} + +    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { +      return base_; +    } +    // Advance should not be called on beyond-of-range iterators +    // so no component iterators must be beyond end of range, either. +    virtual void Advance() { +      assert(!AtEnd()); +      ++current10_; +      if (current10_ == end10_) { +        current10_ = begin10_; +        ++current9_; +      } +      if (current9_ == end9_) { +        current9_ = begin9_; +        ++current8_; +      } +      if (current8_ == end8_) { +        current8_ = begin8_; +        ++current7_; +      } +      if (current7_ == end7_) { +        current7_ = begin7_; +        ++current6_; +      } +      if (current6_ == end6_) { +        current6_ = begin6_; +        ++current5_; +      } +      if (current5_ == end5_) { +        current5_ = begin5_; +        ++current4_; +      } +      if (current4_ == end4_) { +        current4_ = begin4_; +        ++current3_; +      } +      if (current3_ == end3_) { +        current3_ = begin3_; +        ++current2_; +      } +      if (current2_ == end2_) { +        current2_ = begin2_; +        ++current1_; +      } +      ComputeCurrentValue(); +    } +    virtual ParamIteratorInterface<ParamType>* Clone() const { +      return new Iterator(*this); +    } +    virtual const ParamType* Current() const { return ¤t_value_; } +    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { +      // Having the same base generator guarantees that the other +      // iterator is of the same type and we can downcast. +      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) +          << "The program attempted to compare iterators " +          << "from different generators." << std::endl; +      const Iterator* typed_other = +          CheckedDowncastToActualType<const Iterator>(&other); +      // We must report iterators equal if they both point beyond their +      // respective ranges. That can happen in a variety of fashions, +      // so we have to consult AtEnd(). +      return (AtEnd() && typed_other->AtEnd()) || +         ( +          current1_ == typed_other->current1_ && +          current2_ == typed_other->current2_ && +          current3_ == typed_other->current3_ && +          current4_ == typed_other->current4_ && +          current5_ == typed_other->current5_ && +          current6_ == typed_other->current6_ && +          current7_ == typed_other->current7_ && +          current8_ == typed_other->current8_ && +          current9_ == typed_other->current9_ && +          current10_ == typed_other->current10_); +    } + +   private: +    Iterator(const Iterator& other) +        : base_(other.base_), +        begin1_(other.begin1_), +        end1_(other.end1_), +        current1_(other.current1_), +        begin2_(other.begin2_), +        end2_(other.end2_), +        current2_(other.current2_), +        begin3_(other.begin3_), +        end3_(other.end3_), +        current3_(other.current3_), +        begin4_(other.begin4_), +        end4_(other.end4_), +        current4_(other.current4_), +        begin5_(other.begin5_), +        end5_(other.end5_), +        current5_(other.current5_), +        begin6_(other.begin6_), +        end6_(other.end6_), +        current6_(other.current6_), +        begin7_(other.begin7_), +        end7_(other.end7_), +        current7_(other.current7_), +        begin8_(other.begin8_), +        end8_(other.end8_), +        current8_(other.current8_), +        begin9_(other.begin9_), +        end9_(other.end9_), +        current9_(other.current9_), +        begin10_(other.begin10_), +        end10_(other.end10_), +        current10_(other.current10_) { +      ComputeCurrentValue(); +    } + +    void ComputeCurrentValue() { +      if (!AtEnd()) +        current_value_ = ParamType(*current1_, *current2_, *current3_, +            *current4_, *current5_, *current6_, *current7_, *current8_, +            *current9_, *current10_); +    } +    bool AtEnd() const { +      // We must report iterator past the end of the range when either of the +      // component iterators has reached the end of its range. +      return +          current1_ == end1_ || +          current2_ == end2_ || +          current3_ == end3_ || +          current4_ == end4_ || +          current5_ == end5_ || +          current6_ == end6_ || +          current7_ == end7_ || +          current8_ == end8_ || +          current9_ == end9_ || +          current10_ == end10_; +    } + +    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. +    const typename ParamGenerator<T1>::iterator begin1_; +    const typename ParamGenerator<T1>::iterator end1_; +    typename ParamGenerator<T1>::iterator current1_; +    const typename ParamGenerator<T2>::iterator begin2_; +    const typename ParamGenerator<T2>::iterator end2_; +    typename ParamGenerator<T2>::iterator current2_; +    const typename ParamGenerator<T3>::iterator begin3_; +    const typename ParamGenerator<T3>::iterator end3_; +    typename ParamGenerator<T3>::iterator current3_; +    const typename ParamGenerator<T4>::iterator begin4_; +    const typename ParamGenerator<T4>::iterator end4_; +    typename ParamGenerator<T4>::iterator current4_; +    const typename ParamGenerator<T5>::iterator begin5_; +    const typename ParamGenerator<T5>::iterator end5_; +    typename ParamGenerator<T5>::iterator current5_; +    const typename ParamGenerator<T6>::iterator begin6_; +    const typename ParamGenerator<T6>::iterator end6_; +    typename ParamGenerator<T6>::iterator current6_; +    const typename ParamGenerator<T7>::iterator begin7_; +    const typename ParamGenerator<T7>::iterator end7_; +    typename ParamGenerator<T7>::iterator current7_; +    const typename ParamGenerator<T8>::iterator begin8_; +    const typename ParamGenerator<T8>::iterator end8_; +    typename ParamGenerator<T8>::iterator current8_; +    const typename ParamGenerator<T9>::iterator begin9_; +    const typename ParamGenerator<T9>::iterator end9_; +    typename ParamGenerator<T9>::iterator current9_; +    const typename ParamGenerator<T10>::iterator begin10_; +    const typename ParamGenerator<T10>::iterator end10_; +    typename ParamGenerator<T10>::iterator current10_; +    ParamType current_value_; +  }; + +  const ParamGenerator<T1> g1_; +  const ParamGenerator<T2> g2_; +  const ParamGenerator<T3> g3_; +  const ParamGenerator<T4> g4_; +  const ParamGenerator<T5> g5_; +  const ParamGenerator<T6> g6_; +  const ParamGenerator<T7> g7_; +  const ParamGenerator<T8> g8_; +  const ParamGenerator<T9> g9_; +  const ParamGenerator<T10> g10_; +}; + + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Helper classes providing Combine() with polymorphic features. They allow +// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is +// convertible to U. +// +template <class Generator1, class Generator2> +class CartesianProductHolder2 { + public: +CartesianProductHolder2(const Generator1& g1, const Generator2& g2) +      : g1_(g1), g2_(g2) {} +  template <typename T1, typename T2> +  operator ParamGenerator< ::std::tr1::tuple<T1, T2> >() const { +    return ParamGenerator< ::std::tr1::tuple<T1, T2> >( +        new CartesianProductGenerator2<T1, T2>( +        static_cast<ParamGenerator<T1> >(g1_), +        static_cast<ParamGenerator<T2> >(g2_))); +  } + + private: +  const Generator1 g1_; +  const Generator2 g2_; +}; + +template <class Generator1, class Generator2, class Generator3> +class CartesianProductHolder3 { + public: +CartesianProductHolder3(const Generator1& g1, const Generator2& g2, +    const Generator3& g3) +      : g1_(g1), g2_(g2), g3_(g3) {} +  template <typename T1, typename T2, typename T3> +  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >() const { +    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >( +        new CartesianProductGenerator3<T1, T2, T3>( +        static_cast<ParamGenerator<T1> >(g1_), +        static_cast<ParamGenerator<T2> >(g2_), +        static_cast<ParamGenerator<T3> >(g3_))); +  } + + private: +  const Generator1 g1_; +  const Generator2 g2_; +  const Generator3 g3_; +}; + +template <class Generator1, class Generator2, class Generator3, +    class Generator4> +class CartesianProductHolder4 { + public: +CartesianProductHolder4(const Generator1& g1, const Generator2& g2, +    const Generator3& g3, const Generator4& g4) +      : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} +  template <typename T1, typename T2, typename T3, typename T4> +  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >() const { +    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >( +        new CartesianProductGenerator4<T1, T2, T3, T4>( +        static_cast<ParamGenerator<T1> >(g1_), +        static_cast<ParamGenerator<T2> >(g2_), +        static_cast<ParamGenerator<T3> >(g3_), +        static_cast<ParamGenerator<T4> >(g4_))); +  } + + private: +  const Generator1 g1_; +  const Generator2 g2_; +  const Generator3 g3_; +  const Generator4 g4_; +}; + +template <class Generator1, class Generator2, class Generator3, +    class Generator4, class Generator5> +class CartesianProductHolder5 { + public: +CartesianProductHolder5(const Generator1& g1, const Generator2& g2, +    const Generator3& g3, const Generator4& g4, const Generator5& g5) +      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} +  template <typename T1, typename T2, typename T3, typename T4, typename T5> +  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >() const { +    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >( +        new CartesianProductGenerator5<T1, T2, T3, T4, T5>( +        static_cast<ParamGenerator<T1> >(g1_), +        static_cast<ParamGenerator<T2> >(g2_), +        static_cast<ParamGenerator<T3> >(g3_), +        static_cast<ParamGenerator<T4> >(g4_), +        static_cast<ParamGenerator<T5> >(g5_))); +  } + + private: +  const Generator1 g1_; +  const Generator2 g2_; +  const Generator3 g3_; +  const Generator4 g4_; +  const Generator5 g5_; +}; + +template <class Generator1, class Generator2, class Generator3, +    class Generator4, class Generator5, class Generator6> +class CartesianProductHolder6 { + public: +CartesianProductHolder6(const Generator1& g1, const Generator2& g2, +    const Generator3& g3, const Generator4& g4, const Generator5& g5, +    const Generator6& g6) +      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} +  template <typename T1, typename T2, typename T3, typename T4, typename T5, +      typename T6> +  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >() const { +    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >( +        new CartesianProductGenerator6<T1, T2, T3, T4, T5, T6>( +        static_cast<ParamGenerator<T1> >(g1_), +        static_cast<ParamGenerator<T2> >(g2_), +        static_cast<ParamGenerator<T3> >(g3_), +        static_cast<ParamGenerator<T4> >(g4_), +        static_cast<ParamGenerator<T5> >(g5_), +        static_cast<ParamGenerator<T6> >(g6_))); +  } + + private: +  const Generator1 g1_; +  const Generator2 g2_; +  const Generator3 g3_; +  const Generator4 g4_; +  const Generator5 g5_; +  const Generator6 g6_; +}; + +template <class Generator1, class Generator2, class Generator3, +    class Generator4, class Generator5, class Generator6, class Generator7> +class CartesianProductHolder7 { + public: +CartesianProductHolder7(const Generator1& g1, const Generator2& g2, +    const Generator3& g3, const Generator4& g4, const Generator5& g5, +    const Generator6& g6, const Generator7& g7) +      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} +  template <typename T1, typename T2, typename T3, typename T4, typename T5, +      typename T6, typename T7> +  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, +      T7> >() const { +    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> >( +        new CartesianProductGenerator7<T1, T2, T3, T4, T5, T6, T7>( +        static_cast<ParamGenerator<T1> >(g1_), +        static_cast<ParamGenerator<T2> >(g2_), +        static_cast<ParamGenerator<T3> >(g3_), +        static_cast<ParamGenerator<T4> >(g4_), +        static_cast<ParamGenerator<T5> >(g5_), +        static_cast<ParamGenerator<T6> >(g6_), +        static_cast<ParamGenerator<T7> >(g7_))); +  } + + private: +  const Generator1 g1_; +  const Generator2 g2_; +  const Generator3 g3_; +  const Generator4 g4_; +  const Generator5 g5_; +  const Generator6 g6_; +  const Generator7 g7_; +}; + +template <class Generator1, class Generator2, class Generator3, +    class Generator4, class Generator5, class Generator6, class Generator7, +    class Generator8> +class CartesianProductHolder8 { + public: +CartesianProductHolder8(const Generator1& g1, const Generator2& g2, +    const Generator3& g3, const Generator4& g4, const Generator5& g5, +    const Generator6& g6, const Generator7& g7, const Generator8& g8) +      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), +          g8_(g8) {} +  template <typename T1, typename T2, typename T3, typename T4, typename T5, +      typename T6, typename T7, typename T8> +  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, +      T8> >() const { +    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> >( +        new CartesianProductGenerator8<T1, T2, T3, T4, T5, T6, T7, T8>( +        static_cast<ParamGenerator<T1> >(g1_), +        static_cast<ParamGenerator<T2> >(g2_), +        static_cast<ParamGenerator<T3> >(g3_), +        static_cast<ParamGenerator<T4> >(g4_), +        static_cast<ParamGenerator<T5> >(g5_), +        static_cast<ParamGenerator<T6> >(g6_), +        static_cast<ParamGenerator<T7> >(g7_), +        static_cast<ParamGenerator<T8> >(g8_))); +  } + + private: +  const Generator1 g1_; +  const Generator2 g2_; +  const Generator3 g3_; +  const Generator4 g4_; +  const Generator5 g5_; +  const Generator6 g6_; +  const Generator7 g7_; +  const Generator8 g8_; +}; + +template <class Generator1, class Generator2, class Generator3, +    class Generator4, class Generator5, class Generator6, class Generator7, +    class Generator8, class Generator9> +class CartesianProductHolder9 { + public: +CartesianProductHolder9(const Generator1& g1, const Generator2& g2, +    const Generator3& g3, const Generator4& g4, const Generator5& g5, +    const Generator6& g6, const Generator7& g7, const Generator8& g8, +    const Generator9& g9) +      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), +          g9_(g9) {} +  template <typename T1, typename T2, typename T3, typename T4, typename T5, +      typename T6, typename T7, typename T8, typename T9> +  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, +      T9> >() const { +    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, +        T9> >( +        new CartesianProductGenerator9<T1, T2, T3, T4, T5, T6, T7, T8, T9>( +        static_cast<ParamGenerator<T1> >(g1_), +        static_cast<ParamGenerator<T2> >(g2_), +        static_cast<ParamGenerator<T3> >(g3_), +        static_cast<ParamGenerator<T4> >(g4_), +        static_cast<ParamGenerator<T5> >(g5_), +        static_cast<ParamGenerator<T6> >(g6_), +        static_cast<ParamGenerator<T7> >(g7_), +        static_cast<ParamGenerator<T8> >(g8_), +        static_cast<ParamGenerator<T9> >(g9_))); +  } + + private: +  const Generator1 g1_; +  const Generator2 g2_; +  const Generator3 g3_; +  const Generator4 g4_; +  const Generator5 g5_; +  const Generator6 g6_; +  const Generator7 g7_; +  const Generator8 g8_; +  const Generator9 g9_; +}; + +template <class Generator1, class Generator2, class Generator3, +    class Generator4, class Generator5, class Generator6, class Generator7, +    class Generator8, class Generator9, class Generator10> +class CartesianProductHolder10 { + public: +CartesianProductHolder10(const Generator1& g1, const Generator2& g2, +    const Generator3& g3, const Generator4& g4, const Generator5& g5, +    const Generator6& g6, const Generator7& g7, const Generator8& g8, +    const Generator9& g9, const Generator10& g10) +      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), +          g9_(g9), g10_(g10) {} +  template <typename T1, typename T2, typename T3, typename T4, typename T5, +      typename T6, typename T7, typename T8, typename T9, typename T10> +  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, +      T9, T10> >() const { +    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, +        T9, T10> >( +        new CartesianProductGenerator10<T1, T2, T3, T4, T5, T6, T7, T8, T9, +            T10>( +        static_cast<ParamGenerator<T1> >(g1_), +        static_cast<ParamGenerator<T2> >(g2_), +        static_cast<ParamGenerator<T3> >(g3_), +        static_cast<ParamGenerator<T4> >(g4_), +        static_cast<ParamGenerator<T5> >(g5_), +        static_cast<ParamGenerator<T6> >(g6_), +        static_cast<ParamGenerator<T7> >(g7_), +        static_cast<ParamGenerator<T8> >(g8_), +        static_cast<ParamGenerator<T9> >(g9_), +        static_cast<ParamGenerator<T10> >(g10_))); +  } + + private: +  const Generator1 g1_; +  const Generator2 g2_; +  const Generator3 g3_; +  const Generator4 g4_; +  const Generator5 g5_; +  const Generator6 g6_; +  const Generator7 g7_; +  const Generator8 g8_; +  const Generator9 g9_; +  const Generator10 g10_; +}; + +#endif  // GTEST_HAS_COMBINE + +}  // namespace internal +}  // namespace testing + +#endif  //  GTEST_HAS_PARAM_TEST + +#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ diff --git a/llvm/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h new file mode 100644 index 00000000000..3bb07ecfc01 --- /dev/null +++ b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h @@ -0,0 +1,629 @@ +// Copyright 2008 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: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ + +#include <iterator> +#include <utility> +#include <vector> + +#include <gtest/internal/gtest-port.h> + +#ifdef GTEST_HAS_PARAM_TEST + +#if GTEST_HAS_RTTI +#include <typeinfo> +#endif  // GTEST_HAS_RTTI + +#include <gtest/internal/gtest-linked_ptr.h> +#include <gtest/internal/gtest-internal.h> + +namespace testing { +namespace internal { + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Outputs a message explaining invalid registration of different +// fixture class for the same test case. This may happen when +// TEST_P macro is used to define two tests with the same name +// but in different namespaces. +void ReportInvalidTestCaseType(const char* test_case_name, +                               const char* file, int line); + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Downcasts the pointer of type Base to Derived. +// Derived must be a subclass of Base. The parameter MUST +// point to a class of type Derived, not any subclass of it. +// When RTTI is available, the function performs a runtime +// check to enforce this. +template <class Derived, class Base> +Derived* CheckedDowncastToActualType(Base* base) { +#if GTEST_HAS_RTTI +  GTEST_CHECK_(typeid(*base) == typeid(Derived)); +  Derived* derived = dynamic_cast<Derived*>(base);  // NOLINT +#else +  Derived* derived = static_cast<Derived*>(base);  // Poor man's downcast. +#endif  // GTEST_HAS_RTTI +  return derived; +} + +template <typename> class ParamGeneratorInterface; +template <typename> class ParamGenerator; + +// Interface for iterating over elements provided by an implementation +// of ParamGeneratorInterface<T>. +template <typename T> +class ParamIteratorInterface { + public: +  virtual ~ParamIteratorInterface() {} +  // A pointer to the base generator instance. +  // Used only for the purposes of iterator comparison +  // to make sure that two iterators belong to the same generator. +  virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0; +  // Advances iterator to point to the next element +  // provided by the generator. The caller is responsible +  // for not calling Advance() on an iterator equal to +  // BaseGenerator()->End(). +  virtual void Advance() = 0; +  // Clones the iterator object. Used for implementing copy semantics +  // of ParamIterator<T>. +  virtual ParamIteratorInterface* Clone() const = 0; +  // Dereferences the current iterator and provides (read-only) access +  // to the pointed value. It is the caller's responsibility not to call +  // Current() on an iterator equal to BaseGenerator()->End(). +  // Used for implementing ParamGenerator<T>::operator*(). +  virtual const T* Current() const = 0; +  // Determines whether the given iterator and other point to the same +  // element in the sequence generated by the generator. +  // Used for implementing ParamGenerator<T>::operator==(). +  virtual bool Equals(const ParamIteratorInterface& other) const = 0; +}; + +// Class iterating over elements provided by an implementation of +// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T> +// and implements the const forward iterator concept. +template <typename T> +class ParamIterator { + public: +  typedef T value_type; +  typedef const T& reference; +  typedef ptrdiff_t difference_type; + +  // ParamIterator assumes ownership of the impl_ pointer. +  ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} +  ParamIterator& operator=(const ParamIterator& other) { +    if (this != &other) +      impl_.reset(other.impl_->Clone()); +    return *this; +  } + +  const T& operator*() const { return *impl_->Current(); } +  const T* operator->() const { return impl_->Current(); } +  // Prefix version of operator++. +  ParamIterator& operator++() { +    impl_->Advance(); +    return *this; +  } +  // Postfix version of operator++. +  ParamIterator operator++(int /*unused*/) { +    ParamIteratorInterface<T>* clone = impl_->Clone(); +    impl_->Advance(); +    return ParamIterator(clone); +  } +  bool operator==(const ParamIterator& other) const { +    return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); +  } +  bool operator!=(const ParamIterator& other) const { +    return !(*this == other); +  } + + private: +  friend class ParamGenerator<T>; +  explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {} +  scoped_ptr<ParamIteratorInterface<T> > impl_; +}; + +// ParamGeneratorInterface<T> is the binary interface to access generators +// defined in other translation units. +template <typename T> +class ParamGeneratorInterface { + public: +  typedef T ParamType; + +  virtual ~ParamGeneratorInterface() {} + +  // Generator interface definition +  virtual ParamIteratorInterface<T>* Begin() const = 0; +  virtual ParamIteratorInterface<T>* End() const = 0; +}; + +// Wraps ParamGeneratorInetrface<T> and provides general generator syntax +// compatible with the STL Container concept. +// This class implements copy initialization semantics and the contained +// ParamGeneratorInterface<T> instance is shared among all copies +// of the original object. This is possible because that instance is immutable. +template<typename T> +class ParamGenerator { + public: +  typedef ParamIterator<T> iterator; + +  explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {} +  ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} + +  ParamGenerator& operator=(const ParamGenerator& other) { +    impl_ = other.impl_; +    return *this; +  } + +  iterator begin() const { return iterator(impl_->Begin()); } +  iterator end() const { return iterator(impl_->End()); } + + private: +  ::testing::internal::linked_ptr<const ParamGeneratorInterface<T> > impl_; +}; + +// Generates values from a range of two comparable values. Can be used to +// generate sequences of user-defined types that implement operator+() and +// operator<(). +// This class is used in the Range() function. +template <typename T, typename IncrementT> +class RangeGenerator : public ParamGeneratorInterface<T> { + public: +  RangeGenerator(T begin, T end, IncrementT step) +      : begin_(begin), end_(end), +        step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} +  virtual ~RangeGenerator() {} + +  virtual ParamIteratorInterface<T>* Begin() const { +    return new Iterator(this, begin_, 0, step_); +  } +  virtual ParamIteratorInterface<T>* End() const { +    return new Iterator(this, end_, end_index_, step_); +  } + + private: +  class Iterator : public ParamIteratorInterface<T> { +   public: +    Iterator(const ParamGeneratorInterface<T>* base, T value, int index, +             IncrementT step) +        : base_(base), value_(value), index_(index), step_(step) {} +    virtual ~Iterator() {} + +    virtual const ParamGeneratorInterface<T>* BaseGenerator() const { +      return base_; +    } +    virtual void Advance() { +      value_ = value_ + step_; +      index_++; +    } +    virtual ParamIteratorInterface<T>* Clone() const { +      return new Iterator(*this); +    } +    virtual const T* Current() const { return &value_; } +    virtual bool Equals(const ParamIteratorInterface<T>& other) const { +      // Having the same base generator guarantees that the other +      // iterator is of the same type and we can downcast. +      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) +          << "The program attempted to compare iterators " +          << "from different generators." << std::endl; +      const int other_index = +          CheckedDowncastToActualType<const Iterator>(&other)->index_; +      return index_ == other_index; +    } + +   private: +    Iterator(const Iterator& other) +        : base_(other.base_), value_(other.value_), index_(other.index_), +          step_(other.step_) {} + +    const ParamGeneratorInterface<T>* const base_; +    T value_; +    int index_; +    const IncrementT step_; +  };  // class RangeGenerator::Iterator + +  static int CalculateEndIndex(const T& begin, +                               const T& end, +                               const IncrementT& step) { +    int end_index = 0; +    for (T i = begin; i < end; i = i + step) +      end_index++; +    return end_index; +  } + +  const T begin_; +  const T end_; +  const IncrementT step_; +  // The index for the end() iterator. All the elements in the generated +  // sequence are indexed (0-based) to aid iterator comparison. +  const int end_index_; +};  // class RangeGenerator + + +// Generates values from a pair of STL-style iterators. Used in the +// ValuesIn() function. The elements are copied from the source range +// since the source can be located on the stack, and the generator +// is likely to persist beyond that stack frame. +template <typename T> +class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> { + public: +  template <typename ForwardIterator> +  ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) +      : container_(begin, end) {} +  virtual ~ValuesInIteratorRangeGenerator() {} + +  virtual ParamIteratorInterface<T>* Begin() const { +    return new Iterator(this, container_.begin()); +  } +  virtual ParamIteratorInterface<T>* End() const { +    return new Iterator(this, container_.end()); +  } + + private: +  typedef typename ::std::vector<T> ContainerType; + +  class Iterator : public ParamIteratorInterface<T> { +   public: +    Iterator(const ParamGeneratorInterface<T>* base, +             typename ContainerType::const_iterator iterator) +        :  base_(base), iterator_(iterator) {} +    virtual ~Iterator() {} + +    virtual const ParamGeneratorInterface<T>* BaseGenerator() const { +      return base_; +    } +    virtual void Advance() { +      ++iterator_; +      value_.reset(); +    } +    virtual ParamIteratorInterface<T>* Clone() const { +      return new Iterator(*this); +    } +    // We need to use cached value referenced by iterator_ because *iterator_ +    // can return a temporary object (and of type other then T), so just +    // having "return &*iterator_;" doesn't work. +    // value_ is updated here and not in Advance() because Advance() +    // can advance iterator_ beyond the end of the range, and we cannot +    // detect that fact. The client code, on the other hand, is +    // responsible for not calling Current() on an out-of-range iterator. +    virtual const T* Current() const { +      if (value_.get() == NULL) +        value_.reset(new T(*iterator_)); +      return value_.get(); +    } +    virtual bool Equals(const ParamIteratorInterface<T>& other) const { +      // Having the same base generator guarantees that the other +      // iterator is of the same type and we can downcast. +      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) +          << "The program attempted to compare iterators " +          << "from different generators." << std::endl; +      return iterator_ == +          CheckedDowncastToActualType<const Iterator>(&other)->iterator_; +    } + +   private: +    Iterator(const Iterator& other) +          // The explicit constructor call suppresses a false warning +          // emitted by gcc when supplied with the -Wextra option. +        : ParamIteratorInterface<T>(), +          base_(other.base_), +          iterator_(other.iterator_) {} + +    const ParamGeneratorInterface<T>* const base_; +    typename ContainerType::const_iterator iterator_; +    // A cached value of *iterator_. We keep it here to allow access by +    // pointer in the wrapping iterator's operator->(). +    // value_ needs to be mutable to be accessed in Current(). +    // 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_; +  }; + +  const ContainerType container_; +};  // class ValuesInIteratorRangeGenerator + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Stores a parameter value and later creates tests parameterized with that +// value. +template <class TestClass> +class ParameterizedTestFactory : public TestFactoryBase { + public: +  typedef typename TestClass::ParamType ParamType; +  explicit ParameterizedTestFactory(ParamType parameter) : +      parameter_(parameter) {} +  virtual Test* CreateTest() { +    TestClass::SetParam(¶meter_); +    return new TestClass(); +  } + + private: +  const ParamType parameter_; + +  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactoryBase is a base class for meta-factories that create +// test factories for passing into MakeAndRegisterTestInfo function. +template <class ParamType> +class TestMetaFactoryBase { + public: +  virtual ~TestMetaFactoryBase() {} + +  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactory creates test factories for passing into +// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives +// ownership of test factory pointer, same factory object cannot be passed +// into that method twice. But ParameterizedTestCaseInfo is going to call +// it for each Test/Parameter value combination. Thus it needs meta factory +// creator class. +template <class TestCase> +class TestMetaFactory +    : public TestMetaFactoryBase<typename TestCase::ParamType> { + public: +  typedef typename TestCase::ParamType ParamType; + +  TestMetaFactory() {} + +  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { +    return new ParameterizedTestFactory<TestCase>(parameter); +  } + + private: +  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseInfoBase is a generic interface +// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase +// accumulates test information provided by TEST_P macro invocations +// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations +// and uses that information to register all resulting test instances +// in RegisterTests method. The ParameterizeTestCaseRegistry class holds +// a collection of pointers to the ParameterizedTestCaseInfo objects +// and calls RegisterTests() on each of them when asked. +class ParameterizedTestCaseInfoBase { + public: +  virtual ~ParameterizedTestCaseInfoBase() {} + +  // Base part of test case name for display purposes. +  virtual const String& GetTestCaseName() const = 0; +  // Test case id to verify identity. +  virtual TypeId GetTestCaseTypeId() const = 0; +  // UnitTest class invokes this method to register tests in this +  // test case right before running them in RUN_ALL_TESTS macro. +  // This method should not be called more then once on any single +  // instance of a ParameterizedTestCaseInfoBase derived class. +  virtual void RegisterTests() = 0; + + protected: +  ParameterizedTestCaseInfoBase() {} + + private: +  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P +// macro invocations for a particular test case and generators +// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that +// test case. It registers tests with all values generated by all +// generators when asked. +template <class TestCase> +class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { + public: +  // ParamType and GeneratorCreationFunc are private types but are required +  // for declarations of public methods AddTestPattern() and +  // AddTestCaseInstantiation(). +  typedef typename TestCase::ParamType ParamType; +  // A function that returns an instance of appropriate generator type. +  typedef ParamGenerator<ParamType>(GeneratorCreationFunc)(); + +  explicit ParameterizedTestCaseInfo(const char* name) +      : test_case_name_(name) {} + +  // Test case base name for display purposes. +  virtual const String& GetTestCaseName() const { return test_case_name_; } +  // Test case id to verify identity. +  virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); } +  // TEST_P macro uses AddTestPattern() to record information +  // about a single test in a LocalTestInfo structure. +  // test_case_name is the base name of the test case (without invocation +  // prefix). test_base_name is the name of an individual test without +  // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is +  // test case base name and DoBar is test base name. +  void AddTestPattern(const char* test_case_name, +                      const char* test_base_name, +                      TestMetaFactoryBase<ParamType>* meta_factory) { +    tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name, +                                                       test_base_name, +                                                       meta_factory))); +  } +  // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information +  // about a generator. +  int AddTestCaseInstantiation(const char* instantiation_name, +                               GeneratorCreationFunc* func, +                               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. +  } +  // UnitTest class invokes this method to register tests in this test case +  // test cases right before running tests in RUN_ALL_TESTS macro. +  // This method should not be called more then once on any single +  // instance of a ParameterizedTestCaseInfoBase derived class. +  // UnitTest has a guard to prevent from calling this method more then once. +  virtual void RegisterTests() { +    for (typename TestInfoContainer::iterator test_it = tests_.begin(); +         test_it != tests_.end(); ++test_it) { +      linked_ptr<TestInfo> test_info = *test_it; +      for (typename InstantiationContainer::iterator gen_it = +               instantiations_.begin(); gen_it != instantiations_.end(); +               ++gen_it) { +        const String& instantiation_name = gen_it->first; +        ParamGenerator<ParamType> generator((*gen_it->second)()); + +        Message test_case_name_stream; +        if ( !instantiation_name.empty() ) +          test_case_name_stream << instantiation_name.c_str() << "/"; +        test_case_name_stream << test_info->test_case_base_name.c_str(); + +        int i = 0; +        for (typename ParamGenerator<ParamType>::iterator param_it = +                 generator.begin(); +             param_it != generator.end(); ++param_it, ++i) { +          Message test_name_stream; +          test_name_stream << test_info->test_base_name.c_str() << "/" << i; +          ::testing::internal::MakeAndRegisterTestInfo( +              test_case_name_stream.GetString().c_str(), +              test_name_stream.GetString().c_str(), +              "",  // test_case_comment +              "",  // comment; TODO(vladl@google.com): provide parameter value +                   //                                  representation. +              GetTestCaseTypeId(), +              TestCase::SetUpTestCase, +              TestCase::TearDownTestCase, +              test_info->test_meta_factory->CreateTestFactory(*param_it)); +        }  // for param_it +      }  // for gen_it +    }  // for test_it +  }  // RegisterTests + + private: +  // LocalTestInfo structure keeps information about a single test registered +  // with TEST_P macro. +  struct TestInfo { +    TestInfo(const char* test_case_base_name, +             const char* test_base_name, +             TestMetaFactoryBase<ParamType>* test_meta_factory) : +        test_case_base_name(test_case_base_name), +        test_base_name(test_base_name), +        test_meta_factory(test_meta_factory) {} + +    const String test_case_base_name; +    const String test_base_name; +    const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory; +  }; +  typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer; +  // Keeps pairs of <Instantiation name, Sequence generator creation function> +  // received from INSTANTIATE_TEST_CASE_P macros. +  typedef ::std::vector<std::pair<String, GeneratorCreationFunc*> > +      InstantiationContainer; + +  const String test_case_name_; +  TestInfoContainer tests_; +  InstantiationContainer instantiations_; + +  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); +};  // class ParameterizedTestCaseInfo + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase +// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P +// macros use it to locate their corresponding ParameterizedTestCaseInfo +// descriptors. +class ParameterizedTestCaseRegistry { + public: +  ParameterizedTestCaseRegistry() {} +  ~ParameterizedTestCaseRegistry() { +    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); +         it != test_case_infos_.end(); ++it) { +      delete *it; +    } +  } + +  // Looks up or creates and returns a structure containing information about +  // tests and instantiations of a particular test case. +  template <class TestCase> +  ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder( +      const char* test_case_name, +      const char* file, +      int line) { +    ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL; +    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); +         it != test_case_infos_.end(); ++it) { +      if ((*it)->GetTestCaseName() == test_case_name) { +        if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) { +          // Complain about incorrect usage of Google Test facilities +          // and terminate the program since we cannot guaranty correct +          // test case setup and tear-down in this case. +          ReportInvalidTestCaseType(test_case_name,  file, line); +          abort(); +        } else { +          // At this point we are sure that the object we found is of the same +          // type we are looking for, so we downcast it to that type +          // without further checks. +          typed_test_info = CheckedDowncastToActualType< +              ParameterizedTestCaseInfo<TestCase> >(*it); +        } +        break; +      } +    } +    if (typed_test_info == NULL) { +      typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name); +      test_case_infos_.push_back(typed_test_info); +    } +    return typed_test_info; +  } +  void RegisterTests() { +    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); +         it != test_case_infos_.end(); ++it) { +      (*it)->RegisterTests(); +    } +  } + + private: +  typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer; + +  TestCaseInfoContainer test_case_infos_; + +  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); +}; + +}  // namespace internal +}  // namespace testing + +#endif  //  GTEST_HAS_PARAM_TEST + +#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ diff --git a/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port.h b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port.h new file mode 100644 index 00000000000..6a1593ef017 --- /dev/null +++ b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port.h @@ -0,0 +1,862 @@ +// Copyright 2005, 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. +// +// Authors: wan@google.com (Zhanyong Wan) +// +// Low-level types and utilities for porting Google Test to various +// platforms.  They are subject to change without notice.  DO NOT USE +// THEM IN USER CODE. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ + +// The user can define the following macros in the build script to +// control Google Test's behavior.  If the user doesn't define a macro +// in this list, Google Test will define it. +// +//   GTEST_HAS_CLONE          - Define it to 1/0 to indicate that clone(2) +//                              is/isn't available. +//   GTEST_HAS_GLOBAL_STRING  - Define it to 1/0 to indicate that ::string +//                              is/isn't available (some systems define +//                              ::string, which is different to std::string). +//   GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string +//                              is/isn't available (some systems define +//                              ::wstring, which is different to std::wstring). +//   GTEST_HAS_PTHREAD        - Define it to 1/0 to indicate that <pthread.h> +//                              is/isn't available. +//   GTEST_HAS_RTTI           - Define it to 1/0 to indicate that RTTI is/isn't +//                              enabled. +//   GTEST_HAS_STD_STRING     - Define it to 1/0 to indicate that +//                              std::string does/doesn't work (Google Test can +//                              be used where std::string is unavailable). +//   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 +//                              is/isn't available. + +// This header defines the following utilities: +// +// Macros indicating the name of the Google C++ Testing Framework project: +//   GTEST_NAME              - a string literal of the project name. +//   GTEST_FLAG_PREFIX       - a string literal of the prefix all Google +//                             Test flag names share. +//   GTEST_FLAG_PREFIX_UPPER - a string literal of the prefix all Google +//                             Test flag names share, in upper case. +// +// Macros indicating the current platform: +//   GTEST_OS_CYGWIN   - defined iff compiled on Cygwin. +//   GTEST_OS_LINUX    - defined iff compiled on Linux. +//   GTEST_OS_MAC      - defined iff compiled on Mac OS X. +//   GTEST_OS_SOLARIS  - defined iff compiled on Sun Solaris. +//   GTEST_OS_SYMBIAN  - defined iff compiled for Symbian. +//   GTEST_OS_WINDOWS  - defined iff compiled on Windows. +//   GTEST_OS_ZOS      - defined iff compiled on IBM z/OS. +// +// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the +// most stable support.  Since core members of the Google Test project +// don't have access to other platforms, support for them may be less +// stable.  If you notice any problems on your platform, please notify +// googletestframework@googlegroups.com (patches for fixing them are +// even more welcome!). +// +// Note that it is possible that none of the GTEST_OS_ macros are defined. +// +// Macros indicating available Google Test features: +//   GTEST_HAS_COMBINE      - defined iff Combine construct is supported +//                            in value-parameterized tests. +//   GTEST_HAS_DEATH_TEST   - defined iff death tests are supported. +//   GTEST_HAS_PARAM_TEST   - defined iff value-parameterized tests are +//                            supported. +//   GTEST_HAS_TYPED_TEST   - defined iff typed tests are supported. +//   GTEST_HAS_TYPED_TEST_P - defined iff type-parameterized tests are +//                            supported. +// +// 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_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. +//   GTEST_MUST_USE_RESULT_   - declares that a function's result must be used. +// +// Synchronization: +//   Mutex, MutexLock, ThreadLocal, GetThreadCount() +//                  - synchronization primitives. +//   GTEST_IS_THREADSAFE - defined to 1 to indicate that the above +//                         synchronization primitives have real implementations +//                         and Google Test is thread-safe; or 0 otherwise. +// +// Template meta programming: +//   is_pointer     - as in TR1; needed on Symbian and IBM XL C/C++ only. +// +// Smart pointers: +//   scoped_ptr     - as in TR2. +// +// Regular expressions: +//   RE             - a simple regular expression class using the POSIX +//                    Extended Regular Expression syntax.  Not available on +//                    Windows. +// +// Logging: +//   GTEST_LOG_()   - logs messages at the specified severity level. +//   LogToStderr()  - directs all log messages to stderr. +//   FlushInfoLog() - flushes informational log messages. +// +// Stderr capturing: +//   CaptureStderr()     - starts capturing stderr. +//   GetCapturedStderr() - stops capturing stderr and returns the captured +//                         string. +// +// Integer types: +//   TypeWithSize   - maps an integer to a int type. +//   Int32, UInt32, Int64, UInt64, TimeInMillis +//                  - integers of known sizes. +//   BiggestInt     - the biggest signed integer type. +// +// Command-line utilities: +//   GTEST_FLAG()       - references a flag. +//   GTEST_DECLARE_*()  - declares a flag. +//   GTEST_DEFINE_*()   - defines a flag. +//   GetArgvs()         - returns the command line as a vector of strings. +// +// Environment variable utilities: +//   GetEnv()             - gets the value of an environment variable. +//   BoolFromGTestEnv()   - parses a bool environment variable. +//   Int32FromGTestEnv()  - parses an Int32 environment variable. +//   StringFromGTestEnv() - parses a string environment variable. + +#include <stdlib.h> +#include <stdio.h> +#include <iostream>  // Used for GTEST_CHECK_ + +#define GTEST_NAME "Google Test" +#define GTEST_FLAG_PREFIX "gtest_" +#define GTEST_FLAG_PREFIX_UPPER "GTEST_" + +// Determines the version of gcc that is used to compile this. +#ifdef __GNUC__ +// 40302 means version 4.3.2. +#define GTEST_GCC_VER_ \ +    (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) +#endif  // __GNUC__ + +// Determines the platform on which Google Test is compiled. +#ifdef __CYGWIN__ +#define GTEST_OS_CYGWIN +#elif __SYMBIAN32__ +#define GTEST_OS_SYMBIAN +#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. +#define GTEST_OS_WINDOWS +#elif defined __APPLE__ +#define GTEST_OS_MAC +#elif defined __linux__ +#define GTEST_OS_LINUX +#elif defined __MVS__ +#define GTEST_OS_ZOS +#elif defined(__sun) && defined(__SVR4) +#define GTEST_OS_SOLARIS +#endif  // _MSC_VER + +// Determines whether ::std::string and ::string are available. + +#ifndef GTEST_HAS_STD_STRING +// The user didn't tell us whether ::std::string is available, so we +// need to figure it out. + +#ifdef GTEST_OS_WINDOWS +// Assumes that exceptions are enabled by default. +#ifndef _HAS_EXCEPTIONS +#define _HAS_EXCEPTIONS 1 +#endif  // _HAS_EXCEPTIONS +// GTEST_HAS_EXCEPTIONS is non-zero iff exceptions are enabled.  It is +// always defined, while _HAS_EXCEPTIONS is defined only on Windows. +#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS +// On Windows, we can use ::std::string if the compiler version is VS +// 2005 or above, or if exceptions are enabled. +#define GTEST_HAS_STD_STRING ((_MSC_VER >= 1400) || GTEST_HAS_EXCEPTIONS) +#else  // We are on Linux or Mac OS. +#define GTEST_HAS_EXCEPTIONS 0 +#define GTEST_HAS_STD_STRING 1 +#endif  // GTEST_OS_WINDOWS + +#endif  // GTEST_HAS_STD_STRING + +#ifndef GTEST_HAS_GLOBAL_STRING +// The user didn't tell us whether ::string is available, so we need +// to figure it out. + +#define GTEST_HAS_GLOBAL_STRING 0 + +#endif  // GTEST_HAS_GLOBAL_STRING + +#ifndef GTEST_HAS_STD_WSTRING +// The user didn't tell us whether ::std::wstring is available, so we need +// to figure it out. +// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring +//   is available. + +#if defined(GTEST_OS_CYGWIN) || defined(GTEST_OS_SOLARIS) +// At least some versions of cygwin don't support ::std::wstring. +// Solaris' libc++ doesn't support it either. +#define GTEST_HAS_STD_WSTRING 0 +#else +#define GTEST_HAS_STD_WSTRING GTEST_HAS_STD_STRING +#endif  // defined(GTEST_OS_CYGWIN) || defined(GTEST_OS_SOLARIS) + +#endif  // GTEST_HAS_STD_WSTRING + +#ifndef GTEST_HAS_GLOBAL_WSTRING +// The user didn't tell us whether ::wstring is available, so we need +// to figure it out. +#define GTEST_HAS_GLOBAL_WSTRING GTEST_HAS_GLOBAL_STRING +#endif  // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_STRING || GTEST_HAS_GLOBAL_STRING || \ +    GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING +#include <string>  // NOLINT +#endif  // GTEST_HAS_STD_STRING || GTEST_HAS_GLOBAL_STRING || +        // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_STRING +#include <sstream>  // NOLINT +#else +#include <strstream>  // NOLINT +#endif  // GTEST_HAS_STD_STRING + +// Determines whether RTTI is available. +#ifndef GTEST_HAS_RTTI +// The user didn't tell us whether RTTI is enabled, so we need to +// figure it out. + +#ifdef _MSC_VER + +#ifdef _CPPRTTI  // MSVC defines this macro iff RTTI is enabled. +#define GTEST_HAS_RTTI 1 +#else +#define GTEST_HAS_RTTI 0 +#endif  // _CPPRTTI + +#elif defined(__GNUC__) + +// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled. +#if GTEST_GCC_VER_ >= 40302 +#ifdef __GXX_RTTI +#define GTEST_HAS_RTTI 1 +#else +#define GTEST_HAS_RTTI 0 +#endif  // __GXX_RTTI +#else +// For gcc versions smaller than 4.3.2, we assume RTTI is enabled. +#define GTEST_HAS_RTTI 1 +#endif  // GTEST_GCC_VER >= 40302 + +#else + +// Unknown compiler - assume RTTI is enabled. +#define GTEST_HAS_RTTI 1 + +#endif  // _MSC_VER + +#endif  // GTEST_HAS_RTTI + +// Determines whether <pthread.h> is available. +#ifndef GTEST_HAS_PTHREAD +// The user didn't tell us, so we need to figure it out. + +#if defined(GTEST_OS_LINUX) || defined(GTEST_OS_MAC) +#define GTEST_HAS_PTHREAD 1 +#else +#define GTEST_HAS_PTHREAD 0 +#endif  // 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. +#ifndef GTEST_HAS_TR1_TUPLE +// The user didn't tell us, so we need to figure it out. + +// GCC provides <tr1/tuple> since 4.0.0. +#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) +#define GTEST_HAS_TR1_TUPLE 1 +#else +#define GTEST_HAS_TR1_TUPLE 0 +#endif  // __GNUC__ +#endif  // GTEST_HAS_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>. +#include <tr1/tuple> +#else +// If the compiler is not GCC, we assume the user is using a +// spec-conforming TR1 implementation. +#include <tuple> +#endif  // __GNUC__ +#endif  // GTEST_HAS_TR1_TUPLE + +// Determines whether clone(2) is supported. +// Usually it will only be available on Linux, excluding +// Linux on the Itanium architecture. +// Also see http://linux.die.net/man/2/clone. +#ifndef GTEST_HAS_CLONE +// The user didn't tell us, so we need to figure it out. + +#if defined(GTEST_OS_LINUX) && !defined(__ia64__) +#define GTEST_HAS_CLONE 1 +#else +#define GTEST_HAS_CLONE 0 +#endif  // defined(GTEST_OS_LINUX) && !defined(__ia64__) + +#endif  // GTEST_HAS_CLONE + +// Determines whether to support death tests. +#if GTEST_HAS_STD_STRING && GTEST_HAS_CLONE +#define GTEST_HAS_DEATH_TEST +// 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> +#include <vector> +#include <fcntl.h> +#include <sys/mman.h> +#endif  // GTEST_HAS_STD_STRING && GTEST_HAS_CLONE + +// Determines whether to support value-parameterized tests. + +#if defined(__GNUC__) || (_MSC_VER >= 1400) +// TODO(vladl@google.com): get the implementation rid of vector and list +// to compile on MSVC 7.1. +#define GTEST_HAS_PARAM_TEST +#endif  // defined(__GNUC__) || (_MSC_VER >= 1400) + +// Determines whether to support type-driven tests. + +// Typed tests need <typeinfo> and variadic macros, which gcc and VC +// 8.0+ support. +#if defined(__GNUC__) || (_MSC_VER >= 1400) +#define GTEST_HAS_TYPED_TEST +#define GTEST_HAS_TYPED_TEST_P +#endif  // defined(__GNUC__) || (_MSC_VER >= 1400) + +// Determines whether to support Combine(). This only makes sense when +// value-parameterized tests are enabled. +#if defined(GTEST_HAS_PARAM_TEST) && GTEST_HAS_TR1_TUPLE +#define GTEST_HAS_COMBINE +#endif  // defined(GTEST_HAS_PARAM_TEST) && GTEST_HAS_TR1_TUPLE + +// Determines whether the system compiler uses UTF-16 for encoding wide strings. +#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_CYGWIN) || \ +        defined(GTEST_OS_SYMBIAN) +#define GTEST_WIDE_STRING_USES_UTF16_ 1 +#endif + +// Defines some utility macros. + +// The GNU compiler emits a warning if nested "if" statements are followed by +// an "else" statement and braces are not used to explicitly disambiguate the +// "else" binding.  This leads to problems with code like: +// +//   if (gate) +//     ASSERT_*(condition) << "Some message"; +// +// The "switch (0) case 0:" idiom is used to suppress this. +#ifdef __INTEL_COMPILER +#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ +#else +#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0:  // NOLINT +#endif + +// 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: +// +//   struct Foo { +//     Foo() { ... } +//   } GTEST_ATTRIBUTE_UNUSED_; +#if defined(__GNUC__) && !defined(COMPILER_ICC) +#define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) +#else +#define GTEST_ATTRIBUTE_UNUSED_ +#endif + +// A macro to disallow the evil copy constructor and operator= functions +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\ +  type(const type &);\ +  void operator=(const type &) + +// Tell the compiler to warn about unused return values for functions declared +// with this macro.  The macro should be used on function declarations +// following the argument list: +// +//   Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; +#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC) +#define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) +#else +#define GTEST_MUST_USE_RESULT_ +#endif  // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC + +namespace testing { + +class Message; + +namespace internal { + +class String; + +// std::strstream is deprecated.  However, we have to use it on +// Windows as std::stringstream won't compile on Windows when +// exceptions are disabled.  We use std::stringstream on other +// platforms to avoid compiler warnings there. +#if GTEST_HAS_STD_STRING +typedef ::std::stringstream StrStream; +#else +typedef ::std::strstream StrStream; +#endif  // GTEST_HAS_STD_STRING + +// Defines scoped_ptr. + +// This implementation of scoped_ptr is PARTIAL - it only contains +// enough stuff to satisfy Google Test's need. +template <typename T> +class scoped_ptr { + public: +  explicit scoped_ptr(T* p = NULL) : ptr_(p) {} +  ~scoped_ptr() { reset(); } + +  T& operator*() const { return *ptr_; } +  T* operator->() const { return ptr_; } +  T* get() const { return ptr_; } + +  T* release() { +    T* const ptr = ptr_; +    ptr_ = NULL; +    return ptr; +  } + +  void reset(T* p = NULL) { +    if (p != ptr_) { +      if (sizeof(T) > 0) {  // Makes sure T is a complete type. +        delete ptr_; +      } +      ptr_ = p; +    } +  } + private: +  T* ptr_; + +  GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr); +}; + +#ifdef GTEST_HAS_DEATH_TEST + +// Defines RE. + +// A simple C++ wrapper for <regex.h>.  It uses the POSIX Enxtended +// Regular Expression syntax. +class RE { + public: +  // Constructs an RE from a string. +#if GTEST_HAS_STD_STRING +  RE(const ::std::string& regex) { Init(regex.c_str()); }  // NOLINT +#endif  // GTEST_HAS_STD_STRING + +#if GTEST_HAS_GLOBAL_STRING +  RE(const ::string& regex) { Init(regex.c_str()); }  // NOLINT +#endif  // GTEST_HAS_GLOBAL_STRING + +  RE(const char* regex) { Init(regex); }  // NOLINT +  ~RE(); + +  // Returns the string representation of the regex. +  const char* pattern() const { return pattern_; } + +  // FullMatch(str, re) returns true iff regular expression re matches +  // the entire str. +  // PartialMatch(str, re) returns true iff regular expression re +  // matches a substring of str (including str itself). +  // +  // TODO(wan@google.com): make FullMatch() and PartialMatch() work +  // when str contains NUL characters. +#if GTEST_HAS_STD_STRING +  static bool FullMatch(const ::std::string& str, const RE& re) { +    return FullMatch(str.c_str(), re); +  } +  static bool PartialMatch(const ::std::string& str, const RE& re) { +    return PartialMatch(str.c_str(), re); +  } +#endif  // GTEST_HAS_STD_STRING + +#if GTEST_HAS_GLOBAL_STRING +  static bool FullMatch(const ::string& str, const RE& re) { +    return FullMatch(str.c_str(), re); +  } +  static bool PartialMatch(const ::string& str, const RE& re) { +    return PartialMatch(str.c_str(), re); +  } +#endif  // GTEST_HAS_GLOBAL_STRING + +  static bool FullMatch(const char* str, const RE& re); +  static bool PartialMatch(const char* str, const RE& re); + + private: +  void Init(const char* regex); + +  // We use a const char* instead of a string, as Google Test may be used +  // where string is not available.  We also do not use Google Test's own +  // String type here, in order to simplify dependencies between the +  // files. +  const char* pattern_; +  regex_t full_regex_;     // For FullMatch(). +  regex_t partial_regex_;  // For PartialMatch(). +  bool is_valid_; +}; + +#endif  // GTEST_HAS_DEATH_TEST + +// Defines logging utilities: +//   GTEST_LOG_()   - logs messages at the specified severity level. +//   LogToStderr()  - directs all log messages to stderr. +//   FlushInfoLog() - flushes informational log messages. + +enum GTestLogSeverity { +  GTEST_INFO, +  GTEST_WARNING, +  GTEST_ERROR, +  GTEST_FATAL +}; + +void GTestLog(GTestLogSeverity severity, const char* file, +              int line, const char* msg); + +#define GTEST_LOG_(severity, msg)\ +    ::testing::internal::GTestLog(\ +        ::testing::internal::GTEST_##severity, __FILE__, __LINE__, \ +        (::testing::Message() << (msg)).GetString().c_str()) + +inline void LogToStderr() {} +inline void FlushInfoLog() { fflush(NULL); } + +// Defines the stderr capturer: +//   CaptureStderr     - starts capturing stderr. +//   GetCapturedStderr - stops capturing stderr and returns the captured string. + +#ifdef GTEST_HAS_DEATH_TEST + +// A copy of all command line arguments.  Set by InitGoogleTest(). +extern ::std::vector<String> g_argvs; + +void CaptureStderr(); +// GTEST_HAS_DEATH_TEST implies we have ::std::string. +::std::string GetCapturedStderr(); +const ::std::vector<String>& GetArgvs(); + +#endif  // GTEST_HAS_DEATH_TEST + +// Defines synchronization primitives. + +// A dummy implementation of synchronization primitives (mutex, lock, +// and thread-local variable).  Necessary for compiling Google Test where +// mutex is not supported - using Google Test in multiple threads is not +// supported on such platforms. + +class Mutex { + public: +  Mutex() {} +  explicit Mutex(int /*unused*/) {} +  void AssertHeld() const {} +  enum { NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX = 0 }; +}; + +// We cannot call it MutexLock directly as the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms.  Hence the typedef trick below. +class GTestMutexLock { + public: +  explicit GTestMutexLock(Mutex*) {}  // NOLINT +}; + +typedef GTestMutexLock MutexLock; + +template <typename T> +class ThreadLocal { + public: +  ThreadLocal() : value_() {} +  explicit ThreadLocal(const T& value) : value_(value) {} +  T* pointer() { return &value_; } +  const T* pointer() const { return &value_; } +  const T& get() const { return value_; } +  void set(const T& value) { value_ = value; } + private: +  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; } + +// The above synchronization primitives have dummy implementations. +// Therefore Google Test is not thread-safe. +#define GTEST_IS_THREADSAFE 0 + +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) + +// Passing non-POD classes through ellipsis (...) crashes the ARM +// compiler.  The Nokia Symbian and the IBM XL C/C++ compiler try to +// instantiate a copy constructor for objects passed through ellipsis +// (...), failing for uncopyable objects.  We define this to indicate +// the fact. +#define GTEST_ELLIPSIS_NEEDS_COPY_ 1 + +// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between +// const T& and const T* in a function template.  These compilers +// _can_ decide between class template specializations for T and T*, +// so a tr1::type_traits-like is_pointer works. +#define GTEST_NEEDS_IS_POINTER_ 1 + +#endif  // defined(__SYMBIAN32__) || defined(__IBMCPP__) + +template <bool bool_value> +struct bool_constant { +  typedef bool_constant<bool_value> type; +  static const bool value = bool_value; +}; +template <bool bool_value> const bool bool_constant<bool_value>::value; + +typedef bool_constant<false> false_type; +typedef bool_constant<true> true_type; + +template <typename T> +struct is_pointer : public false_type {}; + +template <typename T> +struct is_pointer<T*> : public true_type {}; + +// Defines BiggestInt as the biggest signed integer type the compiler +// supports. + +#ifdef GTEST_OS_WINDOWS +typedef __int64 BiggestInt; +#else +typedef long long BiggestInt;  // NOLINT +#endif  // GTEST_OS_WINDOWS + +// The maximum number a BiggestInt can represent.  This definition +// works no matter BiggestInt is represented in one's complement or +// two's complement. +// +// We cannot rely on numeric_limits in STL, as __int64 and long long +// are not part of standard C++ and numeric_limits doesn't need to be +// defined for them. +const BiggestInt kMaxBiggestInt = +    ~(static_cast<BiggestInt>(1) << (8*sizeof(BiggestInt) - 1)); + +// This template class serves as a compile-time function from size to +// type.  It maps a size in bytes to a primitive type with that +// size. e.g. +// +//   TypeWithSize<4>::UInt +// +// is typedef-ed to be unsigned int (unsigned integer made up of 4 +// bytes). +// +// Such functionality should belong to STL, but I cannot find it +// there. +// +// Google Test uses this class in the implementation of floating-point +// comparison. +// +// For now it only handles UInt (unsigned int) as that's all Google Test +// needs.  Other types can be easily added in the future if need +// arises. +template <size_t size> +class TypeWithSize { + public: +  // This prevents the user from using TypeWithSize<N> with incorrect +  // values of N. +  typedef void UInt; +}; + +// The specialization for size 4. +template <> +class TypeWithSize<4> { + public: +  // unsigned int has size 4 in both gcc and MSVC. +  // +  // As base/basictypes.h doesn't compile on Windows, we cannot use +  // uint32, uint64, and etc here. +  typedef int Int; +  typedef unsigned int UInt; +}; + +// The specialization for size 8. +template <> +class TypeWithSize<8> { + public: +#ifdef GTEST_OS_WINDOWS +  typedef __int64 Int; +  typedef unsigned __int64 UInt; +#else +  typedef long long Int;  // NOLINT +  typedef unsigned long long UInt;  // NOLINT +#endif  // GTEST_OS_WINDOWS +}; + +// Integer types of known sizes. +typedef TypeWithSize<4>::Int Int32; +typedef TypeWithSize<4>::UInt UInt32; +typedef TypeWithSize<8>::Int Int64; +typedef TypeWithSize<8>::UInt UInt64; +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 defined(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 +// is not satisfied. +//  Synopsys: +//    GTEST_CHECK_(boolean_condition); +//     or +//    GTEST_CHECK_(boolean_condition) << "Additional message"; +// +//    This checks the condition and if the condition is not satisfied +//    it prints message about the condition violation, including the +//    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) \ +      ; \ +    else \ +      ::testing::internal::GTestCheckProvider(\ +          #condition, __FILE__, __LINE__).GetStream() + +// Macro for referencing flags. +#define GTEST_FLAG(name) FLAGS_gtest_##name + +// Macros for declaring flags. +#define GTEST_DECLARE_bool_(name) extern bool GTEST_FLAG(name) +#define GTEST_DECLARE_int32_(name) \ +    extern ::testing::internal::Int32 GTEST_FLAG(name) +#define GTEST_DECLARE_string_(name) \ +    extern ::testing::internal::String GTEST_FLAG(name) + +// Macros for defining flags. +#define GTEST_DEFINE_bool_(name, default_val, doc) \ +    bool GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_int32_(name, default_val, doc) \ +    ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_string_(name, default_val, doc) \ +    ::testing::internal::String GTEST_FLAG(name) = (default_val) + +// Parses 'str' for a 32-bit signed integer.  If successful, writes the result +// to *value and returns true; otherwise leaves *value unchanged and returns +// false. +// TODO(chandlerc): Find a better way to refactor flag and environment parsing +// out of both gtest-port.cc and gtest.cc to avoid exporting this utility +// function. +bool ParseInt32(const Message& src_text, const char* str, Int32* value); + +// Parses a bool/Int32/string from the environment variable +// corresponding to the given Google Test flag. +bool BoolFromGTestEnv(const char* flag, bool default_val); +Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); +const char* StringFromGTestEnv(const char* flag, const char* default_val); + +}  // namespace internal +}  // namespace testing + +#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ diff --git a/llvm/utils/unittest/googletest/include/gtest/internal/gtest-string.h b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-string.h new file mode 100644 index 00000000000..178f14e1264 --- /dev/null +++ b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-string.h @@ -0,0 +1,335 @@ +// Copyright 2005, 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. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file declares the String class and functions used internally by +// Google Test.  They are subject to change without notice. They should not used +// by code external to Google Test. +// +// This header file is #included by testing/base/internal/gtest-internal.h. +// It should not be #included by other files. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ + +#include <string.h> +#include <gtest/internal/gtest-port.h> + +#if GTEST_HAS_GLOBAL_STRING || GTEST_HAS_STD_STRING +#include <string> +#endif  // GTEST_HAS_GLOBAL_STRING || GTEST_HAS_STD_STRING + +namespace testing { +namespace internal { + +// String - a UTF-8 string class. +// +// We cannot use std::string as Microsoft's STL implementation in +// Visual C++ 7.1 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. +// +// Also, String is different from std::string in that it can represent +// both NULL and the empty string, while std::string cannot represent +// NULL. +// +// NULL and the empty string are considered different.  NULL is less +// than anything (including the empty string) except itself. +// +// This class only provides minimum functionality necessary for +// implementing Google Test.  We do not intend to implement a full-fledged +// string class here. +// +// Since the purpose of this class is to provide a substitute for +// std::string on platforms where it cannot be used, we define a copy +// constructor and assignment operators such that we don't need +// conditional compilation in a lot of places. +// +// In order to make the representation efficient, the d'tor of String +// is not virtual.  Therefore DO NOT INHERIT FROM String. +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". +  // +  // This is useful for printing a C string in the syntax of a literal. +  // +  // Known issue: escape sequences are not handled yet. +  static String ShowCStringQuoted(const char* c_str); + +  // Clones a 0-terminated C string, allocating memory using new.  The +  // caller is responsible for deleting the return value using +  // delete[].  Returns the cloned string, or NULL if the input is +  // NULL. +  // +  // This is different from strdup() in string.h, which allocates +  // memory using malloc(). +  static const char* CloneCString(const char* c_str); + +#ifdef _WIN32_WCE +  // 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. + +  // Creates a UTF-16 wide string from the given ANSI string, allocating +  // memory using new. The caller is responsible for deleting the return +  // value using delete[]. Returns the wide string, or NULL if the +  // input is NULL. +  // +  // The wide string is created using the ANSI codepage (CP_ACP) to +  // match the behaviour of the ANSI versions of Win32 calls and the +  // C runtime. +  static LPCWSTR AnsiToUtf16(const char* c_str); + +  // Creates an ANSI string from the given wide string, allocating +  // memory using new. The caller is responsible for deleting the return +  // value using delete[]. Returns the ANSI string, or NULL if the +  // input is NULL. +  // +  // The returned string is created using the ANSI codepage (CP_ACP) to +  // match the behaviour of the ANSI versions of Win32 calls and the +  // C runtime. +  static const char* Utf16ToAnsi(LPCWSTR utf16_str); +#endif + +  // Compares two C strings.  Returns true iff they have the same content. +  // +  // Unlike strcmp(), this function can handle NULL argument(s).  A +  // NULL C string is considered different to any non-NULL C string, +  // including the empty string. +  static bool CStringEquals(const char* lhs, const char* rhs); + +  // Converts a wide C string to a String using the UTF-8 encoding. +  // NULL will be converted to "(null)".  If an error occurred during +  // the conversion, "(failed to convert from wide string)" is +  // returned. +  static String ShowWideCString(const wchar_t* wide_c_str); + +  // Similar to ShowWideCString(), except that this function encloses +  // the converted string in double quotes. +  static String ShowWideCStringQuoted(const wchar_t* wide_c_str); + +  // Compares two wide C strings.  Returns true iff they have the same +  // content. +  // +  // Unlike wcscmp(), this function can handle NULL argument(s).  A +  // NULL C string is considered different to any non-NULL C string, +  // including the empty string. +  static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); + +  // Compares two C strings, ignoring case.  Returns true iff they +  // have the same content. +  // +  // Unlike strcasecmp(), this function can handle NULL argument(s). +  // A NULL C string is considered different to any non-NULL C string, +  // including the empty string. +  static bool CaseInsensitiveCStringEquals(const char* lhs, +                                           const char* rhs); + +  // Compares two wide C strings, ignoring case.  Returns true iff they +  // have the same content. +  // +  // Unlike wcscasecmp(), this function can handle NULL argument(s). +  // A NULL C string is considered different to any non-NULL wide C string, +  // including the empty string. +  // NB: The implementations on different platforms slightly differ. +  // On windows, this method uses _wcsicmp which compares according to LC_CTYPE +  // environment variable. On GNU platform this method uses wcscasecmp +  // which compares according to LC_CTYPE category of the current locale. +  // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the +  // current locale. +  static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, +                                               const wchar_t* rhs); + +  // Formats a list of arguments to a String, using the same format +  // spec string as for printf. +  // +  // We do not use the StringPrintf class as it is not universally +  // available. +  // +  // The result is limited to 4096 characters (including the tailing +  // 0).  If 4096 characters are not enough to format the input, +  // "<buffer exceeded>" is returned. +  static String Format(const char* format, ...); + +  // C'tors + +  // The default c'tor constructs a NULL string. +  String() : c_str_(NULL) {} + +  // Constructs a String by cloning a 0-terminated C string. +  String(const char* c_str) : c_str_(NULL) {  // NOLINT +    *this = 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); + +  // 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; +  } + +  // D'tor.  String is intended to be a final class, so the d'tor +  // doesn't need to be virtual. +  ~String() { delete[] c_str_; } + +  // Allows a String to be implicitly converted to an ::std::string or +  // ::string, and vice versa.  Converting a String containing a NULL +  // pointer to ::std::string or ::string is undefined behavior. +  // Converting a ::std::string or ::string containing an embedded NUL +  // 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(); } + +  operator ::std::string() const { return ::std::string(c_str_); } +#endif  // GTEST_HAS_STD_STRING + +#if GTEST_HAS_GLOBAL_STRING +  String(const ::string& str) : c_str_(NULL) { *this = str.c_str(); } + +  operator ::string() const { return ::string(c_str_); } +#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'); +  } + +  // Compares this with another String. +  // Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0 +  // if this is greater than rhs. +  int Compare(const String& rhs) const; + +  // 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); +  } + +  // Returns true iff this String is less than the given C 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); +  } + +  // Returns true iff this String ends with the given suffix.  *Any* +  // String is considered to end with a NULL or empty suffix. +  bool EndsWith(const char* suffix) const; + +  // Returns true iff this String ends with the given suffix, not considering +  // 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 +  // string is NULL. +  int GetLength() const { +    return c_str_ ? static_cast<int>(strlen(c_str_)) : -1; +  } + +  // 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); + +  // Assigns a String object to this object.  Self-assignment works. +  const String& operator=(const String &rhs) { +    *this = rhs.c_str_; +    return *this; +  } + + private: +  const char* c_str_; +}; + +// 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()); +} + +// Gets the content of the StrStream's buffer as a String.  Each '\0' +// character in the buffer is replaced with "\\0". +String StrStreamToString(StrStream* stream); + +// Converts a streamable value to a String.  A NULL pointer is +// converted to "(null)".  When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". + +// Declared here but defined in gtest.h, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template <typename T> +String StreamableToString(const T& streamable); + +}  // namespace internal +}  // namespace testing + +#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ diff --git a/llvm/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h new file mode 100644 index 00000000000..815da4ba83c --- /dev/null +++ b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h @@ -0,0 +1,3319 @@ +// This file was GENERATED by a script.  DO NOT EDIT BY HAND!!! + +// Copyright 2008 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) + +// Type utilities needed for implementing typed and type-parameterized +// tests.  This file is generated by a SCRIPT.  DO NOT EDIT BY HAND! +// +// Currently we support at most 50 types in a list, and at most 50 +// type-parameterized tests in one type-parameterized test case. +// Please contact googletestframework@googlegroups.com if you need +// more. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + +#include <gtest/internal/gtest-port.h> +#include <gtest/internal/gtest-string.h> + +#if defined(GTEST_HAS_TYPED_TEST) || defined(GTEST_HAS_TYPED_TEST_P) + +#ifdef __GNUC__ +#include <cxxabi.h> +#endif  // __GNUC__ + +#include <typeinfo> + +namespace testing { +namespace internal { + +// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same +// type.  This can be used as a compile-time assertion to ensure that +// two types are equal. + +template <typename T1, typename T2> +struct AssertTypeEq; + +template <typename T> +struct AssertTypeEq<T, T> { +  typedef bool type; +}; + +// GetTypeName<T>() returns a human-readable name of type T. +template <typename T> +String GetTypeName() { +#if GTEST_HAS_RTTI + +  const char* const name = typeid(T).name(); +#ifdef __GNUC__ +  int status = 0; +  // gcc's implementation of typeid(T).name() mangles the type name, +  // so we have to demangle it. +  char* const readable_name = abi::__cxa_demangle(name, 0, 0, &status); +  const String name_str(status == 0 ? readable_name : name); +  free(readable_name); +  return name_str; +#else +  return name; +#endif  // __GNUC__ + +#else +  return "<type>"; +#endif  // GTEST_HAS_RTTI +} + +// A unique type used as the default value for the arguments of class +// template Types.  This allows us to simulate variadic templates +// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't +// support directly. +struct None {}; + +// The following family of struct and struct templates are used to +// represent type lists.  In particular, TypesN<T1, T2, ..., TN> +// represents a type list with N types (T1, T2, ..., and TN) in it. +// Except for Types0, every struct in the family has two member types: +// Head for the first type in the list, and Tail for the rest of the +// list. + +// The empty type list. +struct Types0 {}; + +// Type lists of length 1, 2, 3, and so on. + +template <typename T1> +struct Types1 { +  typedef T1 Head; +  typedef Types0 Tail; +}; +template <typename T1, typename T2> +struct Types2 { +  typedef T1 Head; +  typedef Types1<T2> Tail; +}; + +template <typename T1, typename T2, typename T3> +struct Types3 { +  typedef T1 Head; +  typedef Types2<T2, T3> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4> +struct Types4 { +  typedef T1 Head; +  typedef Types3<T2, T3, T4> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5> +struct Types5 { +  typedef T1 Head; +  typedef Types4<T2, T3, T4, T5> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6> +struct Types6 { +  typedef T1 Head; +  typedef Types5<T2, T3, T4, T5, T6> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7> +struct Types7 { +  typedef T1 Head; +  typedef Types6<T2, T3, T4, T5, T6, T7> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8> +struct Types8 { +  typedef T1 Head; +  typedef Types7<T2, T3, T4, T5, T6, T7, T8> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9> +struct Types9 { +  typedef T1 Head; +  typedef Types8<T2, T3, T4, T5, T6, T7, T8, T9> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10> +struct Types10 { +  typedef T1 Head; +  typedef Types9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11> +struct Types11 { +  typedef T1 Head; +  typedef Types10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12> +struct Types12 { +  typedef T1 Head; +  typedef Types11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13> +struct Types13 { +  typedef T1 Head; +  typedef Types12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14> +struct Types14 { +  typedef T1 Head; +  typedef Types13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15> +struct Types15 { +  typedef T1 Head; +  typedef Types14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16> +struct Types16 { +  typedef T1 Head; +  typedef Types15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17> +struct Types17 { +  typedef T1 Head; +  typedef Types16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18> +struct Types18 { +  typedef T1 Head; +  typedef Types17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19> +struct Types19 { +  typedef T1 Head; +  typedef Types18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20> +struct Types20 { +  typedef T1 Head; +  typedef Types19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21> +struct Types21 { +  typedef T1 Head; +  typedef Types20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22> +struct Types22 { +  typedef T1 Head; +  typedef Types21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23> +struct Types23 { +  typedef T1 Head; +  typedef Types22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24> +struct Types24 { +  typedef T1 Head; +  typedef Types23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25> +struct Types25 { +  typedef T1 Head; +  typedef Types24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26> +struct Types26 { +  typedef T1 Head; +  typedef Types25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27> +struct Types27 { +  typedef T1 Head; +  typedef Types26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28> +struct Types28 { +  typedef T1 Head; +  typedef Types27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29> +struct Types29 { +  typedef T1 Head; +  typedef Types28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30> +struct Types30 { +  typedef T1 Head; +  typedef Types29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31> +struct Types31 { +  typedef T1 Head; +  typedef Types30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32> +struct Types32 { +  typedef T1 Head; +  typedef Types31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33> +struct Types33 { +  typedef T1 Head; +  typedef Types32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32, T33> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34> +struct Types34 { +  typedef T1 Head; +  typedef Types33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32, T33, T34> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35> +struct Types35 { +  typedef T1 Head; +  typedef Types34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32, T33, T34, T35> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36> +struct Types36 { +  typedef T1 Head; +  typedef Types35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32, T33, T34, T35, T36> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37> +struct Types37 { +  typedef T1 Head; +  typedef Types36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32, T33, T34, T35, T36, T37> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38> +struct Types38 { +  typedef T1 Head; +  typedef Types37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39> +struct Types39 { +  typedef T1 Head; +  typedef Types38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40> +struct Types40 { +  typedef T1 Head; +  typedef Types39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41> +struct Types41 { +  typedef T1 Head; +  typedef Types40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42> +struct Types42 { +  typedef T1 Head; +  typedef Types41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43> +struct Types43 { +  typedef T1 Head; +  typedef Types42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, +      T43> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44> +struct Types44 { +  typedef T1 Head; +  typedef Types43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, +      T44> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45> +struct Types45 { +  typedef T1 Head; +  typedef Types44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, +      T44, T45> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46> +struct Types46 { +  typedef T1 Head; +  typedef Types45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, +      T44, T45, T46> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46, typename T47> +struct Types47 { +  typedef T1 Head; +  typedef Types46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, +      T44, T45, T46, T47> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46, typename T47, typename T48> +struct Types48 { +  typedef T1 Head; +  typedef Types47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, +      T44, T45, T46, T47, T48> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46, typename T47, typename T48, typename T49> +struct Types49 { +  typedef T1 Head; +  typedef Types48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, +      T44, T45, T46, T47, T48, T49> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46, typename T47, typename T48, typename T49, typename T50> +struct Types50 { +  typedef T1 Head; +  typedef Types49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, +      T44, T45, T46, T47, T48, T49, T50> Tail; +}; + + +}  // namespace internal + +// We don't want to require the users to write TypesN<...> directly, +// as that would require them to count the length.  Types<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Types<int> +// will appear as Types<int, None, None, ..., None> in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Types<T1, ..., TN>, and Google Test will translate +// that to TypesN<T1, ..., TN> internally to make error messages +// readable.  The translation is done by the 'type' member of the +// Types template. +template <typename T1 = internal::None, typename T2 = internal::None, +    typename T3 = internal::None, typename T4 = internal::None, +    typename T5 = internal::None, typename T6 = internal::None, +    typename T7 = internal::None, typename T8 = internal::None, +    typename T9 = internal::None, typename T10 = internal::None, +    typename T11 = internal::None, typename T12 = internal::None, +    typename T13 = internal::None, typename T14 = internal::None, +    typename T15 = internal::None, typename T16 = internal::None, +    typename T17 = internal::None, typename T18 = internal::None, +    typename T19 = internal::None, typename T20 = internal::None, +    typename T21 = internal::None, typename T22 = internal::None, +    typename T23 = internal::None, typename T24 = internal::None, +    typename T25 = internal::None, typename T26 = internal::None, +    typename T27 = internal::None, typename T28 = internal::None, +    typename T29 = internal::None, typename T30 = internal::None, +    typename T31 = internal::None, typename T32 = internal::None, +    typename T33 = internal::None, typename T34 = internal::None, +    typename T35 = internal::None, typename T36 = internal::None, +    typename T37 = internal::None, typename T38 = internal::None, +    typename T39 = internal::None, typename T40 = internal::None, +    typename T41 = internal::None, typename T42 = internal::None, +    typename T43 = internal::None, typename T44 = internal::None, +    typename T45 = internal::None, typename T46 = internal::None, +    typename T47 = internal::None, typename T48 = internal::None, +    typename T49 = internal::None, typename T50 = internal::None> +struct Types { +  typedef internal::Types50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, +      T41, T42, T43, T44, T45, T46, T47, T48, T49, T50> type; +}; + +template <> +struct Types<internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None> { +  typedef internal::Types0 type; +}; +template <typename T1> +struct Types<T1, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None> { +  typedef internal::Types1<T1> type; +}; +template <typename T1, typename T2> +struct Types<T1, T2, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None> { +  typedef internal::Types2<T1, T2> type; +}; +template <typename T1, typename T2, typename T3> +struct Types<T1, T2, T3, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None> { +  typedef internal::Types3<T1, T2, T3> type; +}; +template <typename T1, typename T2, typename T3, typename T4> +struct Types<T1, T2, T3, T4, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None> { +  typedef internal::Types4<T1, T2, T3, T4> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5> +struct Types<T1, T2, T3, T4, T5, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None> { +  typedef internal::Types5<T1, T2, T3, T4, T5> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6> +struct Types<T1, T2, T3, T4, T5, T6, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None> { +  typedef internal::Types6<T1, T2, T3, T4, T5, T6> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7> +struct Types<T1, T2, T3, T4, T5, T6, T7, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None> { +  typedef internal::Types7<T1, T2, T3, T4, T5, T6, T7> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None> { +  typedef internal::Types8<T1, T2, T3, T4, T5, T6, T7, T8> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None> { +  typedef internal::Types9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None> { +  typedef internal::Types10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None> { +  typedef internal::Types11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None> { +  typedef internal::Types12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, +      T12> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None> { +  typedef internal::Types13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None> { +  typedef internal::Types14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None> { +  typedef internal::Types15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None> { +  typedef internal::Types16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None> { +  typedef internal::Types17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None> { +  typedef internal::Types18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None> { +  typedef internal::Types19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None> { +  typedef internal::Types20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None> { +  typedef internal::Types21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None> { +  typedef internal::Types22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None> { +  typedef internal::Types23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None> { +  typedef internal::Types24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None> { +  typedef internal::Types25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None> { +  typedef internal::Types26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, +      T26> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None> { +  typedef internal::Types27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None> { +  typedef internal::Types28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None> { +  typedef internal::Types29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None> { +  typedef internal::Types30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None> { +  typedef internal::Types31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, T32, internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None> { +  typedef internal::Types32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, T32, T33, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None> { +  typedef internal::Types33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, T32, T33, T34, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None> { +  typedef internal::Types34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33, T34> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, T32, T33, T34, T35, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None> { +  typedef internal::Types35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33, T34, T35> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, T32, T33, T34, T35, T36, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None> { +  typedef internal::Types36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, T32, T33, T34, T35, T36, T37, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None> { +  typedef internal::Types37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, T32, T33, T34, T35, T36, T37, T38, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None> { +  typedef internal::Types38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, T32, T33, T34, T35, T36, T37, T38, T39, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None> { +  typedef internal::Types39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None> { +  typedef internal::Types40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, +      T40> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None, internal::None> { +  typedef internal::Types41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, +      T41> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, internal::None, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None> { +  typedef internal::Types42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, +      T41, T42> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None, internal::None> { +  typedef internal::Types43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, +      T41, T42, T43> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, +    internal::None, internal::None, internal::None, internal::None, +    internal::None, internal::None> { +  typedef internal::Types44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, +      T41, T42, T43, T44> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, +    internal::None, internal::None, internal::None, internal::None, +    internal::None> { +  typedef internal::Types45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, +      T41, T42, T43, T44, T45> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, +    T46, internal::None, internal::None, internal::None, internal::None> { +  typedef internal::Types46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, +      T41, T42, T43, T44, T45, T46> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46, typename T47> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, +    T46, T47, internal::None, internal::None, internal::None> { +  typedef internal::Types47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, +      T41, T42, T43, T44, T45, T46, T47> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46, typename T47, typename T48> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, +    T46, T47, T48, internal::None, internal::None> { +  typedef internal::Types48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, +      T41, T42, T43, T44, T45, T46, T47, T48> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46, typename T47, typename T48, typename T49> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, +    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, +    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, +    T46, T47, T48, T49, internal::None> { +  typedef internal::Types49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, +      T41, T42, T43, T44, T45, T46, T47, T48, T49> type; +}; + +namespace internal { + +#define GTEST_TEMPLATE_ template <typename T> class + +// The template "selector" struct TemplateSel<Tmpl> is used to +// represent Tmpl, which must be a class template with one type +// parameter, as a type.  TemplateSel<Tmpl>::Bind<T>::type is defined +// as the type Tmpl<T>.  This allows us to actually instantiate the +// template "selected" by TemplateSel<Tmpl>. +// +// This trick is necessary for simulating typedef for class templates, +// which C++ doesn't support directly. +template <GTEST_TEMPLATE_ Tmpl> +struct TemplateSel { +  template <typename T> +  struct Bind { +    typedef Tmpl<T> type; +  }; +}; + +#define GTEST_BIND_(TmplSel, T) \ +  TmplSel::template Bind<T>::type + +// A unique struct template used as the default value for the +// arguments of class template Templates.  This allows us to simulate +// variadic templates (e.g. Templates<int>, Templates<int, double>, +// and etc), which C++ doesn't support directly. +template <typename T> +struct NoneT {}; + +// The following family of struct and struct templates are used to +// represent template lists.  In particular, TemplatesN<T1, T2, ..., +// TN> represents a list of N templates (T1, T2, ..., and TN).  Except +// for Templates0, every struct in the family has two member types: +// Head for the selector of the first template in the list, and Tail +// for the rest of the list. + +// The empty template list. +struct Templates0 {}; + +// Template lists of length 1, 2, 3, and so on. + +template <GTEST_TEMPLATE_ T1> +struct Templates1 { +  typedef TemplateSel<T1> Head; +  typedef Templates0 Tail; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2> +struct Templates2 { +  typedef TemplateSel<T1> Head; +  typedef Templates1<T2> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3> +struct Templates3 { +  typedef TemplateSel<T1> Head; +  typedef Templates2<T2, T3> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4> +struct Templates4 { +  typedef TemplateSel<T1> Head; +  typedef Templates3<T2, T3, T4> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5> +struct Templates5 { +  typedef TemplateSel<T1> Head; +  typedef Templates4<T2, T3, T4, T5> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6> +struct Templates6 { +  typedef TemplateSel<T1> Head; +  typedef Templates5<T2, T3, T4, T5, T6> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7> +struct Templates7 { +  typedef TemplateSel<T1> Head; +  typedef Templates6<T2, T3, T4, T5, T6, T7> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8> +struct Templates8 { +  typedef TemplateSel<T1> Head; +  typedef Templates7<T2, T3, T4, T5, T6, T7, T8> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9> +struct Templates9 { +  typedef TemplateSel<T1> Head; +  typedef Templates8<T2, T3, T4, T5, T6, T7, T8, T9> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10> +struct Templates10 { +  typedef TemplateSel<T1> Head; +  typedef Templates9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11> +struct Templates11 { +  typedef TemplateSel<T1> Head; +  typedef Templates10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12> +struct Templates12 { +  typedef TemplateSel<T1> Head; +  typedef Templates11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13> +struct Templates13 { +  typedef TemplateSel<T1> Head; +  typedef Templates12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14> +struct Templates14 { +  typedef TemplateSel<T1> Head; +  typedef Templates13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15> +struct Templates15 { +  typedef TemplateSel<T1> Head; +  typedef Templates14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16> +struct Templates16 { +  typedef TemplateSel<T1> Head; +  typedef Templates15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17> +struct Templates17 { +  typedef TemplateSel<T1> Head; +  typedef Templates16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18> +struct Templates18 { +  typedef TemplateSel<T1> Head; +  typedef Templates17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19> +struct Templates19 { +  typedef TemplateSel<T1> Head; +  typedef Templates18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20> +struct Templates20 { +  typedef TemplateSel<T1> Head; +  typedef Templates19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21> +struct Templates21 { +  typedef TemplateSel<T1> Head; +  typedef Templates20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22> +struct Templates22 { +  typedef TemplateSel<T1> Head; +  typedef Templates21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23> +struct Templates23 { +  typedef TemplateSel<T1> Head; +  typedef Templates22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24> +struct Templates24 { +  typedef TemplateSel<T1> Head; +  typedef Templates23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25> +struct Templates25 { +  typedef TemplateSel<T1> Head; +  typedef Templates24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26> +struct Templates26 { +  typedef TemplateSel<T1> Head; +  typedef Templates25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27> +struct Templates27 { +  typedef TemplateSel<T1> Head; +  typedef Templates26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28> +struct Templates28 { +  typedef TemplateSel<T1> Head; +  typedef Templates27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29> +struct Templates29 { +  typedef TemplateSel<T1> Head; +  typedef Templates28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30> +struct Templates30 { +  typedef TemplateSel<T1> Head; +  typedef Templates29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31> +struct Templates31 { +  typedef TemplateSel<T1> Head; +  typedef Templates30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32> +struct Templates32 { +  typedef TemplateSel<T1> Head; +  typedef Templates31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33> +struct Templates33 { +  typedef TemplateSel<T1> Head; +  typedef Templates32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32, T33> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34> +struct Templates34 { +  typedef TemplateSel<T1> Head; +  typedef Templates33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32, T33, T34> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35> +struct Templates35 { +  typedef TemplateSel<T1> Head; +  typedef Templates34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32, T33, T34, T35> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36> +struct Templates36 { +  typedef TemplateSel<T1> Head; +  typedef Templates35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32, T33, T34, T35, T36> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37> +struct Templates37 { +  typedef TemplateSel<T1> Head; +  typedef Templates36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32, T33, T34, T35, T36, T37> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38> +struct Templates38 { +  typedef TemplateSel<T1> Head; +  typedef Templates37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39> +struct Templates39 { +  typedef TemplateSel<T1> Head; +  typedef Templates38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40> +struct Templates40 { +  typedef TemplateSel<T1> Head; +  typedef Templates39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41> +struct Templates41 { +  typedef TemplateSel<T1> Head; +  typedef Templates40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42> +struct Templates42 { +  typedef TemplateSel<T1> Head; +  typedef Templates41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, +      T42> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, +    GTEST_TEMPLATE_ T43> +struct Templates43 { +  typedef TemplateSel<T1> Head; +  typedef Templates42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, +      T43> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, +    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44> +struct Templates44 { +  typedef TemplateSel<T1> Head; +  typedef Templates43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, +      T43, T44> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, +    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45> +struct Templates45 { +  typedef TemplateSel<T1> Head; +  typedef Templates44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, +      T43, T44, T45> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, +    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, +    GTEST_TEMPLATE_ T46> +struct Templates46 { +  typedef TemplateSel<T1> Head; +  typedef Templates45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, +      T43, T44, T45, T46> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, +    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, +    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47> +struct Templates47 { +  typedef TemplateSel<T1> Head; +  typedef Templates46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, +      T43, T44, T45, T46, T47> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, +    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, +    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48> +struct Templates48 { +  typedef TemplateSel<T1> Head; +  typedef Templates47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, +      T43, T44, T45, T46, T47, T48> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, +    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, +    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48, +    GTEST_TEMPLATE_ T49> +struct Templates49 { +  typedef TemplateSel<T1> Head; +  typedef Templates48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, +      T43, T44, T45, T46, T47, T48, T49> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, +    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, +    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48, +    GTEST_TEMPLATE_ T49, GTEST_TEMPLATE_ T50> +struct Templates50 { +  typedef TemplateSel<T1> Head; +  typedef Templates49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, +      T43, T44, T45, T46, T47, T48, T49, T50> Tail; +}; + + +// We don't want to require the users to write TemplatesN<...> directly, +// as that would require them to count the length.  Templates<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Templates<list> +// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Templates<T1, ..., TN>, and Google Test will translate +// that to TemplatesN<T1, ..., TN> internally to make error messages +// readable.  The translation is done by the 'type' member of the +// Templates template. +template <GTEST_TEMPLATE_ T1 = NoneT, GTEST_TEMPLATE_ T2 = NoneT, +    GTEST_TEMPLATE_ T3 = NoneT, GTEST_TEMPLATE_ T4 = NoneT, +    GTEST_TEMPLATE_ T5 = NoneT, GTEST_TEMPLATE_ T6 = NoneT, +    GTEST_TEMPLATE_ T7 = NoneT, GTEST_TEMPLATE_ T8 = NoneT, +    GTEST_TEMPLATE_ T9 = NoneT, GTEST_TEMPLATE_ T10 = NoneT, +    GTEST_TEMPLATE_ T11 = NoneT, GTEST_TEMPLATE_ T12 = NoneT, +    GTEST_TEMPLATE_ T13 = NoneT, GTEST_TEMPLATE_ T14 = NoneT, +    GTEST_TEMPLATE_ T15 = NoneT, GTEST_TEMPLATE_ T16 = NoneT, +    GTEST_TEMPLATE_ T17 = NoneT, GTEST_TEMPLATE_ T18 = NoneT, +    GTEST_TEMPLATE_ T19 = NoneT, GTEST_TEMPLATE_ T20 = NoneT, +    GTEST_TEMPLATE_ T21 = NoneT, GTEST_TEMPLATE_ T22 = NoneT, +    GTEST_TEMPLATE_ T23 = NoneT, GTEST_TEMPLATE_ T24 = NoneT, +    GTEST_TEMPLATE_ T25 = NoneT, GTEST_TEMPLATE_ T26 = NoneT, +    GTEST_TEMPLATE_ T27 = NoneT, GTEST_TEMPLATE_ T28 = NoneT, +    GTEST_TEMPLATE_ T29 = NoneT, GTEST_TEMPLATE_ T30 = NoneT, +    GTEST_TEMPLATE_ T31 = NoneT, GTEST_TEMPLATE_ T32 = NoneT, +    GTEST_TEMPLATE_ T33 = NoneT, GTEST_TEMPLATE_ T34 = NoneT, +    GTEST_TEMPLATE_ T35 = NoneT, GTEST_TEMPLATE_ T36 = NoneT, +    GTEST_TEMPLATE_ T37 = NoneT, GTEST_TEMPLATE_ T38 = NoneT, +    GTEST_TEMPLATE_ T39 = NoneT, GTEST_TEMPLATE_ T40 = NoneT, +    GTEST_TEMPLATE_ T41 = NoneT, GTEST_TEMPLATE_ T42 = NoneT, +    GTEST_TEMPLATE_ T43 = NoneT, GTEST_TEMPLATE_ T44 = NoneT, +    GTEST_TEMPLATE_ T45 = NoneT, GTEST_TEMPLATE_ T46 = NoneT, +    GTEST_TEMPLATE_ T47 = NoneT, GTEST_TEMPLATE_ T48 = NoneT, +    GTEST_TEMPLATE_ T49 = NoneT, GTEST_TEMPLATE_ T50 = NoneT> +struct Templates { +  typedef Templates50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, +      T42, T43, T44, T45, T46, T47, T48, T49, T50> type; +}; + +template <> +struct Templates<NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT> { +  typedef Templates0 type; +}; +template <GTEST_TEMPLATE_ T1> +struct Templates<T1, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT> { +  typedef Templates1<T1> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2> +struct Templates<T1, T2, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT> { +  typedef Templates2<T1, T2> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3> +struct Templates<T1, T2, T3, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates3<T1, T2, T3> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4> +struct Templates<T1, T2, T3, T4, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates4<T1, T2, T3, T4> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5> +struct Templates<T1, T2, T3, T4, T5, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates5<T1, T2, T3, T4, T5> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6> +struct Templates<T1, T2, T3, T4, T5, T6, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates6<T1, T2, T3, T4, T5, T6> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7> +struct Templates<T1, T2, T3, T4, T5, T6, T7, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates7<T1, T2, T3, T4, T5, T6, T7> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates8<T1, T2, T3, T4, T5, T6, T7, T8> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT> { +  typedef Templates18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT> { +  typedef Templates19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT> { +  typedef Templates20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT> { +  typedef Templates21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT> { +  typedef Templates22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT> { +  typedef Templates23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT> { +  typedef Templates24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT> { +  typedef Templates25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT> { +  typedef Templates26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT> { +  typedef Templates27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT> { +  typedef Templates28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT> { +  typedef Templates29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, T32, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, T32, T33, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32, T33> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, T32, T33, T34, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32, T33, T34> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, T32, T33, T34, T35, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32, T33, T34, T35> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, T32, T33, T34, T35, T36, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32, T33, T34, T35, T36> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, T32, T33, T34, T35, T36, T37, NoneT, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, T32, T33, T34, T35, T36, T37, T38, NoneT, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, NoneT, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, NoneT, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, +      T41> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, NoneT, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, +      T42> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, +    GTEST_TEMPLATE_ T43> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, +      T42, T43> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, +    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, +    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, +      T42, T43, T44> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, +    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, +    T45, NoneT, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, +      T42, T43, T44, T45> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, +    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, +    GTEST_TEMPLATE_ T46> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, +    T45, T46, NoneT, NoneT, NoneT, NoneT> { +  typedef Templates46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, +      T42, T43, T44, T45, T46> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, +    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, +    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, +    T45, T46, T47, NoneT, NoneT, NoneT> { +  typedef Templates47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, +      T42, T43, T44, T45, T46, T47> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, +    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, +    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, +    T45, T46, T47, T48, NoneT, NoneT> { +  typedef Templates48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, +      T42, T43, T44, T45, T46, T47, T48> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, +    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, +    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, +    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, +    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, +    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, +    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, +    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, +    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, +    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, +    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, +    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, +    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, +    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, +    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, +    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48, +    GTEST_TEMPLATE_ T49> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, +    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, +    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, +    T45, T46, T47, T48, T49, NoneT> { +  typedef Templates49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, +      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, +      T42, T43, T44, T45, T46, T47, T48, T49> type; +}; + +// The TypeList template makes it possible to use either a single type +// or a Types<...> list in TYPED_TEST_CASE() and +// INSTANTIATE_TYPED_TEST_CASE_P(). + +template <typename T> +struct TypeList { typedef Types1<T> type; }; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, +    typename T6, typename T7, typename T8, typename T9, typename T10, +    typename T11, typename T12, typename T13, typename T14, typename T15, +    typename T16, typename T17, typename T18, typename T19, typename T20, +    typename T21, typename T22, typename T23, typename T24, typename T25, +    typename T26, typename T27, typename T28, typename T29, typename T30, +    typename T31, typename T32, typename T33, typename T34, typename T35, +    typename T36, typename T37, typename T38, typename T39, typename T40, +    typename T41, typename T42, typename T43, typename T44, typename T45, +    typename T46, typename T47, typename T48, typename T49, typename T50> +struct TypeList<Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, +    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, +    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, +    T44, T45, T46, T47, T48, T49, T50> > { +  typedef typename Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, +      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, +      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, +      T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>::type type; +}; + +}  // namespace internal +}  // namespace testing + +#endif  // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ diff --git a/llvm/utils/unittest/googletest/src/gtest-all.cc b/llvm/utils/unittest/googletest/src/gtest-all.cc new file mode 100644 index 00000000000..a67ea0fa0f3 --- /dev/null +++ b/llvm/utils/unittest/googletest/src/gtest-all.cc @@ -0,0 +1,41 @@ +// Copyright 2008, 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: mheule@google.com (Markus Heule) +// +// Google C++ Testing Framework (Google Test) +// +// Sometimes it's desirable to build Google Test by compiling a single file. +// This file serves this purpose. +#include "src/gtest.cc" +#include "src/gtest-death-test.cc" +#include "src/gtest-filepath.cc" +#include "src/gtest-port.cc" +#include "src/gtest-test-part.cc" +#include "src/gtest-typed-test.cc" diff --git a/llvm/utils/unittest/googletest/src/gtest-death-test.cc b/llvm/utils/unittest/googletest/src/gtest-death-test.cc new file mode 100644 index 00000000000..b667682fb98 --- /dev/null +++ b/llvm/utils/unittest/googletest/src/gtest-death-test.cc @@ -0,0 +1,775 @@ +// Copyright 2005, 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) +// +// This file implements death tests. + +#include <gtest/gtest-death-test.h> +#include <gtest/internal/gtest-port.h> + +#ifdef GTEST_HAS_DEATH_TEST +#include <errno.h> +#include <limits.h> +#include <stdarg.h> +#endif  // GTEST_HAS_DEATH_TEST + +#include <gtest/gtest-message.h> +#include <gtest/internal/gtest-string.h> + +// Indicates that this translation unit is part of Google Test's +// implementation.  It must come before gtest-internal-inl.h is +// included, or there will be a compiler error.  This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION + +namespace testing { + +// Constants. + +// The default death test style. +static const char kDefaultDeathTestStyle[] = "fast"; + +GTEST_DEFINE_string_( +    death_test_style, +    internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), +    "Indicates how to run a death test in a forked child process: " +    "\"threadsafe\" (child process re-executes the test binary " +    "from the beginning, running only the specific death test) or " +    "\"fast\" (child process runs the death test immediately " +    "after forking)."); + +namespace internal { +GTEST_DEFINE_string_( +    internal_run_death_test, "", +    "Indicates the file, line number, temporal index of " +    "the single death test to run, and a file descriptor to " +    "which a success code may be sent, all separated by " +    "colons.  This flag is specified if and only if the current " +    "process is a sub-process launched for running a thread-safe " +    "death test.  FOR INTERNAL USE ONLY."); +}  // namespace internal + +#ifdef GTEST_HAS_DEATH_TEST + +// ExitedWithCode constructor. +ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { +} + +// ExitedWithCode function-call operator. +bool ExitedWithCode::operator()(int exit_status) const { +  return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; +} + +// KilledBySignal constructor. +KilledBySignal::KilledBySignal(int signum) : signum_(signum) { +} + +// KilledBySignal function-call operator. +bool KilledBySignal::operator()(int exit_status) const { +  return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; +} + +namespace internal { + +// Utilities needed for death tests. + +// Generates a textual description of a given exit code, in the format +// specified by wait(2). +static String ExitSummary(int exit_code) { +  Message m; +  if (WIFEXITED(exit_code)) { +    m << "Exited with exit status " << WEXITSTATUS(exit_code); +  } else if (WIFSIGNALED(exit_code)) { +    m << "Terminated by signal " << WTERMSIG(exit_code); +  } +#ifdef WCOREDUMP +  if (WCOREDUMP(exit_code)) { +    m << " (core dumped)"; +  } +#endif +  return m.GetString(); +} + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +bool ExitedUnsuccessfully(int exit_status) { +  return !ExitedWithCode(0)(exit_status); +} + +// Generates a textual failure message when a death test finds more than +// one thread running, or cannot determine the number of threads, prior +// to executing the given statement.  It is the responsibility of the +// caller not to pass a thread_count of 1. +static String DeathTestThreadWarning(size_t thread_count) { +  Message msg; +  msg << "Death tests use fork(), which is unsafe particularly" +      << " in a threaded context. For this test, " << GTEST_NAME << " "; +  if (thread_count == 0) +    msg << "couldn't detect the number of threads."; +  else +    msg << "detected " << thread_count << " threads."; +  return msg.GetString(); +} + +// Static string containing a description of the outcome of the +// last death test. +static String last_death_test_message; + +// Flag characters for reporting a death test that did not die. +static const char kDeathTestLived = 'L'; +static const char kDeathTestReturned = 'R'; +static const char kDeathTestInternalError = 'I'; + +// An enumeration describing all of the possible ways that a death test +// can conclude.  DIED means that the process died while executing the +// test code; LIVED means that process lived beyond the end of the test +// code; and RETURNED means that the test statement attempted a "return," +// which is not allowed.  IN_PROGRESS means the test has not yet +// concluded. +enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED }; + +// Routine for aborting the program which is safe to call from an +// exec-style death test child process, in which case the the error +// message is propagated back to the parent process.  Otherwise, the +// message is simply printed to stderr.  In either case, the program +// then exits with status 1. +void DeathTestAbort(const char* format, ...) { +  // This function may be called from a threadsafe-style death test +  // child process, which operates on a very small stack.  Use the +  // heap for any additional non-miniscule memory requirements. +  const InternalRunDeathTestFlag* const flag = +      GetUnitTestImpl()->internal_run_death_test_flag(); +  va_list args; +  va_start(args, format); + +  if (flag != NULL) { +    FILE* parent = fdopen(flag->status_fd, "w"); +    fputc(kDeathTestInternalError, parent); +    vfprintf(parent, format, args); +    fclose(parent); +    va_end(args); +    _exit(1); +  } else { +    vfprintf(stderr, format, args); +    va_end(args); +    abort(); +  } +} + +// A replacement for CHECK that calls DeathTestAbort if the assertion +// fails. +#define GTEST_DEATH_TEST_CHECK_(expression) \ +  do { \ +    if (!(expression)) { \ +      DeathTestAbort("CHECK failed: File %s, line %d: %s", \ +                     __FILE__, __LINE__, #expression); \ +    } \ +  } while (0) + +// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for +// evaluating any system call that fulfills two conditions: it must return +// -1 on failure, and set errno to EINTR when it is interrupted and +// should be tried again.  The macro expands to a loop that repeatedly +// evaluates the expression as long as it evaluates to -1 and sets +// errno to EINTR.  If the expression evaluates to -1 but errno is +// something other than EINTR, DeathTestAbort is called. +#define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ +  do { \ +    int retval; \ +    do { \ +      retval = (expression); \ +    } while (retval == -1 && errno == EINTR); \ +    if (retval == -1) { \ +      DeathTestAbort("CHECK failed: File %s, line %d: %s != -1", \ +                     __FILE__, __LINE__, #expression); \ +    } \ +  } while (0) + +// Death test constructor.  Increments the running death test count +// for the current test. +DeathTest::DeathTest() { +  TestInfo* const info = GetUnitTestImpl()->current_test_info(); +  if (info == NULL) { +    DeathTestAbort("Cannot run a death test outside of a TEST or " +                   "TEST_F construct"); +  } +} + +// Creates and returns a death test by dispatching to the current +// death test factory. +bool DeathTest::Create(const char* statement, const RE* regex, +                       const char* file, int line, DeathTest** test) { +  return GetUnitTestImpl()->death_test_factory()->Create( +      statement, regex, file, line, test); +} + +const char* DeathTest::LastMessage() { +  return last_death_test_message.c_str(); +} + +// ForkingDeathTest provides implementations for most of the abstract +// methods of the DeathTest interface.  Only the AssumeRole method is +// left undefined. +class ForkingDeathTest : public DeathTest { + public: +  ForkingDeathTest(const char* statement, const RE* regex); + +  // All of these virtual functions are inherited from DeathTest. +  virtual int Wait(); +  virtual bool Passed(bool status_ok); +  virtual void Abort(AbortReason reason); + + protected: +  void set_forked(bool forked) { forked_ = forked; } +  void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } +  void set_read_fd(int fd) { read_fd_ = fd; } +  void set_write_fd(int fd) { write_fd_ = fd; } + + private: +  // The textual content of the code this object is testing. +  const char* const statement_; +  // The regular expression which test output must match. +  const RE* const regex_; +  // True if the death test successfully forked. +  bool forked_; +  // PID of child process during death test; 0 in the child process itself. +  pid_t child_pid_; +  // File descriptors for communicating the death test's status byte. +  int read_fd_;   // Always -1 in the child process. +  int write_fd_;  // Always -1 in the parent process. +  // The exit status of the child process. +  int status_; +  // How the death test concluded. +  DeathTestOutcome outcome_; +}; + +// Constructs a ForkingDeathTest. +ForkingDeathTest::ForkingDeathTest(const char* statement, const RE* regex) +    : DeathTest(), +      statement_(statement), +      regex_(regex), +      forked_(false), +      child_pid_(-1), +      read_fd_(-1), +      write_fd_(-1), +      status_(-1), +      outcome_(IN_PROGRESS) { +} + +// Reads an internal failure message from a file descriptor, then calls +// LOG(FATAL) with that message.  Called from a death test parent process +// to read a failure message from the death test child process. +static void FailFromInternalError(int fd) { +  Message error; +  char buffer[256]; +  ssize_t num_read; + +  do { +    while ((num_read = read(fd, buffer, 255)) > 0) { +      buffer[num_read] = '\0'; +      error << buffer; +    } +  } while (num_read == -1 && errno == EINTR); + +  // TODO(smcafee):  Maybe just FAIL the test instead? +  if (num_read == 0) { +    GTEST_LOG_(FATAL, error); +  } else { +    GTEST_LOG_(FATAL, +               Message() << "Error while reading death test internal: " +               << strerror(errno) << " [" << errno << "]"); +  } +} + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists.  As a side effect, sets the +// outcome data member. +int ForkingDeathTest::Wait() { +  if (!forked_) +    return 0; + +  // The read() here blocks until data is available (signifying the +  // failure of the death test) or until the pipe is closed (signifying +  // its success), so it's okay to call this in the parent before +  // the child process has exited. +  char flag; +  ssize_t bytes_read; + +  do { +    bytes_read = read(read_fd_, &flag, 1); +  } while (bytes_read == -1 && errno == EINTR); + +  if (bytes_read == 0) { +    outcome_ = DIED; +  } else if (bytes_read == 1) { +    switch (flag) { +      case kDeathTestReturned: +        outcome_ = RETURNED; +        break; +      case kDeathTestLived: +        outcome_ = LIVED; +        break; +      case kDeathTestInternalError: +        FailFromInternalError(read_fd_);  // Does not return. +        break; +      default: +        GTEST_LOG_(FATAL, +                   Message() << "Death test child process reported unexpected " +                   << "status byte (" << static_cast<unsigned int>(flag) +                   << ")"); +    } +  } else { +    GTEST_LOG_(FATAL, +               Message() << "Read from death test child process failed: " +               << strerror(errno)); +  } + +  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(read_fd_)); +  GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_, 0)); +  return status_; +} + +// Assesses the success or failure of a death test, using both private +// members which have previously been set, and one argument: +// +// Private data members: +//   outcome:  an enumeration describing how the death test +//             concluded: DIED, LIVED, or RETURNED.  The death test fails +//             in the latter two cases +//   status:   the exit status of the child process, in the format +//             specified by wait(2) +//   regex:    a regular expression object to be applied to +//             the test's captured standard error output; the death test +//             fails if it does not match +// +// Argument: +//   status_ok: true if exit_status is acceptable in the context of +//              this particular death test, which fails if it is false +// +// Returns true iff all of the above conditions are met.  Otherwise, the +// first failing condition, in the order given above, is the one that is +// reported. Also sets the static variable last_death_test_message. +bool ForkingDeathTest::Passed(bool status_ok) { +  if (!forked_) +    return false; + +#if GTEST_HAS_GLOBAL_STRING +  const ::string error_message = GetCapturedStderr(); +#else +  const ::std::string error_message = GetCapturedStderr(); +#endif  // GTEST_HAS_GLOBAL_STRING + +  bool success = false; +  Message buffer; + +  buffer << "Death test: " << statement_ << "\n"; +  switch (outcome_) { +    case LIVED: +      buffer << "    Result: failed to die.\n" +             << " Error msg: " << error_message; +      break; +    case RETURNED: +      buffer << "    Result: illegal return in test statement.\n" +             << " Error msg: " << error_message; +      break; +    case DIED: +      if (status_ok) { +        if (RE::PartialMatch(error_message, *regex_)) { +          success = true; +        } else { +          buffer << "    Result: died but not with expected error.\n" +                 << "  Expected: " << regex_->pattern() << "\n" +                 << "Actual msg: " << error_message; +        } +      } else { +        buffer << "    Result: died but not with expected exit code:\n" +               << "            " << ExitSummary(status_) << "\n"; +      } +      break; +    case IN_PROGRESS: +    default: +      GTEST_LOG_(FATAL, +                 "DeathTest::Passed somehow called before conclusion of test"); +  } + +  last_death_test_message = buffer.GetString(); +  return success; +} + +// Signals that the death test code which should have exited, didn't. +// Should be called only in a death test child process. +// Writes a status byte to the child's status file desriptor, then +// calls _exit(1). +void ForkingDeathTest::Abort(AbortReason reason) { +  // The parent process considers the death test to be a failure if +  // it finds any data in our pipe.  So, here we write a single flag byte +  // to the pipe, then exit. +  const char flag = +      reason == TEST_DID_NOT_DIE ? kDeathTestLived : kDeathTestReturned; +  GTEST_DEATH_TEST_CHECK_SYSCALL_(write(write_fd_, &flag, 1)); +  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(write_fd_)); +  _exit(1);  // Exits w/o any normal exit hooks (we were supposed to crash) +} + +// A concrete death test class that forks, then immediately runs the test +// in the child process. +class NoExecDeathTest : public ForkingDeathTest { + public: +  NoExecDeathTest(const char* statement, const RE* regex) : +      ForkingDeathTest(statement, regex) { } +  virtual TestRole AssumeRole(); +}; + +// The AssumeRole process for a fork-and-run death test.  It implements a +// straightforward fork, with a simple pipe to transmit the status byte. +DeathTest::TestRole NoExecDeathTest::AssumeRole() { +  const size_t thread_count = GetThreadCount(); +  if (thread_count != 1) { +    GTEST_LOG_(WARNING, DeathTestThreadWarning(thread_count)); +  } + +  int pipe_fd[2]; +  GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + +  last_death_test_message = ""; +  CaptureStderr(); +  // When we fork the process below, the log file buffers are copied, but the +  // file descriptors are shared.  We flush all log files here so that closing +  // the file descriptors in the child process doesn't throw off the +  // synchronization between descriptors and buffers in the parent process. +  // This is as close to the fork as possible to avoid a race condition in case +  // there are multiple threads running before the death test, and another +  // thread writes to the log file. +  FlushInfoLog(); + +  const pid_t child_pid = fork(); +  GTEST_DEATH_TEST_CHECK_(child_pid != -1); +  set_child_pid(child_pid); +  if (child_pid == 0) { +    GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); +    set_write_fd(pipe_fd[1]); +    // Redirects all logging to stderr in the child process to prevent +    // concurrent writes to the log files.  We capture stderr in the parent +    // process and append the child process' output to a log. +    LogToStderr(); +    return EXECUTE_TEST; +  } else { +    GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); +    set_read_fd(pipe_fd[0]); +    set_forked(true); +    return OVERSEE_TEST; +  } +} + +// A concrete death test class that forks and re-executes the main +// program from the beginning, with command-line flags set that cause +// only this specific death test to be run. +class ExecDeathTest : public ForkingDeathTest { + public: +  ExecDeathTest(const char* statement, const RE* regex, +                const char* file, int line) : +      ForkingDeathTest(statement, regex), file_(file), line_(line) { } +  virtual TestRole AssumeRole(); + private: +  // The name of the file in which the death test is located. +  const char* const file_; +  // The line number on which the death test is located. +  const int line_; +}; + +// Utility class for accumulating command-line arguments. +class Arguments { + public: +  Arguments() { +    args_.push_back(NULL); +  } +  ~Arguments() { +    for (std::vector<char*>::iterator i = args_.begin(); +         i + 1 != args_.end(); +         ++i) { +      free(*i); +    } +  } +  void AddArgument(const char* argument) { +    args_.insert(args_.end() - 1, strdup(argument)); +  } + +  template <typename Str> +  void AddArguments(const ::std::vector<Str>& arguments) { +    for (typename ::std::vector<Str>::const_iterator i = arguments.begin(); +         i != arguments.end(); +         ++i) { +      args_.insert(args_.end() - 1, strdup(i->c_str())); +    } +  } +  char* const* Argv() { +    return &args_[0]; +  } + private: +  std::vector<char*> args_; +}; + +// A struct that encompasses the arguments to the child process of a +// threadsafe-style death test process. +struct ExecDeathTestArgs { +  char* const* argv;  // Command-line arguments for the child's call to exec +  int close_fd;       // File descriptor to close; the read end of a pipe +}; + +// The main function for a threadsafe-style death test child process. +// This function is called in a clone()-ed process and thus must avoid +// any potentially unsafe operations like malloc or libc functions. +static int ExecDeathTestChildMain(void* child_arg) { +  ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg); +  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); + +  // We need to execute the test program in the same environment where +  // it was originally invoked.  Therefore we change to the original +  // working directory first. +  const char* const original_dir = +      UnitTest::GetInstance()->original_working_dir(); +  // We can safely call chdir() as it's a direct system call. +  if (chdir(original_dir) != 0) { +    DeathTestAbort("chdir(\"%s\") failed: %s", +                   original_dir, strerror(errno)); +    return EXIT_FAILURE; +  } + +  // We can safely call execve() as it's a direct system call.  We +  // cannot use execvp() as it's a libc function and thus potentially +  // unsafe.  Since execve() doesn't search the PATH, the user must +  // invoke the test program via a valid path that contains at least +  // one path separator. +  execve(args->argv[0], args->argv, environ); +  DeathTestAbort("execve(%s, ...) in %s failed: %s", +                 args->argv[0], original_dir, strerror(errno)); +  return EXIT_FAILURE; +} + +// Two utility routines that together determine the direction the stack +// grows. +// This could be accomplished more elegantly by a single recursive +// function, but we want to guard against the unlikely possibility of +// a smart compiler optimizing the recursion away. +static bool StackLowerThanAddress(const void* ptr) { +  int dummy; +  return &dummy < ptr; +} + +static bool StackGrowsDown() { +  int dummy; +  return StackLowerThanAddress(&dummy); +} + +// A threadsafe implementation of fork(2) for threadsafe-style death tests +// that uses clone(2).  It dies with an error message if anything goes +// wrong. +static pid_t ExecDeathTestFork(char* const* argv, int close_fd) { +  static const bool stack_grows_down = StackGrowsDown(); +  const size_t stack_size = getpagesize(); +  void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, +                           MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); +  GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); +  void* const stack_top = +      static_cast<char*>(stack) + (stack_grows_down ? stack_size : 0); +  ExecDeathTestArgs args = { argv, close_fd }; +  const pid_t child_pid = clone(&ExecDeathTestChildMain, stack_top, +                                SIGCHLD, &args); +  GTEST_DEATH_TEST_CHECK_(child_pid != -1); +  GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); +  return child_pid; +} + +// The AssumeRole process for a fork-and-exec death test.  It re-executes the +// main program from the beginning, setting the --gtest_filter +// and --gtest_internal_run_death_test flags to cause only the current +// death test to be re-run. +DeathTest::TestRole ExecDeathTest::AssumeRole() { +  const UnitTestImpl* const impl = GetUnitTestImpl(); +  const InternalRunDeathTestFlag* const flag = +      impl->internal_run_death_test_flag(); +  const TestInfo* const info = impl->current_test_info(); +  const int death_test_index = info->result()->death_test_count(); + +  if (flag != NULL) { +    set_write_fd(flag->status_fd); +    return EXECUTE_TEST; +  } + +  int pipe_fd[2]; +  GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); +  // Clear the close-on-exec flag on the write end of the pipe, lest +  // it be closed when the child process does an exec: +  GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); + +  const String filter_flag = +      String::Format("--%s%s=%s.%s", +                     GTEST_FLAG_PREFIX, kFilterFlag, +                     info->test_case_name(), info->name()); +  const String internal_flag = +      String::Format("--%s%s=%s:%d:%d:%d", +                     GTEST_FLAG_PREFIX, kInternalRunDeathTestFlag, file_, line_, +                     death_test_index, pipe_fd[1]); +  Arguments args; +  args.AddArguments(GetArgvs()); +  args.AddArgument("--logtostderr"); +  args.AddArgument(filter_flag.c_str()); +  args.AddArgument(internal_flag.c_str()); + +  last_death_test_message = ""; + +  CaptureStderr(); +  // See the comment in NoExecDeathTest::AssumeRole for why the next line +  // is necessary. +  FlushInfoLog(); + +  const pid_t child_pid = ExecDeathTestFork(args.Argv(), pipe_fd[0]); +  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); +  set_child_pid(child_pid); +  set_read_fd(pipe_fd[0]); +  set_forked(true); +  return OVERSEE_TEST; +} + +// Creates a concrete DeathTest-derived class that depends on the +// --gtest_death_test_style flag, and sets the pointer pointed to +// by the "test" argument to its address.  If the test should be +// skipped, sets that pointer to NULL.  Returns true, unless the +// flag is set to an invalid value. +bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, +                                     const char* file, int line, +                                     DeathTest** test) { +  UnitTestImpl* const impl = GetUnitTestImpl(); +  const InternalRunDeathTestFlag* const flag = +      impl->internal_run_death_test_flag(); +  const int death_test_index = impl->current_test_info() +      ->increment_death_test_count(); + +  if (flag != NULL) { +    if (death_test_index > flag->index) { +      last_death_test_message = String::Format( +          "Death test count (%d) somehow exceeded expected maximum (%d)", +          death_test_index, flag->index); +      return false; +    } + +    if (!(flag->file == file && flag->line == line && +          flag->index == death_test_index)) { +      *test = NULL; +      return true; +    } +  } + +  if (GTEST_FLAG(death_test_style) == "threadsafe") { +    *test = new ExecDeathTest(statement, regex, file, line); +  } else if (GTEST_FLAG(death_test_style) == "fast") { +    *test = new NoExecDeathTest(statement, regex); +  } else { +    last_death_test_message = String::Format( +        "Unknown death test style \"%s\" encountered", +        GTEST_FLAG(death_test_style).c_str()); +    return false; +  } + +  return true; +} + +// Splits a given string on a given delimiter, populating a given +// vector with the fields.  GTEST_HAS_DEATH_TEST implies that we have +// ::std::string, so we can use it here. +static void SplitString(const ::std::string& str, char delimiter, +                        ::std::vector< ::std::string>* dest) { +  ::std::vector< ::std::string> parsed; +  ::std::string::size_type pos = 0; +  while (true) { +    const ::std::string::size_type colon = str.find(delimiter, pos); +    if (colon == ::std::string::npos) { +      parsed.push_back(str.substr(pos)); +      break; +    } else { +      parsed.push_back(str.substr(pos, colon - pos)); +      pos = colon + 1; +    } +  } +  dest->swap(parsed); +} + +// Attempts to parse a string into a positive integer.  Returns true +// if that is possible.  GTEST_HAS_DEATH_TEST implies that we have +// ::std::string, so we can use it here. +static bool ParsePositiveInt(const ::std::string& str, int* number) { +  // Fail fast if the given string does not begin with a digit; +  // this bypasses strtol's "optional leading whitespace and plus +  // or minus sign" semantics, which are undesirable here. +  if (str.empty() || !isdigit(str[0])) { +    return false; +  } +  char* endptr; +  const long parsed = strtol(str.c_str(), &endptr, 10);  // NOLINT +  if (*endptr == '\0' && parsed <= INT_MAX) { +    *number = static_cast<int>(parsed); +    return true; +  } else { +    return false; +  } +} + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { +  if (GTEST_FLAG(internal_run_death_test) == "") return NULL; + +  InternalRunDeathTestFlag* const internal_run_death_test_flag = +      new InternalRunDeathTestFlag; +  // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we +  // can use it here. +  ::std::vector< ::std::string> fields; +  SplitString(GTEST_FLAG(internal_run_death_test).c_str(), ':', &fields); +  if (fields.size() != 4 +      || !ParsePositiveInt(fields[1], &internal_run_death_test_flag->line) +      || !ParsePositiveInt(fields[2], &internal_run_death_test_flag->index) +      || !ParsePositiveInt(fields[3], +                           &internal_run_death_test_flag->status_fd)) { +    DeathTestAbort("Bad --gtest_internal_run_death_test flag: %s", +                   GTEST_FLAG(internal_run_death_test).c_str()); +  } +  internal_run_death_test_flag->file = fields[0].c_str(); +  return internal_run_death_test_flag; +} + +}  // namespace internal + +#endif  // GTEST_HAS_DEATH_TEST + +}  // namespace testing diff --git a/llvm/utils/unittest/googletest/src/gtest-filepath.cc b/llvm/utils/unittest/googletest/src/gtest-filepath.cc new file mode 100644 index 00000000000..640c27c313c --- /dev/null +++ b/llvm/utils/unittest/googletest/src/gtest-filepath.cc @@ -0,0 +1,321 @@ +// Copyright 2008, 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. +// +// Authors: keith.ray@gmail.com (Keith Ray) + +#include <gtest/internal/gtest-filepath.h> +#include <gtest/internal/gtest-port.h> + +#include <stdlib.h> + +#ifdef _WIN32_WCE +#include <windows.h> +#elif defined(GTEST_OS_WINDOWS) +#include <direct.h> +#include <io.h> +#include <sys/stat.h> +#elif defined(GTEST_OS_SYMBIAN) +// Symbian OpenC has PATH_MAX in sys/syslimits.h +#include <sys/syslimits.h> +#include <unistd.h> +#else +#include <limits.h> +#include <sys/stat.h> +#include <unistd.h> +#endif  // _WIN32_WCE or _WIN32 + +#ifdef GTEST_OS_WINDOWS +#define GTEST_PATH_MAX_ _MAX_PATH +#elif defined(PATH_MAX) +#define GTEST_PATH_MAX_ PATH_MAX +#elif defined(_XOPEN_PATH_MAX) +#define GTEST_PATH_MAX_ _XOPEN_PATH_MAX +#else +#define GTEST_PATH_MAX_ _POSIX_PATH_MAX +#endif  // GTEST_OS_WINDOWS + +#include <gtest/internal/gtest-string.h> + +namespace testing { +namespace internal { + +#ifdef GTEST_OS_WINDOWS +const char kPathSeparator = '\\'; +const char kPathSeparatorString[] = "\\"; +#ifdef _WIN32_WCE +// Windows CE doesn't have a current directory. You should not use +// the current directory in tests on Windows CE, but this at least +// provides a reasonable fallback. +const char kCurrentDirectoryString[] = "\\"; +// Windows CE doesn't define INVALID_FILE_ATTRIBUTES +const DWORD kInvalidFileAttributes = 0xffffffff; +#else +const char kCurrentDirectoryString[] = ".\\"; +#endif  // _WIN32_WCE +#else +const char kPathSeparator = '/'; +const char kPathSeparatorString[] = "/"; +const char kCurrentDirectoryString[] = "./"; +#endif  // GTEST_OS_WINDOWS + +// Returns the current working directory, or "" if unsuccessful. +FilePath FilePath::GetCurrentDir() { +#ifdef _WIN32_WCE +// Windows CE doesn't have a current directory, so we just return +// something reasonable. +  return FilePath(kCurrentDirectoryString); +#elif defined(GTEST_OS_WINDOWS) +  char cwd[GTEST_PATH_MAX_ + 1] = {}; +  return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#else +  char cwd[GTEST_PATH_MAX_ + 1] = {}; +  return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#endif +} + +// Returns a copy of the FilePath with the case-insensitive extension removed. +// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns +// FilePath("dir/file"). If a case-insensitive extension is not +// found, returns a copy of the original FilePath. +FilePath FilePath::RemoveExtension(const char* extension) const { +  String dot_extension(String::Format(".%s", extension)); +  if (pathname_.EndsWithCaseInsensitive(dot_extension.c_str())) { +    return FilePath(String(pathname_.c_str(), pathname_.GetLength() - 4)); +  } +  return *this; +} + +// Returns a copy of the FilePath with the directory part removed. +// Example: FilePath("path/to/file").RemoveDirectoryName() returns +// FilePath("file"). If there is no directory part ("just_a_file"), it returns +// the FilePath unmodified. If there is no file part ("just_a_dir/") it +// returns an empty FilePath (""). +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveDirectoryName() const { +  const char* const last_sep = strrchr(c_str(), kPathSeparator); +  return last_sep ? FilePath(String(last_sep + 1)) : *this; +} + +// RemoveFileName returns the directory path with the filename removed. +// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". +// If the FilePath is "a_file" or "/a_file", RemoveFileName returns +// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does +// not have a file, like "just/a/dir/", it returns the FilePath unmodified. +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveFileName() const { +  const char* const last_sep = strrchr(c_str(), kPathSeparator); +  return FilePath(last_sep ? String(c_str(), last_sep + 1 - c_str()) +                           : String(kCurrentDirectoryString)); +} + +// Helper functions for naming files in a directory for xml output. + +// Given directory = "dir", base_name = "test", number = 0, +// extension = "xml", returns "dir/test.xml". If number is greater +// than zero (e.g., 12), returns "dir/test_12.xml". +// On Windows platform, uses \ as the separator rather than /. +FilePath FilePath::MakeFileName(const FilePath& directory, +                                const FilePath& base_name, +                                int number, +                                const char* extension) { +  FilePath dir(directory.RemoveTrailingPathSeparator()); +  if (number == 0) { +    return FilePath(String::Format("%s%c%s.%s", dir.c_str(), kPathSeparator, +                                   base_name.c_str(), extension)); +  } +  return FilePath(String::Format("%s%c%s_%d.%s", dir.c_str(), kPathSeparator, +                                 base_name.c_str(), number, extension)); +} + +// Returns true if pathname describes something findable in the file-system, +// either a file, directory, or whatever. +bool FilePath::FileOrDirectoryExists() const { +#ifdef GTEST_OS_WINDOWS +#ifdef _WIN32_WCE +  LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); +  const DWORD attributes = GetFileAttributes(unicode); +  delete [] unicode; +  return attributes != kInvalidFileAttributes; +#else +  struct _stat file_stat = {}; +  return _stat(pathname_.c_str(), &file_stat) == 0; +#endif  // _WIN32_WCE +#else +  struct stat file_stat = {}; +  return stat(pathname_.c_str(), &file_stat) == 0; +#endif  // GTEST_OS_WINDOWS +} + +// Returns true if pathname describes a directory in the file-system +// that exists. +bool FilePath::DirectoryExists() const { +  bool result = false; +#ifdef GTEST_OS_WINDOWS +  // Don't strip off trailing separator if path is a root directory on +  // Windows (like "C:\\"). +  const FilePath& path(IsRootDirectory() ? *this : +                                           RemoveTrailingPathSeparator()); +#ifdef _WIN32_WCE +  LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); +  const DWORD attributes = GetFileAttributes(unicode); +  delete [] unicode; +  if ((attributes != kInvalidFileAttributes) && +      (attributes & FILE_ATTRIBUTE_DIRECTORY)) { +    result = true; +  } +#else +  struct _stat file_stat = {}; +  result = _stat(path.c_str(), &file_stat) == 0 && +      (_S_IFDIR & file_stat.st_mode) != 0; +#endif  // _WIN32_WCE +#else +  struct stat file_stat = {}; +  result = stat(pathname_.c_str(), &file_stat) == 0 && +      S_ISDIR(file_stat.st_mode); +#endif  // GTEST_OS_WINDOWS +  return result; +} + +// Returns true if pathname describes a root directory. (Windows has one +// root directory per disk drive.) +bool FilePath::IsRootDirectory() const { +#ifdef GTEST_OS_WINDOWS +  const char* const name = pathname_.c_str(); +  return pathname_.GetLength() == 3 && +     ((name[0] >= 'a' && name[0] <= 'z') || +      (name[0] >= 'A' && name[0] <= 'Z')) && +     name[1] == ':' && +     name[2] == kPathSeparator; +#else +  return pathname_ == kPathSeparatorString; +#endif +} + +// Returns a pathname for a file that does not currently exist. The pathname +// will be directory/base_name.extension or +// directory/base_name_<number>.extension if directory/base_name.extension +// already exists. The number will be incremented until a pathname is found +// that does not already exist. +// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. +// There could be a race condition if two or more processes are calling this +// function at the same time -- they could both pick the same filename. +FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, +                                          const FilePath& base_name, +                                          const char* extension) { +  FilePath full_pathname; +  int number = 0; +  do { +    full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); +  } while (full_pathname.FileOrDirectoryExists()); +  return full_pathname; +} + +// Returns true if FilePath ends with a path separator, which indicates that +// it is intended to represent a directory. Returns false otherwise. +// This does NOT check that a directory (or file) actually exists. +bool FilePath::IsDirectory() const { +  return pathname_.EndsWith(kPathSeparatorString); +} + +// Create directories so that path exists. Returns true if successful or if +// the directories already exist; returns false if unable to create directories +// for any reason. +bool FilePath::CreateDirectoriesRecursively() const { +  if (!this->IsDirectory()) { +    return false; +  } + +  if (pathname_.GetLength() == 0 || this->DirectoryExists()) { +    return true; +  } + +  const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); +  return parent.CreateDirectoriesRecursively() && this->CreateFolder(); +} + +// Create the directory so that path exists. Returns true if successful or +// if the directory already exists; returns false if unable to create the +// directory for any reason, including if the parent directory does not +// exist. Not named "CreateDirectory" because that's a macro on Windows. +bool FilePath::CreateFolder() const { +#ifdef GTEST_OS_WINDOWS +#ifdef _WIN32_WCE +  FilePath removed_sep(this->RemoveTrailingPathSeparator()); +  LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); +  int result = CreateDirectory(unicode, NULL) ? 0 : -1; +  delete [] unicode; +#else +  int result = _mkdir(pathname_.c_str()); +#endif  // !WIN32_WCE +#else +  int result = mkdir(pathname_.c_str(), 0777); +#endif  // _WIN32 +  if (result == -1) { +    return this->DirectoryExists();  // An error is OK if the directory exists. +  } +  return true;  // No error. +} + +// If input name has a trailing separator character, remove it and return the +// name, otherwise return the name string unmodified. +// On Windows platform, uses \ as the separator, other platforms use /. +FilePath FilePath::RemoveTrailingPathSeparator() const { +  return pathname_.EndsWith(kPathSeparatorString) +      ? FilePath(String(pathname_.c_str(), pathname_.GetLength() - 1)) +      : *this; +} + +// Normalize removes any redundant separators that might be in the pathname. +// For example, "bar///foo" becomes "bar/foo". Does not eliminate other +// redundancies that might be in a pathname involving "." or "..". +void FilePath::Normalize() { +  if (pathname_.c_str() == NULL) { +    pathname_ = ""; +    return; +  } +  const char* src = pathname_.c_str(); +  char* const dest = new char[pathname_.GetLength() + 1]; +  char* dest_ptr = dest; +  memset(dest_ptr, 0, pathname_.GetLength() + 1); + +  while (*src != '\0') { +    *dest_ptr++ = *src; +    if (*src != kPathSeparator) +      src++; +    else +      while (*src == kPathSeparator) +        src++; +  } +  *dest_ptr = '\0'; +  pathname_ = dest; +  delete[] dest; +} + +}  // namespace internal +}  // namespace testing diff --git a/llvm/utils/unittest/googletest/src/gtest-internal-inl.h b/llvm/utils/unittest/googletest/src/gtest-internal-inl.h new file mode 100644 index 00000000000..b8f67c18657 --- /dev/null +++ b/llvm/utils/unittest/googletest/src/gtest-internal-inl.h @@ -0,0 +1,1267 @@ +// Copyright 2005, 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. + +// Utility functions and classes used by the Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) +// +// This file contains purely Google Test's internal implementation.  Please +// DO NOT #INCLUDE IT IN A USER PROGRAM. + +#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ +#define GTEST_SRC_GTEST_INTERNAL_INL_H_ + +// GTEST_IMPLEMENTATION is defined iff the current translation unit is +// part of Google Test's implementation. +#ifndef GTEST_IMPLEMENTATION +// A user is trying to include this from his code - just say no. +#error "gtest-internal-inl.h is part of Google Test's internal implementation." +#error "It must not be included except by Google Test itself." +#endif  // GTEST_IMPLEMENTATION + +#include <stddef.h> + +#include <gtest/internal/gtest-port.h> + +#ifdef GTEST_OS_WINDOWS +#include <windows.h>  // NOLINT +#endif  // GTEST_OS_WINDOWS + +#include <gtest/gtest.h> +#include <gtest/gtest-spi.h> + +namespace testing { + +// Declares the flags. +// +// We don't want the users to modify these flags in the code, but want +// Google Test's own unit tests to be able to access them.  Therefore we +// declare them here as opposed to in gtest.h. +GTEST_DECLARE_bool_(break_on_failure); +GTEST_DECLARE_bool_(catch_exceptions); +GTEST_DECLARE_string_(color); +GTEST_DECLARE_string_(filter); +GTEST_DECLARE_bool_(list_tests); +GTEST_DECLARE_string_(output); +GTEST_DECLARE_bool_(print_time); +GTEST_DECLARE_int32_(repeat); +GTEST_DECLARE_int32_(stack_trace_depth); +GTEST_DECLARE_bool_(show_internal_stack_frames); + +namespace internal { + +// The value of GetTestTypeId() as seen from within the Google Test +// library.  This is solely for testing GetTestTypeId(). +extern const TypeId kTestTypeIdInGoogleTest; + +// Names of the flags (needed for parsing Google Test flags). +const char kBreakOnFailureFlag[] = "break_on_failure"; +const char kCatchExceptionsFlag[] = "catch_exceptions"; +const char kColorFlag[] = "color"; +const char kFilterFlag[] = "filter"; +const char kListTestsFlag[] = "list_tests"; +const char kOutputFlag[] = "output"; +const char kPrintTimeFlag[] = "print_time"; +const char kRepeatFlag[] = "repeat"; + +// This class saves the values of all Google Test flags in its c'tor, and +// restores them in its d'tor. +class GTestFlagSaver { + public: +  // The c'tor. +  GTestFlagSaver() { +    break_on_failure_ = GTEST_FLAG(break_on_failure); +    catch_exceptions_ = GTEST_FLAG(catch_exceptions); +    color_ = GTEST_FLAG(color); +    death_test_style_ = GTEST_FLAG(death_test_style); +    filter_ = GTEST_FLAG(filter); +    internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); +    list_tests_ = GTEST_FLAG(list_tests); +    output_ = GTEST_FLAG(output); +    print_time_ = GTEST_FLAG(print_time); +    repeat_ = GTEST_FLAG(repeat); +  } + +  // The d'tor is not virtual.  DO NOT INHERIT FROM THIS CLASS. +  ~GTestFlagSaver() { +    GTEST_FLAG(break_on_failure) = break_on_failure_; +    GTEST_FLAG(catch_exceptions) = catch_exceptions_; +    GTEST_FLAG(color) = color_; +    GTEST_FLAG(death_test_style) = death_test_style_; +    GTEST_FLAG(filter) = filter_; +    GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; +    GTEST_FLAG(list_tests) = list_tests_; +    GTEST_FLAG(output) = output_; +    GTEST_FLAG(print_time) = print_time_; +    GTEST_FLAG(repeat) = repeat_; +  } + private: +  // Fields for saving the original values of flags. +  bool break_on_failure_; +  bool catch_exceptions_; +  String color_; +  String death_test_style_; +  String filter_; +  String internal_run_death_test_; +  bool list_tests_; +  String output_; +  bool print_time_; +  bool pretty_; +  internal::Int32 repeat_; +} GTEST_ATTRIBUTE_UNUSED_; + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// The output buffer str must containt at least 32 characters. +// The function returns the address of the output buffer. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. +char* CodePointToUtf8(UInt32 code_point, char* str); + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +//   UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +String WideStringToUtf8(const wchar_t* str, int num_chars); + +// Returns the number of active threads, or 0 when there is an error. +size_t GetThreadCount(); + +// List is a simple singly-linked list container. +// +// 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. +// +// 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 +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 { + public: + +  // Creates an empty list. +  List() : head_(NULL), last_(NULL), size_(0) {} + +  // D'tor. +  virtual ~List(); + +  // Clears the list. +  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(); +      } + +      // 2. Resets the member variables. +      head_ = last_ = NULL; +      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 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_++; +    } +  } + +  // Removes an element from the beginning of this list.  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. +  bool PopFront(E* result) { +    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; + +    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; +    size_++; +    if (node == last_) { +      last_ = new_node; +    } + +    return new_node; +  } + +  // Returns the number of elements that satisfy a given predicate. +  // The parameter 'predicate' is a Boolean function or functor that +  // accepts a 'const E &', where E is the element type. +  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()) ) { +        count++; +      } +    } + +    return count; +  } + +  // Applies a function/functor to each element in the list.  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()); +    } +  } + +  // Returns the first node whose element satisfies a given predicate, +  // or NULL if none is found.  The parameter 'predicate' is a +  // 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; +      } +    } + +    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; +      } +    } + +    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. + +  // We disallow copying List. +  GTEST_DISALLOW_COPY_AND_ASSIGN_(List); +}; + +// The virtual destructor of List. +template <typename E> +List<E>::~List() { +  Clear(); +} + +// A function for deleting an object.  Handy for being used as a +// functor. +template <typename T> +static void Delete(T * x) { +  delete x; +} + +// A copyable object representing a user specified test property which can be +// output as a key/value string pair. +// +// Don't inherit from TestProperty as its destructor is not virtual. +class TestProperty { + public: +  // C'tor.  TestProperty does NOT have a default constructor. +  // Always use this constructor (with parameters) to create a +  // TestProperty object. +  TestProperty(const char* key, const char* value) : +    key_(key), value_(value) { +  } + +  // Gets the user supplied key. +  const char* key() const { +    return key_.c_str(); +  } + +  // Gets the user supplied value. +  const char* value() const { +    return value_.c_str(); +  } + +  // Sets a new value, overriding the one supplied in the constructor. +  void SetValue(const char* new_value) { +    value_ = new_value; +  } + + private: +  // The key supplied by the user. +  String key_; +  // The value supplied by the user. +  String value_; +}; + +// A predicate that checks the key of a TestProperty against a known key. +// +// TestPropertyKeyIs is copyable. +class TestPropertyKeyIs { + public: +  // Constructor. +  // +  // TestPropertyKeyIs has NO default constructor. +  explicit TestPropertyKeyIs(const char* key) +      : key_(key) {} + +  // Returns true iff the test name of test property matches on key_. +  bool operator()(const TestProperty& test_property) const { +    return String(test_property.key()).Compare(key_) == 0; +  } + + private: +  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, +               const char* name, const char* test_case_comment, +               const char* comment, TypeId fixture_class_id, +               internal::TestFactoryBase* factory); +  ~TestInfoImpl(); + +  // Returns true if this test should run. +  bool should_run() const { return should_run_; } + +  // Sets the should_run member. +  void set_should_run(bool should) { should_run_ = should; } + +  // Returns true if this test is disabled. Disabled tests are not run. +  bool is_disabled() const { return is_disabled_; } + +  // Sets the is_disabled member. +  void set_is_disabled(bool is) { is_disabled_ = is; } + +  // Returns the test case name. +  const char* test_case_name() const { return test_case_name_.c_str(); } + +  // Returns the test name. +  const char* name() const { return name_.c_str(); } + +  // Returns the test case comment. +  const char* test_case_comment() const { return test_case_comment_.c_str(); } + +  // Returns the test comment. +  const char* comment() const { return comment_.c_str(); } + +  // Returns the ID of the test fixture class. +  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_; } + +  // 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(); } + +  // Clears the test result in the given TestInfo object. +  static void ClearTestResult(TestInfo * test_info) { +    test_info->impl()->ClearResult(); +  } + + private: +  // These fields are immutable properties of the test. +  TestInfo* const parent_;          // The owner of this object +  const String test_case_name_;     // Test case name +  const String name_;               // Test name +  const String test_case_comment_;  // Test case comment +  const String comment_;            // Test comment +  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 +  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_; + +  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 +// specifies when running the tests.  It has only static members. +// +// In most cases, the user can specify an option using either an +// environment variable or a command line flag.  E.g. you can set the +// test filter using either GTEST_FILTER or --gtest_filter.  If both +// the variable and the flag are present, the latter overrides the +// former. +class UnitTestOptions { + public: +  // Functions for processing the gtest_output flag. + +  // Returns the output format, or "" for normal printed output. +  static String GetOutputFormat(); + +  // Returns the name of the requested output file, or the default if none +  // was explicitly specified. +  static String GetOutputFile(); + +  // Functions for processing the gtest_filter flag. + +  // Returns true iff the wildcard pattern matches the string.  The +  // first ':' or '\0' character in pattern marks the end of it. +  // +  // This recursive algorithm isn't very efficient, but is clear and +  // works well enough for matching test names, which are short. +  static bool PatternMatchesString(const char *pattern, const char *str); + +  // Returns true iff the user-specified filter matches the test case +  // name and the test name. +  static bool FilterMatchesTest(const String &test_case_name, +                                const String &test_name); + +#ifdef GTEST_OS_WINDOWS +  // Function for supporting the gtest_catch_exception flag. + +  // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the +  // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. +  // This function is useful as an __except condition. +  static int GTestShouldProcessSEH(DWORD exception_code); +#endif  // GTEST_OS_WINDOWS + +  // Returns true if "name" matches the ':' separated list of glob-style +  // filters in "filter". +  static bool MatchesFilter(const String& name, const char* filter); +}; + +// Returns the current application's name, removing directory path if that +// is present.  Used by UnitTestOptions::GetOutputFile. +FilePath GetCurrentExecutableName(); + +// The role interface for getting the OS stack trace as a string. +class OsStackTraceGetterInterface { + public: +  OsStackTraceGetterInterface() {} +  virtual ~OsStackTraceGetterInterface() {} + +  // Returns the current OS stack trace as a String.  Parameters: +  // +  //   max_depth  - the maximum number of stack frames to be included +  //                in the trace. +  //   skip_count - the number of top frames to be skipped; doesn't count +  //                against max_depth. +  virtual String CurrentStackTrace(int max_depth, int skip_count) = 0; + +  // UponLeavingGTest() should be called immediately before Google Test calls +  // user code. It saves some information about the current stack that +  // CurrentStackTrace() will use to find and hide Google Test stack frames. +  virtual void UponLeavingGTest() = 0; + + private: +  GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); +}; + +// A working implementation of the OsStackTraceGetterInterface interface. +class OsStackTraceGetter : public OsStackTraceGetterInterface { + public: +  OsStackTraceGetter() {} +  virtual String CurrentStackTrace(int max_depth, int skip_count); +  virtual void UponLeavingGTest(); + +  // This string is inserted in place of stack frames that are part of +  // Google Test's implementation. +  static const char* const kElidedFramesMarker; + + private: +  Mutex mutex_;  // protects all internal state + +  // We save the stack frame below the frame that calls user code. +  // We do this because the address of the frame immediately below +  // the user code changes between the call to UponLeavingGTest() +  // and any calls to CurrentStackTrace() from within the user code. +  void* caller_frame_; + +  GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); +}; + +// Information about a Google Test trace point. +struct TraceInfo { +  const char* file; +  int line; +  String message; +}; + +// This is the default global test part result reporter used in UnitTestImpl. +// This class should only be used by UnitTestImpl. +class DefaultGlobalTestPartResultReporter +  : public TestPartResultReporterInterface { + public: +  explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); +  // Implements the TestPartResultReporterInterface. Reports the test part +  // result in the current test. +  virtual void ReportTestPartResult(const TestPartResult& result); + + private: +  UnitTestImpl* const unit_test_; +}; + +// This is the default per thread test part result reporter used in +// UnitTestImpl. This class should only be used by UnitTestImpl. +class DefaultPerThreadTestPartResultReporter +    : public TestPartResultReporterInterface { + public: +  explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); +  // Implements the TestPartResultReporterInterface. The implementation just +  // delegates to the current global test part result reporter of *unit_test_. +  virtual void ReportTestPartResult(const TestPartResult& result); + + private: +  UnitTestImpl* const unit_test_; +}; + +// The private implementation of the UnitTest class.  We don't protect +// the methods under a mutex, as this class is not accessible by a +// user and the UnitTest class that delegates work to this class does +// proper locking. +class UnitTestImpl { + public: +  explicit UnitTestImpl(UnitTest* parent); +  virtual ~UnitTestImpl(); + +  // There are two different ways to register your own TestPartResultReporter. +  // You can register your own repoter to listen either only for test results +  // from the current thread or for results from all threads. +  // By default, each per-thread test result repoter just passes a new +  // TestPartResult to the global test result reporter, which registers the +  // test part result for the currently running test. + +  // Returns the global test part result reporter. +  TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); + +  // Sets the global test part result reporter. +  void SetGlobalTestPartResultReporter( +      TestPartResultReporterInterface* reporter); + +  // Returns the test part result reporter for the current thread. +  TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); + +  // Sets the test part result reporter for the current thread. +  void SetTestPartResultReporterForCurrentThread( +      TestPartResultReporterInterface* reporter); + +  // Gets the number of successful test cases. +  int successful_test_case_count() const; + +  // Gets the number of failed test cases. +  int failed_test_case_count() const; + +  // Gets the number of all test cases. +  int total_test_case_count() const; + +  // Gets the number of all test cases that contain at least one test +  // that should run. +  int test_case_to_run_count() const; + +  // Gets the number of successful tests. +  int successful_test_count() const; + +  // Gets the number of failed tests. +  int failed_test_count() const; + +  // Gets the number of disabled tests. +  int disabled_test_count() const; + +  // Gets the number of all tests. +  int total_test_count() const; + +  // Gets the number of tests that should run. +  int test_to_run_count() const; + +  // Gets the elapsed time, in milliseconds. +  TimeInMillis elapsed_time() const { return elapsed_time_; } + +  // Returns true iff the unit test passed (i.e. all test cases passed). +  bool Passed() const { return !Failed(); } + +  // Returns true iff the unit test failed (i.e. some test case failed +  // or something outside of all tests failed). +  bool Failed() const { +    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(); + +  // Returns the TestResult for the ad hoc test. +  const internal::TestResult* ad_hoc_test_result() const { +    return &ad_hoc_test_result_; +  } + +  // 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); + +  // 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(); + +  // Sets the OS stack trace getter. +  // +  // Does nothing if the input and the current OS stack trace getter +  // are the same; otherwise, deletes the old getter and makes the +  // input the current getter. +  void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); + +  // Returns the current OS stack trace getter if it is not NULL; +  // otherwise, creates an OsStackTraceGetter, makes it the current +  // getter, and returns it. +  OsStackTraceGetterInterface* os_stack_trace_getter(); + +  // Returns the current OS stack trace as a String. +  // +  // The maximum number of stack frames to be included is specified by +  // the gtest_stack_trace_depth flag.  The skip_count parameter +  // specifies the number of top frames to be skipped, which doesn't +  // count against the number of frames to be included. +  // +  // For example, if Foo() calls Bar(), which in turn calls +  // CurrentOsStackTraceExceptTop(1), Foo() will be included in the +  // trace but Bar() and CurrentOsStackTraceExceptTop() won't. +  String CurrentOsStackTraceExceptTop(int skip_count); + +  // Finds and returns a TestCase with the given name.  If one doesn't +  // exist, creates one and returns it. +  // +  // Arguments: +  // +  //   test_case_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* GetTestCase(const char* test_case_name, +                        const char* comment, +                        Test::SetUpTestCaseFunc set_up_tc, +                        Test::TearDownTestCaseFunc tear_down_tc); + +  // Adds a TestInfo to the unit test. +  // +  // Arguments: +  // +  //   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 +  //   test_info:    the TestInfo object +  void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, +                   Test::TearDownTestCaseFunc tear_down_tc, +                   TestInfo * test_info) { +    // In order to support thread-safe death tests, we need to +    // remember the original working directory when the test program +    // was first invoked.  We cannot do this in RUN_ALL_TESTS(), as +    // the user may have changed the current directory before calling +    // RUN_ALL_TESTS().  Therefore we capture the current directory in +    // AddTestInfo(), which is called to register a TEST or TEST_F +    // 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(); +      } +    } + +    GetTestCase(test_info->test_case_name(), +                test_info->test_case_comment(), +                set_up_tc, +                tear_down_tc)->AddTestInfo(test_info); +  } + +#ifdef GTEST_HAS_PARAM_TEST +  // Returns ParameterizedTestCaseRegistry object used to keep track of +  // value-parameterized tests and instantiate and register them. +  internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { +    return parameterized_test_registry_; +  } +#endif  // GTEST_HAS_PARAM_TEST + +  // Sets the TestCase object for the test that's currently running. +  void set_current_test_case(TestCase* current_test_case) { +    current_test_case_ = current_test_case; +  } + +  // Sets the TestInfo object for the test that's currently running.  If +  // current_test_info is NULL, the assertion results will be stored in +  // ad_hoc_test_result_. +  void set_current_test_info(TestInfo* current_test_info) { +    current_test_info_ = current_test_info; +  } + +  // Registers all parameterized tests defined using TEST_P and +  // INSTANTIATE_TEST_P, creating regular tests for each test/parameter +  // combination. This method can be called more then once; it has +  // guards protecting from registering the tests more then once. +  // If value-parameterized tests are disabled, RegisterParameterizedTests +  // is present but does nothing. +  void RegisterParameterizedTests(); + +  // Runs all tests in this UnitTest object, prints the result, and +  // returns 0 if all tests are successful, or 1 otherwise.  If any +  // exception is thrown during a test on Windows, this test is +  // considered to be failed, but the rest of the tests will still be +  // run.  (We disable exceptions on Linux and Mac OS X, so the issue +  // doesn't apply there.) +  int RunAllTests(); + +  // Clears the results of all tests, including the ad hoc test. +  void ClearResult() { +    test_cases_.ForEach(TestCase::ClearTestCaseResult); +    ad_hoc_test_result_.Clear(); +  } + +  // Matches the full name of each test against the user-specified +  // filter to decide whether the test should run, then records the +  // result in each TestCase and TestInfo object. +  // Returns the number of tests that should run. +  int FilterTests(); + +  // Lists all the tests by name. +  void ListAllTests(); + +  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 +  // before/after the tests are run. +  internal::List<Environment*>* environments() { return &environments_; } +  internal::List<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() { +    return gtest_trace_stack_.pointer(); +  } +  const internal::List<TraceInfo>* gtest_trace_stack() const { +    return gtest_trace_stack_.pointer(); +  } + +#ifdef GTEST_HAS_DEATH_TEST +  // 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. +  const InternalRunDeathTestFlag* internal_run_death_test_flag() const { +    return internal_run_death_test_flag_.get(); +  } + +  // Returns a pointer to the current death test factory. +  internal::DeathTestFactory* death_test_factory() { +    return death_test_factory_.get(); +  } + +  friend class ReplaceDeathTestFactory; +#endif  // GTEST_HAS_DEATH_TEST + + private: +  friend class ::testing::UnitTest; + +  // The UnitTest object that owns this implementation object. +  UnitTest* const parent_; + +  // The working directory when the first TEST() or TEST_F() was +  // executed. +  internal::FilePath original_working_dir_; + +  // The default test part result reporters. +  DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; +  DefaultPerThreadTestPartResultReporter +      default_per_thread_test_part_result_reporter_; + +  // Points to (but doesn't own) the global test part result reporter. +  TestPartResultReporterInterface* global_test_part_result_repoter_; + +  // Protects read and write access to global_test_part_result_reporter_. +  internal::Mutex global_test_part_result_reporter_mutex_; + +  // Points to (but doesn't own) the per-thread test part result reporter. +  internal::ThreadLocal<TestPartResultReporterInterface*> +      per_thread_test_part_result_reporter_; + +  // The list 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::List<TestCase*> test_cases_;  // The list of TestCases. + +#ifdef GTEST_HAS_PARAM_TEST +  // ParameterizedTestRegistry object used to register value-parameterized +  // tests. +  internal::ParameterizedTestCaseRegistry parameterized_test_registry_; + +  // Indicates whether RegisterParameterizedTests() has been called already. +  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_; + +  // 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. +  TestCase* current_test_case_; + +  // This points to the TestInfo for the currently running test.  It +  // changes as Google Test goes through one test after another.  When +  // no test is running, this is set to NULL and Google Test stores +  // assertion results in ad_hoc_test_result_.  Initially NULL. +  TestInfo* current_test_info_; + +  // Normally, a user only writes assertions inside a TEST or TEST_F, +  // or inside a function called by a TEST or TEST_F.  Since Google +  // Test keeps track of which test is current running, it can +  // associate such an assertion with the test it belongs to. +  // +  // 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_; + +  // 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 OS stack trace getter.  Will be deleted when the UnitTest +  // object is destructed.  By default, an OsStackTraceGetter is used, +  // but the user can set this field to use a custom getter if that is +  // desired. +  OsStackTraceGetterInterface* os_stack_trace_getter_; + +  // How long the test took to run, in milliseconds. +  TimeInMillis elapsed_time_; + +#ifdef GTEST_HAS_DEATH_TEST +  // The decomposed components of the gtest_internal_run_death_test flag, +  // parsed when RUN_ALL_TESTS is called. +  internal::scoped_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_; +  internal::scoped_ptr<internal::DeathTestFactory> death_test_factory_; +#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_; + +  GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); +};  // class UnitTestImpl + +// Convenience function for accessing the global UnitTest +// implementation object. +inline UnitTestImpl* GetUnitTestImpl() { +  return UnitTest::GetInstance()->impl(); +} + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +void ParseGoogleTestFlagsOnly(int* argc, char** argv); +void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); + +}  // namespace internal +}  // namespace testing + +#endif  // GTEST_SRC_GTEST_INTERNAL_INL_H_ diff --git a/llvm/utils/unittest/googletest/src/gtest-port.cc b/llvm/utils/unittest/googletest/src/gtest-port.cc new file mode 100644 index 00000000000..9878cae05d6 --- /dev/null +++ b/llvm/utils/unittest/googletest/src/gtest-port.cc @@ -0,0 +1,332 @@ +// Copyright 2008, 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) + +#include <gtest/internal/gtest-port.h> + +#include <limits.h> +#include <stdlib.h> +#include <stdio.h> + +#ifdef GTEST_HAS_DEATH_TEST +#include <regex.h> +#endif  // GTEST_HAS_DEATH_TEST + +#ifdef _WIN32_WCE +#include <windows.h>  // For TerminateProcess() +#endif  // _WIN32_WCE + +#include <gtest/gtest-spi.h> +#include <gtest/gtest-message.h> +#include <gtest/internal/gtest-string.h> + + +namespace testing { +namespace internal { + +#ifdef GTEST_HAS_DEATH_TEST + +// Implements RE.  Currently only needed for death tests. + +RE::~RE() { +  regfree(&partial_regex_); +  regfree(&full_regex_); +  free(const_cast<char*>(pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { +  if (!re.is_valid_) return false; + +  regmatch_t match; +  return regexec(&re.full_regex_, str, 1, &match, 0) == 0; +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { +  if (!re.is_valid_) return false; + +  regmatch_t match; +  return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { +  pattern_ = strdup(regex); + +  // Reserves enough bytes to hold the regular expression used for a +  // full match. +  const size_t full_regex_len = strlen(regex) + 10; +  char* const full_pattern = new char[full_regex_len]; + +  snprintf(full_pattern, full_regex_len, "^(%s)$", regex); +  is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; +  // We want to call regcomp(&partial_regex_, ...) even if the +  // previous expression returns false.  Otherwise partial_regex_ may +  // not be properly initialized can may cause trouble when it's +  // freed. +  is_valid_ = (regcomp(&partial_regex_, regex, REG_EXTENDED) == 0) && is_valid_; +  EXPECT_TRUE(is_valid_) +      << "Regular expression \"" << regex +      << "\" is not a valid POSIX Extended regular expression."; + +  delete[] full_pattern; +} + +#endif  // GTEST_HAS_DEATH_TEST + +// Logs a message at the given severity level. +void GTestLog(GTestLogSeverity severity, const char* file, +              int line, const char* msg) { +  const char* const marker = +      severity == GTEST_INFO ?    "[  INFO ]" : +      severity == GTEST_WARNING ? "[WARNING]" : +      severity == GTEST_ERROR ?   "[ ERROR ]" : "[ FATAL ]"; +  fprintf(stderr, "\n%s %s:%d: %s\n", marker, file, line, msg); +  if (severity == GTEST_FATAL) { +    abort(); +  } +} + +#ifdef GTEST_HAS_DEATH_TEST + +// Defines the stderr capturer. + +class CapturedStderr { + public: +  // The ctor redirects stderr to a temporary file. +  CapturedStderr() { +    uncaptured_fd_ = dup(STDERR_FILENO); + +    // There's no guarantee that a test has write access to the +    // current directory, so we create the temporary file in the /tmp +    // directory instead. +    char name_template[] = "/tmp/captured_stderr.XXXXXX"; +    const int captured_fd = mkstemp(name_template); +    filename_ = name_template; +    fflush(NULL); +    dup2(captured_fd, STDERR_FILENO); +    close(captured_fd); +  } + +  ~CapturedStderr() { +    remove(filename_.c_str()); +  } + +  // Stops redirecting stderr. +  void StopCapture() { +    // Restores the original stream. +    fflush(NULL); +    dup2(uncaptured_fd_, STDERR_FILENO); +    close(uncaptured_fd_); +    uncaptured_fd_ = -1; +  } + +  // Returns the name of the temporary file holding the stderr output. +  // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we +  // can use it here. +  ::std::string filename() const { return filename_; } + + private: +  int uncaptured_fd_; +  ::std::string filename_; +}; + +static CapturedStderr* g_captured_stderr = NULL; + +// Returns the size (in bytes) of a file. +static size_t GetFileSize(FILE * file) { +  fseek(file, 0, SEEK_END); +  return static_cast<size_t>(ftell(file)); +} + +// Reads the entire content of a file as a string. +// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can +// use it here. +static ::std::string ReadEntireFile(FILE * file) { +  const size_t file_size = GetFileSize(file); +  char* const buffer = new char[file_size]; + +  size_t bytes_last_read = 0;  // # of bytes read in the last fread() +  size_t bytes_read = 0;       // # of bytes read so far + +  fseek(file, 0, SEEK_SET); + +  // Keeps reading the file until we cannot read further or the +  // pre-determined file size is reached. +  do { +    bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); +    bytes_read += bytes_last_read; +  } while (bytes_last_read > 0 && bytes_read < file_size); + +  const ::std::string content(buffer, buffer+bytes_read); +  delete[] buffer; + +  return content; +} + +// Starts capturing stderr. +void CaptureStderr() { +  if (g_captured_stderr != NULL) { +    GTEST_LOG_(FATAL, "Only one stderr capturer can exist at one time."); +  } +  g_captured_stderr = new CapturedStderr; +} + +// Stops capturing stderr and returns the captured string. +// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can +// use it here. +::std::string GetCapturedStderr() { +  g_captured_stderr->StopCapture(); +  FILE* const file = fopen(g_captured_stderr->filename().c_str(), "r"); +  const ::std::string content = ReadEntireFile(file); +  fclose(file); + +  delete g_captured_stderr; +  g_captured_stderr = NULL; + +  return content; +} + +// A copy of all command line arguments.  Set by InitGoogleTest(). +::std::vector<String> g_argvs; + +// Returns the command line as a vector of strings. +const ::std::vector<String>& GetArgvs() { return g_argvs; } + +#endif  // GTEST_HAS_DEATH_TEST + +#ifdef _WIN32_WCE +void abort() { +  DebugBreak(); +  TerminateProcess(GetCurrentProcess(), 1); +} +#endif  // _WIN32_WCE + +// Returns the name of the environment variable corresponding to the +// given flag.  For example, FlagToEnvVar("foo") will return +// "GTEST_FOO" in the open-source version. +static String FlagToEnvVar(const char* flag) { +  const String full_flag = (Message() << GTEST_FLAG_PREFIX << flag).GetString(); + +  Message env_var; +  for (int i = 0; i != full_flag.GetLength(); i++) { +    env_var << static_cast<char>(toupper(full_flag.c_str()[i])); +  } + +  return env_var.GetString(); +} + +// Reads and returns the Boolean environment variable corresponding to +// the given flag; if it's not set, returns default_value. +// +// The value is considered true iff it's not "0". +bool BoolFromGTestEnv(const char* flag, bool default_value) { +  const String env_var = FlagToEnvVar(flag); +  const char* const string_value = GetEnv(env_var.c_str()); +  return string_value == NULL ? +      default_value : strcmp(string_value, "0") != 0; +} + +// Parses 'str' for a 32-bit signed integer.  If successful, writes +// the result to *value and returns true; otherwise leaves *value +// unchanged and returns false. +bool ParseInt32(const Message& src_text, const char* str, Int32* value) { +  // Parses the environment variable as a decimal integer. +  char* end = NULL; +  const long long_value = strtol(str, &end, 10);  // NOLINT + +  // Has strtol() consumed all characters in the string? +  if (*end != '\0') { +    // No - an invalid character was encountered. +    Message msg; +    msg << "WARNING: " << src_text +        << " is expected to be a 32-bit integer, but actually" +        << " has value \"" << str << "\".\n"; +    printf("%s", msg.GetString().c_str()); +    fflush(stdout); +    return false; +  } + +  // Is the parsed value in the range of an Int32? +  const Int32 result = static_cast<Int32>(long_value); +  if (long_value == LONG_MAX || long_value == LONG_MIN || +      // The parsed value overflows as a long.  (strtol() returns +      // LONG_MAX or LONG_MIN when the input overflows.) +      result != long_value +      // The parsed value overflows as an Int32. +      ) { +    Message msg; +    msg << "WARNING: " << src_text +        << " is expected to be a 32-bit integer, but actually" +        << " has value " << str << ", which overflows.\n"; +    printf("%s", msg.GetString().c_str()); +    fflush(stdout); +    return false; +  } + +  *value = result; +  return true; +} + +// Reads and returns a 32-bit integer stored in the environment +// variable corresponding to the given flag; if it isn't set or +// doesn't represent a valid 32-bit integer, returns default_value. +Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { +  const String env_var = FlagToEnvVar(flag); +  const char* const string_value = GetEnv(env_var.c_str()); +  if (string_value == NULL) { +    // The environment variable is not set. +    return default_value; +  } + +  Int32 result = default_value; +  if (!ParseInt32(Message() << "Environment variable " << env_var, +                  string_value, &result)) { +    printf("The default value %s is used.\n", +           (Message() << default_value).GetString().c_str()); +    fflush(stdout); +    return default_value; +  } + +  return result; +} + +// Reads and returns the string environment variable corresponding to +// the given flag; if it's not set, returns default_value. +const char* StringFromGTestEnv(const char* flag, const char* default_value) { +  const String env_var = FlagToEnvVar(flag); +  const char* const value = GetEnv(env_var.c_str()); +  return value == NULL ? default_value : value; +} + +}  // namespace internal +}  // namespace testing diff --git a/llvm/utils/unittest/googletest/src/gtest-test-part.cc b/llvm/utils/unittest/googletest/src/gtest-test-part.cc new file mode 100644 index 00000000000..dcd30b25848 --- /dev/null +++ b/llvm/utils/unittest/googletest/src/gtest-test-part.cc @@ -0,0 +1,124 @@ +// Copyright 2008, 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: mheule@google.com (Markus Heule) +// +// The Google C++ Testing Framework (Google Test) + +#include <gtest/gtest-test-part.h> + +// Indicates that this translation unit is part of Google Test's +// implementation.  It must come before gtest-internal-inl.h is +// included, or there will be a compiler error.  This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION + +namespace testing { + +// Gets the summary of the failure message by omitting the stack trace +// in it. +internal::String TestPartResult::ExtractSummary(const char* message) { +  const char* const stack_trace = strstr(message, internal::kStackTraceMarker); +  return stack_trace == NULL ? internal::String(message) : +      internal::String(message, stack_trace - message); +} + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { +  return os << result.file_name() << ":" +            << result.line_number() << ": " +            << (result.type() == TPRT_SUCCESS ? "Success" : +                result.type() == TPRT_FATAL_FAILURE ? "Fatal failure" : +                "Non-fatal failure") << ":\n" +            << result.message() << std::endl; +} + +// Constructs an empty TestPartResultArray. +TestPartResultArray::TestPartResultArray() +    : list_(new internal::List<TestPartResult>) { +} + +// Destructs a TestPartResultArray. +TestPartResultArray::~TestPartResultArray() { +  delete list_; +} + +// Appends a TestPartResult to the array. +void TestPartResultArray::Append(const TestPartResult& result) { +  list_->PushBack(result); +} + +// Returns the TestPartResult at the given index (0-based). +const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { +  if (index < 0 || index >= size()) { +    printf("\nInvalid index (%d) into TestPartResultArray.\n", index); +    internal::abort(); +  } + +  const internal::ListNode<TestPartResult>* p = list_->Head(); +  for (int i = 0; i < index; i++) { +    p = p->next(); +  } + +  return p->element(); +} + +// Returns the number of TestPartResult objects in the array. +int TestPartResultArray::size() const { +  return list_->size(); +} + +namespace internal { + +HasNewFatalFailureHelper::HasNewFatalFailureHelper() +    : has_new_fatal_failure_(false), +      original_reporter_(UnitTest::GetInstance()->impl()-> +                         GetTestPartResultReporterForCurrentThread()) { +  UnitTest::GetInstance()->impl()->SetTestPartResultReporterForCurrentThread( +      this); +} + +HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { +  UnitTest::GetInstance()->impl()->SetTestPartResultReporterForCurrentThread( +      original_reporter_); +} + +void HasNewFatalFailureHelper::ReportTestPartResult( +    const TestPartResult& result) { +  if (result.fatally_failed()) +    has_new_fatal_failure_ = true; +  original_reporter_->ReportTestPartResult(result); +} + +}  // namespace internal + +}  // namespace testing diff --git a/llvm/utils/unittest/googletest/src/gtest-typed-test.cc b/llvm/utils/unittest/googletest/src/gtest-typed-test.cc new file mode 100644 index 00000000000..d42a1596d57 --- /dev/null +++ b/llvm/utils/unittest/googletest/src/gtest-typed-test.cc @@ -0,0 +1,97 @@ +// Copyright 2008 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) + +#include <gtest/gtest-typed-test.h> +#include <gtest/gtest.h> + +namespace testing { +namespace internal { + +#ifdef GTEST_HAS_TYPED_TEST_P + +// Verifies that registered_tests match the test names in +// defined_test_names_; returns registered_tests if successful, or +// aborts the program otherwise. +const char* TypedTestCasePState::VerifyRegisteredTestNames( +    const char* file, int line, const char* registered_tests) { +  typedef ::std::set<const char*>::const_iterator DefinedTestIter; +  registered_ = true; + +  Message errors; +  ::std::set<String> tests; +  for (const char* names = registered_tests; names != NULL; +       names = SkipComma(names)) { +    const String name = GetPrefixUntilComma(names); +    if (tests.count(name) != 0) { +      errors << "Test " << name << " is listed more than once.\n"; +      continue; +    } + +    bool found = false; +    for (DefinedTestIter it = defined_test_names_.begin(); +         it != defined_test_names_.end(); +         ++it) { +      if (name == *it) { +        found = true; +        break; +      } +    } + +    if (found) { +      tests.insert(name); +    } else { +      errors << "No test named " << name +             << " can be found in this test case.\n"; +    } +  } + +  for (DefinedTestIter it = defined_test_names_.begin(); +       it != defined_test_names_.end(); +       ++it) { +    if (tests.count(*it) == 0) { +      errors << "You forgot to list test " << *it << ".\n"; +    } +  } + +  const String& errors_str = errors.GetString(); +  if (errors_str != "") { +    fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), +            errors_str.c_str()); +    abort(); +  } + +  return registered_tests; +} + +#endif  // GTEST_HAS_TYPED_TEST_P + +}  // namespace internal +}  // namespace testing diff --git a/llvm/utils/unittest/googletest/src/gtest.cc b/llvm/utils/unittest/googletest/src/gtest.cc new file mode 100644 index 00000000000..a9ca334ac1d --- /dev/null +++ b/llvm/utils/unittest/googletest/src/gtest.cc @@ -0,0 +1,3951 @@ +// Copyright 2005, 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) +// +// The Google C++ Testing Framework (Google Test) + +#include <gtest/gtest.h> +#include <gtest/gtest-spi.h> + +#include <ctype.h> +#include <math.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <wchar.h> +#include <wctype.h> + +#ifdef GTEST_OS_LINUX + +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +#define GTEST_HAS_GETTIMEOFDAY + +#include <fcntl.h> +#include <limits.h> +#include <sched.h> +// Declares vsnprintf().  This header is not available on Windows. +#include <strings.h> +#include <sys/mman.h> +#include <sys/time.h> +#include <unistd.h> +#include <string> +#include <vector> + +#elif defined(GTEST_OS_SYMBIAN) +#define GTEST_HAS_GETTIMEOFDAY +#include <sys/time.h>  // NOLINT + +#elif defined(GTEST_OS_ZOS) +#define GTEST_HAS_GETTIMEOFDAY +#include <sys/time.h>  // NOLINT + +// On z/OS we additionally need strings.h for strcasecmp. +#include <strings.h> + +#elif defined(_WIN32_WCE)  // We are on Windows CE. + +#include <windows.h>  // NOLINT + +#elif defined(GTEST_OS_WINDOWS)  // We are on Windows proper. + +#include <io.h>  // NOLINT +#include <sys/timeb.h>  // NOLINT +#include <sys/types.h>  // NOLINT +#include <sys/stat.h>  // NOLINT + +#if defined(__MINGW__) || defined(__MINGW32__) +// MinGW has gettimeofday() but not _ftime64(). +// TODO(kenton@google.com): Use autoconf to detect availability of +//   gettimeofday(). +// TODO(kenton@google.com): There are other ways to get the time on +//   Windows, like GetTickCount() or GetSystemTimeAsFileTime().  MinGW +//   supports these.  consider using them instead. +#define GTEST_HAS_GETTIMEOFDAY +#include <sys/time.h>  // NOLINT +#endif + +// cpplint thinks that the header is already included, so we want to +// silence it. +#include <windows.h>  // NOLINT + +#else + +// Assume other platforms have gettimeofday(). +// TODO(kenton@google.com): Use autoconf to detect availability of +//   gettimeofday(). +#define GTEST_HAS_GETTIMEOFDAY + +// cpplint thinks that the header is already included, so we want to +// silence it. +#include <sys/time.h>  // NOLINT +#include <unistd.h>  // NOLINT + +#endif + +// Indicates that this translation unit is part of Google Test's +// implementation.  It must come before gtest-internal-inl.h is +// included, or there will be a compiler error.  This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION + +#ifdef GTEST_OS_WINDOWS +#define fileno _fileno +#define isatty _isatty +#define vsnprintf _vsnprintf +#endif  // GTEST_OS_WINDOWS + +namespace testing { + +// Constants. + +// A test whose test case name or test name matches this filter is +// disabled and not run. +static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; + +// A test case whose name matches this filter is considered a death +// test case and will be run before test cases whose name doesn't +// match this filter. +static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*"; + +// A test filter that matches everything. +static const char kUniversalFilter[] = "*"; + +// The default output file for XML output. +static const char kDefaultOutputFile[] = "test_detail.xml"; + +namespace internal { + +// The text used in failure messages to indicate the start of the +// stack trace. +const char kStackTraceMarker[] = "\nStack trace:\n"; + +}  // namespace internal + +GTEST_DEFINE_bool_( +    break_on_failure, +    internal::BoolFromGTestEnv("break_on_failure", false), +    "True iff a failed assertion should be a debugger break-point."); + +GTEST_DEFINE_bool_( +    catch_exceptions, +    internal::BoolFromGTestEnv("catch_exceptions", false), +    "True iff " GTEST_NAME +    " should catch exceptions and treat them as test failures."); + +GTEST_DEFINE_string_( +    color, +    internal::StringFromGTestEnv("color", "auto"), +    "Whether to use colors in the output.  Valid values: yes, no, " +    "and auto.  'auto' means to use colors if the output is " +    "being sent to a terminal and the TERM environment variable " +    "is set to xterm or xterm-color."); + +GTEST_DEFINE_string_( +    filter, +    internal::StringFromGTestEnv("filter", kUniversalFilter), +    "A colon-separated list of glob (not regex) patterns " +    "for filtering the tests to run, optionally followed by a " +    "'-' and a : separated list of negative patterns (tests to " +    "exclude).  A test is run if it matches one of the positive " +    "patterns and does not match any of the negative patterns."); + +GTEST_DEFINE_bool_(list_tests, false, +                   "List all tests without running them."); + +GTEST_DEFINE_string_( +    output, +    internal::StringFromGTestEnv("output", ""), +    "A format (currently must be \"xml\"), optionally followed " +    "by a colon and an output file name or directory. A directory " +    "is indicated by a trailing pathname separator. " +    "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " +    "If a directory is specified, output files will be created " +    "within that directory, with file-names based on the test " +    "executable's name and, if necessary, made unique by adding " +    "digits."); + +GTEST_DEFINE_bool_( +    print_time, +    internal::BoolFromGTestEnv("print_time", false), +    "True iff " GTEST_NAME +    " should display elapsed time in text output."); + +GTEST_DEFINE_int32_( +    repeat, +    internal::Int32FromGTestEnv("repeat", 1), +    "How many times to repeat each test.  Specify a negative number " +    "for repeating forever.  Useful for shaking out flaky tests."); + +GTEST_DEFINE_int32_( +    stack_trace_depth, +        internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), +    "The maximum number of stack frames to print when an " +    "assertion fails.  The valid range is 0 through 100, inclusive."); + +GTEST_DEFINE_bool_( +    show_internal_stack_frames, false, +    "True iff " GTEST_NAME " should include internal stack frames when " +    "printing test failure stack traces."); + +namespace internal { + +// GTestIsInitialized() returns true iff the user has initialized +// Google Test.  Useful for catching the user mistake of not initializing +// Google Test before calling RUN_ALL_TESTS(). +// +// A user must call testing::InitGoogleTest() to initialize Google +// Test.  g_init_gtest_count is set to the number of times +// InitGoogleTest() has been called.  We don't protect this variable +// under a mutex as it is only accessed in the main thread. +int g_init_gtest_count = 0; +static bool GTestIsInitialized() { return g_init_gtest_count != 0; } + +// Iterates over a list of TestCases, keeping a running sum of the +// results of calling a given int-returning method on each. +// Returns the sum. +static int SumOverTestCaseList(const internal::List<TestCase*>& case_list, +                               int (TestCase::*method)() const) { +  int sum = 0; +  for (const internal::ListNode<TestCase*>* node = case_list.Head(); +       node != NULL; +       node = node->next()) { +    sum += (node->element()->*method)(); +  } +  return sum; +} + +// Returns true iff the test case passed. +static bool TestCasePassed(const TestCase* test_case) { +  return test_case->should_run() && test_case->Passed(); +} + +// Returns true iff the test case failed. +static bool TestCaseFailed(const TestCase* test_case) { +  return test_case->should_run() && test_case->Failed(); +} + +// Returns true iff test_case contains at least one test that should +// run. +static bool ShouldRunTestCase(const TestCase* test_case) { +  return test_case->should_run(); +} + +// AssertHelper constructor. +AssertHelper::AssertHelper(TestPartResultType type, const char* file, +                           int line, const char* message) +    : type_(type), file_(file), line_(line), message_(message) { +} + +// Message assignment, for assertion streaming support. +void AssertHelper::operator=(const Message& message) const { +  UnitTest::GetInstance()-> +    AddTestPartResult(type_, file_, line_, +                      AppendUserMessage(message_, message), +                      UnitTest::GetInstance()->impl() +                      ->CurrentOsStackTraceExceptTop(1) +                      // Skips the stack frame for this function itself. +                      );  // NOLINT +} + +// Mutex for linked pointers. +Mutex g_linked_ptr_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX); + +// Application pathname gotten in InitGoogleTest. +String g_executable_path; + +// Returns the current application's name, removing directory path if that +// is present. +FilePath GetCurrentExecutableName() { +  FilePath result; + +#if defined(_WIN32_WCE) || defined(GTEST_OS_WINDOWS) +  result.Set(FilePath(g_executable_path).RemoveExtension("exe")); +#else +  result.Set(FilePath(g_executable_path)); +#endif  // _WIN32_WCE || GTEST_OS_WINDOWS + +  return result.RemoveDirectoryName(); +} + +// Functions for processing the gtest_output flag. + +// Returns the output format, or "" for normal printed output. +String UnitTestOptions::GetOutputFormat() { +  const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); +  if (gtest_output_flag == NULL) return String(""); + +  const char* const colon = strchr(gtest_output_flag, ':'); +  return (colon == NULL) ? +      String(gtest_output_flag) : +      String(gtest_output_flag, colon - gtest_output_flag); +} + +// Returns the name of the requested output file, or the default if none +// was explicitly specified. +String UnitTestOptions::GetOutputFile() { +  const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); +  if (gtest_output_flag == NULL) +    return String(""); + +  const char* const colon = strchr(gtest_output_flag, ':'); +  if (colon == NULL) +    return String(kDefaultOutputFile); + +  internal::FilePath output_name(colon + 1); +  if (!output_name.IsDirectory()) +    return output_name.ToString(); + +  internal::FilePath result(internal::FilePath::GenerateUniqueFileName( +      output_name, internal::GetCurrentExecutableName(), +      GetOutputFormat().c_str())); +  return result.ToString(); +} + +// Returns true iff the wildcard pattern matches the string.  The +// first ':' or '\0' character in pattern marks the end of it. +// +// This recursive algorithm isn't very efficient, but is clear and +// works well enough for matching test names, which are short. +bool UnitTestOptions::PatternMatchesString(const char *pattern, +                                           const char *str) { +  switch (*pattern) { +    case '\0': +    case ':':  // Either ':' or '\0' marks the end of the pattern. +      return *str == '\0'; +    case '?':  // Matches any single character. +      return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); +    case '*':  // Matches any string (possibly empty) of characters. +      return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || +          PatternMatchesString(pattern + 1, str); +    default:  // Non-special character.  Matches itself. +      return *pattern == *str && +          PatternMatchesString(pattern + 1, str + 1); +  } +} + +bool UnitTestOptions::MatchesFilter(const String& name, const char* filter) { +  const char *cur_pattern = filter; +  while (true) { +    if (PatternMatchesString(cur_pattern, name.c_str())) { +      return true; +    } + +    // Finds the next pattern in the filter. +    cur_pattern = strchr(cur_pattern, ':'); + +    // Returns if no more pattern can be found. +    if (cur_pattern == NULL) { +      return false; +    } + +    // Skips the pattern separater (the ':' character). +    cur_pattern++; +  } +} + +// TODO(keithray): move String function implementations to gtest-string.cc. + +// Returns true iff the user-specified filter matches the test case +// name and the test name. +bool UnitTestOptions::FilterMatchesTest(const String &test_case_name, +                                        const String &test_name) { +  const String& full_name = String::Format("%s.%s", +                                           test_case_name.c_str(), +                                           test_name.c_str()); + +  // Split --gtest_filter at '-', if there is one, to separate into +  // positive filter and negative filter portions +  const char* const p = GTEST_FLAG(filter).c_str(); +  const char* const dash = strchr(p, '-'); +  String positive; +  String negative; +  if (dash == NULL) { +    positive = GTEST_FLAG(filter).c_str();  // Whole string is a positive filter +    negative = String(""); +  } else { +    positive.Set(p, dash - p);       // Everything up to the dash +    negative = String(dash+1);       // Everything after the dash +    if (positive.empty()) { +      // Treat '-test1' as the same as '*-test1' +      positive = kUniversalFilter; +    } +  } + +  // A filter is a colon-separated list of patterns.  It matches a +  // test if any pattern in it matches the test. +  return (MatchesFilter(full_name, positive.c_str()) && +          !MatchesFilter(full_name, negative.c_str())); +} + +#ifdef GTEST_OS_WINDOWS +// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the +// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. +// This function is useful as an __except condition. +int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { +  // Google Test should handle an exception if: +  //   1. the user wants it to, AND +  //   2. this is not a breakpoint exception. +  return (GTEST_FLAG(catch_exceptions) && +          exception_code != EXCEPTION_BREAKPOINT) ? +      EXCEPTION_EXECUTE_HANDLER : +      EXCEPTION_CONTINUE_SEARCH; +} +#endif  // GTEST_OS_WINDOWS + +}  // namespace internal + +// The interface for printing the result of a UnitTest +class UnitTestEventListenerInterface { + public: +  // The d'tor is pure virtual as this is an abstract class. +  virtual ~UnitTestEventListenerInterface() = 0; + +  // Called before the unit test starts. +  virtual void OnUnitTestStart(const UnitTest*) {} + +  // Called after the unit test ends. +  virtual void OnUnitTestEnd(const UnitTest*) {} + +  // Called before the test case starts. +  virtual void OnTestCaseStart(const TestCase*) {} + +  // Called after the test case ends. +  virtual void OnTestCaseEnd(const TestCase*) {} + +  // Called before the global set-up starts. +  virtual void OnGlobalSetUpStart(const UnitTest*) {} + +  // Called after the global set-up ends. +  virtual void OnGlobalSetUpEnd(const UnitTest*) {} + +  // Called before the global tear-down starts. +  virtual void OnGlobalTearDownStart(const UnitTest*) {} + +  // Called after the global tear-down ends. +  virtual void OnGlobalTearDownEnd(const UnitTest*) {} + +  // Called before the test starts. +  virtual void OnTestStart(const TestInfo*) {} + +  // Called after the test ends. +  virtual void OnTestEnd(const TestInfo*) {} + +  // Called after an assertion. +  virtual void OnNewTestPartResult(const TestPartResult*) {} +}; + +// The c'tor sets this object as the test part result reporter used by +// Google Test.  The 'result' parameter specifies where to report the +// results. Intercepts only failures from the current thread. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( +    TestPartResultArray* result) +    : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), +      result_(result) { +  Init(); +} + +// The c'tor sets this object as the test part result reporter used by +// Google Test.  The 'result' parameter specifies where to report the +// results. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( +    InterceptMode intercept_mode, TestPartResultArray* result) +    : intercept_mode_(intercept_mode), +      result_(result) { +  Init(); +} + +void ScopedFakeTestPartResultReporter::Init() { +  internal::UnitTestImpl* const impl = UnitTest::GetInstance()->impl(); +  if (intercept_mode_ == INTERCEPT_ALL_THREADS) { +    old_reporter_ = impl->GetGlobalTestPartResultReporter(); +    impl->SetGlobalTestPartResultReporter(this); +  } else { +    old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); +    impl->SetTestPartResultReporterForCurrentThread(this); +  } +} + +// The d'tor restores the test part result reporter used by Google Test +// before. +ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { +  internal::UnitTestImpl* const impl = UnitTest::GetInstance()->impl(); +  if (intercept_mode_ == INTERCEPT_ALL_THREADS) { +    impl->SetGlobalTestPartResultReporter(old_reporter_); +  } else { +    impl->SetTestPartResultReporterForCurrentThread(old_reporter_); +  } +} + +// Increments the test part result count and remembers the result. +// This method is from the TestPartResultReporterInterface interface. +void ScopedFakeTestPartResultReporter::ReportTestPartResult( +    const TestPartResult& result) { +  result_->Append(result); +} + +namespace internal { + +// Returns the type ID of ::testing::Test.  We should always call this +// instead of GetTypeId< ::testing::Test>() to get the type ID of +// testing::Test.  This is to work around a suspected linker bug when +// using Google Test as a framework on Mac OS X.  The bug causes +// GetTypeId< ::testing::Test>() to return different values depending +// on whether the call is from the Google Test framework itself or +// from user test code.  GetTestTypeId() is guaranteed to always +// return the same value, as it always calls GetTypeId<>() from the +// gtest.cc, which is within the Google Test framework. +TypeId GetTestTypeId() { +  return GetTypeId<Test>(); +} + +// The value of GetTestTypeId() as seen from within the Google Test +// library.  This is solely for testing GetTestTypeId(). +extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); + +// This predicate-formatter checks that 'results' contains a test part +// failure of the given type and that the failure message contains the +// given substring. +AssertionResult HasOneFailure(const char* /* results_expr */, +                              const char* /* type_expr */, +                              const char* /* substr_expr */, +                              const TestPartResultArray& results, +                              TestPartResultType type, +                              const char* substr) { +  const String expected( +      type == TPRT_FATAL_FAILURE ? "1 fatal failure" : +      "1 non-fatal failure"); +  Message msg; +  if (results.size() != 1) { +    msg << "Expected: " << expected << "\n" +        << "  Actual: " << results.size() << " failures"; +    for (int i = 0; i < results.size(); i++) { +      msg << "\n" << results.GetTestPartResult(i); +    } +    return AssertionFailure(msg); +  } + +  const TestPartResult& r = results.GetTestPartResult(0); +  if (r.type() != type) { +    msg << "Expected: " << expected << "\n" +        << "  Actual:\n" +        << r; +    return AssertionFailure(msg); +  } + +  if (strstr(r.message(), substr) == NULL) { +    msg << "Expected: " << expected << " containing \"" +        << substr << "\"\n" +        << "  Actual:\n" +        << r; +    return AssertionFailure(msg); +  } + +  return AssertionSuccess(); +} + +// The constructor of SingleFailureChecker remembers where to look up +// test part results, what type of failure we expect, and what +// substring the failure message should contain. +SingleFailureChecker:: SingleFailureChecker( +    const TestPartResultArray* results, +    TestPartResultType type, +    const char* substr) +    : results_(results), +      type_(type), +      substr_(substr) {} + +// The destructor of SingleFailureChecker verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring.  If that's not the case, a +// non-fatal failure will be generated. +SingleFailureChecker::~SingleFailureChecker() { +  EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_.c_str()); +} + +DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( +    UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultGlobalTestPartResultReporter::ReportTestPartResult( +    const TestPartResult& result) { +  unit_test_->current_test_result()->AddTestPartResult(result); +  unit_test_->result_printer()->OnNewTestPartResult(&result); +} + +DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( +    UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( +    const TestPartResult& result) { +  unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); +} + +// Returns the global test part result reporter. +TestPartResultReporterInterface* +UnitTestImpl::GetGlobalTestPartResultReporter() { +  internal::MutexLock lock(&global_test_part_result_reporter_mutex_); +  return global_test_part_result_repoter_; +} + +// Sets the global test part result reporter. +void UnitTestImpl::SetGlobalTestPartResultReporter( +    TestPartResultReporterInterface* reporter) { +  internal::MutexLock lock(&global_test_part_result_reporter_mutex_); +  global_test_part_result_repoter_ = reporter; +} + +// Returns the test part result reporter for the current thread. +TestPartResultReporterInterface* +UnitTestImpl::GetTestPartResultReporterForCurrentThread() { +  return per_thread_test_part_result_reporter_.get(); +} + +// Sets the test part result reporter for the current thread. +void UnitTestImpl::SetTestPartResultReporterForCurrentThread( +    TestPartResultReporterInterface* reporter) { +  per_thread_test_part_result_reporter_.set(reporter); +} + +// Gets the number of successful test cases. +int UnitTestImpl::successful_test_case_count() const { +  return test_cases_.CountIf(TestCasePassed); +} + +// Gets the number of failed test cases. +int UnitTestImpl::failed_test_case_count() const { +  return test_cases_.CountIf(TestCaseFailed); +} + +// Gets the number of all test cases. +int UnitTestImpl::total_test_case_count() const { +  return test_cases_.size(); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTestImpl::test_case_to_run_count() const { +  return test_cases_.CountIf(ShouldRunTestCase); +} + +// Gets the number of successful tests. +int UnitTestImpl::successful_test_count() const { +  return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); +} + +// Gets the number of failed tests. +int UnitTestImpl::failed_test_count() const { +  return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); +} + +// Gets the number of disabled tests. +int UnitTestImpl::disabled_test_count() const { +  return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); +} + +// Gets the number of all tests. +int UnitTestImpl::total_test_count() const { +  return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); +} + +// Gets the number of tests that should run. +int UnitTestImpl::test_to_run_count() const { +  return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); +} + +// Returns the current OS stack trace as a String. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag.  The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// CurrentOsStackTraceExceptTop(1), Foo() will be included in the +// trace but Bar() and CurrentOsStackTraceExceptTop() won't. +String UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { +  (void)skip_count; +  return String(""); +} + +static TimeInMillis GetTimeInMillis() { +#ifdef _WIN32_WCE  // We are on Windows CE +  // Difference between 1970-01-01 and 1601-01-01 in miliseconds. +  // http://analogous.blogspot.com/2005/04/epoch.html +  const TimeInMillis kJavaEpochToWinFileTimeDelta = 11644473600000UL; +  const DWORD kTenthMicrosInMilliSecond = 10000; + +  SYSTEMTIME now_systime; +  FILETIME now_filetime; +  ULARGE_INTEGER now_int64; +  // TODO(kenton@google.com): Shouldn't this just use +  //   GetSystemTimeAsFileTime()? +  GetSystemTime(&now_systime); +  if (SystemTimeToFileTime(&now_systime, &now_filetime)) { +    now_int64.LowPart = now_filetime.dwLowDateTime; +    now_int64.HighPart = now_filetime.dwHighDateTime; +    now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - +      kJavaEpochToWinFileTimeDelta; +    return now_int64.QuadPart; +  } +  return 0; +#elif defined(GTEST_OS_WINDOWS) && !defined(GTEST_HAS_GETTIMEOFDAY) +  __timeb64 now; +#ifdef _MSC_VER +  // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 +  // (deprecated function) there. +  // TODO(kenton@google.com): Use GetTickCount()?  Or use +  //   SystemTimeToFileTime() +#pragma warning(push)          // Saves the current warning state. +#pragma warning(disable:4996)  // Temporarily disables warning 4996. +  _ftime64(&now); +#pragma warning(pop)           // Restores the warning state. +#else +  _ftime64(&now); +#endif  // _MSC_VER +  return static_cast<TimeInMillis>(now.time) * 1000 + now.millitm; +#elif defined(GTEST_HAS_GETTIMEOFDAY) +  struct timeval now; +  gettimeofday(&now, NULL); +  return static_cast<TimeInMillis>(now.tv_sec) * 1000 + now.tv_usec / 1000; +#else +#error "Don't know how to get the current time on your system." +#endif +} + +// Utilities + +// class String + +// Returns the input enclosed in double quotes if it's not NULL; +// otherwise returns "(null)".  For example, "\"Hello\"" is returned +// for input "Hello". +// +// This is useful for printing a C string in the syntax of a literal. +// +// Known issue: escape sequences are not handled yet. +String String::ShowCStringQuoted(const char* c_str) { +  return c_str ? String::Format("\"%s\"", c_str) : String("(null)"); +} + +// Copies at most length characters from str into a newly-allocated +// piece of memory of size length+1.  The memory is allocated with new[]. +// A terminating null byte is written to the memory, and a pointer to it +// is returned.  If str is NULL, NULL is returned. +static char* CloneString(const char* str, size_t length) { +  if (str == NULL) { +    return NULL; +  } else { +    char* const clone = new char[length + 1]; +    // MSVC 8 deprecates strncpy(), so we want to suppress warning +    // 4996 (deprecated function) there. +#ifdef GTEST_OS_WINDOWS  // We are on Windows. +#pragma warning(push)          // Saves the current warning state. +#pragma warning(disable:4996)  // Temporarily disables warning 4996. +    strncpy(clone, str, length); +#pragma warning(pop)           // Restores the warning state. +#else  // We are on Linux or Mac OS. +    strncpy(clone, str, length); +#endif  // GTEST_OS_WINDOWS +    clone[length] = '\0'; +    return clone; +  } +} + +// Clones a 0-terminated C string, allocating memory using new.  The +// caller is responsible for deleting[] the return value.  Returns the +// cloned string, or NULL if the input is NULL. +const char * String::CloneCString(const char* c_str) { +  return (c_str == NULL) ? +                    NULL : CloneString(c_str, strlen(c_str)); +} + +#ifdef _WIN32_WCE +// Creates a UTF-16 wide string from the given ANSI string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the wide string, or NULL if the +// input is NULL. +LPCWSTR String::AnsiToUtf16(const char* ansi) { +  if (!ansi) return NULL; +  const int length = strlen(ansi); +  const int unicode_length = +      MultiByteToWideChar(CP_ACP, 0, ansi, length, +                          NULL, 0); +  WCHAR* unicode = new WCHAR[unicode_length + 1]; +  MultiByteToWideChar(CP_ACP, 0, ansi, length, +                      unicode, unicode_length); +  unicode[unicode_length] = 0; +  return unicode; +} + +// Creates an ANSI string from the given wide string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the ANSI string, or NULL if the +// input is NULL. +const char* String::Utf16ToAnsi(LPCWSTR utf16_str)  { +  if (!utf16_str) return NULL; +  const int ansi_length = +      WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, +                          NULL, 0, NULL, NULL); +  char* ansi = new char[ansi_length + 1]; +  WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, +                      ansi, ansi_length, NULL, NULL); +  ansi[ansi_length] = 0; +  return ansi; +} + +#endif  // _WIN32_WCE + +// Compares two C strings.  Returns true iff they have the same content. +// +// Unlike strcmp(), this function can handle NULL argument(s).  A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CStringEquals(const char * lhs, const char * rhs) { +  if ( lhs == NULL ) return rhs == NULL; + +  if ( rhs == NULL ) return false; + +  return strcmp(lhs, rhs) == 0; +} + +#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +// Converts an array of wide chars to a narrow string using the UTF-8 +// encoding, and streams the result to the given Message object. +static void StreamWideCharsToMessage(const wchar_t* wstr, size_t len, +                                     Message* msg) { +  // TODO(wan): consider allowing a testing::String object to +  // contain '\0'.  This will make it behave more like std::string, +  // and will allow ToUtf8String() to return the correct encoding +  // for '\0' s.t. we can get rid of the conditional here (and in +  // several other places). +  for (size_t i = 0; i != len; ) {  // NOLINT +    if (wstr[i] != L'\0') { +      *msg << WideStringToUtf8(wstr + i, static_cast<int>(len - i)); +      while (i != len && wstr[i] != L'\0') +        i++; +    } else { +      *msg << '\0'; +      i++; +    } +  } +} + +#endif  // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +}  // namespace internal + +#if GTEST_HAS_STD_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::std::wstring& wstr) { +  internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); +  return *this; +} +#endif  // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::wstring& wstr) { +  internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); +  return *this; +} +#endif  // GTEST_HAS_GLOBAL_WSTRING + +namespace internal { + +// Formats a value to be used in a failure message. + +// For a char value, we print it as a C++ char literal and as an +// unsigned integer (both in decimal and in hexadecimal). +String FormatForFailureMessage(char ch) { +  const unsigned int ch_as_uint = ch; +  // A String object cannot contain '\0', so we print "\\0" when ch is +  // '\0'. +  return String::Format("'%s' (%u, 0x%X)", +                        ch ? String::Format("%c", ch).c_str() : "\\0", +                        ch_as_uint, ch_as_uint); +} + +// For a wchar_t value, we print it as a C++ wchar_t literal and as an +// unsigned integer (both in decimal and in hexidecimal). +String FormatForFailureMessage(wchar_t wchar) { +  // The C++ standard doesn't specify the exact size of the wchar_t +  // type.  It just says that it shall have the same size as another +  // integral type, called its underlying type. +  // +  // Therefore, in order to print a wchar_t value in the numeric form, +  // we first convert it to the largest integral type (UInt64) and +  // then print the converted value. +  // +  // We use streaming to print the value as "%llu" doesn't work +  // correctly with MSVC 7.1. +  const UInt64 wchar_as_uint64 = wchar; +  Message msg; +  // A String object cannot contain '\0', so we print "\\0" when wchar is +  // L'\0'. +  char buffer[32];  // CodePointToUtf8 requires a buffer that big. +  msg << "L'" +      << (wchar ? CodePointToUtf8(static_cast<UInt32>(wchar), buffer) : "\\0") +      << "' (" << wchar_as_uint64 << ", 0x" << ::std::setbase(16) +      << wchar_as_uint64 << ")"; +  return msg.GetString(); +} + +}  // namespace internal + +// AssertionResult constructor. +AssertionResult::AssertionResult(const internal::String& failure_message) +    : failure_message_(failure_message) { +} + + +// Makes a successful assertion result. +AssertionResult AssertionSuccess() { +  return AssertionResult(); +} + + +// Makes a failed assertion result with the given failure message. +AssertionResult AssertionFailure(const Message& message) { +  return AssertionResult(message.GetString()); +} + +namespace internal { + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings.  For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +//   expected_expression: "foo" +//   actual_expression:   "bar" +//   expected_value:      "5" +//   actual_value:        "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*.  When it's true, the string " (ignoring case)" will +// be inserted into the message. +AssertionResult EqFailure(const char* expected_expression, +                          const char* actual_expression, +                          const String& expected_value, +                          const String& actual_value, +                          bool ignoring_case) { +  Message msg; +  msg << "Value of: " << actual_expression; +  if (actual_value != actual_expression) { +    msg << "\n  Actual: " << actual_value; +  } + +  msg << "\nExpected: " << expected_expression; +  if (ignoring_case) { +    msg << " (ignoring case)"; +  } +  if (expected_value != expected_expression) { +    msg << "\nWhich is: " << expected_value; +  } + +  return AssertionFailure(msg); +} + + +// Helper function for implementing ASSERT_NEAR. +AssertionResult DoubleNearPredFormat(const char* expr1, +                                     const char* expr2, +                                     const char* abs_error_expr, +                                     double val1, +                                     double val2, +                                     double abs_error) { +  const double diff = fabs(val1 - val2); +  if (diff <= abs_error) return AssertionSuccess(); + +  // TODO(wan): do not print the value of an expression if it's +  // already a literal. +  Message msg; +  msg << "The difference between " << expr1 << " and " << expr2 +      << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" +      << expr1 << " evaluates to " << val1 << ",\n" +      << expr2 << " evaluates to " << val2 << ", and\n" +      << abs_error_expr << " evaluates to " << abs_error << "."; +  return AssertionFailure(msg); +} + + +// Helper template for implementing FloatLE() and DoubleLE(). +template <typename RawType> +AssertionResult FloatingPointLE(const char* expr1, +                                const char* expr2, +                                RawType val1, +                                RawType val2) { +  // Returns success if val1 is less than val2, +  if (val1 < val2) { +    return AssertionSuccess(); +  } + +  // or if val1 is almost equal to val2. +  const FloatingPoint<RawType> lhs(val1), rhs(val2); +  if (lhs.AlmostEquals(rhs)) { +    return AssertionSuccess(); +  } + +  // Note that the above two checks will both fail if either val1 or +  // val2 is NaN, as the IEEE floating-point standard requires that +  // any predicate involving a NaN must return false. + +  StrStream val1_ss; +  val1_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) +          << val1; + +  StrStream val2_ss; +  val2_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) +          << val2; + +  Message msg; +  msg << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" +      << "  Actual: " << StrStreamToString(&val1_ss) << " vs " +      << StrStreamToString(&val2_ss); + +  return AssertionFailure(msg); +} + +}  // namespace internal + +// Asserts that val1 is less than, or almost equal to, val2.  Fails +// otherwise.  In particular, it fails if either val1 or val2 is NaN. +AssertionResult FloatLE(const char* expr1, const char* expr2, +                        float val1, float val2) { +  return internal::FloatingPointLE<float>(expr1, expr2, val1, val2); +} + +// Asserts that val1 is less than, or almost equal to, val2.  Fails +// otherwise.  In particular, it fails if either val1 or val2 is NaN. +AssertionResult DoubleLE(const char* expr1, const char* expr2, +                         double val1, double val2) { +  return internal::FloatingPointLE<double>(expr1, expr2, val1, val2); +} + +namespace internal { + +// The helper function for {ASSERT|EXPECT}_EQ with int or enum +// arguments. +AssertionResult CmpHelperEQ(const char* expected_expression, +                            const char* actual_expression, +                            BiggestInt expected, +                            BiggestInt actual) { +  if (expected == actual) { +    return AssertionSuccess(); +  } + +  return EqFailure(expected_expression, +                   actual_expression, +                   FormatForComparisonFailureMessage(expected, actual), +                   FormatForComparisonFailureMessage(actual, expected), +                   false); +} + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_?? with integer or enum arguments.  It is here +// just to avoid copy-and-paste of similar code. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ +                                   BiggestInt val1, BiggestInt val2) {\ +  if (val1 op val2) {\ +    return AssertionSuccess();\ +  } else {\ +    Message msg;\ +    msg << "Expected: (" << expr1 << ") " #op " (" << expr2\ +        << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ +        << " vs " << FormatForComparisonFailureMessage(val2, val1);\ +    return AssertionFailure(msg);\ +  }\ +} + +// Implements the helper function for {ASSERT|EXPECT}_NE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(NE, !=) +// Implements the helper function for {ASSERT|EXPECT}_LE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LE, <=) +// Implements the helper function for {ASSERT|EXPECT}_LT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LT, < ) +// Implements the helper function for {ASSERT|EXPECT}_GE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GE, >=) +// Implements the helper function for {ASSERT|EXPECT}_GT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GT, > ) + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +AssertionResult CmpHelperSTREQ(const char* expected_expression, +                               const char* actual_expression, +                               const char* expected, +                               const char* actual) { +  if (String::CStringEquals(expected, actual)) { +    return AssertionSuccess(); +  } + +  return EqFailure(expected_expression, +                   actual_expression, +                   String::ShowCStringQuoted(expected), +                   String::ShowCStringQuoted(actual), +                   false); +} + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, +                                   const char* actual_expression, +                                   const char* expected, +                                   const char* actual) { +  if (String::CaseInsensitiveCStringEquals(expected, actual)) { +    return AssertionSuccess(); +  } + +  return EqFailure(expected_expression, +                   actual_expression, +                   String::ShowCStringQuoted(expected), +                   String::ShowCStringQuoted(actual), +                   true); +} + +// The helper function for {ASSERT|EXPECT}_STRNE. +AssertionResult CmpHelperSTRNE(const char* s1_expression, +                               const char* s2_expression, +                               const char* s1, +                               const char* s2) { +  if (!String::CStringEquals(s1, s2)) { +    return AssertionSuccess(); +  } else { +    Message msg; +    msg << "Expected: (" << s1_expression << ") != (" +        << s2_expression << "), actual: \"" +        << s1 << "\" vs \"" << s2 << "\""; +    return AssertionFailure(msg); +  } +} + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +AssertionResult CmpHelperSTRCASENE(const char* s1_expression, +                                   const char* s2_expression, +                                   const char* s1, +                                   const char* s2) { +  if (!String::CaseInsensitiveCStringEquals(s1, s2)) { +    return AssertionSuccess(); +  } else { +    Message msg; +    msg << "Expected: (" << s1_expression << ") != (" +        << s2_expression << ") (ignoring case), actual: \"" +        << s1 << "\" vs \"" << s2 << "\""; +    return AssertionFailure(msg); +  } +} + +}  // namespace internal + +namespace { + +// Helper functions for implementing IsSubString() and IsNotSubstring(). + +// This group of overloaded functions return true iff needle is a +// substring of haystack.  NULL is considered a substring of itself +// only. + +bool IsSubstringPred(const char* needle, const char* haystack) { +  if (needle == NULL || haystack == NULL) +    return needle == haystack; + +  return strstr(haystack, needle) != NULL; +} + +bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { +  if (needle == NULL || haystack == NULL) +    return needle == haystack; + +  return wcsstr(haystack, needle) != NULL; +} + +// StringType here can be either ::std::string or ::std::wstring. +template <typename StringType> +bool IsSubstringPred(const StringType& needle, +                     const StringType& haystack) { +  return haystack.find(needle) != StringType::npos; +} + +// This function implements either IsSubstring() or IsNotSubstring(), +// depending on the value of the expected_to_be_substring parameter. +// StringType here can be const char*, const wchar_t*, ::std::string, +// or ::std::wstring. +template <typename StringType> +AssertionResult IsSubstringImpl( +    bool expected_to_be_substring, +    const char* needle_expr, const char* haystack_expr, +    const StringType& needle, const StringType& haystack) { +  if (IsSubstringPred(needle, haystack) == expected_to_be_substring) +    return AssertionSuccess(); + +  const bool is_wide_string = sizeof(needle[0]) > 1; +  const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; +  return AssertionFailure( +      Message() +      << "Value of: " << needle_expr << "\n" +      << "  Actual: " << begin_string_quote << needle << "\"\n" +      << "Expected: " << (expected_to_be_substring ? "" : "not ") +      << "a substring of " << haystack_expr << "\n" +      << "Which is: " << begin_string_quote << haystack << "\""); +} + +}  // namespace + +// IsSubstring() and IsNotSubstring() check whether needle is a +// substring of haystack (NULL is considered a substring of itself +// only), and return an appropriate error message when they fail. + +AssertionResult IsSubstring( +    const char* needle_expr, const char* haystack_expr, +    const char* needle, const char* haystack) { +  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( +    const char* needle_expr, const char* haystack_expr, +    const wchar_t* needle, const wchar_t* haystack) { +  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( +    const char* needle_expr, const char* haystack_expr, +    const char* needle, const char* haystack) { +  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( +    const char* needle_expr, const char* haystack_expr, +    const wchar_t* needle, const wchar_t* haystack) { +  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +#if GTEST_HAS_STD_STRING +AssertionResult IsSubstring( +    const char* needle_expr, const char* haystack_expr, +    const ::std::string& needle, const ::std::string& haystack) { +  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( +    const char* needle_expr, const char* haystack_expr, +    const ::std::string& needle, const ::std::string& haystack) { +  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} +#endif  // GTEST_HAS_STD_STRING + +#if GTEST_HAS_STD_WSTRING +AssertionResult IsSubstring( +    const char* needle_expr, const char* haystack_expr, +    const ::std::wstring& needle, const ::std::wstring& haystack) { +  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( +    const char* needle_expr, const char* haystack_expr, +    const ::std::wstring& needle, const ::std::wstring& haystack) { +  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} +#endif  // GTEST_HAS_STD_WSTRING + +namespace internal { + +#ifdef GTEST_OS_WINDOWS + +namespace { + +// Helper function for IsHRESULT{SuccessFailure} predicates +AssertionResult HRESULTFailureHelper(const char* expr, +                                     const char* expected, +                                     long hr) {  // NOLINT +#ifdef _WIN32_WCE +  // Windows CE doesn't support FormatMessage. +  const char error_text[] = ""; +#else +  // Looks up the human-readable system message for the HRESULT code +  // and since we're not passing any params to FormatMessage, we don't +  // want inserts expanded. +  const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | +                       FORMAT_MESSAGE_IGNORE_INSERTS; +  const DWORD kBufSize = 4096;  // String::Format can't exceed this length. +  // Gets the system's human readable message string for this HRESULT. +  char error_text[kBufSize] = { '\0' }; +  DWORD message_length = ::FormatMessageA(kFlags, +                                          0,  // no source, we're asking system +                                          hr,  // the error +                                          0,  // no line width restrictions +                                          error_text,  // output buffer +                                          kBufSize,  // buf size +                                          NULL);  // no arguments for inserts +  // Trims tailing white space (FormatMessage leaves a trailing cr-lf) +  for (; message_length && isspace(error_text[message_length - 1]); +          --message_length) { +    error_text[message_length - 1] = '\0'; +  } +#endif  // _WIN32_WCE + +  const String error_hex(String::Format("0x%08X ", hr)); +  Message msg; +  msg << "Expected: " << expr << " " << expected << ".\n" +      << "  Actual: " << error_hex << error_text << "\n"; + +  return ::testing::AssertionFailure(msg); +} + +}  // namespace + +AssertionResult IsHRESULTSuccess(const char* expr, long hr) {  // NOLINT +  if (SUCCEEDED(hr)) { +    return AssertionSuccess(); +  } +  return HRESULTFailureHelper(expr, "succeeds", hr); +} + +AssertionResult IsHRESULTFailure(const char* expr, long hr) {  // NOLINT +  if (FAILED(hr)) { +    return AssertionSuccess(); +  } +  return HRESULTFailureHelper(expr, "fails", hr); +} + +#endif  // GTEST_OS_WINDOWS + +// Utility functions for encoding Unicode text (wide strings) in +// UTF-8. + +// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 +// like this: +// +// Code-point length   Encoding +//   0 -  7 bits       0xxxxxxx +//   8 - 11 bits       110xxxxx 10xxxxxx +//  12 - 16 bits       1110xxxx 10xxxxxx 10xxxxxx +//  17 - 21 bits       11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + +// The maximum code-point a one-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint1 = (static_cast<UInt32>(1) <<  7) - 1; + +// The maximum code-point a two-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint2 = (static_cast<UInt32>(1) << (5 + 6)) - 1; + +// The maximum code-point a three-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint3 = (static_cast<UInt32>(1) << (4 + 2*6)) - 1; + +// The maximum code-point a four-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint4 = (static_cast<UInt32>(1) << (3 + 3*6)) - 1; + +// Chops off the n lowest bits from a bit pattern.  Returns the n +// lowest bits.  As a side effect, the original bit pattern will be +// shifted to the right by n bits. +inline UInt32 ChopLowBits(UInt32* bits, int n) { +  const UInt32 low_bits = *bits & ((static_cast<UInt32>(1) << n) - 1); +  *bits >>= n; +  return low_bits; +} + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// The output buffer str must containt at least 32 characters. +// The function returns the address of the output buffer. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. +char* CodePointToUtf8(UInt32 code_point, char* str) { +  if (code_point <= kMaxCodePoint1) { +    str[1] = '\0'; +    str[0] = static_cast<char>(code_point);                          // 0xxxxxxx +  } else if (code_point <= kMaxCodePoint2) { +    str[2] = '\0'; +    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx +    str[0] = static_cast<char>(0xC0 | code_point);                   // 110xxxxx +  } else if (code_point <= kMaxCodePoint3) { +    str[3] = '\0'; +    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx +    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx +    str[0] = static_cast<char>(0xE0 | code_point);                   // 1110xxxx +  } else if (code_point <= kMaxCodePoint4) { +    str[4] = '\0'; +    str[3] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx +    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx +    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx +    str[0] = static_cast<char>(0xF0 | code_point);                   // 11110xxx +  } else { +    // The longest string String::Format can produce when invoked +    // with these parameters is 28 character long (not including +    // the terminating nul character). We are asking for 32 character +    // buffer just in case. This is also enough for strncpy to +    // null-terminate the destination string. +    // MSVC 8 deprecates strncpy(), so we want to suppress warning +    // 4996 (deprecated function) there. +#ifdef GTEST_OS_WINDOWS  // We are on Windows. +#pragma warning(push)          // Saves the current warning state. +#pragma warning(disable:4996)  // Temporarily disables warning 4996. +#endif +    strncpy(str, String::Format("(Invalid Unicode 0x%X)", code_point).c_str(), +            32); +#ifdef GTEST_OS_WINDOWS  // We are on Windows. +#pragma warning(pop)           // Restores the warning state. +#endif +    str[31] = '\0';  // Makes sure no change in the format to strncpy leaves +                     // the result unterminated. +  } +  return str; +} + +// The following two functions only make sense if the the system +// uses UTF-16 for wide string encoding. All supported systems +// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16. + +// Determines if the arguments constitute UTF-16 surrogate pair +// and thus should be combined into a single Unicode code point +// using CreateCodePointFromUtf16SurrogatePair. +inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { +  if (sizeof(wchar_t) == 2) +    return (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; +  else +    return false; +} + +// Creates a Unicode code point from UTF16 surrogate pair. +inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, +                                                    wchar_t second) { +  if (sizeof(wchar_t) == 2) { +    const UInt32 mask = (1 << 10) - 1; +    return (((first & mask) << 10) | (second & mask)) + 0x10000; +  } else { +    // This should not be called, but we provide a sensible default +    // in case it is. +    return static_cast<UInt32>(first); +  } +} + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +//   UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +String WideStringToUtf8(const wchar_t* str, int num_chars) { +  if (num_chars == -1) +    num_chars = static_cast<int>(wcslen(str)); + +  StrStream stream; +  for (int i = 0; i < num_chars; ++i) { +    UInt32 unicode_code_point; + +    if (str[i] == L'\0') { +      break; +    } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { +      unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], +                                                                 str[i + 1]); +      i++; +    } else { +      unicode_code_point = static_cast<UInt32>(str[i]); +    } + +    char buffer[32];  // CodePointToUtf8 requires a buffer this big. +    stream << CodePointToUtf8(unicode_code_point, buffer); +  } +  return StrStreamToString(&stream); +} + +// Converts a wide C string to a String using the UTF-8 encoding. +// NULL will be converted to "(null)". +String String::ShowWideCString(const wchar_t * wide_c_str) { +  if (wide_c_str == NULL) return String("(null)"); + +  return String(internal::WideStringToUtf8(wide_c_str, -1).c_str()); +} + +// Similar to ShowWideCString(), except that this function encloses +// the converted string in double quotes. +String String::ShowWideCStringQuoted(const wchar_t* wide_c_str) { +  if (wide_c_str == NULL) return String("(null)"); + +  return String::Format("L\"%s\"", +                        String::ShowWideCString(wide_c_str).c_str()); +} + +// Compares two wide C strings.  Returns true iff they have the same +// content. +// +// Unlike wcscmp(), this function can handle NULL argument(s).  A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { +  if (lhs == NULL) return rhs == NULL; + +  if (rhs == NULL) return false; + +  return wcscmp(lhs, rhs) == 0; +} + +// Helper function for *_STREQ on wide strings. +AssertionResult CmpHelperSTREQ(const char* expected_expression, +                               const char* actual_expression, +                               const wchar_t* expected, +                               const wchar_t* actual) { +  if (String::WideCStringEquals(expected, actual)) { +    return AssertionSuccess(); +  } + +  return EqFailure(expected_expression, +                   actual_expression, +                   String::ShowWideCStringQuoted(expected), +                   String::ShowWideCStringQuoted(actual), +                   false); +} + +// Helper function for *_STRNE on wide strings. +AssertionResult CmpHelperSTRNE(const char* s1_expression, +                               const char* s2_expression, +                               const wchar_t* s1, +                               const wchar_t* s2) { +  if (!String::WideCStringEquals(s1, s2)) { +    return AssertionSuccess(); +  } + +  Message msg; +  msg << "Expected: (" << s1_expression << ") != (" +      << s2_expression << "), actual: " +      << String::ShowWideCStringQuoted(s1) +      << " vs " << String::ShowWideCStringQuoted(s2); +  return AssertionFailure(msg); +} + +// Compares two C strings, ignoring case.  Returns true iff they have +// the same content. +// +// Unlike strcasecmp(), this function can handle NULL argument(s).  A +// NULL C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { +  if ( lhs == NULL ) return rhs == NULL; + +  if ( rhs == NULL ) return false; + +#ifdef GTEST_OS_WINDOWS +  return _stricmp(lhs, rhs) == 0; +#else  // GTEST_OS_WINDOWS +  return strcasecmp(lhs, rhs) == 0; +#endif  // GTEST_OS_WINDOWS +} + +  // Compares two wide C strings, ignoring case.  Returns true iff they +  // have the same content. +  // +  // Unlike wcscasecmp(), this function can handle NULL argument(s). +  // A NULL C string is considered different to any non-NULL wide C string, +  // including the empty string. +  // NB: The implementations on different platforms slightly differ. +  // On windows, this method uses _wcsicmp which compares according to LC_CTYPE +  // environment variable. On GNU platform this method uses wcscasecmp +  // which compares according to LC_CTYPE category of the current locale. +  // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the +  // current locale. +bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, +                                              const wchar_t* rhs) { +  if ( lhs == NULL ) return rhs == NULL; + +  if ( rhs == NULL ) return false; + +#ifdef GTEST_OS_WINDOWS +  return _wcsicmp(lhs, rhs) == 0; +#elif defined(GTEST_OS_LINUX) +  return wcscasecmp(lhs, rhs) == 0; +#else +  // Mac OS X and Cygwin don't define wcscasecmp.  Other unknown OSes +  // may not define it either. +  wint_t left, right; +  do { +    left = towlower(*lhs++); +    right = towlower(*rhs++); +  } while (left && left == right); +  return left == right; +#endif // OS selector +} + +// Constructs a String by copying a given number of chars from a +// buffer.  E.g. String("hello", 3) will create the string "hel". +String::String(const char * buffer, size_t len) { +  char * const temp = new char[ len + 1 ]; +  memcpy(temp, buffer, len); +  temp[ len ] = '\0'; +  c_str_ = temp; +} + +// Compares this with another String. +// Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0 +// if this is greater than rhs. +int String::Compare(const String & rhs) const { +  if ( c_str_ == NULL ) { +    return rhs.c_str_ == NULL ? 0 : -1;  // NULL < anything except NULL +  } + +  return rhs.c_str_ == NULL ? 1 : strcmp(c_str_, rhs.c_str_); +} + +// Returns true iff this String ends with the given suffix.  *Any* +// String is considered to end with a NULL or empty suffix. +bool String::EndsWith(const char* suffix) const { +  if (suffix == NULL || CStringEquals(suffix, "")) return true; + +  if (c_str_ == NULL) return false; + +  const size_t this_len = strlen(c_str_); +  const size_t suffix_len = strlen(suffix); +  return (this_len >= suffix_len) && +         CStringEquals(c_str_ + this_len - suffix_len, suffix); +} + +// Returns true iff this String ends with the given suffix, ignoring case. +// Any String is considered to end with a NULL or empty suffix. +bool String::EndsWithCaseInsensitive(const char* suffix) const { +  if (suffix == NULL || CStringEquals(suffix, "")) return true; + +  if (c_str_ == NULL) return false; + +  const size_t this_len = strlen(c_str_); +  const size_t suffix_len = strlen(suffix); +  return (this_len >= suffix_len) && +         CaseInsensitiveCStringEquals(c_str_ + this_len - suffix_len, suffix); +} + +// 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 String::Set(const char * c_str, size_t length) { +  // Makes sure this works when c_str == c_str_ +  const char* const temp = CloneString(c_str, length); +  delete[] c_str_; +  c_str_ = temp; +} + +// Assigns a C string to this object.  Self-assignment works. +const String& String::operator=(const char* c_str) { +  // Makes sure this works when c_str == c_str_ +  if (c_str != c_str_) { +    delete[] c_str_; +    c_str_ = CloneCString(c_str); +  } +  return *this; +} + +// Formats a list of arguments to a String, using the same format +// spec string as for printf. +// +// We do not use the StringPrintf class as it is not universally +// available. +// +// The result is limited to 4096 characters (including the tailing 0). +// If 4096 characters are not enough to format the input, +// "<buffer exceeded>" is returned. +String String::Format(const char * format, ...) { +  va_list args; +  va_start(args, format); + +  char buffer[4096]; +  // MSVC 8 deprecates vsnprintf(), so we want to suppress warning +  // 4996 (deprecated function) there. +#ifdef GTEST_OS_WINDOWS  // We are on Windows. +#pragma warning(push)          // Saves the current warning state. +#pragma warning(disable:4996)  // Temporarily disables warning 4996. +  const int size = +    vsnprintf(buffer, sizeof(buffer)/sizeof(buffer[0]) - 1, format, args); +#pragma warning(pop)           // Restores the warning state. +#else  // We are on Linux or Mac OS. +  const int size = +    vsnprintf(buffer, sizeof(buffer)/sizeof(buffer[0]) - 1, format, args); +#endif  // GTEST_OS_WINDOWS +  va_end(args); + +  return String(size >= 0 ? buffer : "<buffer exceeded>"); +} + +// Converts the buffer in a StrStream to a String, converting NUL +// bytes to "\\0" along the way. +String StrStreamToString(StrStream* ss) { +#if GTEST_HAS_STD_STRING +  const ::std::string& str = ss->str(); +  const char* const start = str.c_str(); +  const char* const end = start + str.length(); +#else +  const char* const start = ss->str(); +  const char* const end = start + ss->pcount(); +#endif  // GTEST_HAS_STD_STRING + +  // We need to use a helper StrStream to do this transformation +  // because String doesn't support push_back(). +  StrStream helper; +  for (const char* ch = start; ch != end; ++ch) { +    if (*ch == '\0') { +      helper << "\\0";  // Replaces NUL with "\\0"; +    } else { +      helper.put(*ch); +    } +  } + +#if GTEST_HAS_STD_STRING +  return String(helper.str().c_str()); +#else +  const String str(helper.str(), helper.pcount()); +  helper.freeze(false); +  ss->freeze(false); +  return str; +#endif  // GTEST_HAS_STD_STRING +} + +// Appends the user-supplied message to the Google-Test-generated message. +String AppendUserMessage(const String& gtest_msg, +                         const Message& user_msg) { +  // Appends the user message if it's non-empty. +  const String user_msg_string = user_msg.GetString(); +  if (user_msg_string.empty()) { +    return gtest_msg; +  } + +  Message msg; +  msg << gtest_msg << "\n" << user_msg_string; + +  return msg.GetString(); +} + +// class TestResult + +// Creates an empty TestResult. +TestResult::TestResult() +    : death_test_count_(0), +      elapsed_time_(0) { +} + +// D'tor. +TestResult::~TestResult() { +} + +// Adds a test part result to the list. +void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { +  test_part_results_.PushBack(test_part_result); +} + +// Adds a test property to the list. If a property with the same key as the +// supplied property is already represented, the value of this test_property +// replaces the old value for that key. +void TestResult::RecordProperty(const TestProperty& test_property) { +  if (!ValidateTestProperty(test_property)) { +    return; +  } +  MutexLock lock(&test_properites_mutex_); +  ListNode<TestProperty>* const node_with_matching_key = +      test_properties_.FindIf(TestPropertyKeyIs(test_property.key())); +  if (node_with_matching_key == NULL) { +    test_properties_.PushBack(test_property); +    return; +  } +  TestProperty& property_with_matching_key = node_with_matching_key->element(); +  property_with_matching_key.SetValue(test_property.value()); +} + +// Adds a failure if the key is a reserved attribute of Google Test +// testcase tags.  Returns true if the property is valid. +bool TestResult::ValidateTestProperty(const TestProperty& test_property) { +  String key(test_property.key()); +  if (key == "name" || key == "status" || key == "time" || key == "classname") { +    ADD_FAILURE() +        << "Reserved key used in RecordProperty(): " +        << key +        << " ('name', 'status', 'time', and 'classname' are reserved by " +        << GTEST_NAME << ")"; +    return false; +  } +  return true; +} + +// Clears the object. +void TestResult::Clear() { +  test_part_results_.Clear(); +  test_properties_.Clear(); +  death_test_count_ = 0; +  elapsed_time_ = 0; +} + +// Returns true iff the test part passed. +static bool TestPartPassed(const TestPartResult & result) { +  return result.passed(); +} + +// Gets the number of successful test parts. +int TestResult::successful_part_count() const { +  return test_part_results_.CountIf(TestPartPassed); +} + +// Returns true iff the test part failed. +static bool TestPartFailed(const TestPartResult & result) { +  return result.failed(); +} + +// Gets the number of failed test parts. +int TestResult::failed_part_count() const { +  return test_part_results_.CountIf(TestPartFailed); +} + +// Returns true iff the test part fatally failed. +static bool TestPartFatallyFailed(const TestPartResult & result) { +  return result.fatally_failed(); +} + +// Returns true iff the test fatally failed. +bool TestResult::HasFatalFailure() const { +  return test_part_results_.CountIf(TestPartFatallyFailed) > 0; +} + +// 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 TestResult::total_part_count() const { +  return test_part_results_.size(); +} + +}  // namespace internal + +// class Test + +// Creates a Test object. + +// The c'tor saves the values of all Google Test flags. +Test::Test() +    : gtest_flag_saver_(new internal::GTestFlagSaver) { +} + +// The d'tor restores the values of all Google Test flags. +Test::~Test() { +  delete gtest_flag_saver_; +} + +// Sets up the test fixture. +// +// A sub-class may override this. +void Test::SetUp() { +} + +// Tears down the test fixture. +// +// A sub-class may override this. +void Test::TearDown() { +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const char* key, const char* value) { +  UnitTest::GetInstance()->RecordPropertyForCurrentTest(key, value); +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const char* key, int value) { +  Message value_message; +  value_message << value; +  RecordProperty(key, value_message.GetString().c_str()); +} + +#ifdef GTEST_OS_WINDOWS +// We are on Windows. + +// Adds an "exception thrown" fatal failure to the current test. +static void AddExceptionThrownFailure(DWORD exception_code, +                                      const char* location) { +  Message message; +  message << "Exception thrown with code 0x" << std::setbase(16) << +    exception_code << std::setbase(10) << " in " << location << "."; + +  UnitTest* const unit_test = UnitTest::GetInstance(); +  unit_test->AddTestPartResult( +      TPRT_FATAL_FAILURE, +      static_cast<const char *>(NULL), +           // We have no info about the source file where the exception +           // occurred. +      -1,  // We have no info on which line caused the exception. +      message.GetString(), +      internal::String("")); +} + +#endif  // GTEST_OS_WINDOWS + +// Google Test requires all tests in the same test case to use the same test +// fixture class.  This function checks if the current test has the +// same fixture class as the first test in the current test case.  If +// yes, it returns true; otherwise it generates a Google Test failure and +// returns false. +bool Test::HasSameFixtureClass() { +  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); +  const TestCase* const test_case = impl->current_test_case(); + +  // Info about the first test in the current test case. +  const internal::TestInfoImpl* const first_test_info = +      test_case->test_info_list().Head()->element()->impl(); +  const internal::TypeId first_fixture_id = first_test_info->fixture_class_id(); +  const char* const first_test_name = first_test_info->name(); + +  // Info about the current test. +  const internal::TestInfoImpl* const this_test_info = +      impl->current_test_info()->impl(); +  const internal::TypeId this_fixture_id = this_test_info->fixture_class_id(); +  const char* const this_test_name = this_test_info->name(); + +  if (this_fixture_id != first_fixture_id) { +    // Is the first test defined using TEST? +    const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); +    // Is this test defined using TEST? +    const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); + +    if (first_is_TEST || this_is_TEST) { +      // The user mixed TEST and TEST_F in this test case - we'll tell +      // him/her how to fix it. + +      // Gets the name of the TEST and the name of the TEST_F.  Note +      // that first_is_TEST and this_is_TEST cannot both be true, as +      // the fixture IDs are different for the two tests. +      const char* const TEST_name = +          first_is_TEST ? first_test_name : this_test_name; +      const char* const TEST_F_name = +          first_is_TEST ? this_test_name : first_test_name; + +      ADD_FAILURE() +          << "All tests in the same test case must use the same test fixture\n" +          << "class, so mixing TEST_F and TEST in the same test case is\n" +          << "illegal.  In test case " << this_test_info->test_case_name() +          << ",\n" +          << "test " << TEST_F_name << " is defined using TEST_F but\n" +          << "test " << TEST_name << " is defined using TEST.  You probably\n" +          << "want to change the TEST to TEST_F or move it to another test\n" +          << "case."; +    } else { +      // The user defined two fixture classes with the same name in +      // two namespaces - we'll tell him/her how to fix it. +      ADD_FAILURE() +          << "All tests in the same test case must use the same test fixture\n" +          << "class.  However, in test case " +          << this_test_info->test_case_name() << ",\n" +          << "you defined test " << first_test_name +          << " and test " << this_test_name << "\n" +          << "using two different test fixture classes.  This can happen if\n" +          << "the two classes are from different namespaces or translation\n" +          << "units and have the same name.  You should probably rename one\n" +          << "of the classes to put the tests into different test cases."; +    } +    return false; +  } + +  return true; +} + +// Runs the test and updates the test result. +void Test::Run() { +  if (!HasSameFixtureClass()) return; + +  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); +#ifdef GTEST_OS_WINDOWS +  // We are on Windows. +  impl->os_stack_trace_getter()->UponLeavingGTest(); +  __try { +    SetUp(); +  } __except(internal::UnitTestOptions::GTestShouldProcessSEH( +      GetExceptionCode())) { +    AddExceptionThrownFailure(GetExceptionCode(), "SetUp()"); +  } + +  // We will run the test only if SetUp() had no fatal failure. +  if (!HasFatalFailure()) { +    impl->os_stack_trace_getter()->UponLeavingGTest(); +    __try { +      TestBody(); +    } __except(internal::UnitTestOptions::GTestShouldProcessSEH( +        GetExceptionCode())) { +      AddExceptionThrownFailure(GetExceptionCode(), "the test body"); +    } +  } + +  // However, we want to clean up as much as possible.  Hence we will +  // always call TearDown(), even if SetUp() or the test body has +  // failed. +  impl->os_stack_trace_getter()->UponLeavingGTest(); +  __try { +    TearDown(); +  } __except(internal::UnitTestOptions::GTestShouldProcessSEH( +      GetExceptionCode())) { +    AddExceptionThrownFailure(GetExceptionCode(), "TearDown()"); +  } + +#else  // We are on Linux or Mac - exceptions are disabled. +  impl->os_stack_trace_getter()->UponLeavingGTest(); +  SetUp(); + +  // We will run the test only if SetUp() was successful. +  if (!HasFatalFailure()) { +    impl->os_stack_trace_getter()->UponLeavingGTest(); +    TestBody(); +  } + +  // However, we want to clean up as much as possible.  Hence we will +  // always call TearDown(), even if SetUp() or the test body has +  // failed. +  impl->os_stack_trace_getter()->UponLeavingGTest(); +  TearDown(); +#endif  // GTEST_OS_WINDOWS +} + + +// Returns true iff the current test has a fatal failure. +bool Test::HasFatalFailure() { +  return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); +} + +// class TestInfo + +// Constructs a TestInfo object. It assumes ownership of the test factory +// object via impl_. +TestInfo::TestInfo(const char* test_case_name, +                   const char* name, +                   const char* test_case_comment, +                   const char* comment, +                   internal::TypeId fixture_class_id, +                   internal::TestFactoryBase* factory) { +  impl_ = new internal::TestInfoImpl(this, test_case_name, name, +                                     test_case_comment, comment, +                                     fixture_class_id, factory); +} + +// Destructs a TestInfo object. +TestInfo::~TestInfo() { +  delete impl_; +} + +namespace internal { + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +//   test_case_name:   name of the test case +//   name:             name of the test +//   test_case_comment: a comment on the test case that will be included in +//                      the test output +//   comment:          a comment on the test that will be included in the +//                     test output +//   fixture_class_id: ID of the test fixture class +//   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 +//   factory:          pointer to the factory that creates a test object. +//                     The newly created TestInfo instance will assume +//                     ownership of the factory object. +TestInfo* MakeAndRegisterTestInfo( +    const char* test_case_name, const char* name, +    const char* test_case_comment, const char* comment, +    TypeId fixture_class_id, +    SetUpTestCaseFunc set_up_tc, +    TearDownTestCaseFunc tear_down_tc, +    TestFactoryBase* factory) { +  TestInfo* const test_info = +      new TestInfo(test_case_name, name, test_case_comment, comment, +                   fixture_class_id, factory); +  GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); +  return test_info; +} + +#ifdef GTEST_HAS_PARAM_TEST +void ReportInvalidTestCaseType(const char* test_case_name, +                               const char* file, int line) { +  Message errors; +  errors +      << "Attempted redefinition of test case " << test_case_name << ".\n" +      << "All tests in the same test case must use the same test fixture\n" +      << "class.  However, in test case " << test_case_name << ", you tried\n" +      << "to define a test using a fixture class different from the one\n" +      << "used earlier. This can happen if the two fixture classes are\n" +      << "from different namespaces and have the same name. You should\n" +      << "probably rename one of the classes to put the tests into different\n" +      << "test cases."; + +  fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), +          errors.GetString().c_str()); +} +#endif  // GTEST_HAS_PARAM_TEST + +}  // namespace internal + +// Returns the test case name. +const char* TestInfo::test_case_name() const { +  return impl_->test_case_name(); +} + +// Returns the test name. +const char* TestInfo::name() const { +  return impl_->name(); +} + +// Returns the test case comment. +const char* TestInfo::test_case_comment() const { +  return impl_->test_case_comment(); +} + +// Returns the test comment. +const char* TestInfo::comment() const { +  return impl_->comment(); +} + +// Returns true if this test should run. +bool TestInfo::should_run() const { return impl_->should_run(); } + +// Returns the result of the test. +const internal::TestResult* TestInfo::result() const { return impl_->result(); } + +// Increments the number of death tests encountered in this test so +// far. +int TestInfo::increment_death_test_count() { +  return impl_->result()->increment_death_test_count(); +} + +namespace { + +// A predicate that checks the test name of a TestInfo against a known +// value. +// +// This is used for implementation of the TestCase class only.  We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestNameIs is copyable. +class TestNameIs { + public: +  // Constructor. +  // +  // TestNameIs has NO default constructor. +  explicit TestNameIs(const char* name) +      : name_(name) {} + +  // Returns true iff the test name of test_info matches name_. +  bool operator()(const TestInfo * test_info) const { +    return test_info && internal::String(test_info->name()).Compare(name_) == 0; +  } + + private: +  internal::String name_; +}; + +}  // namespace + +// Finds and returns a TestInfo with the given name.  If one doesn't +// exist, returns NULL. +TestInfo * TestCase::GetTestInfo(const char* test_name) { +  // Can we find a TestInfo with the given name? +  internal::ListNode<TestInfo *> * const node = test_info_list_->FindIf( +      TestNameIs(test_name)); + +  // Returns the TestInfo found. +  return node ? node->element() : NULL; +} + +namespace internal { + +// This method expands all parameterized tests registered with macros TEST_P +// and INSTANTIATE_TEST_CASE_P into regular tests and registers those. +// This will be done just once during the program runtime. +void UnitTestImpl::RegisterParameterizedTests() { +#ifdef GTEST_HAS_PARAM_TEST +  if (!parameterized_tests_registered_) { +    parameterized_test_registry_.RegisterTests(); +    parameterized_tests_registered_ = true; +  } +#endif +} + +// Creates the test object, runs it, records its result, and then +// deletes it. +void TestInfoImpl::Run() { +  if (!should_run_) return; + +  // Tells UnitTest where to store test result. +  UnitTestImpl* const impl = internal::GetUnitTestImpl(); +  impl->set_current_test_info(parent_); + +  // Notifies the unit test event listener that a test is about to +  // start. +  UnitTestEventListenerInterface* const result_printer = +    impl->result_printer(); +  result_printer->OnTestStart(parent_); + +  const TimeInMillis start = GetTimeInMillis(); + +  impl->os_stack_trace_getter()->UponLeavingGTest(); +#ifdef GTEST_OS_WINDOWS +  // We are on Windows. +  Test* test = NULL; + +  __try { +    // Creates the test object. +    test = factory_->CreateTest(); +  } __except(internal::UnitTestOptions::GTestShouldProcessSEH( +      GetExceptionCode())) { +    AddExceptionThrownFailure(GetExceptionCode(), +                              "the test fixture's constructor"); +    return; +  } +#else  // We are on Linux or Mac OS - exceptions are disabled. + +  // TODO(wan): If test->Run() throws, test won't be deleted.  This is +  // not a problem now as we don't use exceptions.  If we were to +  // enable exceptions, we should revise the following to be +  // exception-safe. + +  // Creates the test object. +  Test* test = factory_->CreateTest(); +#endif  // GTEST_OS_WINDOWS + +  // Runs the test only if the constructor of the test fixture didn't +  // generate a fatal failure. +  if (!Test::HasFatalFailure()) { +    test->Run(); +  } + +  // Deletes the test object. +  impl->os_stack_trace_getter()->UponLeavingGTest(); +  delete test; +  test = NULL; + +  result_.set_elapsed_time(GetTimeInMillis() - start); + +  // Notifies the unit test event listener that a test has just finished. +  result_printer->OnTestEnd(parent_); + +  // Tells UnitTest to stop associating assertion results to this +  // test. +  impl->set_current_test_info(NULL); +} + +}  // namespace internal + +// class TestCase + +// Gets the number of successful tests in this test case. +int TestCase::successful_test_count() const { +  return test_info_list_->CountIf(TestPassed); +} + +// Gets the number of failed tests in this test case. +int TestCase::failed_test_count() const { +  return test_info_list_->CountIf(TestFailed); +} + +int TestCase::disabled_test_count() const { +  return test_info_list_->CountIf(TestDisabled); +} + +// Get the number of tests in this test case that should run. +int TestCase::test_to_run_count() const { +  return test_info_list_->CountIf(ShouldRunTest); +} + +// Gets the number of all tests. +int TestCase::total_test_count() const { +  return test_info_list_->size(); +} + +// Creates a TestCase with the given name. +// +// 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::TestCase(const char* name, const char* comment, +                   Test::SetUpTestCaseFunc set_up_tc, +                   Test::TearDownTestCaseFunc tear_down_tc) +    : name_(name), +      comment_(comment), +      set_up_tc_(set_up_tc), +      tear_down_tc_(tear_down_tc), +      should_run_(false), +      elapsed_time_(0) { +  test_info_list_ = new internal::List<TestInfo *>; +} + +// Destructor of TestCase. +TestCase::~TestCase() { +  // Deletes every Test in the collection. +  test_info_list_->ForEach(internal::Delete<TestInfo>); + +  // Then deletes the Test collection. +  delete test_info_list_; +  test_info_list_ = NULL; +} + +// Adds a test to this test case.  Will delete the test upon +// destruction of the TestCase object. +void TestCase::AddTestInfo(TestInfo * test_info) { +  test_info_list_->PushBack(test_info); +} + +// Runs every test in this TestCase. +void TestCase::Run() { +  if (!should_run_) return; + +  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); +  impl->set_current_test_case(this); + +  UnitTestEventListenerInterface * const result_printer = +      impl->result_printer(); + +  result_printer->OnTestCaseStart(this); +  impl->os_stack_trace_getter()->UponLeavingGTest(); +  set_up_tc_(); + +  const internal::TimeInMillis start = internal::GetTimeInMillis(); +  test_info_list_->ForEach(internal::TestInfoImpl::RunTest); +  elapsed_time_ = internal::GetTimeInMillis() - start; + +  impl->os_stack_trace_getter()->UponLeavingGTest(); +  tear_down_tc_(); +  result_printer->OnTestCaseEnd(this); +  impl->set_current_test_case(NULL); +} + +// Clears the results of all tests in this test case. +void TestCase::ClearResult() { +  test_info_list_->ForEach(internal::TestInfoImpl::ClearTestResult); +} + + +// class UnitTestEventListenerInterface + +// The virtual d'tor. +UnitTestEventListenerInterface::~UnitTestEventListenerInterface() { +} + +// A result printer that never prints anything.  Used in the child process +// of an exec-style death test to avoid needless output clutter. +class NullUnitTestResultPrinter : public UnitTestEventListenerInterface {}; + +// Formats a countable noun.  Depending on its quantity, either the +// singular form or the plural form is used. e.g. +// +// FormatCountableNoun(1, "formula", "formuli") returns "1 formula". +// FormatCountableNoun(5, "book", "books") returns "5 books". +static internal::String FormatCountableNoun(int count, +                                            const char * singular_form, +                                            const char * plural_form) { +  return internal::String::Format("%d %s", count, +                                  count == 1 ? singular_form : plural_form); +} + +// Formats the count of tests. +static internal::String FormatTestCount(int test_count) { +  return FormatCountableNoun(test_count, "test", "tests"); +} + +// Formats the count of test cases. +static internal::String FormatTestCaseCount(int test_case_count) { +  return FormatCountableNoun(test_case_count, "test case", "test cases"); +} + +// Converts a TestPartResultType enum to human-friendly string +// representation.  Both TPRT_NONFATAL_FAILURE and TPRT_FATAL_FAILURE +// are translated to "Failure", as the user usually doesn't care about +// the difference between the two when viewing the test result. +static const char * TestPartResultTypeToString(TestPartResultType type) { +  switch (type) { +    case TPRT_SUCCESS: +      return "Success"; + +    case TPRT_NONFATAL_FAILURE: +    case TPRT_FATAL_FAILURE: +#ifdef _MSC_VER +      return "error: "; +#else +      return "Failure\n"; +#endif +  } + +  return "Unknown result type"; +} + +// Prints a TestPartResult. +static void PrintTestPartResult( +    const TestPartResult & test_part_result) { +  printf("%s %s%s\n", +         internal::FormatFileLocation(test_part_result.file_name(), +                                      test_part_result.line_number()).c_str(), +         TestPartResultTypeToString(test_part_result.type()), +         test_part_result.message()); +  fflush(stdout); +} + +// class PrettyUnitTestResultPrinter + +namespace internal { + +enum GTestColor { +  COLOR_RED, +  COLOR_GREEN, +  COLOR_YELLOW +}; + +#if defined(GTEST_OS_WINDOWS) && !defined(_WIN32_WCE) + +// Returns the character attribute for the given color. +WORD GetColorAttribute(GTestColor color) { +  switch (color) { +    case COLOR_RED:    return FOREGROUND_RED; +    case COLOR_GREEN:  return FOREGROUND_GREEN; +    case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; +  } +  return 0; +} + +#else + +// Returns the ANSI color code for the given color. +const char* GetAnsiColorCode(GTestColor color) { +  switch (color) { +    case COLOR_RED:     return "1"; +    case COLOR_GREEN:   return "2"; +    case COLOR_YELLOW:  return "3"; +  }; +  return NULL; +} + +#endif  // GTEST_OS_WINDOWS && !_WIN32_WCE + +// Returns true iff Google Test should use colors in the output. +bool ShouldUseColor(bool stdout_is_tty) { +  const char* const gtest_color = GTEST_FLAG(color).c_str(); + +  if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { +#ifdef GTEST_OS_WINDOWS +    // On Windows the TERM variable is usually not set, but the +    // console there does support colors. +    return stdout_is_tty; +#else +    // On non-Windows platforms, we rely on the TERM variable. +    const char* const term = GetEnv("TERM"); +    const bool term_supports_color = +        String::CStringEquals(term, "xterm") || +        String::CStringEquals(term, "xterm-color") || +        String::CStringEquals(term, "cygwin"); +    return stdout_is_tty && term_supports_color; +#endif  // GTEST_OS_WINDOWS +  } + +  return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || +      String::CaseInsensitiveCStringEquals(gtest_color, "true") || +      String::CaseInsensitiveCStringEquals(gtest_color, "t") || +      String::CStringEquals(gtest_color, "1"); +  // We take "yes", "true", "t", and "1" as meaning "yes".  If the +  // value is neither one of these nor "auto", we treat it as "no" to +  // be conservative. +} + +// Helpers for printing colored strings to stdout. Note that on Windows, we +// cannot simply emit special characters and have the terminal change colors. +// This routine must actually emit the characters rather than return a string +// that would be colored when printed, as can be done on Linux. +void ColoredPrintf(GTestColor color, const char* fmt, ...) { +  va_list args; +  va_start(args, fmt); + +#if defined(_WIN32_WCE) || defined(GTEST_OS_SYMBIAN) || defined(GTEST_OS_ZOS) +  static const bool use_color = false; +#else +  static const bool use_color = ShouldUseColor(isatty(fileno(stdout)) != 0); +#endif  // !_WIN32_WCE +  // The '!= 0' comparison is necessary to satisfy MSVC 7.1. + +  if (!use_color) { +    vprintf(fmt, args); +    va_end(args); +    return; +  } + +#if defined(GTEST_OS_WINDOWS) && !defined(_WIN32_WCE) +  const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); + +  // Gets the current text color. +  CONSOLE_SCREEN_BUFFER_INFO buffer_info; +  GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); +  const WORD old_color_attrs = buffer_info.wAttributes; + +  SetConsoleTextAttribute(stdout_handle, +                          GetColorAttribute(color) | FOREGROUND_INTENSITY); +  vprintf(fmt, args); + +  // Restores the text color. +  SetConsoleTextAttribute(stdout_handle, old_color_attrs); +#else +  printf("\033[0;3%sm", GetAnsiColorCode(color)); +  vprintf(fmt, args); +  printf("\033[m");  // Resets the terminal to default. +#endif  // GTEST_OS_WINDOWS && !_WIN32_WCE +  va_end(args); +} + +}  // namespace internal + +using internal::ColoredPrintf; +using internal::COLOR_RED; +using internal::COLOR_GREEN; +using internal::COLOR_YELLOW; + +// This class implements the UnitTestEventListenerInterface interface. +// +// Class PrettyUnitTestResultPrinter is copyable. +class PrettyUnitTestResultPrinter : public UnitTestEventListenerInterface { + public: +  PrettyUnitTestResultPrinter() {} +  static void PrintTestName(const char * test_case, const char * test) { +    printf("%s.%s", test_case, test); +  } + +  // The following methods override what's in the +  // UnitTestEventListenerInterface class. +  virtual void OnUnitTestStart(const UnitTest * unit_test); +  virtual void OnGlobalSetUpStart(const UnitTest*); +  virtual void OnTestCaseStart(const TestCase * test_case); +  virtual void OnTestCaseEnd(const TestCase * test_case); +  virtual void OnTestStart(const TestInfo * test_info); +  virtual void OnNewTestPartResult(const TestPartResult * result); +  virtual void OnTestEnd(const TestInfo * test_info); +  virtual void OnGlobalTearDownStart(const UnitTest*); +  virtual void OnUnitTestEnd(const UnitTest * unit_test); + + private: +  internal::String test_case_name_; +}; + +// Called before the unit test starts. +void PrettyUnitTestResultPrinter::OnUnitTestStart( +    const UnitTest * unit_test) { +  const char * const filter = GTEST_FLAG(filter).c_str(); + +  // Prints the filter if it's not *.  This reminds the user that some +  // tests may be skipped. +  if (!internal::String::CStringEquals(filter, kUniversalFilter)) { +    ColoredPrintf(COLOR_YELLOW, +                  "Note: %s filter = %s\n", GTEST_NAME, filter); +  } + +  const internal::UnitTestImpl* const impl = unit_test->impl(); +  ColoredPrintf(COLOR_GREEN,  "[==========] "); +  printf("Running %s from %s.\n", +         FormatTestCount(impl->test_to_run_count()).c_str(), +         FormatTestCaseCount(impl->test_case_to_run_count()).c_str()); +  fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnGlobalSetUpStart(const UnitTest*) { +  ColoredPrintf(COLOR_GREEN,  "[----------] "); +  printf("Global test environment set-up.\n"); +  fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseStart( +    const TestCase * test_case) { +  test_case_name_ = test_case->name(); +  const internal::String counts = +      FormatCountableNoun(test_case->test_to_run_count(), "test", "tests"); +  ColoredPrintf(COLOR_GREEN, "[----------] "); +  printf("%s from %s", counts.c_str(), test_case_name_.c_str()); +  if (test_case->comment()[0] == '\0') { +    printf("\n"); +  } else { +    printf(", where %s\n", test_case->comment()); +  } +  fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseEnd( +    const TestCase * test_case) { +  if (!GTEST_FLAG(print_time)) return; + +  test_case_name_ = test_case->name(); +  const internal::String counts = +      FormatCountableNoun(test_case->test_to_run_count(), "test", "tests"); +  ColoredPrintf(COLOR_GREEN, "[----------] "); +  printf("%s from %s (%s ms total)\n\n", +         counts.c_str(), test_case_name_.c_str(), +         internal::StreamableToString(test_case->elapsed_time()).c_str()); +  fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo * test_info) { +  ColoredPrintf(COLOR_GREEN,  "[ RUN      ] "); +  PrintTestName(test_case_name_.c_str(), test_info->name()); +  if (test_info->comment()[0] == '\0') { +    printf("\n"); +  } else { +    printf(", where %s\n", test_info->comment()); +  } +  fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo * test_info) { +  if (test_info->result()->Passed()) { +    ColoredPrintf(COLOR_GREEN, "[       OK ] "); +  } else { +    ColoredPrintf(COLOR_RED, "[  FAILED  ] "); +  } +  PrintTestName(test_case_name_.c_str(), test_info->name()); +  if (GTEST_FLAG(print_time)) { +    printf(" (%s ms)\n", internal::StreamableToString( +           test_info->result()->elapsed_time()).c_str()); +  } else { +    printf("\n"); +  } +  fflush(stdout); +} + +// Called after an assertion failure. +void PrettyUnitTestResultPrinter::OnNewTestPartResult( +    const TestPartResult * result) { +  // If the test part succeeded, we don't need to do anything. +  if (result->type() == TPRT_SUCCESS) +    return; + +  // Print failure message from the assertion (e.g. expected this and got that). +  PrintTestPartResult(*result); +  fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnGlobalTearDownStart(const UnitTest*) { +  ColoredPrintf(COLOR_GREEN,  "[----------] "); +  printf("Global test environment tear-down\n"); +  fflush(stdout); +} + +namespace internal { + +// Internal helper for printing the list of failed tests. +static void PrintFailedTestsPretty(const UnitTestImpl* impl) { +  const int failed_test_count = impl->failed_test_count(); +  if (failed_test_count == 0) { +    return; +  } + +  for (const internal::ListNode<TestCase*>* node = impl->test_cases()->Head(); +       node != NULL; node = node->next()) { +    const TestCase* const tc = node->element(); +    if (!tc->should_run() || (tc->failed_test_count() == 0)) { +      continue; +    } +    for (const internal::ListNode<TestInfo*>* tinode = +         tc->test_info_list().Head(); +         tinode != NULL; tinode = tinode->next()) { +      const TestInfo* const ti = tinode->element(); +      if (!tc->ShouldRunTest(ti) || tc->TestPassed(ti)) { +        continue; +      } +      ColoredPrintf(COLOR_RED, "[  FAILED  ] "); +      printf("%s.%s", ti->test_case_name(), ti->name()); +      if (ti->test_case_comment()[0] != '\0' || +          ti->comment()[0] != '\0') { +        printf(", where %s", ti->test_case_comment()); +        if (ti->test_case_comment()[0] != '\0' && +            ti->comment()[0] != '\0') { +          printf(" and "); +        } +      } +      printf("%s\n", ti->comment()); +    } +  } +} + +}  // namespace internal + +void PrettyUnitTestResultPrinter::OnUnitTestEnd( +    const UnitTest * unit_test) { +  const internal::UnitTestImpl* const impl = unit_test->impl(); + +  ColoredPrintf(COLOR_GREEN,  "[==========] "); +  printf("%s from %s ran.", +         FormatTestCount(impl->test_to_run_count()).c_str(), +         FormatTestCaseCount(impl->test_case_to_run_count()).c_str()); +  if (GTEST_FLAG(print_time)) { +    printf(" (%s ms total)", +           internal::StreamableToString(impl->elapsed_time()).c_str()); +  } +  printf("\n"); +  ColoredPrintf(COLOR_GREEN,  "[  PASSED  ] "); +  printf("%s.\n", FormatTestCount(impl->successful_test_count()).c_str()); + +  int num_failures = impl->failed_test_count(); +  if (!impl->Passed()) { +    const int failed_test_count = impl->failed_test_count(); +    ColoredPrintf(COLOR_RED,  "[  FAILED  ] "); +    printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); +    internal::PrintFailedTestsPretty(impl); +    printf("\n%2d FAILED %s\n", num_failures, +                        num_failures == 1 ? "TEST" : "TESTS"); +  } + +  int num_disabled = impl->disabled_test_count(); +  if (num_disabled) { +    if (!num_failures) { +      printf("\n");  // Add a spacer if no FAILURE banner is displayed. +    } +    ColoredPrintf(COLOR_YELLOW, +                  "  YOU HAVE %d DISABLED %s\n\n", +                  num_disabled, +                  num_disabled == 1 ? "TEST" : "TESTS"); +  } +  // Ensure that Google Test output is printed before, e.g., heapchecker output. +  fflush(stdout); +} + +// End PrettyUnitTestResultPrinter + +// class UnitTestEventsRepeater +// +// This class forwards events to other event listeners. +class UnitTestEventsRepeater : public UnitTestEventListenerInterface { + public: +  typedef internal::List<UnitTestEventListenerInterface *> Listeners; +  typedef internal::ListNode<UnitTestEventListenerInterface *> ListenersNode; +  UnitTestEventsRepeater() {} +  virtual ~UnitTestEventsRepeater(); +  void AddListener(UnitTestEventListenerInterface *listener); + +  virtual void OnUnitTestStart(const UnitTest* unit_test); +  virtual void OnUnitTestEnd(const UnitTest* unit_test); +  virtual void OnGlobalSetUpStart(const UnitTest* unit_test); +  virtual void OnGlobalSetUpEnd(const UnitTest* unit_test); +  virtual void OnGlobalTearDownStart(const UnitTest* unit_test); +  virtual void OnGlobalTearDownEnd(const UnitTest* unit_test); +  virtual void OnTestCaseStart(const TestCase* test_case); +  virtual void OnTestCaseEnd(const TestCase* test_case); +  virtual void OnTestStart(const TestInfo* test_info); +  virtual void OnTestEnd(const TestInfo* test_info); +  virtual void OnNewTestPartResult(const TestPartResult* result); + + private: +  Listeners listeners_; + +  GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestEventsRepeater); +}; + +UnitTestEventsRepeater::~UnitTestEventsRepeater() { +  for (ListenersNode* listener = listeners_.Head(); +       listener != NULL; +       listener = listener->next()) { +    delete listener->element(); +  } +} + +void UnitTestEventsRepeater::AddListener( +    UnitTestEventListenerInterface *listener) { +  listeners_.PushBack(listener); +} + +// Since the methods are identical, use a macro to reduce boilerplate. +// This defines a member that repeats the call to all listeners. +#define GTEST_REPEATER_METHOD_(Name, Type) \ +void UnitTestEventsRepeater::Name(const Type* parameter) { \ +  for (ListenersNode* listener = listeners_.Head(); \ +       listener != NULL; \ +       listener = listener->next()) { \ +    listener->element()->Name(parameter); \ +  } \ +} + +GTEST_REPEATER_METHOD_(OnUnitTestStart, UnitTest) +GTEST_REPEATER_METHOD_(OnUnitTestEnd, UnitTest) +GTEST_REPEATER_METHOD_(OnGlobalSetUpStart, UnitTest) +GTEST_REPEATER_METHOD_(OnGlobalSetUpEnd, UnitTest) +GTEST_REPEATER_METHOD_(OnGlobalTearDownStart, UnitTest) +GTEST_REPEATER_METHOD_(OnGlobalTearDownEnd, UnitTest) +GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase) +GTEST_REPEATER_METHOD_(OnTestCaseEnd, TestCase) +GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) +GTEST_REPEATER_METHOD_(OnTestEnd, TestInfo) +GTEST_REPEATER_METHOD_(OnNewTestPartResult, TestPartResult) + +#undef GTEST_REPEATER_METHOD_ + +// End PrettyUnitTestResultPrinter + +// This class generates an XML output file. +class XmlUnitTestResultPrinter : public UnitTestEventListenerInterface { + public: +  explicit XmlUnitTestResultPrinter(const char* output_file); + +  virtual void OnUnitTestEnd(const UnitTest* unit_test); + + private: +  // Is c a whitespace character that is normalized to a space character +  // when it appears in an XML attribute value? +  static bool IsNormalizableWhitespace(char c) { +    return c == 0x9 || c == 0xA || c == 0xD; +  } + +  // May c appear in a well-formed XML document? +  static bool IsValidXmlCharacter(char c) { +    return IsNormalizableWhitespace(c) || c >= 0x20; +  } + +  // Returns an XML-escaped copy of the input string str.  If +  // is_attribute is true, the text is meant to appear as an attribute +  // value, and normalizable whitespace is preserved by replacing it +  // with character references. +  static internal::String EscapeXml(const char* str, +                                    bool is_attribute); + +  // Convenience wrapper around EscapeXml when str is an attribute value. +  static internal::String EscapeXmlAttribute(const char* str) { +    return EscapeXml(str, true); +  } + +  // Convenience wrapper around EscapeXml when str is not an attribute value. +  static internal::String EscapeXmlText(const char* str) { +    return EscapeXml(str, false); +  } + +  // Prints an XML representation of a TestInfo object. +  static void PrintXmlTestInfo(FILE* out, +                               const char* test_case_name, +                               const TestInfo* test_info); + +  // Prints an XML representation of a TestCase object +  static void PrintXmlTestCase(FILE* out, const TestCase* test_case); + +  // Prints an XML summary of unit_test to output stream out. +  static void PrintXmlUnitTest(FILE* out, const UnitTest* unit_test); + +  // Produces a string representing the test properties in a result as space +  // delimited XML attributes based on the property key="value" pairs. +  // When the String is not empty, it includes a space at the beginning, +  // to delimit this attribute from prior attributes. +  static internal::String TestPropertiesAsXmlAttributes( +      const internal::TestResult* result); + +  // The output file. +  const internal::String output_file_; + +  GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); +}; + +// Creates a new XmlUnitTestResultPrinter. +XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) +    : output_file_(output_file) { +  if (output_file_.c_str() == NULL || output_file_.empty()) { +    fprintf(stderr, "XML output file may not be null\n"); +    fflush(stderr); +    exit(EXIT_FAILURE); +  } +} + +// Called after the unit test ends. +void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest* unit_test) { +  FILE* xmlout = NULL; +  internal::FilePath output_file(output_file_); +  internal::FilePath output_dir(output_file.RemoveFileName()); + +  if (output_dir.CreateDirectoriesRecursively()) { +  // MSVC 8 deprecates fopen(), so we want to suppress warning 4996 +  // (deprecated function) there. +#ifdef GTEST_OS_WINDOWS +  // We are on Windows. +#pragma warning(push)          // Saves the current warning state. +#pragma warning(disable:4996)  // Temporarily disables warning 4996. +    xmlout = fopen(output_file_.c_str(), "w"); +#pragma warning(pop)           // Restores the warning state. +#else  // We are on Linux or Mac OS. +    xmlout = fopen(output_file_.c_str(), "w"); +#endif  // GTEST_OS_WINDOWS +  } +  if (xmlout == NULL) { +    // TODO(wan): report the reason of the failure. +    // +    // We don't do it for now as: +    // +    //   1. There is no urgent need for it. +    //   2. It's a bit involved to make the errno variable thread-safe on +    //      all three operating systems (Linux, Windows, and Mac OS). +    //   3. To interpret the meaning of errno in a thread-safe way, +    //      we need the strerror_r() function, which is not available on +    //      Windows. +    fprintf(stderr, +            "Unable to open file \"%s\"\n", +            output_file_.c_str()); +    fflush(stderr); +    exit(EXIT_FAILURE); +  } +  PrintXmlUnitTest(xmlout, unit_test); +  fclose(xmlout); +} + +// Returns an XML-escaped copy of the input string str.  If is_attribute +// is true, the text is meant to appear as an attribute value, and +// normalizable whitespace is preserved by replacing it with character +// references. +// +// Invalid XML characters in str, if any, are stripped from the output. +// It is expected that most, if not all, of the text processed by this +// module will consist of ordinary English text. +// If this module is ever modified to produce version 1.1 XML output, +// most invalid characters can be retained using character references. +// TODO(wan): It might be nice to have a minimally invasive, human-readable +// escaping scheme for invalid characters, rather than dropping them. +internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str, +                                                     bool is_attribute) { +  Message m; + +  if (str != NULL) { +    for (const char* src = str; *src; ++src) { +      switch (*src) { +        case '<': +          m << "<"; +          break; +        case '>': +          m << ">"; +          break; +        case '&': +          m << "&"; +          break; +        case '\'': +          if (is_attribute) +            m << "'"; +          else +            m << '\''; +          break; +        case '"': +          if (is_attribute) +            m << """; +          else +            m << '"'; +          break; +        default: +          if (IsValidXmlCharacter(*src)) { +            if (is_attribute && IsNormalizableWhitespace(*src)) +              m << internal::String::Format("&#x%02X;", unsigned(*src)); +            else +              m << *src; +          } +          break; +      } +    } +  } + +  return m.GetString(); +} + + +// The following routines generate an XML representation of a UnitTest +// object. +// +// This is how Google Test concepts map to the DTD: +// +// <testsuite name="AllTests">         <-- corresponds to a UnitTest object +//   <testsuite name="testcase-name">  <-- corresponds to a TestCase object +//     <testcase name="test-name">     <-- corresponds to a TestInfo object +//       <failure message="...">...</failure> +//       <failure message="...">...</failure> +//       <failure message="...">...</failure> +//                                     <-- individual assertion failures +//     </testcase> +//   </testsuite> +// </testsuite> + +namespace internal { + +// Formats the given time in milliseconds as seconds.  The returned +// C-string is owned by this function and cannot be released by the +// caller.  Calling the function again invalidates the previous +// result. +const char* FormatTimeInMillisAsSeconds(TimeInMillis ms) { +  static String str; +  str = (Message() << (ms/1000.0)).GetString(); +  return str.c_str(); +} + +}  // namespace internal + +// Prints an XML representation of a TestInfo object. +// TODO(wan): There is also value in printing properties with the plain printer. +void XmlUnitTestResultPrinter::PrintXmlTestInfo(FILE* out, +                                                const char* test_case_name, +                                                const TestInfo* test_info) { +  const internal::TestResult * const result = test_info->result(); +  const internal::List<TestPartResult> &results = result->test_part_results(); +  fprintf(out, +          "    <testcase name=\"%s\" status=\"%s\" time=\"%s\" " +          "classname=\"%s\"%s", +          EscapeXmlAttribute(test_info->name()).c_str(), +          test_info->should_run() ? "run" : "notrun", +          internal::FormatTimeInMillisAsSeconds(result->elapsed_time()), +          EscapeXmlAttribute(test_case_name).c_str(), +          TestPropertiesAsXmlAttributes(result).c_str()); + +  int failures = 0; +  for (const internal::ListNode<TestPartResult>* part_node = results.Head(); +       part_node != NULL; +       part_node = part_node->next()) { +    const TestPartResult& part = part_node->element(); +    if (part.failed()) { +      const internal::String message = +          internal::String::Format("%s:%d\n%s", part.file_name(), +                                   part.line_number(), part.message()); +      if (++failures == 1) +        fprintf(out, ">\n"); +      fprintf(out, +              "      <failure message=\"%s\" type=\"\"><![CDATA[%s]]>" +              "</failure>\n", +              EscapeXmlAttribute(part.summary()).c_str(), message.c_str()); +    } +  } + +  if (failures == 0) +    fprintf(out, " />\n"); +  else +    fprintf(out, "    </testcase>\n"); +} + +// Prints an XML representation of a TestCase object +void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out, +                                                const TestCase* test_case) { +  fprintf(out, +          "  <testsuite name=\"%s\" tests=\"%d\" failures=\"%d\" " +          "disabled=\"%d\" ", +          EscapeXmlAttribute(test_case->name()).c_str(), +          test_case->total_test_count(), +          test_case->failed_test_count(), +          test_case->disabled_test_count()); +  fprintf(out, +          "errors=\"0\" time=\"%s\">\n", +          internal::FormatTimeInMillisAsSeconds(test_case->elapsed_time())); +  for (const internal::ListNode<TestInfo*>* info_node = +         test_case->test_info_list().Head(); +       info_node != NULL; +       info_node = info_node->next()) { +    PrintXmlTestInfo(out, test_case->name(), info_node->element()); +  } +  fprintf(out, "  </testsuite>\n"); +} + +// Prints an XML summary of unit_test to output stream out. +void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out, +                                                const UnitTest* unit_test) { +  const internal::UnitTestImpl* const impl = unit_test->impl(); +  fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); +  fprintf(out, +          "<testsuite tests=\"%d\" failures=\"%d\" disabled=\"%d\" " +          "errors=\"0\" time=\"%s\" ", +          impl->total_test_count(), +          impl->failed_test_count(), +          impl->disabled_test_count(), +          internal::FormatTimeInMillisAsSeconds(impl->elapsed_time())); +  fprintf(out, "name=\"AllTests\">\n"); +  for (const internal::ListNode<TestCase*>* case_node = +       impl->test_cases()->Head(); +       case_node != NULL; +       case_node = case_node->next()) { +    PrintXmlTestCase(out, case_node->element()); +  } +  fprintf(out, "</testsuite>\n"); +} + +// Produces a string representing the test properties in a result as space +// delimited XML attributes based on the property key="value" pairs. +internal::String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( +    const internal::TestResult* result) { +  using internal::TestProperty; +  Message attributes; +  const internal::List<TestProperty>& properties = result->test_properties(); +  for (const internal::ListNode<TestProperty>* property_node = +       properties.Head(); +       property_node != NULL; +       property_node = property_node->next()) { +    const TestProperty& property = property_node->element(); +    attributes << " " << property.key() << "=" +        << "\"" << EscapeXmlAttribute(property.value()) << "\""; +  } +  return attributes.GetString(); +} + +// End XmlUnitTestResultPrinter + +namespace internal { + +// Class ScopedTrace + +// Pushes the given source file location and message onto a per-thread +// trace stack maintained by Google Test. +// L < UnitTest::mutex_ +ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) { +  TraceInfo trace; +  trace.file = file; +  trace.line = line; +  trace.message = message.GetString(); + +  UnitTest::GetInstance()->PushGTestTrace(trace); +} + +// Pops the info pushed by the c'tor. +// L < UnitTest::mutex_ +ScopedTrace::~ScopedTrace() { +  UnitTest::GetInstance()->PopGTestTrace(); +} + + +// class OsStackTraceGetter + +// Returns the current OS stack trace as a String.  Parameters: +// +//   max_depth  - the maximum number of stack frames to be included +//                in the trace. +//   skip_count - the number of top frames to be skipped; doesn't count +//                against max_depth. +// +// L < mutex_ +// We use "L < mutex_" to denote that the function may acquire mutex_. +String OsStackTraceGetter::CurrentStackTrace(int, int) { +  return String(""); +} + +// L < mutex_ +void OsStackTraceGetter::UponLeavingGTest() { +} + +const char* const +OsStackTraceGetter::kElidedFramesMarker = +    "... " GTEST_NAME " internal frames ..."; + +}  // namespace internal + +// class UnitTest + +// Gets the singleton UnitTest object.  The first time this method is +// called, a UnitTest object is constructed and returned.  Consecutive +// calls will return the same object. +// +// We don't protect this under mutex_ as a user is not supposed to +// call this before main() starts, from which point on the return +// value will never change. +UnitTest * UnitTest::GetInstance() { +  // When compiled with MSVC 7.1 in optimized mode, destroying the +  // UnitTest object upon exiting the program messes up the exit code, +  // causing successful tests to appear failed.  We have to use a +  // different implementation in this case to bypass the compiler bug. +  // This implementation makes the compiler happy, at the cost of +  // leaking the UnitTest object. +#if _MSC_VER == 1310 && !defined(_DEBUG)  // MSVC 7.1 and optimized build. +  static UnitTest* const instance = new UnitTest; +  return instance; +#else +  static UnitTest instance; +  return &instance; +#endif  // _MSC_VER==1310 && !defined(_DEBUG) +} + +// Registers and returns a global test environment.  When a test +// program is run, all global test environments will be set-up in the +// order they were registered.  After all tests in the program have +// finished, all global test environments will be torn-down in the +// *reverse* order they were registered. +// +// The UnitTest object takes ownership of the given environment. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +Environment* UnitTest::AddEnvironment(Environment* env) { +  if (env == NULL) { +    return NULL; +  } + +  impl_->environments()->PushBack(env); +  impl_->environments_in_reverse_order()->PushFront(env); +  return env; +} + +// Adds a TestPartResult to the current TestResult object.  All Google Test +// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call +// this to report their results.  The user code should use the +// assertion macros instead of calling this directly. +// L < mutex_ +void UnitTest::AddTestPartResult(TestPartResultType result_type, +                                 const char* file_name, +                                 int line_number, +                                 const internal::String& message, +                                 const internal::String& os_stack_trace) { +  Message msg; +  msg << message; + +  internal::MutexLock lock(&mutex_); +  if (impl_->gtest_trace_stack()->size() > 0) { +    msg << "\n" << GTEST_NAME << " trace:"; + +    for (internal::ListNode<internal::TraceInfo>* node = +         impl_->gtest_trace_stack()->Head(); +         node != NULL; +         node = node->next()) { +      const internal::TraceInfo& trace = node->element(); +      msg << "\n" << trace.file << ":" << trace.line << ": " << trace.message; +    } +  } + +  if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { +    msg << internal::kStackTraceMarker << os_stack_trace; +  } + +  const TestPartResult result = +    TestPartResult(result_type, file_name, line_number, +                   msg.GetString().c_str()); +  impl_->GetTestPartResultReporterForCurrentThread()-> +      ReportTestPartResult(result); + +  // If this is a failure and the user wants the debugger to break on +  // failures ... +  if (result_type != TPRT_SUCCESS && GTEST_FLAG(break_on_failure)) { +    // ... then we generate a seg fault. +    *static_cast<int*>(NULL) = 1; +  } +} + +// Creates and adds a property to the current TestResult. If a property matching +// the supplied value already exists, updates its value instead. +void UnitTest::RecordPropertyForCurrentTest(const char* key, +                                            const char* value) { +  const internal::TestProperty test_property(key, value); +  impl_->current_test_result()->RecordProperty(test_property); +} + +// Runs all tests in this UnitTest object and prints the result. +// Returns 0 if successful, or 1 otherwise. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +int UnitTest::Run() { +#ifdef GTEST_OS_WINDOWS + +#if !defined(_WIN32_WCE) +  // SetErrorMode doesn't exist on CE. +  if (GTEST_FLAG(catch_exceptions)) { +    // The user wants Google Test to catch exceptions thrown by the tests. + +    // This lets fatal errors be handled by us, instead of causing pop-ups. +    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | +                 SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); +  } +#endif  // _WIN32_WCE + +  __try { +    return impl_->RunAllTests(); +  } __except(internal::UnitTestOptions::GTestShouldProcessSEH( +      GetExceptionCode())) { +    printf("Exception thrown with code 0x%x.\nFAIL\n", GetExceptionCode()); +    fflush(stdout); +    return 1; +  } + +#else +  // We are on Linux or Mac OS.  There is no exception of any kind. + +  return impl_->RunAllTests(); +#endif  // GTEST_OS_WINDOWS +} + +// Returns the working directory when the first TEST() or TEST_F() was +// executed. +const char* UnitTest::original_working_dir() const { +  return impl_->original_working_dir_.c_str(); +} + +// Returns the TestCase object for the test that's currently running, +// or NULL if no test is running. +// L < mutex_ +const TestCase* UnitTest::current_test_case() const { +  internal::MutexLock lock(&mutex_); +  return impl_->current_test_case(); +} + +// Returns the TestInfo object for the test that's currently running, +// or NULL if no test is running. +// L < mutex_ +const TestInfo* UnitTest::current_test_info() const { +  internal::MutexLock lock(&mutex_); +  return impl_->current_test_info(); +} + +#ifdef GTEST_HAS_PARAM_TEST +// Returns ParameterizedTestCaseRegistry object used to keep track of +// value-parameterized tests and instantiate and register them. +// L < mutex_ +internal::ParameterizedTestCaseRegistry& +    UnitTest::parameterized_test_registry() { +  return impl_->parameterized_test_registry(); +} +#endif  // GTEST_HAS_PARAM_TEST + +// Creates an empty UnitTest. +UnitTest::UnitTest() { +  impl_ = new internal::UnitTestImpl(this); +} + +// Destructor of UnitTest. +UnitTest::~UnitTest() { +  delete impl_; +} + +// Pushes a trace defined by SCOPED_TRACE() on to the per-thread +// Google Test trace stack. +// L < mutex_ +void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) { +  internal::MutexLock lock(&mutex_); +  impl_->gtest_trace_stack()->PushFront(trace); +} + +// Pops a trace from the per-thread Google Test trace stack. +// L < mutex_ +void UnitTest::PopGTestTrace() { +  internal::MutexLock lock(&mutex_); +  impl_->gtest_trace_stack()->PopFront(NULL); +} + +namespace internal { + +UnitTestImpl::UnitTestImpl(UnitTest* parent) +    : parent_(parent), +#ifdef _MSC_VER +#pragma warning(push)                    // Saves the current warning state. +#pragma warning(disable:4355)            // Temporarily disables warning 4355 +                                         // (using this in initializer). +      default_global_test_part_result_reporter_(this), +      default_per_thread_test_part_result_reporter_(this), +#pragma warning(pop)                     // Restores the warning state again. +#else +      default_global_test_part_result_reporter_(this), +      default_per_thread_test_part_result_reporter_(this), +#endif  // _MSC_VER +      global_test_part_result_repoter_( +          &default_global_test_part_result_reporter_), +      per_thread_test_part_result_reporter_( +          &default_per_thread_test_part_result_reporter_), +      test_cases_(), +#ifdef GTEST_HAS_PARAM_TEST +      parameterized_test_registry_(), +      parameterized_tests_registered_(false), +#endif  // GTEST_HAS_PARAM_TEST +      last_death_test_case_(NULL), +      current_test_case_(NULL), +      current_test_info_(NULL), +      ad_hoc_test_result_(), +      result_printer_(NULL), +      os_stack_trace_getter_(NULL), +#ifdef GTEST_HAS_DEATH_TEST +      elapsed_time_(0), +      internal_run_death_test_flag_(NULL), +      death_test_factory_(new DefaultDeathTestFactory) { +#else +      elapsed_time_(0) { +#endif  // GTEST_HAS_DEATH_TEST +} + +UnitTestImpl::~UnitTestImpl() { +  // Deletes every TestCase. +  test_cases_.ForEach(internal::Delete<TestCase>); + +  // Deletes every Environment. +  environments_.ForEach(internal::Delete<Environment>); + +  // Deletes the current test result printer. +  delete result_printer_; + +  delete os_stack_trace_getter_; +} + +// A predicate that checks the name of a TestCase against a known +// value. +// +// This is used for implementation of the UnitTest class only.  We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestCaseNameIs is copyable. +class TestCaseNameIs { + public: +  // Constructor. +  explicit TestCaseNameIs(const String& name) +      : name_(name) {} + +  // Returns true iff the name of test_case matches name_. +  bool operator()(const TestCase* test_case) const { +    return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; +  } + + private: +  String name_; +}; + +// Finds and returns a TestCase with the given name.  If one doesn't +// exist, creates one and returns it. +// +// Arguments: +// +//   test_case_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* UnitTestImpl::GetTestCase(const char* test_case_name, +                                    const char* comment, +                                    Test::SetUpTestCaseFunc set_up_tc, +                                    Test::TearDownTestCaseFunc tear_down_tc) { +  // Can we find a TestCase with the given name? +  internal::ListNode<TestCase*>* node = test_cases_.FindIf( +      TestCaseNameIs(test_case_name)); + +  if (node == NULL) { +    // No.  Let's create one. +    TestCase* const test_case = +      new TestCase(test_case_name, comment, set_up_tc, tear_down_tc); + +    // Is this a death test case? +    if (internal::UnitTestOptions::MatchesFilter(String(test_case_name), +                                                 kDeathTestCaseFilter)) { +      // Yes.  Inserts the test case after the last death test case +      // defined so far. +      node = test_cases_.InsertAfter(last_death_test_case_, test_case); +      last_death_test_case_ = node; +    } else { +      // No.  Appends to the end of the list. +      test_cases_.PushBack(test_case); +      node = test_cases_.Last(); +    } +  } + +  // Returns the TestCase found. +  return node->element(); +} + +// Helpers for setting up / tearing down the given environment.  They +// are for use in the List::ForEach() method. +static void SetUpEnvironment(Environment* env) { env->SetUp(); } +static void TearDownEnvironment(Environment* env) { env->TearDown(); } + +// Runs all tests in this UnitTest object, prints the result, and +// returns 0 if all tests are successful, or 1 otherwise.  If any +// exception is thrown during a test on Windows, this test is +// considered to be failed, but the rest of the tests will still be +// run.  (We disable exceptions on Linux and Mac OS X, so the issue +// doesn't apply there.) +// When parameterized tests are enabled, it explands and registers +// parameterized tests first in RegisterParameterizedTests(). +// All other functions called from RunAllTests() may safely assume that +// parameterized tests are ready to be counted and run. +int UnitTestImpl::RunAllTests() { +  // Makes sure InitGoogleTest() was called. +  if (!GTestIsInitialized()) { +    printf("%s", +           "\nThis test program did NOT call ::testing::InitGoogleTest " +           "before calling RUN_ALL_TESTS().  Please fix it.\n"); +    return 1; +  } + +  RegisterParameterizedTests(); + +  // Lists all the tests and exits if the --gtest_list_tests +  // flag was specified. +  if (GTEST_FLAG(list_tests)) { +    ListAllTests(); +    return 0; +  } + +  // True iff we are in a subprocess for running a thread-safe-style +  // death test. +  bool in_subprocess_for_death_test = false; + +#ifdef GTEST_HAS_DEATH_TEST +  internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); +  in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); +#endif  // GTEST_HAS_DEATH_TEST + +  UnitTestEventListenerInterface * const printer = result_printer(); + +  // Compares the full test names with the filter to decide which +  // tests to run. +  const bool has_tests_to_run = FilterTests() > 0; +  // True iff at least one test has failed. +  bool failed = false; + +  // How many times to repeat the tests?  We don't want to repeat them +  // when we are inside the subprocess of a death test. +  const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); +  // Repeats forever if the repeat count is negative. +  const bool forever = repeat < 0; +  for (int i = 0; forever || i != repeat; i++) { +    if (repeat != 1) { +      printf("\nRepeating all tests (iteration %d) . . .\n\n", i + 1); +    } + +    // Tells the unit test event listener that the tests are about to +    // start. +    printer->OnUnitTestStart(parent_); + +    const TimeInMillis start = GetTimeInMillis(); + +    // Runs each test case if there is at least one test to run. +    if (has_tests_to_run) { +      // Sets up all environments beforehand. +      printer->OnGlobalSetUpStart(parent_); +      environments_.ForEach(SetUpEnvironment); +      printer->OnGlobalSetUpEnd(parent_); + +      // Runs the tests only if there was no fatal failure during global +      // set-up. +      if (!Test::HasFatalFailure()) { +        test_cases_.ForEach(TestCase::RunTestCase); +      } + +      // Tears down all environments in reverse order afterwards. +      printer->OnGlobalTearDownStart(parent_); +      environments_in_reverse_order_.ForEach(TearDownEnvironment); +      printer->OnGlobalTearDownEnd(parent_); +    } + +    elapsed_time_ = GetTimeInMillis() - start; + +    // Tells the unit test event listener that the tests have just +    // finished. +    printer->OnUnitTestEnd(parent_); + +    // Gets the result and clears it. +    if (!Passed()) { +      failed = true; +    } +    ClearResult(); +  } + +  // Returns 0 if all tests passed, or 1 other wise. +  return failed ? 1 : 0; +} + +// Compares the name of each test with the user-specified filter to +// decide whether the test should be run, then records the result in +// each TestCase and TestInfo object. +// Returns the number of tests that should run. +int UnitTestImpl::FilterTests() { +  int num_runnable_tests = 0; +  for (const internal::ListNode<TestCase *> *test_case_node = +       test_cases_.Head(); +       test_case_node != NULL; +       test_case_node = test_case_node->next()) { +    TestCase * const test_case = test_case_node->element(); +    const String &test_case_name = test_case->name(); +    test_case->set_should_run(false); + +    for (const internal::ListNode<TestInfo *> *test_info_node = +           test_case->test_info_list().Head(); +         test_info_node != NULL; +         test_info_node = test_info_node->next()) { +      TestInfo * const test_info = test_info_node->element(); +      const String test_name(test_info->name()); +      // A test is disabled if test case name or test name matches +      // kDisableTestFilter. +      const bool is_disabled = +        internal::UnitTestOptions::MatchesFilter(test_case_name, +                                                 kDisableTestFilter) || +        internal::UnitTestOptions::MatchesFilter(test_name, +                                                 kDisableTestFilter); +      test_info->impl()->set_is_disabled(is_disabled); + +      const bool should_run = !is_disabled && +          internal::UnitTestOptions::FilterMatchesTest(test_case_name, +                                                       test_name); +      test_info->impl()->set_should_run(should_run); +      test_case->set_should_run(test_case->should_run() || should_run); +      if (should_run) { +        num_runnable_tests++; +      } +    } +  } +  return num_runnable_tests; +} + +// Lists all tests by name. +void UnitTestImpl::ListAllTests() { +  for (const internal::ListNode<TestCase*>* test_case_node = test_cases_.Head(); +       test_case_node != NULL; +       test_case_node = test_case_node->next()) { +    const TestCase* const test_case = test_case_node->element(); + +    // Prints the test case name following by an indented list of test nodes. +    printf("%s.\n", test_case->name()); + +    for (const internal::ListNode<TestInfo*>* test_info_node = +         test_case->test_info_list().Head(); +         test_info_node != NULL; +         test_info_node = test_info_node->next()) { +      const TestInfo* const test_info = test_info_node->element(); + +      printf("  %s\n", test_info->name()); +    } +  } +  fflush(stdout); +} + +// 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 UnitTestImpl::set_result_printer( +    UnitTestEventListenerInterface* result_printer) { +  if (result_printer_ != result_printer) { +    delete result_printer_; +    result_printer_ = result_printer; +  } +} + +// 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* UnitTestImpl::result_printer() { +  if (result_printer_ != NULL) { +    return result_printer_; +  } + +#ifdef GTEST_HAS_DEATH_TEST +  if (internal_run_death_test_flag_.get() != NULL) { +    result_printer_ = new NullUnitTestResultPrinter; +    return result_printer_; +  } +#endif  // GTEST_HAS_DEATH_TEST + +  UnitTestEventsRepeater *repeater = new UnitTestEventsRepeater; +  const String& output_format = internal::UnitTestOptions::GetOutputFormat(); +  if (output_format == "xml") { +    repeater->AddListener(new XmlUnitTestResultPrinter( +        internal::UnitTestOptions::GetOutputFile().c_str())); +  } else if (output_format != "") { +      printf("WARNING: unrecognized output format \"%s\" ignored.\n", +             output_format.c_str()); +      fflush(stdout); +  } +  repeater->AddListener(new PrettyUnitTestResultPrinter); +  result_printer_ = repeater; +  return result_printer_; +} + +// Sets the OS stack trace getter. +// +// Does nothing if the input and the current OS stack trace getter are +// the same; otherwise, deletes the old getter and makes the input the +// current getter. +void UnitTestImpl::set_os_stack_trace_getter( +    OsStackTraceGetterInterface* getter) { +  if (os_stack_trace_getter_ != getter) { +    delete os_stack_trace_getter_; +    os_stack_trace_getter_ = getter; +  } +} + +// Returns the current OS stack trace getter if it is not NULL; +// otherwise, creates an OsStackTraceGetter, makes it the current +// getter, and returns it. +OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { +  if (os_stack_trace_getter_ == NULL) { +    os_stack_trace_getter_ = new OsStackTraceGetter; +  } + +  return os_stack_trace_getter_; +} + +// 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* UnitTestImpl::current_test_result() { +  return current_test_info_ ? +    current_test_info_->impl()->result() : &ad_hoc_test_result_; +} + +// TestInfoImpl constructor. The new instance assumes ownership of the test +// factory object. +TestInfoImpl::TestInfoImpl(TestInfo* parent, +                           const char* test_case_name, +                           const char* name, +                           const char* test_case_comment, +                           const char* comment, +                           TypeId fixture_class_id, +                           internal::TestFactoryBase* factory) : +    parent_(parent), +    test_case_name_(String(test_case_name)), +    name_(String(name)), +    test_case_comment_(String(test_case_comment)), +    comment_(String(comment)), +    fixture_class_id_(fixture_class_id), +    should_run_(false), +    is_disabled_(false), +    factory_(factory) { +} + +// TestInfoImpl destructor. +TestInfoImpl::~TestInfoImpl() { +  delete factory_; +} + +// Returns the current OS stack trace as a String. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag.  The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, int skip_count) { +  // We pass skip_count + 1 to skip this wrapper function in addition +  // to what the user really wants to skip. +  return unit_test->impl()->CurrentOsStackTraceExceptTop(skip_count + 1); +} + +// Returns the number of failed test parts in the given test result object. +int GetFailedPartCount(const TestResult* result) { +  return result->failed_part_count(); +} + +// Parses a string as a command line flag.  The string should have +// the format "--flag=value".  When def_optional is true, the "=value" +// part can be omitted. +// +// Returns the value of the flag, or NULL if the parsing failed. +const char* ParseFlagValue(const char* str, +                           const char* flag, +                           bool def_optional) { +  // str and flag must not be NULL. +  if (str == NULL || flag == NULL) return NULL; + +  // The flag must start with "--" followed by GTEST_FLAG_PREFIX. +  const String flag_str = String::Format("--%s%s", GTEST_FLAG_PREFIX, flag); +  const size_t flag_len = flag_str.GetLength(); +  if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; + +  // Skips the flag name. +  const char* flag_end = str + flag_len; + +  // When def_optional is true, it's OK to not have a "=value" part. +  if (def_optional && (flag_end[0] == '\0')) { +    return flag_end; +  } + +  // If def_optional is true and there are more characters after the +  // flag name, or if def_optional is false, there must be a '=' after +  // the flag name. +  if (flag_end[0] != '=') return NULL; + +  // Returns the string after "=". +  return flag_end + 1; +} + +// Parses a string for a bool flag, in the form of either +// "--flag=value" or "--flag". +// +// In the former case, the value is taken as true as long as it does +// not start with '0', 'f', or 'F'. +// +// In the latter case, the value is taken as true. +// +// On success, stores the value of the flag in *value, and returns +// true.  On failure, returns false without changing *value. +bool ParseBoolFlag(const char* str, const char* flag, bool* value) { +  // Gets the value of the flag as a string. +  const char* const value_str = ParseFlagValue(str, flag, true); + +  // Aborts if the parsing failed. +  if (value_str == NULL) return false; + +  // Converts the string value to a bool. +  *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); +  return true; +} + +// Parses a string for an Int32 flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true.  On failure, returns false without changing *value. +bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { +  // Gets the value of the flag as a string. +  const char* const value_str = ParseFlagValue(str, flag, false); + +  // Aborts if the parsing failed. +  if (value_str == NULL) return false; + +  // Sets *value to the value of the flag. +  return ParseInt32(Message() << "The value of flag --" << flag, +                    value_str, value); +} + +// Parses a string for a string flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true.  On failure, returns false without changing *value. +bool ParseStringFlag(const char* str, const char* flag, String* value) { +  // Gets the value of the flag as a string. +  const char* const value_str = ParseFlagValue(str, flag, false); + +  // Aborts if the parsing failed. +  if (value_str == NULL) return false; + +  // Sets *value to the value of the flag. +  *value = value_str; +  return true; +} + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test.  The type parameter CharType can be +// instantiated to either char or wchar_t. +template <typename CharType> +void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { +  for (int i = 1; i < *argc; i++) { +    const String arg_string = StreamableToString(argv[i]); +    const char* const arg = arg_string.c_str(); + +    using internal::ParseBoolFlag; +    using internal::ParseInt32Flag; +    using internal::ParseStringFlag; + +    // Do we see a Google Test flag? +    if (ParseBoolFlag(arg, kBreakOnFailureFlag, +                      >EST_FLAG(break_on_failure)) || +        ParseBoolFlag(arg, kCatchExceptionsFlag, +                      >EST_FLAG(catch_exceptions)) || +        ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || +        ParseStringFlag(arg, kDeathTestStyleFlag, +                        >EST_FLAG(death_test_style)) || +        ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || +        ParseStringFlag(arg, kInternalRunDeathTestFlag, +                        >EST_FLAG(internal_run_death_test)) || +        ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || +        ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || +        ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || +        ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) +        ) { +      // Yes.  Shift the remainder of the argv list left by one.  Note +      // that argv has (*argc + 1) elements, the last one always being +      // NULL.  The following loop moves the trailing NULL element as +      // well. +      for (int j = i; j != *argc; j++) { +        argv[j] = argv[j + 1]; +      } + +      // Decrements the argument count. +      (*argc)--; + +      // We also need to decrement the iterator as we just removed +      // an element. +      i--; +    } +  } +} + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +void ParseGoogleTestFlagsOnly(int* argc, char** argv) { +  ParseGoogleTestFlagsOnlyImpl(argc, argv); +} +void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { +  ParseGoogleTestFlagsOnlyImpl(argc, argv); +} + +// The internal implementation of InitGoogleTest(). +// +// The type parameter CharType can be instantiated to either char or +// wchar_t. +template <typename CharType> +void InitGoogleTestImpl(int* argc, CharType** argv) { +  g_init_gtest_count++; + +  // We don't want to run the initialization code twice. +  if (g_init_gtest_count != 1) return; + +  if (*argc <= 0) return; + +  internal::g_executable_path = internal::StreamableToString(argv[0]); + +#ifdef GTEST_HAS_DEATH_TEST +  g_argvs.clear(); +  for (int i = 0; i != *argc; i++) { +    g_argvs.push_back(StreamableToString(argv[i])); +  } +#endif  // GTEST_HAS_DEATH_TEST + +  ParseGoogleTestFlagsOnly(argc, argv); +} + +}  // namespace internal + +// Initializes Google Test.  This must be called before calling +// RUN_ALL_TESTS().  In particular, it parses a command line for the +// flags that Google Test recognizes.  Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned.  Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +void InitGoogleTest(int* argc, char** argv) { +  internal::InitGoogleTestImpl(argc, argv); +} + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +void InitGoogleTest(int* argc, wchar_t** argv) { +  internal::InitGoogleTestImpl(argc, argv); +} + +}  // namespace testing diff --git a/llvm/utils/unittest/googletest/src/gtest_main.cc b/llvm/utils/unittest/googletest/src/gtest_main.cc new file mode 100644 index 00000000000..d20c02fdfb0 --- /dev/null +++ b/llvm/utils/unittest/googletest/src/gtest_main.cc @@ -0,0 +1,39 @@ +// Copyright 2006, 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. + +#include <iostream> + +#include <gtest/gtest.h> + +int main(int argc, char **argv) { +  std::cout << "Running main() from gtest_main.cc\n"; + +  testing::InitGoogleTest(&argc, argv); +  return RUN_ALL_TESTS(); +}  | 

