113481Sgiacomo.travaglini@arm.com// Copyright 2007, Google Inc.
213481Sgiacomo.travaglini@arm.com// All rights reserved.
313481Sgiacomo.travaglini@arm.com//
413481Sgiacomo.travaglini@arm.com// Redistribution and use in source and binary forms, with or without
513481Sgiacomo.travaglini@arm.com// modification, are permitted provided that the following conditions are
613481Sgiacomo.travaglini@arm.com// met:
713481Sgiacomo.travaglini@arm.com//
813481Sgiacomo.travaglini@arm.com//     * Redistributions of source code must retain the above copyright
913481Sgiacomo.travaglini@arm.com// notice, this list of conditions and the following disclaimer.
1013481Sgiacomo.travaglini@arm.com//     * Redistributions in binary form must reproduce the above
1113481Sgiacomo.travaglini@arm.com// copyright notice, this list of conditions and the following disclaimer
1213481Sgiacomo.travaglini@arm.com// in the documentation and/or other materials provided with the
1313481Sgiacomo.travaglini@arm.com// distribution.
1413481Sgiacomo.travaglini@arm.com//     * Neither the name of Google Inc. nor the names of its
1513481Sgiacomo.travaglini@arm.com// contributors may be used to endorse or promote products derived from
1613481Sgiacomo.travaglini@arm.com// this software without specific prior written permission.
1713481Sgiacomo.travaglini@arm.com//
1813481Sgiacomo.travaglini@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1913481Sgiacomo.travaglini@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2013481Sgiacomo.travaglini@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2113481Sgiacomo.travaglini@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2213481Sgiacomo.travaglini@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2313481Sgiacomo.travaglini@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2413481Sgiacomo.travaglini@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2513481Sgiacomo.travaglini@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2613481Sgiacomo.travaglini@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2713481Sgiacomo.travaglini@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2813481Sgiacomo.travaglini@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2913481Sgiacomo.travaglini@arm.com//
3013481Sgiacomo.travaglini@arm.com// Author: wan@google.com (Zhanyong Wan)
3113481Sgiacomo.travaglini@arm.com
3213481Sgiacomo.travaglini@arm.com// Google Mock - a framework for writing C++ mock classes.
3313481Sgiacomo.travaglini@arm.com//
3413481Sgiacomo.travaglini@arm.com// This file implements some commonly used actions.
3513481Sgiacomo.travaglini@arm.com
3613481Sgiacomo.travaglini@arm.com#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
3713481Sgiacomo.travaglini@arm.com#define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
3813481Sgiacomo.travaglini@arm.com
3913481Sgiacomo.travaglini@arm.com#ifndef _WIN32_WCE
4013481Sgiacomo.travaglini@arm.com# include <errno.h>
4113481Sgiacomo.travaglini@arm.com#endif
4213481Sgiacomo.travaglini@arm.com
4313481Sgiacomo.travaglini@arm.com#include <algorithm>
4413481Sgiacomo.travaglini@arm.com#include <string>
4513481Sgiacomo.travaglini@arm.com
4613481Sgiacomo.travaglini@arm.com#include "gmock/internal/gmock-internal-utils.h"
4713481Sgiacomo.travaglini@arm.com#include "gmock/internal/gmock-port.h"
4813481Sgiacomo.travaglini@arm.com
4913481Sgiacomo.travaglini@arm.com#if GTEST_HAS_STD_TYPE_TRAITS_  // Defined by gtest-port.h via gmock-port.h.
5013481Sgiacomo.travaglini@arm.com#include <type_traits>
5113481Sgiacomo.travaglini@arm.com#endif
5213481Sgiacomo.travaglini@arm.com
5313481Sgiacomo.travaglini@arm.comnamespace testing {
5413481Sgiacomo.travaglini@arm.com
5513481Sgiacomo.travaglini@arm.com// To implement an action Foo, define:
5613481Sgiacomo.travaglini@arm.com//   1. a class FooAction that implements the ActionInterface interface, and
5713481Sgiacomo.travaglini@arm.com//   2. a factory function that creates an Action object from a
5813481Sgiacomo.travaglini@arm.com//      const FooAction*.
5913481Sgiacomo.travaglini@arm.com//
6013481Sgiacomo.travaglini@arm.com// The two-level delegation design follows that of Matcher, providing
6113481Sgiacomo.travaglini@arm.com// consistency for extension developers.  It also eases ownership
6213481Sgiacomo.travaglini@arm.com// management as Action objects can now be copied like plain values.
6313481Sgiacomo.travaglini@arm.com
6413481Sgiacomo.travaglini@arm.comnamespace internal {
6513481Sgiacomo.travaglini@arm.com
6613481Sgiacomo.travaglini@arm.comtemplate <typename F1, typename F2>
6713481Sgiacomo.travaglini@arm.comclass ActionAdaptor;
6813481Sgiacomo.travaglini@arm.com
6913481Sgiacomo.travaglini@arm.com// BuiltInDefaultValueGetter<T, true>::Get() returns a
7013481Sgiacomo.travaglini@arm.com// default-constructed T value.  BuiltInDefaultValueGetter<T,
7113481Sgiacomo.travaglini@arm.com// false>::Get() crashes with an error.
7213481Sgiacomo.travaglini@arm.com//
7313481Sgiacomo.travaglini@arm.com// This primary template is used when kDefaultConstructible is true.
7413481Sgiacomo.travaglini@arm.comtemplate <typename T, bool kDefaultConstructible>
7513481Sgiacomo.travaglini@arm.comstruct BuiltInDefaultValueGetter {
7613481Sgiacomo.travaglini@arm.com  static T Get() { return T(); }
7713481Sgiacomo.travaglini@arm.com};
7813481Sgiacomo.travaglini@arm.comtemplate <typename T>
7913481Sgiacomo.travaglini@arm.comstruct BuiltInDefaultValueGetter<T, false> {
8013481Sgiacomo.travaglini@arm.com  static T Get() {
8113481Sgiacomo.travaglini@arm.com    Assert(false, __FILE__, __LINE__,
8213481Sgiacomo.travaglini@arm.com           "Default action undefined for the function return type.");
8313481Sgiacomo.travaglini@arm.com    return internal::Invalid<T>();
8413481Sgiacomo.travaglini@arm.com    // The above statement will never be reached, but is required in
8513481Sgiacomo.travaglini@arm.com    // order for this function to compile.
8613481Sgiacomo.travaglini@arm.com  }
8713481Sgiacomo.travaglini@arm.com};
8813481Sgiacomo.travaglini@arm.com
8913481Sgiacomo.travaglini@arm.com// BuiltInDefaultValue<T>::Get() returns the "built-in" default value
9013481Sgiacomo.travaglini@arm.com// for type T, which is NULL when T is a raw pointer type, 0 when T is
9113481Sgiacomo.travaglini@arm.com// a numeric type, false when T is bool, or "" when T is string or
9213481Sgiacomo.travaglini@arm.com// std::string.  In addition, in C++11 and above, it turns a
9313481Sgiacomo.travaglini@arm.com// default-constructed T value if T is default constructible.  For any
9413481Sgiacomo.travaglini@arm.com// other type T, the built-in default T value is undefined, and the
9513481Sgiacomo.travaglini@arm.com// function will abort the process.
9613481Sgiacomo.travaglini@arm.comtemplate <typename T>
9713481Sgiacomo.travaglini@arm.comclass BuiltInDefaultValue {
9813481Sgiacomo.travaglini@arm.com public:
9913481Sgiacomo.travaglini@arm.com#if GTEST_HAS_STD_TYPE_TRAITS_
10013481Sgiacomo.travaglini@arm.com  // This function returns true iff type T has a built-in default value.
10113481Sgiacomo.travaglini@arm.com  static bool Exists() {
10213481Sgiacomo.travaglini@arm.com    return ::std::is_default_constructible<T>::value;
10313481Sgiacomo.travaglini@arm.com  }
10413481Sgiacomo.travaglini@arm.com
10513481Sgiacomo.travaglini@arm.com  static T Get() {
10613481Sgiacomo.travaglini@arm.com    return BuiltInDefaultValueGetter<
10713481Sgiacomo.travaglini@arm.com        T, ::std::is_default_constructible<T>::value>::Get();
10813481Sgiacomo.travaglini@arm.com  }
10913481Sgiacomo.travaglini@arm.com
11013481Sgiacomo.travaglini@arm.com#else  // GTEST_HAS_STD_TYPE_TRAITS_
11113481Sgiacomo.travaglini@arm.com  // This function returns true iff type T has a built-in default value.
11213481Sgiacomo.travaglini@arm.com  static bool Exists() {
11313481Sgiacomo.travaglini@arm.com    return false;
11413481Sgiacomo.travaglini@arm.com  }
11513481Sgiacomo.travaglini@arm.com
11613481Sgiacomo.travaglini@arm.com  static T Get() {
11713481Sgiacomo.travaglini@arm.com    return BuiltInDefaultValueGetter<T, false>::Get();
11813481Sgiacomo.travaglini@arm.com  }
11913481Sgiacomo.travaglini@arm.com
12013481Sgiacomo.travaglini@arm.com#endif  // GTEST_HAS_STD_TYPE_TRAITS_
12113481Sgiacomo.travaglini@arm.com};
12213481Sgiacomo.travaglini@arm.com
12313481Sgiacomo.travaglini@arm.com// This partial specialization says that we use the same built-in
12413481Sgiacomo.travaglini@arm.com// default value for T and const T.
12513481Sgiacomo.travaglini@arm.comtemplate <typename T>
12613481Sgiacomo.travaglini@arm.comclass BuiltInDefaultValue<const T> {
12713481Sgiacomo.travaglini@arm.com public:
12813481Sgiacomo.travaglini@arm.com  static bool Exists() { return BuiltInDefaultValue<T>::Exists(); }
12913481Sgiacomo.travaglini@arm.com  static T Get() { return BuiltInDefaultValue<T>::Get(); }
13013481Sgiacomo.travaglini@arm.com};
13113481Sgiacomo.travaglini@arm.com
13213481Sgiacomo.travaglini@arm.com// This partial specialization defines the default values for pointer
13313481Sgiacomo.travaglini@arm.com// types.
13413481Sgiacomo.travaglini@arm.comtemplate <typename T>
13513481Sgiacomo.travaglini@arm.comclass BuiltInDefaultValue<T*> {
13613481Sgiacomo.travaglini@arm.com public:
13713481Sgiacomo.travaglini@arm.com  static bool Exists() { return true; }
13813481Sgiacomo.travaglini@arm.com  static T* Get() { return NULL; }
13913481Sgiacomo.travaglini@arm.com};
14013481Sgiacomo.travaglini@arm.com
14113481Sgiacomo.travaglini@arm.com// The following specializations define the default values for
14213481Sgiacomo.travaglini@arm.com// specific types we care about.
14313481Sgiacomo.travaglini@arm.com#define GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(type, value) \
14413481Sgiacomo.travaglini@arm.com  template <> \
14513481Sgiacomo.travaglini@arm.com  class BuiltInDefaultValue<type> { \
14613481Sgiacomo.travaglini@arm.com   public: \
14713481Sgiacomo.travaglini@arm.com    static bool Exists() { return true; } \
14813481Sgiacomo.travaglini@arm.com    static type Get() { return value; } \
14913481Sgiacomo.travaglini@arm.com  }
15013481Sgiacomo.travaglini@arm.com
15113481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(void, );  // NOLINT
15213481Sgiacomo.travaglini@arm.com#if GTEST_HAS_GLOBAL_STRING
15313481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::string, "");
15413481Sgiacomo.travaglini@arm.com#endif  // GTEST_HAS_GLOBAL_STRING
15513481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::std::string, "");
15613481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(bool, false);
15713481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned char, '\0');
15813481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed char, '\0');
15913481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(char, '\0');
16013481Sgiacomo.travaglini@arm.com
16113481Sgiacomo.travaglini@arm.com// There's no need for a default action for signed wchar_t, as that
16213481Sgiacomo.travaglini@arm.com// type is the same as wchar_t for gcc, and invalid for MSVC.
16313481Sgiacomo.travaglini@arm.com//
16413481Sgiacomo.travaglini@arm.com// There's also no need for a default action for unsigned wchar_t, as
16513481Sgiacomo.travaglini@arm.com// that type is the same as unsigned int for gcc, and invalid for
16613481Sgiacomo.travaglini@arm.com// MSVC.
16713481Sgiacomo.travaglini@arm.com#if GMOCK_WCHAR_T_IS_NATIVE_
16813481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(wchar_t, 0U);  // NOLINT
16913481Sgiacomo.travaglini@arm.com#endif
17013481Sgiacomo.travaglini@arm.com
17113481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned short, 0U);  // NOLINT
17213481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed short, 0);     // NOLINT
17313481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned int, 0U);
17413481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed int, 0);
17513481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long, 0UL);  // NOLINT
17613481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long, 0L);     // NOLINT
17713481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(UInt64, 0);
17813481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(Int64, 0);
17913481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(float, 0);
18013481Sgiacomo.travaglini@arm.comGMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0);
18113481Sgiacomo.travaglini@arm.com
18213481Sgiacomo.travaglini@arm.com#undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_
18313481Sgiacomo.travaglini@arm.com
18413481Sgiacomo.travaglini@arm.com}  // namespace internal
18513481Sgiacomo.travaglini@arm.com
18613481Sgiacomo.travaglini@arm.com// When an unexpected function call is encountered, Google Mock will
18713481Sgiacomo.travaglini@arm.com// let it return a default value if the user has specified one for its
18813481Sgiacomo.travaglini@arm.com// return type, or if the return type has a built-in default value;
18913481Sgiacomo.travaglini@arm.com// otherwise Google Mock won't know what value to return and will have
19013481Sgiacomo.travaglini@arm.com// to abort the process.
19113481Sgiacomo.travaglini@arm.com//
19213481Sgiacomo.travaglini@arm.com// The DefaultValue<T> class allows a user to specify the
19313481Sgiacomo.travaglini@arm.com// default value for a type T that is both copyable and publicly
19413481Sgiacomo.travaglini@arm.com// destructible (i.e. anything that can be used as a function return
19513481Sgiacomo.travaglini@arm.com// type).  The usage is:
19613481Sgiacomo.travaglini@arm.com//
19713481Sgiacomo.travaglini@arm.com//   // Sets the default value for type T to be foo.
19813481Sgiacomo.travaglini@arm.com//   DefaultValue<T>::Set(foo);
19913481Sgiacomo.travaglini@arm.comtemplate <typename T>
20013481Sgiacomo.travaglini@arm.comclass DefaultValue {
20113481Sgiacomo.travaglini@arm.com public:
20213481Sgiacomo.travaglini@arm.com  // Sets the default value for type T; requires T to be
20313481Sgiacomo.travaglini@arm.com  // copy-constructable and have a public destructor.
20413481Sgiacomo.travaglini@arm.com  static void Set(T x) {
20513481Sgiacomo.travaglini@arm.com    delete producer_;
20613481Sgiacomo.travaglini@arm.com    producer_ = new FixedValueProducer(x);
20713481Sgiacomo.travaglini@arm.com  }
20813481Sgiacomo.travaglini@arm.com
20913481Sgiacomo.travaglini@arm.com  // Provides a factory function to be called to generate the default value.
21013481Sgiacomo.travaglini@arm.com  // This method can be used even if T is only move-constructible, but it is not
21113481Sgiacomo.travaglini@arm.com  // limited to that case.
21213481Sgiacomo.travaglini@arm.com  typedef T (*FactoryFunction)();
21313481Sgiacomo.travaglini@arm.com  static void SetFactory(FactoryFunction factory) {
21413481Sgiacomo.travaglini@arm.com    delete producer_;
21513481Sgiacomo.travaglini@arm.com    producer_ = new FactoryValueProducer(factory);
21613481Sgiacomo.travaglini@arm.com  }
21713481Sgiacomo.travaglini@arm.com
21813481Sgiacomo.travaglini@arm.com  // Unsets the default value for type T.
21913481Sgiacomo.travaglini@arm.com  static void Clear() {
22013481Sgiacomo.travaglini@arm.com    delete producer_;
22113481Sgiacomo.travaglini@arm.com    producer_ = NULL;
22213481Sgiacomo.travaglini@arm.com  }
22313481Sgiacomo.travaglini@arm.com
22413481Sgiacomo.travaglini@arm.com  // Returns true iff the user has set the default value for type T.
22513481Sgiacomo.travaglini@arm.com  static bool IsSet() { return producer_ != NULL; }
22613481Sgiacomo.travaglini@arm.com
22713481Sgiacomo.travaglini@arm.com  // Returns true if T has a default return value set by the user or there
22813481Sgiacomo.travaglini@arm.com  // exists a built-in default value.
22913481Sgiacomo.travaglini@arm.com  static bool Exists() {
23013481Sgiacomo.travaglini@arm.com    return IsSet() || internal::BuiltInDefaultValue<T>::Exists();
23113481Sgiacomo.travaglini@arm.com  }
23213481Sgiacomo.travaglini@arm.com
23313481Sgiacomo.travaglini@arm.com  // Returns the default value for type T if the user has set one;
23413481Sgiacomo.travaglini@arm.com  // otherwise returns the built-in default value. Requires that Exists()
23513481Sgiacomo.travaglini@arm.com  // is true, which ensures that the return value is well-defined.
23613481Sgiacomo.travaglini@arm.com  static T Get() {
23713481Sgiacomo.travaglini@arm.com    return producer_ == NULL ?
23813481Sgiacomo.travaglini@arm.com        internal::BuiltInDefaultValue<T>::Get() : producer_->Produce();
23913481Sgiacomo.travaglini@arm.com  }
24013481Sgiacomo.travaglini@arm.com
24113481Sgiacomo.travaglini@arm.com private:
24213481Sgiacomo.travaglini@arm.com  class ValueProducer {
24313481Sgiacomo.travaglini@arm.com   public:
24413481Sgiacomo.travaglini@arm.com    virtual ~ValueProducer() {}
24513481Sgiacomo.travaglini@arm.com    virtual T Produce() = 0;
24613481Sgiacomo.travaglini@arm.com  };
24713481Sgiacomo.travaglini@arm.com
24813481Sgiacomo.travaglini@arm.com  class FixedValueProducer : public ValueProducer {
24913481Sgiacomo.travaglini@arm.com   public:
25013481Sgiacomo.travaglini@arm.com    explicit FixedValueProducer(T value) : value_(value) {}
25113481Sgiacomo.travaglini@arm.com    virtual T Produce() { return value_; }
25213481Sgiacomo.travaglini@arm.com
25313481Sgiacomo.travaglini@arm.com   private:
25413481Sgiacomo.travaglini@arm.com    const T value_;
25513481Sgiacomo.travaglini@arm.com    GTEST_DISALLOW_COPY_AND_ASSIGN_(FixedValueProducer);
25613481Sgiacomo.travaglini@arm.com  };
25713481Sgiacomo.travaglini@arm.com
25813481Sgiacomo.travaglini@arm.com  class FactoryValueProducer : public ValueProducer {
25913481Sgiacomo.travaglini@arm.com   public:
26013481Sgiacomo.travaglini@arm.com    explicit FactoryValueProducer(FactoryFunction factory)
26113481Sgiacomo.travaglini@arm.com        : factory_(factory) {}
26213481Sgiacomo.travaglini@arm.com    virtual T Produce() { return factory_(); }
26313481Sgiacomo.travaglini@arm.com
26413481Sgiacomo.travaglini@arm.com   private:
26513481Sgiacomo.travaglini@arm.com    const FactoryFunction factory_;
26613481Sgiacomo.travaglini@arm.com    GTEST_DISALLOW_COPY_AND_ASSIGN_(FactoryValueProducer);
26713481Sgiacomo.travaglini@arm.com  };
26813481Sgiacomo.travaglini@arm.com
26913481Sgiacomo.travaglini@arm.com  static ValueProducer* producer_;
27013481Sgiacomo.travaglini@arm.com};
27113481Sgiacomo.travaglini@arm.com
27213481Sgiacomo.travaglini@arm.com// This partial specialization allows a user to set default values for
27313481Sgiacomo.travaglini@arm.com// reference types.
27413481Sgiacomo.travaglini@arm.comtemplate <typename T>
27513481Sgiacomo.travaglini@arm.comclass DefaultValue<T&> {
27613481Sgiacomo.travaglini@arm.com public:
27713481Sgiacomo.travaglini@arm.com  // Sets the default value for type T&.
27813481Sgiacomo.travaglini@arm.com  static void Set(T& x) {  // NOLINT
27913481Sgiacomo.travaglini@arm.com    address_ = &x;
28013481Sgiacomo.travaglini@arm.com  }
28113481Sgiacomo.travaglini@arm.com
28213481Sgiacomo.travaglini@arm.com  // Unsets the default value for type T&.
28313481Sgiacomo.travaglini@arm.com  static void Clear() {
28413481Sgiacomo.travaglini@arm.com    address_ = NULL;
28513481Sgiacomo.travaglini@arm.com  }
28613481Sgiacomo.travaglini@arm.com
28713481Sgiacomo.travaglini@arm.com  // Returns true iff the user has set the default value for type T&.
28813481Sgiacomo.travaglini@arm.com  static bool IsSet() { return address_ != NULL; }
28913481Sgiacomo.travaglini@arm.com
29013481Sgiacomo.travaglini@arm.com  // Returns true if T has a default return value set by the user or there
29113481Sgiacomo.travaglini@arm.com  // exists a built-in default value.
29213481Sgiacomo.travaglini@arm.com  static bool Exists() {
29313481Sgiacomo.travaglini@arm.com    return IsSet() || internal::BuiltInDefaultValue<T&>::Exists();
29413481Sgiacomo.travaglini@arm.com  }
29513481Sgiacomo.travaglini@arm.com
29613481Sgiacomo.travaglini@arm.com  // Returns the default value for type T& if the user has set one;
29713481Sgiacomo.travaglini@arm.com  // otherwise returns the built-in default value if there is one;
29813481Sgiacomo.travaglini@arm.com  // otherwise aborts the process.
29913481Sgiacomo.travaglini@arm.com  static T& Get() {
30013481Sgiacomo.travaglini@arm.com    return address_ == NULL ?
30113481Sgiacomo.travaglini@arm.com        internal::BuiltInDefaultValue<T&>::Get() : *address_;
30213481Sgiacomo.travaglini@arm.com  }
30313481Sgiacomo.travaglini@arm.com
30413481Sgiacomo.travaglini@arm.com private:
30513481Sgiacomo.travaglini@arm.com  static T* address_;
30613481Sgiacomo.travaglini@arm.com};
30713481Sgiacomo.travaglini@arm.com
30813481Sgiacomo.travaglini@arm.com// This specialization allows DefaultValue<void>::Get() to
30913481Sgiacomo.travaglini@arm.com// compile.
31013481Sgiacomo.travaglini@arm.comtemplate <>
31113481Sgiacomo.travaglini@arm.comclass DefaultValue<void> {
31213481Sgiacomo.travaglini@arm.com public:
31313481Sgiacomo.travaglini@arm.com  static bool Exists() { return true; }
31413481Sgiacomo.travaglini@arm.com  static void Get() {}
31513481Sgiacomo.travaglini@arm.com};
31613481Sgiacomo.travaglini@arm.com
31713481Sgiacomo.travaglini@arm.com// Points to the user-set default value for type T.
31813481Sgiacomo.travaglini@arm.comtemplate <typename T>
31913481Sgiacomo.travaglini@arm.comtypename DefaultValue<T>::ValueProducer* DefaultValue<T>::producer_ = NULL;
32013481Sgiacomo.travaglini@arm.com
32113481Sgiacomo.travaglini@arm.com// Points to the user-set default value for type T&.
32213481Sgiacomo.travaglini@arm.comtemplate <typename T>
32313481Sgiacomo.travaglini@arm.comT* DefaultValue<T&>::address_ = NULL;
32413481Sgiacomo.travaglini@arm.com
32513481Sgiacomo.travaglini@arm.com// Implement this interface to define an action for function type F.
32613481Sgiacomo.travaglini@arm.comtemplate <typename F>
32713481Sgiacomo.travaglini@arm.comclass ActionInterface {
32813481Sgiacomo.travaglini@arm.com public:
32913481Sgiacomo.travaglini@arm.com  typedef typename internal::Function<F>::Result Result;
33013481Sgiacomo.travaglini@arm.com  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
33113481Sgiacomo.travaglini@arm.com
33213481Sgiacomo.travaglini@arm.com  ActionInterface() {}
33313481Sgiacomo.travaglini@arm.com  virtual ~ActionInterface() {}
33413481Sgiacomo.travaglini@arm.com
33513481Sgiacomo.travaglini@arm.com  // Performs the action.  This method is not const, as in general an
33613481Sgiacomo.travaglini@arm.com  // action can have side effects and be stateful.  For example, a
33713481Sgiacomo.travaglini@arm.com  // get-the-next-element-from-the-collection action will need to
33813481Sgiacomo.travaglini@arm.com  // remember the current element.
33913481Sgiacomo.travaglini@arm.com  virtual Result Perform(const ArgumentTuple& args) = 0;
34013481Sgiacomo.travaglini@arm.com
34113481Sgiacomo.travaglini@arm.com private:
34213481Sgiacomo.travaglini@arm.com  GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionInterface);
34313481Sgiacomo.travaglini@arm.com};
34413481Sgiacomo.travaglini@arm.com
34513481Sgiacomo.travaglini@arm.com// An Action<F> is a copyable and IMMUTABLE (except by assignment)
34613481Sgiacomo.travaglini@arm.com// object that represents an action to be taken when a mock function
34713481Sgiacomo.travaglini@arm.com// of type F is called.  The implementation of Action<T> is just a
34813481Sgiacomo.travaglini@arm.com// linked_ptr to const ActionInterface<T>, so copying is fairly cheap.
34913481Sgiacomo.travaglini@arm.com// Don't inherit from Action!
35013481Sgiacomo.travaglini@arm.com//
35113481Sgiacomo.travaglini@arm.com// You can view an object implementing ActionInterface<F> as a
35213481Sgiacomo.travaglini@arm.com// concrete action (including its current state), and an Action<F>
35313481Sgiacomo.travaglini@arm.com// object as a handle to it.
35413481Sgiacomo.travaglini@arm.comtemplate <typename F>
35513481Sgiacomo.travaglini@arm.comclass Action {
35613481Sgiacomo.travaglini@arm.com public:
35713481Sgiacomo.travaglini@arm.com  typedef typename internal::Function<F>::Result Result;
35813481Sgiacomo.travaglini@arm.com  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
35913481Sgiacomo.travaglini@arm.com
36013481Sgiacomo.travaglini@arm.com  // Constructs a null Action.  Needed for storing Action objects in
36113481Sgiacomo.travaglini@arm.com  // STL containers.
36213481Sgiacomo.travaglini@arm.com  Action() : impl_(NULL) {}
36313481Sgiacomo.travaglini@arm.com
36413481Sgiacomo.travaglini@arm.com  // Constructs an Action from its implementation.  A NULL impl is
36513481Sgiacomo.travaglini@arm.com  // used to represent the "do-default" action.
36613481Sgiacomo.travaglini@arm.com  explicit Action(ActionInterface<F>* impl) : impl_(impl) {}
36713481Sgiacomo.travaglini@arm.com
36813481Sgiacomo.travaglini@arm.com  // Copy constructor.
36913481Sgiacomo.travaglini@arm.com  Action(const Action& action) : impl_(action.impl_) {}
37013481Sgiacomo.travaglini@arm.com
37113481Sgiacomo.travaglini@arm.com  // This constructor allows us to turn an Action<Func> object into an
37213481Sgiacomo.travaglini@arm.com  // Action<F>, as long as F's arguments can be implicitly converted
37313481Sgiacomo.travaglini@arm.com  // to Func's and Func's return type can be implicitly converted to
37413481Sgiacomo.travaglini@arm.com  // F's.
37513481Sgiacomo.travaglini@arm.com  template <typename Func>
37613481Sgiacomo.travaglini@arm.com  explicit Action(const Action<Func>& action);
37713481Sgiacomo.travaglini@arm.com
37813481Sgiacomo.travaglini@arm.com  // Returns true iff this is the DoDefault() action.
37913481Sgiacomo.travaglini@arm.com  bool IsDoDefault() const { return impl_.get() == NULL; }
38013481Sgiacomo.travaglini@arm.com
38113481Sgiacomo.travaglini@arm.com  // Performs the action.  Note that this method is const even though
38213481Sgiacomo.travaglini@arm.com  // the corresponding method in ActionInterface is not.  The reason
38313481Sgiacomo.travaglini@arm.com  // is that a const Action<F> means that it cannot be re-bound to
38413481Sgiacomo.travaglini@arm.com  // another concrete action, not that the concrete action it binds to
38513481Sgiacomo.travaglini@arm.com  // cannot change state.  (Think of the difference between a const
38613481Sgiacomo.travaglini@arm.com  // pointer and a pointer to const.)
38713481Sgiacomo.travaglini@arm.com  Result Perform(const ArgumentTuple& args) const {
38813481Sgiacomo.travaglini@arm.com    internal::Assert(
38913481Sgiacomo.travaglini@arm.com        !IsDoDefault(), __FILE__, __LINE__,
39013481Sgiacomo.travaglini@arm.com        "You are using DoDefault() inside a composite action like "
39113481Sgiacomo.travaglini@arm.com        "DoAll() or WithArgs().  This is not supported for technical "
39213481Sgiacomo.travaglini@arm.com        "reasons.  Please instead spell out the default action, or "
39313481Sgiacomo.travaglini@arm.com        "assign the default action to an Action variable and use "
39413481Sgiacomo.travaglini@arm.com        "the variable in various places.");
39513481Sgiacomo.travaglini@arm.com    return impl_->Perform(args);
39613481Sgiacomo.travaglini@arm.com  }
39713481Sgiacomo.travaglini@arm.com
39813481Sgiacomo.travaglini@arm.com private:
39913481Sgiacomo.travaglini@arm.com  template <typename F1, typename F2>
40013481Sgiacomo.travaglini@arm.com  friend class internal::ActionAdaptor;
40113481Sgiacomo.travaglini@arm.com
40213481Sgiacomo.travaglini@arm.com  internal::linked_ptr<ActionInterface<F> > impl_;
40313481Sgiacomo.travaglini@arm.com};
40413481Sgiacomo.travaglini@arm.com
40513481Sgiacomo.travaglini@arm.com// The PolymorphicAction class template makes it easy to implement a
40613481Sgiacomo.travaglini@arm.com// polymorphic action (i.e. an action that can be used in mock
40713481Sgiacomo.travaglini@arm.com// functions of than one type, e.g. Return()).
40813481Sgiacomo.travaglini@arm.com//
40913481Sgiacomo.travaglini@arm.com// To define a polymorphic action, a user first provides a COPYABLE
41013481Sgiacomo.travaglini@arm.com// implementation class that has a Perform() method template:
41113481Sgiacomo.travaglini@arm.com//
41213481Sgiacomo.travaglini@arm.com//   class FooAction {
41313481Sgiacomo.travaglini@arm.com//    public:
41413481Sgiacomo.travaglini@arm.com//     template <typename Result, typename ArgumentTuple>
41513481Sgiacomo.travaglini@arm.com//     Result Perform(const ArgumentTuple& args) const {
41613481Sgiacomo.travaglini@arm.com//       // Processes the arguments and returns a result, using
41713481Sgiacomo.travaglini@arm.com//       // tr1::get<N>(args) to get the N-th (0-based) argument in the tuple.
41813481Sgiacomo.travaglini@arm.com//     }
41913481Sgiacomo.travaglini@arm.com//     ...
42013481Sgiacomo.travaglini@arm.com//   };
42113481Sgiacomo.travaglini@arm.com//
42213481Sgiacomo.travaglini@arm.com// Then the user creates the polymorphic action using
42313481Sgiacomo.travaglini@arm.com// MakePolymorphicAction(object) where object has type FooAction.  See
42413481Sgiacomo.travaglini@arm.com// the definition of Return(void) and SetArgumentPointee<N>(value) for
42513481Sgiacomo.travaglini@arm.com// complete examples.
42613481Sgiacomo.travaglini@arm.comtemplate <typename Impl>
42713481Sgiacomo.travaglini@arm.comclass PolymorphicAction {
42813481Sgiacomo.travaglini@arm.com public:
42913481Sgiacomo.travaglini@arm.com  explicit PolymorphicAction(const Impl& impl) : impl_(impl) {}
43013481Sgiacomo.travaglini@arm.com
43113481Sgiacomo.travaglini@arm.com  template <typename F>
43213481Sgiacomo.travaglini@arm.com  operator Action<F>() const {
43313481Sgiacomo.travaglini@arm.com    return Action<F>(new MonomorphicImpl<F>(impl_));
43413481Sgiacomo.travaglini@arm.com  }
43513481Sgiacomo.travaglini@arm.com
43613481Sgiacomo.travaglini@arm.com private:
43713481Sgiacomo.travaglini@arm.com  template <typename F>
43813481Sgiacomo.travaglini@arm.com  class MonomorphicImpl : public ActionInterface<F> {
43913481Sgiacomo.travaglini@arm.com   public:
44013481Sgiacomo.travaglini@arm.com    typedef typename internal::Function<F>::Result Result;
44113481Sgiacomo.travaglini@arm.com    typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
44213481Sgiacomo.travaglini@arm.com
44313481Sgiacomo.travaglini@arm.com    explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
44413481Sgiacomo.travaglini@arm.com
44513481Sgiacomo.travaglini@arm.com    virtual Result Perform(const ArgumentTuple& args) {
44613481Sgiacomo.travaglini@arm.com      return impl_.template Perform<Result>(args);
44713481Sgiacomo.travaglini@arm.com    }
44813481Sgiacomo.travaglini@arm.com
44913481Sgiacomo.travaglini@arm.com   private:
45013481Sgiacomo.travaglini@arm.com    Impl impl_;
45113481Sgiacomo.travaglini@arm.com
45213481Sgiacomo.travaglini@arm.com    GTEST_DISALLOW_ASSIGN_(MonomorphicImpl);
45313481Sgiacomo.travaglini@arm.com  };
45413481Sgiacomo.travaglini@arm.com
45513481Sgiacomo.travaglini@arm.com  Impl impl_;
45613481Sgiacomo.travaglini@arm.com
45713481Sgiacomo.travaglini@arm.com  GTEST_DISALLOW_ASSIGN_(PolymorphicAction);
45813481Sgiacomo.travaglini@arm.com};
45913481Sgiacomo.travaglini@arm.com
46013481Sgiacomo.travaglini@arm.com// Creates an Action from its implementation and returns it.  The
46113481Sgiacomo.travaglini@arm.com// created Action object owns the implementation.
46213481Sgiacomo.travaglini@arm.comtemplate <typename F>
46313481Sgiacomo.travaglini@arm.comAction<F> MakeAction(ActionInterface<F>* impl) {
46413481Sgiacomo.travaglini@arm.com  return Action<F>(impl);
46513481Sgiacomo.travaglini@arm.com}
46613481Sgiacomo.travaglini@arm.com
46713481Sgiacomo.travaglini@arm.com// Creates a polymorphic action from its implementation.  This is
46813481Sgiacomo.travaglini@arm.com// easier to use than the PolymorphicAction<Impl> constructor as it
46913481Sgiacomo.travaglini@arm.com// doesn't require you to explicitly write the template argument, e.g.
47013481Sgiacomo.travaglini@arm.com//
47113481Sgiacomo.travaglini@arm.com//   MakePolymorphicAction(foo);
47213481Sgiacomo.travaglini@arm.com// vs
47313481Sgiacomo.travaglini@arm.com//   PolymorphicAction<TypeOfFoo>(foo);
47413481Sgiacomo.travaglini@arm.comtemplate <typename Impl>
47513481Sgiacomo.travaglini@arm.cominline PolymorphicAction<Impl> MakePolymorphicAction(const Impl& impl) {
47613481Sgiacomo.travaglini@arm.com  return PolymorphicAction<Impl>(impl);
47713481Sgiacomo.travaglini@arm.com}
47813481Sgiacomo.travaglini@arm.com
47913481Sgiacomo.travaglini@arm.comnamespace internal {
48013481Sgiacomo.travaglini@arm.com
48113481Sgiacomo.travaglini@arm.com// Allows an Action<F2> object to pose as an Action<F1>, as long as F2
48213481Sgiacomo.travaglini@arm.com// and F1 are compatible.
48313481Sgiacomo.travaglini@arm.comtemplate <typename F1, typename F2>
48413481Sgiacomo.travaglini@arm.comclass ActionAdaptor : public ActionInterface<F1> {
48513481Sgiacomo.travaglini@arm.com public:
48613481Sgiacomo.travaglini@arm.com  typedef typename internal::Function<F1>::Result Result;
48713481Sgiacomo.travaglini@arm.com  typedef typename internal::Function<F1>::ArgumentTuple ArgumentTuple;
48813481Sgiacomo.travaglini@arm.com
48913481Sgiacomo.travaglini@arm.com  explicit ActionAdaptor(const Action<F2>& from) : impl_(from.impl_) {}
49013481Sgiacomo.travaglini@arm.com
49113481Sgiacomo.travaglini@arm.com  virtual Result Perform(const ArgumentTuple& args) {
49213481Sgiacomo.travaglini@arm.com    return impl_->Perform(args);
49313481Sgiacomo.travaglini@arm.com  }
49413481Sgiacomo.travaglini@arm.com
49513481Sgiacomo.travaglini@arm.com private:
49613481Sgiacomo.travaglini@arm.com  const internal::linked_ptr<ActionInterface<F2> > impl_;
49713481Sgiacomo.travaglini@arm.com
49813481Sgiacomo.travaglini@arm.com  GTEST_DISALLOW_ASSIGN_(ActionAdaptor);
49913481Sgiacomo.travaglini@arm.com};
50013481Sgiacomo.travaglini@arm.com
50113481Sgiacomo.travaglini@arm.com// Helper struct to specialize ReturnAction to execute a move instead of a copy
50213481Sgiacomo.travaglini@arm.com// on return. Useful for move-only types, but could be used on any type.
50313481Sgiacomo.travaglini@arm.comtemplate <typename T>
50413481Sgiacomo.travaglini@arm.comstruct ByMoveWrapper {
50513481Sgiacomo.travaglini@arm.com  explicit ByMoveWrapper(T value) : payload(internal::move(value)) {}
50613481Sgiacomo.travaglini@arm.com  T payload;
50713481Sgiacomo.travaglini@arm.com};
50813481Sgiacomo.travaglini@arm.com
50913481Sgiacomo.travaglini@arm.com// Implements the polymorphic Return(x) action, which can be used in
51013481Sgiacomo.travaglini@arm.com// any function that returns the type of x, regardless of the argument
51113481Sgiacomo.travaglini@arm.com// types.
51213481Sgiacomo.travaglini@arm.com//
51313481Sgiacomo.travaglini@arm.com// Note: The value passed into Return must be converted into
51413481Sgiacomo.travaglini@arm.com// Function<F>::Result when this action is cast to Action<F> rather than
51513481Sgiacomo.travaglini@arm.com// when that action is performed. This is important in scenarios like
51613481Sgiacomo.travaglini@arm.com//
51713481Sgiacomo.travaglini@arm.com// MOCK_METHOD1(Method, T(U));
51813481Sgiacomo.travaglini@arm.com// ...
51913481Sgiacomo.travaglini@arm.com// {
52013481Sgiacomo.travaglini@arm.com//   Foo foo;
52113481Sgiacomo.travaglini@arm.com//   X x(&foo);
52213481Sgiacomo.travaglini@arm.com//   EXPECT_CALL(mock, Method(_)).WillOnce(Return(x));
52313481Sgiacomo.travaglini@arm.com// }
52413481Sgiacomo.travaglini@arm.com//
52513481Sgiacomo.travaglini@arm.com// In the example above the variable x holds reference to foo which leaves
52613481Sgiacomo.travaglini@arm.com// scope and gets destroyed.  If copying X just copies a reference to foo,
52713481Sgiacomo.travaglini@arm.com// that copy will be left with a hanging reference.  If conversion to T
52813481Sgiacomo.travaglini@arm.com// makes a copy of foo, the above code is safe. To support that scenario, we
52913481Sgiacomo.travaglini@arm.com// need to make sure that the type conversion happens inside the EXPECT_CALL
53013481Sgiacomo.travaglini@arm.com// statement, and conversion of the result of Return to Action<T(U)> is a
53113481Sgiacomo.travaglini@arm.com// good place for that.
53213481Sgiacomo.travaglini@arm.com//
53313481Sgiacomo.travaglini@arm.comtemplate <typename R>
53413481Sgiacomo.travaglini@arm.comclass ReturnAction {
53513481Sgiacomo.travaglini@arm.com public:
53613481Sgiacomo.travaglini@arm.com  // Constructs a ReturnAction object from the value to be returned.
53713481Sgiacomo.travaglini@arm.com  // 'value' is passed by value instead of by const reference in order
53813481Sgiacomo.travaglini@arm.com  // to allow Return("string literal") to compile.
53913481Sgiacomo.travaglini@arm.com  explicit ReturnAction(R value) : value_(new R(internal::move(value))) {}
54013481Sgiacomo.travaglini@arm.com
54113481Sgiacomo.travaglini@arm.com  // This template type conversion operator allows Return(x) to be
54213481Sgiacomo.travaglini@arm.com  // used in ANY function that returns x's type.
54313481Sgiacomo.travaglini@arm.com  template <typename F>
54413481Sgiacomo.travaglini@arm.com  operator Action<F>() const {
54513481Sgiacomo.travaglini@arm.com    // Assert statement belongs here because this is the best place to verify
54613481Sgiacomo.travaglini@arm.com    // conditions on F. It produces the clearest error messages
54713481Sgiacomo.travaglini@arm.com    // in most compilers.
54813481Sgiacomo.travaglini@arm.com    // Impl really belongs in this scope as a local class but can't
54913481Sgiacomo.travaglini@arm.com    // because MSVC produces duplicate symbols in different translation units
55013481Sgiacomo.travaglini@arm.com    // in this case. Until MS fixes that bug we put Impl into the class scope
55113481Sgiacomo.travaglini@arm.com    // and put the typedef both here (for use in assert statement) and
55213481Sgiacomo.travaglini@arm.com    // in the Impl class. But both definitions must be the same.
55313481Sgiacomo.travaglini@arm.com    typedef typename Function<F>::Result Result;
55413481Sgiacomo.travaglini@arm.com    GTEST_COMPILE_ASSERT_(
55513481Sgiacomo.travaglini@arm.com        !is_reference<Result>::value,
55613481Sgiacomo.travaglini@arm.com        use_ReturnRef_instead_of_Return_to_return_a_reference);
55713481Sgiacomo.travaglini@arm.com    return Action<F>(new Impl<R, F>(value_));
55813481Sgiacomo.travaglini@arm.com  }
55913481Sgiacomo.travaglini@arm.com
56013481Sgiacomo.travaglini@arm.com private:
56113481Sgiacomo.travaglini@arm.com  // Implements the Return(x) action for a particular function type F.
56213481Sgiacomo.travaglini@arm.com  template <typename R_, typename F>
56313481Sgiacomo.travaglini@arm.com  class Impl : public ActionInterface<F> {
56413481Sgiacomo.travaglini@arm.com   public:
56513481Sgiacomo.travaglini@arm.com    typedef typename Function<F>::Result Result;
56613481Sgiacomo.travaglini@arm.com    typedef typename Function<F>::ArgumentTuple ArgumentTuple;
56713481Sgiacomo.travaglini@arm.com
56813481Sgiacomo.travaglini@arm.com    // The implicit cast is necessary when Result has more than one
56913481Sgiacomo.travaglini@arm.com    // single-argument constructor (e.g. Result is std::vector<int>) and R
57013481Sgiacomo.travaglini@arm.com    // has a type conversion operator template.  In that case, value_(value)
57113481Sgiacomo.travaglini@arm.com    // won't compile as the compiler doesn't known which constructor of
57213481Sgiacomo.travaglini@arm.com    // Result to call.  ImplicitCast_ forces the compiler to convert R to
57313481Sgiacomo.travaglini@arm.com    // Result without considering explicit constructors, thus resolving the
57413481Sgiacomo.travaglini@arm.com    // ambiguity. value_ is then initialized using its copy constructor.
57513481Sgiacomo.travaglini@arm.com    explicit Impl(const linked_ptr<R>& value)
57613481Sgiacomo.travaglini@arm.com        : value_before_cast_(*value),
57713481Sgiacomo.travaglini@arm.com          value_(ImplicitCast_<Result>(value_before_cast_)) {}
57813481Sgiacomo.travaglini@arm.com
57913481Sgiacomo.travaglini@arm.com    virtual Result Perform(const ArgumentTuple&) { return value_; }
58013481Sgiacomo.travaglini@arm.com
58113481Sgiacomo.travaglini@arm.com   private:
58213481Sgiacomo.travaglini@arm.com    GTEST_COMPILE_ASSERT_(!is_reference<Result>::value,
58313481Sgiacomo.travaglini@arm.com                          Result_cannot_be_a_reference_type);
58413481Sgiacomo.travaglini@arm.com    // We save the value before casting just in case it is being cast to a
58513481Sgiacomo.travaglini@arm.com    // wrapper type.
58613481Sgiacomo.travaglini@arm.com    R value_before_cast_;
58713481Sgiacomo.travaglini@arm.com    Result value_;
58813481Sgiacomo.travaglini@arm.com
58913481Sgiacomo.travaglini@arm.com    GTEST_DISALLOW_COPY_AND_ASSIGN_(Impl);
59013481Sgiacomo.travaglini@arm.com  };
59113481Sgiacomo.travaglini@arm.com
59213481Sgiacomo.travaglini@arm.com  // Partially specialize for ByMoveWrapper. This version of ReturnAction will
59313481Sgiacomo.travaglini@arm.com  // move its contents instead.
59413481Sgiacomo.travaglini@arm.com  template <typename R_, typename F>
59513481Sgiacomo.travaglini@arm.com  class Impl<ByMoveWrapper<R_>, F> : public ActionInterface<F> {
59613481Sgiacomo.travaglini@arm.com   public:
59713481Sgiacomo.travaglini@arm.com    typedef typename Function<F>::Result Result;
59813481Sgiacomo.travaglini@arm.com    typedef typename Function<F>::ArgumentTuple ArgumentTuple;
59913481Sgiacomo.travaglini@arm.com
60013481Sgiacomo.travaglini@arm.com    explicit Impl(const linked_ptr<R>& wrapper)
60113481Sgiacomo.travaglini@arm.com        : performed_(false), wrapper_(wrapper) {}
60213481Sgiacomo.travaglini@arm.com
60313481Sgiacomo.travaglini@arm.com    virtual Result Perform(const ArgumentTuple&) {
60413481Sgiacomo.travaglini@arm.com      GTEST_CHECK_(!performed_)
60513481Sgiacomo.travaglini@arm.com          << "A ByMove() action should only be performed once.";
60613481Sgiacomo.travaglini@arm.com      performed_ = true;
60713481Sgiacomo.travaglini@arm.com      return internal::move(wrapper_->payload);
60813481Sgiacomo.travaglini@arm.com    }
60913481Sgiacomo.travaglini@arm.com
61013481Sgiacomo.travaglini@arm.com   private:
61113481Sgiacomo.travaglini@arm.com    bool performed_;
61213481Sgiacomo.travaglini@arm.com    const linked_ptr<R> wrapper_;
61313481Sgiacomo.travaglini@arm.com
61413481Sgiacomo.travaglini@arm.com    GTEST_DISALLOW_ASSIGN_(Impl);
61513481Sgiacomo.travaglini@arm.com  };
61613481Sgiacomo.travaglini@arm.com
61713481Sgiacomo.travaglini@arm.com  const linked_ptr<R> value_;
61813481Sgiacomo.travaglini@arm.com
61913481Sgiacomo.travaglini@arm.com  GTEST_DISALLOW_ASSIGN_(ReturnAction);
62013481Sgiacomo.travaglini@arm.com};
62113481Sgiacomo.travaglini@arm.com
62213481Sgiacomo.travaglini@arm.com// Implements the ReturnNull() action.
62313481Sgiacomo.travaglini@arm.comclass ReturnNullAction {
62413481Sgiacomo.travaglini@arm.com public:
62513481Sgiacomo.travaglini@arm.com  // Allows ReturnNull() to be used in any pointer-returning function. In C++11
62613481Sgiacomo.travaglini@arm.com  // this is enforced by returning nullptr, and in non-C++11 by asserting a
62713481Sgiacomo.travaglini@arm.com  // pointer type on compile time.
62813481Sgiacomo.travaglini@arm.com  template <typename Result, typename ArgumentTuple>
62913481Sgiacomo.travaglini@arm.com  static Result Perform(const ArgumentTuple&) {
63013481Sgiacomo.travaglini@arm.com#if GTEST_LANG_CXX11
63113481Sgiacomo.travaglini@arm.com    return nullptr;
63213481Sgiacomo.travaglini@arm.com#else
63313481Sgiacomo.travaglini@arm.com    GTEST_COMPILE_ASSERT_(internal::is_pointer<Result>::value,
63413481Sgiacomo.travaglini@arm.com                          ReturnNull_can_be_used_to_return_a_pointer_only);
63513481Sgiacomo.travaglini@arm.com    return NULL;
63613481Sgiacomo.travaglini@arm.com#endif  // GTEST_LANG_CXX11
63713481Sgiacomo.travaglini@arm.com  }
63813481Sgiacomo.travaglini@arm.com};
63913481Sgiacomo.travaglini@arm.com
64013481Sgiacomo.travaglini@arm.com// Implements the Return() action.
64113481Sgiacomo.travaglini@arm.comclass ReturnVoidAction {
64213481Sgiacomo.travaglini@arm.com public:
64313481Sgiacomo.travaglini@arm.com  // Allows Return() to be used in any void-returning function.
64413481Sgiacomo.travaglini@arm.com  template <typename Result, typename ArgumentTuple>
64513481Sgiacomo.travaglini@arm.com  static void Perform(const ArgumentTuple&) {
64613481Sgiacomo.travaglini@arm.com    CompileAssertTypesEqual<void, Result>();
64713481Sgiacomo.travaglini@arm.com  }
64813481Sgiacomo.travaglini@arm.com};
64913481Sgiacomo.travaglini@arm.com
65013481Sgiacomo.travaglini@arm.com// Implements the polymorphic ReturnRef(x) action, which can be used
65113481Sgiacomo.travaglini@arm.com// in any function that returns a reference to the type of x,
65213481Sgiacomo.travaglini@arm.com// regardless of the argument types.
65313481Sgiacomo.travaglini@arm.comtemplate <typename T>
65413481Sgiacomo.travaglini@arm.comclass ReturnRefAction {
65513481Sgiacomo.travaglini@arm.com public:
65613481Sgiacomo.travaglini@arm.com  // Constructs a ReturnRefAction object from the reference to be returned.
65713481Sgiacomo.travaglini@arm.com  explicit ReturnRefAction(T& ref) : ref_(ref) {}  // NOLINT
65813481Sgiacomo.travaglini@arm.com
65913481Sgiacomo.travaglini@arm.com  // This template type conversion operator allows ReturnRef(x) to be
66013481Sgiacomo.travaglini@arm.com  // used in ANY function that returns a reference to x's type.
66113481Sgiacomo.travaglini@arm.com  template <typename F>
66213481Sgiacomo.travaglini@arm.com  operator Action<F>() const {
66313481Sgiacomo.travaglini@arm.com    typedef typename Function<F>::Result Result;
66413481Sgiacomo.travaglini@arm.com    // Asserts that the function return type is a reference.  This
66513481Sgiacomo.travaglini@arm.com    // catches the user error of using ReturnRef(x) when Return(x)
66613481Sgiacomo.travaglini@arm.com    // should be used, and generates some helpful error message.
66713481Sgiacomo.travaglini@arm.com    GTEST_COMPILE_ASSERT_(internal::is_reference<Result>::value,
66813481Sgiacomo.travaglini@arm.com                          use_Return_instead_of_ReturnRef_to_return_a_value);
66913481Sgiacomo.travaglini@arm.com    return Action<F>(new Impl<F>(ref_));
67013481Sgiacomo.travaglini@arm.com  }
67113481Sgiacomo.travaglini@arm.com
67213481Sgiacomo.travaglini@arm.com private:
67313481Sgiacomo.travaglini@arm.com  // Implements the ReturnRef(x) action for a particular function type F.
67413481Sgiacomo.travaglini@arm.com  template <typename F>
67513481Sgiacomo.travaglini@arm.com  class Impl : public ActionInterface<F> {
67613481Sgiacomo.travaglini@arm.com   public:
67713481Sgiacomo.travaglini@arm.com    typedef typename Function<F>::Result Result;
67813481Sgiacomo.travaglini@arm.com    typedef typename Function<F>::ArgumentTuple ArgumentTuple;
67913481Sgiacomo.travaglini@arm.com
68013481Sgiacomo.travaglini@arm.com    explicit Impl(T& ref) : ref_(ref) {}  // NOLINT
68113481Sgiacomo.travaglini@arm.com
68213481Sgiacomo.travaglini@arm.com    virtual Result Perform(const ArgumentTuple&) {
68313481Sgiacomo.travaglini@arm.com      return ref_;
68413481Sgiacomo.travaglini@arm.com    }
68513481Sgiacomo.travaglini@arm.com
68613481Sgiacomo.travaglini@arm.com   private:
68713481Sgiacomo.travaglini@arm.com    T& ref_;
68813481Sgiacomo.travaglini@arm.com
68913481Sgiacomo.travaglini@arm.com    GTEST_DISALLOW_ASSIGN_(Impl);
69013481Sgiacomo.travaglini@arm.com  };
69113481Sgiacomo.travaglini@arm.com
69213481Sgiacomo.travaglini@arm.com  T& ref_;
69313481Sgiacomo.travaglini@arm.com
69413481Sgiacomo.travaglini@arm.com  GTEST_DISALLOW_ASSIGN_(ReturnRefAction);
69513481Sgiacomo.travaglini@arm.com};
69613481Sgiacomo.travaglini@arm.com
69713481Sgiacomo.travaglini@arm.com// Implements the polymorphic ReturnRefOfCopy(x) action, which can be
69813481Sgiacomo.travaglini@arm.com// used in any function that returns a reference to the type of x,
69913481Sgiacomo.travaglini@arm.com// regardless of the argument types.
70013481Sgiacomo.travaglini@arm.comtemplate <typename T>
70113481Sgiacomo.travaglini@arm.comclass ReturnRefOfCopyAction {
70213481Sgiacomo.travaglini@arm.com public:
70313481Sgiacomo.travaglini@arm.com  // Constructs a ReturnRefOfCopyAction object from the reference to
70413481Sgiacomo.travaglini@arm.com  // be returned.
70513481Sgiacomo.travaglini@arm.com  explicit ReturnRefOfCopyAction(const T& value) : value_(value) {}  // NOLINT
70613481Sgiacomo.travaglini@arm.com
70713481Sgiacomo.travaglini@arm.com  // This template type conversion operator allows ReturnRefOfCopy(x) to be
70813481Sgiacomo.travaglini@arm.com  // used in ANY function that returns a reference to x's type.
70913481Sgiacomo.travaglini@arm.com  template <typename F>
71013481Sgiacomo.travaglini@arm.com  operator Action<F>() const {
71113481Sgiacomo.travaglini@arm.com    typedef typename Function<F>::Result Result;
71213481Sgiacomo.travaglini@arm.com    // Asserts that the function return type is a reference.  This
71313481Sgiacomo.travaglini@arm.com    // catches the user error of using ReturnRefOfCopy(x) when Return(x)
71413481Sgiacomo.travaglini@arm.com    // should be used, and generates some helpful error message.
71513481Sgiacomo.travaglini@arm.com    GTEST_COMPILE_ASSERT_(
71613481Sgiacomo.travaglini@arm.com        internal::is_reference<Result>::value,
71713481Sgiacomo.travaglini@arm.com        use_Return_instead_of_ReturnRefOfCopy_to_return_a_value);
71813481Sgiacomo.travaglini@arm.com    return Action<F>(new Impl<F>(value_));
71913481Sgiacomo.travaglini@arm.com  }
72013481Sgiacomo.travaglini@arm.com
72113481Sgiacomo.travaglini@arm.com private:
72213481Sgiacomo.travaglini@arm.com  // Implements the ReturnRefOfCopy(x) action for a particular function type F.
72313481Sgiacomo.travaglini@arm.com  template <typename F>
72413481Sgiacomo.travaglini@arm.com  class Impl : public ActionInterface<F> {
72513481Sgiacomo.travaglini@arm.com   public:
72613481Sgiacomo.travaglini@arm.com    typedef typename Function<F>::Result Result;
72713481Sgiacomo.travaglini@arm.com    typedef typename Function<F>::ArgumentTuple ArgumentTuple;
72813481Sgiacomo.travaglini@arm.com
72913481Sgiacomo.travaglini@arm.com    explicit Impl(const T& value) : value_(value) {}  // NOLINT
73013481Sgiacomo.travaglini@arm.com
73113481Sgiacomo.travaglini@arm.com    virtual Result Perform(const ArgumentTuple&) {
73213481Sgiacomo.travaglini@arm.com      return value_;
73313481Sgiacomo.travaglini@arm.com    }
73413481Sgiacomo.travaglini@arm.com
73513481Sgiacomo.travaglini@arm.com   private:
73613481Sgiacomo.travaglini@arm.com    T value_;
73713481Sgiacomo.travaglini@arm.com
73813481Sgiacomo.travaglini@arm.com    GTEST_DISALLOW_ASSIGN_(Impl);
73913481Sgiacomo.travaglini@arm.com  };
74013481Sgiacomo.travaglini@arm.com
74113481Sgiacomo.travaglini@arm.com  const T value_;
74213481Sgiacomo.travaglini@arm.com
74313481Sgiacomo.travaglini@arm.com  GTEST_DISALLOW_ASSIGN_(ReturnRefOfCopyAction);
74413481Sgiacomo.travaglini@arm.com};
74513481Sgiacomo.travaglini@arm.com
74613481Sgiacomo.travaglini@arm.com// Implements the polymorphic DoDefault() action.
74713481Sgiacomo.travaglini@arm.comclass DoDefaultAction {
74813481Sgiacomo.travaglini@arm.com public:
74913481Sgiacomo.travaglini@arm.com  // This template type conversion operator allows DoDefault() to be
75013481Sgiacomo.travaglini@arm.com  // used in any function.
75113481Sgiacomo.travaglini@arm.com  template <typename F>
75213481Sgiacomo.travaglini@arm.com  operator Action<F>() const { return Action<F>(NULL); }
75313481Sgiacomo.travaglini@arm.com};
75413481Sgiacomo.travaglini@arm.com
75513481Sgiacomo.travaglini@arm.com// Implements the Assign action to set a given pointer referent to a
75613481Sgiacomo.travaglini@arm.com// particular value.
75713481Sgiacomo.travaglini@arm.comtemplate <typename T1, typename T2>
75813481Sgiacomo.travaglini@arm.comclass AssignAction {
75913481Sgiacomo.travaglini@arm.com public:
76013481Sgiacomo.travaglini@arm.com  AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {}
76113481Sgiacomo.travaglini@arm.com
76213481Sgiacomo.travaglini@arm.com  template <typename Result, typename ArgumentTuple>
76313481Sgiacomo.travaglini@arm.com  void Perform(const ArgumentTuple& /* args */) const {
76413481Sgiacomo.travaglini@arm.com    *ptr_ = value_;
76513481Sgiacomo.travaglini@arm.com  }
76613481Sgiacomo.travaglini@arm.com
76713481Sgiacomo.travaglini@arm.com private:
76813481Sgiacomo.travaglini@arm.com  T1* const ptr_;
76913481Sgiacomo.travaglini@arm.com  const T2 value_;
77013481Sgiacomo.travaglini@arm.com
77113481Sgiacomo.travaglini@arm.com  GTEST_DISALLOW_ASSIGN_(AssignAction);
77213481Sgiacomo.travaglini@arm.com};
77313481Sgiacomo.travaglini@arm.com
77413481Sgiacomo.travaglini@arm.com#if !GTEST_OS_WINDOWS_MOBILE
77513481Sgiacomo.travaglini@arm.com
77613481Sgiacomo.travaglini@arm.com// Implements the SetErrnoAndReturn action to simulate return from
77713481Sgiacomo.travaglini@arm.com// various system calls and libc functions.
77813481Sgiacomo.travaglini@arm.comtemplate <typename T>
77913481Sgiacomo.travaglini@arm.comclass SetErrnoAndReturnAction {
78013481Sgiacomo.travaglini@arm.com public:
78113481Sgiacomo.travaglini@arm.com  SetErrnoAndReturnAction(int errno_value, T result)
78213481Sgiacomo.travaglini@arm.com      : errno_(errno_value),
78313481Sgiacomo.travaglini@arm.com        result_(result) {}
78413481Sgiacomo.travaglini@arm.com  template <typename Result, typename ArgumentTuple>
78513481Sgiacomo.travaglini@arm.com  Result Perform(const ArgumentTuple& /* args */) const {
78613481Sgiacomo.travaglini@arm.com    errno = errno_;
78713481Sgiacomo.travaglini@arm.com    return result_;
78813481Sgiacomo.travaglini@arm.com  }
78913481Sgiacomo.travaglini@arm.com
79013481Sgiacomo.travaglini@arm.com private:
79113481Sgiacomo.travaglini@arm.com  const int errno_;
79213481Sgiacomo.travaglini@arm.com  const T result_;
79313481Sgiacomo.travaglini@arm.com
79413481Sgiacomo.travaglini@arm.com  GTEST_DISALLOW_ASSIGN_(SetErrnoAndReturnAction);
79513481Sgiacomo.travaglini@arm.com};
79613481Sgiacomo.travaglini@arm.com
79713481Sgiacomo.travaglini@arm.com#endif  // !GTEST_OS_WINDOWS_MOBILE
79813481Sgiacomo.travaglini@arm.com
79913481Sgiacomo.travaglini@arm.com// Implements the SetArgumentPointee<N>(x) action for any function
80013481Sgiacomo.travaglini@arm.com// whose N-th argument (0-based) is a pointer to x's type.  The
80113481Sgiacomo.travaglini@arm.com// template parameter kIsProto is true iff type A is ProtocolMessage,
80213481Sgiacomo.travaglini@arm.com// proto2::Message, or a sub-class of those.
80313481Sgiacomo.travaglini@arm.comtemplate <size_t N, typename A, bool kIsProto>
80413481Sgiacomo.travaglini@arm.comclass SetArgumentPointeeAction {
80513481Sgiacomo.travaglini@arm.com public:
80613481Sgiacomo.travaglini@arm.com  // Constructs an action that sets the variable pointed to by the
80713481Sgiacomo.travaglini@arm.com  // N-th function argument to 'value'.
80813481Sgiacomo.travaglini@arm.com  explicit SetArgumentPointeeAction(const A& value) : value_(value) {}
80913481Sgiacomo.travaglini@arm.com
81013481Sgiacomo.travaglini@arm.com  template <typename Result, typename ArgumentTuple>
81113481Sgiacomo.travaglini@arm.com  void Perform(const ArgumentTuple& args) const {
81213481Sgiacomo.travaglini@arm.com    CompileAssertTypesEqual<void, Result>();
81313481Sgiacomo.travaglini@arm.com    *::testing::get<N>(args) = value_;
81413481Sgiacomo.travaglini@arm.com  }
81513481Sgiacomo.travaglini@arm.com
81613481Sgiacomo.travaglini@arm.com private:
81713481Sgiacomo.travaglini@arm.com  const A value_;
81813481Sgiacomo.travaglini@arm.com
81913481Sgiacomo.travaglini@arm.com  GTEST_DISALLOW_ASSIGN_(SetArgumentPointeeAction);
82013481Sgiacomo.travaglini@arm.com};
82113481Sgiacomo.travaglini@arm.com
82213481Sgiacomo.travaglini@arm.comtemplate <size_t N, typename Proto>
82313481Sgiacomo.travaglini@arm.comclass SetArgumentPointeeAction<N, Proto, true> {
82413481Sgiacomo.travaglini@arm.com public:
82513481Sgiacomo.travaglini@arm.com  // Constructs an action that sets the variable pointed to by the
82613481Sgiacomo.travaglini@arm.com  // N-th function argument to 'proto'.  Both ProtocolMessage and
82713481Sgiacomo.travaglini@arm.com  // proto2::Message have the CopyFrom() method, so the same
82813481Sgiacomo.travaglini@arm.com  // implementation works for both.
82913481Sgiacomo.travaglini@arm.com  explicit SetArgumentPointeeAction(const Proto& proto) : proto_(new Proto) {
83013481Sgiacomo.travaglini@arm.com    proto_->CopyFrom(proto);
83113481Sgiacomo.travaglini@arm.com  }
83213481Sgiacomo.travaglini@arm.com
83313481Sgiacomo.travaglini@arm.com  template <typename Result, typename ArgumentTuple>
83413481Sgiacomo.travaglini@arm.com  void Perform(const ArgumentTuple& args) const {
83513481Sgiacomo.travaglini@arm.com    CompileAssertTypesEqual<void, Result>();
83613481Sgiacomo.travaglini@arm.com    ::testing::get<N>(args)->CopyFrom(*proto_);
83713481Sgiacomo.travaglini@arm.com  }
83813481Sgiacomo.travaglini@arm.com
83913481Sgiacomo.travaglini@arm.com private:
84013481Sgiacomo.travaglini@arm.com  const internal::linked_ptr<Proto> proto_;
84113481Sgiacomo.travaglini@arm.com
84213481Sgiacomo.travaglini@arm.com  GTEST_DISALLOW_ASSIGN_(SetArgumentPointeeAction);
84313481Sgiacomo.travaglini@arm.com};
84413481Sgiacomo.travaglini@arm.com
84513481Sgiacomo.travaglini@arm.com// Implements the InvokeWithoutArgs(f) action.  The template argument
84613481Sgiacomo.travaglini@arm.com// FunctionImpl is the implementation type of f, which can be either a
84713481Sgiacomo.travaglini@arm.com// function pointer or a functor.  InvokeWithoutArgs(f) can be used as an
84813481Sgiacomo.travaglini@arm.com// Action<F> as long as f's type is compatible with F (i.e. f can be
84913481Sgiacomo.travaglini@arm.com// assigned to a tr1::function<F>).
85013481Sgiacomo.travaglini@arm.comtemplate <typename FunctionImpl>
85113481Sgiacomo.travaglini@arm.comclass InvokeWithoutArgsAction {
85213481Sgiacomo.travaglini@arm.com public:
85313481Sgiacomo.travaglini@arm.com  // The c'tor makes a copy of function_impl (either a function
85413481Sgiacomo.travaglini@arm.com  // pointer or a functor).
85513481Sgiacomo.travaglini@arm.com  explicit InvokeWithoutArgsAction(FunctionImpl function_impl)
85613481Sgiacomo.travaglini@arm.com      : function_impl_(function_impl) {}
85713481Sgiacomo.travaglini@arm.com
85813481Sgiacomo.travaglini@arm.com  // Allows InvokeWithoutArgs(f) to be used as any action whose type is
85913481Sgiacomo.travaglini@arm.com  // compatible with f.
86013481Sgiacomo.travaglini@arm.com  template <typename Result, typename ArgumentTuple>
86113481Sgiacomo.travaglini@arm.com  Result Perform(const ArgumentTuple&) { return function_impl_(); }
86213481Sgiacomo.travaglini@arm.com
86313481Sgiacomo.travaglini@arm.com private:
86413481Sgiacomo.travaglini@arm.com  FunctionImpl function_impl_;
86513481Sgiacomo.travaglini@arm.com
86613481Sgiacomo.travaglini@arm.com  GTEST_DISALLOW_ASSIGN_(InvokeWithoutArgsAction);
86713481Sgiacomo.travaglini@arm.com};
86813481Sgiacomo.travaglini@arm.com
86913481Sgiacomo.travaglini@arm.com// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action.
87013481Sgiacomo.travaglini@arm.comtemplate <class Class, typename MethodPtr>
87113481Sgiacomo.travaglini@arm.comclass InvokeMethodWithoutArgsAction {
87213481Sgiacomo.travaglini@arm.com public:
87313481Sgiacomo.travaglini@arm.com  InvokeMethodWithoutArgsAction(Class* obj_ptr, MethodPtr method_ptr)
87413481Sgiacomo.travaglini@arm.com      : obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
87513481Sgiacomo.travaglini@arm.com
87613481Sgiacomo.travaglini@arm.com  template <typename Result, typename ArgumentTuple>
87713481Sgiacomo.travaglini@arm.com  Result Perform(const ArgumentTuple&) const {
87813481Sgiacomo.travaglini@arm.com    return (obj_ptr_->*method_ptr_)();
87913481Sgiacomo.travaglini@arm.com  }
88013481Sgiacomo.travaglini@arm.com
88113481Sgiacomo.travaglini@arm.com private:
88213481Sgiacomo.travaglini@arm.com  Class* const obj_ptr_;
88313481Sgiacomo.travaglini@arm.com  const MethodPtr method_ptr_;
88413481Sgiacomo.travaglini@arm.com
88513481Sgiacomo.travaglini@arm.com  GTEST_DISALLOW_ASSIGN_(InvokeMethodWithoutArgsAction);
88613481Sgiacomo.travaglini@arm.com};
88713481Sgiacomo.travaglini@arm.com
88813481Sgiacomo.travaglini@arm.com// Implements the IgnoreResult(action) action.
88913481Sgiacomo.travaglini@arm.comtemplate <typename A>
89013481Sgiacomo.travaglini@arm.comclass IgnoreResultAction {
89113481Sgiacomo.travaglini@arm.com public:
89213481Sgiacomo.travaglini@arm.com  explicit IgnoreResultAction(const A& action) : action_(action) {}
89313481Sgiacomo.travaglini@arm.com
89413481Sgiacomo.travaglini@arm.com  template <typename F>
89513481Sgiacomo.travaglini@arm.com  operator Action<F>() const {
89613481Sgiacomo.travaglini@arm.com    // Assert statement belongs here because this is the best place to verify
89713481Sgiacomo.travaglini@arm.com    // conditions on F. It produces the clearest error messages
89813481Sgiacomo.travaglini@arm.com    // in most compilers.
89913481Sgiacomo.travaglini@arm.com    // Impl really belongs in this scope as a local class but can't
90013481Sgiacomo.travaglini@arm.com    // because MSVC produces duplicate symbols in different translation units
90113481Sgiacomo.travaglini@arm.com    // in this case. Until MS fixes that bug we put Impl into the class scope
90213481Sgiacomo.travaglini@arm.com    // and put the typedef both here (for use in assert statement) and
90313481Sgiacomo.travaglini@arm.com    // in the Impl class. But both definitions must be the same.
90413481Sgiacomo.travaglini@arm.com    typedef typename internal::Function<F>::Result Result;
90513481Sgiacomo.travaglini@arm.com
90613481Sgiacomo.travaglini@arm.com    // Asserts at compile time that F returns void.
90713481Sgiacomo.travaglini@arm.com    CompileAssertTypesEqual<void, Result>();
90813481Sgiacomo.travaglini@arm.com
90913481Sgiacomo.travaglini@arm.com    return Action<F>(new Impl<F>(action_));
91013481Sgiacomo.travaglini@arm.com  }
91113481Sgiacomo.travaglini@arm.com
91213481Sgiacomo.travaglini@arm.com private:
91313481Sgiacomo.travaglini@arm.com  template <typename F>
91413481Sgiacomo.travaglini@arm.com  class Impl : public ActionInterface<F> {
91513481Sgiacomo.travaglini@arm.com   public:
91613481Sgiacomo.travaglini@arm.com    typedef typename internal::Function<F>::Result Result;
91713481Sgiacomo.travaglini@arm.com    typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
91813481Sgiacomo.travaglini@arm.com
91913481Sgiacomo.travaglini@arm.com    explicit Impl(const A& action) : action_(action) {}
92013481Sgiacomo.travaglini@arm.com
92113481Sgiacomo.travaglini@arm.com    virtual void Perform(const ArgumentTuple& args) {
92213481Sgiacomo.travaglini@arm.com      // Performs the action and ignores its result.
92313481Sgiacomo.travaglini@arm.com      action_.Perform(args);
92413481Sgiacomo.travaglini@arm.com    }
92513481Sgiacomo.travaglini@arm.com
92613481Sgiacomo.travaglini@arm.com   private:
92713481Sgiacomo.travaglini@arm.com    // Type OriginalFunction is the same as F except that its return
92813481Sgiacomo.travaglini@arm.com    // type is IgnoredValue.
92913481Sgiacomo.travaglini@arm.com    typedef typename internal::Function<F>::MakeResultIgnoredValue
93013481Sgiacomo.travaglini@arm.com        OriginalFunction;
93113481Sgiacomo.travaglini@arm.com
93213481Sgiacomo.travaglini@arm.com    const Action<OriginalFunction> action_;
93313481Sgiacomo.travaglini@arm.com
93413481Sgiacomo.travaglini@arm.com    GTEST_DISALLOW_ASSIGN_(Impl);
93513481Sgiacomo.travaglini@arm.com  };
93613481Sgiacomo.travaglini@arm.com
93713481Sgiacomo.travaglini@arm.com  const A action_;
93813481Sgiacomo.travaglini@arm.com
93913481Sgiacomo.travaglini@arm.com  GTEST_DISALLOW_ASSIGN_(IgnoreResultAction);
94013481Sgiacomo.travaglini@arm.com};
94113481Sgiacomo.travaglini@arm.com
94213481Sgiacomo.travaglini@arm.com// A ReferenceWrapper<T> object represents a reference to type T,
94313481Sgiacomo.travaglini@arm.com// which can be either const or not.  It can be explicitly converted
94413481Sgiacomo.travaglini@arm.com// from, and implicitly converted to, a T&.  Unlike a reference,
94513481Sgiacomo.travaglini@arm.com// ReferenceWrapper<T> can be copied and can survive template type
94613481Sgiacomo.travaglini@arm.com// inference.  This is used to support by-reference arguments in the
94713481Sgiacomo.travaglini@arm.com// InvokeArgument<N>(...) action.  The idea was from "reference
94813481Sgiacomo.travaglini@arm.com// wrappers" in tr1, which we don't have in our source tree yet.
94913481Sgiacomo.travaglini@arm.comtemplate <typename T>
95013481Sgiacomo.travaglini@arm.comclass ReferenceWrapper {
95113481Sgiacomo.travaglini@arm.com public:
95213481Sgiacomo.travaglini@arm.com  // Constructs a ReferenceWrapper<T> object from a T&.
95313481Sgiacomo.travaglini@arm.com  explicit ReferenceWrapper(T& l_value) : pointer_(&l_value) {}  // NOLINT
95413481Sgiacomo.travaglini@arm.com
95513481Sgiacomo.travaglini@arm.com  // Allows a ReferenceWrapper<T> object to be implicitly converted to
95613481Sgiacomo.travaglini@arm.com  // a T&.
95713481Sgiacomo.travaglini@arm.com  operator T&() const { return *pointer_; }
95813481Sgiacomo.travaglini@arm.com private:
95913481Sgiacomo.travaglini@arm.com  T* pointer_;
96013481Sgiacomo.travaglini@arm.com};
96113481Sgiacomo.travaglini@arm.com
96213481Sgiacomo.travaglini@arm.com// Allows the expression ByRef(x) to be printed as a reference to x.
96313481Sgiacomo.travaglini@arm.comtemplate <typename T>
96413481Sgiacomo.travaglini@arm.comvoid PrintTo(const ReferenceWrapper<T>& ref, ::std::ostream* os) {
96513481Sgiacomo.travaglini@arm.com  T& value = ref;
96613481Sgiacomo.travaglini@arm.com  UniversalPrinter<T&>::Print(value, os);
96713481Sgiacomo.travaglini@arm.com}
96813481Sgiacomo.travaglini@arm.com
96913481Sgiacomo.travaglini@arm.com// Does two actions sequentially.  Used for implementing the DoAll(a1,
97013481Sgiacomo.travaglini@arm.com// a2, ...) action.
97113481Sgiacomo.travaglini@arm.comtemplate <typename Action1, typename Action2>
97213481Sgiacomo.travaglini@arm.comclass DoBothAction {
97313481Sgiacomo.travaglini@arm.com public:
97413481Sgiacomo.travaglini@arm.com  DoBothAction(Action1 action1, Action2 action2)
97513481Sgiacomo.travaglini@arm.com      : action1_(action1), action2_(action2) {}
97613481Sgiacomo.travaglini@arm.com
97713481Sgiacomo.travaglini@arm.com  // This template type conversion operator allows DoAll(a1, ..., a_n)
97813481Sgiacomo.travaglini@arm.com  // to be used in ANY function of compatible type.
97913481Sgiacomo.travaglini@arm.com  template <typename F>
98013481Sgiacomo.travaglini@arm.com  operator Action<F>() const {
98113481Sgiacomo.travaglini@arm.com    return Action<F>(new Impl<F>(action1_, action2_));
98213481Sgiacomo.travaglini@arm.com  }
98313481Sgiacomo.travaglini@arm.com
98413481Sgiacomo.travaglini@arm.com private:
98513481Sgiacomo.travaglini@arm.com  // Implements the DoAll(...) action for a particular function type F.
98613481Sgiacomo.travaglini@arm.com  template <typename F>
98713481Sgiacomo.travaglini@arm.com  class Impl : public ActionInterface<F> {
98813481Sgiacomo.travaglini@arm.com   public:
98913481Sgiacomo.travaglini@arm.com    typedef typename Function<F>::Result Result;
99013481Sgiacomo.travaglini@arm.com    typedef typename Function<F>::ArgumentTuple ArgumentTuple;
99113481Sgiacomo.travaglini@arm.com    typedef typename Function<F>::MakeResultVoid VoidResult;
99213481Sgiacomo.travaglini@arm.com
99313481Sgiacomo.travaglini@arm.com    Impl(const Action<VoidResult>& action1, const Action<F>& action2)
99413481Sgiacomo.travaglini@arm.com        : action1_(action1), action2_(action2) {}
99513481Sgiacomo.travaglini@arm.com
99613481Sgiacomo.travaglini@arm.com    virtual Result Perform(const ArgumentTuple& args) {
99713481Sgiacomo.travaglini@arm.com      action1_.Perform(args);
99813481Sgiacomo.travaglini@arm.com      return action2_.Perform(args);
99913481Sgiacomo.travaglini@arm.com    }
100013481Sgiacomo.travaglini@arm.com
100113481Sgiacomo.travaglini@arm.com   private:
100213481Sgiacomo.travaglini@arm.com    const Action<VoidResult> action1_;
100313481Sgiacomo.travaglini@arm.com    const Action<F> action2_;
100413481Sgiacomo.travaglini@arm.com
100513481Sgiacomo.travaglini@arm.com    GTEST_DISALLOW_ASSIGN_(Impl);
100613481Sgiacomo.travaglini@arm.com  };
100713481Sgiacomo.travaglini@arm.com
100813481Sgiacomo.travaglini@arm.com  Action1 action1_;
100913481Sgiacomo.travaglini@arm.com  Action2 action2_;
101013481Sgiacomo.travaglini@arm.com
101113481Sgiacomo.travaglini@arm.com  GTEST_DISALLOW_ASSIGN_(DoBothAction);
101213481Sgiacomo.travaglini@arm.com};
101313481Sgiacomo.travaglini@arm.com
101413481Sgiacomo.travaglini@arm.com}  // namespace internal
101513481Sgiacomo.travaglini@arm.com
101613481Sgiacomo.travaglini@arm.com// An Unused object can be implicitly constructed from ANY value.
101713481Sgiacomo.travaglini@arm.com// This is handy when defining actions that ignore some or all of the
101813481Sgiacomo.travaglini@arm.com// mock function arguments.  For example, given
101913481Sgiacomo.travaglini@arm.com//
102013481Sgiacomo.travaglini@arm.com//   MOCK_METHOD3(Foo, double(const string& label, double x, double y));
102113481Sgiacomo.travaglini@arm.com//   MOCK_METHOD3(Bar, double(int index, double x, double y));
102213481Sgiacomo.travaglini@arm.com//
102313481Sgiacomo.travaglini@arm.com// instead of
102413481Sgiacomo.travaglini@arm.com//
102513481Sgiacomo.travaglini@arm.com//   double DistanceToOriginWithLabel(const string& label, double x, double y) {
102613481Sgiacomo.travaglini@arm.com//     return sqrt(x*x + y*y);
102713481Sgiacomo.travaglini@arm.com//   }
102813481Sgiacomo.travaglini@arm.com//   double DistanceToOriginWithIndex(int index, double x, double y) {
102913481Sgiacomo.travaglini@arm.com//     return sqrt(x*x + y*y);
103013481Sgiacomo.travaglini@arm.com//   }
103113481Sgiacomo.travaglini@arm.com//   ...
103213481Sgiacomo.travaglini@arm.com//   EXEPCT_CALL(mock, Foo("abc", _, _))
103313481Sgiacomo.travaglini@arm.com//       .WillOnce(Invoke(DistanceToOriginWithLabel));
103413481Sgiacomo.travaglini@arm.com//   EXEPCT_CALL(mock, Bar(5, _, _))
103513481Sgiacomo.travaglini@arm.com//       .WillOnce(Invoke(DistanceToOriginWithIndex));
103613481Sgiacomo.travaglini@arm.com//
103713481Sgiacomo.travaglini@arm.com// you could write
103813481Sgiacomo.travaglini@arm.com//
103913481Sgiacomo.travaglini@arm.com//   // We can declare any uninteresting argument as Unused.
104013481Sgiacomo.travaglini@arm.com//   double DistanceToOrigin(Unused, double x, double y) {
104113481Sgiacomo.travaglini@arm.com//     return sqrt(x*x + y*y);
104213481Sgiacomo.travaglini@arm.com//   }
104313481Sgiacomo.travaglini@arm.com//   ...
104413481Sgiacomo.travaglini@arm.com//   EXEPCT_CALL(mock, Foo("abc", _, _)).WillOnce(Invoke(DistanceToOrigin));
104513481Sgiacomo.travaglini@arm.com//   EXEPCT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
104613481Sgiacomo.travaglini@arm.comtypedef internal::IgnoredValue Unused;
104713481Sgiacomo.travaglini@arm.com
104813481Sgiacomo.travaglini@arm.com// This constructor allows us to turn an Action<From> object into an
104913481Sgiacomo.travaglini@arm.com// Action<To>, as long as To's arguments can be implicitly converted
105013481Sgiacomo.travaglini@arm.com// to From's and From's return type cann be implicitly converted to
105113481Sgiacomo.travaglini@arm.com// To's.
105213481Sgiacomo.travaglini@arm.comtemplate <typename To>
105313481Sgiacomo.travaglini@arm.comtemplate <typename From>
105413481Sgiacomo.travaglini@arm.comAction<To>::Action(const Action<From>& from)
105513481Sgiacomo.travaglini@arm.com    : impl_(new internal::ActionAdaptor<To, From>(from)) {}
105613481Sgiacomo.travaglini@arm.com
105713481Sgiacomo.travaglini@arm.com// Creates an action that returns 'value'.  'value' is passed by value
105813481Sgiacomo.travaglini@arm.com// instead of const reference - otherwise Return("string literal")
105913481Sgiacomo.travaglini@arm.com// will trigger a compiler error about using array as initializer.
106013481Sgiacomo.travaglini@arm.comtemplate <typename R>
106113481Sgiacomo.travaglini@arm.cominternal::ReturnAction<R> Return(R value) {
106213481Sgiacomo.travaglini@arm.com  return internal::ReturnAction<R>(internal::move(value));
106313481Sgiacomo.travaglini@arm.com}
106413481Sgiacomo.travaglini@arm.com
106513481Sgiacomo.travaglini@arm.com// Creates an action that returns NULL.
106613481Sgiacomo.travaglini@arm.cominline PolymorphicAction<internal::ReturnNullAction> ReturnNull() {
106713481Sgiacomo.travaglini@arm.com  return MakePolymorphicAction(internal::ReturnNullAction());
106813481Sgiacomo.travaglini@arm.com}
106913481Sgiacomo.travaglini@arm.com
107013481Sgiacomo.travaglini@arm.com// Creates an action that returns from a void function.
107113481Sgiacomo.travaglini@arm.cominline PolymorphicAction<internal::ReturnVoidAction> Return() {
107213481Sgiacomo.travaglini@arm.com  return MakePolymorphicAction(internal::ReturnVoidAction());
107313481Sgiacomo.travaglini@arm.com}
107413481Sgiacomo.travaglini@arm.com
107513481Sgiacomo.travaglini@arm.com// Creates an action that returns the reference to a variable.
107613481Sgiacomo.travaglini@arm.comtemplate <typename R>
107713481Sgiacomo.travaglini@arm.cominline internal::ReturnRefAction<R> ReturnRef(R& x) {  // NOLINT
107813481Sgiacomo.travaglini@arm.com  return internal::ReturnRefAction<R>(x);
107913481Sgiacomo.travaglini@arm.com}
108013481Sgiacomo.travaglini@arm.com
108113481Sgiacomo.travaglini@arm.com// Creates an action that returns the reference to a copy of the
108213481Sgiacomo.travaglini@arm.com// argument.  The copy is created when the action is constructed and
108313481Sgiacomo.travaglini@arm.com// lives as long as the action.
108413481Sgiacomo.travaglini@arm.comtemplate <typename R>
108513481Sgiacomo.travaglini@arm.cominline internal::ReturnRefOfCopyAction<R> ReturnRefOfCopy(const R& x) {
108613481Sgiacomo.travaglini@arm.com  return internal::ReturnRefOfCopyAction<R>(x);
108713481Sgiacomo.travaglini@arm.com}
108813481Sgiacomo.travaglini@arm.com
108913481Sgiacomo.travaglini@arm.com// Modifies the parent action (a Return() action) to perform a move of the
109013481Sgiacomo.travaglini@arm.com// argument instead of a copy.
109113481Sgiacomo.travaglini@arm.com// Return(ByMove()) actions can only be executed once and will assert this
109213481Sgiacomo.travaglini@arm.com// invariant.
109313481Sgiacomo.travaglini@arm.comtemplate <typename R>
109413481Sgiacomo.travaglini@arm.cominternal::ByMoveWrapper<R> ByMove(R x) {
109513481Sgiacomo.travaglini@arm.com  return internal::ByMoveWrapper<R>(internal::move(x));
109613481Sgiacomo.travaglini@arm.com}
109713481Sgiacomo.travaglini@arm.com
109813481Sgiacomo.travaglini@arm.com// Creates an action that does the default action for the give mock function.
109913481Sgiacomo.travaglini@arm.cominline internal::DoDefaultAction DoDefault() {
110013481Sgiacomo.travaglini@arm.com  return internal::DoDefaultAction();
110113481Sgiacomo.travaglini@arm.com}
110213481Sgiacomo.travaglini@arm.com
110313481Sgiacomo.travaglini@arm.com// Creates an action that sets the variable pointed by the N-th
110413481Sgiacomo.travaglini@arm.com// (0-based) function argument to 'value'.
110513481Sgiacomo.travaglini@arm.comtemplate <size_t N, typename T>
110613481Sgiacomo.travaglini@arm.comPolymorphicAction<
110713481Sgiacomo.travaglini@arm.com  internal::SetArgumentPointeeAction<
110813481Sgiacomo.travaglini@arm.com    N, T, internal::IsAProtocolMessage<T>::value> >
110913481Sgiacomo.travaglini@arm.comSetArgPointee(const T& x) {
111013481Sgiacomo.travaglini@arm.com  return MakePolymorphicAction(internal::SetArgumentPointeeAction<
111113481Sgiacomo.travaglini@arm.com      N, T, internal::IsAProtocolMessage<T>::value>(x));
111213481Sgiacomo.travaglini@arm.com}
111313481Sgiacomo.travaglini@arm.com
111413481Sgiacomo.travaglini@arm.com#if !((GTEST_GCC_VER_ && GTEST_GCC_VER_ < 40000) || GTEST_OS_SYMBIAN)
111513481Sgiacomo.travaglini@arm.com// This overload allows SetArgPointee() to accept a string literal.
111613481Sgiacomo.travaglini@arm.com// GCC prior to the version 4.0 and Symbian C++ compiler cannot distinguish
111713481Sgiacomo.travaglini@arm.com// this overload from the templated version and emit a compile error.
111813481Sgiacomo.travaglini@arm.comtemplate <size_t N>
111913481Sgiacomo.travaglini@arm.comPolymorphicAction<
112013481Sgiacomo.travaglini@arm.com  internal::SetArgumentPointeeAction<N, const char*, false> >
112113481Sgiacomo.travaglini@arm.comSetArgPointee(const char* p) {
112213481Sgiacomo.travaglini@arm.com  return MakePolymorphicAction(internal::SetArgumentPointeeAction<
112313481Sgiacomo.travaglini@arm.com      N, const char*, false>(p));
112413481Sgiacomo.travaglini@arm.com}
112513481Sgiacomo.travaglini@arm.com
112613481Sgiacomo.travaglini@arm.comtemplate <size_t N>
112713481Sgiacomo.travaglini@arm.comPolymorphicAction<
112813481Sgiacomo.travaglini@arm.com  internal::SetArgumentPointeeAction<N, const wchar_t*, false> >
112913481Sgiacomo.travaglini@arm.comSetArgPointee(const wchar_t* p) {
113013481Sgiacomo.travaglini@arm.com  return MakePolymorphicAction(internal::SetArgumentPointeeAction<
113113481Sgiacomo.travaglini@arm.com      N, const wchar_t*, false>(p));
113213481Sgiacomo.travaglini@arm.com}
113313481Sgiacomo.travaglini@arm.com#endif
113413481Sgiacomo.travaglini@arm.com
113513481Sgiacomo.travaglini@arm.com// The following version is DEPRECATED.
113613481Sgiacomo.travaglini@arm.comtemplate <size_t N, typename T>
113713481Sgiacomo.travaglini@arm.comPolymorphicAction<
113813481Sgiacomo.travaglini@arm.com  internal::SetArgumentPointeeAction<
113913481Sgiacomo.travaglini@arm.com    N, T, internal::IsAProtocolMessage<T>::value> >
114013481Sgiacomo.travaglini@arm.comSetArgumentPointee(const T& x) {
114113481Sgiacomo.travaglini@arm.com  return MakePolymorphicAction(internal::SetArgumentPointeeAction<
114213481Sgiacomo.travaglini@arm.com      N, T, internal::IsAProtocolMessage<T>::value>(x));
114313481Sgiacomo.travaglini@arm.com}
114413481Sgiacomo.travaglini@arm.com
114513481Sgiacomo.travaglini@arm.com// Creates an action that sets a pointer referent to a given value.
114613481Sgiacomo.travaglini@arm.comtemplate <typename T1, typename T2>
114713481Sgiacomo.travaglini@arm.comPolymorphicAction<internal::AssignAction<T1, T2> > Assign(T1* ptr, T2 val) {
114813481Sgiacomo.travaglini@arm.com  return MakePolymorphicAction(internal::AssignAction<T1, T2>(ptr, val));
114913481Sgiacomo.travaglini@arm.com}
115013481Sgiacomo.travaglini@arm.com
115113481Sgiacomo.travaglini@arm.com#if !GTEST_OS_WINDOWS_MOBILE
115213481Sgiacomo.travaglini@arm.com
115313481Sgiacomo.travaglini@arm.com// Creates an action that sets errno and returns the appropriate error.
115413481Sgiacomo.travaglini@arm.comtemplate <typename T>
115513481Sgiacomo.travaglini@arm.comPolymorphicAction<internal::SetErrnoAndReturnAction<T> >
115613481Sgiacomo.travaglini@arm.comSetErrnoAndReturn(int errval, T result) {
115713481Sgiacomo.travaglini@arm.com  return MakePolymorphicAction(
115813481Sgiacomo.travaglini@arm.com      internal::SetErrnoAndReturnAction<T>(errval, result));
115913481Sgiacomo.travaglini@arm.com}
116013481Sgiacomo.travaglini@arm.com
116113481Sgiacomo.travaglini@arm.com#endif  // !GTEST_OS_WINDOWS_MOBILE
116213481Sgiacomo.travaglini@arm.com
116313481Sgiacomo.travaglini@arm.com// Various overloads for InvokeWithoutArgs().
116413481Sgiacomo.travaglini@arm.com
116513481Sgiacomo.travaglini@arm.com// Creates an action that invokes 'function_impl' with no argument.
116613481Sgiacomo.travaglini@arm.comtemplate <typename FunctionImpl>
116713481Sgiacomo.travaglini@arm.comPolymorphicAction<internal::InvokeWithoutArgsAction<FunctionImpl> >
116813481Sgiacomo.travaglini@arm.comInvokeWithoutArgs(FunctionImpl function_impl) {
116913481Sgiacomo.travaglini@arm.com  return MakePolymorphicAction(
117013481Sgiacomo.travaglini@arm.com      internal::InvokeWithoutArgsAction<FunctionImpl>(function_impl));
117113481Sgiacomo.travaglini@arm.com}
117213481Sgiacomo.travaglini@arm.com
117313481Sgiacomo.travaglini@arm.com// Creates an action that invokes the given method on the given object
117413481Sgiacomo.travaglini@arm.com// with no argument.
117513481Sgiacomo.travaglini@arm.comtemplate <class Class, typename MethodPtr>
117613481Sgiacomo.travaglini@arm.comPolymorphicAction<internal::InvokeMethodWithoutArgsAction<Class, MethodPtr> >
117713481Sgiacomo.travaglini@arm.comInvokeWithoutArgs(Class* obj_ptr, MethodPtr method_ptr) {
117813481Sgiacomo.travaglini@arm.com  return MakePolymorphicAction(
117913481Sgiacomo.travaglini@arm.com      internal::InvokeMethodWithoutArgsAction<Class, MethodPtr>(
118013481Sgiacomo.travaglini@arm.com          obj_ptr, method_ptr));
118113481Sgiacomo.travaglini@arm.com}
118213481Sgiacomo.travaglini@arm.com
118313481Sgiacomo.travaglini@arm.com// Creates an action that performs an_action and throws away its
118413481Sgiacomo.travaglini@arm.com// result.  In other words, it changes the return type of an_action to
118513481Sgiacomo.travaglini@arm.com// void.  an_action MUST NOT return void, or the code won't compile.
118613481Sgiacomo.travaglini@arm.comtemplate <typename A>
118713481Sgiacomo.travaglini@arm.cominline internal::IgnoreResultAction<A> IgnoreResult(const A& an_action) {
118813481Sgiacomo.travaglini@arm.com  return internal::IgnoreResultAction<A>(an_action);
118913481Sgiacomo.travaglini@arm.com}
119013481Sgiacomo.travaglini@arm.com
119113481Sgiacomo.travaglini@arm.com// Creates a reference wrapper for the given L-value.  If necessary,
119213481Sgiacomo.travaglini@arm.com// you can explicitly specify the type of the reference.  For example,
119313481Sgiacomo.travaglini@arm.com// suppose 'derived' is an object of type Derived, ByRef(derived)
119413481Sgiacomo.travaglini@arm.com// would wrap a Derived&.  If you want to wrap a const Base& instead,
119513481Sgiacomo.travaglini@arm.com// where Base is a base class of Derived, just write:
119613481Sgiacomo.travaglini@arm.com//
119713481Sgiacomo.travaglini@arm.com//   ByRef<const Base>(derived)
119813481Sgiacomo.travaglini@arm.comtemplate <typename T>
119913481Sgiacomo.travaglini@arm.cominline internal::ReferenceWrapper<T> ByRef(T& l_value) {  // NOLINT
120013481Sgiacomo.travaglini@arm.com  return internal::ReferenceWrapper<T>(l_value);
120113481Sgiacomo.travaglini@arm.com}
120213481Sgiacomo.travaglini@arm.com
120313481Sgiacomo.travaglini@arm.com}  // namespace testing
120413481Sgiacomo.travaglini@arm.com
120513481Sgiacomo.travaglini@arm.com#endif  // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
1206