Import the latest version of gtest and gmock. Change-Id: I4b686c44bba823cab1dae40efa99e31340d2b52a
diff --git a/internal/ceres/gmock/gmock.h b/internal/ceres/gmock/gmock.h index 681f9e2..70e2275 100644 --- a/internal/ceres/gmock/gmock.h +++ b/internal/ceres/gmock/gmock.h
@@ -240,6 +240,52 @@ // here, as Google Mock depends on Google Test. Only add a utility // here if it's truly specific to Google Mock. #include "gtest/gtest.h" +// Copyright 2015, 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. +// +// Injection point for custom user configurations. +// The following macros can be defined: +// +// Flag related macros: +// GMOCK_DECLARE_bool_(name) +// GMOCK_DECLARE_int32_(name) +// GMOCK_DECLARE_string_(name) +// GMOCK_DEFINE_bool_(name, default_val, doc) +// GMOCK_DEFINE_int32_(name, default_val, doc) +// GMOCK_DEFINE_string_(name, default_val, doc) +// +// ** Custom implementation starts here ** + +#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ +#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ + +#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ // To avoid conditional compilation everywhere, we make it // gmock-port.h's responsibility to #include the header implementing @@ -256,6 +302,8 @@ // use this syntax to reference Google Mock flags. #define GMOCK_FLAG(name) FLAGS_gmock_##name +#if !defined(GMOCK_DECLARE_bool_) + // Macros for declaring flags. #define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name) #define GMOCK_DECLARE_int32_(name) \ @@ -271,6 +319,8 @@ #define GMOCK_DEFINE_string_(name, default_val, doc) \ GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val) +#endif // !defined(GMOCK_DECLARE_bool_) + #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ namespace testing { @@ -299,70 +349,70 @@ struct MatcherTuple; template <> -struct MatcherTuple< ::std::tr1::tuple<> > { - typedef ::std::tr1::tuple< > type; +struct MatcherTuple< ::testing::tuple<> > { + typedef ::testing::tuple< > type; }; template <typename A1> -struct MatcherTuple< ::std::tr1::tuple<A1> > { - typedef ::std::tr1::tuple<Matcher<A1> > type; +struct MatcherTuple< ::testing::tuple<A1> > { + typedef ::testing::tuple<Matcher<A1> > type; }; template <typename A1, typename A2> -struct MatcherTuple< ::std::tr1::tuple<A1, A2> > { - typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2> > type; +struct MatcherTuple< ::testing::tuple<A1, A2> > { + typedef ::testing::tuple<Matcher<A1>, Matcher<A2> > type; }; template <typename A1, typename A2, typename A3> -struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3> > { - typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3> > type; +struct MatcherTuple< ::testing::tuple<A1, A2, A3> > { + typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3> > type; }; template <typename A1, typename A2, typename A3, typename A4> -struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4> > { - typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, +struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4> > { + typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4> > type; }; template <typename A1, typename A2, typename A3, typename A4, typename A5> -struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5> > { - typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>, +struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5> > { + typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>, Matcher<A5> > type; }; template <typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> -struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6> > { - typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>, +struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6> > { + typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>, Matcher<A5>, Matcher<A6> > type; }; template <typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7> -struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7> > { - typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>, +struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> > { + typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>, Matcher<A5>, Matcher<A6>, Matcher<A7> > type; }; template <typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8> -struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > { - typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>, +struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > { + typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>, Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8> > type; }; template <typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9> -struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > { - typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>, +struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > { + typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>, Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9> > type; }; template <typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10> -struct MatcherTuple< ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9, +struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10> > { - typedef ::std::tr1::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>, + typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>, Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9>, Matcher<A10> > type; }; @@ -386,7 +436,7 @@ template <typename R> struct Function<R()> { typedef R Result; - typedef ::std::tr1::tuple<> ArgumentTuple; + typedef ::testing::tuple<> ArgumentTuple; typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; typedef void MakeResultVoid(); typedef IgnoredValue MakeResultIgnoredValue(); @@ -396,7 +446,7 @@ struct Function<R(A1)> : Function<R()> { typedef A1 Argument1; - typedef ::std::tr1::tuple<A1> ArgumentTuple; + typedef ::testing::tuple<A1> ArgumentTuple; typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; typedef void MakeResultVoid(A1); typedef IgnoredValue MakeResultIgnoredValue(A1); @@ -406,7 +456,7 @@ struct Function<R(A1, A2)> : Function<R(A1)> { typedef A2 Argument2; - typedef ::std::tr1::tuple<A1, A2> ArgumentTuple; + typedef ::testing::tuple<A1, A2> ArgumentTuple; typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; typedef void MakeResultVoid(A1, A2); typedef IgnoredValue MakeResultIgnoredValue(A1, A2); @@ -416,7 +466,7 @@ struct Function<R(A1, A2, A3)> : Function<R(A1, A2)> { typedef A3 Argument3; - typedef ::std::tr1::tuple<A1, A2, A3> ArgumentTuple; + typedef ::testing::tuple<A1, A2, A3> ArgumentTuple; typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; typedef void MakeResultVoid(A1, A2, A3); typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3); @@ -426,7 +476,7 @@ struct Function<R(A1, A2, A3, A4)> : Function<R(A1, A2, A3)> { typedef A4 Argument4; - typedef ::std::tr1::tuple<A1, A2, A3, A4> ArgumentTuple; + typedef ::testing::tuple<A1, A2, A3, A4> ArgumentTuple; typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; typedef void MakeResultVoid(A1, A2, A3, A4); typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4); @@ -437,7 +487,7 @@ struct Function<R(A1, A2, A3, A4, A5)> : Function<R(A1, A2, A3, A4)> { typedef A5 Argument5; - typedef ::std::tr1::tuple<A1, A2, A3, A4, A5> ArgumentTuple; + typedef ::testing::tuple<A1, A2, A3, A4, A5> ArgumentTuple; typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; typedef void MakeResultVoid(A1, A2, A3, A4, A5); typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5); @@ -448,7 +498,7 @@ struct Function<R(A1, A2, A3, A4, A5, A6)> : Function<R(A1, A2, A3, A4, A5)> { typedef A6 Argument6; - typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6> ArgumentTuple; + typedef ::testing::tuple<A1, A2, A3, A4, A5, A6> ArgumentTuple; typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6); typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6); @@ -459,7 +509,7 @@ struct Function<R(A1, A2, A3, A4, A5, A6, A7)> : Function<R(A1, A2, A3, A4, A5, A6)> { typedef A7 Argument7; - typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7> ArgumentTuple; + typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> ArgumentTuple; typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7); typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7); @@ -470,7 +520,7 @@ struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8)> : Function<R(A1, A2, A3, A4, A5, A6, A7)> { typedef A8 Argument8; - typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8> ArgumentTuple; + typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> ArgumentTuple; typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8); typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8); @@ -481,7 +531,7 @@ struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> : Function<R(A1, A2, A3, A4, A5, A6, A7, A8)> { typedef A9 Argument9; - typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> ArgumentTuple; + typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> ArgumentTuple; typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9); typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8, @@ -494,7 +544,7 @@ struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> : Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> { typedef A10 Argument10; - typedef ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9, + typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10> ArgumentTuple; typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple; typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); @@ -909,16 +959,17 @@ // ConstReference(const char * (&)[4])') // (and though the N parameter type is mismatched in the above explicit // conversion of it doesn't help - only the conversion of the array). - return type(const_cast<Element*>(&array[0]), N, kReference); + return type(const_cast<Element*>(&array[0]), N, + RelationToSourceReference()); #else - return type(array, N, kReference); + return type(array, N, RelationToSourceReference()); #endif // GTEST_OS_SYMBIAN } static type Copy(const Element (&array)[N]) { #if GTEST_OS_SYMBIAN - return type(const_cast<Element*>(&array[0]), N, kCopy); + return type(const_cast<Element*>(&array[0]), N, RelationToSourceCopy()); #else - return type(array, N, kCopy); + return type(array, N, RelationToSourceCopy()); #endif // GTEST_OS_SYMBIAN } }; @@ -926,7 +977,7 @@ // This specialization is used when RawContainer is a native array // represented as a (pointer, size) tuple. template <typename ElementPointer, typename Size> -class StlContainerView< ::std::tr1::tuple<ElementPointer, Size> > { +class StlContainerView< ::testing::tuple<ElementPointer, Size> > { public: typedef GTEST_REMOVE_CONST_( typename internal::PointeeOf<ElementPointer>::type) RawElement; @@ -934,13 +985,11 @@ typedef const type const_reference; static const_reference ConstReference( - const ::std::tr1::tuple<ElementPointer, Size>& array) { - using ::std::tr1::get; - return type(get<0>(array), get<1>(array), kReference); + const ::testing::tuple<ElementPointer, Size>& array) { + return type(get<0>(array), get<1>(array), RelationToSourceReference()); } - static type Copy(const ::std::tr1::tuple<ElementPointer, Size>& array) { - using ::std::tr1::get; - return type(get<0>(array), get<1>(array), kCopy); + static type Copy(const ::testing::tuple<ElementPointer, Size>& array) { + return type(get<0>(array), get<1>(array), RelationToSourceCopy()); } }; @@ -972,6 +1021,11 @@ #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ + +#if GTEST_LANG_CXX11 // Defined by gtest-port.h via gmock-port.h. +#include <type_traits> +#endif + namespace testing { // To implement an action Foo, define: @@ -988,16 +1042,17 @@ template <typename F1, typename F2> class ActionAdaptor; -// BuiltInDefaultValue<T>::Get() returns the "built-in" default -// value for type T, which is NULL when T is a pointer type, 0 when T -// is a numeric type, false when T is bool, or "" when T is string or -// std::string. For any other type T, this value is undefined and the -// function will abort the process. +// BuiltInDefaultValueGetter<T, true>::Get() returns a +// default-constructed T value. BuiltInDefaultValueGetter<T, +// false>::Get() crashes with an error. +// +// This primary template is used when kDefaultConstructible is true. +template <typename T, bool kDefaultConstructible> +struct BuiltInDefaultValueGetter { + static T Get() { return T(); } +}; template <typename T> -class BuiltInDefaultValue { - public: - // This function returns true iff type T has a built-in default value. - static bool Exists() { return false; } +struct BuiltInDefaultValueGetter<T, false> { static T Get() { Assert(false, __FILE__, __LINE__, "Default action undefined for the function return type."); @@ -1007,6 +1062,40 @@ } }; +// BuiltInDefaultValue<T>::Get() returns the "built-in" default value +// for type T, which is NULL when T is a raw pointer type, 0 when T is +// a numeric type, false when T is bool, or "" when T is string or +// std::string. In addition, in C++11 and above, it turns a +// default-constructed T value if T is default constructible. For any +// other type T, the built-in default T value is undefined, and the +// function will abort the process. +template <typename T> +class BuiltInDefaultValue { + public: +#if GTEST_LANG_CXX11 + // This function returns true iff type T has a built-in default value. + static bool Exists() { + return ::std::is_default_constructible<T>::value; + } + + static T Get() { + return BuiltInDefaultValueGetter< + T, ::std::is_default_constructible<T>::value>::Get(); + } + +#else // GTEST_LANG_CXX11 + // This function returns true iff type T has a built-in default value. + static bool Exists() { + return false; + } + + static T Get() { + return BuiltInDefaultValueGetter<T, false>::Get(); + } + +#endif // GTEST_LANG_CXX11 +}; + // This partial specialization says that we use the same built-in // default value for T and const T. template <typename T> @@ -1385,6 +1474,14 @@ GTEST_DISALLOW_ASSIGN_(ActionAdaptor); }; +// Helper struct to specialize ReturnAction to execute a move instead of a copy +// on return. Useful for move-only types, but could be used on any type. +template <typename T> +struct ByMoveWrapper { + explicit ByMoveWrapper(T value) : payload(internal::move(value)) {} + T payload; +}; + // Implements the polymorphic Return(x) action, which can be used in // any function that returns the type of x, regardless of the argument // types. @@ -1415,7 +1512,7 @@ // Constructs a ReturnAction object from the value to be returned. // 'value' is passed by value instead of by const reference in order // to allow Return("string literal") to compile. - explicit ReturnAction(R value) : value_(value) {} + explicit ReturnAction(R value) : value_(new R(internal::move(value))) {} // This template type conversion operator allows Return(x) to be // used in ANY function that returns x's type. @@ -1431,14 +1528,14 @@ // in the Impl class. But both definitions must be the same. typedef typename Function<F>::Result Result; GTEST_COMPILE_ASSERT_( - !internal::is_reference<Result>::value, + !is_reference<Result>::value, use_ReturnRef_instead_of_Return_to_return_a_reference); - return Action<F>(new Impl<F>(value_)); + return Action<F>(new Impl<R, F>(value_)); } private: // Implements the Return(x) action for a particular function type F. - template <typename F> + template <typename R_, typename F> class Impl : public ActionInterface<F> { public: typedef typename Function<F>::Result Result; @@ -1451,20 +1548,49 @@ // Result to call. ImplicitCast_ forces the compiler to convert R to // Result without considering explicit constructors, thus resolving the // ambiguity. value_ is then initialized using its copy constructor. - explicit Impl(R value) - : value_(::testing::internal::ImplicitCast_<Result>(value)) {} + explicit Impl(const linked_ptr<R>& value) + : value_before_cast_(*value), + value_(ImplicitCast_<Result>(value_before_cast_)) {} virtual Result Perform(const ArgumentTuple&) { return value_; } private: - GTEST_COMPILE_ASSERT_(!internal::is_reference<Result>::value, + GTEST_COMPILE_ASSERT_(!is_reference<Result>::value, Result_cannot_be_a_reference_type); + // We save the value before casting just in case it is being cast to a + // wrapper type. + R value_before_cast_; Result value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(Impl); + }; + + // Partially specialize for ByMoveWrapper. This version of ReturnAction will + // move its contents instead. + template <typename R_, typename F> + class Impl<ByMoveWrapper<R_>, F> : public ActionInterface<F> { + public: + typedef typename Function<F>::Result Result; + typedef typename Function<F>::ArgumentTuple ArgumentTuple; + + explicit Impl(const linked_ptr<R>& wrapper) + : performed_(false), wrapper_(wrapper) {} + + virtual Result Perform(const ArgumentTuple&) { + GTEST_CHECK_(!performed_) + << "A ByMove() action should only be performed once."; + performed_ = true; + return internal::move(wrapper_->payload); + } + + private: + bool performed_; + const linked_ptr<R> wrapper_; + GTEST_DISALLOW_ASSIGN_(Impl); }; - R value_; + const linked_ptr<R> value_; GTEST_DISALLOW_ASSIGN_(ReturnAction); }; @@ -1472,12 +1598,18 @@ // Implements the ReturnNull() action. class ReturnNullAction { public: - // Allows ReturnNull() to be used in any pointer-returning function. + // Allows ReturnNull() to be used in any pointer-returning function. In C++11 + // this is enforced by returning nullptr, and in non-C++11 by asserting a + // pointer type on compile time. template <typename Result, typename ArgumentTuple> static Result Perform(const ArgumentTuple&) { +#if GTEST_LANG_CXX11 + return nullptr; +#else GTEST_COMPILE_ASSERT_(internal::is_pointer<Result>::value, ReturnNull_can_be_used_to_return_a_pointer_only); return NULL; +#endif // GTEST_LANG_CXX11 } }; @@ -1654,7 +1786,7 @@ template <typename Result, typename ArgumentTuple> void Perform(const ArgumentTuple& args) const { CompileAssertTypesEqual<void, Result>(); - *::std::tr1::get<N>(args) = value_; + *::testing::get<N>(args) = value_; } private: @@ -1677,7 +1809,7 @@ template <typename Result, typename ArgumentTuple> void Perform(const ArgumentTuple& args) const { CompileAssertTypesEqual<void, Result>(); - ::std::tr1::get<N>(args)->CopyFrom(*proto_); + ::testing::get<N>(args)->CopyFrom(*proto_); } private: @@ -1903,7 +2035,7 @@ // will trigger a compiler error about using array as initializer. template <typename R> internal::ReturnAction<R> Return(R value) { - return internal::ReturnAction<R>(value); + return internal::ReturnAction<R>(internal::move(value)); } // Creates an action that returns NULL. @@ -1930,6 +2062,15 @@ return internal::ReturnRefOfCopyAction<R>(x); } +// Modifies the parent action (a Return() action) to perform a move of the +// argument instead of a copy. +// Return(ByMove()) actions can only be executed once and will assert this +// invariant. +template <typename R> +internal::ByMoveWrapper<R> ByMove(R x) { + return internal::ByMoveWrapper<R>(internal::move(x)); +} + // Creates an action that does the default action for the give mock function. inline internal::DoDefaultAction DoDefault() { return internal::DoDefaultAction(); @@ -2234,356 +2375,240 @@ class InvokeHelper; template <typename R> -class InvokeHelper<R, ::std::tr1::tuple<> > { +class InvokeHelper<R, ::testing::tuple<> > { public: template <typename Function> - static R Invoke(Function function, const ::std::tr1::tuple<>&) { - return function(); + static R Invoke(Function function, const ::testing::tuple<>&) { + return function(); } template <class Class, typename MethodPtr> static R InvokeMethod(Class* obj_ptr, MethodPtr method_ptr, - const ::std::tr1::tuple<>&) { - return (obj_ptr->*method_ptr)(); + const ::testing::tuple<>&) { + return (obj_ptr->*method_ptr)(); } }; template <typename R, typename A1> -class InvokeHelper<R, ::std::tr1::tuple<A1> > { +class InvokeHelper<R, ::testing::tuple<A1> > { public: template <typename Function> - static R Invoke(Function function, const ::std::tr1::tuple<A1>& args) { - using ::std::tr1::get; - return function(get<0>(args)); + static R Invoke(Function function, const ::testing::tuple<A1>& args) { + return function(get<0>(args)); } template <class Class, typename MethodPtr> static R InvokeMethod(Class* obj_ptr, MethodPtr method_ptr, - const ::std::tr1::tuple<A1>& args) { - using ::std::tr1::get; - return (obj_ptr->*method_ptr)(get<0>(args)); + const ::testing::tuple<A1>& args) { + return (obj_ptr->*method_ptr)(get<0>(args)); } }; template <typename R, typename A1, typename A2> -class InvokeHelper<R, ::std::tr1::tuple<A1, A2> > { +class InvokeHelper<R, ::testing::tuple<A1, A2> > { public: template <typename Function> - static R Invoke(Function function, const ::std::tr1::tuple<A1, A2>& args) { - using ::std::tr1::get; - return function(get<0>(args), get<1>(args)); + static R Invoke(Function function, const ::testing::tuple<A1, A2>& args) { + return function(get<0>(args), get<1>(args)); } template <class Class, typename MethodPtr> static R InvokeMethod(Class* obj_ptr, MethodPtr method_ptr, - const ::std::tr1::tuple<A1, A2>& args) { - using ::std::tr1::get; - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args)); + const ::testing::tuple<A1, A2>& args) { + return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args)); } }; template <typename R, typename A1, typename A2, typename A3> -class InvokeHelper<R, ::std::tr1::tuple<A1, A2, A3> > { +class InvokeHelper<R, ::testing::tuple<A1, A2, A3> > { public: template <typename Function> - static R Invoke(Function function, const ::std::tr1::tuple<A1, A2, - A3>& args) { - using ::std::tr1::get; - return function(get<0>(args), get<1>(args), get<2>(args)); + static R Invoke(Function function, const ::testing::tuple<A1, A2, A3>& args) { + return function(get<0>(args), get<1>(args), get<2>(args)); } template <class Class, typename MethodPtr> static R InvokeMethod(Class* obj_ptr, MethodPtr method_ptr, - const ::std::tr1::tuple<A1, A2, A3>& args) { - using ::std::tr1::get; - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args)); + const ::testing::tuple<A1, A2, A3>& args) { + return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), + get<2>(args)); } }; template <typename R, typename A1, typename A2, typename A3, typename A4> -class InvokeHelper<R, ::std::tr1::tuple<A1, A2, A3, A4> > { +class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4> > { public: template <typename Function> - static R Invoke(Function function, const ::std::tr1::tuple<A1, A2, A3, + static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4>& args) { - using ::std::tr1::get; - return function(get<0>(args), get<1>(args), get<2>(args), get<3>(args)); + return function(get<0>(args), get<1>(args), get<2>(args), + get<3>(args)); } template <class Class, typename MethodPtr> static R InvokeMethod(Class* obj_ptr, MethodPtr method_ptr, - const ::std::tr1::tuple<A1, A2, A3, A4>& args) { - using ::std::tr1::get; - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args), - get<3>(args)); + const ::testing::tuple<A1, A2, A3, A4>& args) { + return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), + get<2>(args), get<3>(args)); } }; template <typename R, typename A1, typename A2, typename A3, typename A4, typename A5> -class InvokeHelper<R, ::std::tr1::tuple<A1, A2, A3, A4, A5> > { +class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5> > { public: template <typename Function> - static R Invoke(Function function, const ::std::tr1::tuple<A1, A2, A3, A4, + static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5>& args) { - using ::std::tr1::get; - return function(get<0>(args), get<1>(args), get<2>(args), get<3>(args), - get<4>(args)); + return function(get<0>(args), get<1>(args), get<2>(args), + get<3>(args), get<4>(args)); } template <class Class, typename MethodPtr> static R InvokeMethod(Class* obj_ptr, MethodPtr method_ptr, - const ::std::tr1::tuple<A1, A2, A3, A4, A5>& args) { - using ::std::tr1::get; - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args)); + const ::testing::tuple<A1, A2, A3, A4, A5>& args) { + return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), + get<2>(args), get<3>(args), get<4>(args)); } }; template <typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> -class InvokeHelper<R, ::std::tr1::tuple<A1, A2, A3, A4, A5, A6> > { +class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6> > { public: template <typename Function> - static R Invoke(Function function, const ::std::tr1::tuple<A1, A2, A3, A4, - A5, A6>& args) { - using ::std::tr1::get; - return function(get<0>(args), get<1>(args), get<2>(args), get<3>(args), - get<4>(args), get<5>(args)); + static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5, + A6>& args) { + return function(get<0>(args), get<1>(args), get<2>(args), + get<3>(args), get<4>(args), get<5>(args)); } template <class Class, typename MethodPtr> static R InvokeMethod(Class* obj_ptr, MethodPtr method_ptr, - const ::std::tr1::tuple<A1, A2, A3, A4, A5, A6>& args) { - using ::std::tr1::get; - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args), get<5>(args)); + const ::testing::tuple<A1, A2, A3, A4, A5, A6>& args) { + return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), + get<2>(args), get<3>(args), get<4>(args), get<5>(args)); } }; template <typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7> -class InvokeHelper<R, ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7> > { +class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> > { public: template <typename Function> - static R Invoke(Function function, const ::std::tr1::tuple<A1, A2, A3, A4, - A5, A6, A7>& args) { - using ::std::tr1::get; - return function(get<0>(args), get<1>(args), get<2>(args), get<3>(args), - get<4>(args), get<5>(args), get<6>(args)); + static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5, + A6, A7>& args) { + return function(get<0>(args), get<1>(args), get<2>(args), + get<3>(args), get<4>(args), get<5>(args), get<6>(args)); } template <class Class, typename MethodPtr> static R InvokeMethod(Class* obj_ptr, MethodPtr method_ptr, - const ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, + const ::testing::tuple<A1, A2, A3, A4, A5, A6, A7>& args) { - using ::std::tr1::get; - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args), get<5>(args), get<6>(args)); + return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), + get<2>(args), get<3>(args), get<4>(args), get<5>(args), + get<6>(args)); } }; template <typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8> -class InvokeHelper<R, ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > { +class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > { public: template <typename Function> - static R Invoke(Function function, const ::std::tr1::tuple<A1, A2, A3, A4, - A5, A6, A7, A8>& args) { - using ::std::tr1::get; - return function(get<0>(args), get<1>(args), get<2>(args), get<3>(args), - get<4>(args), get<5>(args), get<6>(args), get<7>(args)); + static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5, + A6, A7, A8>& args) { + return function(get<0>(args), get<1>(args), get<2>(args), + get<3>(args), get<4>(args), get<5>(args), get<6>(args), + get<7>(args)); } template <class Class, typename MethodPtr> static R InvokeMethod(Class* obj_ptr, MethodPtr method_ptr, - const ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, + const ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8>& args) { - using ::std::tr1::get; - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args), get<5>(args), get<6>(args), get<7>(args)); + return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), + get<2>(args), get<3>(args), get<4>(args), get<5>(args), + get<6>(args), get<7>(args)); } }; template <typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9> -class InvokeHelper<R, ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > { +class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > { public: template <typename Function> - static R Invoke(Function function, const ::std::tr1::tuple<A1, A2, A3, A4, - A5, A6, A7, A8, A9>& args) { - using ::std::tr1::get; - return function(get<0>(args), get<1>(args), get<2>(args), get<3>(args), - get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args)); + static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5, + A6, A7, A8, A9>& args) { + return function(get<0>(args), get<1>(args), get<2>(args), + get<3>(args), get<4>(args), get<5>(args), get<6>(args), + get<7>(args), get<8>(args)); } template <class Class, typename MethodPtr> static R InvokeMethod(Class* obj_ptr, MethodPtr method_ptr, - const ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, + const ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9>& args) { - using ::std::tr1::get; - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args), get<5>(args), get<6>(args), get<7>(args), - get<8>(args)); + return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), + get<2>(args), get<3>(args), get<4>(args), get<5>(args), + get<6>(args), get<7>(args), get<8>(args)); } }; template <typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10> -class InvokeHelper<R, ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9, +class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10> > { public: template <typename Function> - static R Invoke(Function function, const ::std::tr1::tuple<A1, A2, A3, A4, - A5, A6, A7, A8, A9, A10>& args) { - using ::std::tr1::get; - return function(get<0>(args), get<1>(args), get<2>(args), get<3>(args), - get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args), - get<9>(args)); + static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5, + A6, A7, A8, A9, A10>& args) { + return function(get<0>(args), get<1>(args), get<2>(args), + get<3>(args), get<4>(args), get<5>(args), get<6>(args), + get<7>(args), get<8>(args), get<9>(args)); } template <class Class, typename MethodPtr> static R InvokeMethod(Class* obj_ptr, MethodPtr method_ptr, - const ::std::tr1::tuple<A1, A2, A3, A4, A5, A6, A7, A8, + const ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>& args) { - using ::std::tr1::get; - return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), get<2>(args), - get<3>(args), get<4>(args), get<5>(args), get<6>(args), get<7>(args), - get<8>(args), get<9>(args)); + return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), + get<2>(args), get<3>(args), get<4>(args), get<5>(args), + get<6>(args), get<7>(args), get<8>(args), get<9>(args)); } }; -// CallableHelper has static methods for invoking "callables", -// i.e. function pointers and functors. It uses overloading to -// provide a uniform interface for invoking different kinds of -// callables. In particular, you can use: -// -// CallableHelper<R>::Call(callable, a1, a2, ..., an) -// -// to invoke an n-ary callable, where R is its return type. If an -// argument, say a2, needs to be passed by reference, you should write -// ByRef(a2) instead of a2 in the above expression. -template <typename R> -class CallableHelper { - public: - // Calls a nullary callable. - template <typename Function> - static R Call(Function function) { return function(); } - - // Calls a unary callable. - - // We deliberately pass a1 by value instead of const reference here - // in case it is a C-string literal. If we had declared the - // parameter as 'const A1& a1' and write Call(function, "Hi"), the - // compiler would've thought A1 is 'char[3]', which causes trouble - // when you need to copy a value of type A1. By declaring the - // parameter as 'A1 a1', the compiler will correctly infer that A1 - // is 'const char*' when it sees Call(function, "Hi"). - // - // Since this function is defined inline, the compiler can get rid - // of the copying of the arguments. Therefore the performance won't - // be hurt. - template <typename Function, typename A1> - static R Call(Function function, A1 a1) { return function(a1); } - - // Calls a binary callable. - template <typename Function, typename A1, typename A2> - static R Call(Function function, A1 a1, A2 a2) { - return function(a1, a2); - } - - // Calls a ternary callable. - template <typename Function, typename A1, typename A2, typename A3> - static R Call(Function function, A1 a1, A2 a2, A3 a3) { - return function(a1, a2, a3); - } - - // Calls a 4-ary callable. - template <typename Function, typename A1, typename A2, typename A3, - typename A4> - static R Call(Function function, A1 a1, A2 a2, A3 a3, A4 a4) { - return function(a1, a2, a3, a4); - } - - // Calls a 5-ary callable. - template <typename Function, typename A1, typename A2, typename A3, - typename A4, typename A5> - static R Call(Function function, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { - return function(a1, a2, a3, a4, a5); - } - - // Calls a 6-ary callable. - template <typename Function, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6> - static R Call(Function function, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { - return function(a1, a2, a3, a4, a5, a6); - } - - // Calls a 7-ary callable. - template <typename Function, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6, typename A7> - static R Call(Function function, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, - A7 a7) { - return function(a1, a2, a3, a4, a5, a6, a7); - } - - // Calls a 8-ary callable. - template <typename Function, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6, typename A7, typename A8> - static R Call(Function function, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, - A7 a7, A8 a8) { - return function(a1, a2, a3, a4, a5, a6, a7, a8); - } - - // Calls a 9-ary callable. - template <typename Function, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6, typename A7, typename A8, - typename A9> - static R Call(Function function, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, - A7 a7, A8 a8, A9 a9) { - return function(a1, a2, a3, a4, a5, a6, a7, a8, a9); - } - - // Calls a 10-ary callable. - template <typename Function, typename A1, typename A2, typename A3, - typename A4, typename A5, typename A6, typename A7, typename A8, - typename A9, typename A10> - static R Call(Function function, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, - A7 a7, A8 a8, A9 a9, A10 a10) { - return function(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); - } -}; // class CallableHelper - // An INTERNAL macro for extracting the type of a tuple field. It's // subject to change without notice - DO NOT USE IN USER CODE! #define GMOCK_FIELD_(Tuple, N) \ - typename ::std::tr1::tuple_element<N, Tuple>::type + typename ::testing::tuple_element<N, Tuple>::type // SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::type is the // type of an n-ary function whose i-th (1-based) argument type is the // k{i}-th (0-based) field of ArgumentTuple, which must be a tuple // type, and whose return type is Result. For example, -// SelectArgs<int, ::std::tr1::tuple<bool, char, double, long>, 0, 3>::type +// SelectArgs<int, ::testing::tuple<bool, char, double, long>, 0, 3>::type // is int(bool, long). // // SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::Select(args) // returns the selected fields (k1, k2, ..., k_n) of args as a tuple. // For example, -// SelectArgs<int, ::std::tr1::tuple<bool, char, double>, 2, 0>::Select( -// ::std::tr1::make_tuple(true, 'a', 2.5)) -// returns ::std::tr1::tuple (2.5, true). +// SelectArgs<int, tuple<bool, char, double>, 2, 0>::Select( +// ::testing::make_tuple(true, 'a', 2.5)) +// returns tuple (2.5, true). // // The numbers in list k1, k2, ..., k_n must be >= 0, where n can be // in the range [0, 10]. Duplicates are allowed and they don't have @@ -2601,7 +2626,6 @@ GMOCK_FIELD_(ArgumentTuple, k10)); typedef typename Function<type>::ArgumentTuple SelectedArgs; static SelectedArgs Select(const ArgumentTuple& args) { - using ::std::tr1::get; return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args), get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args), get<k8>(args), get<k9>(args), get<k10>(args)); @@ -2615,7 +2639,6 @@ typedef Result type(); typedef typename Function<type>::ArgumentTuple SelectedArgs; static SelectedArgs Select(const ArgumentTuple& /* args */) { - using ::std::tr1::get; return SelectedArgs(); } }; @@ -2627,7 +2650,6 @@ typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1)); typedef typename Function<type>::ArgumentTuple SelectedArgs; static SelectedArgs Select(const ArgumentTuple& args) { - using ::std::tr1::get; return SelectedArgs(get<k1>(args)); } }; @@ -2640,7 +2662,6 @@ GMOCK_FIELD_(ArgumentTuple, k2)); typedef typename Function<type>::ArgumentTuple SelectedArgs; static SelectedArgs Select(const ArgumentTuple& args) { - using ::std::tr1::get; return SelectedArgs(get<k1>(args), get<k2>(args)); } }; @@ -2653,7 +2674,6 @@ GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3)); typedef typename Function<type>::ArgumentTuple SelectedArgs; static SelectedArgs Select(const ArgumentTuple& args) { - using ::std::tr1::get; return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args)); } }; @@ -2668,7 +2688,6 @@ GMOCK_FIELD_(ArgumentTuple, k4)); typedef typename Function<type>::ArgumentTuple SelectedArgs; static SelectedArgs Select(const ArgumentTuple& args) { - using ::std::tr1::get; return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args), get<k4>(args)); } @@ -2684,7 +2703,6 @@ GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5)); typedef typename Function<type>::ArgumentTuple SelectedArgs; static SelectedArgs Select(const ArgumentTuple& args) { - using ::std::tr1::get; return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args), get<k4>(args), get<k5>(args)); } @@ -2701,7 +2719,6 @@ GMOCK_FIELD_(ArgumentTuple, k6)); typedef typename Function<type>::ArgumentTuple SelectedArgs; static SelectedArgs Select(const ArgumentTuple& args) { - using ::std::tr1::get; return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args), get<k4>(args), get<k5>(args), get<k6>(args)); } @@ -2718,7 +2735,6 @@ GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7)); typedef typename Function<type>::ArgumentTuple SelectedArgs; static SelectedArgs Select(const ArgumentTuple& args) { - using ::std::tr1::get; return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args), get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args)); } @@ -2736,7 +2752,6 @@ GMOCK_FIELD_(ArgumentTuple, k8)); typedef typename Function<type>::ArgumentTuple SelectedArgs; static SelectedArgs Select(const ArgumentTuple& args) { - using ::std::tr1::get; return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args), get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args), get<k8>(args)); @@ -2755,7 +2770,6 @@ GMOCK_FIELD_(ArgumentTuple, k8), GMOCK_FIELD_(ArgumentTuple, k9)); typedef typename Function<type>::ArgumentTuple SelectedArgs; static SelectedArgs Select(const ArgumentTuple& args) { - using ::std::tr1::get; return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args), get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args), get<k8>(args), get<k9>(args)); @@ -2821,8 +2835,7 @@ template <typename Result, class Impl> class ActionHelper { public: - static Result Perform(Impl* impl, const ::std::tr1::tuple<>& args) { - using ::std::tr1::get; + static Result Perform(Impl* impl, const ::testing::tuple<>& args) { return impl->template gmock_PerformImpl<>(args, ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), @@ -2830,8 +2843,7 @@ } template <typename A0> - static Result Perform(Impl* impl, const ::std::tr1::tuple<A0>& args) { - using ::std::tr1::get; + static Result Perform(Impl* impl, const ::testing::tuple<A0>& args) { return impl->template gmock_PerformImpl<A0>(args, get<0>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), @@ -2839,8 +2851,7 @@ } template <typename A0, typename A1> - static Result Perform(Impl* impl, const ::std::tr1::tuple<A0, A1>& args) { - using ::std::tr1::get; + static Result Perform(Impl* impl, const ::testing::tuple<A0, A1>& args) { return impl->template gmock_PerformImpl<A0, A1>(args, get<0>(args), get<1>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), @@ -2848,8 +2859,7 @@ } template <typename A0, typename A1, typename A2> - static Result Perform(Impl* impl, const ::std::tr1::tuple<A0, A1, A2>& args) { - using ::std::tr1::get; + static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2>& args) { return impl->template gmock_PerformImpl<A0, A1, A2>(args, get<0>(args), get<1>(args), get<2>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), @@ -2857,9 +2867,8 @@ } template <typename A0, typename A1, typename A2, typename A3> - static Result Perform(Impl* impl, const ::std::tr1::tuple<A0, A1, A2, + static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3>& args) { - using ::std::tr1::get; return impl->template gmock_PerformImpl<A0, A1, A2, A3>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), @@ -2867,9 +2876,8 @@ } template <typename A0, typename A1, typename A2, typename A3, typename A4> - static Result Perform(Impl* impl, const ::std::tr1::tuple<A0, A1, A2, A3, + static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4>& args) { - using ::std::tr1::get; return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), @@ -2878,9 +2886,8 @@ template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5> - static Result Perform(Impl* impl, const ::std::tr1::tuple<A0, A1, A2, A3, A4, + static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4, A5>& args) { - using ::std::tr1::get; return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args), get<5>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), @@ -2889,9 +2896,8 @@ template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> - static Result Perform(Impl* impl, const ::std::tr1::tuple<A0, A1, A2, A3, A4, + static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4, A5, A6>& args) { - using ::std::tr1::get; return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args), get<5>(args), get<6>(args), ExcessiveArg(), ExcessiveArg(), @@ -2900,9 +2906,8 @@ template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7> - static Result Perform(Impl* impl, const ::std::tr1::tuple<A0, A1, A2, A3, A4, + static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4, A5, A6, A7>& args) { - using ::std::tr1::get; return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6, A7>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args), get<5>(args), get<6>(args), get<7>(args), ExcessiveArg(), @@ -2911,9 +2916,8 @@ template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8> - static Result Perform(Impl* impl, const ::std::tr1::tuple<A0, A1, A2, A3, A4, + static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4, A5, A6, A7, A8>& args) { - using ::std::tr1::get; return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6, A7, A8>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args), @@ -2922,9 +2926,8 @@ template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9> - static Result Perform(Impl* impl, const ::std::tr1::tuple<A0, A1, A2, A3, A4, + static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>& args) { - using ::std::tr1::get; return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args), @@ -3236,7 +3239,7 @@ // ACTION_TEMPLATE(DuplicateArg, // HAS_2_TEMPLATE_PARAMS(int, k, typename, T), // AND_1_VALUE_PARAMS(output)) { -// *output = T(std::tr1::get<k>(args)); +// *output = T(::testing::get<k>(args)); // } // ... // int n; @@ -3567,7 +3570,7 @@ GMOCK_INTERNAL_DECL_TYPE_##value_params>\ class GMOCK_ACTION_CLASS_(name, value_params) {\ public:\ - GMOCK_ACTION_CLASS_(name, value_params)\ + explicit GMOCK_ACTION_CLASS_(name, value_params)\ GMOCK_INTERNAL_INIT_##value_params {}\ template <typename F>\ class gmock_Impl : public ::testing::ActionInterface<F> {\ @@ -3675,7 +3678,7 @@ template <typename p0##_type>\ class name##ActionP {\ public:\ - name##ActionP(p0##_type gmock_p0) : p0(gmock_p0) {}\ + explicit name##ActionP(p0##_type gmock_p0) : p0(gmock_p0) {}\ template <typename F>\ class gmock_Impl : public ::testing::ActionInterface<F> {\ public:\ @@ -4401,6 +4404,7 @@ namespace testing { + // The ACTION*() macros trigger warning C4100 (unreferenced formal // parameter) in MSVC with -W4. Unfortunately they cannot be fixed in // the macro definition, as the warnings are generated when the macro @@ -4441,81 +4445,175 @@ // InvokeArgument action from temporary values and have it performed // later. +namespace internal { +namespace invoke_argument { + +// Appears in InvokeArgumentAdl's argument list to help avoid +// accidental calls to user functions of the same name. +struct AdlTag {}; + +// InvokeArgumentAdl - a helper for InvokeArgument. +// The basic overloads are provided here for generic functors. +// Overloads for other custom-callables are provided in the +// internal/custom/callback-actions.h header. + +template <typename R, typename F> +R InvokeArgumentAdl(AdlTag, F f) { + return f(); +} +template <typename R, typename F, typename A1> +R InvokeArgumentAdl(AdlTag, F f, A1 a1) { + return f(a1); +} +template <typename R, typename F, typename A1, typename A2> +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2) { + return f(a1, a2); +} +template <typename R, typename F, typename A1, typename A2, typename A3> +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3) { + return f(a1, a2, a3); +} +template <typename R, typename F, typename A1, typename A2, typename A3, + typename A4> +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4) { + return f(a1, a2, a3, a4); +} +template <typename R, typename F, typename A1, typename A2, typename A3, + typename A4, typename A5> +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + return f(a1, a2, a3, a4, a5); +} +template <typename R, typename F, typename A1, typename A2, typename A3, + typename A4, typename A5, typename A6> +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { + return f(a1, a2, a3, a4, a5, a6); +} +template <typename R, typename F, typename A1, typename A2, typename A3, + typename A4, typename A5, typename A6, typename A7> +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, + A7 a7) { + return f(a1, a2, a3, a4, a5, a6, a7); +} +template <typename R, typename F, typename A1, typename A2, typename A3, + typename A4, typename A5, typename A6, typename A7, typename A8> +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, + A7 a7, A8 a8) { + return f(a1, a2, a3, a4, a5, a6, a7, a8); +} +template <typename R, typename F, typename A1, typename A2, typename A3, + typename A4, typename A5, typename A6, typename A7, typename A8, + typename A9> +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, + A7 a7, A8 a8, A9 a9) { + return f(a1, a2, a3, a4, a5, a6, a7, a8, a9); +} +template <typename R, typename F, typename A1, typename A2, typename A3, + typename A4, typename A5, typename A6, typename A7, typename A8, + typename A9, typename A10> +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, + A7 a7, A8 a8, A9 a9, A10 a10) { + return f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); +} +} // namespace invoke_argument +} // namespace internal + ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_0_VALUE_PARAMS()) { - return internal::CallableHelper<return_type>::Call( - ::std::tr1::get<k>(args)); + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl<return_type>( + internal::invoke_argument::AdlTag(), + ::testing::get<k>(args)); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_1_VALUE_PARAMS(p0)) { - return internal::CallableHelper<return_type>::Call( - ::std::tr1::get<k>(args), p0); + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl<return_type>( + internal::invoke_argument::AdlTag(), + ::testing::get<k>(args), p0); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_2_VALUE_PARAMS(p0, p1)) { - return internal::CallableHelper<return_type>::Call( - ::std::tr1::get<k>(args), p0, p1); + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl<return_type>( + internal::invoke_argument::AdlTag(), + ::testing::get<k>(args), p0, p1); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_3_VALUE_PARAMS(p0, p1, p2)) { - return internal::CallableHelper<return_type>::Call( - ::std::tr1::get<k>(args), p0, p1, p2); + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl<return_type>( + internal::invoke_argument::AdlTag(), + ::testing::get<k>(args), p0, p1, p2); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_4_VALUE_PARAMS(p0, p1, p2, p3)) { - return internal::CallableHelper<return_type>::Call( - ::std::tr1::get<k>(args), p0, p1, p2, p3); + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl<return_type>( + internal::invoke_argument::AdlTag(), + ::testing::get<k>(args), p0, p1, p2, p3); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) { - return internal::CallableHelper<return_type>::Call( - ::std::tr1::get<k>(args), p0, p1, p2, p3, p4); + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl<return_type>( + internal::invoke_argument::AdlTag(), + ::testing::get<k>(args), p0, p1, p2, p3, p4); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) { - return internal::CallableHelper<return_type>::Call( - ::std::tr1::get<k>(args), p0, p1, p2, p3, p4, p5); + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl<return_type>( + internal::invoke_argument::AdlTag(), + ::testing::get<k>(args), p0, p1, p2, p3, p4, p5); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) { - return internal::CallableHelper<return_type>::Call( - ::std::tr1::get<k>(args), p0, p1, p2, p3, p4, p5, p6); + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl<return_type>( + internal::invoke_argument::AdlTag(), + ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)) { - return internal::CallableHelper<return_type>::Call( - ::std::tr1::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7); + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl<return_type>( + internal::invoke_argument::AdlTag(), + ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8)) { - return internal::CallableHelper<return_type>::Call( - ::std::tr1::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8); + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl<return_type>( + internal::invoke_argument::AdlTag(), + ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8); } ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) { - return internal::CallableHelper<return_type>::Call( - ::std::tr1::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl<return_type>( + internal::invoke_argument::AdlTag(), + ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); } // Various overloads for ReturnNew<T>(). @@ -4595,6 +4693,18 @@ } // namespace testing +// Include any custom actions added by the local installation. +// We must include this header at the end to make sure it can use the +// declarations from this file. +// This file was GENERATED by command: +// pump.py gmock-generated-actions.h.pump +// DO NOT EDIT BY HAND!!! + +#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ +#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ + +#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ + #endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ // This file was GENERATED by command: // pump.py gmock-generated-function-mockers.h.pump @@ -4908,6 +5018,31 @@ namespace internal { +struct AnyEq { + template <typename A, typename B> + bool operator()(const A& a, const B& b) const { return a == b; } +}; +struct AnyNe { + template <typename A, typename B> + bool operator()(const A& a, const B& b) const { return a != b; } +}; +struct AnyLt { + template <typename A, typename B> + bool operator()(const A& a, const B& b) const { return a < b; } +}; +struct AnyGt { + template <typename A, typename B> + bool operator()(const A& a, const B& b) const { return a > b; } +}; +struct AnyLe { + template <typename A, typename B> + bool operator()(const A& a, const B& b) const { return a <= b; } +}; +struct AnyGe { + template <typename A, typename B> + bool operator()(const A& a, const B& b) const { return a >= b; } +}; + // A match result listener that ignores the explanation. class DummyMatchResultListener : public MatchResultListener { public: @@ -5005,7 +5140,7 @@ // Constructs a null matcher. Needed for storing Matcher objects in STL // containers. A default-constructed matcher is not yet initialized. You // cannot use it until a valid value has been assigned to it. - Matcher() {} + explicit Matcher() {} // NOLINT // Constructs a matcher from its implementation. explicit Matcher(const MatcherInterface<T>* impl) @@ -5415,7 +5550,6 @@ template <typename MatcherTuple, typename ValueTuple> static bool Matches(const MatcherTuple& matcher_tuple, const ValueTuple& value_tuple) { - using ::std::tr1::get; return TuplePrefix<N - 1>::Matches(matcher_tuple, value_tuple) && get<N - 1>(matcher_tuple).Matches(get<N - 1>(value_tuple)); } @@ -5428,9 +5562,6 @@ static void ExplainMatchFailuresTo(const MatcherTuple& matchers, const ValueTuple& values, ::std::ostream* os) { - using ::std::tr1::tuple_element; - using ::std::tr1::get; - // First, describes failures in the first N - 1 fields. TuplePrefix<N - 1>::ExplainMatchFailuresTo(matchers, values, os); @@ -5483,7 +5614,6 @@ template <typename MatcherTuple, typename ValueTuple> bool TupleMatches(const MatcherTuple& matcher_tuple, const ValueTuple& value_tuple) { - using ::std::tr1::tuple_size; // Makes sure that matcher_tuple and value_tuple have the same // number of fields. GTEST_COMPILE_ASSERT_(tuple_size<MatcherTuple>::value == @@ -5499,7 +5629,6 @@ void ExplainMatchFailureTupleTo(const MatcherTuple& matchers, const ValueTuple& values, ::std::ostream* os) { - using ::std::tr1::tuple_size; TuplePrefix<tuple_size<MatcherTuple>::value>::ExplainMatchFailuresTo( matchers, values, os); } @@ -5511,7 +5640,7 @@ template <typename Tuple, typename Func, typename OutIter> class TransformTupleValuesHelper { private: - typedef typename ::std::tr1::tuple_size<Tuple> TupleSize; + typedef ::testing::tuple_size<Tuple> TupleSize; public: // For each member of tuple 't', taken in order, evaluates '*out++ = f(t)'. @@ -5524,7 +5653,7 @@ template <typename Tup, size_t kRemainingSize> struct IterateOverTuple { OutIter operator() (Func f, const Tup& t, OutIter out) const { - *out++ = f(::std::tr1::get<TupleSize::value - kRemainingSize>(t)); + *out++ = f(::testing::get<TupleSize::value - kRemainingSize>(t)); return IterateOverTuple<Tup, kRemainingSize - 1>()(f, t, out); } }; @@ -5577,55 +5706,90 @@ // used to match an int, a short, a double, etc). Therefore we use // a template type conversion operator in the implementation. // -// We define this as a macro in order to eliminate duplicated source -// code. -// // The following template definition assumes that the Rhs parameter is // a "bare" type (i.e. neither 'const T' nor 'T&'). -#define GMOCK_IMPLEMENT_COMPARISON_MATCHER_( \ - name, op, relation, negated_relation) \ - template <typename Rhs> class name##Matcher { \ - public: \ - explicit name##Matcher(const Rhs& rhs) : rhs_(rhs) {} \ - template <typename Lhs> \ - operator Matcher<Lhs>() const { \ - return MakeMatcher(new Impl<Lhs>(rhs_)); \ - } \ - private: \ - template <typename Lhs> \ - class Impl : public MatcherInterface<Lhs> { \ - public: \ - explicit Impl(const Rhs& rhs) : rhs_(rhs) {} \ - virtual bool MatchAndExplain(\ - Lhs lhs, MatchResultListener* /* listener */) const { \ - return lhs op rhs_; \ - } \ - virtual void DescribeTo(::std::ostream* os) const { \ - *os << relation " "; \ - UniversalPrint(rhs_, os); \ - } \ - virtual void DescribeNegationTo(::std::ostream* os) const { \ - *os << negated_relation " "; \ - UniversalPrint(rhs_, os); \ - } \ - private: \ - Rhs rhs_; \ - GTEST_DISALLOW_ASSIGN_(Impl); \ - }; \ - Rhs rhs_; \ - GTEST_DISALLOW_ASSIGN_(name##Matcher); \ +template <typename D, typename Rhs, typename Op> +class ComparisonBase { + public: + explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {} + template <typename Lhs> + operator Matcher<Lhs>() const { + return MakeMatcher(new Impl<Lhs>(rhs_)); } -// Implements Eq(v), Ge(v), Gt(v), Le(v), Lt(v), and Ne(v) -// respectively. -GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Eq, ==, "is equal to", "isn't equal to"); -GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Ge, >=, "is >=", "isn't >="); -GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Gt, >, "is >", "isn't >"); -GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Le, <=, "is <=", "isn't <="); -GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Lt, <, "is <", "isn't <"); -GMOCK_IMPLEMENT_COMPARISON_MATCHER_(Ne, !=, "isn't equal to", "is equal to"); + private: + template <typename Lhs> + class Impl : public MatcherInterface<Lhs> { + public: + explicit Impl(const Rhs& rhs) : rhs_(rhs) {} + virtual bool MatchAndExplain( + Lhs lhs, MatchResultListener* /* listener */) const { + return Op()(lhs, rhs_); + } + virtual void DescribeTo(::std::ostream* os) const { + *os << D::Desc() << " "; + UniversalPrint(rhs_, os); + } + virtual void DescribeNegationTo(::std::ostream* os) const { + *os << D::NegatedDesc() << " "; + UniversalPrint(rhs_, os); + } + private: + Rhs rhs_; + GTEST_DISALLOW_ASSIGN_(Impl); + }; + Rhs rhs_; + GTEST_DISALLOW_ASSIGN_(ComparisonBase); +}; -#undef GMOCK_IMPLEMENT_COMPARISON_MATCHER_ +template <typename Rhs> +class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> { + public: + explicit EqMatcher(const Rhs& rhs) + : ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) { } + static const char* Desc() { return "is equal to"; } + static const char* NegatedDesc() { return "isn't equal to"; } +}; +template <typename Rhs> +class NeMatcher : public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> { + public: + explicit NeMatcher(const Rhs& rhs) + : ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) { } + static const char* Desc() { return "isn't equal to"; } + static const char* NegatedDesc() { return "is equal to"; } +}; +template <typename Rhs> +class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> { + public: + explicit LtMatcher(const Rhs& rhs) + : ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) { } + static const char* Desc() { return "is <"; } + static const char* NegatedDesc() { return "isn't <"; } +}; +template <typename Rhs> +class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> { + public: + explicit GtMatcher(const Rhs& rhs) + : ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) { } + static const char* Desc() { return "is >"; } + static const char* NegatedDesc() { return "isn't >"; } +}; +template <typename Rhs> +class LeMatcher : public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> { + public: + explicit LeMatcher(const Rhs& rhs) + : ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) { } + static const char* Desc() { return "is <="; } + static const char* NegatedDesc() { return "isn't <="; } +}; +template <typename Rhs> +class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> { + public: + explicit GeMatcher(const Rhs& rhs) + : ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) { } + static const char* Desc() { return "is >="; } + static const char* NegatedDesc() { return "isn't >="; } +}; // Implements the polymorphic IsNull() matcher, which matches any raw or smart // pointer that is NULL. @@ -5634,7 +5798,11 @@ template <typename Pointer> bool MatchAndExplain(const Pointer& p, MatchResultListener* /* listener */) const { +#if GTEST_LANG_CXX11 + return p == nullptr; +#else // GTEST_LANG_CXX11 return GetRawPointer(p) == NULL; +#endif // GTEST_LANG_CXX11 } void DescribeTo(::std::ostream* os) const { *os << "is NULL"; } @@ -5650,7 +5818,11 @@ template <typename Pointer> bool MatchAndExplain(const Pointer& p, MatchResultListener* /* listener */) const { +#if GTEST_LANG_CXX11 + return p != nullptr; +#else // GTEST_LANG_CXX11 return GetRawPointer(p) != NULL; +#endif // GTEST_LANG_CXX11 } void DescribeTo(::std::ostream* os) const { *os << "isn't NULL"; } @@ -6024,51 +6196,64 @@ // used to match a tuple<int, short>, a tuple<const long&, double>, // etc). Therefore we use a template type conversion operator in the // implementation. -// -// We define this as a macro in order to eliminate duplicated source -// code. -#define GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(name, op, relation) \ - class name##2Matcher { \ - public: \ - template <typename T1, typename T2> \ - operator Matcher< ::std::tr1::tuple<T1, T2> >() const { \ - return MakeMatcher(new Impl< ::std::tr1::tuple<T1, T2> >); \ - } \ - template <typename T1, typename T2> \ - operator Matcher<const ::std::tr1::tuple<T1, T2>&>() const { \ - return MakeMatcher(new Impl<const ::std::tr1::tuple<T1, T2>&>); \ - } \ - private: \ - template <typename Tuple> \ - class Impl : public MatcherInterface<Tuple> { \ - public: \ - virtual bool MatchAndExplain( \ - Tuple args, \ - MatchResultListener* /* listener */) const { \ - return ::std::tr1::get<0>(args) op ::std::tr1::get<1>(args); \ - } \ - virtual void DescribeTo(::std::ostream* os) const { \ - *os << "are " relation; \ - } \ - virtual void DescribeNegationTo(::std::ostream* os) const { \ - *os << "aren't " relation; \ - } \ - }; \ +template <typename D, typename Op> +class PairMatchBase { + public: + template <typename T1, typename T2> + operator Matcher< ::testing::tuple<T1, T2> >() const { + return MakeMatcher(new Impl< ::testing::tuple<T1, T2> >); + } + template <typename T1, typename T2> + operator Matcher<const ::testing::tuple<T1, T2>&>() const { + return MakeMatcher(new Impl<const ::testing::tuple<T1, T2>&>); } -// Implements Eq(), Ge(), Gt(), Le(), Lt(), and Ne() respectively. -GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Eq, ==, "an equal pair"); -GMOCK_IMPLEMENT_COMPARISON2_MATCHER_( - Ge, >=, "a pair where the first >= the second"); -GMOCK_IMPLEMENT_COMPARISON2_MATCHER_( - Gt, >, "a pair where the first > the second"); -GMOCK_IMPLEMENT_COMPARISON2_MATCHER_( - Le, <=, "a pair where the first <= the second"); -GMOCK_IMPLEMENT_COMPARISON2_MATCHER_( - Lt, <, "a pair where the first < the second"); -GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Ne, !=, "an unequal pair"); + private: + static ::std::ostream& GetDesc(::std::ostream& os) { // NOLINT + return os << D::Desc(); + } -#undef GMOCK_IMPLEMENT_COMPARISON2_MATCHER_ + template <typename Tuple> + class Impl : public MatcherInterface<Tuple> { + public: + virtual bool MatchAndExplain( + Tuple args, + MatchResultListener* /* listener */) const { + return Op()(::testing::get<0>(args), ::testing::get<1>(args)); + } + virtual void DescribeTo(::std::ostream* os) const { + *os << "are " << GetDesc; + } + virtual void DescribeNegationTo(::std::ostream* os) const { + *os << "aren't " << GetDesc; + } + }; +}; + +class Eq2Matcher : public PairMatchBase<Eq2Matcher, AnyEq> { + public: + static const char* Desc() { return "an equal pair"; } +}; +class Ne2Matcher : public PairMatchBase<Ne2Matcher, AnyNe> { + public: + static const char* Desc() { return "an unequal pair"; } +}; +class Lt2Matcher : public PairMatchBase<Lt2Matcher, AnyLt> { + public: + static const char* Desc() { return "a pair where the first < the second"; } +}; +class Gt2Matcher : public PairMatchBase<Gt2Matcher, AnyGt> { + public: + static const char* Desc() { return "a pair where the first > the second"; } +}; +class Le2Matcher : public PairMatchBase<Le2Matcher, AnyLe> { + public: + static const char* Desc() { return "a pair where the first <= the second"; } +}; +class Ge2Matcher : public PairMatchBase<Ge2Matcher, AnyGe> { + public: + static const char* Desc() { return "a pair where the first >= the second"; } +}; // Implements the Not(...) matcher for a particular argument type T. // We do not nest it inside the NotMatcher class template, as that @@ -6467,7 +6652,7 @@ template <typename M> class PredicateFormatterFromMatcher { public: - explicit PredicateFormatterFromMatcher(const M& m) : matcher_(m) {} + explicit PredicateFormatterFromMatcher(M m) : matcher_(internal::move(m)) {} // This template () operator allows a PredicateFormatterFromMatcher // object to act as a predicate-formatter suitable for using with @@ -6507,10 +6692,11 @@ // A helper function for converting a matcher to a predicate-formatter // without the user needing to explicitly write the type. This is // used for implementing ASSERT_THAT() and EXPECT_THAT(). +// Implementation detail: 'matcher' is received by-value to force decaying. template <typename M> inline PredicateFormatterFromMatcher<M> -MakePredicateFormatterFromMatcher(const M& matcher) { - return PredicateFormatterFromMatcher<M>(matcher); +MakePredicateFormatterFromMatcher(M matcher) { + return PredicateFormatterFromMatcher<M>(internal::move(matcher)); } // Implements the polymorphic floating point equality matcher, which matches @@ -6521,20 +6707,23 @@ class FloatingEqMatcher { public: // Constructor for FloatingEqMatcher. - // The matcher's input will be compared with rhs. The matcher treats two + // The matcher's input will be compared with expected. The matcher treats two // NANs as equal if nan_eq_nan is true. Otherwise, under IEEE standards, // equality comparisons between NANs will always return false. We specify a // negative max_abs_error_ term to indicate that ULP-based approximation will // be used for comparison. - FloatingEqMatcher(FloatType rhs, bool nan_eq_nan) : - rhs_(rhs), nan_eq_nan_(nan_eq_nan), max_abs_error_(-1) { + FloatingEqMatcher(FloatType expected, bool nan_eq_nan) : + expected_(expected), nan_eq_nan_(nan_eq_nan), max_abs_error_(-1) { } // Constructor that supports a user-specified max_abs_error that will be used // for comparison instead of ULP-based approximation. The max absolute // should be non-negative. - FloatingEqMatcher(FloatType rhs, bool nan_eq_nan, FloatType max_abs_error) : - rhs_(rhs), nan_eq_nan_(nan_eq_nan), max_abs_error_(max_abs_error) { + FloatingEqMatcher(FloatType expected, bool nan_eq_nan, + FloatType max_abs_error) + : expected_(expected), + nan_eq_nan_(nan_eq_nan), + max_abs_error_(max_abs_error) { GTEST_CHECK_(max_abs_error >= 0) << ", where max_abs_error is" << max_abs_error; } @@ -6543,16 +6732,18 @@ template <typename T> class Impl : public MatcherInterface<T> { public: - Impl(FloatType rhs, bool nan_eq_nan, FloatType max_abs_error) : - rhs_(rhs), nan_eq_nan_(nan_eq_nan), max_abs_error_(max_abs_error) {} + Impl(FloatType expected, bool nan_eq_nan, FloatType max_abs_error) + : expected_(expected), + nan_eq_nan_(nan_eq_nan), + max_abs_error_(max_abs_error) {} virtual bool MatchAndExplain(T value, - MatchResultListener* /* listener */) const { - const FloatingPoint<FloatType> lhs(value), rhs(rhs_); + MatchResultListener* listener) const { + const FloatingPoint<FloatType> actual(value), expected(expected_); // Compares NaNs first, if nan_eq_nan_ is true. - if (lhs.is_nan() || rhs.is_nan()) { - if (lhs.is_nan() && rhs.is_nan()) { + if (actual.is_nan() || expected.is_nan()) { + if (actual.is_nan() && expected.is_nan()) { return nan_eq_nan_; } // One is nan; the other is not nan. @@ -6560,12 +6751,24 @@ } if (HasMaxAbsError()) { // We perform an equality check so that inf will match inf, regardless - // of error bounds. If the result of value - rhs_ would result in + // of error bounds. If the result of value - expected_ would result in // overflow or if either value is inf, the default result is infinity, // which should only match if max_abs_error_ is also infinity. - return value == rhs_ || fabs(value - rhs_) <= max_abs_error_; + if (value == expected_) { + return true; + } + + const FloatType diff = value - expected_; + if (fabs(diff) <= max_abs_error_) { + return true; + } + + if (listener->IsInterested()) { + *listener << "which is " << diff << " from " << expected_; + } + return false; } else { - return lhs.AlmostEquals(rhs); + return actual.AlmostEquals(expected); } } @@ -6575,14 +6778,14 @@ // after outputting. const ::std::streamsize old_precision = os->precision( ::std::numeric_limits<FloatType>::digits10 + 2); - if (FloatingPoint<FloatType>(rhs_).is_nan()) { + if (FloatingPoint<FloatType>(expected_).is_nan()) { if (nan_eq_nan_) { *os << "is NaN"; } else { *os << "never matches"; } } else { - *os << "is approximately " << rhs_; + *os << "is approximately " << expected_; if (HasMaxAbsError()) { *os << " (absolute error <= " << max_abs_error_ << ")"; } @@ -6594,14 +6797,14 @@ // As before, get original precision. const ::std::streamsize old_precision = os->precision( ::std::numeric_limits<FloatType>::digits10 + 2); - if (FloatingPoint<FloatType>(rhs_).is_nan()) { + if (FloatingPoint<FloatType>(expected_).is_nan()) { if (nan_eq_nan_) { *os << "isn't NaN"; } else { *os << "is anything"; } } else { - *os << "isn't approximately " << rhs_; + *os << "isn't approximately " << expected_; if (HasMaxAbsError()) { *os << " (absolute error > " << max_abs_error_ << ")"; } @@ -6615,7 +6818,7 @@ return max_abs_error_ >= 0; } - const FloatType rhs_; + const FloatType expected_; const bool nan_eq_nan_; // max_abs_error will be used for value comparison when >= 0. const FloatType max_abs_error_; @@ -6623,27 +6826,29 @@ GTEST_DISALLOW_ASSIGN_(Impl); }; - // The following 3 type conversion operators allow FloatEq(rhs) and - // NanSensitiveFloatEq(rhs) to be used as a Matcher<float>, a + // The following 3 type conversion operators allow FloatEq(expected) and + // NanSensitiveFloatEq(expected) to be used as a Matcher<float>, a // Matcher<const float&>, or a Matcher<float&>, but nothing else. // (While Google's C++ coding style doesn't allow arguments passed // by non-const reference, we may see them in code not conforming to // the style. Therefore Google Mock needs to support them.) operator Matcher<FloatType>() const { - return MakeMatcher(new Impl<FloatType>(rhs_, nan_eq_nan_, max_abs_error_)); + return MakeMatcher( + new Impl<FloatType>(expected_, nan_eq_nan_, max_abs_error_)); } operator Matcher<const FloatType&>() const { return MakeMatcher( - new Impl<const FloatType&>(rhs_, nan_eq_nan_, max_abs_error_)); + new Impl<const FloatType&>(expected_, nan_eq_nan_, max_abs_error_)); } operator Matcher<FloatType&>() const { - return MakeMatcher(new Impl<FloatType&>(rhs_, nan_eq_nan_, max_abs_error_)); + return MakeMatcher( + new Impl<FloatType&>(expected_, nan_eq_nan_, max_abs_error_)); } private: - const FloatType rhs_; + const FloatType expected_; const bool nan_eq_nan_; // max_abs_error will be used for value comparison when >= 0. const FloatType max_abs_error_; @@ -6712,6 +6917,83 @@ GTEST_DISALLOW_ASSIGN_(PointeeMatcher); }; +// Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or +// reference that matches inner_matcher when dynamic_cast<T> is applied. +// The result of dynamic_cast<To> is forwarded to the inner matcher. +// If To is a pointer and the cast fails, the inner matcher will receive NULL. +// If To is a reference and the cast fails, this matcher returns false +// immediately. +template <typename To> +class WhenDynamicCastToMatcherBase { + public: + explicit WhenDynamicCastToMatcherBase(const Matcher<To>& matcher) + : matcher_(matcher) {} + + void DescribeTo(::std::ostream* os) const { + GetCastTypeDescription(os); + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const { + GetCastTypeDescription(os); + matcher_.DescribeNegationTo(os); + } + + protected: + const Matcher<To> matcher_; + + static string GetToName() { +#if GTEST_HAS_RTTI + return GetTypeName<To>(); +#else // GTEST_HAS_RTTI + return "the target type"; +#endif // GTEST_HAS_RTTI + } + + private: + static void GetCastTypeDescription(::std::ostream* os) { + *os << "when dynamic_cast to " << GetToName() << ", "; + } + + GTEST_DISALLOW_ASSIGN_(WhenDynamicCastToMatcherBase); +}; + +// Primary template. +// To is a pointer. Cast and forward the result. +template <typename To> +class WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase<To> { + public: + explicit WhenDynamicCastToMatcher(const Matcher<To>& matcher) + : WhenDynamicCastToMatcherBase<To>(matcher) {} + + template <typename From> + bool MatchAndExplain(From from, MatchResultListener* listener) const { + // TODO(sbenza): Add more detail on failures. ie did the dyn_cast fail? + To to = dynamic_cast<To>(from); + return MatchPrintAndExplain(to, this->matcher_, listener); + } +}; + +// Specialize for references. +// In this case we return false if the dynamic_cast fails. +template <typename To> +class WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> { + public: + explicit WhenDynamicCastToMatcher(const Matcher<To&>& matcher) + : WhenDynamicCastToMatcherBase<To&>(matcher) {} + + template <typename From> + bool MatchAndExplain(From& from, MatchResultListener* listener) const { + // We don't want an std::bad_cast here, so do the cast with pointers. + To* to = dynamic_cast<To*>(&from); + if (to == NULL) { + *listener << "which cannot be dynamic_cast to " << this->GetToName(); + return false; + } + return MatchPrintAndExplain(*to, this->matcher_, listener); + } +}; + // Implements the Field() matcher for matching a field (i.e. member // variable) of an object. template <typename Class, typename FieldType> @@ -6809,8 +7091,15 @@ *listener << "whose given property is "; // Cannot pass the return value (for example, int) to MatchPrintAndExplain, // which takes a non-const reference as argument. +#if defined(_PREFAST_ ) && _MSC_VER == 1800 + // Workaround bug in VC++ 2013's /analyze parser. + // https://connect.microsoft.com/VisualStudio/feedback/details/1106363/internal-compiler-error-with-analyze-due-to-failure-to-infer-move + posix::Abort(); // To make sure it is never run. + return false; +#else RefToConstProperty result = (obj.*property_)(); return MatchPrintAndExplain(result, matcher_, listener); +#endif } bool MatchAndExplainImpl(true_type /* is_pointer */, const Class* p, @@ -6976,6 +7265,67 @@ GTEST_DISALLOW_ASSIGN_(SizeIsMatcher); }; +// Implements a matcher that checks the begin()..end() distance of an STL-style +// container. +template <typename DistanceMatcher> +class BeginEndDistanceIsMatcher { + public: + explicit BeginEndDistanceIsMatcher(const DistanceMatcher& distance_matcher) + : distance_matcher_(distance_matcher) {} + + template <typename Container> + operator Matcher<Container>() const { + return MakeMatcher(new Impl<Container>(distance_matcher_)); + } + + template <typename Container> + class Impl : public MatcherInterface<Container> { + public: + typedef internal::StlContainerView< + GTEST_REMOVE_REFERENCE_AND_CONST_(Container)> ContainerView; + typedef typename std::iterator_traits< + typename ContainerView::type::const_iterator>::difference_type + DistanceType; + explicit Impl(const DistanceMatcher& distance_matcher) + : distance_matcher_(MatcherCast<DistanceType>(distance_matcher)) {} + + virtual void DescribeTo(::std::ostream* os) const { + *os << "distance between begin() and end() "; + distance_matcher_.DescribeTo(os); + } + virtual void DescribeNegationTo(::std::ostream* os) const { + *os << "distance between begin() and end() "; + distance_matcher_.DescribeNegationTo(os); + } + + virtual bool MatchAndExplain(Container container, + MatchResultListener* listener) const { +#if GTEST_HAS_STD_BEGIN_AND_END_ + using std::begin; + using std::end; + DistanceType distance = std::distance(begin(container), end(container)); +#else + DistanceType distance = std::distance(container.begin(), container.end()); +#endif + StringMatchResultListener distance_listener; + const bool result = + distance_matcher_.MatchAndExplain(distance, &distance_listener); + *listener << "whose distance between begin() and end() " << distance + << (result ? " matches" : " doesn't match"); + PrintIfNotEmpty(distance_listener.str(), listener->stream()); + return result; + } + + private: + const Matcher<DistanceType> distance_matcher_; + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + private: + const DistanceMatcher distance_matcher_; + GTEST_DISALLOW_ASSIGN_(BeginEndDistanceIsMatcher); +}; + // Implements an equality matcher for any STL-style container whose elements // support ==. This matcher is like Eq(), but its failure explanations provide // more detailed information that is useful when the container is used as a set. @@ -6993,9 +7343,10 @@ typedef typename View::type StlContainer; typedef typename View::const_reference StlContainerReference; - // We make a copy of rhs in case the elements in it are modified + // We make a copy of expected in case the elements in it are modified // after this matcher is created. - explicit ContainerEqMatcher(const Container& rhs) : rhs_(View::Copy(rhs)) { + explicit ContainerEqMatcher(const Container& expected) + : expected_(View::Copy(expected)) { // Makes sure the user doesn't instantiate this class template // with a const or reference type. (void)testing::StaticAssertTypeEq<Container, @@ -7004,11 +7355,11 @@ void DescribeTo(::std::ostream* os) const { *os << "equals "; - UniversalPrint(rhs_, os); + UniversalPrint(expected_, os); } void DescribeNegationTo(::std::ostream* os) const { *os << "does not equal "; - UniversalPrint(rhs_, os); + UniversalPrint(expected_, os); } template <typename LhsContainer> @@ -7020,7 +7371,7 @@ LhsView; typedef typename LhsView::type LhsStlContainer; StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs); - if (lhs_stl_container == rhs_) + if (lhs_stl_container == expected_) return true; ::std::ostream* const os = listener->stream(); @@ -7030,8 +7381,8 @@ for (typename LhsStlContainer::const_iterator it = lhs_stl_container.begin(); it != lhs_stl_container.end(); ++it) { - if (internal::ArrayAwareFind(rhs_.begin(), rhs_.end(), *it) == - rhs_.end()) { + if (internal::ArrayAwareFind(expected_.begin(), expected_.end(), *it) == + expected_.end()) { if (printed_header) { *os << ", "; } else { @@ -7044,8 +7395,8 @@ // Now check for missing values. bool printed_header2 = false; - for (typename StlContainer::const_iterator it = rhs_.begin(); - it != rhs_.end(); ++it) { + for (typename StlContainer::const_iterator it = expected_.begin(); + it != expected_.end(); ++it) { if (internal::ArrayAwareFind( lhs_stl_container.begin(), lhs_stl_container.end(), *it) == lhs_stl_container.end()) { @@ -7065,7 +7416,7 @@ } private: - const StlContainer rhs_; + const StlContainer expected_; GTEST_DISALLOW_ASSIGN_(ContainerEqMatcher); }; @@ -7191,7 +7542,7 @@ // reference, as they may be expensive to copy. We must use tuple // instead of pair here, as a pair cannot hold references (C++ 98, // 20.2.2 [lib.pairs]). - typedef ::std::tr1::tuple<const LhsValue&, const RhsValue&> InnerMatcherArg; + typedef ::testing::tuple<const LhsValue&, const RhsValue&> InnerMatcherArg; Impl(const TupleMatcher& tuple_matcher, const RhsStlContainer& rhs) // mono_tuple_matcher_ holds a monomorphic version of the tuple matcher. @@ -7928,7 +8279,7 @@ typedef typename View::value_type Element; typedef ::std::vector<Matcher<const Element&> > MatcherVec; MatcherVec matchers; - matchers.reserve(::std::tr1::tuple_size<MatcherTuple>::value); + matchers.reserve(::testing::tuple_size<MatcherTuple>::value); TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, ::std::back_inserter(matchers)); return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>( @@ -7953,7 +8304,7 @@ typedef typename View::value_type Element; typedef ::std::vector<Matcher<const Element&> > MatcherVec; MatcherVec matchers; - matchers.reserve(::std::tr1::tuple_size<MatcherTuple>::value); + matchers.reserve(::testing::tuple_size<MatcherTuple>::value); TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, ::std::back_inserter(matchers)); return MakeMatcher(new ElementsAreMatcherImpl<Container>( @@ -8007,6 +8358,81 @@ GTEST_DISALLOW_ASSIGN_(ElementsAreArrayMatcher); }; +// Given a 2-tuple matcher tm of type Tuple2Matcher and a value second +// of type Second, BoundSecondMatcher<Tuple2Matcher, Second>(tm, +// second) is a polymorphic matcher that matches a value x iff tm +// matches tuple (x, second). Useful for implementing +// UnorderedPointwise() in terms of UnorderedElementsAreArray(). +// +// BoundSecondMatcher is copyable and assignable, as we need to put +// instances of this class in a vector when implementing +// UnorderedPointwise(). +template <typename Tuple2Matcher, typename Second> +class BoundSecondMatcher { + public: + BoundSecondMatcher(const Tuple2Matcher& tm, const Second& second) + : tuple2_matcher_(tm), second_value_(second) {} + + template <typename T> + operator Matcher<T>() const { + return MakeMatcher(new Impl<T>(tuple2_matcher_, second_value_)); + } + + // We have to define this for UnorderedPointwise() to compile in + // C++98 mode, as it puts BoundSecondMatcher instances in a vector, + // which requires the elements to be assignable in C++98. The + // compiler cannot generate the operator= for us, as Tuple2Matcher + // and Second may not be assignable. + // + // However, this should never be called, so the implementation just + // need to assert. + void operator=(const BoundSecondMatcher& /*rhs*/) { + GTEST_LOG_(FATAL) << "BoundSecondMatcher should never be assigned."; + } + + private: + template <typename T> + class Impl : public MatcherInterface<T> { + public: + typedef ::testing::tuple<T, Second> ArgTuple; + + Impl(const Tuple2Matcher& tm, const Second& second) + : mono_tuple2_matcher_(SafeMatcherCast<const ArgTuple&>(tm)), + second_value_(second) {} + + virtual void DescribeTo(::std::ostream* os) const { + *os << "and "; + UniversalPrint(second_value_, os); + *os << " "; + mono_tuple2_matcher_.DescribeTo(os); + } + + virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { + return mono_tuple2_matcher_.MatchAndExplain(ArgTuple(x, second_value_), + listener); + } + + private: + const Matcher<const ArgTuple&> mono_tuple2_matcher_; + const Second second_value_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + const Tuple2Matcher tuple2_matcher_; + const Second second_value_; +}; + +// Given a 2-tuple matcher tm and a value second, +// MatcherBindSecond(tm, second) returns a matcher that matches a +// value x iff tm matches tuple (x, second). Useful for implementing +// UnorderedPointwise() in terms of UnorderedElementsAreArray(). +template <typename Tuple2Matcher, typename Second> +BoundSecondMatcher<Tuple2Matcher, Second> MatcherBindSecond( + const Tuple2Matcher& tm, const Second& second) { + return BoundSecondMatcher<Tuple2Matcher, Second>(tm, second); +} + // Returns the description for a matcher defined using the MATCHER*() // macro where the user-supplied description string is "", if // 'negation' is false; otherwise returns the description of the @@ -8021,7 +8447,7 @@ // ElementsAreArray(first, last) // ElementsAreArray(pointer, count) // ElementsAreArray(array) -// ElementsAreArray(vector) +// ElementsAreArray(container) // ElementsAreArray({ e1, e2, ..., en }) // // The ElementsAreArray() functions are like ElementsAre(...), except @@ -8053,10 +8479,10 @@ return ElementsAreArray(array, N); } -template <typename T, typename A> -inline internal::ElementsAreArrayMatcher<T> ElementsAreArray( - const ::std::vector<T, A>& vec) { - return ElementsAreArray(vec.begin(), vec.end()); +template <typename Container> +inline internal::ElementsAreArrayMatcher<typename Container::value_type> +ElementsAreArray(const Container& container) { + return ElementsAreArray(container.begin(), container.end()); } #if GTEST_HAS_STD_INITIALIZER_LIST_ @@ -8070,7 +8496,7 @@ // UnorderedElementsAreArray(first, last) // UnorderedElementsAreArray(pointer, count) // UnorderedElementsAreArray(array) -// UnorderedElementsAreArray(vector) +// UnorderedElementsAreArray(container) // UnorderedElementsAreArray({ e1, e2, ..., en }) // // The UnorderedElementsAreArray() functions are like @@ -8095,10 +8521,11 @@ return UnorderedElementsAreArray(array, N); } -template <typename T, typename A> -inline internal::UnorderedElementsAreArrayMatcher<T> -UnorderedElementsAreArray(const ::std::vector<T, A>& vec) { - return UnorderedElementsAreArray(vec.begin(), vec.end()); +template <typename Container> +inline internal::UnorderedElementsAreArrayMatcher< + typename Container::value_type> +UnorderedElementsAreArray(const Container& container) { + return UnorderedElementsAreArray(container.begin(), container.end()); } #if GTEST_HAS_STD_INITIALIZER_LIST_ @@ -8266,6 +8693,19 @@ return internal::PointeeMatcher<InnerMatcher>(inner_matcher); } +// Creates a matcher that matches a pointer or reference that matches +// inner_matcher when dynamic_cast<To> is applied. +// The result of dynamic_cast<To> is forwarded to the inner matcher. +// If To is a pointer and the cast fails, the inner matcher will receive NULL. +// If To is a reference and the cast fails, this matcher returns false +// immediately. +template <typename To> +inline PolymorphicMatcher<internal::WhenDynamicCastToMatcher<To> > +WhenDynamicCastTo(const Matcher<To>& inner_matcher) { + return MakePolymorphicMatcher( + internal::WhenDynamicCastToMatcher<To>(inner_matcher)); +} + // Creates a matcher that matches an object whose given field matches // 'matcher'. For example, // Field(&Foo::number, Ge(5)) @@ -8508,6 +8948,17 @@ return internal::SizeIsMatcher<SizeMatcher>(size_matcher); } +// Returns a matcher that matches the distance between the container's begin() +// iterator and its end() iterator, i.e. the size of the container. This matcher +// can be used instead of SizeIs with containers such as std::forward_list which +// do not implement size(). The container must provide const_iterator (with +// valid iterator_traits), begin() and end(). +template <typename DistanceMatcher> +inline internal::BeginEndDistanceIsMatcher<DistanceMatcher> +BeginEndDistanceIs(const DistanceMatcher& distance_matcher) { + return internal::BeginEndDistanceIsMatcher<DistanceMatcher>(distance_matcher); +} + // Returns a matcher that matches an equal container. // This matcher behaves like Eq(), but in the event of mismatch lists the // values that are included in one container but not the other. (Duplicate @@ -8554,12 +9005,80 @@ GTEST_REMOVE_CONST_(Container)> Pointwise(const TupleMatcher& tuple_matcher, const Container& rhs) { // This following line is for working around a bug in MSVC 8.0, - // which causes Container to be a const type sometimes. + // which causes Container to be a const type sometimes (e.g. when + // rhs is a const int[]).. typedef GTEST_REMOVE_CONST_(Container) RawContainer; return internal::PointwiseMatcher<TupleMatcher, RawContainer>( tuple_matcher, rhs); } +#if GTEST_HAS_STD_INITIALIZER_LIST_ + +// Supports the Pointwise(m, {a, b, c}) syntax. +template <typename TupleMatcher, typename T> +inline internal::PointwiseMatcher<TupleMatcher, std::vector<T> > Pointwise( + const TupleMatcher& tuple_matcher, std::initializer_list<T> rhs) { + return Pointwise(tuple_matcher, std::vector<T>(rhs)); +} + +#endif // GTEST_HAS_STD_INITIALIZER_LIST_ + +// UnorderedPointwise(pair_matcher, rhs) matches an STL-style +// container or a native array that contains the same number of +// elements as in rhs, where in some permutation of the container, its +// i-th element and rhs's i-th element (as a pair) satisfy the given +// pair matcher, for all i. Tuple2Matcher must be able to be safely +// cast to Matcher<tuple<const T1&, const T2&> >, where T1 and T2 are +// the types of elements in the LHS container and the RHS container +// respectively. +// +// This is like Pointwise(pair_matcher, rhs), except that the element +// order doesn't matter. +template <typename Tuple2Matcher, typename RhsContainer> +inline internal::UnorderedElementsAreArrayMatcher< + typename internal::BoundSecondMatcher< + Tuple2Matcher, typename internal::StlContainerView<GTEST_REMOVE_CONST_( + RhsContainer)>::type::value_type> > +UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, + const RhsContainer& rhs_container) { + // This following line is for working around a bug in MSVC 8.0, + // which causes RhsContainer to be a const type sometimes (e.g. when + // rhs_container is a const int[]). + typedef GTEST_REMOVE_CONST_(RhsContainer) RawRhsContainer; + + // RhsView allows the same code to handle RhsContainer being a + // STL-style container and it being a native C-style array. + typedef typename internal::StlContainerView<RawRhsContainer> RhsView; + typedef typename RhsView::type RhsStlContainer; + typedef typename RhsStlContainer::value_type Second; + const RhsStlContainer& rhs_stl_container = + RhsView::ConstReference(rhs_container); + + // Create a matcher for each element in rhs_container. + ::std::vector<internal::BoundSecondMatcher<Tuple2Matcher, Second> > matchers; + for (typename RhsStlContainer::const_iterator it = rhs_stl_container.begin(); + it != rhs_stl_container.end(); ++it) { + matchers.push_back( + internal::MatcherBindSecond(tuple2_matcher, *it)); + } + + // Delegate the work to UnorderedElementsAreArray(). + return UnorderedElementsAreArray(matchers); +} + +#if GTEST_HAS_STD_INITIALIZER_LIST_ + +// Supports the UnorderedPointwise(m, {a, b, c}) syntax. +template <typename Tuple2Matcher, typename T> +inline internal::UnorderedElementsAreArrayMatcher< + typename internal::BoundSecondMatcher<Tuple2Matcher, T> > +UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, + std::initializer_list<T> rhs) { + return UnorderedPointwise(tuple2_matcher, std::vector<T>(rhs)); +} + +#endif // GTEST_HAS_STD_INITIALIZER_LIST_ + // Matches an STL-style container or a native array that contains at // least one element matching the given value or matcher. // @@ -8692,6 +9211,48 @@ } // namespace testing +// Include any custom callback matchers added by the local installation. +// We must include this header at the end to make sure it can use the +// declarations from this file. +// Copyright 2015, 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. +// +// ============================================================ +// An installation-specific extension point for gmock-matchers.h. +// ============================================================ +// +// Adds google3 callback support to CallableTraits. +// +#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_ +#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_ + +#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_ #endif // GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ namespace testing { @@ -9920,14 +10481,13 @@ public: // Constructs a wrapper from the given value/reference. explicit ReferenceOrValueWrapper(T value) - : value_(GTEST_MOVE_(value)) {} + : value_(::testing::internal::move(value)) { + } // Unwraps and returns the underlying value/reference, exactly as // originally passed. The behavior of calling this more than once on // the same object is unspecified. - T Unwrap() { - return GTEST_MOVE_(value_); - } + T Unwrap() { return ::testing::internal::move(value_); } // Provides nondestructive access to the underlying value/reference. // Always returns a const reference (more precisely, @@ -10025,7 +10585,8 @@ typedef ReferenceOrValueWrapper<T> Wrapper; explicit ActionResultHolder(Wrapper result) - : result_(GTEST_MOVE_(result)) {} + : result_(::testing::internal::move(result)) { + } Wrapper result_; @@ -10463,6 +11024,10 @@ #endif // GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ +#if GTEST_HAS_STD_FUNCTION_ +# include <functional> +#endif + namespace testing { namespace internal { @@ -10505,7 +11070,7 @@ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; MockSpec<F>& With(const Matcher<A1>& m1) { - this->current_spec().SetMatchers(::std::tr1::make_tuple(m1)); + this->current_spec().SetMatchers(::testing::make_tuple(m1)); return this->current_spec(); } @@ -10526,7 +11091,7 @@ typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2) { - this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2)); + this->current_spec().SetMatchers(::testing::make_tuple(m1, m2)); return this->current_spec(); } @@ -10548,7 +11113,7 @@ MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2, const Matcher<A3>& m3) { - this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3)); + this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3)); return this->current_spec(); } @@ -10570,7 +11135,7 @@ MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2, const Matcher<A3>& m3, const Matcher<A4>& m4) { - this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4)); + this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4)); return this->current_spec(); } @@ -10593,8 +11158,7 @@ MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2, const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5) { - this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, - m5)); + this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5)); return this->current_spec(); } @@ -10618,7 +11182,7 @@ MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2, const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5, const Matcher<A6>& m6) { - this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5, + this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, m6)); return this->current_spec(); } @@ -10643,7 +11207,7 @@ MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2, const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5, const Matcher<A6>& m6, const Matcher<A7>& m7) { - this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5, + this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, m6, m7)); return this->current_spec(); } @@ -10668,7 +11232,7 @@ MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2, const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5, const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8) { - this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5, + this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, m6, m7, m8)); return this->current_spec(); } @@ -10694,7 +11258,7 @@ const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5, const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8, const Matcher<A9>& m9) { - this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5, + this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, m6, m7, m8, m9)); return this->current_spec(); } @@ -10721,7 +11285,7 @@ const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5, const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8, const Matcher<A9>& m9, const Matcher<A10>& m10) { - this->current_spec().SetMatchers(::std::tr1::make_tuple(m1, m2, m3, m4, m5, + this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, m6, m7, m8, m9, m10)); return this->current_spec(); } @@ -10773,7 +11337,7 @@ #define GMOCK_METHOD0_(tn, constness, ct, Method, ...) \ GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ ) constness { \ - GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ == 0), \ this_method_does_not_take_0_arguments); \ @@ -10792,7 +11356,7 @@ #define GMOCK_METHOD1_(tn, constness, ct, Method, ...) \ GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1) constness { \ - GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ == 1), \ this_method_does_not_take_1_argument); \ @@ -10812,7 +11376,7 @@ GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2) constness { \ - GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ == 2), \ this_method_does_not_take_2_arguments); \ @@ -10834,7 +11398,7 @@ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3) constness { \ - GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ == 3), \ this_method_does_not_take_3_arguments); \ @@ -10860,7 +11424,7 @@ GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4) constness { \ - GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ == 4), \ this_method_does_not_take_4_arguments); \ @@ -10888,7 +11452,7 @@ GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5) constness { \ - GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ == 5), \ this_method_does_not_take_5_arguments); \ @@ -10918,7 +11482,7 @@ GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \ GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6) constness { \ - GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ == 6), \ this_method_does_not_take_6_arguments); \ @@ -10950,7 +11514,7 @@ GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \ GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7) constness { \ - GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ == 7), \ this_method_does_not_take_7_arguments); \ @@ -10984,7 +11548,7 @@ GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \ GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8) constness { \ - GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ == 8), \ this_method_does_not_take_8_arguments); \ @@ -11020,7 +11584,7 @@ GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \ GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \ GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9) constness { \ - GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ == 9), \ this_method_does_not_take_9_arguments); \ @@ -11060,7 +11624,7 @@ GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \ GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9, \ GMOCK_ARG_(tn, 10, __VA_ARGS__) gmock_a10) constness { \ - GTEST_COMPILE_ASSERT_((::std::tr1::tuple_size< \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ == 10), \ this_method_does_not_take_10_arguments); \ @@ -11275,6 +11839,17 @@ // point "2", and nothing should happen between the two check // points. The explicit check points make it easy to tell which // Bar("a") is called by which call to Foo(). +// +// MockFunction<F> can also be used to exercise code that accepts +// std::function<F> callbacks. To do so, use AsStdFunction() method +// to create std::function proxy forwarding to original object's Call. +// Example: +// +// TEST(FooTest, RunsCallbackWithBarArgument) { +// MockFunction<int(string)> callback; +// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1)); +// Foo(callback.AsStdFunction()); +// } template <typename F> class MockFunction; @@ -11285,6 +11860,14 @@ MOCK_METHOD0_T(Call, R()); +#if GTEST_HAS_STD_FUNCTION_ + std::function<R()> AsStdFunction() { + return [this]() -> R { + return this->Call(); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -11296,6 +11879,14 @@ MOCK_METHOD1_T(Call, R(A0)); +#if GTEST_HAS_STD_FUNCTION_ + std::function<R(A0)> AsStdFunction() { + return [this](A0 a0) -> R { + return this->Call(a0); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -11307,6 +11898,14 @@ MOCK_METHOD2_T(Call, R(A0, A1)); +#if GTEST_HAS_STD_FUNCTION_ + std::function<R(A0, A1)> AsStdFunction() { + return [this](A0 a0, A1 a1) -> R { + return this->Call(a0, a1); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -11318,6 +11917,14 @@ MOCK_METHOD3_T(Call, R(A0, A1, A2)); +#if GTEST_HAS_STD_FUNCTION_ + std::function<R(A0, A1, A2)> AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2) -> R { + return this->Call(a0, a1, a2); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -11329,6 +11936,14 @@ MOCK_METHOD4_T(Call, R(A0, A1, A2, A3)); +#if GTEST_HAS_STD_FUNCTION_ + std::function<R(A0, A1, A2, A3)> AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3) -> R { + return this->Call(a0, a1, a2, a3); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -11341,6 +11956,14 @@ MOCK_METHOD5_T(Call, R(A0, A1, A2, A3, A4)); +#if GTEST_HAS_STD_FUNCTION_ + std::function<R(A0, A1, A2, A3, A4)> AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) -> R { + return this->Call(a0, a1, a2, a3, a4); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -11353,6 +11976,14 @@ MOCK_METHOD6_T(Call, R(A0, A1, A2, A3, A4, A5)); +#if GTEST_HAS_STD_FUNCTION_ + std::function<R(A0, A1, A2, A3, A4, A5)> AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) -> R { + return this->Call(a0, a1, a2, a3, a4, a5); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -11365,6 +11996,14 @@ MOCK_METHOD7_T(Call, R(A0, A1, A2, A3, A4, A5, A6)); +#if GTEST_HAS_STD_FUNCTION_ + std::function<R(A0, A1, A2, A3, A4, A5, A6)> AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) -> R { + return this->Call(a0, a1, a2, a3, a4, a5, a6); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -11377,6 +12016,14 @@ MOCK_METHOD8_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7)); +#if GTEST_HAS_STD_FUNCTION_ + std::function<R(A0, A1, A2, A3, A4, A5, A6, A7)> AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) -> R { + return this->Call(a0, a1, a2, a3, a4, a5, a6, a7); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -11389,6 +12036,15 @@ MOCK_METHOD9_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8)); +#if GTEST_HAS_STD_FUNCTION_ + std::function<R(A0, A1, A2, A3, A4, A5, A6, A7, A8)> AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, + A8 a8) -> R { + return this->Call(a0, a1, a2, a3, a4, a5, a6, a7, a8); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -11402,6 +12058,15 @@ MOCK_METHOD10_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)); +#if GTEST_HAS_STD_FUNCTION_ + std::function<R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)> AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, + A8 a8, A9 a9) -> R { + return this->Call(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -11854,7 +12519,7 @@ // The type of the i-th (0-based) field of Tuple. #define GMOCK_FIELD_TYPE_(Tuple, i) \ - typename ::std::tr1::tuple_element<i, Tuple>::type + typename ::testing::tuple_element<i, Tuple>::type // TupleFields<Tuple, k0, ..., kn> is for selecting fields from a // tuple of type Tuple. It has two members: @@ -11877,14 +12542,13 @@ int k7, int k8, int k9> class TupleFields { public: - typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), + typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2), GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4), GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6), GMOCK_FIELD_TYPE_(Tuple, k7), GMOCK_FIELD_TYPE_(Tuple, k8), GMOCK_FIELD_TYPE_(Tuple, k9)> type; static type GetSelectedFields(const Tuple& t) { - using ::std::tr1::get; return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t), get<k5>(t), get<k6>(t), get<k7>(t), get<k8>(t), get<k9>(t)); } @@ -11895,9 +12559,8 @@ template <class Tuple> class TupleFields<Tuple, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1> { public: - typedef ::std::tr1::tuple<> type; + typedef ::testing::tuple<> type; static type GetSelectedFields(const Tuple& /* t */) { - using ::std::tr1::get; return type(); } }; @@ -11905,9 +12568,8 @@ template <class Tuple, int k0> class TupleFields<Tuple, k0, -1, -1, -1, -1, -1, -1, -1, -1, -1> { public: - typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0)> type; + typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0)> type; static type GetSelectedFields(const Tuple& t) { - using ::std::tr1::get; return type(get<k0>(t)); } }; @@ -11915,10 +12577,9 @@ template <class Tuple, int k0, int k1> class TupleFields<Tuple, k0, k1, -1, -1, -1, -1, -1, -1, -1, -1> { public: - typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), + typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), GMOCK_FIELD_TYPE_(Tuple, k1)> type; static type GetSelectedFields(const Tuple& t) { - using ::std::tr1::get; return type(get<k0>(t), get<k1>(t)); } }; @@ -11926,10 +12587,9 @@ template <class Tuple, int k0, int k1, int k2> class TupleFields<Tuple, k0, k1, k2, -1, -1, -1, -1, -1, -1, -1> { public: - typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), + typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2)> type; static type GetSelectedFields(const Tuple& t) { - using ::std::tr1::get; return type(get<k0>(t), get<k1>(t), get<k2>(t)); } }; @@ -11937,11 +12597,10 @@ template <class Tuple, int k0, int k1, int k2, int k3> class TupleFields<Tuple, k0, k1, k2, k3, -1, -1, -1, -1, -1, -1> { public: - typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), + typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2), GMOCK_FIELD_TYPE_(Tuple, k3)> type; static type GetSelectedFields(const Tuple& t) { - using ::std::tr1::get; return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t)); } }; @@ -11949,11 +12608,10 @@ template <class Tuple, int k0, int k1, int k2, int k3, int k4> class TupleFields<Tuple, k0, k1, k2, k3, k4, -1, -1, -1, -1, -1> { public: - typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), + typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2), GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4)> type; static type GetSelectedFields(const Tuple& t) { - using ::std::tr1::get; return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t)); } }; @@ -11961,12 +12619,11 @@ template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5> class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, -1, -1, -1, -1> { public: - typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), + typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2), GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4), GMOCK_FIELD_TYPE_(Tuple, k5)> type; static type GetSelectedFields(const Tuple& t) { - using ::std::tr1::get; return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t), get<k5>(t)); } @@ -11975,12 +12632,11 @@ template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6> class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, k6, -1, -1, -1> { public: - typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), + typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2), GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4), GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6)> type; static type GetSelectedFields(const Tuple& t) { - using ::std::tr1::get; return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t), get<k5>(t), get<k6>(t)); } @@ -11990,13 +12646,12 @@ int k7> class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, k6, k7, -1, -1> { public: - typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), + typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2), GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4), GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6), GMOCK_FIELD_TYPE_(Tuple, k7)> type; static type GetSelectedFields(const Tuple& t) { - using ::std::tr1::get; return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t), get<k5>(t), get<k6>(t), get<k7>(t)); } @@ -12006,13 +12661,12 @@ int k7, int k8> class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, k6, k7, k8, -1> { public: - typedef ::std::tr1::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), + typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0), GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2), GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4), GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6), GMOCK_FIELD_TYPE_(Tuple, k7), GMOCK_FIELD_TYPE_(Tuple, k8)> type; static type GetSelectedFields(const Tuple& t) { - using ::std::tr1::get; return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t), get<k5>(t), get<k6>(t), get<k7>(t), get<k8>(t)); } @@ -12382,29 +13036,29 @@ // undefined (e.g. hash_map). inline internal::ElementsAreMatcher< - std::tr1::tuple<> > + ::testing::tuple<> > ElementsAre() { - typedef std::tr1::tuple<> Args; + typedef ::testing::tuple<> Args; return internal::ElementsAreMatcher<Args>(Args()); } template <typename T1> inline internal::ElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type> > ElementsAre(const T1& e1) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type> Args; return internal::ElementsAreMatcher<Args>(Args(e1)); } template <typename T1, typename T2> inline internal::ElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type> > ElementsAre(const T1& e1, const T2& e2) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type> Args; return internal::ElementsAreMatcher<Args>(Args(e1, e2)); @@ -12412,12 +13066,12 @@ template <typename T1, typename T2, typename T3> inline internal::ElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type> > ElementsAre(const T1& e1, const T2& e2, const T3& e3) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type> Args; @@ -12426,13 +13080,13 @@ template <typename T1, typename T2, typename T3, typename T4> inline internal::ElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, typename internal::DecayArray<T4>::type> > ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12442,7 +13096,7 @@ template <typename T1, typename T2, typename T3, typename T4, typename T5> inline internal::ElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12450,7 +13104,7 @@ typename internal::DecayArray<T5>::type> > ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, const T5& e5) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12462,7 +13116,7 @@ template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> inline internal::ElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12471,7 +13125,7 @@ typename internal::DecayArray<T6>::type> > ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, const T5& e5, const T6& e6) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12484,7 +13138,7 @@ template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> inline internal::ElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12494,7 +13148,7 @@ typename internal::DecayArray<T7>::type> > ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, const T5& e5, const T6& e6, const T7& e7) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12508,7 +13162,7 @@ template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> inline internal::ElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12519,7 +13173,7 @@ typename internal::DecayArray<T8>::type> > ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, const T5& e5, const T6& e6, const T7& e7, const T8& e8) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12535,7 +13189,7 @@ template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> inline internal::ElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12547,7 +13201,7 @@ typename internal::DecayArray<T9>::type> > ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12564,7 +13218,7 @@ template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10> inline internal::ElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12578,7 +13232,7 @@ ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9, const T10& e10) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12597,29 +13251,29 @@ // that matches n elements in any order. We support up to n=10 arguments. inline internal::UnorderedElementsAreMatcher< - std::tr1::tuple<> > + ::testing::tuple<> > UnorderedElementsAre() { - typedef std::tr1::tuple<> Args; + typedef ::testing::tuple<> Args; return internal::UnorderedElementsAreMatcher<Args>(Args()); } template <typename T1> inline internal::UnorderedElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type> > UnorderedElementsAre(const T1& e1) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type> Args; return internal::UnorderedElementsAreMatcher<Args>(Args(e1)); } template <typename T1, typename T2> inline internal::UnorderedElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type> > UnorderedElementsAre(const T1& e1, const T2& e2) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type> Args; return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2)); @@ -12627,12 +13281,12 @@ template <typename T1, typename T2, typename T3> inline internal::UnorderedElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type> > UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type> Args; @@ -12641,13 +13295,13 @@ template <typename T1, typename T2, typename T3, typename T4> inline internal::UnorderedElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, typename internal::DecayArray<T4>::type> > UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12657,7 +13311,7 @@ template <typename T1, typename T2, typename T3, typename T4, typename T5> inline internal::UnorderedElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12665,7 +13319,7 @@ typename internal::DecayArray<T5>::type> > UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, const T5& e5) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12677,7 +13331,7 @@ template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> inline internal::UnorderedElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12686,7 +13340,7 @@ typename internal::DecayArray<T6>::type> > UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, const T5& e5, const T6& e6) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12700,7 +13354,7 @@ template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> inline internal::UnorderedElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12710,7 +13364,7 @@ typename internal::DecayArray<T7>::type> > UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, const T5& e5, const T6& e6, const T7& e7) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12725,7 +13379,7 @@ template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> inline internal::UnorderedElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12736,7 +13390,7 @@ typename internal::DecayArray<T8>::type> > UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, const T5& e5, const T6& e6, const T7& e7, const T8& e8) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12752,7 +13406,7 @@ template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> inline internal::UnorderedElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12764,7 +13418,7 @@ typename internal::DecayArray<T9>::type> > UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12781,7 +13435,7 @@ template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10> inline internal::UnorderedElementsAreMatcher< - std::tr1::tuple< + ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -12795,7 +13449,7 @@ UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9, const T10& e10) { - typedef std::tr1::tuple< + typedef ::testing::tuple< typename internal::DecayArray<T1>::type, typename internal::DecayArray<T2>::type, typename internal::DecayArray<T3>::type, @@ -13218,7 +13872,7 @@ return ::testing::internal::FormatMatcherDescription(\ negation, #name, \ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tr1::tuple<>()));\ + ::testing::tuple<>()));\ }\ GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ };\ @@ -13267,7 +13921,7 @@ return ::testing::internal::FormatMatcherDescription(\ negation, #name, \ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tr1::tuple<p0##_type>(p0)));\ + ::testing::tuple<p0##_type>(p0)));\ }\ GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ };\ @@ -13276,7 +13930,7 @@ return ::testing::Matcher<arg_type>(\ new gmock_Impl<arg_type>(p0));\ }\ - name##MatcherP(p0##_type gmock_p0) : p0(gmock_p0) {\ + explicit name##MatcherP(p0##_type gmock_p0) : p0(gmock_p0) {\ }\ p0##_type p0;\ private:\ @@ -13320,7 +13974,7 @@ return ::testing::internal::FormatMatcherDescription(\ negation, #name, \ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tr1::tuple<p0##_type, p1##_type>(p0, p1)));\ + ::testing::tuple<p0##_type, p1##_type>(p0, p1)));\ }\ GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ };\ @@ -13378,7 +14032,7 @@ return ::testing::internal::FormatMatcherDescription(\ negation, #name, \ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tr1::tuple<p0##_type, p1##_type, p2##_type>(p0, p1, \ + ::testing::tuple<p0##_type, p1##_type, p2##_type>(p0, p1, \ p2)));\ }\ GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ @@ -13441,7 +14095,7 @@ return ::testing::internal::FormatMatcherDescription(\ negation, #name, \ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, \ + ::testing::tuple<p0##_type, p1##_type, p2##_type, \ p3##_type>(p0, p1, p2, p3)));\ }\ GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ @@ -13512,7 +14166,7 @@ return ::testing::internal::FormatMatcherDescription(\ negation, #name, \ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ + ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ p4##_type>(p0, p1, p2, p3, p4)));\ }\ GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ @@ -13586,7 +14240,7 @@ return ::testing::internal::FormatMatcherDescription(\ negation, #name, \ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ + ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ p4##_type, p5##_type>(p0, p1, p2, p3, p4, p5)));\ }\ GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ @@ -13664,7 +14318,7 @@ return ::testing::internal::FormatMatcherDescription(\ negation, #name, \ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ + ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ p4##_type, p5##_type, p6##_type>(p0, p1, p2, p3, p4, p5, \ p6)));\ }\ @@ -13749,7 +14403,7 @@ return ::testing::internal::FormatMatcherDescription(\ negation, #name, \ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ + ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ p4##_type, p5##_type, p6##_type, p7##_type>(p0, p1, p2, \ p3, p4, p5, p6, p7)));\ }\ @@ -13840,7 +14494,7 @@ return ::testing::internal::FormatMatcherDescription(\ negation, #name, \ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ + ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ p4##_type, p5##_type, p6##_type, p7##_type, \ p8##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8)));\ }\ @@ -13936,7 +14590,7 @@ return ::testing::internal::FormatMatcherDescription(\ negation, #name, \ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ - ::std::tr1::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ + ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \ p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \ p9##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)));\ }\ @@ -14066,7 +14720,7 @@ class InvokeMethodAction { public: InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr) - : obj_ptr_(obj_ptr), method_ptr_(method_ptr) {} + : method_ptr_(method_ptr), obj_ptr_(obj_ptr) {} template <typename Result, typename ArgumentTuple> Result Perform(const ArgumentTuple& args) const { @@ -14075,8 +14729,11 @@ } private: - Class* const obj_ptr_; + // The order of these members matters. Reversing the order can trigger + // warning C4121 in MSVC (see + // http://computer-programming-forum.com/7-vc.net/6fbc30265f860ad1.htm ). const MethodPtr method_ptr_; + Class* const obj_ptr_; GTEST_DISALLOW_ASSIGN_(InvokeMethodAction); }; @@ -14152,7 +14809,7 @@ ACTION_TEMPLATE(ReturnArg, HAS_1_TEMPLATE_PARAMS(int, k), AND_0_VALUE_PARAMS()) { - return std::tr1::get<k>(args); + return ::testing::get<k>(args); } // Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the @@ -14160,7 +14817,7 @@ ACTION_TEMPLATE(SaveArg, HAS_1_TEMPLATE_PARAMS(int, k), AND_1_VALUE_PARAMS(pointer)) { - *pointer = ::std::tr1::get<k>(args); + *pointer = ::testing::get<k>(args); } // Action SaveArgPointee<k>(pointer) saves the value pointed to @@ -14168,7 +14825,7 @@ ACTION_TEMPLATE(SaveArgPointee, HAS_1_TEMPLATE_PARAMS(int, k), AND_1_VALUE_PARAMS(pointer)) { - *pointer = *::std::tr1::get<k>(args); + *pointer = *::testing::get<k>(args); } // Action SetArgReferee<k>(value) assigns 'value' to the variable @@ -14176,13 +14833,13 @@ ACTION_TEMPLATE(SetArgReferee, HAS_1_TEMPLATE_PARAMS(int, k), AND_1_VALUE_PARAMS(value)) { - typedef typename ::std::tr1::tuple_element<k, args_type>::type argk_type; + typedef typename ::testing::tuple_element<k, args_type>::type argk_type; // Ensures that argument #k is a reference. If you get a compiler // error on the next line, you are using SetArgReferee<k>(value) in // a mock function whose k-th (0-based) argument is not a reference. GTEST_COMPILE_ASSERT_(internal::is_reference<argk_type>::value, SetArgReferee_must_be_used_with_a_reference_argument); - ::std::tr1::get<k>(args) = value; + ::testing::get<k>(args) = value; } // Action SetArrayArgument<k>(first, last) copies the elements in @@ -14195,9 +14852,9 @@ AND_2_VALUE_PARAMS(first, last)) { // Visual Studio deprecates ::std::copy, so we use our own copy in that case. #ifdef _MSC_VER - internal::CopyElements(first, last, ::std::tr1::get<k>(args)); + internal::CopyElements(first, last, ::testing::get<k>(args)); #else - ::std::copy(first, last, ::std::tr1::get<k>(args)); + ::std::copy(first, last, ::testing::get<k>(args)); #endif } @@ -14206,7 +14863,7 @@ ACTION_TEMPLATE(DeleteArg, HAS_1_TEMPLATE_PARAMS(int, k), AND_0_VALUE_PARAMS()) { - delete ::std::tr1::get<k>(args); + delete ::testing::get<k>(args); } // This action returns the value pointed to by 'pointer'.
diff --git a/internal/ceres/gmock_gtest_all.cc b/internal/ceres/gmock_gtest_all.cc index 5b7ee84..2fc3e3c 100644 --- a/internal/ceres/gmock_gtest_all.cc +++ b/internal/ceres/gmock_gtest_all.cc
@@ -316,6 +316,8 @@ #include <algorithm> #include <iomanip> #include <limits> +#include <list> +#include <map> #include <ostream> // NOLINT #include <sstream> #include <vector> @@ -350,6 +352,7 @@ #elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. # include <windows.h> // NOLINT +# undef min #elif GTEST_OS_WINDOWS // We are on Windows proper. @@ -372,6 +375,7 @@ // cpplint thinks that the header is already included, so we want to // silence it. # include <windows.h> // NOLINT +# undef min #else @@ -394,6 +398,8 @@ #if GTEST_CAN_STREAM_RESULTS_ # include <arpa/inet.h> // NOLINT # include <netdb.h> // NOLINT +# include <sys/socket.h> // NOLINT +# include <sys/types.h> // NOLINT #endif // Indicates that this translation unit is part of Google Test's @@ -444,7 +450,7 @@ // GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is // part of Google Test's implementation; otherwise it's undefined. #if !GTEST_IMPLEMENTATION_ -// A user is trying to include this from his code - just say no. +// If this file is included from the user's 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_ @@ -501,6 +507,7 @@ const char kStackTraceDepthFlag[] = "stack_trace_depth"; const char kStreamResultToFlag[] = "stream_result_to"; const char kThrowOnFailureFlag[] = "throw_on_failure"; +const char kFlagfileFlag[] = "flagfile"; // A valid random seed must be in [1, kMaxRandomSeed]. const int kMaxRandomSeed = 99999; @@ -833,6 +840,10 @@ // CurrentStackTrace() will use to find and hide Google Test stack frames. virtual void UponLeavingGTest() = 0; + // This string is inserted in place of stack frames that are part of + // Google Test's implementation. + static const char* const kElidedFramesMarker; + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); }; @@ -840,26 +851,12 @@ // A working implementation of the OsStackTraceGetterInterface interface. class OsStackTraceGetter : public OsStackTraceGetterInterface { public: - OsStackTraceGetter() : caller_frame_(NULL) {} + OsStackTraceGetter() {} - virtual string CurrentStackTrace(int max_depth, int skip_count) - GTEST_LOCK_EXCLUDED_(mutex_); - - virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_); - - // This string is inserted in place of stack frames that are part of - // Google Test's implementation. - static const char* const kElidedFramesMarker; + virtual string CurrentStackTrace(int max_depth, int skip_count); + virtual void UponLeavingGTest(); 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); }; @@ -1369,32 +1366,6 @@ // platform. GTEST_API_ std::string GetLastErrnoDescription(); -# if GTEST_OS_WINDOWS -// Provides leak-safe Windows kernel handle ownership. -class AutoHandle { - public: - AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} - explicit AutoHandle(HANDLE handle) : handle_(handle) {} - - ~AutoHandle() { Reset(); } - - HANDLE Get() const { return handle_; } - void Reset() { Reset(INVALID_HANDLE_VALUE); } - void Reset(HANDLE handle) { - if (handle != handle_) { - if (handle_ != INVALID_HANDLE_VALUE) - ::CloseHandle(handle_); - handle_ = handle; - } - } - - private: - HANDLE handle_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); -}; -# endif // GTEST_OS_WINDOWS - // Attempts to parse a string into a positive integer pointed to by the // number parameter. Returns true if that is possible. // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use @@ -1667,6 +1638,12 @@ } // namespace internal static const char* GetDefaultFilter() { +#ifdef GTEST_TEST_FILTER_ENV_VAR_ + const char* const testbridge_test_only = getenv(GTEST_TEST_FILTER_ENV_VAR_); + if (testbridge_test_only != NULL) { + return testbridge_test_only; + } +#endif // GTEST_TEST_FILTER_ENV_VAR_ return kUniversalFilter; } @@ -1767,6 +1744,13 @@ "if exceptions are enabled or exit the program with a non-zero code " "otherwise."); +#if GTEST_USE_OWN_FLAGFILE_FLAG_ +GTEST_DEFINE_string_( + flagfile, + internal::StringFromGTestEnv("flagfile", ""), + "This flag specifies the flagfile to read command-line flags from."); +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ + namespace internal { // Generates a random number from [0, range), using a Linear @@ -1791,13 +1775,7 @@ // 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. -GTEST_API_ int g_init_gtest_count = 0; -static bool GTestIsInitialized() { return g_init_gtest_count != 0; } +static bool GTestIsInitialized() { return GetArgvs().size() > 0; } // Iterates over a vector of TestCases, keeping a running sum of the // results of calling a given int-returning method on each. @@ -1853,8 +1831,16 @@ // Mutex for linked pointers. GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); -// Application pathname gotten in InitGoogleTest. -std::string g_executable_path; +// A copy of all command line arguments. Set by InitGoogleTest(). +::std::vector<testing::internal::string> g_argvs; + +const ::std::vector<testing::internal::string>& GetArgvs() { +#if defined(GTEST_CUSTOM_GET_ARGVS_) + return GTEST_CUSTOM_GET_ARGVS_(); +#else // defined(GTEST_CUSTOM_GET_ARGVS_) + return g_argvs; +#endif // defined(GTEST_CUSTOM_GET_ARGVS_) +} // Returns the current application's name, removing directory path if that // is present. @@ -1862,9 +1848,9 @@ FilePath result; #if GTEST_OS_WINDOWS - result.Set(FilePath(g_executable_path).RemoveExtension("exe")); + result.Set(FilePath(GetArgvs()[0]).RemoveExtension("exe")); #else - result.Set(FilePath(g_executable_path)); + result.Set(FilePath(GetArgvs()[0])); #endif // GTEST_OS_WINDOWS return result.RemoveDirectoryName(); @@ -2256,8 +2242,12 @@ // CurrentOsStackTraceExceptTop(1), Foo() will be included in the // trace but Bar() and CurrentOsStackTraceExceptTop() won't. std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { - (void)skip_count; - return ""; + return os_stack_trace_getter()->CurrentStackTrace( + static_cast<int>(GTEST_FLAG(stack_trace_depth)), + skip_count + 1 + // Skips the user-specified number of frames plus this function + // itself. + ); // NOLINT } // Returns the current time in milliseconds. @@ -2286,21 +2276,13 @@ #elif GTEST_OS_WINDOWS && !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. + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) _ftime64(&now); -# pragma warning(pop) // Restores the warning state. -# else - - _ftime64(&now); - -# endif // _MSC_VER + GTEST_DISABLE_MSC_WARNINGS_POP_() return static_cast<TimeInMillis>(now.time) * 1000 + now.millitm; #elif GTEST_HAS_GETTIMEOFDAY_ @@ -2385,6 +2367,23 @@ #endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING +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 (::testing::internal::AlwaysTrue()) { + 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); +} + } // namespace internal // Constructs an empty Message. @@ -2440,6 +2439,13 @@ static_cast< ::std::string*>(NULL)) { } +// Swaps two AssertionResults. +void AssertionResult::swap(AssertionResult& other) { + using std::swap; + swap(success_, other.success_); + swap(message_, other.message_); +} + // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. AssertionResult AssertionResult::operator!() const { AssertionResult negation(!success_); @@ -2466,6 +2472,276 @@ namespace internal { +namespace edit_distance { +std::vector<EditType> CalculateOptimalEdits(const std::vector<size_t>& left, + const std::vector<size_t>& right) { + std::vector<std::vector<double> > costs( + left.size() + 1, std::vector<double>(right.size() + 1)); + std::vector<std::vector<EditType> > best_move( + left.size() + 1, std::vector<EditType>(right.size() + 1)); + + // Populate for empty right. + for (size_t l_i = 0; l_i < costs.size(); ++l_i) { + costs[l_i][0] = static_cast<double>(l_i); + best_move[l_i][0] = kRemove; + } + // Populate for empty left. + for (size_t r_i = 1; r_i < costs[0].size(); ++r_i) { + costs[0][r_i] = static_cast<double>(r_i); + best_move[0][r_i] = kAdd; + } + + for (size_t l_i = 0; l_i < left.size(); ++l_i) { + for (size_t r_i = 0; r_i < right.size(); ++r_i) { + if (left[l_i] == right[r_i]) { + // Found a match. Consume it. + costs[l_i + 1][r_i + 1] = costs[l_i][r_i]; + best_move[l_i + 1][r_i + 1] = kMatch; + continue; + } + + const double add = costs[l_i + 1][r_i]; + const double remove = costs[l_i][r_i + 1]; + const double replace = costs[l_i][r_i]; + if (add < remove && add < replace) { + costs[l_i + 1][r_i + 1] = add + 1; + best_move[l_i + 1][r_i + 1] = kAdd; + } else if (remove < add && remove < replace) { + costs[l_i + 1][r_i + 1] = remove + 1; + best_move[l_i + 1][r_i + 1] = kRemove; + } else { + // We make replace a little more expensive than add/remove to lower + // their priority. + costs[l_i + 1][r_i + 1] = replace + 1.00001; + best_move[l_i + 1][r_i + 1] = kReplace; + } + } + } + + // Reconstruct the best path. We do it in reverse order. + std::vector<EditType> best_path; + for (size_t l_i = left.size(), r_i = right.size(); l_i > 0 || r_i > 0;) { + EditType move = best_move[l_i][r_i]; + best_path.push_back(move); + l_i -= move != kAdd; + r_i -= move != kRemove; + } + std::reverse(best_path.begin(), best_path.end()); + return best_path; +} + +namespace { + +// Helper class to convert string into ids with deduplication. +class InternalStrings { + public: + size_t GetId(const std::string& str) { + IdMap::iterator it = ids_.find(str); + if (it != ids_.end()) return it->second; + size_t id = ids_.size(); + return ids_[str] = id; + } + + private: + typedef std::map<std::string, size_t> IdMap; + IdMap ids_; +}; + +} // namespace + +std::vector<EditType> CalculateOptimalEdits( + const std::vector<std::string>& left, + const std::vector<std::string>& right) { + std::vector<size_t> left_ids, right_ids; + { + InternalStrings intern_table; + for (size_t i = 0; i < left.size(); ++i) { + left_ids.push_back(intern_table.GetId(left[i])); + } + for (size_t i = 0; i < right.size(); ++i) { + right_ids.push_back(intern_table.GetId(right[i])); + } + } + return CalculateOptimalEdits(left_ids, right_ids); +} + +namespace { + +// Helper class that holds the state for one hunk and prints it out to the +// stream. +// It reorders adds/removes when possible to group all removes before all +// adds. It also adds the hunk header before printint into the stream. +class Hunk { + public: + Hunk(size_t left_start, size_t right_start) + : left_start_(left_start), + right_start_(right_start), + adds_(), + removes_(), + common_() {} + + void PushLine(char edit, const char* line) { + switch (edit) { + case ' ': + ++common_; + FlushEdits(); + hunk_.push_back(std::make_pair(' ', line)); + break; + case '-': + ++removes_; + hunk_removes_.push_back(std::make_pair('-', line)); + break; + case '+': + ++adds_; + hunk_adds_.push_back(std::make_pair('+', line)); + break; + } + } + + void PrintTo(std::ostream* os) { + PrintHeader(os); + FlushEdits(); + for (std::list<std::pair<char, const char*> >::const_iterator it = + hunk_.begin(); + it != hunk_.end(); ++it) { + *os << it->first << it->second << "\n"; + } + } + + bool has_edits() const { return adds_ || removes_; } + + private: + void FlushEdits() { + hunk_.splice(hunk_.end(), hunk_removes_); + hunk_.splice(hunk_.end(), hunk_adds_); + } + + // Print a unified diff header for one hunk. + // The format is + // "@@ -<left_start>,<left_length> +<right_start>,<right_length> @@" + // where the left/right parts are ommitted if unnecessary. + void PrintHeader(std::ostream* ss) const { + *ss << "@@ "; + if (removes_) { + *ss << "-" << left_start_ << "," << (removes_ + common_); + } + if (removes_ && adds_) { + *ss << " "; + } + if (adds_) { + *ss << "+" << right_start_ << "," << (adds_ + common_); + } + *ss << " @@\n"; + } + + size_t left_start_, right_start_; + size_t adds_, removes_, common_; + std::list<std::pair<char, const char*> > hunk_, hunk_adds_, hunk_removes_; +}; + +} // namespace + +// Create a list of diff hunks in Unified diff format. +// Each hunk has a header generated by PrintHeader above plus a body with +// lines prefixed with ' ' for no change, '-' for deletion and '+' for +// addition. +// 'context' represents the desired unchanged prefix/suffix around the diff. +// If two hunks are close enough that their contexts overlap, then they are +// joined into one hunk. +std::string CreateUnifiedDiff(const std::vector<std::string>& left, + const std::vector<std::string>& right, + size_t context) { + const std::vector<EditType> edits = CalculateOptimalEdits(left, right); + + size_t l_i = 0, r_i = 0, edit_i = 0; + std::stringstream ss; + while (edit_i < edits.size()) { + // Find first edit. + while (edit_i < edits.size() && edits[edit_i] == kMatch) { + ++l_i; + ++r_i; + ++edit_i; + } + + // Find the first line to include in the hunk. + const size_t prefix_context = std::min(l_i, context); + Hunk hunk(l_i - prefix_context + 1, r_i - prefix_context + 1); + for (size_t i = prefix_context; i > 0; --i) { + hunk.PushLine(' ', left[l_i - i].c_str()); + } + + // Iterate the edits until we found enough suffix for the hunk or the input + // is over. + size_t n_suffix = 0; + for (; edit_i < edits.size(); ++edit_i) { + if (n_suffix >= context) { + // Continue only if the next hunk is very close. + std::vector<EditType>::const_iterator it = edits.begin() + edit_i; + while (it != edits.end() && *it == kMatch) ++it; + if (it == edits.end() || (it - edits.begin()) - edit_i >= context) { + // There is no next edit or it is too far away. + break; + } + } + + EditType edit = edits[edit_i]; + // Reset count when a non match is found. + n_suffix = edit == kMatch ? n_suffix + 1 : 0; + + if (edit == kMatch || edit == kRemove || edit == kReplace) { + hunk.PushLine(edit == kMatch ? ' ' : '-', left[l_i].c_str()); + } + if (edit == kAdd || edit == kReplace) { + hunk.PushLine('+', right[r_i].c_str()); + } + + // Advance indices, depending on edit type. + l_i += edit != kAdd; + r_i += edit != kRemove; + } + + if (!hunk.has_edits()) { + // We are done. We don't want this hunk. + break; + } + + hunk.PrintTo(&ss); + } + return ss.str(); +} + +} // namespace edit_distance + +namespace { + +// The string representation of the values received in EqFailure() are already +// escaped. Split them on escaped '\n' boundaries. Leave all other escaped +// characters the same. +std::vector<std::string> SplitEscapedString(const std::string& str) { + std::vector<std::string> lines; + size_t start = 0, end = str.size(); + if (end > 2 && str[0] == '"' && str[end - 1] == '"') { + ++start; + --end; + } + bool escaped = false; + for (size_t i = start; i + 1 < end; ++i) { + if (escaped) { + escaped = false; + if (str[i] == 'n') { + lines.push_back(str.substr(start, i - start - 1)); + start = i + 1; + } + } else { + escaped = str[i] == '\\'; + } + } + lines.push_back(str.substr(start, end - start)); + return lines; +} + +} // namespace + // Constructs and returns the message for an equality assertion // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. // @@ -2500,6 +2776,17 @@ msg << "\nWhich is: " << expected_value; } + if (!expected_value.empty() && !actual_value.empty()) { + const std::vector<std::string> expected_lines = + SplitEscapedString(expected_value); + const std::vector<std::string> actual_lines = + SplitEscapedString(actual_value); + if (expected_lines.size() > 1 || actual_lines.size() > 1) { + msg << "\nWith diff:\n" + << edit_distance::CreateUnifiedDiff(expected_lines, actual_lines); + } + } + return AssertionFailure() << msg; } @@ -3371,14 +3658,15 @@ // Creates a Test object. -// The c'tor saves the values of all Google Test flags. +// The c'tor saves the states of all flags. Test::Test() - : gtest_flag_saver_(new internal::GTestFlagSaver) { + : gtest_flag_saver_(new GTEST_FLAG_SAVER_) { } -// The d'tor restores the values of all Google Test flags. +// The d'tor restores the states of all flags. The actual work is +// done by the d'tor of the gtest_flag_saver_ field, and thus not +// visible here. Test::~Test() { - delete gtest_flag_saver_; } // Sets up the test fixture. @@ -3447,8 +3735,8 @@ 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. + // Both TEST and TEST_F appear in same test case, which is incorrect. + // Tell the user how to fix this. // 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 @@ -3468,8 +3756,8 @@ << "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. + // Two fixture classes with the same name appear in two different + // namespaces, which is not allowed. Tell the user how to fix this. ADD_FAILURE() << "All tests in the same test case must use the same test fixture\n" << "class. However, in test case " @@ -3662,12 +3950,14 @@ const std::string& a_name, const char* a_type_param, const char* a_value_param, + internal::CodeLocation a_code_location, internal::TypeId fixture_class_id, internal::TestFactoryBase* factory) : test_case_name_(a_test_case_name), name_(a_name), type_param_(a_type_param ? new std::string(a_type_param) : NULL), value_param_(a_value_param ? new std::string(a_value_param) : NULL), + location_(a_code_location), fixture_class_id_(fixture_class_id), should_run_(false), is_disabled_(false), @@ -3691,6 +3981,7 @@ // this is not a typed or a type-parameterized test. // value_param: text representation of the test's value parameter, // or NULL if this is not a value-parameterized test. +// code_location: code location where the test is defined // 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 @@ -3702,20 +3993,21 @@ const char* name, const char* type_param, const char* value_param, + CodeLocation code_location, TypeId fixture_class_id, SetUpTestCaseFunc set_up_tc, TearDownTestCaseFunc tear_down_tc, TestFactoryBase* factory) { TestInfo* const test_info = new TestInfo(test_case_name, name, type_param, value_param, - fixture_class_id, factory); + code_location, fixture_class_id, factory); GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); return test_info; } #if GTEST_HAS_PARAM_TEST void ReportInvalidTestCaseType(const char* test_case_name, - const char* file, int line) { + CodeLocation code_location) { Message errors; errors << "Attempted redefinition of test case " << test_case_name << ".\n" @@ -3727,7 +4019,9 @@ << "probably rename one of the classes to put the tests into different\n" << "test cases."; - fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + fprintf(stderr, "%s %s", + FormatFileLocation(code_location.file.c_str(), + code_location.line).c_str(), errors.GetString().c_str()); } #endif // GTEST_HAS_PARAM_TEST @@ -4038,7 +4332,8 @@ COLOR_YELLOW }; -#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \ + !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT // Returns the character attribute for the given color. WORD GetColorAttribute(GTestColor color) { @@ -4083,6 +4378,8 @@ String::CStringEquals(term, "xterm-256color") || String::CStringEquals(term, "screen") || String::CStringEquals(term, "screen-256color") || + String::CStringEquals(term, "rxvt-unicode") || + String::CStringEquals(term, "rxvt-unicode-256color") || String::CStringEquals(term, "linux") || String::CStringEquals(term, "cygwin"); return stdout_is_tty && term_supports_color; @@ -4106,8 +4403,9 @@ va_list args; va_start(args, fmt); -#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || GTEST_OS_IOS - const bool use_color = false; +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || \ + GTEST_OS_IOS || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT + const bool use_color = AlwaysFalse(); #else static const bool in_color_mode = ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); @@ -4121,7 +4419,8 @@ return; } -#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \ + !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); // Gets the current text color. @@ -4696,34 +4995,39 @@ // Formats the given time in milliseconds as seconds. std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { ::std::stringstream ss; - ss << ms/1000.0; + ss << (static_cast<double>(ms) * 1e-3); return ss.str(); } +static bool PortableLocaltime(time_t seconds, struct tm* out) { +#if defined(_MSC_VER) + return localtime_s(out, &seconds) == 0; +#elif defined(__MINGW32__) || defined(__MINGW64__) + // MINGW <time.h> provides neither localtime_r nor localtime_s, but uses + // Windows' localtime(), which has a thread-local tm buffer. + struct tm* tm_ptr = localtime(&seconds); // NOLINT + if (tm_ptr == NULL) + return false; + *out = *tm_ptr; + return true; +#else + return localtime_r(&seconds, out) != NULL; +#endif +} + // Converts the given epoch time in milliseconds to a date string in the ISO // 8601 format, without the timezone information. std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) { - // Using non-reentrant version as localtime_r is not portable. - time_t seconds = static_cast<time_t>(ms / 1000); -#ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4996) // Temporarily disables warning 4996 - // (function or variable may be unsafe). - const struct tm* const time_struct = localtime(&seconds); // NOLINT -# pragma warning(pop) // Restores the warning state again. -#else - const struct tm* const time_struct = localtime(&seconds); // NOLINT -#endif - if (time_struct == NULL) - return ""; // Invalid ms value - + struct tm time_struct; + if (!PortableLocaltime(static_cast<time_t>(ms / 1000), &time_struct)) + return ""; // YYYY-MM-DDThh:mm:ss - return StreamableToString(time_struct->tm_year + 1900) + "-" + - String::FormatIntWidth2(time_struct->tm_mon + 1) + "-" + - String::FormatIntWidth2(time_struct->tm_mday) + "T" + - String::FormatIntWidth2(time_struct->tm_hour) + ":" + - String::FormatIntWidth2(time_struct->tm_min) + ":" + - String::FormatIntWidth2(time_struct->tm_sec); + return StreamableToString(time_struct.tm_year + 1900) + "-" + + String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" + + String::FormatIntWidth2(time_struct.tm_mday) + "T" + + String::FormatIntWidth2(time_struct.tm_hour) + ":" + + String::FormatIntWidth2(time_struct.tm_min) + ":" + + String::FormatIntWidth2(time_struct.tm_sec); } // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. @@ -4986,26 +5290,15 @@ // class OsStackTraceGetter -// Returns the current OS stack trace as an std::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. -// -string OsStackTraceGetter::CurrentStackTrace(int /* max_depth */, - int /* skip_count */) - GTEST_LOCK_EXCLUDED_(mutex_) { +const char* const OsStackTraceGetterInterface::kElidedFramesMarker = + "... " GTEST_NAME_ " internal frames ..."; + +string OsStackTraceGetter::CurrentStackTrace(int /*max_depth*/, + int /*skip_count*/) { return ""; } -void OsStackTraceGetter::UponLeavingGTest() - GTEST_LOCK_EXCLUDED_(mutex_) { -} - -const char* const -OsStackTraceGetter::kElidedFramesMarker = - "... " GTEST_NAME_ " internal frames ..."; +void OsStackTraceGetter::UponLeavingGTest() {} // A helper class that creates the premature-exit file in its // constructor and deletes the file in its destructor. @@ -5296,7 +5589,7 @@ // with another testing framework) and specify the former on the // command line for debugging. if (GTEST_FLAG(break_on_failure)) { -#if GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT // Using DebugBreak on Windows allows gtest to still break into a debugger // when a failure happens and both the --gtest_break_on_failure and // the --gtest_catch_exceptions flags are specified. @@ -5374,7 +5667,7 @@ // process. In either case the user does not want to see pop-up dialogs // about crashes - they are expected. if (impl()->catch_exceptions() || in_death_test_child_process) { -# if !GTEST_OS_WINDOWS_MOBILE +# if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT // SetErrorMode doesn't exist on CE. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); @@ -5477,17 +5770,10 @@ 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). + GTEST_DISABLE_MSC_WARNINGS_PUSH_(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 + GTEST_DISABLE_MSC_WARNINGS_POP_() global_test_part_result_repoter_( &default_global_test_part_result_reporter_), per_thread_test_part_result_reporter_( @@ -5598,6 +5884,11 @@ if (!post_flag_parse_init_performed_) { post_flag_parse_init_performed_ = true; +#if defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_) + // Register to send notifications about key process state changes. + listeners()->Append(new GTEST_CUSTOM_TEST_EVENT_LISTENER_()); +#endif // defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_) + #if GTEST_HAS_DEATH_TEST InitDeathTestSubprocessControlInfo(); SuppressTestEventsIfInSubprocess(); @@ -5731,6 +6022,11 @@ #if GTEST_HAS_DEATH_TEST in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); +# if defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_) + if (in_subprocess_for_death_test) { + GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_(); + } +# endif // defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_) #endif // GTEST_HAS_DEATH_TEST const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, @@ -6067,7 +6363,11 @@ // getter, and returns it. OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { if (os_stack_trace_getter_ == NULL) { +#ifdef GTEST_OS_STACK_TRACE_GETTER_ + os_stack_trace_getter_ = new GTEST_OS_STACK_TRACE_GETTER_; +#else os_stack_trace_getter_ = new OsStackTraceGetter; +#endif // GTEST_OS_STACK_TRACE_GETTER_ } return os_stack_trace_getter_; @@ -6366,6 +6666,58 @@ "(not one in your own code or tests), please report it to\n" "@G<" GTEST_DEV_EMAIL_ ">@D.\n"; +bool ParseGoogleTestFlag(const char* const arg) { + return ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, + >EST_FLAG(also_run_disabled_tests)) || + 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)) || + ParseBoolFlag(arg, kDeathTestUseFork, + >EST_FLAG(death_test_use_fork)) || + 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, kRandomSeedFlag, >EST_FLAG(random_seed)) || + ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || + ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || + ParseInt32Flag(arg, kStackTraceDepthFlag, + >EST_FLAG(stack_trace_depth)) || + ParseStringFlag(arg, kStreamResultToFlag, + >EST_FLAG(stream_result_to)) || + ParseBoolFlag(arg, kThrowOnFailureFlag, + >EST_FLAG(throw_on_failure)); +} + +#if GTEST_USE_OWN_FLAGFILE_FLAG_ +void LoadFlagsFromFile(const std::string& path) { + FILE* flagfile = posix::FOpen(path.c_str(), "r"); + if (!flagfile) { + fprintf(stderr, + "Unable to open file \"%s\"\n", + GTEST_FLAG(flagfile).c_str()); + fflush(stderr); + exit(EXIT_FAILURE); + } + std::string contents(ReadEntireFile(flagfile)); + posix::FClose(flagfile); + std::vector<std::string> lines; + SplitString(contents, '\n', &lines); + for (size_t i = 0; i < lines.size(); ++i) { + if (lines[i].empty()) + continue; + if (!ParseGoogleTestFlag(lines[i].c_str())) + g_help_flag = true; + } +} +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ + // 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. @@ -6379,35 +6731,24 @@ using internal::ParseInt32Flag; using internal::ParseStringFlag; - // Do we see a Google Test flag? - if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, - >EST_FLAG(also_run_disabled_tests)) || - 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)) || - ParseBoolFlag(arg, kDeathTestUseFork, - >EST_FLAG(death_test_use_fork)) || - 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, kRandomSeedFlag, >EST_FLAG(random_seed)) || - ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || - ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || - ParseInt32Flag(arg, kStackTraceDepthFlag, - >EST_FLAG(stack_trace_depth)) || - ParseStringFlag(arg, kStreamResultToFlag, - >EST_FLAG(stream_result_to)) || - ParseBoolFlag(arg, kThrowOnFailureFlag, - >EST_FLAG(throw_on_failure)) - ) { - // Yes. Shift the remainder of the argv list left by one. Note + bool remove_flag = false; + if (ParseGoogleTestFlag(arg)) { + remove_flag = true; +#if GTEST_USE_OWN_FLAGFILE_FLAG_ + } else if (ParseStringFlag(arg, kFlagfileFlag, >EST_FLAG(flagfile))) { + LoadFlagsFromFile(GTEST_FLAG(flagfile)); + remove_flag = true; +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ + } else if (arg_string == "--help" || arg_string == "-h" || + arg_string == "-?" || arg_string == "/?" || + HasGoogleTestFlagPrefix(arg)) { + // Both help flag and unrecognized Google Test flags (excluding + // internal ones) trigger help display. + g_help_flag = true; + } + + if (remove_flag) { + // 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. @@ -6421,12 +6762,6 @@ // We also need to decrement the iterator as we just removed // an element. i--; - } else if (arg_string == "--help" || arg_string == "-h" || - arg_string == "-?" || arg_string == "/?" || - HasGoogleTestFlagPrefix(arg)) { - // Both help flag and unrecognized Google Test flags (excluding - // internal ones) trigger help display. - g_help_flag = true; } } @@ -6453,24 +6788,16 @@ // 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 (GTestIsInitialized()) return; if (*argc <= 0) return; - internal::g_executable_path = internal::StreamableToString(argv[0]); - -#if 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); GetUnitTestImpl()->PostFlagParsingInit(); } @@ -6487,13 +6814,21 @@ // // Calling the function for the second time has no user-visible effect. void InitGoogleTest(int* argc, char** argv) { +#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) + GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv); +#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) internal::InitGoogleTestImpl(argc, argv); +#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) } // This overloaded version can be used in Windows programs compiled in // UNICODE mode. void InitGoogleTest(int* argc, wchar_t** argv) { +#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) + GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv); +#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) internal::InitGoogleTestImpl(argc, argv); +#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) } } // namespace testing @@ -6563,9 +6898,9 @@ // 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. +// included, or there will be a compiler error. This trick exists to +// prevent the accidental inclusion of gtest-internal-inl.h in the +// user's code. #define GTEST_IMPLEMENTATION_ 1 #undef GTEST_IMPLEMENTATION_ @@ -6614,7 +6949,9 @@ // Valid only for fast death tests. Indicates the code is running in the // child process of a fast style death test. +# if !GTEST_OS_WINDOWS static bool g_in_fast_death_test_child = false; +# endif // Returns a Boolean value indicating whether the caller is currently // executing in the context of the death test child process. Tools such as @@ -6663,6 +7000,14 @@ // KilledBySignal function-call operator. bool KilledBySignal::operator()(int exit_status) const { +# if defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) + { + bool result; + if (GTEST_KILLED_BY_SIGNAL_OVERRIDE_(signum_, exit_status, &result)) { + return result; + } + } +# endif // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; } # endif // !GTEST_OS_WINDOWS @@ -7369,6 +7714,11 @@ static ::std::vector<testing::internal::string> GetArgvsForDeathTestChildProcess() { ::std::vector<testing::internal::string> args = GetInjectableArgvs(); +# if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) + ::std::vector<testing::internal::string> extra_args = + GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_(); + args.insert(args.end(), extra_args.begin(), extra_args.end()); +# endif // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) return args; } // The name of the file in which the death test is located. @@ -7479,6 +7829,8 @@ *result = (&dummy < ptr); } +// Make sure AddressSanitizer does not tamper with the stack here. +GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ bool StackGrowsDown() { int dummy; bool result; @@ -7696,26 +8048,6 @@ 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 (::testing::internal::AlwaysTrue()) { - 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); -} - # if GTEST_OS_WINDOWS // Recreates the pipe and event handles from the provided parameters, // signals the event, and returns a file descriptor wrapped around the pipe @@ -7931,7 +8263,7 @@ // Returns the current working directory, or "" if unsuccessful. FilePath FilePath::GetCurrentDir() { -#if GTEST_OS_WINDOWS_MOBILE +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT // Windows CE doesn't have a current directory, so we just return // something reasonable. return FilePath(kCurrentDirectoryString); @@ -7940,7 +8272,14 @@ return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); #else char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; - return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); + char* result = getcwd(cwd, sizeof(cwd)); +# if GTEST_OS_NACL + // getcwd will likely fail in NaCl due to the sandbox, so return something + // reasonable. The user may have provided a shim implementation for getcwd, + // however, so fallback only when failure is detected. + return FilePath(result == NULL ? kCurrentDirectoryString : cwd); +# endif // GTEST_OS_NACL + return FilePath(result == NULL ? "" : cwd); #endif // GTEST_OS_WINDOWS_MOBILE } @@ -8248,15 +8587,16 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> +#include <fstream> -#if GTEST_OS_WINDOWS_MOBILE -# include <windows.h> // For TerminateProcess() -#elif GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS +# include <windows.h> # include <io.h> # include <sys/stat.h> +# include <map> // Used in ThreadLocal. #else # include <unistd.h> -#endif // GTEST_OS_WINDOWS_MOBILE +#endif // GTEST_OS_WINDOWS #if GTEST_OS_MAC # include <mach/mach_init.h> @@ -8266,15 +8606,16 @@ #if GTEST_OS_QNX # include <devctl.h> +# include <fcntl.h> # include <sys/procfs.h> #endif // GTEST_OS_QNX // 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. +// included, or there will be a compiler error. This trick exists to +// prevent the accidental inclusion of gtest-internal-inl.h in the +// user's code. #define GTEST_IMPLEMENTATION_ 1 #undef GTEST_IMPLEMENTATION_ @@ -8290,10 +8631,31 @@ const int kStdErrFileno = STDERR_FILENO; #endif // _MSC_VER -#if GTEST_OS_MAC +#if GTEST_OS_LINUX -// Returns the number of threads running in the process, or 0 to indicate that -// we cannot detect it. +namespace { +template <typename T> +T ReadProcFileField(const string& filename, int field) { + std::string dummy; + std::ifstream file(filename.c_str()); + while (field-- > 0) { + file >> dummy; + } + T output = 0; + file >> output; + return output; +} +} // namespace + +// Returns the number of active threads, or 0 when there is an error. +size_t GetThreadCount() { + const string filename = + (Message() << "/proc/" << getpid() << "/stat").GetString(); + return ReadProcFileField<int>(filename, 19); +} + +#elif GTEST_OS_MAC + size_t GetThreadCount() { const task_t task = mach_task_self(); mach_msg_type_number_t thread_count; @@ -8339,7 +8701,390 @@ return 0; } -#endif // GTEST_OS_MAC +#endif // GTEST_OS_LINUX + +#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS + +void SleepMilliseconds(int n) { + ::Sleep(n); +} + +AutoHandle::AutoHandle() + : handle_(INVALID_HANDLE_VALUE) {} + +AutoHandle::AutoHandle(Handle handle) + : handle_(handle) {} + +AutoHandle::~AutoHandle() { + Reset(); +} + +AutoHandle::Handle AutoHandle::Get() const { + return handle_; +} + +void AutoHandle::Reset() { + Reset(INVALID_HANDLE_VALUE); +} + +void AutoHandle::Reset(HANDLE handle) { + // Resetting with the same handle we already own is invalid. + if (handle_ != handle) { + if (IsCloseable()) { + ::CloseHandle(handle_); + } + handle_ = handle; + } else { + GTEST_CHECK_(!IsCloseable()) + << "Resetting a valid handle to itself is likely a programmer error " + "and thus not allowed."; + } +} + +bool AutoHandle::IsCloseable() const { + // Different Windows APIs may use either of these values to represent an + // invalid handle. + return handle_ != NULL && handle_ != INVALID_HANDLE_VALUE; +} + +Notification::Notification() + : event_(::CreateEvent(NULL, // Default security attributes. + TRUE, // Do not reset automatically. + FALSE, // Initially unset. + NULL)) { // Anonymous event. + GTEST_CHECK_(event_.Get() != NULL); +} + +void Notification::Notify() { + GTEST_CHECK_(::SetEvent(event_.Get()) != FALSE); +} + +void Notification::WaitForNotification() { + GTEST_CHECK_( + ::WaitForSingleObject(event_.Get(), INFINITE) == WAIT_OBJECT_0); +} + +Mutex::Mutex() + : owner_thread_id_(0), + type_(kDynamic), + critical_section_init_phase_(0), + critical_section_(new CRITICAL_SECTION) { + ::InitializeCriticalSection(critical_section_); +} + +Mutex::~Mutex() { + // Static mutexes are leaked intentionally. It is not thread-safe to try + // to clean them up. + // TODO(yukawa): Switch to Slim Reader/Writer (SRW) Locks, which requires + // nothing to clean it up but is available only on Vista and later. + // http://msdn.microsoft.com/en-us/library/windows/desktop/aa904937.aspx + if (type_ == kDynamic) { + ::DeleteCriticalSection(critical_section_); + delete critical_section_; + critical_section_ = NULL; + } +} + +void Mutex::Lock() { + ThreadSafeLazyInit(); + ::EnterCriticalSection(critical_section_); + owner_thread_id_ = ::GetCurrentThreadId(); +} + +void Mutex::Unlock() { + ThreadSafeLazyInit(); + // We don't protect writing to owner_thread_id_ here, as it's the + // caller's responsibility to ensure that the current thread holds the + // mutex when this is called. + owner_thread_id_ = 0; + ::LeaveCriticalSection(critical_section_); +} + +// Does nothing if the current thread holds the mutex. Otherwise, crashes +// with high probability. +void Mutex::AssertHeld() { + ThreadSafeLazyInit(); + GTEST_CHECK_(owner_thread_id_ == ::GetCurrentThreadId()) + << "The current thread is not holding the mutex @" << this; +} + +// Initializes owner_thread_id_ and critical_section_ in static mutexes. +void Mutex::ThreadSafeLazyInit() { + // Dynamic mutexes are initialized in the constructor. + if (type_ == kStatic) { + switch ( + ::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) { + case 0: + // If critical_section_init_phase_ was 0 before the exchange, we + // are the first to test it and need to perform the initialization. + owner_thread_id_ = 0; + critical_section_ = new CRITICAL_SECTION; + ::InitializeCriticalSection(critical_section_); + // Updates the critical_section_init_phase_ to 2 to signal + // initialization complete. + GTEST_CHECK_(::InterlockedCompareExchange( + &critical_section_init_phase_, 2L, 1L) == + 1L); + break; + case 1: + // Somebody else is already initializing the mutex; spin until they + // are done. + while (::InterlockedCompareExchange(&critical_section_init_phase_, + 2L, + 2L) != 2L) { + // Possibly yields the rest of the thread's time slice to other + // threads. + ::Sleep(0); + } + break; + + case 2: + break; // The mutex is already initialized and ready for use. + + default: + GTEST_CHECK_(false) + << "Unexpected value of critical_section_init_phase_ " + << "while initializing a static mutex."; + } + } +} + +namespace { + +class ThreadWithParamSupport : public ThreadWithParamBase { + public: + static HANDLE CreateThread(Runnable* runnable, + Notification* thread_can_start) { + ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start); + DWORD thread_id; + // TODO(yukawa): Consider to use _beginthreadex instead. + HANDLE thread_handle = ::CreateThread( + NULL, // Default security. + 0, // Default stack size. + &ThreadWithParamSupport::ThreadMain, + param, // Parameter to ThreadMainStatic + 0x0, // Default creation flags. + &thread_id); // Need a valid pointer for the call to work under Win98. + GTEST_CHECK_(thread_handle != NULL) << "CreateThread failed with error " + << ::GetLastError() << "."; + if (thread_handle == NULL) { + delete param; + } + return thread_handle; + } + + private: + struct ThreadMainParam { + ThreadMainParam(Runnable* runnable, Notification* thread_can_start) + : runnable_(runnable), + thread_can_start_(thread_can_start) { + } + scoped_ptr<Runnable> runnable_; + // Does not own. + Notification* thread_can_start_; + }; + + static DWORD WINAPI ThreadMain(void* ptr) { + // Transfers ownership. + scoped_ptr<ThreadMainParam> param(static_cast<ThreadMainParam*>(ptr)); + if (param->thread_can_start_ != NULL) + param->thread_can_start_->WaitForNotification(); + param->runnable_->Run(); + return 0; + } + + // Prohibit instantiation. + ThreadWithParamSupport(); + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParamSupport); +}; + +} // namespace + +ThreadWithParamBase::ThreadWithParamBase(Runnable *runnable, + Notification* thread_can_start) + : thread_(ThreadWithParamSupport::CreateThread(runnable, + thread_can_start)) { +} + +ThreadWithParamBase::~ThreadWithParamBase() { + Join(); +} + +void ThreadWithParamBase::Join() { + GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0) + << "Failed to join the thread with error " << ::GetLastError() << "."; +} + +// Maps a thread to a set of ThreadIdToThreadLocals that have values +// instantiated on that thread and notifies them when the thread exits. A +// ThreadLocal instance is expected to persist until all threads it has +// values on have terminated. +class ThreadLocalRegistryImpl { + public: + // Registers thread_local_instance as having value on the current thread. + // Returns a value that can be used to identify the thread from other threads. + static ThreadLocalValueHolderBase* GetValueOnCurrentThread( + const ThreadLocalBase* thread_local_instance) { + DWORD current_thread = ::GetCurrentThreadId(); + MutexLock lock(&mutex_); + ThreadIdToThreadLocals* const thread_to_thread_locals = + GetThreadLocalsMapLocked(); + ThreadIdToThreadLocals::iterator thread_local_pos = + thread_to_thread_locals->find(current_thread); + if (thread_local_pos == thread_to_thread_locals->end()) { + thread_local_pos = thread_to_thread_locals->insert( + std::make_pair(current_thread, ThreadLocalValues())).first; + StartWatcherThreadFor(current_thread); + } + ThreadLocalValues& thread_local_values = thread_local_pos->second; + ThreadLocalValues::iterator value_pos = + thread_local_values.find(thread_local_instance); + if (value_pos == thread_local_values.end()) { + value_pos = + thread_local_values + .insert(std::make_pair( + thread_local_instance, + linked_ptr<ThreadLocalValueHolderBase>( + thread_local_instance->NewValueForCurrentThread()))) + .first; + } + return value_pos->second.get(); + } + + static void OnThreadLocalDestroyed( + const ThreadLocalBase* thread_local_instance) { + std::vector<linked_ptr<ThreadLocalValueHolderBase> > value_holders; + // Clean up the ThreadLocalValues data structure while holding the lock, but + // defer the destruction of the ThreadLocalValueHolderBases. + { + MutexLock lock(&mutex_); + ThreadIdToThreadLocals* const thread_to_thread_locals = + GetThreadLocalsMapLocked(); + for (ThreadIdToThreadLocals::iterator it = + thread_to_thread_locals->begin(); + it != thread_to_thread_locals->end(); + ++it) { + ThreadLocalValues& thread_local_values = it->second; + ThreadLocalValues::iterator value_pos = + thread_local_values.find(thread_local_instance); + if (value_pos != thread_local_values.end()) { + value_holders.push_back(value_pos->second); + thread_local_values.erase(value_pos); + // This 'if' can only be successful at most once, so theoretically we + // could break out of the loop here, but we don't bother doing so. + } + } + } + // Outside the lock, let the destructor for 'value_holders' deallocate the + // ThreadLocalValueHolderBases. + } + + static void OnThreadExit(DWORD thread_id) { + GTEST_CHECK_(thread_id != 0) << ::GetLastError(); + std::vector<linked_ptr<ThreadLocalValueHolderBase> > value_holders; + // Clean up the ThreadIdToThreadLocals data structure while holding the + // lock, but defer the destruction of the ThreadLocalValueHolderBases. + { + MutexLock lock(&mutex_); + ThreadIdToThreadLocals* const thread_to_thread_locals = + GetThreadLocalsMapLocked(); + ThreadIdToThreadLocals::iterator thread_local_pos = + thread_to_thread_locals->find(thread_id); + if (thread_local_pos != thread_to_thread_locals->end()) { + ThreadLocalValues& thread_local_values = thread_local_pos->second; + for (ThreadLocalValues::iterator value_pos = + thread_local_values.begin(); + value_pos != thread_local_values.end(); + ++value_pos) { + value_holders.push_back(value_pos->second); + } + thread_to_thread_locals->erase(thread_local_pos); + } + } + // Outside the lock, let the destructor for 'value_holders' deallocate the + // ThreadLocalValueHolderBases. + } + + private: + // In a particular thread, maps a ThreadLocal object to its value. + typedef std::map<const ThreadLocalBase*, + linked_ptr<ThreadLocalValueHolderBase> > ThreadLocalValues; + // Stores all ThreadIdToThreadLocals having values in a thread, indexed by + // thread's ID. + typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals; + + // Holds the thread id and thread handle that we pass from + // StartWatcherThreadFor to WatcherThreadFunc. + typedef std::pair<DWORD, HANDLE> ThreadIdAndHandle; + + static void StartWatcherThreadFor(DWORD thread_id) { + // The returned handle will be kept in thread_map and closed by + // watcher_thread in WatcherThreadFunc. + HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, + FALSE, + thread_id); + GTEST_CHECK_(thread != NULL); + // We need to to pass a valid thread ID pointer into CreateThread for it + // to work correctly under Win98. + DWORD watcher_thread_id; + HANDLE watcher_thread = ::CreateThread( + NULL, // Default security. + 0, // Default stack size + &ThreadLocalRegistryImpl::WatcherThreadFunc, + reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)), + CREATE_SUSPENDED, + &watcher_thread_id); + GTEST_CHECK_(watcher_thread != NULL); + // Give the watcher thread the same priority as ours to avoid being + // blocked by it. + ::SetThreadPriority(watcher_thread, + ::GetThreadPriority(::GetCurrentThread())); + ::ResumeThread(watcher_thread); + ::CloseHandle(watcher_thread); + } + + // Monitors exit from a given thread and notifies those + // ThreadIdToThreadLocals about thread termination. + static DWORD WINAPI WatcherThreadFunc(LPVOID param) { + const ThreadIdAndHandle* tah = + reinterpret_cast<const ThreadIdAndHandle*>(param); + GTEST_CHECK_( + ::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0); + OnThreadExit(tah->first); + ::CloseHandle(tah->second); + delete tah; + return 0; + } + + // Returns map of thread local instances. + static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() { + mutex_.AssertHeld(); + static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals; + return map; + } + + // Protects access to GetThreadLocalsMapLocked() and its return value. + static Mutex mutex_; + // Protects access to GetThreadMapLocked() and its return value. + static Mutex thread_map_mutex_; +}; + +Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); +Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex); + +ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread( + const ThreadLocalBase* thread_local_instance) { + return ThreadLocalRegistryImpl::GetValueOnCurrentThread( + thread_local_instance); +} + +void ThreadLocalRegistry::OnThreadLocalDestroyed( + const ThreadLocalBase* thread_local_instance) { + ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance); +} + +#endif // GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS #if GTEST_USES_POSIX_RE @@ -8689,7 +9434,6 @@ return file_name + ":" + StreamableToString(line); } - GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) : severity_(severity) { const char* const marker = @@ -8710,10 +9454,7 @@ } // Disable Microsoft deprecation warnings for POSIX functions called from // this class (creat, dup, dup2, and close) -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable: 4996) -#endif // _MSC_VER +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) #if GTEST_HAS_STREAM_REDIRECTION @@ -8789,12 +9530,6 @@ } private: - // Reads the entire content of a file as an std::string. - static std::string ReadEntireFile(FILE* file); - - // Returns the size (in bytes) of a file. - static size_t GetFileSize(FILE* file); - const int fd_; // A stream to capture. int uncaptured_fd_; // Name of the temporary file holding the stderr output. @@ -8803,38 +9538,7 @@ GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); }; -// Returns the size (in bytes) of a file. -size_t CapturedStream::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. -std::string CapturedStream::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, bytes_read); - delete[] buffer; - - return content; -} - -# ifdef _MSC_VER -# pragma warning(pop) -# endif // _MSC_VER +GTEST_DISABLE_MSC_WARNINGS_POP_() static CapturedStream* g_captured_stderr = NULL; static CapturedStream* g_captured_stdout = NULL; @@ -8880,10 +9584,52 @@ #endif // GTEST_HAS_STREAM_REDIRECTION -#if GTEST_HAS_DEATH_TEST +std::string TempDir() { +#if GTEST_OS_WINDOWS_MOBILE + return "\\temp\\"; +#elif GTEST_OS_WINDOWS + const char* temp_dir = posix::GetEnv("TEMP"); + if (temp_dir == NULL || temp_dir[0] == '\0') + return "\\temp\\"; + else if (temp_dir[strlen(temp_dir) - 1] == '\\') + return temp_dir; + else + return std::string(temp_dir) + "\\"; +#elif GTEST_OS_LINUX_ANDROID + return "/sdcard/"; +#else + return "/tmp/"; +#endif // GTEST_OS_WINDOWS_MOBILE +} -// A copy of all command line arguments. Set by InitGoogleTest(). -::std::vector<testing::internal::string> g_argvs; +size_t GetFileSize(FILE* file) { + fseek(file, 0, SEEK_END); + return static_cast<size_t>(ftell(file)); +} + +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, bytes_read); + delete[] buffer; + + return content; +} + +#if GTEST_HAS_DEATH_TEST static const ::std::vector<testing::internal::string>* g_injected_test_argvs = NULL; // Owned. @@ -8898,7 +9644,7 @@ if (g_injected_test_argvs != NULL) { return *g_injected_test_argvs; } - return g_argvs; + return GetArgvs(); } #endif // GTEST_HAS_DEATH_TEST @@ -8972,6 +9718,9 @@ // // The value is considered true iff it's not "0". bool BoolFromGTestEnv(const char* flag, bool default_value) { +#if defined(GTEST_GET_BOOL_FROM_ENV_) + return GTEST_GET_BOOL_FROM_ENV_(flag, default_value); +#endif // defined(GTEST_GET_BOOL_FROM_ENV_) const std::string env_var = FlagToEnvVar(flag); const char* const string_value = posix::GetEnv(env_var.c_str()); return string_value == NULL ? @@ -8982,6 +9731,9 @@ // 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) { +#if defined(GTEST_GET_INT32_FROM_ENV_) + return GTEST_GET_INT32_FROM_ENV_(flag, default_value); +#endif // defined(GTEST_GET_INT32_FROM_ENV_) const std::string env_var = FlagToEnvVar(flag); const char* const string_value = posix::GetEnv(env_var.c_str()); if (string_value == NULL) { @@ -9004,6 +9756,9 @@ // 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) { +#if defined(GTEST_GET_STRING_FROM_ENV_) + return GTEST_GET_STRING_FROM_ENV_(flag, default_value); +#endif // defined(GTEST_GET_STRING_FROM_ENV_) const std::string env_var = FlagToEnvVar(flag); const char* const value = posix::GetEnv(env_var.c_str()); return value == NULL ? default_value : value; @@ -9057,6 +9812,7 @@ #include <ctype.h> #include <stdio.h> +#include <cwchar> #include <ostream> // NOLINT #include <string> @@ -9069,6 +9825,7 @@ // Prints a segment of bytes in the given object. GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, size_t count, ostream* os) { char text[5] = ""; @@ -9267,6 +10024,7 @@ template <typename CharType> GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static void PrintCharsAsStringTo( const CharType* begin, size_t len, ostream* os) { const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; @@ -9290,6 +10048,7 @@ template <typename CharType> GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static void UniversalPrintCharArray( const CharType* begin, size_t len, ostream* os) { // The code @@ -9346,7 +10105,7 @@ *os << "NULL"; } else { *os << ImplicitCast_<const void*>(s) << " pointing to "; - PrintCharsAsStringTo(s, wcslen(s), os); + PrintCharsAsStringTo(s, std::wcslen(s), os); } } #endif // wchar_t is native @@ -9414,9 +10173,9 @@ // 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. +// included, or there will be a compiler error. This trick exists to +// prevent the accidental inclusion of gtest-internal-inl.h in the +// user's code. #define GTEST_IMPLEMENTATION_ 1 #undef GTEST_IMPLEMENTATION_ @@ -9531,33 +10290,41 @@ return str; } +static std::vector<std::string> SplitIntoTestNames(const char* src) { + std::vector<std::string> name_vec; + src = SkipSpaces(src); + for (; src != NULL; src = SkipComma(src)) { + name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src))); + } + return name_vec; +} + // Verifies that registered_tests match the test names in -// defined_test_names_; returns registered_tests if successful, or +// registered_tests_; 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; + typedef RegisteredTestsMap::const_iterator RegisteredTestIter; registered_ = true; - // Skip initial whitespace in registered_tests since some - // preprocessors prefix stringizied literals with whitespace. - registered_tests = SkipSpaces(registered_tests); + std::vector<std::string> name_vec = SplitIntoTestNames(registered_tests); Message errors; - ::std::set<std::string> tests; - for (const char* names = registered_tests; names != NULL; - names = SkipComma(names)) { - const std::string name = GetPrefixUntilComma(names); + + std::set<std::string> tests; + for (std::vector<std::string>::const_iterator name_it = name_vec.begin(); + name_it != name_vec.end(); ++name_it) { + const std::string& name = *name_it; 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(); + for (RegisteredTestIter it = registered_tests_.begin(); + it != registered_tests_.end(); ++it) { - if (name == *it) { + if (name == it->first) { found = true; break; } @@ -9571,11 +10338,11 @@ } } - for (DefinedTestIter it = defined_test_names_.begin(); - it != defined_test_names_.end(); + for (RegisteredTestIter it = registered_tests_.begin(); + it != registered_tests_.end(); ++it) { - if (tests.count(*it) == 0) { - errors << "You forgot to list test " << *it << ".\n"; + if (tests.count(it->first) == 0) { + errors << "You forgot to list test " << it->first << ".\n"; } } @@ -10150,9 +10917,9 @@ // . [ sink ] . // // See Also: -// [1] Cormen, et al (2001). "Section 26.2: The Ford–Fulkerson method". -// "Introduction to Algorithms (Second ed.)", pp. 651–664. -// [2] "Ford–Fulkerson algorithm", Wikipedia, +// [1] Cormen, et al (2001). "Section 26.2: The Ford-Fulkerson method". +// "Introduction to Algorithms (Second ed.)", pp. 651-664. +// [2] "Ford-Fulkerson algorithm", Wikipedia, // 'http://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm' class MaxBipartiteMatchState { public: @@ -10699,9 +11466,12 @@ // Reports an uninteresting call (whose description is in msg) in the // manner specified by 'reaction'. void ReportUninterestingCall(CallReaction reaction, const string& msg) { + // Include a stack trace only if --gmock_verbose=info is specified. + const int stack_frames_to_skip = + GMOCK_FLAG(verbose) == kInfoVerbosity ? 3 : -1; switch (reaction) { case kAllow: - Log(kInfo, msg, 3); + Log(kInfo, msg, stack_frames_to_skip); break; case kWarn: Log(kWarning, @@ -10710,8 +11480,8 @@ "call should not happen. Do not suppress it by blindly adding " "an EXPECT_CALL() if you don't mean to enforce the call. " "See http://code.google.com/p/googlemock/wiki/CookBook#" - "Knowing_When_to_Expect for details.", - 3); + "Knowing_When_to_Expect for details.\n", + stack_frames_to_skip); break; default: // FAIL Expect(false, NULL, -1, msg); @@ -11378,8 +12148,9 @@ // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. +template <typename String> static bool ParseGoogleMockStringFlag(const char* str, const char* flag, - std::string* value) { + String* value) { // Gets the value of the flag as a string. const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
diff --git a/internal/ceres/gtest/gtest.h b/internal/ceres/gtest/gtest.h index 56e10fa..13771e8 100644 --- a/internal/ceres/gtest/gtest.h +++ b/internal/ceres/gtest/gtest.h
@@ -217,12 +217,12 @@ // // GTEST_OS_AIX - IBM AIX // GTEST_OS_CYGWIN - Cygwin +// GTEST_OS_FREEBSD - FreeBSD // GTEST_OS_HPUX - HP-UX // GTEST_OS_LINUX - Linux // GTEST_OS_LINUX_ANDROID - Google Android // GTEST_OS_MAC - Mac OS X // GTEST_OS_IOS - iOS -// GTEST_OS_IOS_SIMULATOR - iOS simulator // GTEST_OS_NACL - Google Native Client (NaCl) // GTEST_OS_OPENBSD - OpenBSD // GTEST_OS_QNX - QNX @@ -232,6 +232,8 @@ // GTEST_OS_WINDOWS_DESKTOP - Windows Desktop // GTEST_OS_WINDOWS_MINGW - MinGW // GTEST_OS_WINDOWS_MOBILE - Windows Mobile +// GTEST_OS_WINDOWS_PHONE - Windows Phone +// GTEST_OS_WINDOWS_RT - Windows Store App/WinRT // GTEST_OS_ZOS - z/OS // // Among the platforms, Cygwin, Linux, Max OS X, and Windows have the @@ -300,7 +302,7 @@ // // C++11 feature wrappers: // -// GTEST_MOVE_ - portability wrapper for std::move. +// testing::internal::move - portability wrapper for std::move. // // Synchronization: // Mutex, MutexLock, ThreadLocal, GetThreadCount() @@ -365,24 +367,49 @@ # include <TargetConditionals.h> #endif +#include <algorithm> // NOLINT #include <iostream> // NOLINT #include <sstream> // NOLINT #include <string> // NOLINT #include <utility> +#include <vector> // NOLINT -#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" -#define GTEST_FLAG_PREFIX_ "gtest_" -#define GTEST_FLAG_PREFIX_DASH_ "gtest-" -#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" -#define GTEST_NAME_ "Google Test" -#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/" +// Copyright 2015, 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. +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the GTEST_OS_* macro. +// It is separate from gtest-port.h so that custom/gtest-port.h can include it. -// 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__ +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ // Determines the platform on which Google Test is compiled. #ifdef __CYGWIN__ @@ -395,6 +422,19 @@ # define GTEST_OS_WINDOWS_MOBILE 1 # elif defined(__MINGW__) || defined(__MINGW32__) # define GTEST_OS_WINDOWS_MINGW 1 +# elif defined(WINAPI_FAMILY) +# include <winapifamily.h> +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +# define GTEST_OS_WINDOWS_DESKTOP 1 +# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) +# define GTEST_OS_WINDOWS_PHONE 1 +# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +# define GTEST_OS_WINDOWS_RT 1 +# else + // WINAPI_FAMILY defined but no known partition matched. + // Default to desktop. +# define GTEST_OS_WINDOWS_DESKTOP 1 +# endif # else # define GTEST_OS_WINDOWS_DESKTOP 1 # endif // _WIN32_WCE @@ -402,10 +442,9 @@ # define GTEST_OS_MAC 1 # if TARGET_OS_IPHONE # define GTEST_OS_IOS 1 -# if TARGET_IPHONE_SIMULATOR -# define GTEST_OS_IOS_SIMULATOR 1 -# endif # endif +#elif defined __FreeBSD__ +# define GTEST_OS_FREEBSD 1 #elif defined __linux__ # define GTEST_OS_LINUX 1 # if defined __ANDROID__ @@ -427,6 +466,114 @@ # define GTEST_OS_QNX 1 #endif // __CYGWIN__ +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ +// Copyright 2015, 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. +// +// Injection point for custom user configurations. +// The following macros can be defined: +// +// Flag related macros: +// GTEST_FLAG(flag_name) +// GTEST_USE_OWN_FLAGFILE_FLAG_ - Define to 0 when the system provides its +// own flagfile flag parsing. +// GTEST_DECLARE_bool_(name) +// GTEST_DECLARE_int32_(name) +// GTEST_DECLARE_string_(name) +// GTEST_DEFINE_bool_(name, default_val, doc) +// GTEST_DEFINE_int32_(name, default_val, doc) +// GTEST_DEFINE_string_(name, default_val, doc) +// +// Test filtering: +// GTEST_TEST_FILTER_ENV_VAR_ - The name of an environment variable that +// will be used if --GTEST_FLAG(test_filter) +// is not provided. +// +// Logging: +// GTEST_LOG_(severity) +// GTEST_CHECK_(condition) +// Functions LogToStderr() and FlushInfoLog() have to be provided too. +// +// Threading: +// GTEST_HAS_NOTIFICATION_ - Enabled if Notification is already provided. +// GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ - Enabled if Mutex and ThreadLocal are +// already provided. +// Must also provide GTEST_DECLARE_STATIC_MUTEX_(mutex) and +// GTEST_DEFINE_STATIC_MUTEX_(mutex) +// +// GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) +// GTEST_LOCK_EXCLUDED_(locks) +// +// ** Custom implementation starts here ** + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ + +#if !defined(GTEST_DEV_EMAIL_) +# define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" +# define GTEST_FLAG_PREFIX_ "gtest_" +# define GTEST_FLAG_PREFIX_DASH_ "gtest-" +# define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" +# define GTEST_NAME_ "Google Test" +# define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/" +#endif // !defined(GTEST_DEV_EMAIL_) + +#if !defined(GTEST_INIT_GOOGLE_TEST_NAME_) +# define GTEST_INIT_GOOGLE_TEST_NAME_ "testing::InitGoogleTest" +#endif // !defined(GTEST_INIT_GOOGLE_TEST_NAME_) + +// 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__ + +// Macros for disabling Microsoft Visual C++ warnings. +// +// GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 4385) +// /* code that triggers warnings C4800 and C4385 */ +// GTEST_DISABLE_MSC_WARNINGS_POP_() +#if _MSC_VER >= 1500 +# define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) \ + __pragma(warning(push)) \ + __pragma(warning(disable: warnings)) +# define GTEST_DISABLE_MSC_WARNINGS_POP_() \ + __pragma(warning(pop)) +#else +// Older versions of MSVC don't have __pragma. +# define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) +# define GTEST_DISABLE_MSC_WARNINGS_POP_() +#endif + #ifndef GTEST_LANG_CXX11 // gcc and clang define __GXX_EXPERIMENTAL_CXX0X__ when // -std={c,gnu}++{0x,11} is passed. The C++11 standard specifies a @@ -440,12 +587,35 @@ # endif #endif -// C++11 specifies that <initializer_list> provides std::initializer_list. Use -// that if gtest is used in C++11 mode and libstdc++ isn't very old (binaries -// targeting OS X 10.6 can build with clang but need to use gcc4.2's -// libstdc++). -#if GTEST_LANG_CXX11 && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20110325) +// Distinct from C++11 language support, some environments don't provide +// proper C++11 library support. Notably, it's possible to build in +// C++11 mode when targeting Mac OS X 10.6, which has an old libstdc++ +// with no C++11 support. +// +// libstdc++ has sufficient C++11 support as of GCC 4.6.0, __GLIBCXX__ +// 20110325, but maintenance releases in the 4.4 and 4.5 series followed +// this date, so check for those versions by their date stamps. +// https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html#abi.versioning +#if GTEST_LANG_CXX11 && \ + (!defined(__GLIBCXX__) || ( \ + __GLIBCXX__ >= 20110325ul && /* GCC >= 4.6.0 */ \ + /* Blacklist of patch releases of older branches: */ \ + __GLIBCXX__ != 20110416ul && /* GCC 4.4.6 */ \ + __GLIBCXX__ != 20120313ul && /* GCC 4.4.7 */ \ + __GLIBCXX__ != 20110428ul && /* GCC 4.5.3 */ \ + __GLIBCXX__ != 20120702ul)) /* GCC 4.5.4 */ +# define GTEST_STDLIB_CXX11 1 +#endif + +// Only use C++11 library features if the library provides them. +#if GTEST_STDLIB_CXX11 +# define GTEST_HAS_STD_BEGIN_AND_END_ 1 +# define GTEST_HAS_STD_FORWARD_LIST_ 1 +# define GTEST_HAS_STD_FUNCTION_ 1 # define GTEST_HAS_STD_INITIALIZER_LIST_ 1 +# define GTEST_HAS_STD_MOVE_ 1 +# define GTEST_HAS_STD_UNIQUE_PTR_ 1 +# define GTEST_HAS_STD_SHARED_PTR_ 1 #endif // C++11 specifies that <tuple> provides std::tuple. @@ -475,16 +645,23 @@ // Brings in definitions for functions used in the testing::internal::posix // namespace (read, write, close, chdir, isatty, stat). We do not currently // use them on Windows Mobile. -#if !GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS +# if !GTEST_OS_WINDOWS_MOBILE +# include <direct.h> +# include <io.h> +# endif +// In order to avoid having to include <windows.h>, use forward declaration +// assuming CRITICAL_SECTION is a typedef of _RTL_CRITICAL_SECTION. +// This assumption is verified by +// WindowsTypesTest.CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION. +struct _RTL_CRITICAL_SECTION; +#else // This assumes that non-Windows OSes provide unistd.h. For OSes where this // is not the case, we need to include headers that provide the functions // mentioned above. # include <unistd.h> # include <strings.h> -#elif !GTEST_OS_WINDOWS_MOBILE -# include <direct.h> -# include <io.h> -#endif +#endif // GTEST_OS_WINDOWS #if GTEST_OS_LINUX_ANDROID // Used to define __ANDROID_API__ matching the target NDK API level. @@ -501,7 +678,10 @@ # endif #endif -#if GTEST_HAS_POSIX_RE +#if GTEST_USES_PCRE +// The appropriate headers have already been included. + +#elif GTEST_HAS_POSIX_RE // On some platforms, <regex.h> needs someone to define size_t, and // won't compile otherwise. We can #include it here as we already @@ -523,7 +703,7 @@ // simple regex implementation instead. # define GTEST_USES_SIMPLE_RE 1 -#endif // GTEST_HAS_POSIX_RE +#endif // GTEST_USES_PCRE #ifndef GTEST_HAS_EXCEPTIONS // The user didn't tell us whether exceptions are enabled, so we need @@ -536,6 +716,15 @@ # define _HAS_EXCEPTIONS 1 # endif // _HAS_EXCEPTIONS # define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS +# elif defined(__clang__) +// clang defines __EXCEPTIONS iff exceptions are enabled before clang 220714, +// but iff cleanups are enabled after that. In Obj-C++ files, there can be +// cleanups for ObjC exceptions which also need cleanups, even if C++ exceptions +// are disabled. clang has __has_feature(cxx_exceptions) which checks for C++ +// exceptions starting at clang r206352, but which checked for cleanups prior to +// that. To reliably check for C++ exception availability with clang, check for +// __EXCEPTIONS && __has_feature(cxx_exceptions). +# define GTEST_HAS_EXCEPTIONS (__EXCEPTIONS && __has_feature(cxx_exceptions)) # elif defined(__GNUC__) && __EXCEPTIONS // gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. # define GTEST_HAS_EXCEPTIONS 1 @@ -661,13 +850,13 @@ // 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 -// available on Linux and Mac. +// The user didn't tell us explicitly, so we make reasonable assumptions about +// which platforms have pthreads support. // // To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 // to your compiler flags. # define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX \ - || GTEST_OS_QNX) + || GTEST_OS_QNX || GTEST_OS_FREEBSD || GTEST_OS_NACL) #endif // GTEST_HAS_PTHREAD #if GTEST_HAS_PTHREAD @@ -679,6 +868,15 @@ # include <time.h> // NOLINT #endif +// Determines if hash_map/hash_set are available. +// Only used for testing against those containers. +#if !defined(GTEST_HAS_HASH_MAP_) +# if _MSC_VER +# define GTEST_HAS_HASH_MAP_ 1 // Indicates that hash_map is available. +# define GTEST_HAS_HASH_SET_ 1 // Indicates that hash_set is available. +# endif // _MSC_VER +#endif // !defined(GTEST_HAS_HASH_MAP_) + // Determines whether Google Test can use tr1/tuple. You can define // this macro to 0 to prevent Google Test from using tuple (any // feature depending on tuple with be disabled in this mode). @@ -729,8 +927,18 @@ // To avoid conditional compilation everywhere, we make it // gtest-port.h's responsibility to #include the header implementing -// tr1/tuple. +// tuple. +#if GTEST_HAS_STD_TUPLE_ +# include <tuple> // IWYU pragma: export +# define GTEST_TUPLE_NAMESPACE_ ::std +#endif // GTEST_HAS_STD_TUPLE_ + +// We include tr1::tuple even if std::tuple is available to define printers for +// them. #if GTEST_HAS_TR1_TUPLE +# ifndef GTEST_TUPLE_NAMESPACE_ +# define GTEST_TUPLE_NAMESPACE_ ::std::tr1 +# endif // GTEST_TUPLE_NAMESPACE_ # if GTEST_USE_OWN_TR1_TUPLE // This file was GENERATED by command: @@ -1783,7 +1991,7 @@ // This prevents <boost/tr1/detail/config.hpp>, which defines // BOOST_HAS_TR1_TUPLE, from being #included by Boost's <tuple>. # define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED -# include <tuple> +# include <tuple> // IWYU pragma: export // NOLINT # elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) // GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header. This does @@ -1806,7 +2014,7 @@ # else // If the compiler is not GCC 4.0+, we assume the user is using a // spec-conforming TR1 implementation. -# include <tuple> // NOLINT +# include <tuple> // IWYU pragma: export // NOLINT # endif // GTEST_USE_OWN_TR1_TUPLE #endif // GTEST_HAS_TR1_TUPLE @@ -1840,7 +2048,8 @@ #ifndef GTEST_HAS_STREAM_REDIRECTION // By default, we assume that stream redirection is supported on all // platforms except known mobile ones. -# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN +# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || \ + GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT # define GTEST_HAS_STREAM_REDIRECTION 0 # else # define GTEST_HAS_STREAM_REDIRECTION 1 @@ -1852,12 +2061,11 @@ // abort() in a VC 7.1 application compiled as GUI in debug config // pops up a dialog window that cannot be suppressed programmatically. #if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ - (GTEST_OS_MAC && !GTEST_OS_IOS) || GTEST_OS_IOS_SIMULATOR || \ + (GTEST_OS_MAC && !GTEST_OS_IOS) || \ (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \ - GTEST_OS_OPENBSD || GTEST_OS_QNX) + GTEST_OS_OPENBSD || GTEST_OS_QNX || GTEST_OS_FREEBSD) # define GTEST_HAS_DEATH_TEST 1 -# include <vector> // NOLINT #endif // We don't support MSVC 7.1 with exceptions disabled now. Therefore @@ -1921,7 +2129,12 @@ // compiler the variable/parameter does not have to be used. #if defined(__GNUC__) && !defined(COMPILER_ICC) # define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) -#else +#elif defined(__clang__) +# if __has_attribute(unused) +# define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) +# endif +#endif +#ifndef GTEST_ATTRIBUTE_UNUSED_ # define GTEST_ATTRIBUTE_UNUSED_ #endif @@ -1947,30 +2160,18 @@ # define GTEST_MUST_USE_RESULT_ #endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC -#if GTEST_LANG_CXX11 -# define GTEST_MOVE_(x) ::std::move(x) // NOLINT -#else -# define GTEST_MOVE_(x) x -#endif - // MS C++ compiler emits warning when a conditional expression is compile time // constant. In some contexts this warning is false positive and needs to be // suppressed. Use the following two macros in such cases: // -// GTEST_INTENTIONAL_CONST_COND_PUSH_ +// GTEST_INTENTIONAL_CONST_COND_PUSH_() // while (true) { -// GTEST_INTENTIONAL_CONST_COND_POP_ +// GTEST_INTENTIONAL_CONST_COND_POP_() // } -#if defined(_MSC_VER) -# define GTEST_INTENTIONAL_CONST_COND_PUSH_ \ - __pragma(warning(push)) \ - __pragma(warning(disable: 4127)) -# define GTEST_INTENTIONAL_CONST_COND_POP_ \ - __pragma(warning(pop)) -#else -# define GTEST_INTENTIONAL_CONST_COND_PUSH_ -# define GTEST_INTENTIONAL_CONST_COND_POP_ -#endif +# define GTEST_INTENTIONAL_CONST_COND_PUSH_() \ + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4127) +# define GTEST_INTENTIONAL_CONST_COND_POP_() \ + GTEST_DISABLE_MSC_WARNINGS_POP_() // Determine whether the compiler supports Microsoft's Structured Exception // Handling. This is supported by several Windows compilers but generally @@ -1986,6 +2187,11 @@ # define GTEST_HAS_SEH 0 # endif +#define GTEST_IS_THREADSAFE \ + (GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ \ + || (GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT) \ + || GTEST_HAS_PTHREAD) + #endif // GTEST_HAS_SEH #ifdef _MSC_VER @@ -2041,10 +2247,33 @@ # define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ #endif // __clang__ +// A function level attribute to disable ThreadSanitizer instrumentation. +#if defined(__clang__) +# if __has_feature(thread_sanitizer) +# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ \ + __attribute__((no_sanitize_thread)) +# else +# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +# endif // __has_feature(thread_sanitizer) +#else +# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +#endif // __clang__ + namespace testing { class Message; +#if defined(GTEST_TUPLE_NAMESPACE_) +// Import tuple and friends into the ::testing namespace. +// It is part of our interface, having them in ::testing allows us to change +// their types as needed. +using GTEST_TUPLE_NAMESPACE_::get; +using GTEST_TUPLE_NAMESPACE_::make_tuple; +using GTEST_TUPLE_NAMESPACE_::tuple; +using GTEST_TUPLE_NAMESPACE_::tuple_size; +using GTEST_TUPLE_NAMESPACE_::tuple_element; +#endif // defined(GTEST_TUPLE_NAMESPACE_) + namespace internal { // A secret type that Google Test users don't know about. It has no @@ -2067,16 +2296,22 @@ // the expression is false, most compilers will issue a warning/error // containing the name of the variable. +#if GTEST_LANG_CXX11 +# define GTEST_COMPILE_ASSERT_(expr, msg) static_assert(expr, #msg) +#else // !GTEST_LANG_CXX11 template <bool> -struct CompileAssert { + struct CompileAssert { }; -#define GTEST_COMPILE_ASSERT_(expr, msg) \ +# define GTEST_COMPILE_ASSERT_(expr, msg) \ typedef ::testing::internal::CompileAssert<(static_cast<bool>(expr))> \ msg[static_cast<bool>(expr) ? 1 : -1] GTEST_ATTRIBUTE_UNUSED_ +#endif // !GTEST_LANG_CXX11 // Implementation details of GTEST_COMPILE_ASSERT_: // +// (In C++11, we simply use static_assert instead of the following) +// // - GTEST_COMPILE_ASSERT_ works by defining an array type that has -1 // elements (and thus is invalid) when the expression is false. // @@ -2123,7 +2358,9 @@ struct StaticAssertTypeEqHelper; template <typename T> -struct StaticAssertTypeEqHelper<T, T> {}; +struct StaticAssertTypeEqHelper<T, T> { + enum { value = true }; +}; // Evaluates to the number of elements in 'array'. #define GTEST_ARRAY_SIZE_(array) (sizeof(array) / sizeof(array[0])) @@ -2175,6 +2412,11 @@ } } + friend void swap(scoped_ptr& a, scoped_ptr& b) { + using std::swap; + swap(a.ptr_, b.ptr_); + } + private: T* ptr_; @@ -2298,13 +2540,18 @@ GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); }; -#define GTEST_LOG_(severity) \ +#if !defined(GTEST_LOG_) + +# define GTEST_LOG_(severity) \ ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ __FILE__, __LINE__).GetStream() inline void LogToStderr() {} inline void FlushInfoLog() { fflush(NULL); } +#endif // !defined(GTEST_LOG_) + +#if !defined(GTEST_CHECK_) // INTERNAL IMPLEMENTATION - DO NOT USE. // // GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition @@ -2319,12 +2566,13 @@ // 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. -#define GTEST_CHECK_(condition) \ +# define GTEST_CHECK_(condition) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::IsTrue(condition)) \ ; \ else \ GTEST_LOG_(FATAL) << "Condition " #condition " failed. " +#endif // !defined(GTEST_CHECK_) // An all-mode assert to verify that the given POSIX-style function // call returns 0 (indicating success). Known limitation: this @@ -2336,6 +2584,15 @@ GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ << gtest_error +#if GTEST_HAS_STD_MOVE_ +using std::move; +#else // GTEST_HAS_STD_MOVE_ +template <typename T> +const T& move(const T& t) { + return t; +} +#endif // GTEST_HAS_STD_MOVE_ + // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Use ImplicitCast_ as a safe version of static_cast for upcasting in @@ -2386,9 +2643,9 @@ // for compile-time type checking, and has no overhead in an // optimized build at run-time, as it will be optimized away // completely. - GTEST_INTENTIONAL_CONST_COND_PUSH_ + GTEST_INTENTIONAL_CONST_COND_PUSH_() if (false) { - GTEST_INTENTIONAL_CONST_COND_POP_ + GTEST_INTENTIONAL_CONST_COND_POP_() const To to = NULL; ::testing::internal::ImplicitCast_<From*>(to); } @@ -2409,6 +2666,11 @@ Derived* CheckedDowncastToActualType(Base* base) { #if GTEST_HAS_RTTI GTEST_CHECK_(typeid(*base) == typeid(Derived)); +#endif + +#if GTEST_HAS_DOWNCAST_ + return ::down_cast<Derived*>(base); +#elif GTEST_HAS_RTTI return dynamic_cast<Derived*>(base); // NOLINT #else return static_cast<Derived*>(base); // Poor man's downcast. @@ -2430,6 +2692,17 @@ #endif // GTEST_HAS_STREAM_REDIRECTION +// Returns a path to temporary directory. +GTEST_API_ std::string TempDir(); + +// Returns the size (in bytes) of a file. +GTEST_API_ size_t GetFileSize(FILE* file); + +// Reads the entire content of a file as a string. +GTEST_API_ std::string ReadEntireFile(FILE* file); + +// All command line arguments. +GTEST_API_ const ::std::vector<testing::internal::string>& GetArgvs(); #if GTEST_HAS_DEATH_TEST @@ -2437,18 +2710,15 @@ void SetInjectableArgvs(const ::std::vector<testing::internal::string>* new_argvs); -// A copy of all command line arguments. Set by InitGoogleTest(). -extern ::std::vector<testing::internal::string> g_argvs; #endif // GTEST_HAS_DEATH_TEST // Defines synchronization primitives. - -#if GTEST_HAS_PTHREAD - -// Sleeps for (roughly) n milli-seconds. This function is only for -// testing Google Test's own constructs. Don't use it in user tests, -// either directly or indirectly. +#if GTEST_IS_THREADSAFE +# if GTEST_HAS_PTHREAD +// Sleeps for (roughly) n milliseconds. This function is only for testing +// Google Test's own constructs. Don't use it in user tests, either +// directly or indirectly. inline void SleepMilliseconds(int n) { const timespec time = { 0, // 0 seconds. @@ -2456,7 +2726,13 @@ }; nanosleep(&time, NULL); } +# endif // GTEST_HAS_PTHREAD +# if GTEST_HAS_NOTIFICATION_ +// Notification has already been imported into the namespace. +// Nothing to do here. + +# elif GTEST_HAS_PTHREAD // Allows a controller thread to pause execution of newly created // threads until notified. Instances of this class must be created // and destroyed in the controller thread. @@ -2500,6 +2776,62 @@ GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); }; +# elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT + +GTEST_API_ void SleepMilliseconds(int n); + +// Provides leak-safe Windows kernel handle ownership. +// Used in death tests and in threading support. +class GTEST_API_ AutoHandle { + public: + // Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to + // avoid including <windows.h> in this header file. Including <windows.h> is + // undesirable because it defines a lot of symbols and macros that tend to + // conflict with client code. This assumption is verified by + // WindowsTypesTest.HANDLEIsVoidStar. + typedef void* Handle; + AutoHandle(); + explicit AutoHandle(Handle handle); + + ~AutoHandle(); + + Handle Get() const; + void Reset(); + void Reset(Handle handle); + + private: + // Returns true iff the handle is a valid handle object that can be closed. + bool IsCloseable() const; + + Handle handle_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); +}; + +// Allows a controller thread to pause execution of newly created +// threads until notified. Instances of this class must be created +// and destroyed in the controller thread. +// +// This class is only for testing Google Test's own constructs. Do not +// use it in user tests, either directly or indirectly. +class GTEST_API_ Notification { + public: + Notification(); + void Notify(); + void WaitForNotification(); + + private: + AutoHandle event_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); +}; +# endif // GTEST_HAS_NOTIFICATION_ + +// On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD +// defined, but we don't want to use MinGW's pthreads implementation, which +// has conformance problems with some versions of the POSIX standard. +# if GTEST_HAS_PTHREAD && !GTEST_OS_WINDOWS_MINGW + // As a C-function, ThreadFuncWithCLinkage cannot be templated itself. // Consequently, it cannot select a correct instantiation of ThreadWithParam // in order to call its Run(). Introducing ThreadWithParamBase as a @@ -2537,10 +2869,9 @@ template <typename T> class ThreadWithParam : public ThreadWithParamBase { public: - typedef void (*UserThreadFunc)(T); + typedef void UserThreadFunc(T); - ThreadWithParam( - UserThreadFunc func, T param, Notification* thread_can_start) + ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start) : func_(func), param_(param), thread_can_start_(thread_can_start), @@ -2567,7 +2898,7 @@ } private: - const UserThreadFunc func_; // User-supplied thread function. + UserThreadFunc* const func_; // User-supplied thread function. const T param_; // User-supplied parameter to the thread function. // When non-NULL, used to block execution until the controller thread // notifies. @@ -2577,26 +2908,293 @@ GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); }; +# endif // !GTEST_OS_WINDOWS && GTEST_HAS_PTHREAD || + // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ -// MutexBase and Mutex implement mutex on pthreads-based platforms. They -// are used in conjunction with class MutexLock: +# if GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ +// Mutex and ThreadLocal have already been imported into the namespace. +// Nothing to do here. + +# elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT + +// Mutex implements mutex on Windows platforms. It is used in conjunction +// with class MutexLock: // // Mutex mutex; // ... -// MutexLock lock(&mutex); // Acquires the mutex and releases it at the end -// // of the current scope. +// MutexLock lock(&mutex); // Acquires the mutex and releases it at the +// // end of the current scope. // -// MutexBase implements behavior for both statically and dynamically -// allocated mutexes. Do not use MutexBase directly. Instead, write -// the following to define a static mutex: -// +// A static Mutex *must* be defined or declared using one of the following +// macros: // GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex); -// -// You can forward declare a static mutex like this: -// // GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); // -// To create a dynamic mutex, just define an object of type Mutex. +// (A non-static Mutex is defined/declared in the usual way). +class GTEST_API_ Mutex { + public: + enum MutexType { kStatic = 0, kDynamic = 1 }; + // We rely on kStaticMutex being 0 as it is to what the linker initializes + // type_ in static mutexes. critical_section_ will be initialized lazily + // in ThreadSafeLazyInit(). + enum StaticConstructorSelector { kStaticMutex = 0 }; + + // This constructor intentionally does nothing. It relies on type_ being + // statically initialized to 0 (effectively setting it to kStatic) and on + // ThreadSafeLazyInit() to lazily initialize the rest of the members. + explicit Mutex(StaticConstructorSelector /*dummy*/) {} + + Mutex(); + ~Mutex(); + + void Lock(); + + void Unlock(); + + // Does nothing if the current thread holds the mutex. Otherwise, crashes + // with high probability. + void AssertHeld(); + + private: + // Initializes owner_thread_id_ and critical_section_ in static mutexes. + void ThreadSafeLazyInit(); + + // Per http://blogs.msdn.com/b/oldnewthing/archive/2004/02/23/78395.aspx, + // we assume that 0 is an invalid value for thread IDs. + unsigned int owner_thread_id_; + + // For static mutexes, we rely on these members being initialized to zeros + // by the linker. + MutexType type_; + long critical_section_init_phase_; // NOLINT + _RTL_CRITICAL_SECTION* critical_section_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); +}; + +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::Mutex mutex + +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ + ::testing::internal::Mutex mutex(::testing::internal::Mutex::kStaticMutex) + +// We cannot name this class MutexLock because the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms. That macro is used as a defensive measure to prevent against +// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than +// "MutexLock l(&mu)". Hence the typedef trick below. +class GTestMutexLock { + public: + explicit GTestMutexLock(Mutex* mutex) + : mutex_(mutex) { mutex_->Lock(); } + + ~GTestMutexLock() { mutex_->Unlock(); } + + private: + Mutex* const mutex_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); +}; + +typedef GTestMutexLock MutexLock; + +// Base class for ValueHolder<T>. Allows a caller to hold and delete a value +// without knowing its type. +class ThreadLocalValueHolderBase { + public: + virtual ~ThreadLocalValueHolderBase() {} +}; + +// Provides a way for a thread to send notifications to a ThreadLocal +// regardless of its parameter type. +class ThreadLocalBase { + public: + // Creates a new ValueHolder<T> object holding a default value passed to + // this ThreadLocal<T>'s constructor and returns it. It is the caller's + // responsibility not to call this when the ThreadLocal<T> instance already + // has a value on the current thread. + virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const = 0; + + protected: + ThreadLocalBase() {} + virtual ~ThreadLocalBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocalBase); +}; + +// Maps a thread to a set of ThreadLocals that have values instantiated on that +// thread and notifies them when the thread exits. A ThreadLocal instance is +// expected to persist until all threads it has values on have terminated. +class GTEST_API_ ThreadLocalRegistry { + public: + // Registers thread_local_instance as having value on the current thread. + // Returns a value that can be used to identify the thread from other threads. + static ThreadLocalValueHolderBase* GetValueOnCurrentThread( + const ThreadLocalBase* thread_local_instance); + + // Invoked when a ThreadLocal instance is destroyed. + static void OnThreadLocalDestroyed( + const ThreadLocalBase* thread_local_instance); +}; + +class GTEST_API_ ThreadWithParamBase { + public: + void Join(); + + protected: + class Runnable { + public: + virtual ~Runnable() {} + virtual void Run() = 0; + }; + + ThreadWithParamBase(Runnable *runnable, Notification* thread_can_start); + virtual ~ThreadWithParamBase(); + + private: + AutoHandle thread_; +}; + +// Helper class for testing Google Test's multi-threading constructs. +template <typename T> +class ThreadWithParam : public ThreadWithParamBase { + public: + typedef void UserThreadFunc(T); + + ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start) + : ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) { + } + virtual ~ThreadWithParam() {} + + private: + class RunnableImpl : public Runnable { + public: + RunnableImpl(UserThreadFunc* func, T param) + : func_(func), + param_(param) { + } + virtual ~RunnableImpl() {} + virtual void Run() { + func_(param_); + } + + private: + UserThreadFunc* const func_; + const T param_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(RunnableImpl); + }; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); +}; + +// Implements thread-local storage on Windows systems. +// +// // Thread 1 +// ThreadLocal<int> tl(100); // 100 is the default value for each thread. +// +// // Thread 2 +// tl.set(150); // Changes the value for thread 2 only. +// EXPECT_EQ(150, tl.get()); +// +// // Thread 1 +// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value. +// tl.set(200); +// EXPECT_EQ(200, tl.get()); +// +// The template type argument T must have a public copy constructor. +// In addition, the default ThreadLocal constructor requires T to have +// a public default constructor. +// +// The users of a TheadLocal instance have to make sure that all but one +// threads (including the main one) using that instance have exited before +// destroying it. Otherwise, the per-thread objects managed for them by the +// ThreadLocal instance are not guaranteed to be destroyed on all platforms. +// +// Google Test only uses global ThreadLocal objects. That means they +// will die after main() has returned. Therefore, no per-thread +// object managed by Google Test will be leaked as long as all threads +// using Google Test have exited when main() returns. +template <typename T> +class ThreadLocal : public ThreadLocalBase { + public: + ThreadLocal() : default_factory_(new DefaultValueHolderFactory()) {} + explicit ThreadLocal(const T& value) + : default_factory_(new InstanceValueHolderFactory(value)) {} + + ~ThreadLocal() { ThreadLocalRegistry::OnThreadLocalDestroyed(this); } + + T* pointer() { return GetOrCreateValue(); } + const T* pointer() const { return GetOrCreateValue(); } + const T& get() const { return *pointer(); } + void set(const T& value) { *pointer() = value; } + + private: + // Holds a value of T. Can be deleted via its base class without the caller + // knowing the type of T. + class ValueHolder : public ThreadLocalValueHolderBase { + public: + ValueHolder() : value_() {} + explicit ValueHolder(const T& value) : value_(value) {} + + T* pointer() { return &value_; } + + private: + T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); + }; + + + T* GetOrCreateValue() const { + return static_cast<ValueHolder*>( + ThreadLocalRegistry::GetValueOnCurrentThread(this))->pointer(); + } + + virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const { + return default_factory_->MakeNewHolder(); + } + + class ValueHolderFactory { + public: + ValueHolderFactory() {} + virtual ~ValueHolderFactory() {} + virtual ValueHolder* MakeNewHolder() const = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolderFactory); + }; + + class DefaultValueHolderFactory : public ValueHolderFactory { + public: + DefaultValueHolderFactory() {} + virtual ValueHolder* MakeNewHolder() const { return new ValueHolder(); } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory); + }; + + class InstanceValueHolderFactory : public ValueHolderFactory { + public: + explicit InstanceValueHolderFactory(const T& value) : value_(value) {} + virtual ValueHolder* MakeNewHolder() const { + return new ValueHolder(value_); + } + + private: + const T value_; // The value for each thread. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(InstanceValueHolderFactory); + }; + + scoped_ptr<ValueHolderFactory> default_factory_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); +}; + +# elif GTEST_HAS_PTHREAD + +// MutexBase and Mutex implement mutex on pthreads-based platforms. class MutexBase { public: // Acquires this mutex. @@ -2641,8 +3239,8 @@ }; // Forward-declares a static mutex. -# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ - extern ::testing::internal::MutexBase mutex +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::MutexBase mutex // Defines and statically (i.e. at link time) initializes a static mutex. // The initialization list here does not explicitly initialize each field, @@ -2650,8 +3248,8 @@ // particular, the owner_ field (a pthread_t) is not explicitly initialized. // This allows initialization to work whether pthread_t is a scalar or struct. // The flag -Wmissing-field-initializers must not be specified for this to work. -# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ - ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false } +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ + ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false } // The Mutex class can only be used for mutexes created at runtime. It // shares its API with MutexBase otherwise. @@ -2669,9 +3267,11 @@ GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); }; -// We cannot name this class MutexLock as the ctor declaration would +// We cannot name this class MutexLock because the ctor declaration would // conflict with a macro named MutexLock, which is defined on some -// platforms. Hence the typedef trick below. +// platforms. That macro is used as a defensive measure to prevent against +// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than +// "MutexLock l(&mu)". Hence the typedef trick below. class GTestMutexLock { public: explicit GTestMutexLock(MutexBase* mutex) @@ -2705,41 +3305,14 @@ } // Implements thread-local storage on pthreads-based systems. -// -// // Thread 1 -// ThreadLocal<int> tl(100); // 100 is the default value for each thread. -// -// // Thread 2 -// tl.set(150); // Changes the value for thread 2 only. -// EXPECT_EQ(150, tl.get()); -// -// // Thread 1 -// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value. -// tl.set(200); -// EXPECT_EQ(200, tl.get()); -// -// The template type argument T must have a public copy constructor. -// In addition, the default ThreadLocal constructor requires T to have -// a public default constructor. -// -// An object managed for a thread by a ThreadLocal instance is deleted -// when the thread exits. Or, if the ThreadLocal instance dies in -// that thread, when the ThreadLocal dies. It's the user's -// responsibility to ensure that all other threads using a ThreadLocal -// have exited when it dies, or the per-thread objects for those -// threads will not be deleted. -// -// Google Test only uses global ThreadLocal objects. That means they -// will die after main() has returned. Therefore, no per-thread -// object managed by Google Test will be leaked as long as all threads -// using Google Test have exited when main() returns. template <typename T> class ThreadLocal { public: - ThreadLocal() : key_(CreateKey()), - default_() {} - explicit ThreadLocal(const T& value) : key_(CreateKey()), - default_(value) {} + ThreadLocal() + : key_(CreateKey()), default_factory_(new DefaultValueHolderFactory()) {} + explicit ThreadLocal(const T& value) + : key_(CreateKey()), + default_factory_(new InstanceValueHolderFactory(value)) {} ~ThreadLocal() { // Destroys the managed object for the current thread, if any. @@ -2759,6 +3332,7 @@ // Holds a value of type T. class ValueHolder : public ThreadLocalValueHolderBase { public: + ValueHolder() : value_() {} explicit ValueHolder(const T& value) : value_(value) {} T* pointer() { return &value_; } @@ -2784,22 +3358,54 @@ return CheckedDowncastToActualType<ValueHolder>(holder)->pointer(); } - ValueHolder* const new_holder = new ValueHolder(default_); + ValueHolder* const new_holder = default_factory_->MakeNewHolder(); ThreadLocalValueHolderBase* const holder_base = new_holder; GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); return new_holder->pointer(); } + class ValueHolderFactory { + public: + ValueHolderFactory() {} + virtual ~ValueHolderFactory() {} + virtual ValueHolder* MakeNewHolder() const = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolderFactory); + }; + + class DefaultValueHolderFactory : public ValueHolderFactory { + public: + DefaultValueHolderFactory() {} + virtual ValueHolder* MakeNewHolder() const { return new ValueHolder(); } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory); + }; + + class InstanceValueHolderFactory : public ValueHolderFactory { + public: + explicit InstanceValueHolderFactory(const T& value) : value_(value) {} + virtual ValueHolder* MakeNewHolder() const { + return new ValueHolder(value_); + } + + private: + const T value_; // The value for each thread. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(InstanceValueHolderFactory); + }; + // A key pthreads uses for looking up per-thread values. const pthread_key_t key_; - const T default_; // The default value for each thread. + scoped_ptr<ValueHolderFactory> default_factory_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); }; -# define GTEST_IS_THREADSAFE 1 +# endif // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ -#else // GTEST_HAS_PTHREAD +#else // GTEST_IS_THREADSAFE // A dummy implementation of synchronization primitives (mutex, lock, // and thread-local variable). Necessary for compiling Google Test where @@ -2819,6 +3425,11 @@ # define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex +// We cannot name this class MutexLock because the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms. That macro is used as a defensive measure to prevent against +// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than +// "MutexLock l(&mu)". Hence the typedef trick below. class GTestMutexLock { public: explicit GTestMutexLock(Mutex*) {} // NOLINT @@ -2839,11 +3450,7 @@ T value_; }; -// The above synchronization primitives have dummy implementations. -// Therefore Google Test is not thread-safe. -# define GTEST_IS_THREADSAFE 0 - -#endif // GTEST_HAS_PTHREAD +#endif // GTEST_IS_THREADSAFE // Returns the number of threads running in the process, or 0 to indicate that // we cannot detect it. @@ -2953,6 +3560,13 @@ return static_cast<char>(toupper(static_cast<unsigned char>(ch))); } +inline std::string StripTrailingSpaces(std::string str) { + std::string::iterator it = str.end(); + while (it != str.begin() && IsSpace(*--it)) + it = str.erase(it); + return str; +} + // The testing::internal::posix namespace holds wrappers for common // POSIX functions. These wrappers hide the differences between // Windows/MSVC and POSIX systems. Since some compilers define these @@ -3016,11 +3630,7 @@ // Functions deprecated by MSVC 8.0. -#ifdef _MSC_VER -// Temporarily disable warning 4996 (deprecated function). -# pragma warning(push) -# pragma warning(disable:4996) -#endif +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996 /* deprecated function */) inline const char* StrNCpy(char* dest, const char* src, size_t n) { return strncpy(dest, src, n); @@ -3030,7 +3640,7 @@ // StrError() aren't needed on Windows CE at this time and thus not // defined there. -#if !GTEST_OS_WINDOWS_MOBILE +#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT inline int ChDir(const char* dir) { return chdir(dir); } #endif inline FILE* FOpen(const char* path, const char* mode) { @@ -3054,8 +3664,9 @@ inline const char* StrError(int errnum) { return strerror(errnum); } #endif inline const char* GetEnv(const char* name) { -#if GTEST_OS_WINDOWS_MOBILE +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE | GTEST_OS_WINDOWS_RT // We are on Windows CE, which has no environment variables. + static_cast<void>(name); // To prevent 'unused argument' warning. return NULL; #elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) // Environment variables which we programmatically clear will be set to the @@ -3067,9 +3678,7 @@ #endif } -#ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. -#endif +GTEST_DISABLE_MSC_WARNINGS_POP_() #if GTEST_OS_WINDOWS_MOBILE // Windows CE has no C library. The abort() function is used in @@ -3170,11 +3779,20 @@ // Utilities for command line flags and environment variables. // Macro for referencing flags. -#define GTEST_FLAG(name) FLAGS_gtest_##name +#if !defined(GTEST_FLAG) +# define GTEST_FLAG(name) FLAGS_gtest_##name +#endif // !defined(GTEST_FLAG) + +#if !defined(GTEST_USE_OWN_FLAGFILE_FLAG_) +# define GTEST_USE_OWN_FLAGFILE_FLAG_ 1 +#endif // !defined(GTEST_USE_OWN_FLAGFILE_FLAG_) + +#if !defined(GTEST_DECLARE_bool_) +# define GTEST_FLAG_SAVER_ ::testing::internal::GTestFlagSaver // Macros for declaring flags. -#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) -#define GTEST_DECLARE_int32_(name) \ +# define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) +# define GTEST_DECLARE_int32_(name) \ GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) #define GTEST_DECLARE_string_(name) \ GTEST_API_ extern ::std::string GTEST_FLAG(name) @@ -3187,9 +3805,13 @@ #define GTEST_DEFINE_string_(name, default_val, doc) \ GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) +#endif // !defined(GTEST_DECLARE_bool_) + // Thread annotations -#define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) -#define GTEST_LOCK_EXCLUDED_(locks) +#if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_) +# define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) +# define GTEST_LOCK_EXCLUDED_(locks) +#endif // !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_) // Parses 'str' for a 32-bit signed integer. If successful, writes the result // to *value and returns true; otherwise leaves *value unchanged and returns @@ -3210,6 +3832,7 @@ #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ + #if GTEST_OS_LINUX # include <stdlib.h> # include <sys/types.h> @@ -3226,7 +3849,10 @@ #include <string.h> #include <iomanip> #include <limits> +#include <map> #include <set> +#include <string> +#include <vector> // Copyright 2005, Google Inc. // All rights reserved. @@ -7214,9 +7840,6 @@ class TestInfoImpl; // Opaque implementation of TestInfo class UnitTestImpl; // Opaque implementation of UnitTest -// How many times InitGoogleTest() has been called. -GTEST_API_ extern int g_init_gtest_count; - // The text used in failure messages to indicate the start of the // stack trace. GTEST_API_ extern const char kStackTraceMarker[]; @@ -7288,6 +7911,36 @@ // c'tor and d'tor. Therefore it doesn't // need to be used otherwise. +namespace edit_distance { +// Returns the optimal edits to go from 'left' to 'right'. +// All edits cost the same, with replace having lower priority than +// add/remove. +// Simple implementation of the Wagner–Fischer algorithm. +// See http://en.wikipedia.org/wiki/Wagner-Fischer_algorithm +enum EditType { kMatch, kAdd, kRemove, kReplace }; +GTEST_API_ std::vector<EditType> CalculateOptimalEdits( + const std::vector<size_t>& left, const std::vector<size_t>& right); + +// Same as above, but the input is represented as strings. +GTEST_API_ std::vector<EditType> CalculateOptimalEdits( + const std::vector<std::string>& left, + const std::vector<std::string>& right); + +// Create a diff of the input strings in Unified diff format. +GTEST_API_ std::string CreateUnifiedDiff(const std::vector<std::string>& left, + const std::vector<std::string>& right, + size_t context = 2); + +} // namespace edit_distance + +// Calculate the diff between 'left' and 'right' and return it in unified diff +// format. +// If not null, stores in 'total_line_count' the total number of lines found +// in left + right. +GTEST_API_ std::string DiffStrings(const std::string& left, + const std::string& right, + size_t* total_line_count); + // Constructs and returns the message for an equality assertion // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. // @@ -7588,6 +8241,13 @@ typedef void (*SetUpTestCaseFunc)(); typedef void (*TearDownTestCaseFunc)(); +struct CodeLocation { + CodeLocation(const string& a_file, int a_line) : file(a_file), line(a_line) {} + + string file; + int line; +}; + // Creates a new TestInfo object and registers it with Google Test; // returns the created object. // @@ -7599,6 +8259,7 @@ // this is not a typed or a type-parameterized test. // value_param text representation of the test's value parameter, // or NULL if this is not a type-parameterized test. +// code_location: code location where the test is defined // 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 @@ -7610,6 +8271,7 @@ const char* name, const char* type_param, const char* value_param, + CodeLocation code_location, TypeId fixture_class_id, SetUpTestCaseFunc set_up_tc, TearDownTestCaseFunc tear_down_tc, @@ -7639,10 +8301,21 @@ fflush(stderr); posix::Abort(); } - defined_test_names_.insert(test_name); + registered_tests_.insert( + ::std::make_pair(test_name, CodeLocation(file, line))); return true; } + bool TestExists(const std::string& test_name) const { + return registered_tests_.count(test_name) > 0; + } + + const CodeLocation& GetCodeLocation(const std::string& test_name) const { + RegisteredTestsMap::const_iterator it = registered_tests_.find(test_name); + GTEST_CHECK_(it != registered_tests_.end()); + return it->second; + } + // Verifies that registered_tests match the test names in // defined_test_names_; returns registered_tests if successful, or // aborts the program otherwise. @@ -7650,8 +8323,10 @@ const char* file, int line, const char* registered_tests); private: + typedef ::std::map<std::string, CodeLocation> RegisteredTestsMap; + bool registered_; - ::std::set<const char*> defined_test_names_; + RegisteredTestsMap registered_tests_; }; // Skips to the first non-space char after the first comma in 'str'; @@ -7672,6 +8347,11 @@ return comma == NULL ? str : std::string(str, comma); } +// Splits a given string on a given delimiter, populating a given +// vector with the fields. +void SplitString(const ::std::string& str, char delimiter, + ::std::vector< ::std::string>* dest); + // 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 @@ -7686,8 +8366,10 @@ // 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) { + static bool Register(const char* prefix, + CodeLocation code_location, + 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; @@ -7697,9 +8379,10 @@ MakeAndRegisterTestInfo( (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + "/" + StreamableToString(index)).c_str(), - GetPrefixUntilComma(test_names).c_str(), + StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(), GetTypeName<Type>().c_str(), NULL, // No value parameter. + code_location, GetTypeId<FixtureClass>(), TestClass::SetUpTestCase, TestClass::TearDownTestCase, @@ -7707,7 +8390,7 @@ // 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); + ::Register(prefix, code_location, case_name, test_names, index + 1); } }; @@ -7715,8 +8398,9 @@ 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*/) { + static bool Register(const char* /*prefix*/, CodeLocation, + const char* /*case_name*/, const char* /*test_names*/, + int /*index*/) { return true; } }; @@ -7728,17 +8412,31 @@ 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) { + static bool Register(const char* prefix, CodeLocation code_location, + const TypedTestCasePState* state, + const char* case_name, const char* test_names) { + std::string test_name = StripTrailingSpaces( + GetPrefixUntilComma(test_names)); + if (!state->TestExists(test_name)) { + fprintf(stderr, "Failed to get code location for test %s.%s at %s.", + case_name, test_name.c_str(), + FormatFileLocation(code_location.file.c_str(), + code_location.line).c_str()); + fflush(stderr); + posix::Abort(); + } + const CodeLocation& test_location = state->GetCodeLocation(test_name); + 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); + prefix, test_location, 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)); + ::Register(prefix, code_location, state, + case_name, SkipComma(test_names)); } }; @@ -7746,8 +8444,9 @@ template <GTEST_TEMPLATE_ Fixture, typename Types> class TypeParameterizedTestCase<Fixture, Templates0, Types> { public: - static bool Register(const char* /*prefix*/, const char* /*case_name*/, - const char* /*test_names*/) { + static bool Register(const char* /*prefix*/, CodeLocation, + const TypedTestCasePState* /*state*/, + const char* /*case_name*/, const char* /*test_names*/) { return true; } }; @@ -7919,25 +8618,20 @@ // We have to put the 'public' section after the 'private' section, // or MSVC refuses to compile the code. public: - // MSVC warns about implicitly converting from double to int for - // possible loss of data, so we need to temporarily disable the - // warning. -#ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4244) // Temporarily disables warning 4244. - - static const bool value = - sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; -# pragma warning(pop) // Restores the warning state. -#elif defined(__BORLANDC__) +#if defined(__BORLANDC__) // C++Builder cannot use member overload resolution during template // instantiation. The simplest workaround is to use its C++0x type traits // functions (C++Builder 2009 and above only). static const bool value = __is_convertible(From, To); #else + // MSVC warns about implicitly converting from double to int for + // possible loss of data, so we need to temporarily disable the + // warning. + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244) static const bool value = sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; -#endif // _MSV_VER + GTEST_DISABLE_MSC_WARNINGS_POP_() +#endif // __BORLANDC__ }; template <typename From, typename To> const bool ImplicitlyConvertible<From, To>::value; @@ -8063,11 +8757,10 @@ // The relation between an NativeArray object (see below) and the // native array it represents. -enum RelationToSource { - kReference, // The NativeArray references the native array. - kCopy // The NativeArray makes a copy of the native array and - // owns the copy. -}; +// We use 2 different structs to allow non-copyable types to be used, as long +// as RelationToSourceReference() is passed. +struct RelationToSourceReference {}; +struct RelationToSourceCopy {}; // Adapts a native array to a read-only STL-style container. Instead // of the complete STL container concept, this adaptor only implements @@ -8085,22 +8778,23 @@ typedef Element* iterator; typedef const Element* const_iterator; - // Constructs from a native array. - NativeArray(const Element* array, size_t count, RelationToSource relation) { - Init(array, count, relation); + // Constructs from a native array. References the source. + NativeArray(const Element* array, size_t count, RelationToSourceReference) { + InitRef(array, count); + } + + // Constructs from a native array. Copies the source. + NativeArray(const Element* array, size_t count, RelationToSourceCopy) { + InitCopy(array, count); } // Copy constructor. NativeArray(const NativeArray& rhs) { - Init(rhs.array_, rhs.size_, rhs.relation_to_source_); + (this->*rhs.clone_)(rhs.array_, rhs.size_); } ~NativeArray() { - // Ensures that the user doesn't instantiate NativeArray with a - // const or reference type. - static_cast<void>(StaticAssertTypeEqHelper<Element, - GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>()); - if (relation_to_source_ == kCopy) + if (clone_ != &NativeArray::InitRef) delete[] array_; } @@ -8114,23 +8808,30 @@ } private: - // Initializes this object; makes a copy of the input array if - // 'relation' is kCopy. - void Init(const Element* array, size_t a_size, RelationToSource relation) { - if (relation == kReference) { - array_ = array; - } else { - Element* const copy = new Element[a_size]; - CopyArray(array, a_size, copy); - array_ = copy; - } + enum { + kCheckTypeIsNotConstOrAReference = StaticAssertTypeEqHelper< + Element, GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>::value, + }; + + // Initializes this object with a copy of the input. + void InitCopy(const Element* array, size_t a_size) { + Element* const copy = new Element[a_size]; + CopyArray(array, a_size, copy); + array_ = copy; size_ = a_size; - relation_to_source_ = relation; + clone_ = &NativeArray::InitCopy; + } + + // Initializes this object with a reference of the input. + void InitRef(const Element* array, size_t a_size) { + array_ = array; + size_ = a_size; + clone_ = &NativeArray::InitRef; } const Element* array_; size_t size_; - RelationToSource relation_to_source_; + void (NativeArray::*clone_)(const Element*, size_t); GTEST_DISALLOW_ASSIGN_(NativeArray); }; @@ -8265,6 +8966,7 @@ ::test_info_ =\ ::testing::internal::MakeAndRegisterTestInfo(\ #test_case_name, #test_name, NULL, NULL, \ + ::testing::internal::CodeLocation(__FILE__, __LINE__), \ (parent_id), \ parent_class::SetUpTestCase, \ parent_class::TearDownTestCase, \ @@ -8273,6 +8975,7 @@ void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ + // Copyright 2005, Google Inc. // All rights reserved. // @@ -9109,7 +9812,10 @@ #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ +#include <ctype.h> + #include <iterator> +#include <set> #include <utility> #include <vector> @@ -9227,7 +9933,12 @@ MutexLock lock(&g_linked_ptr_mutex); linked_ptr_internal const* p = ptr; - while (p->next_ != ptr) p = p->next_; + while (p->next_ != ptr) { + assert(p->next_ != this && + "Trying to join() a linked ring we are already in. " + "Is GMock thread safety enabled?"); + p = p->next_; + } p->next_ = this; next_ = ptr; } @@ -9240,7 +9951,12 @@ if (next_ == this) return true; linked_ptr_internal const* p = next_; - while (p->next_ != this) p = p->next_; + while (p->next_ != this) { + assert(p->next_ != next_ && + "Trying to depart() a linked ring we are not in. " + "Is GMock thread safety enabled?"); + p = p->next_; + } p->next_ = next_; return false; } @@ -9602,6 +10318,103 @@ namespace testing { namespace internal { +// FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a +// value of type ToPrint that is an operand of a comparison assertion +// (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in +// the comparison, and is used to help determine the best way to +// format the value. In particular, when the value is a C string +// (char pointer) and the other operand is an STL string object, we +// want to format the C string as a string, since we know it is +// compared by value with the string object. If the value is a char +// pointer but the other operand is not an STL string object, we don't +// know whether the pointer is supposed to point to a NUL-terminated +// string, and thus want to print it as a pointer to be safe. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + +// The default case. +template <typename ToPrint, typename OtherOperand> +class FormatForComparison { + public: + static ::std::string Format(const ToPrint& value) { + return ::testing::PrintToString(value); + } +}; + +// Array. +template <typename ToPrint, size_t N, typename OtherOperand> +class FormatForComparison<ToPrint[N], OtherOperand> { + public: + static ::std::string Format(const ToPrint* value) { + return FormatForComparison<const ToPrint*, OtherOperand>::Format(value); + } +}; + +// By default, print C string as pointers to be safe, as we don't know +// whether they actually point to a NUL-terminated string. + +#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \ + template <typename OtherOperand> \ + class FormatForComparison<CharType*, OtherOperand> { \ + public: \ + static ::std::string Format(CharType* value) { \ + return ::testing::PrintToString(static_cast<const void*>(value)); \ + } \ + } + +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char); +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char); +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t); +GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t); + +#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_ + +// If a C string is compared with an STL string object, we know it's meant +// to point to a NUL-terminated string, and thus can print it as a string. + +#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \ + template <> \ + class FormatForComparison<CharType*, OtherStringType> { \ + public: \ + static ::std::string Format(CharType* value) { \ + return ::testing::PrintToString(value); \ + } \ + } + +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string); + +#if GTEST_HAS_GLOBAL_STRING +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string); +#endif + +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring); +#endif + +#if GTEST_HAS_STD_WSTRING +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring); +GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring); +#endif + +#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_ + +// 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* or void*, and print it as a C string when it is compared +// against an std::string object, for example. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template <typename T1, typename T2> +std::string FormatForComparisonFailureMessage( + const T1& value, const T2& /* other_operand */) { + return FormatForComparison<T1, T2>::Format(value); +} + // UniversalPrinter<T>::Print(value, ostream_ptr) prints the given // value to the given ostream. The caller must ensure that // 'ostream_ptr' is not NULL, or the behavior is undefined. @@ -9941,10 +10754,7 @@ public: // MSVC warns about adding const to a function type, so we want to // disable the warning. -#ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4180) // Temporarily disables warning 4180. -#endif // _MSC_VER + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180) // Note: we deliberately don't call this PrintTo(), as that name // conflicts with ::testing::internal::PrintTo in the body of the @@ -9961,9 +10771,7 @@ PrintTo(value, os); } -#ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. -#endif // _MSC_VER + GTEST_DISABLE_MSC_WARNINGS_POP_() }; // UniversalPrintArray(begin, len, os) prints an array of 'len' @@ -10015,10 +10823,7 @@ public: // MSVC warns about adding const to a function type, so we want to // disable the warning. -#ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4180) // Temporarily disables warning 4180. -#endif // _MSC_VER + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180) static void Print(const T& value, ::std::ostream* os) { // Prints the address of the value. We use reinterpret_cast here @@ -10029,9 +10834,7 @@ UniversalPrint(value, os); } -#ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. -#endif // _MSC_VER + GTEST_DISABLE_MSC_WARNINGS_POP_() }; // Prints a value tersely: for a reference type, the referenced value @@ -10183,9 +10986,9 @@ template <typename Tuple> static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { TuplePrefixPrinter<N - 1>::PrintPrefixTo(t, os); - GTEST_INTENTIONAL_CONST_COND_PUSH_ + GTEST_INTENTIONAL_CONST_COND_PUSH_() if (N > 1) { - GTEST_INTENTIONAL_CONST_COND_POP_ + GTEST_INTENTIONAL_CONST_COND_POP_() *os << ", "; } UniversalPrinter< @@ -10246,11 +11049,78 @@ } // namespace testing +// Include any custom printer added by the local installation. +// We must include this header at the end to make sure it can use the +// declarations from this file. +// Copyright 2015, 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 provides an injection point for custom printers in a local +// installation of gTest. +// It will be included from gtest-printers.h and the overrides in this file +// will be visible to everyone. +// See documentation at gtest/gtest-printers.h for details on how to define a +// custom printer. +// +// ** Custom implementation starts here ** + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ + #endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ #if GTEST_HAS_PARAM_TEST namespace testing { + +// Input to a parameterized test name generator, describing a test parameter. +// Consists of the parameter value and the integer parameter index. +template <class ParamType> +struct TestParamInfo { + TestParamInfo(const ParamType& a_param, size_t an_index) : + param(a_param), + index(an_index) {} + ParamType param; + size_t index; +}; + +// A builtin parameterized test name generator which returns the result of +// testing::PrintToString. +struct PrintToStringParamName { + template <class ParamType> + std::string operator()(const TestParamInfo<ParamType>& info) const { + return PrintToString(info.param); + } +}; + namespace internal { // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. @@ -10260,7 +11130,7 @@ // TEST_P macro is used to define two tests with the same name // but in different namespaces. GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, - const char* file, int line); + CodeLocation code_location); template <typename> class ParamGeneratorInterface; template <typename> class ParamGenerator; @@ -10408,7 +11278,7 @@ return base_; } virtual void Advance() { - value_ = value_ + step_; + value_ = static_cast<T>(value_ + step_); index_++; } virtual ParamIteratorInterface<T>* Clone() const { @@ -10445,7 +11315,7 @@ const T& end, const IncrementT& step) { int end_index = 0; - for (T i = begin; i < end; i = i + step) + for (T i = begin; i < end; i = static_cast<T>(i + step)) end_index++; return end_index; } @@ -10549,6 +11419,37 @@ // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // +// Default parameterized test name generator, returns a string containing the +// integer test parameter index. +template <class ParamType> +std::string DefaultParamName(const TestParamInfo<ParamType>& info) { + Message name_stream; + name_stream << info.index; + return name_stream.GetString(); +} + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Parameterized test name overload helpers, which help the +// INSTANTIATE_TEST_CASE_P macro choose between the default parameterized +// test name generator and user param name generator. +template <class ParamType, class ParamNameGenFunctor> +ParamNameGenFunctor GetParamNameGen(ParamNameGenFunctor func) { + return func; +} + +template <class ParamType> +struct ParamNameGenFunc { + typedef std::string Type(const TestParamInfo<ParamType>&); +}; + +template <class ParamType> +typename ParamNameGenFunc<ParamType>::Type *GetParamNameGen() { + return DefaultParamName; +} + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// // Stores a parameter value and later creates tests parameterized with that // value. template <class TestClass> @@ -10651,9 +11552,11 @@ typedef typename TestCase::ParamType ParamType; // A function that returns an instance of appropriate generator type. typedef ParamGenerator<ParamType>(GeneratorCreationFunc)(); + typedef typename ParamNameGenFunc<ParamType>::Type ParamNameGeneratorFunc; - explicit ParameterizedTestCaseInfo(const char* name) - : test_case_name_(name) {} + explicit ParameterizedTestCaseInfo( + const char* name, CodeLocation code_location) + : test_case_name_(name), code_location_(code_location) {} // Test case base name for display purposes. virtual const string& GetTestCaseName() const { return test_case_name_; } @@ -10676,9 +11579,11 @@ // about a generator. int AddTestCaseInstantiation(const string& instantiation_name, GeneratorCreationFunc* func, - const char* /* file */, - int /* line */) { - instantiations_.push_back(::std::make_pair(instantiation_name, func)); + ParamNameGeneratorFunc* name_func, + const char* file, + int line) { + instantiations_.push_back( + InstantiationInfo(instantiation_name, func, name_func, file, line)); 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 @@ -10693,25 +11598,45 @@ 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)()); + const string& instantiation_name = gen_it->name; + ParamGenerator<ParamType> generator((*gen_it->generator)()); + ParamNameGeneratorFunc* name_func = gen_it->name_func; + const char* file = gen_it->file; + int line = gen_it->line; string test_case_name; if ( !instantiation_name.empty() ) test_case_name = instantiation_name + "/"; test_case_name += test_info->test_case_base_name; - int i = 0; + size_t i = 0; + std::set<std::string> test_param_names; 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 << "/" << i; + + std::string param_name = name_func( + TestParamInfo<ParamType>(*param_it, i)); + + GTEST_CHECK_(IsValidParamName(param_name)) + << "Parameterized test name '" << param_name + << "' is invalid, in " << file + << " line " << line << std::endl; + + GTEST_CHECK_(test_param_names.count(param_name) == 0) + << "Duplicate parameterized test name '" << param_name + << "', in " << file << " line " << line << std::endl; + + test_param_names.insert(param_name); + + test_name_stream << test_info->test_base_name << "/" << param_name; MakeAndRegisterTestInfo( test_case_name.c_str(), test_name_stream.GetString().c_str(), NULL, // No type parameter. PrintToString(*param_it).c_str(), + code_location_, GetTestCaseTypeId(), TestCase::SetUpTestCase, TestCase::TearDownTestCase, @@ -10737,12 +11662,45 @@ 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; + // Records data received from INSTANTIATE_TEST_CASE_P macros: + // <Instantiation name, Sequence generator creation function, + // Name generator function, Source file, Source line> + struct InstantiationInfo { + InstantiationInfo(const std::string &name_in, + GeneratorCreationFunc* generator_in, + ParamNameGeneratorFunc* name_func_in, + const char* file_in, + int line_in) + : name(name_in), + generator(generator_in), + name_func(name_func_in), + file(file_in), + line(line_in) {} + + std::string name; + GeneratorCreationFunc* generator; + ParamNameGeneratorFunc* name_func; + const char* file; + int line; + }; + typedef ::std::vector<InstantiationInfo> InstantiationContainer; + + static bool IsValidParamName(const std::string& name) { + // Check for empty string + if (name.empty()) + return false; + + // Check for invalid characters + for (std::string::size_type index = 0; index < name.size(); ++index) { + if (!isalnum(name[index]) && name[index] != '_') + return false; + } + + return true; + } const string test_case_name_; + CodeLocation code_location_; TestInfoContainer tests_; InstantiationContainer instantiations_; @@ -10770,8 +11728,7 @@ template <class TestCase> ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder( const char* test_case_name, - const char* file, - int line) { + CodeLocation code_location) { ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL; for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); it != test_case_infos_.end(); ++it) { @@ -10780,7 +11737,7 @@ // 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); + ReportInvalidTestCaseType(test_case_name, code_location); posix::Abort(); } else { // At this point we are sure that the object we found is of the same @@ -10793,7 +11750,8 @@ } } if (typed_test_info == NULL) { - typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name); + typed_test_info = new ParameterizedTestCaseInfo<TestCase>( + test_case_name, code_location); test_case_infos_.push_back(typed_test_info); } return typed_test_info; @@ -10861,7 +11819,7 @@ // 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 +// by the maximum arity of the implementation of tuple which is // currently set at 10. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ @@ -10898,7 +11856,10 @@ explicit ValueArray1(T1 v1) : v1_(v1) {} template <typename T> - operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); } + operator ParamGenerator<T>() const { + const T array[] = {static_cast<T>(v1_)}; + return ValuesIn(array); + } private: // No implementation - assignment is unsupported. @@ -13976,9 +14937,9 @@ // template <typename T1, typename T2> class CartesianProductGenerator2 - : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2> > { + : public ParamGeneratorInterface< ::testing::tuple<T1, T2> > { public: - typedef ::std::tr1::tuple<T1, T2> ParamType; + typedef ::testing::tuple<T1, T2> ParamType; CartesianProductGenerator2(const ParamGenerator<T1>& g1, const ParamGenerator<T2>& g2) @@ -14091,9 +15052,9 @@ template <typename T1, typename T2, typename T3> class CartesianProductGenerator3 - : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3> > { + : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3> > { public: - typedef ::std::tr1::tuple<T1, T2, T3> ParamType; + typedef ::testing::tuple<T1, T2, T3> ParamType; CartesianProductGenerator3(const ParamGenerator<T1>& g1, const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3) @@ -14223,9 +15184,9 @@ template <typename T1, typename T2, typename T3, typename T4> class CartesianProductGenerator4 - : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4> > { + : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4> > { public: - typedef ::std::tr1::tuple<T1, T2, T3, T4> ParamType; + typedef ::testing::tuple<T1, T2, T3, T4> ParamType; CartesianProductGenerator4(const ParamGenerator<T1>& g1, const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, @@ -14374,9 +15335,9 @@ template <typename T1, typename T2, typename T3, typename T4, typename T5> class CartesianProductGenerator5 - : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5> > { + : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5> > { public: - typedef ::std::tr1::tuple<T1, T2, T3, T4, T5> ParamType; + typedef ::testing::tuple<T1, T2, T3, T4, T5> ParamType; CartesianProductGenerator5(const ParamGenerator<T1>& g1, const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, @@ -14542,10 +15503,10 @@ 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, + : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5, T6> > { public: - typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> ParamType; + typedef ::testing::tuple<T1, T2, T3, T4, T5, T6> ParamType; CartesianProductGenerator6(const ParamGenerator<T1>& g1, const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, @@ -14728,10 +15689,10 @@ 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, + : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7> > { public: - typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> ParamType; + typedef ::testing::tuple<T1, T2, T3, T4, T5, T6, T7> ParamType; CartesianProductGenerator7(const ParamGenerator<T1>& g1, const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, @@ -14931,10 +15892,10 @@ 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, + : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8> > { public: - typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> ParamType; + typedef ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8> ParamType; CartesianProductGenerator8(const ParamGenerator<T1>& g1, const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, @@ -15153,10 +16114,10 @@ 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, + : public ParamGeneratorInterface< ::testing::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; + typedef ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9> ParamType; CartesianProductGenerator9(const ParamGenerator<T1>& g1, const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, @@ -15392,10 +16353,10 @@ 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, + : public ParamGeneratorInterface< ::testing::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; + typedef ::testing::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, @@ -15657,8 +16618,8 @@ 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> >( + operator ParamGenerator< ::testing::tuple<T1, T2> >() const { + return ParamGenerator< ::testing::tuple<T1, T2> >( new CartesianProductGenerator2<T1, T2>( static_cast<ParamGenerator<T1> >(g1_), static_cast<ParamGenerator<T2> >(g2_))); @@ -15679,8 +16640,8 @@ 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> >( + operator ParamGenerator< ::testing::tuple<T1, T2, T3> >() const { + return ParamGenerator< ::testing::tuple<T1, T2, T3> >( new CartesianProductGenerator3<T1, T2, T3>( static_cast<ParamGenerator<T1> >(g1_), static_cast<ParamGenerator<T2> >(g2_), @@ -15704,8 +16665,8 @@ 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> >( + operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4> >() const { + return ParamGenerator< ::testing::tuple<T1, T2, T3, T4> >( new CartesianProductGenerator4<T1, T2, T3, T4>( static_cast<ParamGenerator<T1> >(g1_), static_cast<ParamGenerator<T2> >(g2_), @@ -15731,8 +16692,8 @@ 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> >( + operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5> >() const { + return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5> >( new CartesianProductGenerator5<T1, T2, T3, T4, T5>( static_cast<ParamGenerator<T1> >(g1_), static_cast<ParamGenerator<T2> >(g2_), @@ -15762,8 +16723,8 @@ : 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> >( + operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6> >() const { + return ParamGenerator< ::testing::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_), @@ -15795,9 +16756,9 @@ : 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, + operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7> >() const { - return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> >( + return ParamGenerator< ::testing::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_), @@ -15833,9 +16794,9 @@ 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, + operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8> >() const { - return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> >( + return ParamGenerator< ::testing::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_), @@ -15874,9 +16835,9 @@ 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, + operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9> >() const { - return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, + return ParamGenerator< ::testing::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_), @@ -15918,10 +16879,10 @@ 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> >( + operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, + T10> >() const { + return ParamGenerator< ::testing::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_), @@ -17156,14 +18117,17 @@ 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)>()); \ + #test_case_name, \ + ::testing::internal::CodeLocation(\ + __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_; \ + static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \ GTEST_DISALLOW_COPY_AND_ASSIGN_(\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ }; \ @@ -17172,16 +18136,36 @@ 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) \ +// The optional last argument to INSTANTIATE_TEST_CASE_P allows the user +// to specify a function or functor that generates custom test name suffixes +// based on the test parameters. The function should accept one argument of +// type testing::TestParamInfo<class ParamType>, and return std::string. +// +// testing::PrintToStringParamName is a builtin test suffix generator that +// returns the value of testing::PrintToString(GetParam()). It does not work +// for std::string or C strings. +// +// Note: test names must be non-empty, unique, and may only contain ASCII +// alphanumeric characters or underscore. + +# 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_ = \ + ::std::string gtest_##prefix##test_case_name##_EvalGenerateName_( \ + const ::testing::TestParamInfo<test_case_name::ParamType>& info) { \ + return ::testing::internal::GetParamNameGen<test_case_name::ParamType> \ + (__VA_ARGS__)(info); \ + } \ + int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \ ::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__) + #test_case_name, \ + ::testing::internal::CodeLocation(\ + __FILE__, __LINE__))->AddTestCaseInstantiation(\ + #prefix, \ + >est_##prefix##test_case_name##_EvalGenerator_, \ + >est_##prefix##test_case_name##_EvalGenerateName_, \ + __FILE__, __LINE__) } // namespace testing @@ -17604,7 +18588,8 @@ ::testing::internal::TemplateSel< \ GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ GTEST_TYPE_PARAMS_(CaseName)>::Register(\ - "", #CaseName, #TestName, 0); \ + "", ::testing::internal::CodeLocation(__FILE__, __LINE__), \ + #CaseName, #TestName, 0); \ template <typename gtest_TypeParam_> \ void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody() @@ -17675,7 +18660,10 @@ ::testing::internal::TypeParameterizedTestCase<CaseName, \ GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \ ::testing::internal::TypeList< Types >::type>::Register(\ - #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) + #Prefix, \ + ::testing::internal::CodeLocation(__FILE__, __LINE__), \ + >EST_TYPED_TEST_CASE_P_STATE_(CaseName), \ + #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) #endif // GTEST_HAS_TYPED_TEST_P @@ -17686,14 +18674,14 @@ // class ::string, which has the same interface as ::std::string, but // has a different implementation. // -// The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that +// You can 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_GLOBAL_STRING to 0. +// If ::std::string and ::string are the same class on your platform +// due to aliasing, you should define GTEST_HAS_GLOBAL_STRING to 0. // -// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined +// If you do not define GTEST_HAS_GLOBAL_STRING, it is defined // heuristically. namespace testing { @@ -17874,8 +18862,31 @@ // Copy constructor. // Used in EXPECT_TRUE/FALSE(assertion_result). AssertionResult(const AssertionResult& other); + + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */) + // Used in the EXPECT_TRUE/FALSE(bool_expression). - explicit AssertionResult(bool success) : success_(success) {} + // + // T must be contextually convertible to bool. + // + // The second parameter prevents this overload from being considered if + // the argument is implicitly convertible to AssertionResult. In that case + // we want AssertionResult's copy constructor to be used. + template <typename T> + explicit AssertionResult( + const T& success, + typename internal::EnableIf< + !internal::ImplicitlyConvertible<T, AssertionResult>::value>::type* + /*enabler*/ = NULL) + : success_(success) {} + + GTEST_DISABLE_MSC_WARNINGS_POP_() + + // Assignment operator. + AssertionResult& operator=(AssertionResult other) { + swap(other); + return *this; + } // Returns true iff the assertion succeeded. operator bool() const { return success_; } // NOLINT @@ -17916,6 +18927,9 @@ message_->append(a_message.GetString().c_str()); } + // Swap the contents of this AssertionResult with other. + void swap(AssertionResult& other); + // Stores result of the assertion predicate. bool success_; // Stores the message describing the condition in case the expectation @@ -17923,8 +18937,6 @@ // Referenced via a pointer to avoid taking too much stack frame space // with test assertions. internal::scoped_ptr< ::std::string> message_; - - GTEST_DISALLOW_ASSIGN_(AssertionResult); }; // Makes a successful assertion result. @@ -17951,8 +18963,8 @@ // // class FooTest : public testing::Test { // protected: -// virtual void SetUp() { ... } -// virtual void TearDown() { ... } +// void SetUp() override { ... } +// void TearDown() override { ... } // ... // }; // @@ -18044,20 +19056,19 @@ // internal method to avoid clashing with names used in user TESTs. void DeleteSelf_() { delete this; } - // Uses a GTestFlagSaver to save and restore all Google Test flags. - const internal::GTestFlagSaver* const gtest_flag_saver_; + const internal::scoped_ptr< GTEST_FLAG_SAVER_ > gtest_flag_saver_; - // Often a user mis-spells SetUp() as Setup() and spends a long time + // Often a user misspells 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. + // will be a conflict if void Setup() is declared in the user's + // test fixture. // // - This method is private, so it will be another compiler error - // if a user calls it from his test fixture. + // if the method is called from the user's test fixture. // // DO NOT OVERRIDE THIS FUNCTION. // @@ -18262,6 +19273,12 @@ return NULL; } + // Returns the file name where this test is defined. + const char* file() const { return location_.file.c_str(); } + + // Returns the line where this test is defined. + int line() const { return location_.line; } + // Returns true if this test should run, that is if the test is not // disabled (or it is disabled but the also_run_disabled_tests flag has // been specified) and its full name matches the user-specified filter. @@ -18304,6 +19321,7 @@ const char* name, const char* type_param, const char* value_param, + internal::CodeLocation code_location, internal::TypeId fixture_class_id, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc, @@ -18315,6 +19333,7 @@ const std::string& name, const char* a_type_param, // NULL if not a type-parameterized test const char* a_value_param, // NULL if not a value-parameterized test + internal::CodeLocation a_code_location, internal::TypeId fixture_class_id, internal::TestFactoryBase* factory); @@ -18341,6 +19360,7 @@ // Text representation of the value parameter, or NULL if this is not a // value-parameterized test. const internal::scoped_ptr<const ::std::string> value_param_; + internal::CodeLocation location_; const internal::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 @@ -18540,7 +19560,7 @@ }; // An Environment object is capable of setting up and tearing down an -// environment. The user should subclass this to define his own +// environment. You should subclass this to define your own // environment(s). // // An Environment object does the set-up and tear-down in virtual @@ -18952,101 +19972,18 @@ namespace internal { -// FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a -// value of type ToPrint that is an operand of a comparison assertion -// (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in -// the comparison, and is used to help determine the best way to -// format the value. In particular, when the value is a C string -// (char pointer) and the other operand is an STL string object, we -// want to format the C string as a string, since we know it is -// compared by value with the string object. If the value is a char -// pointer but the other operand is not an STL string object, we don't -// know whether the pointer is supposed to point to a NUL-terminated -// string, and thus want to print it as a pointer to be safe. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - -// The default case. -template <typename ToPrint, typename OtherOperand> -class FormatForComparison { - public: - static ::std::string Format(const ToPrint& value) { - return ::testing::PrintToString(value); - } -}; - -// Array. -template <typename ToPrint, size_t N, typename OtherOperand> -class FormatForComparison<ToPrint[N], OtherOperand> { - public: - static ::std::string Format(const ToPrint* value) { - return FormatForComparison<const ToPrint*, OtherOperand>::Format(value); - } -}; - -// By default, print C string as pointers to be safe, as we don't know -// whether they actually point to a NUL-terminated string. - -#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \ - template <typename OtherOperand> \ - class FormatForComparison<CharType*, OtherOperand> { \ - public: \ - static ::std::string Format(CharType* value) { \ - return ::testing::PrintToString(static_cast<const void*>(value)); \ - } \ - } - -GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char); -GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char); -GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t); -GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t); - -#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_ - -// If a C string is compared with an STL string object, we know it's meant -// to point to a NUL-terminated string, and thus can print it as a string. - -#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \ - template <> \ - class FormatForComparison<CharType*, OtherStringType> { \ - public: \ - static ::std::string Format(CharType* value) { \ - return ::testing::PrintToString(value); \ - } \ - } - -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string); - -#if GTEST_HAS_GLOBAL_STRING -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string); -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string); -#endif - -#if GTEST_HAS_GLOBAL_WSTRING -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring); -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring); -#endif - -#if GTEST_HAS_STD_WSTRING -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring); -GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring); -#endif - -#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_ - -// 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* or void*, and print it as a C string when it is compared -// against an std::string object, for example. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// Separate the error generating code from the code path to reduce the stack +// frame size of CmpHelperEQ. This helps reduce the overhead of some sanitizers +// when calling EXPECT_* in a tight loop. template <typename T1, typename T2> -std::string FormatForComparisonFailureMessage( - const T1& value, const T2& /* other_operand */) { - return FormatForComparison<T1, T2>::Format(value); +AssertionResult CmpHelperEQFailure(const char* expected_expression, + const char* actual_expression, + const T1& expected, const T2& actual) { + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); } // The helper function for {ASSERT|EXPECT}_EQ. @@ -19055,25 +19992,14 @@ const char* actual_expression, const T1& expected, const T2& actual) { -#ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4389) // Temporarily disables warning on - // signed/unsigned mismatch. -#endif - +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4389 /* signed/unsigned mismatch */) if (expected == actual) { return AssertionSuccess(); } +GTEST_DISABLE_MSC_WARNINGS_POP_() -#ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. -#endif - - return EqFailure(expected_expression, - actual_expression, - FormatForComparisonFailureMessage(expected, actual), - FormatForComparisonFailureMessage(actual, expected), - false); + return CmpHelperEQFailure(expected_expression, actual_expression, expected, + actual); } // With this overloaded version, we allow anonymous enums to be used @@ -19161,6 +20087,19 @@ } }; +// Separate the error generating code from the code path to reduce the stack +// frame size of CmpHelperOP. This helps reduce the overhead of some sanitizers +// when calling EXPECT_OP in a tight loop. +template <typename T1, typename T2> +AssertionResult CmpHelperOpFailure(const char* expr1, const char* expr2, + const T1& val1, const T2& val2, + const char* op) { + return AssertionFailure() + << "Expected: (" << expr1 << ") " << op << " (" << expr2 + << "), actual: " << FormatForComparisonFailureMessage(val1, val2) + << " vs " << FormatForComparisonFailureMessage(val2, val1); +} + // 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. @@ -19171,6 +20110,7 @@ // 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, \ @@ -19178,10 +20118,7 @@ if (val1 op val2) {\ return AssertionSuccess();\ } else {\ - return AssertionFailure() \ - << "Expected: (" << expr1 << ") " #op " (" << expr2\ - << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ - << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + return CmpHelperOpFailure(expr1, expr2, val1, val2, #op);\ }\ }\ GTEST_API_ AssertionResult CmpHelper##op_name(\ @@ -20188,8 +21125,8 @@ // 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 code should appear between braces after an invocation of +// this macro. Example: // // TEST(FooTest, InitializesCorrectly) { // Foo foo;