diff options
author | Abseil Team <absl-team@google.com> | 2018-10-24 22:04:43 -0400 |
---|---|---|
committer | Gennadiy Civil <misterg@google.com> | 2018-10-26 14:19:59 -0400 |
commit | b57c703963be1ca9749b902c49083beac56648aa (patch) | |
tree | b7f5433fce3803d121c9963dc69bcdeec4d35f7c /googlemock | |
parent | a50e4f05b3d84c6a014c59a24263328242cc8236 (diff) | |
download | googletest-b57c703963be1ca9749b902c49083beac56648aa.tar.gz googletest-b57c703963be1ca9749b902c49083beac56648aa.tar.bz2 googletest-b57c703963be1ca9749b902c49083beac56648aa.zip |
Googletest export
Remove linked_ptr and use std::shared_ptr instead
PiperOrigin-RevId: 218618184
Diffstat (limited to 'googlemock')
-rw-r--r-- | googlemock/include/gmock/gmock-actions.h | 21 | ||||
-rw-r--r-- | googlemock/include/gmock/gmock-cardinalities.h | 8 | ||||
-rw-r--r-- | googlemock/include/gmock/gmock-generated-actions.h | 3 | ||||
-rw-r--r-- | googlemock/include/gmock/gmock-generated-actions.h.pump | 3 | ||||
-rw-r--r-- | googlemock/include/gmock/gmock-matchers.h | 25 | ||||
-rw-r--r-- | googlemock/include/gmock/gmock-spec-builders.h | 31 | ||||
-rw-r--r-- | googlemock/include/gmock/internal/gmock-internal-utils.h | 9 | ||||
-rw-r--r-- | googlemock/include/gmock/internal/gmock-port.h | 1 | ||||
-rw-r--r-- | googlemock/src/gmock-spec-builders.cc | 3 | ||||
-rw-r--r-- | googlemock/test/gmock-generated-actions_test.cc | 16 | ||||
-rw-r--r-- | googlemock/test/gmock-internal-utils_test.cc | 8 | ||||
-rw-r--r-- | googlemock/test/gmock-matchers_test.cc | 32 | ||||
-rw-r--r-- | googlemock/test/gmock-more-actions_test.cc | 11 | ||||
-rw-r--r-- | googlemock/test/gmock-spec-builders_test.cc | 8 | ||||
-rw-r--r-- | googlemock/test/gmock_stress_test.cc | 81 |
15 files changed, 203 insertions, 57 deletions
diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index e4af9d2d..d4af9490 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -42,7 +42,6 @@ #endif #include <algorithm> -#include <memory> #include <string> #include <utility> @@ -347,7 +346,9 @@ class ActionInterface { // An Action<F> is a copyable and IMMUTABLE (except by assignment) // object that represents an action to be taken when a mock function // of type F is called. The implementation of Action<T> is just a -// std::shared_ptr to const ActionInterface<T>. Don't inherit from Action! +// linked_ptr to const ActionInterface<T>, so copying is fairly cheap. +// Don't inherit from Action! +// // You can view an object implementing ActionInterface<F> as a // concrete action (including its current state), and an Action<F> // object as a handle to it. @@ -424,7 +425,7 @@ class Action { #if GTEST_LANG_CXX11 ::std::function<F> fun_; #endif - std::shared_ptr<ActionInterface<F>> impl_; + internal::linked_ptr<ActionInterface<F> > impl_; }; // The PolymorphicAction class template makes it easy to implement a @@ -518,7 +519,7 @@ class ActionAdaptor : public ActionInterface<F1> { } private: - const std::shared_ptr<ActionInterface<F2>> impl_; + const internal::linked_ptr<ActionInterface<F2> > impl_; GTEST_DISALLOW_ASSIGN_(ActionAdaptor); }; @@ -600,7 +601,7 @@ class ReturnAction { // 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(const std::shared_ptr<R>& value) + explicit Impl(const linked_ptr<R>& value) : value_before_cast_(*value), value_(ImplicitCast_<Result>(value_before_cast_)) {} @@ -625,7 +626,7 @@ class ReturnAction { typedef typename Function<F>::Result Result; typedef typename Function<F>::ArgumentTuple ArgumentTuple; - explicit Impl(const std::shared_ptr<R>& wrapper) + explicit Impl(const linked_ptr<R>& wrapper) : performed_(false), wrapper_(wrapper) {} virtual Result Perform(const ArgumentTuple&) { @@ -637,12 +638,12 @@ class ReturnAction { private: bool performed_; - const std::shared_ptr<R> wrapper_; + const linked_ptr<R> wrapper_; GTEST_DISALLOW_ASSIGN_(Impl); }; - const std::shared_ptr<R> value_; + const linked_ptr<R> value_; GTEST_DISALLOW_ASSIGN_(ReturnAction); }; @@ -865,7 +866,7 @@ class SetArgumentPointeeAction<N, Proto, true> { } private: - const std::shared_ptr<Proto> proto_; + const internal::linked_ptr<Proto> proto_; GTEST_DISALLOW_ASSIGN_(SetArgumentPointeeAction); }; @@ -930,7 +931,7 @@ class InvokeCallbackWithoutArgsAction { Result Perform(const ArgumentTuple&) const { return callback_->Run(); } private: - const std::shared_ptr<CallbackType> callback_; + const internal::linked_ptr<CallbackType> callback_; GTEST_DISALLOW_ASSIGN_(InvokeCallbackWithoutArgsAction); }; diff --git a/googlemock/include/gmock/gmock-cardinalities.h b/googlemock/include/gmock/gmock-cardinalities.h index 8fa25ebb..f9169315 100644 --- a/googlemock/include/gmock/gmock-cardinalities.h +++ b/googlemock/include/gmock/gmock-cardinalities.h @@ -40,7 +40,6 @@ #define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ #include <limits.h> -#include <memory> #include <ostream> // NOLINT #include "gmock/internal/gmock-port.h" #include "gtest/gtest.h" @@ -82,8 +81,9 @@ class CardinalityInterface { // A Cardinality is a copyable and IMMUTABLE (except by assignment) // object that specifies how many times a mock function is expected to -// be called. The implementation of Cardinality is just a std::shared_ptr -// to const CardinalityInterface. Don't inherit from Cardinality! +// be called. The implementation of Cardinality is just a linked_ptr +// to const CardinalityInterface, so copying is fairly cheap. +// Don't inherit from Cardinality! class GTEST_API_ Cardinality { public: // Constructs a null cardinality. Needed for storing Cardinality @@ -123,7 +123,7 @@ class GTEST_API_ Cardinality { ::std::ostream* os); private: - std::shared_ptr<const CardinalityInterface> impl_; + internal::linked_ptr<const CardinalityInterface> impl_; }; // Creates a cardinality that allows at least n calls. diff --git a/googlemock/include/gmock/gmock-generated-actions.h b/googlemock/include/gmock/gmock-generated-actions.h index 8966f05c..0845b221 100644 --- a/googlemock/include/gmock/gmock-generated-actions.h +++ b/googlemock/include/gmock/gmock-generated-actions.h @@ -41,7 +41,6 @@ #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ -#include <memory> #include <utility> #include "gmock/gmock-actions.h" @@ -349,7 +348,7 @@ class InvokeCallbackAction { callback_.get(), args); } private: - const std::shared_ptr<CallbackType> callback_; + const linked_ptr<CallbackType> callback_; }; // An INTERNAL macro for extracting the type of a tuple field. It's diff --git a/googlemock/include/gmock/gmock-generated-actions.h.pump b/googlemock/include/gmock/gmock-generated-actions.h.pump index 09a39ca8..bc22be8e 100644 --- a/googlemock/include/gmock/gmock-generated-actions.h.pump +++ b/googlemock/include/gmock/gmock-generated-actions.h.pump @@ -43,7 +43,6 @@ $$}} This meta comment fixes auto-indentation in editors. #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ -#include <memory> #include <utility> #include "gmock/gmock-actions.h" @@ -119,7 +118,7 @@ class InvokeCallbackAction { callback_.get(), args); } private: - const std::shared_ptr<CallbackType> callback_; + const linked_ptr<CallbackType> callback_; }; // An INTERNAL macro for extracting the type of a tuple field. It's diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index 95bc22c5..6e8bc036 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -43,15 +43,14 @@ #include <algorithm> #include <iterator> #include <limits> -#include <memory> #include <ostream> // NOLINT #include <sstream> #include <string> #include <utility> #include <vector> +#include "gtest/gtest.h" #include "gmock/internal/gmock-internal-utils.h" #include "gmock/internal/gmock-port.h" -#include "gtest/gtest.h" #if GTEST_HAS_STD_INITIALIZER_LIST_ # include <initializer_list> // NOLINT -- must be after gtest.h @@ -339,15 +338,29 @@ class MatcherBase { virtual ~MatcherBase() {} private: - std::shared_ptr<const MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)>> impl_; + // shared_ptr (util/gtl/shared_ptr.h) and linked_ptr have similar + // interfaces. The former dynamically allocates a chunk of memory + // to hold the reference count, while the latter tracks all + // references using a circular linked list without allocating + // memory. It has been observed that linked_ptr performs better in + // typical scenarios. However, shared_ptr can out-perform + // linked_ptr when there are many more uses of the copy constructor + // than the default constructor. + // + // If performance becomes a problem, we should see if using + // shared_ptr helps. + ::testing::internal::linked_ptr< + const MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> > + impl_; }; } // namespace internal // A Matcher<T> is a copyable and IMMUTABLE (except by assignment) // object that can check whether a value of type T matches. The -// implementation of Matcher<T> is just a std::shared_ptr to const -// MatcherInterface<T>. Don't inherit from Matcher! +// implementation of Matcher<T> is just a linked_ptr to const +// MatcherInterface<T>, so copying is fairly cheap. Don't inherit +// from Matcher! template <typename T> class Matcher : public internal::MatcherBase<T> { public: @@ -1573,7 +1586,7 @@ class MatchesRegexMatcher { } private: - const std::shared_ptr<const RE> regex_; + const internal::linked_ptr<const RE> regex_; const bool full_match_; GTEST_DISALLOW_ASSIGN_(MatchesRegexMatcher); diff --git a/googlemock/include/gmock/gmock-spec-builders.h b/googlemock/include/gmock/gmock-spec-builders.h index 7759cb35..5d4b73ba 100644 --- a/googlemock/include/gmock/gmock-spec-builders.h +++ b/googlemock/include/gmock/gmock-spec-builders.h @@ -62,7 +62,6 @@ #define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ #include <map> -#include <memory> #include <set> #include <sstream> #include <string> @@ -220,7 +219,8 @@ class GTEST_API_ UntypedFunctionMockerBase { protected: typedef std::vector<const void*> UntypedOnCallSpecs; - using UntypedExpectations = std::vector<std::shared_ptr<ExpectationBase>>; + typedef std::vector<internal::linked_ptr<ExpectationBase> > + UntypedExpectations; // Returns an Expectation object that references and co-owns exp, // which must be an expectation on this mock function. @@ -498,7 +498,12 @@ class GTEST_API_ Mock { // - Constness is shallow: a const Expectation object itself cannot // be modified, but the mutable methods of the ExpectationBase // object it references can be called via expectation_base(). - +// - The constructors and destructor are defined out-of-line because +// the Symbian WINSCW compiler wants to otherwise instantiate them +// when it sees this class definition, at which point it doesn't have +// ExpectationBase available yet, leading to incorrect destruction +// in the linked_ptr (or compilation errors if using a checking +// linked_ptr). class GTEST_API_ Expectation { public: // Constructs a null object that doesn't reference any expectation. @@ -550,15 +555,16 @@ class GTEST_API_ Expectation { typedef ::std::set<Expectation, Less> Set; Expectation( - const std::shared_ptr<internal::ExpectationBase>& expectation_base); + const internal::linked_ptr<internal::ExpectationBase>& expectation_base); // Returns the expectation this object references. - const std::shared_ptr<internal::ExpectationBase>& expectation_base() const { + const internal::linked_ptr<internal::ExpectationBase>& + expectation_base() const { return expectation_base_; } - // A shared_ptr that co-owns the expectation this handle references. - std::shared_ptr<internal::ExpectationBase> expectation_base_; + // A linked_ptr that co-owns the expectation this handle references. + internal::linked_ptr<internal::ExpectationBase> expectation_base_; }; // A set of expectation handles. Useful in the .After() clause of @@ -640,8 +646,11 @@ class GTEST_API_ Sequence { void AddExpectation(const Expectation& expectation) const; private: - // The last expectation in this sequence. - std::shared_ptr<Expectation> last_expectation_; + // The last expectation in this sequence. We use a linked_ptr here + // because Sequence objects are copyable and we want the copies to + // be aliases. The linked_ptr allows the copies to co-own and share + // the same Expectation object. + internal::linked_ptr<Expectation> last_expectation_; }; // class Sequence // An object of this type causes all EXPECT_CALL() statements @@ -864,7 +873,7 @@ class GTEST_API_ ExpectationBase { Cardinality cardinality_; // The cardinality of the expectation. // The immediate pre-requisites (i.e. expectations that must be // satisfied before this expectation can be matched) of this - // expectation. We use std::shared_ptr in the set because we want an + // expectation. We use linked_ptr in the set because we want an // Expectation object to be co-owned by its FunctionMocker and its // successors. This allows multiple mock objects to be deleted at // different times. @@ -1622,7 +1631,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line); TypedExpectation<F>* const expectation = new TypedExpectation<F>(this, file, line, source_text, m); - const std::shared_ptr<ExpectationBase> untyped_expectation(expectation); + const linked_ptr<ExpectationBase> untyped_expectation(expectation); // See the definition of untyped_expectations_ for why access to // it is unprotected here. untyped_expectations_.push_back(untyped_expectation); diff --git a/googlemock/include/gmock/internal/gmock-internal-utils.h b/googlemock/include/gmock/internal/gmock-internal-utils.h index 7514635e..fd33c004 100644 --- a/googlemock/include/gmock/internal/gmock-internal-utils.h +++ b/googlemock/include/gmock/internal/gmock-internal-utils.h @@ -92,6 +92,15 @@ inline const typename Pointer::element_type* GetRawPointer(const Pointer& p) { template <typename Element> inline Element* GetRawPointer(Element* p) { return p; } +// This comparator allows linked_ptr to be stored in sets. +template <typename T> +struct LinkedPtrLessThan { + bool operator()(const ::testing::internal::linked_ptr<T>& lhs, + const ::testing::internal::linked_ptr<T>& rhs) const { + return lhs.get() < rhs.get(); + } +}; + // Symbian compilation can be done with wchar_t being either a native // type or a typedef. Using Google Mock with OpenC without wchar_t // should require the definition of _STLP_NO_WCHAR_T. diff --git a/googlemock/include/gmock/internal/gmock-port.h b/googlemock/include/gmock/internal/gmock-port.h index c5932493..fda27dba 100644 --- a/googlemock/include/gmock/internal/gmock-port.h +++ b/googlemock/include/gmock/internal/gmock-port.h @@ -52,6 +52,7 @@ // here, as Google Mock depends on Google Test. Only add a utility // here if it's truly specific to Google Mock. +#include "gtest/internal/gtest-linked_ptr.h" #include "gtest/internal/gtest-port.h" #include "gmock/internal/custom/gmock-port.h" diff --git a/googlemock/src/gmock-spec-builders.cc b/googlemock/src/gmock-spec-builders.cc index c93b2b5d..5c20ed14 100644 --- a/googlemock/src/gmock-spec-builders.cc +++ b/googlemock/src/gmock-spec-builders.cc @@ -38,7 +38,6 @@ #include <stdlib.h> #include <iostream> // NOLINT #include <map> -#include <memory> #include <set> #include <string> #include <vector> @@ -849,7 +848,7 @@ void Mock::ClearDefaultActionsLocked(void* mock_obj) Expectation::Expectation() {} Expectation::Expectation( - const std::shared_ptr<internal::ExpectationBase>& an_expectation_base) + const internal::linked_ptr<internal::ExpectationBase>& an_expectation_base) : expectation_base_(an_expectation_base) {} Expectation::~Expectation() {} diff --git a/googlemock/test/gmock-generated-actions_test.cc b/googlemock/test/gmock-generated-actions_test.cc index 3111d859..2d663a5e 100644 --- a/googlemock/test/gmock-generated-actions_test.cc +++ b/googlemock/test/gmock-generated-actions_test.cc @@ -35,7 +35,6 @@ #include "gmock/gmock-generated-actions.h" #include <functional> -#include <memory> #include <sstream> #include <string> #include "gmock/gmock.h" @@ -1130,9 +1129,9 @@ ACTION_TEMPLATE(ReturnSmartPointer, } TEST(ActionTemplateTest, WorksForTemplateTemplateParameters) { - const Action<std::shared_ptr<int>()> a = - ReturnSmartPointer<std::shared_ptr>(42); - std::shared_ptr<int> p = a.Perform(std::make_tuple()); + using ::testing::internal::linked_ptr; + const Action<linked_ptr<int>()> a = ReturnSmartPointer<linked_ptr>(42); + linked_ptr<int> p = a.Perform(std::make_tuple()); EXPECT_EQ(42, *p); } @@ -1162,10 +1161,11 @@ ACTION_TEMPLATE(ReturnGiant, } TEST(ActionTemplateTest, WorksFor10TemplateParameters) { - using Giant = GiantTemplate<std::shared_ptr<int>, bool, double, 5, true, 6, - char, unsigned, int>; - const Action<Giant()> a = ReturnGiant<int, bool, double, 5, true, 6, char, - unsigned, int, std::shared_ptr>(42); + using ::testing::internal::linked_ptr; + typedef GiantTemplate<linked_ptr<int>, bool, double, 5, + true, 6, char, unsigned, int> Giant; + const Action<Giant()> a = ReturnGiant< + int, bool, double, 5, true, 6, char, unsigned, int, linked_ptr>(42); Giant giant = a.Perform(std::make_tuple()); EXPECT_EQ(42, giant.value); } diff --git a/googlemock/test/gmock-internal-utils_test.cc b/googlemock/test/gmock-internal-utils_test.cc index aa0162b8..41498f0e 100644 --- a/googlemock/test/gmock-internal-utils_test.cc +++ b/googlemock/test/gmock-internal-utils_test.cc @@ -123,6 +123,8 @@ TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameIsMixture) { } TEST(PointeeOfTest, WorksForSmartPointers) { + CompileAssertTypesEqual<const char, + PointeeOf<internal::linked_ptr<const char> >::type>(); #if GTEST_HAS_STD_UNIQUE_PTR_ CompileAssertTypesEqual<int, PointeeOf<std::unique_ptr<int> >::type>(); #endif // GTEST_HAS_STD_UNIQUE_PTR_ @@ -149,6 +151,10 @@ TEST(GetRawPointerTest, WorksForSmartPointers) { const std::shared_ptr<double> p2(raw_p2); EXPECT_EQ(raw_p2, GetRawPointer(p2)); #endif // GTEST_HAS_STD_SHARED_PTR_ + + const char* const raw_p4 = new const char('a'); // NOLINT + const internal::linked_ptr<const char> p4(raw_p4); + EXPECT_EQ(raw_p4, GetRawPointer(p4)); } TEST(GetRawPointerTest, WorksForRawPointers) { @@ -681,7 +687,7 @@ TEST(StlContainerViewTest, WorksForDynamicNativeArray) { StlContainerView<std::tuple<const int*, size_t> >::type>(); StaticAssertTypeEq< NativeArray<double>, - StlContainerView<std::tuple<std::shared_ptr<double>, int> >::type>(); + StlContainerView<std::tuple<linked_ptr<double>, int> >::type>(); StaticAssertTypeEq< const NativeArray<int>, diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc index 45006bfb..f4e9e9f7 100644 --- a/googlemock/test/gmock-matchers_test.cc +++ b/googlemock/test/gmock-matchers_test.cc @@ -143,11 +143,13 @@ using testing::internal::ExplainMatchFailureTupleTo; using testing::internal::FloatingEqMatcher; using testing::internal::FormatMatcherDescription; using testing::internal::IsReadableTypeName; +using testing::internal::linked_ptr; using testing::internal::MatchMatrix; using testing::internal::RE; using testing::internal::scoped_ptr; using testing::internal::StreamMatchResultListener; using testing::internal::Strings; +using testing::internal::linked_ptr; using testing::internal::scoped_ptr; using testing::internal::string; @@ -1175,6 +1177,24 @@ TEST(IsNullTest, MatchesNullPointer) { #endif } +TEST(IsNullTest, LinkedPtr) { + const Matcher<linked_ptr<int> > m = IsNull(); + const linked_ptr<int> null_p; + const linked_ptr<int> non_null_p(new int); + + EXPECT_TRUE(m.Matches(null_p)); + EXPECT_FALSE(m.Matches(non_null_p)); +} + +TEST(IsNullTest, ReferenceToConstLinkedPtr) { + const Matcher<const linked_ptr<double>&> m = IsNull(); + const linked_ptr<double> null_p; + const linked_ptr<double> non_null_p(new double); + + EXPECT_TRUE(m.Matches(null_p)); + EXPECT_FALSE(m.Matches(non_null_p)); +} + #if GTEST_LANG_CXX11 TEST(IsNullTest, StdFunction) { const Matcher<std::function<void()>> m = IsNull(); @@ -1206,18 +1226,18 @@ TEST(NotNullTest, MatchesNonNullPointer) { } TEST(NotNullTest, LinkedPtr) { - const Matcher<std::shared_ptr<int>> m = NotNull(); - const std::shared_ptr<int> null_p; - const std::shared_ptr<int> non_null_p(new int); + const Matcher<linked_ptr<int> > m = NotNull(); + const linked_ptr<int> null_p; + const linked_ptr<int> non_null_p(new int); EXPECT_FALSE(m.Matches(null_p)); EXPECT_TRUE(m.Matches(non_null_p)); } TEST(NotNullTest, ReferenceToConstLinkedPtr) { - const Matcher<const std::shared_ptr<double>&> m = NotNull(); - const std::shared_ptr<double> null_p; - const std::shared_ptr<double> non_null_p(new double); + const Matcher<const linked_ptr<double>&> m = NotNull(); + const linked_ptr<double> null_p; + const linked_ptr<double> non_null_p(new double); EXPECT_FALSE(m.Matches(null_p)); EXPECT_TRUE(m.Matches(non_null_p)); diff --git a/googlemock/test/gmock-more-actions_test.cc b/googlemock/test/gmock-more-actions_test.cc index b4e0fc30..521f3058 100644 --- a/googlemock/test/gmock-more-actions_test.cc +++ b/googlemock/test/gmock-more-actions_test.cc @@ -35,11 +35,11 @@ #include "gmock/gmock-more-actions.h" #include <functional> -#include <memory> #include <sstream> #include <string> #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "gtest/internal/gtest-linked_ptr.h" namespace testing { namespace gmock_more_actions_test { @@ -61,6 +61,7 @@ using testing::StaticAssertTypeEq; using testing::Unused; using testing::WithArg; using testing::WithoutArgs; +using testing::internal::linked_ptr; // For suppressing compiler warnings on conversion possibly losing precision. inline short Short(short n) { return n; } // NOLINT @@ -528,6 +529,14 @@ TEST(SaveArgPointeeActionTest, WorksForCompatibleType) { EXPECT_EQ('a', result); } +TEST(SaveArgPointeeActionTest, WorksForLinkedPtr) { + int result = 0; + linked_ptr<int> value(new int(5)); + const Action<void(linked_ptr<int>)> a1 = SaveArgPointee<0>(&result); + a1.Perform(std::make_tuple(value)); + EXPECT_EQ(5, result); +} + TEST(SetArgRefereeActionTest, WorksForSameType) { int value = 0; const Action<void(int&)> a1 = SetArgReferee<0>(1); diff --git a/googlemock/test/gmock-spec-builders_test.cc b/googlemock/test/gmock-spec-builders_test.cc index 6502be74..65c9fcc4 100644 --- a/googlemock/test/gmock-spec-builders_test.cc +++ b/googlemock/test/gmock-spec-builders_test.cc @@ -34,7 +34,6 @@ #include "gmock/gmock-spec-builders.h" -#include <memory> #include <ostream> // NOLINT #include <sstream> #include <string> @@ -100,6 +99,7 @@ using testing::internal::kFail; using testing::internal::kInfoVerbosity; using testing::internal::kWarn; using testing::internal::kWarningVerbosity; +using testing::internal::linked_ptr; #if GTEST_HAS_STREAM_REDIRECTION using testing::HasSubstr; @@ -172,7 +172,7 @@ class ReferenceHoldingMock { public: ReferenceHoldingMock() {} - MOCK_METHOD1(AcceptReference, void(std::shared_ptr<MockA>*)); + MOCK_METHOD1(AcceptReference, void(linked_ptr<MockA>*)); private: GTEST_DISALLOW_COPY_AND_ASSIGN_(ReferenceHoldingMock); @@ -2619,7 +2619,7 @@ TEST(VerifyAndClearTest, DoesNotAffectOtherMockObjects) { TEST(VerifyAndClearTest, DestroyingChainedMocksDoesNotDeadlockThroughExpectations) { - std::shared_ptr<MockA> a(new MockA); + linked_ptr<MockA> a(new MockA); ReferenceHoldingMock test_mock; // EXPECT_CALL stores a reference to a inside test_mock. @@ -2639,7 +2639,7 @@ TEST(VerifyAndClearTest, TEST(VerifyAndClearTest, DestroyingChainedMocksDoesNotDeadlockThroughDefaultAction) { - std::shared_ptr<MockA> a(new MockA); + linked_ptr<MockA> a(new MockA); ReferenceHoldingMock test_mock; // ON_CALL stores a reference to a inside test_mock. diff --git a/googlemock/test/gmock_stress_test.cc b/googlemock/test/gmock_stress_test.cc index 20725d69..9ae0b1e5 100644 --- a/googlemock/test/gmock_stress_test.cc +++ b/googlemock/test/gmock_stress_test.cc @@ -60,8 +60,87 @@ void JoinAndDelete(ThreadWithParam<T>* t) { delete t; } +using internal::linked_ptr; + +// Helper classes for testing using linked_ptr concurrently. + +class Base { + public: + explicit Base(int a_x) : x_(a_x) {} + virtual ~Base() {} + int x() const { return x_; } + private: + int x_; +}; + +class Derived1 : public Base { + public: + Derived1(int a_x, int a_y) : Base(a_x), y_(a_y) {} + int y() const { return y_; } + private: + int y_; +}; + +class Derived2 : public Base { + public: + Derived2(int a_x, int a_z) : Base(a_x), z_(a_z) {} + int z() const { return z_; } + private: + int z_; +}; + +linked_ptr<Derived1> pointer1(new Derived1(1, 2)); +linked_ptr<Derived2> pointer2(new Derived2(3, 4)); + struct Dummy {}; +// Tests that we can copy from a linked_ptr and read it concurrently. +void TestConcurrentCopyAndReadLinkedPtr(Dummy /* dummy */) { + // Reads pointer1 and pointer2 while they are being copied from in + // another thread. + EXPECT_EQ(1, pointer1->x()); + EXPECT_EQ(2, pointer1->y()); + EXPECT_EQ(3, pointer2->x()); + EXPECT_EQ(4, pointer2->z()); + + // Copies from pointer1. + linked_ptr<Derived1> p1(pointer1); + EXPECT_EQ(1, p1->x()); + EXPECT_EQ(2, p1->y()); + + // Assigns from pointer2 where the LHS was empty. + linked_ptr<Base> p2; + p2 = pointer1; + EXPECT_EQ(1, p2->x()); + + // Assigns from pointer2 where the LHS was not empty. + p2 = pointer2; + EXPECT_EQ(3, p2->x()); +} + +const linked_ptr<Derived1> p0(new Derived1(1, 2)); + +// Tests that we can concurrently modify two linked_ptrs that point to +// the same object. +void TestConcurrentWriteToEqualLinkedPtr(Dummy /* dummy */) { + // p1 and p2 point to the same, shared thing. One thread resets p1. + // Another thread assigns to p2. This will cause the same + // underlying "ring" to be updated concurrently. + linked_ptr<Derived1> p1(p0); + linked_ptr<Derived1> p2(p0); + + EXPECT_EQ(1, p1->x()); + EXPECT_EQ(2, p1->y()); + + EXPECT_EQ(1, p2->x()); + EXPECT_EQ(2, p2->y()); + + p1.reset(); + p2 = p0; + + EXPECT_EQ(1, p2->x()); + EXPECT_EQ(2, p2->y()); +} // Tests that different mock objects can be used in their respective // threads. This should generate no Google Test failure. @@ -196,6 +275,8 @@ void TestPartiallyOrderedExpectationsWithThreads(Dummy /* dummy */) { // Tests using Google Mock constructs in many threads concurrently. TEST(StressTest, CanUseGMockWithThreads) { void (*test_routines[])(Dummy dummy) = { + &TestConcurrentCopyAndReadLinkedPtr, + &TestConcurrentWriteToEqualLinkedPtr, &TestConcurrentMockObjects, &TestConcurrentCallsOnSameObject, &TestPartiallyOrderedExpectationsWithThreads, |