"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "googlemock/include/gmock/gmock-matchers.h" between
googletest-release-1.10.0.tar.gz and googletest-release-1.11.0.tar.gz

About: GoogleTest is Google's (unit) testing and mocking framework for C++ tests.

gmock-matchers.h  (googletest-release-1.10.0):gmock-matchers.h  (googletest-release-1.11.0)
skipping to change at line 32 skipping to change at line 32
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes. // Google Mock - a framework for writing C++ mock classes.
// //
// This file implements some commonly used argument matchers. More // The MATCHER* family of macros can be used in a namespace scope to
// define custom matchers easily.
//
// Basic Usage
// ===========
//
// The syntax
//
// MATCHER(name, description_string) { statements; }
//
// defines a matcher with the given name that executes the statements,
// which must return a bool to indicate if the match succeeds. Inside
// the statements, you can refer to the value being matched by 'arg',
// and refer to its type by 'arg_type'.
//
// The description string documents what the matcher does, and is used
// to generate the failure message when the match fails. Since a
// MATCHER() is usually defined in a header file shared by multiple
// C++ source files, we require the description to be a C-string
// literal to avoid possible side effects. It can be empty, in which
// case we'll use the sequence of words in the matcher name as the
// description.
//
// For example:
//
// MATCHER(IsEven, "") { return (arg % 2) == 0; }
//
// allows you to write
//
// // Expects mock_foo.Bar(n) to be called where n is even.
// EXPECT_CALL(mock_foo, Bar(IsEven()));
//
// or,
//
// // Verifies that the value of some_expression is even.
// EXPECT_THAT(some_expression, IsEven());
//
// If the above assertion fails, it will print something like:
//
// Value of: some_expression
// Expected: is even
// Actual: 7
//
// where the description "is even" is automatically calculated from the
// matcher name IsEven.
//
// Argument Type
// =============
//
// Note that the type of the value being matched (arg_type) is
// determined by the context in which you use the matcher and is
// supplied to you by the compiler, so you don't need to worry about
// declaring it (nor can you). This allows the matcher to be
// polymorphic. For example, IsEven() can be used to match any type
// where the value of "(arg % 2) == 0" can be implicitly converted to
// a bool. In the "Bar(IsEven())" example above, if method Bar()
// takes an int, 'arg_type' will be int; if it takes an unsigned long,
// 'arg_type' will be unsigned long; and so on.
//
// Parameterizing Matchers
// =======================
//
// Sometimes you'll want to parameterize the matcher. For that you
// can use another macro:
//
// MATCHER_P(name, param_name, description_string) { statements; }
//
// For example:
//
// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; }
//
// will allow you to write:
//
// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n));
//
// which may lead to this message (assuming n is 10):
//
// Value of: Blah("a")
// Expected: has absolute value 10
// Actual: -9
//
// Note that both the matcher description and its parameter are
// printed, making the message human-friendly.
//
// In the matcher definition body, you can write 'foo_type' to
// reference the type of a parameter named 'foo'. For example, in the
// body of MATCHER_P(HasAbsoluteValue, value) above, you can write
// 'value_type' to refer to the type of 'value'.
//
// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to
// support multi-parameter matchers.
//
// Describing Parameterized Matchers
// =================================
//
// The last argument to MATCHER*() is a string-typed expression. The
// expression can reference all of the matcher's parameters and a
// special bool-typed variable named 'negation'. When 'negation' is
// false, the expression should evaluate to the matcher's description;
// otherwise it should evaluate to the description of the negation of
// the matcher. For example,
//
// using testing::PrintToString;
//
// MATCHER_P2(InClosedRange, low, hi,
// std::string(negation ? "is not" : "is") + " in range [" +
// PrintToString(low) + ", " + PrintToString(hi) + "]") {
// return low <= arg && arg <= hi;
// }
// ...
// EXPECT_THAT(3, InClosedRange(4, 6));
// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
//
// would generate two failures that contain the text:
//
// Expected: is in range [4, 6]
// ...
// Expected: is not in range [2, 4]
//
// If you specify "" as the description, the failure message will
// contain the sequence of words in the matcher name followed by the
// parameter values printed as a tuple. For example,
//
// MATCHER_P2(InClosedRange, low, hi, "") { ... }
// ...
// EXPECT_THAT(3, InClosedRange(4, 6));
// EXPECT_THAT(3, Not(InClosedRange(2, 4)));
//
// would generate two failures that contain the text:
//
// Expected: in closed range (4, 6)
// ...
// Expected: not (in closed range (2, 4))
//
// Types of Matcher Parameters
// ===========================
//
// For the purpose of typing, you can view
//
// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }
//
// as shorthand for
//
// template <typename p1_type, ..., typename pk_type>
// FooMatcherPk<p1_type, ..., pk_type>
// Foo(p1_type p1, ..., pk_type pk) { ... }
//
// When you write Foo(v1, ..., vk), the compiler infers the types of
// the parameters v1, ..., and vk for you. If you are not happy with
// the result of the type inference, you can specify the types by
// explicitly instantiating the template, as in Foo<long, bool>(5,
// false). As said earlier, you don't get to (or need to) specify
// 'arg_type' as that's determined by the context in which the matcher
// is used. You can assign the result of expression Foo(p1, ..., pk)
// to a variable of type FooMatcherPk<p1_type, ..., pk_type>. This
// can be useful when composing matchers.
//
// While you can instantiate a matcher template with reference types,
// passing the parameters by pointer usually makes your code more
// readable. If, however, you still want to pass a parameter by
// reference, be aware that in the failure message generated by the
// matcher you will see the value of the referenced object but not its
// address.
//
// Explaining Match Results
// ========================
//
// Sometimes the matcher description alone isn't enough to explain why
// the match has failed or succeeded. For example, when expecting a
// long string, it can be very helpful to also print the diff between
// the expected string and the actual one. To achieve that, you can
// optionally stream additional information to a special variable
// named result_listener, whose type is a pointer to class
// MatchResultListener:
//
// MATCHER_P(EqualsLongString, str, "") {
// if (arg == str) return true;
//
// *result_listener << "the difference: "
/// << DiffStrings(str, arg);
// return false;
// }
//
// Overloading Matchers
// ====================
//
// You can overload matchers with different numbers of parameters:
//
// MATCHER_P(Blah, a, description_string1) { ... }
// MATCHER_P2(Blah, a, b, description_string2) { ... }
//
// Caveats
// =======
//
// When defining a new matcher, you should also consider implementing
// MatcherInterface or using MakePolymorphicMatcher(). These
// approaches require more work than the MATCHER* macros, but also
// give you more control on the types of the value being matched and
// the matcher parameters, which may leads to better compiler error
// messages when the matcher is used wrong. They also allow
// overloading matchers based on parameter types (as opposed to just
// based on the number of parameters).
//
// MATCHER*() can only be used in a namespace scope as templates cannot be
// declared inside of a local class.
//
// More Information
// ================
//
// To learn more about using these macros, please search for 'MATCHER'
// on
// https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md
//
// This file also implements some commonly used argument matchers. More
// matchers can be defined by the user implementing the // matchers can be defined by the user implementing the
// MatcherInterface<T> interface if necessary. // MatcherInterface<T> interface if necessary.
// //
// See googletest/include/gtest/gtest-matchers.h for the definition of class // See googletest/include/gtest/gtest-matchers.h for the definition of class
// Matcher, class MatcherInterface, and others. // Matcher, class MatcherInterface, and others.
// GOOGLETEST_CM0002 DO NOT DELETE // GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
#include <math.h>
#include <algorithm> #include <algorithm>
#include <cmath>
#include <initializer_list> #include <initializer_list>
#include <iterator> #include <iterator>
#include <limits> #include <limits>
#include <memory> #include <memory>
#include <ostream> // NOLINT #include <ostream> // NOLINT
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "gmock/internal/gmock-internal-utils.h" #include "gmock/internal/gmock-internal-utils.h"
#include "gmock/internal/gmock-port.h" #include "gmock/internal/gmock-port.h"
#include "gmock/internal/gmock-pp.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
// MSVC warning C5046 is new as of VS2017 version 15.8. // MSVC warning C5046 is new as of VS2017 version 15.8.
#if defined(_MSC_VER) && _MSC_VER >= 1915 #if defined(_MSC_VER) && _MSC_VER >= 1915
#define GMOCK_MAYBE_5046_ 5046 #define GMOCK_MAYBE_5046_ 5046
#else #else
#define GMOCK_MAYBE_5046_ #define GMOCK_MAYBE_5046_
#endif #endif
GTEST_DISABLE_MSC_WARNINGS_PUSH_( GTEST_DISABLE_MSC_WARNINGS_PUSH_(
skipping to change at line 130 skipping to change at line 345
static Matcher<T> Cast(const M& polymorphic_matcher_or_value) { static Matcher<T> Cast(const M& polymorphic_matcher_or_value) {
// M can be a polymorphic matcher, in which case we want to use // M can be a polymorphic matcher, in which case we want to use
// its conversion operator to create Matcher<T>. Or it can be a value // its conversion operator to create Matcher<T>. Or it can be a value
// that should be passed to the Matcher<T>'s constructor. // that should be passed to the Matcher<T>'s constructor.
// //
// We can't call Matcher<T>(polymorphic_matcher_or_value) when M is a // We can't call Matcher<T>(polymorphic_matcher_or_value) when M is a
// polymorphic matcher because it'll be ambiguous if T has an implicit // polymorphic matcher because it'll be ambiguous if T has an implicit
// constructor from M (this usually happens when T has an implicit // constructor from M (this usually happens when T has an implicit
// constructor from any type). // constructor from any type).
// //
// It won't work to unconditionally implict_cast // It won't work to unconditionally implicit_cast
// polymorphic_matcher_or_value to Matcher<T> because it won't trigger // polymorphic_matcher_or_value to Matcher<T> because it won't trigger
// a user-defined conversion from M to T if one exists (assuming M is // a user-defined conversion from M to T if one exists (assuming M is
// a value). // a value).
return CastImpl(polymorphic_matcher_or_value, return CastImpl(polymorphic_matcher_or_value,
std::is_convertible<M, Matcher<T>>{}, std::is_convertible<M, Matcher<T>>{},
std::is_convertible<M, T>{}); std::is_convertible<M, T>{});
} }
private: private:
template <bool Ignore> template <bool Ignore>
static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value, static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value,
std::true_type /* convertible_to_matcher */, std::true_type /* convertible_to_matcher */,
bool_constant<Ignore>) { std::integral_constant<bool, Ignore>) {
// M is implicitly convertible to Matcher<T>, which means that either // M is implicitly convertible to Matcher<T>, which means that either
// M is a polymorphic matcher or Matcher<T> has an implicit constructor // M is a polymorphic matcher or Matcher<T> has an implicit constructor
// from M. In both cases using the implicit conversion will produce a // from M. In both cases using the implicit conversion will produce a
// matcher. // matcher.
// //
// Even if T has an implicit constructor from M, it won't be called because // Even if T has an implicit constructor from M, it won't be called because
// creating Matcher<T> would require a chain of two user-defined conversions // creating Matcher<T> would require a chain of two user-defined conversions
// (first to create T from M and then to create Matcher<T> from T). // (first to create T from M and then to create Matcher<T> from T).
return polymorphic_matcher_or_value; return polymorphic_matcher_or_value;
} }
skipping to change at line 211 skipping to change at line 426
// Do not allow implicitly converting base*/& to derived*/&. // Do not allow implicitly converting base*/& to derived*/&.
static_assert( static_assert(
// Do not trigger if only one of them is a pointer. That implies a // Do not trigger if only one of them is a pointer. That implies a
// regular conversion and not a down_cast. // regular conversion and not a down_cast.
(std::is_pointer<typename std::remove_reference<T>::type>::value != (std::is_pointer<typename std::remove_reference<T>::type>::value !=
std::is_pointer<typename std::remove_reference<U>::type>::value) || std::is_pointer<typename std::remove_reference<U>::type>::value) ||
std::is_same<FromType, ToType>::value || std::is_same<FromType, ToType>::value ||
!std::is_base_of<FromType, ToType>::value, !std::is_base_of<FromType, ToType>::value,
"Can't implicitly convert from <base> to <derived>"); "Can't implicitly convert from <base> to <derived>");
return source_matcher_.MatchAndExplain(static_cast<U>(x), listener); // Do the cast to `U` explicitly if necessary.
// Otherwise, let implicit conversions do the trick.
using CastType =
typename std::conditional<std::is_convertible<T&, const U&>::value,
T&, U>::type;
return source_matcher_.MatchAndExplain(static_cast<CastType>(x),
listener);
} }
void DescribeTo(::std::ostream* os) const override { void DescribeTo(::std::ostream* os) const override {
source_matcher_.DescribeTo(os); source_matcher_.DescribeTo(os);
} }
void DescribeNegationTo(::std::ostream* os) const override { void DescribeNegationTo(::std::ostream* os) const override {
source_matcher_.DescribeNegationTo(os); source_matcher_.DescribeNegationTo(os);
} }
private: private:
const Matcher<U> source_matcher_; const Matcher<U> source_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; };
}; };
// This even more specialized version is used for efficiently casting // This even more specialized version is used for efficiently casting
// a matcher to its own type. // a matcher to its own type.
template <typename T> template <typename T>
class MatcherCastImpl<T, Matcher<T> > { class MatcherCastImpl<T, Matcher<T> > {
public: public:
static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; } static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; }
}; };
// Template specialization for parameterless Matcher.
template <typename Derived>
class MatcherBaseImpl {
public:
MatcherBaseImpl() = default;
template <typename T>
operator ::testing::Matcher<T>() const { // NOLINT(runtime/explicit)
return ::testing::Matcher<T>(new
typename Derived::template gmock_Impl<T>());
}
};
// Template specialization for Matcher with parameters.
template <template <typename...> class Derived, typename... Ts>
class MatcherBaseImpl<Derived<Ts...>> {
public:
// Mark the constructor explicit for single argument T to avoid implicit
// conversions.
template <typename E = std::enable_if<sizeof...(Ts) == 1>,
typename E::type* = nullptr>
explicit MatcherBaseImpl(Ts... params)
: params_(std::forward<Ts>(params)...) {}
template <typename E = std::enable_if<sizeof...(Ts) != 1>,
typename = typename E::type>
MatcherBaseImpl(Ts... params) // NOLINT
: params_(std::forward<Ts>(params)...) {}
template <typename F>
operator ::testing::Matcher<F>() const { // NOLINT(runtime/explicit)
return Apply<F>(MakeIndexSequence<sizeof...(Ts)>{});
}
private:
template <typename F, std::size_t... tuple_ids>
::testing::Matcher<F> Apply(IndexSequence<tuple_ids...>) const {
return ::testing::Matcher<F>(
new typename Derived<Ts...>::template gmock_Impl<F>(
std::get<tuple_ids>(params_)...));
}
const std::tuple<Ts...> params_;
};
} // namespace internal } // namespace internal
// In order to be safe and clear, casting between different matcher // In order to be safe and clear, casting between different matcher
// types is done explicitly via MatcherCast<T>(m), which takes a // types is done explicitly via MatcherCast<T>(m), which takes a
// matcher m and returns a Matcher<T>. It compiles only when T can be // matcher m and returns a Matcher<T>. It compiles only when T can be
// statically converted to the argument type of m. // statically converted to the argument type of m.
template <typename T, typename M> template <typename T, typename M>
inline Matcher<T> MatcherCast(const M& matcher) { inline Matcher<T> MatcherCast(const M& matcher) {
return internal::MatcherCastImpl<T, M>::Cast(matcher); return internal::MatcherCastImpl<T, M>::Cast(matcher);
} }
// Implements SafeMatcherCast(). // This overload handles polymorphic matchers and values only since
// // monomorphic matchers are handled by the next one.
// FIXME: The intermediate SafeMatcherCastImpl class was introduced as a
// workaround for a compiler bug, and can now be removed.
template <typename T>
class SafeMatcherCastImpl {
public:
// This overload handles polymorphic matchers and values only since
// monomorphic matchers are handled by the next one.
template <typename M>
static inline Matcher<T> Cast(const M& polymorphic_matcher_or_value) {
return internal::MatcherCastImpl<T, M>::Cast(polymorphic_matcher_or_value);
}
// This overload handles monomorphic matchers.
//
// In general, if type T can be implicitly converted to type U, we can
// safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is
// contravariant): just keep a copy of the original Matcher<U>, convert the
// argument from type T to U, and then pass it to the underlying Matcher<U>.
// The only exception is when U is a reference and T is not, as the
// underlying Matcher<U> may be interested in the argument's address, which
// is not preserved in the conversion from T to U.
template <typename U>
static inline Matcher<T> Cast(const Matcher<U>& matcher) {
// Enforce that T can be implicitly converted to U.
GTEST_COMPILE_ASSERT_((std::is_convertible<T, U>::value),
"T must be implicitly convertible to U");
// Enforce that we are not converting a non-reference type T to a reference
// type U.
GTEST_COMPILE_ASSERT_(
std::is_reference<T>::value || !std::is_reference<U>::value,
cannot_convert_non_reference_arg_to_reference);
// In case both T and U are arithmetic types, enforce that the
// conversion is not lossy.
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT;
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU;
const bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther;
const bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther;
GTEST_COMPILE_ASSERT_(
kTIsOther || kUIsOther ||
(internal::LosslessArithmeticConvertible<RawT, RawU>::value),
conversion_of_arithmetic_types_must_be_lossless);
return MatcherCast<T>(matcher);
}
};
template <typename T, typename M> template <typename T, typename M>
inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher) { inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher_or_value) {
return SafeMatcherCastImpl<T>::Cast(polymorphic_matcher); return MatcherCast<T>(polymorphic_matcher_or_value);
}
// This overload handles monomorphic matchers.
//
// In general, if type T can be implicitly converted to type U, we can
// safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is
// contravariant): just keep a copy of the original Matcher<U>, convert the
// argument from type T to U, and then pass it to the underlying Matcher<U>.
// The only exception is when U is a reference and T is not, as the
// underlying Matcher<U> may be interested in the argument's address, which
// is not preserved in the conversion from T to U.
template <typename T, typename U>
inline Matcher<T> SafeMatcherCast(const Matcher<U>& matcher) {
// Enforce that T can be implicitly converted to U.
static_assert(std::is_convertible<const T&, const U&>::value,
"T must be implicitly convertible to U");
// Enforce that we are not converting a non-reference type T to a reference
// type U.
GTEST_COMPILE_ASSERT_(
std::is_reference<T>::value || !std::is_reference<U>::value,
cannot_convert_non_reference_arg_to_reference);
// In case both T and U are arithmetic types, enforce that the
// conversion is not lossy.
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT;
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU;
constexpr bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther;
constexpr bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther;
GTEST_COMPILE_ASSERT_(
kTIsOther || kUIsOther ||
(internal::LosslessArithmeticConvertible<RawT, RawU>::value),
conversion_of_arithmetic_types_must_be_lossless);
return MatcherCast<T>(matcher);
} }
// A<T>() returns a matcher that matches any value of type T. // A<T>() returns a matcher that matches any value of type T.
template <typename T> template <typename T>
Matcher<T> A(); Matcher<T> A();
// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION // Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
// and MUST NOT BE USED IN USER CODE!!! // and MUST NOT BE USED IN USER CODE!!!
namespace internal { namespace internal {
skipping to change at line 486 skipping to change at line 737
}; };
// Successively invokes 'f(element)' on each element of the tuple 't', // Successively invokes 'f(element)' on each element of the tuple 't',
// appending each result to the 'out' iterator. Returns the final value // appending each result to the 'out' iterator. Returns the final value
// of 'out'. // of 'out'.
template <typename Tuple, typename Func, typename OutIter> template <typename Tuple, typename Func, typename OutIter>
OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) { OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) {
return TransformTupleValuesHelper<Tuple, Func, OutIter>::Run(f, t, out); return TransformTupleValuesHelper<Tuple, Func, OutIter>::Run(f, t, out);
} }
// Implements A<T>().
template <typename T>
class AnyMatcherImpl : public MatcherInterface<const T&> {
public:
bool MatchAndExplain(const T& /* x */,
MatchResultListener* /* listener */) const override {
return true;
}
void DescribeTo(::std::ostream* os) const override { *os << "is anything"; }
void DescribeNegationTo(::std::ostream* os) const override {
// This is mostly for completeness' safe, as it's not very useful
// to write Not(A<bool>()). However we cannot completely rule out
// such a possibility, and it doesn't hurt to be prepared.
*os << "never matches";
}
};
// Implements _, a matcher that matches any value of any // Implements _, a matcher that matches any value of any
// type. This is a polymorphic matcher, so we need a template type // type. This is a polymorphic matcher, so we need a template type
// conversion operator to make it appearing as a Matcher<T> for any // conversion operator to make it appearing as a Matcher<T> for any
// type T. // type T.
class AnythingMatcher { class AnythingMatcher {
public: public:
using is_gtest_matcher = void;
template <typename T> template <typename T>
operator Matcher<T>() const { return A<T>(); } bool MatchAndExplain(const T& /* x */, std::ostream* /* listener */) const {
return true;
}
void DescribeTo(std::ostream* os) const { *os << "is anything"; }
void DescribeNegationTo(::std::ostream* os) const {
// This is mostly for completeness' sake, as it's not very useful
// to write Not(A<bool>()). However we cannot completely rule out
// such a possibility, and it doesn't hurt to be prepared.
*os << "never matches";
}
}; };
// Implements the polymorphic IsNull() matcher, which matches any raw or smart // Implements the polymorphic IsNull() matcher, which matches any raw or smart
// pointer that is NULL. // pointer that is NULL.
class IsNullMatcher { class IsNullMatcher {
public: public:
template <typename Pointer> template <typename Pointer>
bool MatchAndExplain(const Pointer& p, bool MatchAndExplain(const Pointer& p,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
return p == nullptr; return p == nullptr;
skipping to change at line 610 skipping to change at line 855
UniversalPrinter<Super&>::Print(object_, os); UniversalPrinter<Super&>::Print(object_, os);
} }
void DescribeNegationTo(::std::ostream* os) const override { void DescribeNegationTo(::std::ostream* os) const override {
*os << "does not reference the variable "; *os << "does not reference the variable ";
UniversalPrinter<Super&>::Print(object_, os); UniversalPrinter<Super&>::Print(object_, os);
} }
private: private:
const Super& object_; const Super& object_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; };
T& object_; T& object_;
GTEST_DISALLOW_ASSIGN_(RefMatcher);
}; };
// Polymorphic helper functions for narrow and wide string matchers. // Polymorphic helper functions for narrow and wide string matchers.
inline bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) { inline bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) {
return String::CaseInsensitiveCStringEquals(lhs, rhs); return String::CaseInsensitiveCStringEquals(lhs, rhs);
} }
inline bool CaseInsensitiveCStringEquals(const wchar_t* lhs, inline bool CaseInsensitiveCStringEquals(const wchar_t* lhs,
const wchar_t* rhs) { const wchar_t* rhs) {
return String::CaseInsensitiveWideCStringEquals(lhs, rhs); return String::CaseInsensitiveWideCStringEquals(lhs, rhs);
skipping to change at line 658 skipping to change at line 899
// Are the tails equal? // Are the tails equal?
return CaseInsensitiveStringEquals(s1.substr(i1 + 1), s2.substr(i2 + 1)); return CaseInsensitiveStringEquals(s1.substr(i1 + 1), s2.substr(i2 + 1));
} }
// String matchers. // String matchers.
// Implements equality-based string matchers like StrEq, StrCaseNe, and etc. // Implements equality-based string matchers like StrEq, StrCaseNe, and etc.
template <typename StringType> template <typename StringType>
class StrEqualityMatcher { class StrEqualityMatcher {
public: public:
StrEqualityMatcher(const StringType& str, bool expect_eq, StrEqualityMatcher(StringType str, bool expect_eq, bool case_sensitive)
bool case_sensitive) : string_(std::move(str)),
: string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {} expect_eq_(expect_eq),
case_sensitive_(case_sensitive) {}
#if GTEST_HAS_ABSL #if GTEST_INTERNAL_HAS_STRING_VIEW
bool MatchAndExplain(const absl::string_view& s, bool MatchAndExplain(const internal::StringView& s,
MatchResultListener* listener) const { MatchResultListener* listener) const {
// This should fail to compile if absl::string_view is used with wide // This should fail to compile if StringView is used with wide
// strings. // strings.
const StringType& str = std::string(s); const StringType& str = std::string(s);
return MatchAndExplain(str, listener); return MatchAndExplain(str, listener);
} }
#endif // GTEST_HAS_ABSL #endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Accepts pointer types, particularly: // Accepts pointer types, particularly:
// const char* // const char*
// char* // char*
// const wchar_t* // const wchar_t*
// wchar_t* // wchar_t*
template <typename CharType> template <typename CharType>
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
if (s == nullptr) { if (s == nullptr) {
return !expect_eq_; return !expect_eq_;
} }
return MatchAndExplain(StringType(s), listener); return MatchAndExplain(StringType(s), listener);
} }
// Matches anything that can convert to StringType. // Matches anything that can convert to StringType.
// //
// This is a template, not just a plain function with const StringType&, // This is a template, not just a plain function with const StringType&,
// because absl::string_view has some interfering non-explicit constructors. // because StringView has some interfering non-explicit constructors.
template <typename MatcheeStringType> template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s, bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
const StringType& s2(s); const StringType s2(s);
const bool eq = case_sensitive_ ? s2 == string_ : const bool eq = case_sensitive_ ? s2 == string_ :
CaseInsensitiveStringEquals(s2, string_); CaseInsensitiveStringEquals(s2, string_);
return expect_eq_ == eq; return expect_eq_ == eq;
} }
void DescribeTo(::std::ostream* os) const { void DescribeTo(::std::ostream* os) const {
DescribeToHelper(expect_eq_, os); DescribeToHelper(expect_eq_, os);
} }
void DescribeNegationTo(::std::ostream* os) const { void DescribeNegationTo(::std::ostream* os) const {
skipping to change at line 719 skipping to change at line 961
*os << "equal to "; *os << "equal to ";
if (!case_sensitive_) { if (!case_sensitive_) {
*os << "(ignoring case) "; *os << "(ignoring case) ";
} }
UniversalPrint(string_, os); UniversalPrint(string_, os);
} }
const StringType string_; const StringType string_;
const bool expect_eq_; const bool expect_eq_;
const bool case_sensitive_; const bool case_sensitive_;
GTEST_DISALLOW_ASSIGN_(StrEqualityMatcher);
}; };
// Implements the polymorphic HasSubstr(substring) matcher, which // Implements the polymorphic HasSubstr(substring) matcher, which
// can be used as a Matcher<T> as long as T can be converted to a // can be used as a Matcher<T> as long as T can be converted to a
// string. // string.
template <typename StringType> template <typename StringType>
class HasSubstrMatcher { class HasSubstrMatcher {
public: public:
explicit HasSubstrMatcher(const StringType& substring) explicit HasSubstrMatcher(const StringType& substring)
: substring_(substring) {} : substring_(substring) {}
#if GTEST_HAS_ABSL #if GTEST_INTERNAL_HAS_STRING_VIEW
bool MatchAndExplain(const absl::string_view& s, bool MatchAndExplain(const internal::StringView& s,
MatchResultListener* listener) const { MatchResultListener* listener) const {
// This should fail to compile if absl::string_view is used with wide // This should fail to compile if StringView is used with wide
// strings. // strings.
const StringType& str = std::string(s); const StringType& str = std::string(s);
return MatchAndExplain(str, listener); return MatchAndExplain(str, listener);
} }
#endif // GTEST_HAS_ABSL #endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Accepts pointer types, particularly: // Accepts pointer types, particularly:
// const char* // const char*
// char* // char*
// const wchar_t* // const wchar_t*
// wchar_t* // wchar_t*
template <typename CharType> template <typename CharType>
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
return s != nullptr && MatchAndExplain(StringType(s), listener); return s != nullptr && MatchAndExplain(StringType(s), listener);
} }
// Matches anything that can convert to StringType. // Matches anything that can convert to StringType.
// //
// This is a template, not just a plain function with const StringType&, // This is a template, not just a plain function with const StringType&,
// because absl::string_view has some interfering non-explicit constructors. // because StringView has some interfering non-explicit constructors.
template <typename MatcheeStringType> template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s, bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
const StringType& s2(s); return StringType(s).find(substring_) != StringType::npos;
return s2.find(substring_) != StringType::npos;
} }
// Describes what this matcher matches. // Describes what this matcher matches.
void DescribeTo(::std::ostream* os) const { void DescribeTo(::std::ostream* os) const {
*os << "has substring "; *os << "has substring ";
UniversalPrint(substring_, os); UniversalPrint(substring_, os);
} }
void DescribeNegationTo(::std::ostream* os) const { void DescribeNegationTo(::std::ostream* os) const {
*os << "has no substring "; *os << "has no substring ";
UniversalPrint(substring_, os); UniversalPrint(substring_, os);
} }
private: private:
const StringType substring_; const StringType substring_;
GTEST_DISALLOW_ASSIGN_(HasSubstrMatcher);
}; };
// Implements the polymorphic StartsWith(substring) matcher, which // Implements the polymorphic StartsWith(substring) matcher, which
// can be used as a Matcher<T> as long as T can be converted to a // can be used as a Matcher<T> as long as T can be converted to a
// string. // string.
template <typename StringType> template <typename StringType>
class StartsWithMatcher { class StartsWithMatcher {
public: public:
explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) { explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) {
} }
#if GTEST_HAS_ABSL #if GTEST_INTERNAL_HAS_STRING_VIEW
bool MatchAndExplain(const absl::string_view& s, bool MatchAndExplain(const internal::StringView& s,
MatchResultListener* listener) const { MatchResultListener* listener) const {
// This should fail to compile if absl::string_view is used with wide // This should fail to compile if StringView is used with wide
// strings. // strings.
const StringType& str = std::string(s); const StringType& str = std::string(s);
return MatchAndExplain(str, listener); return MatchAndExplain(str, listener);
} }
#endif // GTEST_HAS_ABSL #endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Accepts pointer types, particularly: // Accepts pointer types, particularly:
// const char* // const char*
// char* // char*
// const wchar_t* // const wchar_t*
// wchar_t* // wchar_t*
template <typename CharType> template <typename CharType>
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
return s != nullptr && MatchAndExplain(StringType(s), listener); return s != nullptr && MatchAndExplain(StringType(s), listener);
} }
// Matches anything that can convert to StringType. // Matches anything that can convert to StringType.
// //
// This is a template, not just a plain function with const StringType&, // This is a template, not just a plain function with const StringType&,
// because absl::string_view has some interfering non-explicit constructors. // because StringView has some interfering non-explicit constructors.
template <typename MatcheeStringType> template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s, bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
const StringType& s2(s); const StringType& s2(s);
return s2.length() >= prefix_.length() && return s2.length() >= prefix_.length() &&
s2.substr(0, prefix_.length()) == prefix_; s2.substr(0, prefix_.length()) == prefix_;
} }
void DescribeTo(::std::ostream* os) const { void DescribeTo(::std::ostream* os) const {
*os << "starts with "; *os << "starts with ";
UniversalPrint(prefix_, os); UniversalPrint(prefix_, os);
} }
void DescribeNegationTo(::std::ostream* os) const { void DescribeNegationTo(::std::ostream* os) const {
*os << "doesn't start with "; *os << "doesn't start with ";
UniversalPrint(prefix_, os); UniversalPrint(prefix_, os);
} }
private: private:
const StringType prefix_; const StringType prefix_;
GTEST_DISALLOW_ASSIGN_(StartsWithMatcher);
}; };
// Implements the polymorphic EndsWith(substring) matcher, which // Implements the polymorphic EndsWith(substring) matcher, which
// can be used as a Matcher<T> as long as T can be converted to a // can be used as a Matcher<T> as long as T can be converted to a
// string. // string.
template <typename StringType> template <typename StringType>
class EndsWithMatcher { class EndsWithMatcher {
public: public:
explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {} explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {}
#if GTEST_HAS_ABSL #if GTEST_INTERNAL_HAS_STRING_VIEW
bool MatchAndExplain(const absl::string_view& s, bool MatchAndExplain(const internal::StringView& s,
MatchResultListener* listener) const { MatchResultListener* listener) const {
// This should fail to compile if absl::string_view is used with wide // This should fail to compile if StringView is used with wide
// strings. // strings.
const StringType& str = std::string(s); const StringType& str = std::string(s);
return MatchAndExplain(str, listener); return MatchAndExplain(str, listener);
} }
#endif // GTEST_HAS_ABSL #endif // GTEST_INTERNAL_HAS_STRING_VIEW
// Accepts pointer types, particularly: // Accepts pointer types, particularly:
// const char* // const char*
// char* // char*
// const wchar_t* // const wchar_t*
// wchar_t* // wchar_t*
template <typename CharType> template <typename CharType>
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
return s != nullptr && MatchAndExplain(StringType(s), listener); return s != nullptr && MatchAndExplain(StringType(s), listener);
} }
// Matches anything that can convert to StringType. // Matches anything that can convert to StringType.
// //
// This is a template, not just a plain function with const StringType&, // This is a template, not just a plain function with const StringType&,
// because absl::string_view has some interfering non-explicit constructors. // because StringView has some interfering non-explicit constructors.
template <typename MatcheeStringType> template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s, bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
const StringType& s2(s); const StringType& s2(s);
return s2.length() >= suffix_.length() && return s2.length() >= suffix_.length() &&
s2.substr(s2.length() - suffix_.length()) == suffix_; s2.substr(s2.length() - suffix_.length()) == suffix_;
} }
void DescribeTo(::std::ostream* os) const { void DescribeTo(::std::ostream* os) const {
*os << "ends with "; *os << "ends with ";
UniversalPrint(suffix_, os); UniversalPrint(suffix_, os);
} }
void DescribeNegationTo(::std::ostream* os) const { void DescribeNegationTo(::std::ostream* os) const {
*os << "doesn't end with "; *os << "doesn't end with ";
UniversalPrint(suffix_, os); UniversalPrint(suffix_, os);
} }
private: private:
const StringType suffix_; const StringType suffix_;
GTEST_DISALLOW_ASSIGN_(EndsWithMatcher);
}; };
// Implements a matcher that compares the two fields of a 2-tuple // Implements a matcher that compares the two fields of a 2-tuple
// using one of the ==, <=, <, etc, operators. The two fields being // using one of the ==, <=, <, etc, operators. The two fields being
// compared don't have to have the same type. // compared don't have to have the same type.
// //
// The matcher defined here is polymorphic (for example, Eq() can be // The matcher defined here is polymorphic (for example, Eq() can be
// used to match a std::tuple<int, short>, a std::tuple<const long&, double>, // used to match a std::tuple<int, short>, a std::tuple<const long&, double>,
// etc). Therefore we use a template type conversion operator in the // etc). Therefore we use a template type conversion operator in the
// implementation. // implementation.
skipping to change at line 984 skipping to change at line 1217
void DescribeTo(::std::ostream* os) const override { void DescribeTo(::std::ostream* os) const override {
matcher_.DescribeNegationTo(os); matcher_.DescribeNegationTo(os);
} }
void DescribeNegationTo(::std::ostream* os) const override { void DescribeNegationTo(::std::ostream* os) const override {
matcher_.DescribeTo(os); matcher_.DescribeTo(os);
} }
private: private:
const Matcher<T> matcher_; const Matcher<T> matcher_;
GTEST_DISALLOW_ASSIGN_(NotMatcherImpl);
}; };
// Implements the Not(m) matcher, which matches a value that doesn't // Implements the Not(m) matcher, which matches a value that doesn't
// match matcher m. // match matcher m.
template <typename InnerMatcher> template <typename InnerMatcher>
class NotMatcher { class NotMatcher {
public: public:
explicit NotMatcher(InnerMatcher matcher) : matcher_(matcher) {} explicit NotMatcher(InnerMatcher matcher) : matcher_(matcher) {}
// This template type conversion operator allows Not(m) to be used // This template type conversion operator allows Not(m) to be used
// to match any type m can match. // to match any type m can match.
template <typename T> template <typename T>
operator Matcher<T>() const { operator Matcher<T>() const {
return Matcher<T>(new NotMatcherImpl<T>(SafeMatcherCast<T>(matcher_))); return Matcher<T>(new NotMatcherImpl<T>(SafeMatcherCast<T>(matcher_)));
} }
private: private:
InnerMatcher matcher_; InnerMatcher matcher_;
GTEST_DISALLOW_ASSIGN_(NotMatcher);
}; };
// Implements the AllOf(m1, m2) matcher for a particular argument type // Implements the AllOf(m1, m2) matcher for a particular argument type
// T. We do not nest it inside the BothOfMatcher class template, as // T. We do not nest it inside the BothOfMatcher class template, as
// that will prevent different instantiations of BothOfMatcher from // that will prevent different instantiations of BothOfMatcher from
// sharing the same BothOfMatcherImpl<T> class. // sharing the same BothOfMatcherImpl<T> class.
template <typename T> template <typename T>
class AllOfMatcherImpl : public MatcherInterface<const T&> { class AllOfMatcherImpl : public MatcherInterface<const T&> {
public: public:
explicit AllOfMatcherImpl(std::vector<Matcher<T> > matchers) explicit AllOfMatcherImpl(std::vector<Matcher<T> > matchers)
skipping to change at line 1067 skipping to change at line 1296
} }
} }
// Otherwise we need to explain why *both* of them match. // Otherwise we need to explain why *both* of them match.
*listener << all_match_result; *listener << all_match_result;
return true; return true;
} }
private: private:
const std::vector<Matcher<T> > matchers_; const std::vector<Matcher<T> > matchers_;
GTEST_DISALLOW_ASSIGN_(AllOfMatcherImpl);
}; };
// VariadicMatcher is used for the variadic implementation of // VariadicMatcher is used for the variadic implementation of
// AllOf(m_1, m_2, ...) and AnyOf(m_1, m_2, ...). // AllOf(m_1, m_2, ...) and AnyOf(m_1, m_2, ...).
// CombiningMatcher<T> is used to recursively combine the provided matchers // CombiningMatcher<T> is used to recursively combine the provided matchers
// (of type Args...). // (of type Args...).
template <template <typename T> class CombiningMatcher, typename... Args> template <template <typename T> class CombiningMatcher, typename... Args>
class VariadicMatcher { class VariadicMatcher {
public: public:
VariadicMatcher(const Args&... matchers) // NOLINT VariadicMatcher(const Args&... matchers) // NOLINT
: matchers_(matchers...) { : matchers_(matchers...) {
static_assert(sizeof...(Args) > 0, "Must have at least one matcher."); static_assert(sizeof...(Args) > 0, "Must have at least one matcher.");
} }
VariadicMatcher(const VariadicMatcher&) = default;
VariadicMatcher& operator=(const VariadicMatcher&) = delete;
// This template type conversion operator allows an // This template type conversion operator allows an
// VariadicMatcher<Matcher1, Matcher2...> object to match any type that // VariadicMatcher<Matcher1, Matcher2...> object to match any type that
// all of the provided matchers (Matcher1, Matcher2, ...) can match. // all of the provided matchers (Matcher1, Matcher2, ...) can match.
template <typename T> template <typename T>
operator Matcher<T>() const { operator Matcher<T>() const {
std::vector<Matcher<T> > values; std::vector<Matcher<T> > values;
CreateVariadicMatcher<T>(&values, std::integral_constant<size_t, 0>()); CreateVariadicMatcher<T>(&values, std::integral_constant<size_t, 0>());
return Matcher<T>(new CombiningMatcher<T>(std::move(values))); return Matcher<T>(new CombiningMatcher<T>(std::move(values)));
} }
skipping to change at line 1107 skipping to change at line 1337
values->push_back(SafeMatcherCast<T>(std::get<I>(matchers_))); values->push_back(SafeMatcherCast<T>(std::get<I>(matchers_)));
CreateVariadicMatcher<T>(values, std::integral_constant<size_t, I + 1>()); CreateVariadicMatcher<T>(values, std::integral_constant<size_t, I + 1>());
} }
template <typename T> template <typename T>
void CreateVariadicMatcher( void CreateVariadicMatcher(
std::vector<Matcher<T> >*, std::vector<Matcher<T> >*,
std::integral_constant<size_t, sizeof...(Args)>) const {} std::integral_constant<size_t, sizeof...(Args)>) const {}
std::tuple<Args...> matchers_; std::tuple<Args...> matchers_;
GTEST_DISALLOW_ASSIGN_(VariadicMatcher);
}; };
template <typename... Args> template <typename... Args>
using AllOfMatcher = VariadicMatcher<AllOfMatcherImpl, Args...>; using AllOfMatcher = VariadicMatcher<AllOfMatcherImpl, Args...>;
// Implements the AnyOf(m1, m2) matcher for a particular argument type // Implements the AnyOf(m1, m2) matcher for a particular argument type
// T. We do not nest it inside the AnyOfMatcher class template, as // T. We do not nest it inside the AnyOfMatcher class template, as
// that will prevent different instantiations of AnyOfMatcher from // that will prevent different instantiations of AnyOfMatcher from
// sharing the same EitherOfMatcherImpl<T> class. // sharing the same EitherOfMatcherImpl<T> class.
template <typename T> template <typename T>
skipping to change at line 1173 skipping to change at line 1401
} }
} }
// Otherwise we need to explain why *both* of them fail. // Otherwise we need to explain why *both* of them fail.
*listener << no_match_result; *listener << no_match_result;
return false; return false;
} }
private: private:
const std::vector<Matcher<T> > matchers_; const std::vector<Matcher<T> > matchers_;
GTEST_DISALLOW_ASSIGN_(AnyOfMatcherImpl);
}; };
// AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...). // AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...).
template <typename... Args> template <typename... Args>
using AnyOfMatcher = VariadicMatcher<AnyOfMatcherImpl, Args...>; using AnyOfMatcher = VariadicMatcher<AnyOfMatcherImpl, Args...>;
// Wrapper for implementation of Any/AllOfArray(). // Wrapper for implementation of Any/AllOfArray().
template <template <class> class MatcherImpl, typename T> template <template <class> class MatcherImpl, typename T>
class SomeOfArrayMatcher { class SomeOfArrayMatcher {
public: public:
skipping to change at line 1202 skipping to change at line 1428
using RawU = typename std::decay<U>::type; using RawU = typename std::decay<U>::type;
std::vector<Matcher<RawU>> matchers; std::vector<Matcher<RawU>> matchers;
for (const auto& matcher : matchers_) { for (const auto& matcher : matchers_) {
matchers.push_back(MatcherCast<RawU>(matcher)); matchers.push_back(MatcherCast<RawU>(matcher));
} }
return Matcher<U>(new MatcherImpl<RawU>(std::move(matchers))); return Matcher<U>(new MatcherImpl<RawU>(std::move(matchers)));
} }
private: private:
const ::std::vector<T> matchers_; const ::std::vector<T> matchers_;
GTEST_DISALLOW_ASSIGN_(SomeOfArrayMatcher);
}; };
template <typename T> template <typename T>
using AllOfArrayMatcher = SomeOfArrayMatcher<AllOfMatcherImpl, T>; using AllOfArrayMatcher = SomeOfArrayMatcher<AllOfMatcherImpl, T>;
template <typename T> template <typename T>
using AnyOfArrayMatcher = SomeOfArrayMatcher<AnyOfMatcherImpl, T>; using AnyOfArrayMatcher = SomeOfArrayMatcher<AnyOfMatcherImpl, T>;
// Used for implementing Truly(pred), which turns a predicate into a // Used for implementing Truly(pred), which turns a predicate into a
// matcher. // matcher.
skipping to change at line 1225 skipping to change at line 1449
class TrulyMatcher { class TrulyMatcher {
public: public:
explicit TrulyMatcher(Predicate pred) : predicate_(pred) {} explicit TrulyMatcher(Predicate pred) : predicate_(pred) {}
// This method template allows Truly(pred) to be used as a matcher // This method template allows Truly(pred) to be used as a matcher
// for type T where T is the argument type of predicate 'pred'. The // for type T where T is the argument type of predicate 'pred'. The
// argument is passed by reference as the predicate may be // argument is passed by reference as the predicate may be
// interested in the address of the argument. // interested in the address of the argument.
template <typename T> template <typename T>
bool MatchAndExplain(T& x, // NOLINT bool MatchAndExplain(T& x, // NOLINT
MatchResultListener* /* listener */) const { MatchResultListener* listener) const {
// Without the if-statement, MSVC sometimes warns about converting // Without the if-statement, MSVC sometimes warns about converting
// a value to bool (warning 4800). // a value to bool (warning 4800).
// //
// We cannot write 'return !!predicate_(x);' as that doesn't work // We cannot write 'return !!predicate_(x);' as that doesn't work
// when predicate_(x) returns a class convertible to bool but // when predicate_(x) returns a class convertible to bool but
// having no operator!(). // having no operator!().
if (predicate_(x)) if (predicate_(x))
return true; return true;
*listener << "didn't satisfy the given predicate";
return false; return false;
} }
void DescribeTo(::std::ostream* os) const { void DescribeTo(::std::ostream* os) const {
*os << "satisfies the given predicate"; *os << "satisfies the given predicate";
} }
void DescribeNegationTo(::std::ostream* os) const { void DescribeNegationTo(::std::ostream* os) const {
*os << "doesn't satisfy the given predicate"; *os << "doesn't satisfy the given predicate";
} }
private: private:
Predicate predicate_; Predicate predicate_;
GTEST_DISALLOW_ASSIGN_(TrulyMatcher);
}; };
// Used for implementing Matches(matcher), which turns a matcher into // Used for implementing Matches(matcher), which turns a matcher into
// a predicate. // a predicate.
template <typename M> template <typename M>
class MatcherAsPredicate { class MatcherAsPredicate {
public: public:
explicit MatcherAsPredicate(M matcher) : matcher_(matcher) {} explicit MatcherAsPredicate(M matcher) : matcher_(matcher) {}
// This template operator() allows Matches(m) to be used as a // This template operator() allows Matches(m) to be used as a
skipping to change at line 1285 skipping to change at line 1508
// matcher_.Matches(x), it won't compile when matcher_ is // matcher_.Matches(x), it won't compile when matcher_ is
// polymorphic, e.g. Eq(5). // polymorphic, e.g. Eq(5).
// //
// MatcherCast<const T&>() is necessary for making the code work // MatcherCast<const T&>() is necessary for making the code work
// in all of the above situations. // in all of the above situations.
return MatcherCast<const T&>(matcher_).Matches(x); return MatcherCast<const T&>(matcher_).Matches(x);
} }
private: private:
M matcher_; M matcher_;
GTEST_DISALLOW_ASSIGN_(MatcherAsPredicate);
}; };
// For implementing ASSERT_THAT() and EXPECT_THAT(). The template // For implementing ASSERT_THAT() and EXPECT_THAT(). The template
// argument M must be a type that can be converted to a matcher. // argument M must be a type that can be converted to a matcher.
template <typename M> template <typename M>
class PredicateFormatterFromMatcher { class PredicateFormatterFromMatcher {
public: public:
explicit PredicateFormatterFromMatcher(M m) : matcher_(std::move(m)) {} explicit PredicateFormatterFromMatcher(M m) : matcher_(std::move(m)) {}
// This template () operator allows a PredicateFormatterFromMatcher // This template () operator allows a PredicateFormatterFromMatcher
skipping to change at line 1325 skipping to change at line 1546
// tests pass) so optimize for this case. // tests pass) so optimize for this case.
if (matcher.Matches(x)) { if (matcher.Matches(x)) {
return AssertionSuccess(); return AssertionSuccess();
} }
::std::stringstream ss; ::std::stringstream ss;
ss << "Value of: " << value_text << "\n" ss << "Value of: " << value_text << "\n"
<< "Expected: "; << "Expected: ";
matcher.DescribeTo(&ss); matcher.DescribeTo(&ss);
// Rerun the matcher to "PrintAndExain" the failure. // Rerun the matcher to "PrintAndExplain" the failure.
StringMatchResultListener listener; StringMatchResultListener listener;
if (MatchPrintAndExplain(x, matcher, &listener)) { if (MatchPrintAndExplain(x, matcher, &listener)) {
ss << "\n The matcher failed on the initial attempt; but passed when " ss << "\n The matcher failed on the initial attempt; but passed when "
"rerun to generate the explanation."; "rerun to generate the explanation.";
} }
ss << "\n Actual: " << listener.str(); ss << "\n Actual: " << listener.str();
return AssertionFailure() << ss.str(); return AssertionFailure() << ss.str();
} }
private: private:
const M matcher_; const M matcher_;
GTEST_DISALLOW_ASSIGN_(PredicateFormatterFromMatcher);
}; };
// A helper function for converting a matcher to a predicate-formatter // A helper function for converting a matcher to a predicate-formatter
// without the user needing to explicitly write the type. This is // without the user needing to explicitly write the type. This is
// used for implementing ASSERT_THAT() and EXPECT_THAT(). // used for implementing ASSERT_THAT() and EXPECT_THAT().
// Implementation detail: 'matcher' is received by-value to force decaying. // Implementation detail: 'matcher' is received by-value to force decaying.
template <typename M> template <typename M>
inline PredicateFormatterFromMatcher<M> inline PredicateFormatterFromMatcher<M>
MakePredicateFormatterFromMatcher(M matcher) { MakePredicateFormatterFromMatcher(M matcher) {
return PredicateFormatterFromMatcher<M>(std::move(matcher)); return PredicateFormatterFromMatcher<M>(std::move(matcher));
} }
// Implements the polymorphic IsNan() matcher, which matches any floating type
// value that is Nan.
class IsNanMatcher {
public:
template <typename FloatType>
bool MatchAndExplain(const FloatType& f,
MatchResultListener* /* listener */) const {
return (::std::isnan)(f);
}
void DescribeTo(::std::ostream* os) const { *os << "is NaN"; }
void DescribeNegationTo(::std::ostream* os) const {
*os << "isn't NaN";
}
};
// Implements the polymorphic floating point equality matcher, which matches // Implements the polymorphic floating point equality matcher, which matches
// two float values using ULP-based approximation or, optionally, a // two float values using ULP-based approximation or, optionally, a
// user-specified epsilon. The template is meant to be instantiated with // user-specified epsilon. The template is meant to be instantiated with
// FloatType being either float or double. // FloatType being either float or double.
template <typename FloatType> template <typename FloatType>
class FloatingEqMatcher { class FloatingEqMatcher {
public: public:
// Constructor for FloatingEqMatcher. // Constructor for FloatingEqMatcher.
// The matcher's input will be compared with expected. The matcher treats two // The matcher's input will be compared with expected. The matcher treats two
// NANs as equal if nan_eq_nan is true. Otherwise, under IEEE standards, // NANs as equal if nan_eq_nan is true. Otherwise, under IEEE standards,
skipping to change at line 1411 skipping to change at line 1646
if (HasMaxAbsError()) { if (HasMaxAbsError()) {
// We perform an equality check so that inf will match inf, regardless // We perform an equality check so that inf will match inf, regardless
// of error bounds. If the result of value - expected_ would result in // of error bounds. If the result of value - expected_ would result in
// overflow or if either value is inf, the default result is infinity, // overflow or if either value is inf, the default result is infinity,
// which should only match if max_abs_error_ is also infinity. // which should only match if max_abs_error_ is also infinity.
if (value == expected_) { if (value == expected_) {
return true; return true;
} }
const FloatType diff = value - expected_; const FloatType diff = value - expected_;
if (fabs(diff) <= max_abs_error_) { if (::std::fabs(diff) <= max_abs_error_) {
return true; return true;
} }
if (listener->IsInterested()) { if (listener->IsInterested()) {
*listener << "which is " << diff << " from " << expected_; *listener << "which is " << diff << " from " << expected_;
} }
return false; return false;
} else { } else {
return actual.AlmostEquals(expected); return actual.AlmostEquals(expected);
} }
skipping to change at line 1474 skipping to change at line 1709
private: private:
bool HasMaxAbsError() const { bool HasMaxAbsError() const {
return max_abs_error_ >= 0; return max_abs_error_ >= 0;
} }
const FloatType expected_; const FloatType expected_;
const bool nan_eq_nan_; const bool nan_eq_nan_;
// max_abs_error will be used for value comparison when >= 0. // max_abs_error will be used for value comparison when >= 0.
const FloatType max_abs_error_; const FloatType max_abs_error_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; };
// The following 3 type conversion operators allow FloatEq(expected) and // The following 3 type conversion operators allow FloatEq(expected) and
// NanSensitiveFloatEq(expected) to be used as a Matcher<float>, a // NanSensitiveFloatEq(expected) to be used as a Matcher<float>, a
// Matcher<const float&>, or a Matcher<float&>, but nothing else. // Matcher<const float&>, or a Matcher<float&>, but nothing else.
// (While Google's C++ coding style doesn't allow arguments passed
// by non-const reference, we may see them in code not conforming to
// the style. Therefore Google Mock needs to support them.)
operator Matcher<FloatType>() const { operator Matcher<FloatType>() const {
return MakeMatcher( return MakeMatcher(
new Impl<FloatType>(expected_, nan_eq_nan_, max_abs_error_)); new Impl<FloatType>(expected_, nan_eq_nan_, max_abs_error_));
} }
operator Matcher<const FloatType&>() const { operator Matcher<const FloatType&>() const {
return MakeMatcher( return MakeMatcher(
new Impl<const FloatType&>(expected_, nan_eq_nan_, max_abs_error_)); new Impl<const FloatType&>(expected_, nan_eq_nan_, max_abs_error_));
} }
operator Matcher<FloatType&>() const { operator Matcher<FloatType&>() const {
return MakeMatcher( return MakeMatcher(
new Impl<FloatType&>(expected_, nan_eq_nan_, max_abs_error_)); new Impl<FloatType&>(expected_, nan_eq_nan_, max_abs_error_));
} }
private: private:
const FloatType expected_; const FloatType expected_;
const bool nan_eq_nan_; const bool nan_eq_nan_;
// max_abs_error will be used for value comparison when >= 0. // max_abs_error will be used for value comparison when >= 0.
const FloatType max_abs_error_; const FloatType max_abs_error_;
GTEST_DISALLOW_ASSIGN_(FloatingEqMatcher);
}; };
// A 2-tuple ("binary") wrapper around FloatingEqMatcher: // A 2-tuple ("binary") wrapper around FloatingEqMatcher:
// FloatingEq2Matcher() matches (x, y) by matching FloatingEqMatcher(x, false) // FloatingEq2Matcher() matches (x, y) by matching FloatingEqMatcher(x, false)
// against y, and FloatingEq2Matcher(e) matches FloatingEqMatcher(x, false, e) // against y, and FloatingEq2Matcher(e) matches FloatingEqMatcher(x, false, e)
// against y. The former implements "Eq", the latter "Near". At present, there // against y. The former implements "Eq", the latter "Near". At present, there
// is no version that compares NaNs as equal. // is no version that compares NaNs as equal.
template <typename FloatType> template <typename FloatType>
class FloatingEq2Matcher { class FloatingEq2Matcher {
public: public:
skipping to change at line 1609 skipping to change at line 1837
template <typename Pointer> template <typename Pointer>
operator Matcher<Pointer>() const { operator Matcher<Pointer>() const {
return Matcher<Pointer>(new Impl<const Pointer&>(matcher_)); return Matcher<Pointer>(new Impl<const Pointer&>(matcher_));
} }
private: private:
// The monomorphic implementation that works for a particular pointer type. // The monomorphic implementation that works for a particular pointer type.
template <typename Pointer> template <typename Pointer>
class Impl : public MatcherInterface<Pointer> { class Impl : public MatcherInterface<Pointer> {
public: public:
typedef typename PointeeOf<typename std::remove_const< using Pointee =
typename std::remove_reference<Pointer>::type>::type>::type Pointee; typename std::pointer_traits<GTEST_REMOVE_REFERENCE_AND_CONST_(
Pointer)>::element_type;
explicit Impl(const InnerMatcher& matcher) explicit Impl(const InnerMatcher& matcher)
: matcher_(MatcherCast<const Pointee&>(matcher)) {} : matcher_(MatcherCast<const Pointee&>(matcher)) {}
void DescribeTo(::std::ostream* os) const override { void DescribeTo(::std::ostream* os) const override {
*os << "points to a value that "; *os << "points to a value that ";
matcher_.DescribeTo(os); matcher_.DescribeTo(os);
} }
void DescribeNegationTo(::std::ostream* os) const override { void DescribeNegationTo(::std::ostream* os) const override {
skipping to change at line 1635 skipping to change at line 1864
bool MatchAndExplain(Pointer pointer, bool MatchAndExplain(Pointer pointer,
MatchResultListener* listener) const override { MatchResultListener* listener) const override {
if (GetRawPointer(pointer) == nullptr) return false; if (GetRawPointer(pointer) == nullptr) return false;
*listener << "which points to "; *listener << "which points to ";
return MatchPrintAndExplain(*pointer, matcher_, listener); return MatchPrintAndExplain(*pointer, matcher_, listener);
} }
private: private:
const Matcher<const Pointee&> matcher_; const Matcher<const Pointee&> matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; };
const InnerMatcher matcher_; const InnerMatcher matcher_;
};
GTEST_DISALLOW_ASSIGN_(PointeeMatcher); // Implements the Pointer(m) matcher
// Implements the Pointer(m) matcher for matching a pointer that matches matcher
// m. The pointer can be either raw or smart, and will match `m` against the
// raw pointer.
template <typename InnerMatcher>
class PointerMatcher {
public:
explicit PointerMatcher(const InnerMatcher& matcher) : matcher_(matcher) {}
// This type conversion operator template allows Pointer(m) to be
// used as a matcher for any pointer type whose pointer type is
// compatible with the inner matcher, where type PointerType can be
// either a raw pointer or a smart pointer.
//
// The reason we do this instead of relying on
// MakePolymorphicMatcher() is that the latter is not flexible
// enough for implementing the DescribeTo() method of Pointer().
template <typename PointerType>
operator Matcher<PointerType>() const { // NOLINT
return Matcher<PointerType>(new Impl<const PointerType&>(matcher_));
}
private:
// The monomorphic implementation that works for a particular pointer type.
template <typename PointerType>
class Impl : public MatcherInterface<PointerType> {
public:
using Pointer =
const typename std::pointer_traits<GTEST_REMOVE_REFERENCE_AND_CONST_(
PointerType)>::element_type*;
explicit Impl(const InnerMatcher& matcher)
: matcher_(MatcherCast<Pointer>(matcher)) {}
void DescribeTo(::std::ostream* os) const override {
*os << "is a pointer that ";
matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "is not a pointer that ";
matcher_.DescribeTo(os);
}
bool MatchAndExplain(PointerType pointer,
MatchResultListener* listener) const override {
*listener << "which is a pointer that ";
Pointer p = GetRawPointer(pointer);
return MatchPrintAndExplain(p, matcher_, listener);
}
private:
Matcher<Pointer> matcher_;
};
const InnerMatcher matcher_;
}; };
#if GTEST_HAS_RTTI #if GTEST_HAS_RTTI
// Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or // Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or
// reference that matches inner_matcher when dynamic_cast<T> is applied. // reference that matches inner_matcher when dynamic_cast<T> is applied.
// The result of dynamic_cast<To> is forwarded to the inner matcher. // The result of dynamic_cast<To> is forwarded to the inner matcher.
// If To is a pointer and the cast fails, the inner matcher will receive NULL. // If To is a pointer and the cast fails, the inner matcher will receive NULL.
// If To is a reference and the cast fails, this matcher returns false // If To is a reference and the cast fails, this matcher returns false
// immediately. // immediately.
template <typename To> template <typename To>
skipping to change at line 1678 skipping to change at line 1961
const Matcher<To> matcher_; const Matcher<To> matcher_;
static std::string GetToName() { static std::string GetToName() {
return GetTypeName<To>(); return GetTypeName<To>();
} }
private: private:
static void GetCastTypeDescription(::std::ostream* os) { static void GetCastTypeDescription(::std::ostream* os) {
*os << "when dynamic_cast to " << GetToName() << ", "; *os << "when dynamic_cast to " << GetToName() << ", ";
} }
GTEST_DISALLOW_ASSIGN_(WhenDynamicCastToMatcherBase);
}; };
// Primary template. // Primary template.
// To is a pointer. Cast and forward the result. // To is a pointer. Cast and forward the result.
template <typename To> template <typename To>
class WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase<To> { class WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase<To> {
public: public:
explicit WhenDynamicCastToMatcher(const Matcher<To>& matcher) explicit WhenDynamicCastToMatcher(const Matcher<To>& matcher)
: WhenDynamicCastToMatcherBase<To>(matcher) {} : WhenDynamicCastToMatcherBase<To>(matcher) {}
skipping to change at line 1777 skipping to change at line 2058
// the first argument. // the first argument.
return MatchAndExplainImpl(std::false_type(), *p, listener); return MatchAndExplainImpl(std::false_type(), *p, listener);
} }
const FieldType Class::*field_; const FieldType Class::*field_;
const Matcher<const FieldType&> matcher_; const Matcher<const FieldType&> matcher_;
// Contains either "whose given field " if the name of the field is unknown // Contains either "whose given field " if the name of the field is unknown
// or "whose field `name_of_field` " if the name is known. // or "whose field `name_of_field` " if the name is known.
const std::string whose_field_; const std::string whose_field_;
GTEST_DISALLOW_ASSIGN_(FieldMatcher);
}; };
// Implements the Property() matcher for matching a property // Implements the Property() matcher for matching a property
// (i.e. return value of a getter method) of an object. // (i.e. return value of a getter method) of an object.
// //
// Property is a const-qualified member function of Class returning // Property is a const-qualified member function of Class returning
// PropertyType. // PropertyType.
template <typename Class, typename PropertyType, typename Property> template <typename Class, typename PropertyType, typename Property>
class PropertyMatcher { class PropertyMatcher {
public: public:
skipping to change at line 1847 skipping to change at line 2126
// false_type() as the first argument. // false_type() as the first argument.
return MatchAndExplainImpl(std::false_type(), *p, listener); return MatchAndExplainImpl(std::false_type(), *p, listener);
} }
Property property_; Property property_;
const Matcher<RefToConstProperty> matcher_; const Matcher<RefToConstProperty> matcher_;
// Contains either "whose given property " if the name of the property is // Contains either "whose given property " if the name of the property is
// unknown or "whose property `name_of_property` " if the name is known. // unknown or "whose property `name_of_property` " if the name is known.
const std::string whose_property_; const std::string whose_property_;
GTEST_DISALLOW_ASSIGN_(PropertyMatcher);
}; };
// Type traits specifying various features of different functors for ResultOf. // Type traits specifying various features of different functors for ResultOf.
// The default template specifies features for functor objects. // The default template specifies features for functor objects.
template <typename Functor> template <typename Functor>
struct CallableTraits { struct CallableTraits {
typedef Functor StorageType; typedef Functor StorageType;
static void CheckIsValid(Functor /* functor */) {} static void CheckIsValid(Functor /* functor */) {}
skipping to change at line 1938 skipping to change at line 2215
} }
private: private:
// Functors often define operator() as non-const method even though // Functors often define operator() as non-const method even though
// they are actually stateless. But we need to use them even when // they are actually stateless. But we need to use them even when
// 'this' is a const pointer. It's the user's responsibility not to // 'this' is a const pointer. It's the user's responsibility not to
// use stateful callables with ResultOf(), which doesn't guarantee // use stateful callables with ResultOf(), which doesn't guarantee
// how many times the callable will be invoked. // how many times the callable will be invoked.
mutable CallableStorageType callable_; mutable CallableStorageType callable_;
const Matcher<ResultType> matcher_; const Matcher<ResultType> matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; // class Impl }; // class Impl
const CallableStorageType callable_; const CallableStorageType callable_;
const InnerMatcher matcher_; const InnerMatcher matcher_;
GTEST_DISALLOW_ASSIGN_(ResultOfMatcher);
}; };
// Implements a matcher that checks the size of an STL-style container. // Implements a matcher that checks the size of an STL-style container.
template <typename SizeMatcher> template <typename SizeMatcher>
class SizeIsMatcher { class SizeIsMatcher {
public: public:
explicit SizeIsMatcher(const SizeMatcher& size_matcher) explicit SizeIsMatcher(const SizeMatcher& size_matcher)
: size_matcher_(size_matcher) { : size_matcher_(size_matcher) {
} }
skipping to change at line 1990 skipping to change at line 2263
StringMatchResultListener size_listener; StringMatchResultListener size_listener;
const bool result = size_matcher_.MatchAndExplain(size, &size_listener); const bool result = size_matcher_.MatchAndExplain(size, &size_listener);
*listener *listener
<< "whose size " << size << (result ? " matches" : " doesn't match"); << "whose size " << size << (result ? " matches" : " doesn't match");
PrintIfNotEmpty(size_listener.str(), listener->stream()); PrintIfNotEmpty(size_listener.str(), listener->stream());
return result; return result;
} }
private: private:
const Matcher<SizeType> size_matcher_; const Matcher<SizeType> size_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; };
private: private:
const SizeMatcher size_matcher_; const SizeMatcher size_matcher_;
GTEST_DISALLOW_ASSIGN_(SizeIsMatcher);
}; };
// Implements a matcher that checks the begin()..end() distance of an STL-style // Implements a matcher that checks the begin()..end() distance of an STL-style
// container. // container.
template <typename DistanceMatcher> template <typename DistanceMatcher>
class BeginEndDistanceIsMatcher { class BeginEndDistanceIsMatcher {
public: public:
explicit BeginEndDistanceIsMatcher(const DistanceMatcher& distance_matcher) explicit BeginEndDistanceIsMatcher(const DistanceMatcher& distance_matcher)
: distance_matcher_(distance_matcher) {} : distance_matcher_(distance_matcher) {}
skipping to change at line 2047 skipping to change at line 2318
const bool result = const bool result =
distance_matcher_.MatchAndExplain(distance, &distance_listener); distance_matcher_.MatchAndExplain(distance, &distance_listener);
*listener << "whose distance between begin() and end() " << distance *listener << "whose distance between begin() and end() " << distance
<< (result ? " matches" : " doesn't match"); << (result ? " matches" : " doesn't match");
PrintIfNotEmpty(distance_listener.str(), listener->stream()); PrintIfNotEmpty(distance_listener.str(), listener->stream());
return result; return result;
} }
private: private:
const Matcher<DistanceType> distance_matcher_; const Matcher<DistanceType> distance_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; };
private: private:
const DistanceMatcher distance_matcher_; const DistanceMatcher distance_matcher_;
GTEST_DISALLOW_ASSIGN_(BeginEndDistanceIsMatcher);
}; };
// Implements an equality matcher for any STL-style container whose elements // Implements an equality matcher for any STL-style container whose elements
// support ==. This matcher is like Eq(), but its failure explanations provide // support ==. This matcher is like Eq(), but its failure explanations provide
// more detailed information that is useful when the container is used as a set. // more detailed information that is useful when the container is used as a set.
// The failure message reports elements that are in one of the operands but not // The failure message reports elements that are in one of the operands but not
// the other. The failure messages do not report duplicate or out-of-order // the other. The failure messages do not report duplicate or out-of-order
// elements in the containers (which don't properly matter to sets, but can // elements in the containers (which don't properly matter to sets, but can
// occur if the containers are vectors or lists, for example). // occur if the containers are vectors or lists, for example).
// //
skipping to change at line 2145 skipping to change at line 2414
UniversalPrint(*it, os); UniversalPrint(*it, os);
} }
} }
} }
return false; return false;
} }
private: private:
const StlContainer expected_; const StlContainer expected_;
GTEST_DISALLOW_ASSIGN_(ContainerEqMatcher);
}; };
// A comparator functor that uses the < operator to compare two values. // A comparator functor that uses the < operator to compare two values.
struct LessComparator { struct LessComparator {
template <typename T, typename U> template <typename T, typename U>
bool operator()(const T& lhs, const U& rhs) const { return lhs < rhs; } bool operator()(const T& lhs, const U& rhs) const { return lhs < rhs; }
}; };
// Implements WhenSortedBy(comparator, container_matcher). // Implements WhenSortedBy(comparator, container_matcher).
template <typename Comparator, typename ContainerMatcher> template <typename Comparator, typename ContainerMatcher>
skipping to change at line 2228 skipping to change at line 2495
private: private:
const Comparator comparator_; const Comparator comparator_;
const Matcher<const ::std::vector<LhsValue>&> matcher_; const Matcher<const ::std::vector<LhsValue>&> matcher_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(Impl); GTEST_DISALLOW_COPY_AND_ASSIGN_(Impl);
}; };
private: private:
const Comparator comparator_; const Comparator comparator_;
const ContainerMatcher matcher_; const ContainerMatcher matcher_;
GTEST_DISALLOW_ASSIGN_(WhenSortedByMatcher);
}; };
// Implements Pointwise(tuple_matcher, rhs_container). tuple_matcher // Implements Pointwise(tuple_matcher, rhs_container). tuple_matcher
// must be able to be safely cast to Matcher<std::tuple<const T1&, const // must be able to be safely cast to Matcher<std::tuple<const T1&, const
// T2&> >, where T1 and T2 are the types of elements in the LHS // T2&> >, where T1 and T2 are the types of elements in the LHS
// container and the RHS container respectively. // container and the RHS container respectively.
template <typename TupleMatcher, typename RhsContainer> template <typename TupleMatcher, typename RhsContainer>
class PointwiseMatcher { class PointwiseMatcher {
GTEST_COMPILE_ASSERT_( GTEST_COMPILE_ASSERT_(
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>::value, !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>::value,
skipping to change at line 2345 skipping to change at line 2610
return false; return false;
} }
} }
return true; return true;
} }
private: private:
const Matcher<InnerMatcherArg> mono_tuple_matcher_; const Matcher<InnerMatcherArg> mono_tuple_matcher_;
const RhsStlContainer rhs_; const RhsStlContainer rhs_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; };
private: private:
const TupleMatcher tuple_matcher_; const TupleMatcher tuple_matcher_;
const RhsStlContainer rhs_; const RhsStlContainer rhs_;
GTEST_DISALLOW_ASSIGN_(PointwiseMatcher);
}; };
// Holds the logic common to ContainsMatcherImpl and EachMatcherImpl. // Holds the logic common to ContainsMatcherImpl and EachMatcherImpl.
template <typename Container> template <typename Container>
class QuantifierMatcherImpl : public MatcherInterface<Container> { class QuantifierMatcherImpl : public MatcherInterface<Container> {
public: public:
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
typedef StlContainerView<RawContainer> View; typedef StlContainerView<RawContainer> View;
typedef typename View::type StlContainer; typedef typename View::type StlContainer;
typedef typename View::const_reference StlContainerReference; typedef typename View::const_reference StlContainerReference;
skipping to change at line 2396 skipping to change at line 2657
<< (matches ? " matches" : " doesn't match"); << (matches ? " matches" : " doesn't match");
PrintIfNotEmpty(inner_listener.str(), listener->stream()); PrintIfNotEmpty(inner_listener.str(), listener->stream());
return !all_elements_should_match; return !all_elements_should_match;
} }
} }
return all_elements_should_match; return all_elements_should_match;
} }
protected: protected:
const Matcher<const Element&> inner_matcher_; const Matcher<const Element&> inner_matcher_;
GTEST_DISALLOW_ASSIGN_(QuantifierMatcherImpl);
}; };
// Implements Contains(element_matcher) for the given argument type Container. // Implements Contains(element_matcher) for the given argument type Container.
// Symmetric to EachMatcherImpl. // Symmetric to EachMatcherImpl.
template <typename Container> template <typename Container>
class ContainsMatcherImpl : public QuantifierMatcherImpl<Container> { class ContainsMatcherImpl : public QuantifierMatcherImpl<Container> {
public: public:
template <typename InnerMatcher> template <typename InnerMatcher>
explicit ContainsMatcherImpl(InnerMatcher inner_matcher) explicit ContainsMatcherImpl(InnerMatcher inner_matcher)
: QuantifierMatcherImpl<Container>(inner_matcher) {} : QuantifierMatcherImpl<Container>(inner_matcher) {}
skipping to change at line 2424 skipping to change at line 2683
void DescribeNegationTo(::std::ostream* os) const override { void DescribeNegationTo(::std::ostream* os) const override {
*os << "doesn't contain any element that "; *os << "doesn't contain any element that ";
this->inner_matcher_.DescribeTo(os); this->inner_matcher_.DescribeTo(os);
} }
bool MatchAndExplain(Container container, bool MatchAndExplain(Container container,
MatchResultListener* listener) const override { MatchResultListener* listener) const override {
return this->MatchAndExplainImpl(false, container, listener); return this->MatchAndExplainImpl(false, container, listener);
} }
private:
GTEST_DISALLOW_ASSIGN_(ContainsMatcherImpl);
}; };
// Implements Each(element_matcher) for the given argument type Container. // Implements Each(element_matcher) for the given argument type Container.
// Symmetric to ContainsMatcherImpl. // Symmetric to ContainsMatcherImpl.
template <typename Container> template <typename Container>
class EachMatcherImpl : public QuantifierMatcherImpl<Container> { class EachMatcherImpl : public QuantifierMatcherImpl<Container> {
public: public:
template <typename InnerMatcher> template <typename InnerMatcher>
explicit EachMatcherImpl(InnerMatcher inner_matcher) explicit EachMatcherImpl(InnerMatcher inner_matcher)
: QuantifierMatcherImpl<Container>(inner_matcher) {} : QuantifierMatcherImpl<Container>(inner_matcher) {}
skipping to change at line 2453 skipping to change at line 2709
void DescribeNegationTo(::std::ostream* os) const override { void DescribeNegationTo(::std::ostream* os) const override {
*os << "contains some element that "; *os << "contains some element that ";
this->inner_matcher_.DescribeNegationTo(os); this->inner_matcher_.DescribeNegationTo(os);
} }
bool MatchAndExplain(Container container, bool MatchAndExplain(Container container,
MatchResultListener* listener) const override { MatchResultListener* listener) const override {
return this->MatchAndExplainImpl(true, container, listener); return this->MatchAndExplainImpl(true, container, listener);
} }
private:
GTEST_DISALLOW_ASSIGN_(EachMatcherImpl);
}; };
// Implements polymorphic Contains(element_matcher). // Implements polymorphic Contains(element_matcher).
template <typename M> template <typename M>
class ContainsMatcher { class ContainsMatcher {
public: public:
explicit ContainsMatcher(M m) : inner_matcher_(m) {} explicit ContainsMatcher(M m) : inner_matcher_(m) {}
template <typename Container> template <typename Container>
operator Matcher<Container>() const { operator Matcher<Container>() const {
return Matcher<Container>( return Matcher<Container>(
new ContainsMatcherImpl<const Container&>(inner_matcher_)); new ContainsMatcherImpl<const Container&>(inner_matcher_));
} }
private: private:
const M inner_matcher_; const M inner_matcher_;
GTEST_DISALLOW_ASSIGN_(ContainsMatcher);
}; };
// Implements polymorphic Each(element_matcher). // Implements polymorphic Each(element_matcher).
template <typename M> template <typename M>
class EachMatcher { class EachMatcher {
public: public:
explicit EachMatcher(M m) : inner_matcher_(m) {} explicit EachMatcher(M m) : inner_matcher_(m) {}
template <typename Container> template <typename Container>
operator Matcher<Container>() const { operator Matcher<Container>() const {
return Matcher<Container>( return Matcher<Container>(
new EachMatcherImpl<const Container&>(inner_matcher_)); new EachMatcherImpl<const Container&>(inner_matcher_));
} }
private: private:
const M inner_matcher_; const M inner_matcher_;
GTEST_DISALLOW_ASSIGN_(EachMatcher);
}; };
struct Rank1 {}; struct Rank1 {};
struct Rank0 : Rank1 {}; struct Rank0 : Rank1 {};
namespace pair_getters { namespace pair_getters {
using std::get; using std::get;
template <typename T> template <typename T>
auto First(T& x, Rank1) -> decltype(get<0>(x)) { // NOLINT auto First(T& x, Rank1) -> decltype(get<0>(x)) { // NOLINT
return get<0>(x); return get<0>(x);
skipping to change at line 2562 skipping to change at line 2811
} }
// Describes what the negation of this matcher does. // Describes what the negation of this matcher does.
void DescribeNegationTo(::std::ostream* os) const override { void DescribeNegationTo(::std::ostream* os) const override {
*os << "doesn't have a key that "; *os << "doesn't have a key that ";
inner_matcher_.DescribeTo(os); inner_matcher_.DescribeTo(os);
} }
private: private:
const Matcher<const KeyType&> inner_matcher_; const Matcher<const KeyType&> inner_matcher_;
GTEST_DISALLOW_ASSIGN_(KeyMatcherImpl);
}; };
// Implements polymorphic Key(matcher_for_key). // Implements polymorphic Key(matcher_for_key).
template <typename M> template <typename M>
class KeyMatcher { class KeyMatcher {
public: public:
explicit KeyMatcher(M m) : matcher_for_key_(m) {} explicit KeyMatcher(M m) : matcher_for_key_(m) {}
template <typename PairType> template <typename PairType>
operator Matcher<PairType>() const { operator Matcher<PairType>() const {
return Matcher<PairType>( return Matcher<PairType>(
new KeyMatcherImpl<const PairType&>(matcher_for_key_)); new KeyMatcherImpl<const PairType&>(matcher_for_key_));
} }
private: private:
const M matcher_for_key_; const M matcher_for_key_;
};
GTEST_DISALLOW_ASSIGN_(KeyMatcher); // Implements polymorphic Address(matcher_for_address).
template <typename InnerMatcher>
class AddressMatcher {
public:
explicit AddressMatcher(InnerMatcher m) : matcher_(m) {}
template <typename Type>
operator Matcher<Type>() const { // NOLINT
return Matcher<Type>(new Impl<const Type&>(matcher_));
}
private:
// The monomorphic implementation that works for a particular object type.
template <typename Type>
class Impl : public MatcherInterface<Type> {
public:
using Address = const GTEST_REMOVE_REFERENCE_AND_CONST_(Type) *;
explicit Impl(const InnerMatcher& matcher)
: matcher_(MatcherCast<Address>(matcher)) {}
void DescribeTo(::std::ostream* os) const override {
*os << "has address that ";
matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "does not have address that ";
matcher_.DescribeTo(os);
}
bool MatchAndExplain(Type object,
MatchResultListener* listener) const override {
*listener << "which has address ";
Address address = std::addressof(object);
return MatchPrintAndExplain(address, matcher_, listener);
}
private:
const Matcher<Address> matcher_;
};
const InnerMatcher matcher_;
}; };
// Implements Pair(first_matcher, second_matcher) for the given argument pair // Implements Pair(first_matcher, second_matcher) for the given argument pair
// type with its two matchers. See Pair() function below. // type with its two matchers. See Pair() function below.
template <typename PairType> template <typename PairType>
class PairMatcherImpl : public MatcherInterface<PairType> { class PairMatcherImpl : public MatcherInterface<PairType> {
public: public:
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType; typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType;
typedef typename RawPairType::first_type FirstType; typedef typename RawPairType::first_type FirstType;
typedef typename RawPairType::second_type SecondType; typedef typename RawPairType::second_type SecondType;
skipping to change at line 2667 skipping to change at line 2955
*listener << "and "; *listener << "and ";
} else { } else {
*listener << "where "; *listener << "where ";
} }
*listener << "the second field is a value " << second_explanation; *listener << "the second field is a value " << second_explanation;
} }
} }
const Matcher<const FirstType&> first_matcher_; const Matcher<const FirstType&> first_matcher_;
const Matcher<const SecondType&> second_matcher_; const Matcher<const SecondType&> second_matcher_;
GTEST_DISALLOW_ASSIGN_(PairMatcherImpl);
}; };
// Implements polymorphic Pair(first_matcher, second_matcher). // Implements polymorphic Pair(first_matcher, second_matcher).
template <typename FirstMatcher, typename SecondMatcher> template <typename FirstMatcher, typename SecondMatcher>
class PairMatcher { class PairMatcher {
public: public:
PairMatcher(FirstMatcher first_matcher, SecondMatcher second_matcher) PairMatcher(FirstMatcher first_matcher, SecondMatcher second_matcher)
: first_matcher_(first_matcher), second_matcher_(second_matcher) {} : first_matcher_(first_matcher), second_matcher_(second_matcher) {}
template <typename PairType> template <typename PairType>
operator Matcher<PairType> () const { operator Matcher<PairType> () const {
return Matcher<PairType>( return Matcher<PairType>(
new PairMatcherImpl<const PairType&>(first_matcher_, second_matcher_)); new PairMatcherImpl<const PairType&>(first_matcher_, second_matcher_));
} }
private: private:
const FirstMatcher first_matcher_; const FirstMatcher first_matcher_;
const SecondMatcher second_matcher_; const SecondMatcher second_matcher_;
};
GTEST_DISALLOW_ASSIGN_(PairMatcher); template <typename T, size_t... I>
auto UnpackStructImpl(const T& t, IndexSequence<I...>, int)
-> decltype(std::tie(get<I>(t)...)) {
static_assert(std::tuple_size<T>::value == sizeof...(I),
"Number of arguments doesn't match the number of fields.");
return std::tie(get<I>(t)...);
}
#if defined(__cpp_structured_bindings) && __cpp_structured_bindings >= 201606
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<1>, char) {
const auto& [a] = t;
return std::tie(a);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<2>, char) {
const auto& [a, b] = t;
return std::tie(a, b);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<3>, char) {
const auto& [a, b, c] = t;
return std::tie(a, b, c);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<4>, char) {
const auto& [a, b, c, d] = t;
return std::tie(a, b, c, d);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<5>, char) {
const auto& [a, b, c, d, e] = t;
return std::tie(a, b, c, d, e);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<6>, char) {
const auto& [a, b, c, d, e, f] = t;
return std::tie(a, b, c, d, e, f);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<7>, char) {
const auto& [a, b, c, d, e, f, g] = t;
return std::tie(a, b, c, d, e, f, g);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<8>, char) {
const auto& [a, b, c, d, e, f, g, h] = t;
return std::tie(a, b, c, d, e, f, g, h);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<9>, char) {
const auto& [a, b, c, d, e, f, g, h, i] = t;
return std::tie(a, b, c, d, e, f, g, h, i);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<10>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<11>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<12>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<13>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<14>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<15>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o);
}
template <typename T>
auto UnpackStructImpl(const T& t, MakeIndexSequence<16>, char) {
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = t;
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p);
}
#endif // defined(__cpp_structured_bindings)
template <size_t I, typename T>
auto UnpackStruct(const T& t)
-> decltype((UnpackStructImpl)(t, MakeIndexSequence<I>{}, 0)) {
return (UnpackStructImpl)(t, MakeIndexSequence<I>{}, 0);
}
// Helper function to do comma folding in C++11.
// The array ensures left-to-right order of evaluation.
// Usage: VariadicExpand({expr...});
template <typename T, size_t N>
void VariadicExpand(const T (&)[N]) {}
template <typename Struct, typename StructSize>
class FieldsAreMatcherImpl;
template <typename Struct, size_t... I>
class FieldsAreMatcherImpl<Struct, IndexSequence<I...>>
: public MatcherInterface<Struct> {
using UnpackedType =
decltype(UnpackStruct<sizeof...(I)>(std::declval<const Struct&>()));
using MatchersType = std::tuple<
Matcher<const typename std::tuple_element<I, UnpackedType>::type&>...>;
public:
template <typename Inner>
explicit FieldsAreMatcherImpl(const Inner& matchers)
: matchers_(testing::SafeMatcherCast<
const typename std::tuple_element<I, UnpackedType>::type&>(
std::get<I>(matchers))...) {}
void DescribeTo(::std::ostream* os) const override {
const char* separator = "";
VariadicExpand(
{(*os << separator << "has field #" << I << " that ",
std::get<I>(matchers_).DescribeTo(os), separator = ", and ")...});
}
void DescribeNegationTo(::std::ostream* os) const override {
const char* separator = "";
VariadicExpand({(*os << separator << "has field #" << I << " that ",
std::get<I>(matchers_).DescribeNegationTo(os),
separator = ", or ")...});
}
bool MatchAndExplain(Struct t, MatchResultListener* listener) const override {
return MatchInternal((UnpackStruct<sizeof...(I)>)(t), listener);
}
private:
bool MatchInternal(UnpackedType tuple, MatchResultListener* listener) const {
if (!listener->IsInterested()) {
// If the listener is not interested, we don't need to construct the
// explanation.
bool good = true;
VariadicExpand({good = good && std::get<I>(matchers_).Matches(
std::get<I>(tuple))...});
return good;
}
size_t failed_pos = ~size_t{};
std::vector<StringMatchResultListener> inner_listener(sizeof...(I));
VariadicExpand(
{failed_pos == ~size_t{} && !std::get<I>(matchers_).MatchAndExplain(
std::get<I>(tuple), &inner_listener[I])
? failed_pos = I
: 0 ...});
if (failed_pos != ~size_t{}) {
*listener << "whose field #" << failed_pos << " does not match";
PrintIfNotEmpty(inner_listener[failed_pos].str(), listener->stream());
return false;
}
*listener << "whose all elements match";
const char* separator = ", where";
for (size_t index = 0; index < sizeof...(I); ++index) {
const std::string str = inner_listener[index].str();
if (!str.empty()) {
*listener << separator << " field #" << index << " is a value " << str;
separator = ", and";
}
}
return true;
}
MatchersType matchers_;
};
template <typename... Inner>
class FieldsAreMatcher {
public:
explicit FieldsAreMatcher(Inner... inner) : matchers_(std::move(inner)...) {}
template <typename Struct>
operator Matcher<Struct>() const { // NOLINT
return Matcher<Struct>(
new FieldsAreMatcherImpl<const Struct&, IndexSequenceFor<Inner...>>(
matchers_));
}
private:
std::tuple<Inner...> matchers_;
}; };
// Implements ElementsAre() and ElementsAreArray(). // Implements ElementsAre() and ElementsAreArray().
template <typename Container> template <typename Container>
class ElementsAreMatcherImpl : public MatcherInterface<Container> { class ElementsAreMatcherImpl : public MatcherInterface<Container> {
public: public:
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
typedef internal::StlContainerView<RawContainer> View; typedef internal::StlContainerView<RawContainer> View;
typedef typename View::type StlContainer; typedef typename View::type StlContainer;
typedef typename View::const_reference StlContainerReference; typedef typename View::const_reference StlContainerReference;
skipping to change at line 2834 skipping to change at line 3315
} }
private: private:
static Message Elements(size_t count) { static Message Elements(size_t count) {
return Message() << count << (count == 1 ? " element" : " elements"); return Message() << count << (count == 1 ? " element" : " elements");
} }
size_t count() const { return matchers_.size(); } size_t count() const { return matchers_.size(); }
::std::vector<Matcher<const Element&> > matchers_; ::std::vector<Matcher<const Element&> > matchers_;
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcherImpl);
}; };
// Connectivity matrix of (elements X matchers), in element-major order. // Connectivity matrix of (elements X matchers), in element-major order.
// Initially, there are no edges. // Initially, there are no edges.
// Use NextGraph() to iterate over all possible edge configurations. // Use NextGraph() to iterate over all possible edge configurations.
// Use Randomize() to generate a random edge configuration. // Use Randomize() to generate a random edge configuration.
class GTEST_API_ MatchMatrix { class GTEST_API_ MatchMatrix {
public: public:
MatchMatrix(size_t num_elements, size_t num_matchers) MatchMatrix(size_t num_elements, size_t num_matchers)
: num_elements_(num_elements), : num_elements_(num_elements),
skipping to change at line 2938 skipping to change at line 3417
static Message Elements(size_t n) { static Message Elements(size_t n) {
return Message() << n << " element" << (n == 1 ? "" : "s"); return Message() << n << " element" << (n == 1 ? "" : "s");
} }
UnorderedMatcherRequire::Flags match_flags() const { return match_flags_; } UnorderedMatcherRequire::Flags match_flags() const { return match_flags_; }
private: private:
UnorderedMatcherRequire::Flags match_flags_; UnorderedMatcherRequire::Flags match_flags_;
MatcherDescriberVec matcher_describers_; MatcherDescriberVec matcher_describers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase);
}; };
// Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and // Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and
// IsSupersetOf. // IsSupersetOf.
template <typename Container> template <typename Container>
class UnorderedElementsAreMatcherImpl class UnorderedElementsAreMatcherImpl
: public MatcherInterface<Container>, : public MatcherInterface<Container>,
public UnorderedElementsAreMatcherImplBase { public UnorderedElementsAreMatcherImplBase {
public: public:
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
skipping to change at line 2962 skipping to change at line 3439
typedef typename View::const_reference StlContainerReference; typedef typename View::const_reference StlContainerReference;
typedef typename StlContainer::const_iterator StlContainerConstIterator; typedef typename StlContainer::const_iterator StlContainerConstIterator;
typedef typename StlContainer::value_type Element; typedef typename StlContainer::value_type Element;
template <typename InputIter> template <typename InputIter>
UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags, UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags,
InputIter first, InputIter last) InputIter first, InputIter last)
: UnorderedElementsAreMatcherImplBase(matcher_flags) { : UnorderedElementsAreMatcherImplBase(matcher_flags) {
for (; first != last; ++first) { for (; first != last; ++first) {
matchers_.push_back(MatcherCast<const Element&>(*first)); matchers_.push_back(MatcherCast<const Element&>(*first));
matcher_describers().push_back(matchers_.back().GetDescriber()); }
for (const auto& m : matchers_) {
matcher_describers().push_back(m.GetDescriber());
} }
} }
// Describes what this matcher does. // Describes what this matcher does.
void DescribeTo(::std::ostream* os) const override { void DescribeTo(::std::ostream* os) const override {
return UnorderedElementsAreMatcherImplBase::DescribeToImpl(os); return UnorderedElementsAreMatcherImplBase::DescribeToImpl(os);
} }
// Describes what the negation of this matcher does. // Describes what the negation of this matcher does.
void DescribeNegationTo(::std::ostream* os) const override { void DescribeNegationTo(::std::ostream* os) const override {
skipping to change at line 3013 skipping to change at line 3492
} }
private: private:
template <typename ElementIter> template <typename ElementIter>
MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last, MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last,
::std::vector<std::string>* element_printouts, ::std::vector<std::string>* element_printouts,
MatchResultListener* listener) const { MatchResultListener* listener) const {
element_printouts->clear(); element_printouts->clear();
::std::vector<char> did_match; ::std::vector<char> did_match;
size_t num_elements = 0; size_t num_elements = 0;
DummyMatchResultListener dummy;
for (; elem_first != elem_last; ++num_elements, ++elem_first) { for (; elem_first != elem_last; ++num_elements, ++elem_first) {
if (listener->IsInterested()) { if (listener->IsInterested()) {
element_printouts->push_back(PrintToString(*elem_first)); element_printouts->push_back(PrintToString(*elem_first));
} }
for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) { for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) {
did_match.push_back(Matches(matchers_[irhs])(*elem_first)); did_match.push_back(
matchers_[irhs].MatchAndExplain(*elem_first, &dummy));
} }
} }
MatchMatrix matrix(num_elements, matchers_.size()); MatchMatrix matrix(num_elements, matchers_.size());
::std::vector<char>::const_iterator did_match_iter = did_match.begin(); ::std::vector<char>::const_iterator did_match_iter = did_match.begin();
for (size_t ilhs = 0; ilhs != num_elements; ++ilhs) { for (size_t ilhs = 0; ilhs != num_elements; ++ilhs) {
for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) { for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) {
matrix.SetEdge(ilhs, irhs, *did_match_iter++ != 0); matrix.SetEdge(ilhs, irhs, *did_match_iter++ != 0);
} }
} }
return matrix; return matrix;
} }
::std::vector<Matcher<const Element&> > matchers_; ::std::vector<Matcher<const Element&> > matchers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl);
}; };
// Functor for use in TransformTuple. // Functor for use in TransformTuple.
// Performs MatcherCast<Target> on an input argument of any type. // Performs MatcherCast<Target> on an input argument of any type.
template <typename Target> template <typename Target>
struct CastAndAppendTransform { struct CastAndAppendTransform {
template <typename Arg> template <typename Arg>
Matcher<Target> operator()(const Arg& a) const { Matcher<Target> operator()(const Arg& a) const {
return MatcherCast<Target>(a); return MatcherCast<Target>(a);
} }
skipping to change at line 3072 skipping to change at line 3551
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
::std::back_inserter(matchers)); ::std::back_inserter(matchers));
return Matcher<Container>( return Matcher<Container>(
new UnorderedElementsAreMatcherImpl<const Container&>( new UnorderedElementsAreMatcherImpl<const Container&>(
UnorderedMatcherRequire::ExactMatch, matchers.begin(), UnorderedMatcherRequire::ExactMatch, matchers.begin(),
matchers.end())); matchers.end()));
} }
private: private:
const MatcherTuple matchers_; const MatcherTuple matchers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcher);
}; };
// Implements ElementsAre. // Implements ElementsAre.
template <typename MatcherTuple> template <typename MatcherTuple>
class ElementsAreMatcher { class ElementsAreMatcher {
public: public:
explicit ElementsAreMatcher(const MatcherTuple& args) : matchers_(args) {} explicit ElementsAreMatcher(const MatcherTuple& args) : matchers_(args) {}
template <typename Container> template <typename Container>
operator Matcher<Container>() const { operator Matcher<Container>() const {
skipping to change at line 3102 skipping to change at line 3580
MatcherVec matchers; MatcherVec matchers;
matchers.reserve(::std::tuple_size<MatcherTuple>::value); matchers.reserve(::std::tuple_size<MatcherTuple>::value);
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
::std::back_inserter(matchers)); ::std::back_inserter(matchers));
return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>( return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>(
matchers.begin(), matchers.end())); matchers.begin(), matchers.end()));
} }
private: private:
const MatcherTuple matchers_; const MatcherTuple matchers_;
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher);
}; };
// Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf(). // Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf().
template <typename T> template <typename T>
class UnorderedElementsAreArrayMatcher { class UnorderedElementsAreArrayMatcher {
public: public:
template <typename Iter> template <typename Iter>
UnorderedElementsAreArrayMatcher(UnorderedMatcherRequire::Flags match_flags, UnorderedElementsAreArrayMatcher(UnorderedMatcherRequire::Flags match_flags,
Iter first, Iter last) Iter first, Iter last)
: match_flags_(match_flags), matchers_(first, last) {} : match_flags_(match_flags), matchers_(first, last) {}
skipping to change at line 3124 skipping to change at line 3601
template <typename Container> template <typename Container>
operator Matcher<Container>() const { operator Matcher<Container>() const {
return Matcher<Container>( return Matcher<Container>(
new UnorderedElementsAreMatcherImpl<const Container&>( new UnorderedElementsAreMatcherImpl<const Container&>(
match_flags_, matchers_.begin(), matchers_.end())); match_flags_, matchers_.begin(), matchers_.end()));
} }
private: private:
UnorderedMatcherRequire::Flags match_flags_; UnorderedMatcherRequire::Flags match_flags_;
::std::vector<T> matchers_; ::std::vector<T> matchers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher);
}; };
// Implements ElementsAreArray(). // Implements ElementsAreArray().
template <typename T> template <typename T>
class ElementsAreArrayMatcher { class ElementsAreArrayMatcher {
public: public:
template <typename Iter> template <typename Iter>
ElementsAreArrayMatcher(Iter first, Iter last) : matchers_(first, last) {} ElementsAreArrayMatcher(Iter first, Iter last) : matchers_(first, last) {}
template <typename Container> template <typename Container>
skipping to change at line 3147 skipping to change at line 3622
GTEST_COMPILE_ASSERT_( GTEST_COMPILE_ASSERT_(
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value, !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value,
use_UnorderedElementsAreArray_with_hash_tables); use_UnorderedElementsAreArray_with_hash_tables);
return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>( return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>(
matchers_.begin(), matchers_.end())); matchers_.begin(), matchers_.end()));
} }
private: private:
const ::std::vector<T> matchers_; const ::std::vector<T> matchers_;
GTEST_DISALLOW_ASSIGN_(ElementsAreArrayMatcher);
}; };
// Given a 2-tuple matcher tm of type Tuple2Matcher and a value second // Given a 2-tuple matcher tm of type Tuple2Matcher and a value second
// of type Second, BoundSecondMatcher<Tuple2Matcher, Second>(tm, // of type Second, BoundSecondMatcher<Tuple2Matcher, Second>(tm,
// second) is a polymorphic matcher that matches a value x if and only if // second) is a polymorphic matcher that matches a value x if and only if
// tm matches tuple (x, second). Useful for implementing // tm matches tuple (x, second). Useful for implementing
// UnorderedPointwise() in terms of UnorderedElementsAreArray(). // UnorderedPointwise() in terms of UnorderedElementsAreArray().
// //
// BoundSecondMatcher is copyable and assignable, as we need to put // BoundSecondMatcher is copyable and assignable, as we need to put
// instances of this class in a vector when implementing // instances of this class in a vector when implementing
// UnorderedPointwise(). // UnorderedPointwise().
template <typename Tuple2Matcher, typename Second> template <typename Tuple2Matcher, typename Second>
class BoundSecondMatcher { class BoundSecondMatcher {
public: public:
BoundSecondMatcher(const Tuple2Matcher& tm, const Second& second) BoundSecondMatcher(const Tuple2Matcher& tm, const Second& second)
: tuple2_matcher_(tm), second_value_(second) {} : tuple2_matcher_(tm), second_value_(second) {}
BoundSecondMatcher(const BoundSecondMatcher& other) = default;
template <typename T> template <typename T>
operator Matcher<T>() const { operator Matcher<T>() const {
return MakeMatcher(new Impl<T>(tuple2_matcher_, second_value_)); return MakeMatcher(new Impl<T>(tuple2_matcher_, second_value_));
} }
// We have to define this for UnorderedPointwise() to compile in // We have to define this for UnorderedPointwise() to compile in
// C++98 mode, as it puts BoundSecondMatcher instances in a vector, // C++98 mode, as it puts BoundSecondMatcher instances in a vector,
// which requires the elements to be assignable in C++98. The // which requires the elements to be assignable in C++98. The
// compiler cannot generate the operator= for us, as Tuple2Matcher // compiler cannot generate the operator= for us, as Tuple2Matcher
// and Second may not be assignable. // and Second may not be assignable.
skipping to change at line 3208 skipping to change at line 3683
} }
bool MatchAndExplain(T x, MatchResultListener* listener) const override { bool MatchAndExplain(T x, MatchResultListener* listener) const override {
return mono_tuple2_matcher_.MatchAndExplain(ArgTuple(x, second_value_), return mono_tuple2_matcher_.MatchAndExplain(ArgTuple(x, second_value_),
listener); listener);
} }
private: private:
const Matcher<const ArgTuple&> mono_tuple2_matcher_; const Matcher<const ArgTuple&> mono_tuple2_matcher_;
const Second second_value_; const Second second_value_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; };
const Tuple2Matcher tuple2_matcher_; const Tuple2Matcher tuple2_matcher_;
const Second second_value_; const Second second_value_;
}; };
// Given a 2-tuple matcher tm and a value second, // Given a 2-tuple matcher tm and a value second,
// MatcherBindSecond(tm, second) returns a matcher that matches a // MatcherBindSecond(tm, second) returns a matcher that matches a
// value x if and only if tm matches tuple (x, second). Useful for // value x if and only if tm matches tuple (x, second). Useful for
// implementing UnorderedPointwise() in terms of UnorderedElementsAreArray(). // implementing UnorderedPointwise() in terms of UnorderedElementsAreArray().
skipping to change at line 3282 skipping to change at line 3755
StringMatchResultListener value_listener; StringMatchResultListener value_listener;
const bool match = value_matcher_.MatchAndExplain(value, &value_listener); const bool match = value_matcher_.MatchAndExplain(value, &value_listener);
*listener << "whose value " << PrintToString(value) *listener << "whose value " << PrintToString(value)
<< (match ? " matches" : " doesn't match"); << (match ? " matches" : " doesn't match");
PrintIfNotEmpty(value_listener.str(), listener->stream()); PrintIfNotEmpty(value_listener.str(), listener->stream());
return match; return match;
} }
private: private:
const Matcher<ValueType> value_matcher_; const Matcher<ValueType> value_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
}; };
private: private:
const ValueMatcher value_matcher_; const ValueMatcher value_matcher_;
GTEST_DISALLOW_ASSIGN_(OptionalMatcher);
}; };
namespace variant_matcher { namespace variant_matcher {
// Overloads to allow VariantMatcher to do proper ADL lookup. // Overloads to allow VariantMatcher to do proper ADL lookup.
template <typename T> template <typename T>
void holds_alternative() {} void holds_alternative() {}
template <typename T> template <typename T>
void get() {} void get() {}
// Implements a matcher that checks the value of a variant<> type variable. // Implements a matcher that checks the value of a variant<> type variable.
skipping to change at line 3595 skipping to change at line 4066
// //
// 1. The C++ standard permits using the name _ in a namespace that // 1. The C++ standard permits using the name _ in a namespace that
// is not the global namespace or ::std. // is not the global namespace or ::std.
// 2. The AnythingMatcher class has no data member or constructor, // 2. The AnythingMatcher class has no data member or constructor,
// so it's OK to create global variables of this type. // so it's OK to create global variables of this type.
// 3. c-style has approved of using _ in this case. // 3. c-style has approved of using _ in this case.
const internal::AnythingMatcher _ = {}; const internal::AnythingMatcher _ = {};
// Creates a matcher that matches any value of the given type T. // Creates a matcher that matches any value of the given type T.
template <typename T> template <typename T>
inline Matcher<T> A() { inline Matcher<T> A() {
return Matcher<T>(new internal::AnyMatcherImpl<T>()); return _;
} }
// Creates a matcher that matches any value of the given type T. // Creates a matcher that matches any value of the given type T.
template <typename T> template <typename T>
inline Matcher<T> An() { return A<T>(); } inline Matcher<T> An() {
return _;
}
template <typename T, typename M> template <typename T, typename M>
Matcher<T> internal::MatcherCastImpl<T, M>::CastImpl( Matcher<T> internal::MatcherCastImpl<T, M>::CastImpl(
const M& value, std::false_type /* convertible_to_matcher */, const M& value, std::false_type /* convertible_to_matcher */,
std::false_type /* convertible_to_T */) { std::false_type /* convertible_to_T */) {
return Eq(value); return Eq(value);
} }
// Creates a polymorphic matcher that matches any NULL pointer. // Creates a polymorphic matcher that matches any NULL pointer.
inline PolymorphicMatcher<internal::IsNullMatcher > IsNull() { inline PolymorphicMatcher<internal::IsNullMatcher > IsNull() {
skipping to change at line 3628 skipping to change at line 4101
return MakePolymorphicMatcher(internal::NotNullMatcher()); return MakePolymorphicMatcher(internal::NotNullMatcher());
} }
// Creates a polymorphic matcher that matches any argument that // Creates a polymorphic matcher that matches any argument that
// references variable x. // references variable x.
template <typename T> template <typename T>
inline internal::RefMatcher<T&> Ref(T& x) { // NOLINT inline internal::RefMatcher<T&> Ref(T& x) { // NOLINT
return internal::RefMatcher<T&>(x); return internal::RefMatcher<T&>(x);
} }
// Creates a polymorphic matcher that matches any NaN floating point.
inline PolymorphicMatcher<internal::IsNanMatcher> IsNan() {
return MakePolymorphicMatcher(internal::IsNanMatcher());
}
// Creates a matcher that matches any double argument approximately // Creates a matcher that matches any double argument approximately
// equal to rhs, where two NANs are considered unequal. // equal to rhs, where two NANs are considered unequal.
inline internal::FloatingEqMatcher<double> DoubleEq(double rhs) { inline internal::FloatingEqMatcher<double> DoubleEq(double rhs) {
return internal::FloatingEqMatcher<double>(rhs, false); return internal::FloatingEqMatcher<double>(rhs, false);
} }
// Creates a matcher that matches any double argument approximately // Creates a matcher that matches any double argument approximately
// equal to rhs, including NaN values when rhs is NaN. // equal to rhs, including NaN values when rhs is NaN.
inline internal::FloatingEqMatcher<double> NanSensitiveDoubleEq(double rhs) { inline internal::FloatingEqMatcher<double> NanSensitiveDoubleEq(double rhs) {
return internal::FloatingEqMatcher<double>(rhs, true); return internal::FloatingEqMatcher<double>(rhs, true);
skipping to change at line 3810 skipping to change at line 4288
template <typename Callable, typename InnerMatcher> template <typename Callable, typename InnerMatcher>
internal::ResultOfMatcher<Callable, InnerMatcher> ResultOf( internal::ResultOfMatcher<Callable, InnerMatcher> ResultOf(
Callable callable, InnerMatcher matcher) { Callable callable, InnerMatcher matcher) {
return internal::ResultOfMatcher<Callable, InnerMatcher>( return internal::ResultOfMatcher<Callable, InnerMatcher>(
std::move(callable), std::move(matcher)); std::move(callable), std::move(matcher));
} }
// String matchers. // String matchers.
// Matches a string equal to str. // Matches a string equal to str.
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrEq( template <typename T = std::string>
const std::string& str) { PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrEq(
const internal::StringLike<T>& str) {
return MakePolymorphicMatcher( return MakePolymorphicMatcher(
internal::StrEqualityMatcher<std::string>(str, true, true)); internal::StrEqualityMatcher<std::string>(std::string(str), true, true));
} }
// Matches a string not equal to str. // Matches a string not equal to str.
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrNe( template <typename T = std::string>
const std::string& str) { PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrNe(
const internal::StringLike<T>& str) {
return MakePolymorphicMatcher( return MakePolymorphicMatcher(
internal::StrEqualityMatcher<std::string>(str, false, true)); internal::StrEqualityMatcher<std::string>(std::string(str), false, true));
} }
// Matches a string equal to str, ignoring case. // Matches a string equal to str, ignoring case.
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseEq( template <typename T = std::string>
const std::string& str) { PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseEq(
const internal::StringLike<T>& str) {
return MakePolymorphicMatcher( return MakePolymorphicMatcher(
internal::StrEqualityMatcher<std::string>(str, true, false)); internal::StrEqualityMatcher<std::string>(std::string(str), true, false));
} }
// Matches a string not equal to str, ignoring case. // Matches a string not equal to str, ignoring case.
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseNe( template <typename T = std::string>
const std::string& str) { PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseNe(
return MakePolymorphicMatcher( const internal::StringLike<T>& str) {
internal::StrEqualityMatcher<std::string>(str, false, false)); return MakePolymorphicMatcher(internal::StrEqualityMatcher<std::string>(
std::string(str), false, false));
} }
// Creates a matcher that matches any string, std::string, or C string // Creates a matcher that matches any string, std::string, or C string
// that contains the given substring. // that contains the given substring.
inline PolymorphicMatcher<internal::HasSubstrMatcher<std::string> > HasSubstr( template <typename T = std::string>
const std::string& substring) { PolymorphicMatcher<internal::HasSubstrMatcher<std::string> > HasSubstr(
const internal::StringLike<T>& substring) {
return MakePolymorphicMatcher( return MakePolymorphicMatcher(
internal::HasSubstrMatcher<std::string>(substring)); internal::HasSubstrMatcher<std::string>(std::string(substring)));
} }
// Matches a string that starts with 'prefix' (case-sensitive). // Matches a string that starts with 'prefix' (case-sensitive).
inline PolymorphicMatcher<internal::StartsWithMatcher<std::string> > StartsWith( template <typename T = std::string>
const std::string& prefix) { PolymorphicMatcher<internal::StartsWithMatcher<std::string> > StartsWith(
const internal::StringLike<T>& prefix) {
return MakePolymorphicMatcher( return MakePolymorphicMatcher(
internal::StartsWithMatcher<std::string>(prefix)); internal::StartsWithMatcher<std::string>(std::string(prefix)));
} }
// Matches a string that ends with 'suffix' (case-sensitive). // Matches a string that ends with 'suffix' (case-sensitive).
inline PolymorphicMatcher<internal::EndsWithMatcher<std::string> > EndsWith( template <typename T = std::string>
const std::string& suffix) { PolymorphicMatcher<internal::EndsWithMatcher<std::string> > EndsWith(
return MakePolymorphicMatcher(internal::EndsWithMatcher<std::string>(suffix)); const internal::StringLike<T>& suffix) {
return MakePolymorphicMatcher(
internal::EndsWithMatcher<std::string>(std::string(suffix)));
} }
#if GTEST_HAS_STD_WSTRING #if GTEST_HAS_STD_WSTRING
// Wide string matchers. // Wide string matchers.
// Matches a string equal to str. // Matches a string equal to str.
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrEq( inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrEq(
const std::wstring& str) { const std::wstring& str) {
return MakePolymorphicMatcher( return MakePolymorphicMatcher(
internal::StrEqualityMatcher<std::wstring>(str, true, true)); internal::StrEqualityMatcher<std::wstring>(str, true, true));
skipping to change at line 4036 skipping to change at line 4522
} }
// Returns a matcher that matches an equal container. // Returns a matcher that matches an equal container.
// This matcher behaves like Eq(), but in the event of mismatch lists the // This matcher behaves like Eq(), but in the event of mismatch lists the
// values that are included in one container but not the other. (Duplicate // values that are included in one container but not the other. (Duplicate
// values and order differences are not explained.) // values and order differences are not explained.)
template <typename Container> template <typename Container>
inline PolymorphicMatcher<internal::ContainerEqMatcher< inline PolymorphicMatcher<internal::ContainerEqMatcher<
typename std::remove_const<Container>::type>> typename std::remove_const<Container>::type>>
ContainerEq(const Container& rhs) { ContainerEq(const Container& rhs) {
// This following line is for working around a bug in MSVC 8.0, return MakePolymorphicMatcher(internal::ContainerEqMatcher<Container>(rhs));
// which causes Container to be a const type sometimes.
typedef typename std::remove_const<Container>::type RawContainer;
return MakePolymorphicMatcher(
internal::ContainerEqMatcher<RawContainer>(rhs));
} }
// Returns a matcher that matches a container that, when sorted using // Returns a matcher that matches a container that, when sorted using
// the given comparator, matches container_matcher. // the given comparator, matches container_matcher.
template <typename Comparator, typename ContainerMatcher> template <typename Comparator, typename ContainerMatcher>
inline internal::WhenSortedByMatcher<Comparator, ContainerMatcher> inline internal::WhenSortedByMatcher<Comparator, ContainerMatcher>
WhenSortedBy(const Comparator& comparator, WhenSortedBy(const Comparator& comparator,
const ContainerMatcher& container_matcher) { const ContainerMatcher& container_matcher) {
return internal::WhenSortedByMatcher<Comparator, ContainerMatcher>( return internal::WhenSortedByMatcher<Comparator, ContainerMatcher>(
comparator, container_matcher); comparator, container_matcher);
skipping to change at line 4073 skipping to change at line 4555
// Matches an STL-style container or a native array that contains the // Matches an STL-style container or a native array that contains the
// same number of elements as in rhs, where its i-th element and rhs's // same number of elements as in rhs, where its i-th element and rhs's
// i-th element (as a pair) satisfy the given pair matcher, for all i. // i-th element (as a pair) satisfy the given pair matcher, for all i.
// TupleMatcher must be able to be safely cast to Matcher<std::tuple<const // TupleMatcher must be able to be safely cast to Matcher<std::tuple<const
// T1&, const T2&> >, where T1 and T2 are the types of elements in the // T1&, const T2&> >, where T1 and T2 are the types of elements in the
// LHS container and the RHS container respectively. // LHS container and the RHS container respectively.
template <typename TupleMatcher, typename Container> template <typename TupleMatcher, typename Container>
inline internal::PointwiseMatcher<TupleMatcher, inline internal::PointwiseMatcher<TupleMatcher,
typename std::remove_const<Container>::type> typename std::remove_const<Container>::type>
Pointwise(const TupleMatcher& tuple_matcher, const Container& rhs) { Pointwise(const TupleMatcher& tuple_matcher, const Container& rhs) {
// This following line is for working around a bug in MSVC 8.0, return internal::PointwiseMatcher<TupleMatcher, Container>(tuple_matcher,
// which causes Container to be a const type sometimes (e.g. when rhs);
// rhs is a const int[])..
typedef typename std::remove_const<Container>::type RawContainer;
return internal::PointwiseMatcher<TupleMatcher, RawContainer>(
tuple_matcher, rhs);
} }
// Supports the Pointwise(m, {a, b, c}) syntax. // Supports the Pointwise(m, {a, b, c}) syntax.
template <typename TupleMatcher, typename T> template <typename TupleMatcher, typename T>
inline internal::PointwiseMatcher<TupleMatcher, std::vector<T> > Pointwise( inline internal::PointwiseMatcher<TupleMatcher, std::vector<T> > Pointwise(
const TupleMatcher& tuple_matcher, std::initializer_list<T> rhs) { const TupleMatcher& tuple_matcher, std::initializer_list<T> rhs) {
return Pointwise(tuple_matcher, std::vector<T>(rhs)); return Pointwise(tuple_matcher, std::vector<T>(rhs));
} }
// UnorderedPointwise(pair_matcher, rhs) matches an STL-style // UnorderedPointwise(pair_matcher, rhs) matches an STL-style
skipping to change at line 4107 skipping to change at line 4585
// This is like Pointwise(pair_matcher, rhs), except that the element // This is like Pointwise(pair_matcher, rhs), except that the element
// order doesn't matter. // order doesn't matter.
template <typename Tuple2Matcher, typename RhsContainer> template <typename Tuple2Matcher, typename RhsContainer>
inline internal::UnorderedElementsAreArrayMatcher< inline internal::UnorderedElementsAreArrayMatcher<
typename internal::BoundSecondMatcher< typename internal::BoundSecondMatcher<
Tuple2Matcher, Tuple2Matcher,
typename internal::StlContainerView< typename internal::StlContainerView<
typename std::remove_const<RhsContainer>::type>::type::value_type>> typename std::remove_const<RhsContainer>::type>::type::value_type>>
UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
const RhsContainer& rhs_container) { const RhsContainer& rhs_container) {
// This following line is for working around a bug in MSVC 8.0,
// which causes RhsContainer to be a const type sometimes (e.g. when
// rhs_container is a const int[]).
typedef typename std::remove_const<RhsContainer>::type RawRhsContainer;
// RhsView allows the same code to handle RhsContainer being a // RhsView allows the same code to handle RhsContainer being a
// STL-style container and it being a native C-style array. // STL-style container and it being a native C-style array.
typedef typename internal::StlContainerView<RawRhsContainer> RhsView; typedef typename internal::StlContainerView<RhsContainer> RhsView;
typedef typename RhsView::type RhsStlContainer; typedef typename RhsView::type RhsStlContainer;
typedef typename RhsStlContainer::value_type Second; typedef typename RhsStlContainer::value_type Second;
const RhsStlContainer& rhs_stl_container = const RhsStlContainer& rhs_stl_container =
RhsView::ConstReference(rhs_container); RhsView::ConstReference(rhs_container);
// Create a matcher for each element in rhs_container. // Create a matcher for each element in rhs_container.
::std::vector<internal::BoundSecondMatcher<Tuple2Matcher, Second> > matchers; ::std::vector<internal::BoundSecondMatcher<Tuple2Matcher, Second> > matchers;
for (typename RhsStlContainer::const_iterator it = rhs_stl_container.begin(); for (typename RhsStlContainer::const_iterator it = rhs_stl_container.begin();
it != rhs_stl_container.end(); ++it) { it != rhs_stl_container.end(); ++it) {
matchers.push_back( matchers.push_back(
skipping to change at line 4334 skipping to change at line 4807
// example, EXPECT_THAT(map_type, ElementsAre(Pair(Ge(5), "foo"))) can be used // example, EXPECT_THAT(map_type, ElementsAre(Pair(Ge(5), "foo"))) can be used
// to match a std::map<int, string> that contains exactly one element whose key // to match a std::map<int, string> that contains exactly one element whose key
// is >= 5 and whose value equals "foo". // is >= 5 and whose value equals "foo".
template <typename FirstMatcher, typename SecondMatcher> template <typename FirstMatcher, typename SecondMatcher>
inline internal::PairMatcher<FirstMatcher, SecondMatcher> inline internal::PairMatcher<FirstMatcher, SecondMatcher>
Pair(FirstMatcher first_matcher, SecondMatcher second_matcher) { Pair(FirstMatcher first_matcher, SecondMatcher second_matcher) {
return internal::PairMatcher<FirstMatcher, SecondMatcher>( return internal::PairMatcher<FirstMatcher, SecondMatcher>(
first_matcher, second_matcher); first_matcher, second_matcher);
} }
namespace no_adl {
// FieldsAre(matchers...) matches piecewise the fields of compatible structs.
// These include those that support `get<I>(obj)`, and when structured bindings
// are enabled any class that supports them.
// In particular, `std::tuple`, `std::pair`, `std::array` and aggregate types.
template <typename... M>
internal::FieldsAreMatcher<typename std::decay<M>::type...> FieldsAre(
M&&... matchers) {
return internal::FieldsAreMatcher<typename std::decay<M>::type...>(
std::forward<M>(matchers)...);
}
// Creates a matcher that matches a pointer (raw or smart) that matches
// inner_matcher.
template <typename InnerMatcher>
inline internal::PointerMatcher<InnerMatcher> Pointer(
const InnerMatcher& inner_matcher) {
return internal::PointerMatcher<InnerMatcher>(inner_matcher);
}
// Creates a matcher that matches an object that has an address that matches
// inner_matcher.
template <typename InnerMatcher>
inline internal::AddressMatcher<InnerMatcher> Address(
const InnerMatcher& inner_matcher) {
return internal::AddressMatcher<InnerMatcher>(inner_matcher);
}
} // namespace no_adl
// Returns a predicate that is satisfied by anything that matches the // Returns a predicate that is satisfied by anything that matches the
// given matcher. // given matcher.
template <typename M> template <typename M>
inline internal::MatcherAsPredicate<M> Matches(M matcher) { inline internal::MatcherAsPredicate<M> Matches(M matcher) {
return internal::MatcherAsPredicate<M>(matcher); return internal::MatcherAsPredicate<M>(matcher);
} }
// Returns true if and only if the value matches the matcher. // Returns true if and only if the value matches the matcher.
template <typename T, typename M> template <typename T, typename M>
inline bool Value(const T& value, M matcher) { inline bool Value(const T& value, M matcher) {
skipping to change at line 4518 skipping to change at line 5020
// EXPECT_CALL(foo, Bar(_, _)).With(Eq()); // EXPECT_CALL(foo, Bar(_, _)).With(Eq());
template <typename InnerMatcher> template <typename InnerMatcher>
inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; } inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; }
// Returns a matcher that matches the value of an optional<> type variable. // Returns a matcher that matches the value of an optional<> type variable.
// The matcher implementation only uses '!arg' and requires that the optional<> // The matcher implementation only uses '!arg' and requires that the optional<>
// type has a 'value_type' member type and that '*arg' is of type 'value_type' // type has a 'value_type' member type and that '*arg' is of type 'value_type'
// and is printable using 'PrintToString'. It is compatible with // and is printable using 'PrintToString'. It is compatible with
// std::optional/std::experimental::optional. // std::optional/std::experimental::optional.
// Note that to compare an optional type variable against nullopt you should // Note that to compare an optional type variable against nullopt you should
// use Eq(nullopt) and not Optional(Eq(nullopt)). The latter implies that the // use Eq(nullopt) and not Eq(Optional(nullopt)). The latter implies that the
// optional value contains an optional itself. // optional value contains an optional itself.
template <typename ValueMatcher> template <typename ValueMatcher>
inline internal::OptionalMatcher<ValueMatcher> Optional( inline internal::OptionalMatcher<ValueMatcher> Optional(
const ValueMatcher& value_matcher) { const ValueMatcher& value_matcher) {
return internal::OptionalMatcher<ValueMatcher>(value_matcher); return internal::OptionalMatcher<ValueMatcher>(value_matcher);
} }
// Returns a matcher that matches the value of a absl::any type variable. // Returns a matcher that matches the value of a absl::any type variable.
template <typename T> template <typename T>
PolymorphicMatcher<internal::any_cast_matcher::AnyCastMatcher<T> > AnyWith( PolymorphicMatcher<internal::any_cast_matcher::AnyCastMatcher<T> > AnyWith(
skipping to change at line 4545 skipping to change at line 5047
// The matcher implementation uses ADL to find the holds_alternative and get // The matcher implementation uses ADL to find the holds_alternative and get
// functions. // functions.
// It is compatible with std::variant. // It is compatible with std::variant.
template <typename T> template <typename T>
PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith( PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith(
const Matcher<const T&>& matcher) { const Matcher<const T&>& matcher) {
return MakePolymorphicMatcher( return MakePolymorphicMatcher(
internal::variant_matcher::VariantMatcher<T>(matcher)); internal::variant_matcher::VariantMatcher<T>(matcher));
} }
#if GTEST_HAS_EXCEPTIONS
// Anything inside the `internal` namespace is internal to the implementation
// and must not be used in user code!
namespace internal {
class WithWhatMatcherImpl {
public:
WithWhatMatcherImpl(Matcher<std::string> matcher)
: matcher_(std::move(matcher)) {}
void DescribeTo(std::ostream* os) const {
*os << "contains .what() that ";
matcher_.DescribeTo(os);
}
void DescribeNegationTo(std::ostream* os) const {
*os << "contains .what() that does not ";
matcher_.DescribeTo(os);
}
template <typename Err>
bool MatchAndExplain(const Err& err, MatchResultListener* listener) const {
*listener << "which contains .what() that ";
return matcher_.MatchAndExplain(err.what(), listener);
}
private:
const Matcher<std::string> matcher_;
};
inline PolymorphicMatcher<WithWhatMatcherImpl> WithWhat(
Matcher<std::string> m) {
return MakePolymorphicMatcher(WithWhatMatcherImpl(std::move(m)));
}
template <typename Err>
class ExceptionMatcherImpl {
class NeverThrown {
public:
const char* what() const noexcept {
return "this exception should never be thrown";
}
};
// If the matchee raises an exception of a wrong type, we'd like to
// catch it and print its message and type. To do that, we add an additional
// catch clause:
//
// try { ... }
// catch (const Err&) { /* an expected exception */ }
// catch (const std::exception&) { /* exception of a wrong type */ }
//
// However, if the `Err` itself is `std::exception`, we'd end up with two
// identical `catch` clauses:
//
// try { ... }
// catch (const std::exception&) { /* an expected exception */ }
// catch (const std::exception&) { /* exception of a wrong type */ }
//
// This can cause a warning or an error in some compilers. To resolve
// the issue, we use a fake error type whenever `Err` is `std::exception`:
//
// try { ... }
// catch (const std::exception&) { /* an expected exception */ }
// catch (const NeverThrown&) { /* exception of a wrong type */ }
using DefaultExceptionType = typename std::conditional<
std::is_same<typename std::remove_cv<
typename std::remove_reference<Err>::type>::type,
std::exception>::value,
const NeverThrown&, const std::exception&>::type;
public:
ExceptionMatcherImpl(Matcher<const Err&> matcher)
: matcher_(std::move(matcher)) {}
void DescribeTo(std::ostream* os) const {
*os << "throws an exception which is a " << GetTypeName<Err>();
*os << " which ";
matcher_.DescribeTo(os);
}
void DescribeNegationTo(std::ostream* os) const {
*os << "throws an exception which is not a " << GetTypeName<Err>();
*os << " which ";
matcher_.DescribeNegationTo(os);
}
template <typename T>
bool MatchAndExplain(T&& x, MatchResultListener* listener) const {
try {
(void)(std::forward<T>(x)());
} catch (const Err& err) {
*listener << "throws an exception which is a " << GetTypeName<Err>();
*listener << " ";
return matcher_.MatchAndExplain(err, listener);
} catch (DefaultExceptionType err) {
#if GTEST_HAS_RTTI
*listener << "throws an exception of type " << GetTypeName(typeid(err));
*listener << " ";
#else
*listener << "throws an std::exception-derived type ";
#endif
*listener << "with description \"" << err.what() << "\"";
return false;
} catch (...) {
*listener << "throws an exception of an unknown type";
return false;
}
*listener << "does not throw any exception";
return false;
}
private:
const Matcher<const Err&> matcher_;
};
} // namespace internal
// Throws()
// Throws(exceptionMatcher)
// ThrowsMessage(messageMatcher)
//
// This matcher accepts a callable and verifies that when invoked, it throws
// an exception with the given type and properties.
//
// Examples:
//
// EXPECT_THAT(
// []() { throw std::runtime_error("message"); },
// Throws<std::runtime_error>());
//
// EXPECT_THAT(
// []() { throw std::runtime_error("message"); },
// ThrowsMessage<std::runtime_error>(HasSubstr("message")));
//
// EXPECT_THAT(
// []() { throw std::runtime_error("message"); },
// Throws<std::runtime_error>(
// Property(&std::runtime_error::what, HasSubstr("message"))));
template <typename Err>
PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> Throws() {
return MakePolymorphicMatcher(
internal::ExceptionMatcherImpl<Err>(A<const Err&>()));
}
template <typename Err, typename ExceptionMatcher>
PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> Throws(
const ExceptionMatcher& exception_matcher) {
// Using matcher cast allows users to pass a matcher of a more broad type.
// For example user may want to pass Matcher<std::exception>
// to Throws<std::runtime_error>, or Matcher<int64> to Throws<int32>.
return MakePolymorphicMatcher(internal::ExceptionMatcherImpl<Err>(
SafeMatcherCast<const Err&>(exception_matcher)));
}
template <typename Err, typename MessageMatcher>
PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(
MessageMatcher&& message_matcher) {
static_assert(std::is_base_of<std::exception, Err>::value,
"expected an std::exception-derived type");
return Throws<Err>(internal::WithWhat(
MatcherCast<std::string>(std::forward<MessageMatcher>(message_matcher))));
}
#endif // GTEST_HAS_EXCEPTIONS
// These macros allow using matchers to check values in Google Test // These macros allow using matchers to check values in Google Test
// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher) // tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)
// succeed if and only if the value matches the matcher. If the assertion // succeed if and only if the value matches the matcher. If the assertion
// fails, the value and the description of the matcher will be printed. // fails, the value and the description of the matcher will be printed.
#define ASSERT_THAT(value, matcher) ASSERT_PRED_FORMAT1(\ #define ASSERT_THAT(value, matcher) ASSERT_PRED_FORMAT1(\
::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
#define EXPECT_THAT(value, matcher) EXPECT_PRED_FORMAT1(\ #define EXPECT_THAT(value, matcher) EXPECT_PRED_FORMAT1(\
::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
// MATCHER* macroses itself are listed below.
#define MATCHER(name, description) \
class name##Matcher \
: public ::testing::internal::MatcherBaseImpl<name##Matcher> { \
public: \
template <typename arg_type> \
class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> { \
public: \
gmock_Impl() {} \
bool MatchAndExplain( \
const arg_type& arg, \
::testing::MatchResultListener* result_listener) const override; \
void DescribeTo(::std::ostream* gmock_os) const override { \
*gmock_os << FormatDescription(false); \
} \
void DescribeNegationTo(::std::ostream* gmock_os) const override { \
*gmock_os << FormatDescription(true); \
} \
\
private: \
::std::string FormatDescription(bool negation) const { \
::std::string gmock_description = (description); \
if (!gmock_description.empty()) { \
return gmock_description; \
} \
return ::testing::internal::FormatMatcherDescription(negation, #name, \
{}); \
} \
}; \
}; \
GTEST_ATTRIBUTE_UNUSED_ inline name##Matcher name() { return {}; } \
template <typename arg_type> \
bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain( \
const arg_type& arg, \
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_) \
const
#define MATCHER_P(name, p0, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP, description, (p0))
#define MATCHER_P2(name, p0, p1, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP2, description, (p0, p1))
#define MATCHER_P3(name, p0, p1, p2, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP3, description, (p0, p1, p2))
#define MATCHER_P4(name, p0, p1, p2, p3, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP4, description, (p0, p1, p2, p3))
#define MATCHER_P5(name, p0, p1, p2, p3, p4, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP5, description, \
(p0, p1, p2, p3, p4))
#define MATCHER_P6(name, p0, p1, p2, p3, p4, p5, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP6, description, \
(p0, p1, p2, p3, p4, p5))
#define MATCHER_P7(name, p0, p1, p2, p3, p4, p5, p6, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP7, description, \
(p0, p1, p2, p3, p4, p5, p6))
#define MATCHER_P8(name, p0, p1, p2, p3, p4, p5, p6, p7, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP8, description, \
(p0, p1, p2, p3, p4, p5, p6, p7))
#define MATCHER_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP9, description, \
(p0, p1, p2, p3, p4, p5, p6, p7, p8))
#define MATCHER_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, description) \
GMOCK_INTERNAL_MATCHER(name, name##MatcherP10, description, \
(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9))
#define GMOCK_INTERNAL_MATCHER(name, full_name, description, args) \
template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \
class full_name : public ::testing::internal::MatcherBaseImpl< \
full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>> { \
public: \
using full_name::MatcherBaseImpl::MatcherBaseImpl; \
template <typename arg_type> \
class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> { \
public: \
explicit gmock_Impl(GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args)) \
: GMOCK_INTERNAL_MATCHER_FORWARD_ARGS(args) {} \
bool MatchAndExplain( \
const arg_type& arg, \
::testing::MatchResultListener* result_listener) const override; \
void DescribeTo(::std::ostream* gmock_os) const override { \
*gmock_os << FormatDescription(false); \
} \
void DescribeNegationTo(::std::ostream* gmock_os) const override { \
*gmock_os << FormatDescription(true); \
} \
GMOCK_INTERNAL_MATCHER_MEMBERS(args) \
\
private: \
::std::string FormatDescription(bool negation) const { \
::std::string gmock_description = (description); \
if (!gmock_description.empty()) { \
return gmock_description; \
} \
return ::testing::internal::FormatMatcherDescription( \
negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings( \
::std::tuple<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>( \
GMOCK_INTERNAL_MATCHER_MEMBERS_USAGE(args)))); \
} \
}; \
}; \
template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \
inline full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)> name( \
GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args)) { \
return full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>( \
GMOCK_INTERNAL_MATCHER_ARGS_USAGE(args)); \
} \
template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \
template <typename arg_type> \
bool full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>::gmock_Impl< \
arg_type>::MatchAndExplain(const arg_type& arg, \
::testing::MatchResultListener* \
result_listener GTEST_ATTRIBUTE_UNUSED_) \
const
#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args) \
GMOCK_PP_TAIL( \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAM, , args))
#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAM(i_unused, data_unused, arg) \
, typename arg##_type
#define GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args) \
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_TYPE_PARAM, , args))
#define GMOCK_INTERNAL_MATCHER_TYPE_PARAM(i_unused, data_unused, arg) \
, arg##_type
#define GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args) \
GMOCK_PP_TAIL(dummy_first GMOCK_PP_FOR_EACH( \
GMOCK_INTERNAL_MATCHER_FUNCTION_ARG, , args))
#define GMOCK_INTERNAL_MATCHER_FUNCTION_ARG(i, data_unused, arg) \
, arg##_type gmock_p##i
#define GMOCK_INTERNAL_MATCHER_FORWARD_ARGS(args) \
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_FORWARD_ARG, , args))
#define GMOCK_INTERNAL_MATCHER_FORWARD_ARG(i, data_unused, arg) \
, arg(::std::forward<arg##_type>(gmock_p##i))
#define GMOCK_INTERNAL_MATCHER_MEMBERS(args) \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_MEMBER, , args)
#define GMOCK_INTERNAL_MATCHER_MEMBER(i_unused, data_unused, arg) \
const arg##_type arg;
#define GMOCK_INTERNAL_MATCHER_MEMBERS_USAGE(args) \
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_MEMBER_USAGE, , args))
#define GMOCK_INTERNAL_MATCHER_MEMBER_USAGE(i_unused, data_unused, arg) , arg
#define GMOCK_INTERNAL_MATCHER_ARGS_USAGE(args) \
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_ARG_USAGE, , args))
#define GMOCK_INTERNAL_MATCHER_ARG_USAGE(i, data_unused, arg_unused) \
, gmock_p##i
// To prevent ADL on certain functions we put them on a separate namespace.
using namespace no_adl; // NOLINT
} // namespace testing } // namespace testing
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046 GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046
// Include any custom callback matchers added by the local installation. // Include any custom callback matchers added by the local installation.
// We must include this header at the end to make sure it can use the // We must include this header at the end to make sure it can use the
// declarations from this file. // declarations from this file.
#include "gmock/internal/custom/gmock-matchers.h" #include "gmock/internal/custom/gmock-matchers.h"
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ #endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
 End of changes. 125 change blocks. 
247 lines changed or deleted 1071 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)