diff options
-rw-r--r-- | include/gtest/internal/gtest-param-util.h | 22 | ||||
-rw-r--r-- | include/gtest/internal/gtest-port.h | 88 | ||||
-rw-r--r-- | include/gtest/internal/gtest-type-util.h | 6 | ||||
-rw-r--r-- | include/gtest/internal/gtest-type-util.h.pump | 2 |
4 files changed, 73 insertions, 45 deletions
diff --git a/include/gtest/internal/gtest-param-util.h b/include/gtest/internal/gtest-param-util.h index f84bc02..0cbb58c 100644 --- a/include/gtest/internal/gtest-param-util.h +++ b/include/gtest/internal/gtest-param-util.h @@ -47,10 +47,6 @@ #if GTEST_HAS_PARAM_TEST -#if GTEST_HAS_RTTI -#include <typeinfo> // NOLINT -#endif // GTEST_HAS_RTTI - namespace testing { namespace internal { @@ -63,24 +59,6 @@ namespace internal { GTEST_API_ 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; diff --git a/include/gtest/internal/gtest-port.h b/include/gtest/internal/gtest-port.h index 23c2ff6..1db20a2 100644 --- a/include/gtest/internal/gtest-port.h +++ b/include/gtest/internal/gtest-port.h @@ -358,6 +358,12 @@ #endif // GTEST_HAS_RTTI +// It's this header's responsibility to #include <typeinfo> when RTTI +// is enabled. +#if GTEST_HAS_RTTI +#include <typeinfo> +#endif + // Determines whether Google Test can use the pthreads library. #ifndef GTEST_HAS_PTHREAD // The user didn't tell us explicitly, so we assume pthreads support is @@ -493,10 +499,12 @@ #endif // Determines whether to support Combine(). This only makes sense when -// value-parameterized tests are enabled. -#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE +// value-parameterized tests are enabled. The implementation doesn't +// work on Sun Studio since it doesn't understand templated conversion +// operators. +#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC) #define GTEST_HAS_COMBINE 1 -#endif // GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE +#endif // Determines whether the system compiler uses UTF-16 for encoding wide strings. #define GTEST_WIDE_STRING_USES_UTF16_ \ @@ -774,6 +782,23 @@ inline void FlushInfoLog() { fflush(NULL); } GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ << gtest_error +// 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)); + return dynamic_cast<Derived*>(base); // NOLINT +#else + return static_cast<Derived*>(base); // Poor man's downcast. +#endif // GTEST_HAS_RTTI +} + #if GTEST_HAS_STREAM_REDIRECTION_ // Defines the stderr capturer: @@ -888,15 +913,11 @@ class ThreadWithParam : public ThreadWithParamBase { param_(param), thread_can_start_(thread_can_start), finished_(false) { + ThreadWithParamBase* const base = this; // The thread can be created only after all fields except thread_ // have been initialized. GTEST_CHECK_POSIX_SUCCESS_( - // TODO(vladl@google.com): Use implicit_cast instead of static_cast - // when it is moved over from Google Mock. - pthread_create(&thread_, - 0, - &ThreadFuncWithCLinkage, - static_cast<ThreadWithParamBase*>(this))); + pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base)); } ~ThreadWithParam() { Join(); } @@ -1024,6 +1045,23 @@ class GTestMutexLock { typedef GTestMutexLock MutexLock; +// Helpers for ThreadLocal. + +// pthread_key_create() requires DeleteThreadLocalValue() to have +// C-linkage. Therefore it cannot be templatized to access +// ThreadLocal<T>. Hence the need for class +// ThreadLocalValueHolderBase. +class ThreadLocalValueHolderBase { + public: + virtual ~ThreadLocalValueHolderBase() {} +}; + +// Called by pthread to delete thread-local data stored by +// pthread_setspecific(). +extern "C" inline void DeleteThreadLocalValue(void* value_holder) { + delete static_cast<ThreadLocalValueHolderBase*>(value_holder); +} + // Implements thread-local storage on pthreads-based systems. // // // Thread 1 @@ -1062,24 +1100,38 @@ class ThreadLocal { void set(const T& value) { *pointer() = value; } private: + // Holds a value of type T. + class ValueHolder : public ThreadLocalValueHolderBase { + public: + explicit ValueHolder(const T& value) : value_(value) {} + + T* pointer() { return &value_; } + + private: + T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); + }; + static pthread_key_t CreateKey() { pthread_key_t key; - GTEST_CHECK_POSIX_SUCCESS_(pthread_key_create(&key, &DeleteData)); + GTEST_CHECK_POSIX_SUCCESS_( + pthread_key_create(&key, &DeleteThreadLocalValue)); return key; } T* GetOrCreateValue() const { - T* const value = static_cast<T*>(pthread_getspecific(key_)); - if (value != NULL) - return value; + ThreadLocalValueHolderBase* const holder = + static_cast<ThreadLocalValueHolderBase*>(pthread_getspecific(key_)); + if (holder != NULL) { + return CheckedDowncastToActualType<ValueHolder>(holder)->pointer(); + } - T* const new_value = new T(default_); - GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, new_value)); - return new_value; + ValueHolder* const new_holder = new ValueHolder(default_); + ThreadLocalValueHolderBase* const holder_base = new_holder; + GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); + return new_holder->pointer(); } - static void DeleteData(void* data) { delete static_cast<T*>(data); } - // A key pthreads uses for looking up per-thread values. const pthread_key_t key_; const T default_; // The default value for each thread. diff --git a/include/gtest/internal/gtest-type-util.h b/include/gtest/internal/gtest-type-util.h index f1b1bed..093eee6 100644 --- a/include/gtest/internal/gtest-type-util.h +++ b/include/gtest/internal/gtest-type-util.h @@ -1,4 +1,6 @@ -// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! +// This file was GENERATED by command: +// pump.py gtest-type-util.h.pump +// DO NOT EDIT BY HAND!!! // Copyright 2008 Google Inc. // All Rights Reserved. @@ -53,8 +55,6 @@ #include <cxxabi.h> #endif // __GLIBCXX__ -#include <typeinfo> - namespace testing { namespace internal { diff --git a/include/gtest/internal/gtest-type-util.h.pump b/include/gtest/internal/gtest-type-util.h.pump index 3eb5dce..5aed1e5 100644 --- a/include/gtest/internal/gtest-type-util.h.pump +++ b/include/gtest/internal/gtest-type-util.h.pump @@ -53,8 +53,6 @@ $var n = 50 $$ Maximum length of type lists we want to support. #include <cxxabi.h> #endif // __GLIBCXX__ -#include <typeinfo> - namespace testing { namespace internal { |