Reduced template instantiation depth for the AllOf and AnyOf matchers. Also some formatting changes.

This commit is contained in:
jgm 2012-04-10 16:02:11 +00:00
parent 9bcb5f9146
commit 79a367eb21
20 changed files with 659 additions and 334 deletions

View File

@ -36,13 +36,13 @@
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
#include <algorithm>
#include <string>
#ifndef _WIN32_WCE #ifndef _WIN32_WCE
# include <errno.h> # include <errno.h>
#endif #endif
#include <algorithm>
#include <string>
#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"
@ -189,6 +189,7 @@ class DefaultValue {
return value_ == NULL ? return value_ == NULL ?
internal::BuiltInDefaultValue<T>::Get() : *value_; internal::BuiltInDefaultValue<T>::Get() : *value_;
} }
private: private:
static const T* value_; static const T* value_;
}; };
@ -224,6 +225,7 @@ class DefaultValue<T&> {
return address_ == NULL ? return address_ == NULL ?
internal::BuiltInDefaultValue<T&>::Get() : *address_; internal::BuiltInDefaultValue<T&>::Get() : *address_;
} }
private: private:
static T* address_; static T* address_;
}; };

View File

@ -117,6 +117,7 @@ class GTEST_API_ Cardinality {
// Describes the given actual call count to an ostream. // Describes the given actual call count to an ostream.
static void DescribeActualCallCountTo(int actual_call_count, static void DescribeActualCallCountTo(int actual_call_count,
::std::ostream* os); ::std::ostream* os);
private: private:
internal::linked_ptr<const CardinalityInterface> impl_; internal::linked_ptr<const CardinalityInterface> impl_;
}; };

View File

@ -381,7 +381,6 @@ class CallableHelper {
A7 a7, A8 a8, A9 a9, A10 a10) { A7 a7, A8 a8, A9 a9, A10 a10) {
return function(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); return function(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
} }
}; // class CallableHelper }; // class CallableHelper
// An INTERNAL macro for extracting the type of a tuple field. It's // An INTERNAL macro for extracting the type of a tuple field. It's

View File

@ -136,7 +136,6 @@ $var Ts = [[$for j, [[T$j]]]]
} }
]] ]]
}; // class CallableHelper }; // class CallableHelper
// An INTERNAL macro for extracting the type of a tuple field. It's // An INTERNAL macro for extracting the type of a tuple field. It's

View File

@ -661,6 +661,182 @@ class ElementsAreMatcher10 {
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher10); GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher10);
}; };
// A set of metafunctions for computing the result type of AllOf.
// AllOf(m1, ..., mN) returns
// AllOfResultN<decltype(m1), ..., decltype(mN)>::type.
// Although AllOf isn't defined for one argument, AllOfResult1 is defined
// to simplify the implementation.
template <typename M1>
struct AllOfResult1 {
typedef M1 type;
};
template <typename M1, typename M2>
struct AllOfResult2 {
typedef BothOfMatcher<
typename AllOfResult1<M1>::type,
typename AllOfResult1<M2>::type
> type;
};
template <typename M1, typename M2, typename M3>
struct AllOfResult3 {
typedef BothOfMatcher<
typename AllOfResult1<M1>::type,
typename AllOfResult2<M2, M3>::type
> type;
};
template <typename M1, typename M2, typename M3, typename M4>
struct AllOfResult4 {
typedef BothOfMatcher<
typename AllOfResult2<M1, M2>::type,
typename AllOfResult2<M3, M4>::type
> type;
};
template <typename M1, typename M2, typename M3, typename M4, typename M5>
struct AllOfResult5 {
typedef BothOfMatcher<
typename AllOfResult2<M1, M2>::type,
typename AllOfResult3<M3, M4, M5>::type
> type;
};
template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename M6>
struct AllOfResult6 {
typedef BothOfMatcher<
typename AllOfResult3<M1, M2, M3>::type,
typename AllOfResult3<M4, M5, M6>::type
> type;
};
template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename M6, typename M7>
struct AllOfResult7 {
typedef BothOfMatcher<
typename AllOfResult3<M1, M2, M3>::type,
typename AllOfResult4<M4, M5, M6, M7>::type
> type;
};
template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename M6, typename M7, typename M8>
struct AllOfResult8 {
typedef BothOfMatcher<
typename AllOfResult4<M1, M2, M3, M4>::type,
typename AllOfResult4<M5, M6, M7, M8>::type
> type;
};
template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename M6, typename M7, typename M8, typename M9>
struct AllOfResult9 {
typedef BothOfMatcher<
typename AllOfResult4<M1, M2, M3, M4>::type,
typename AllOfResult5<M5, M6, M7, M8, M9>::type
> type;
};
template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename M6, typename M7, typename M8, typename M9, typename M10>
struct AllOfResult10 {
typedef BothOfMatcher<
typename AllOfResult5<M1, M2, M3, M4, M5>::type,
typename AllOfResult5<M6, M7, M8, M9, M10>::type
> type;
};
// A set of metafunctions for computing the result type of AnyOf.
// AnyOf(m1, ..., mN) returns
// AnyOfResultN<decltype(m1), ..., decltype(mN)>::type.
// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined
// to simplify the implementation.
template <typename M1>
struct AnyOfResult1 {
typedef M1 type;
};
template <typename M1, typename M2>
struct AnyOfResult2 {
typedef EitherOfMatcher<
typename AnyOfResult1<M1>::type,
typename AnyOfResult1<M2>::type
> type;
};
template <typename M1, typename M2, typename M3>
struct AnyOfResult3 {
typedef EitherOfMatcher<
typename AnyOfResult1<M1>::type,
typename AnyOfResult2<M2, M3>::type
> type;
};
template <typename M1, typename M2, typename M3, typename M4>
struct AnyOfResult4 {
typedef EitherOfMatcher<
typename AnyOfResult2<M1, M2>::type,
typename AnyOfResult2<M3, M4>::type
> type;
};
template <typename M1, typename M2, typename M3, typename M4, typename M5>
struct AnyOfResult5 {
typedef EitherOfMatcher<
typename AnyOfResult2<M1, M2>::type,
typename AnyOfResult3<M3, M4, M5>::type
> type;
};
template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename M6>
struct AnyOfResult6 {
typedef EitherOfMatcher<
typename AnyOfResult3<M1, M2, M3>::type,
typename AnyOfResult3<M4, M5, M6>::type
> type;
};
template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename M6, typename M7>
struct AnyOfResult7 {
typedef EitherOfMatcher<
typename AnyOfResult3<M1, M2, M3>::type,
typename AnyOfResult4<M4, M5, M6, M7>::type
> type;
};
template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename M6, typename M7, typename M8>
struct AnyOfResult8 {
typedef EitherOfMatcher<
typename AnyOfResult4<M1, M2, M3, M4>::type,
typename AnyOfResult4<M5, M6, M7, M8>::type
> type;
};
template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename M6, typename M7, typename M8, typename M9>
struct AnyOfResult9 {
typedef EitherOfMatcher<
typename AnyOfResult4<M1, M2, M3, M4>::type,
typename AnyOfResult5<M5, M6, M7, M8, M9>::type
> type;
};
template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename M6, typename M7, typename M8, typename M9, typename M10>
struct AnyOfResult10 {
typedef EitherOfMatcher<
typename AnyOfResult5<M1, M2, M3, M4, M5>::type,
typename AnyOfResult5<M6, M7, M8, M9, M10>::type
> type;
};
} // namespace internal } // namespace internal
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected // Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
@ -852,187 +1028,167 @@ ElementsAreArray(const T (&array)[N]) {
// AllOf(m1, m2, ..., mk) matches any value that matches all of the given // AllOf(m1, m2, ..., mk) matches any value that matches all of the given
// sub-matchers. AllOf is called fully qualified to prevent ADL from firing. // sub-matchers. AllOf is called fully qualified to prevent ADL from firing.
template <typename Matcher1, typename Matcher2> template <typename M1, typename M2>
inline internal::BothOfMatcher<Matcher1, Matcher2> inline typename internal::AllOfResult2<M1, M2>::type
AllOf(Matcher1 m1, Matcher2 m2) { AllOf(M1 m1, M2 m2) {
return internal::BothOfMatcher<Matcher1, Matcher2>(m1, m2); return typename internal::AllOfResult2<M1, M2>::type(
m1,
m2);
} }
template <typename Matcher1, typename Matcher2, typename Matcher3> template <typename M1, typename M2, typename M3>
inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2, inline typename internal::AllOfResult3<M1, M2, M3>::type
Matcher3> > AllOf(M1 m1, M2 m2, M3 m3) {
AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3) { return typename internal::AllOfResult3<M1, M2, M3>::type(
return ::testing::AllOf(m1, ::testing::AllOf(m2, m3)); m1,
::testing::AllOf(m2, m3));
} }
template <typename Matcher1, typename Matcher2, typename Matcher3, template <typename M1, typename M2, typename M3, typename M4>
typename Matcher4> inline typename internal::AllOfResult4<M1, M2, M3, M4>::type
inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2, AllOf(M1 m1, M2 m2, M3 m3, M4 m4) {
internal::BothOfMatcher<Matcher3, Matcher4> > > return typename internal::AllOfResult4<M1, M2, M3, M4>::type(
AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4) { ::testing::AllOf(m1, m2),
return ::testing::AllOf(m1, ::testing::AllOf(m2, m3, m4)); ::testing::AllOf(m3, m4));
} }
template <typename Matcher1, typename Matcher2, typename Matcher3, template <typename M1, typename M2, typename M3, typename M4, typename M5>
typename Matcher4, typename Matcher5> inline typename internal::AllOfResult5<M1, M2, M3, M4, M5>::type
inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2, AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5) {
internal::BothOfMatcher<Matcher3, internal::BothOfMatcher<Matcher4, return typename internal::AllOfResult5<M1, M2, M3, M4, M5>::type(
Matcher5> > > > ::testing::AllOf(m1, m2),
AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5) { ::testing::AllOf(m3, m4, m5));
return ::testing::AllOf(m1, ::testing::AllOf(m2, m3, m4, m5));
} }
template <typename Matcher1, typename Matcher2, typename Matcher3, template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename Matcher4, typename Matcher5, typename Matcher6> typename M6>
inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2, inline typename internal::AllOfResult6<M1, M2, M3, M4, M5, M6>::type
internal::BothOfMatcher<Matcher3, internal::BothOfMatcher<Matcher4, AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6) {
internal::BothOfMatcher<Matcher5, Matcher6> > > > > return typename internal::AllOfResult6<M1, M2, M3, M4, M5, M6>::type(
AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5, ::testing::AllOf(m1, m2, m3),
Matcher6 m6) { ::testing::AllOf(m4, m5, m6));
return ::testing::AllOf(m1, ::testing::AllOf(m2, m3, m4, m5, m6));
} }
template <typename Matcher1, typename Matcher2, typename Matcher3, template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename Matcher4, typename Matcher5, typename Matcher6, typename Matcher7> typename M6, typename M7>
inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2, inline typename internal::AllOfResult7<M1, M2, M3, M4, M5, M6, M7>::type
internal::BothOfMatcher<Matcher3, internal::BothOfMatcher<Matcher4, AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7) {
internal::BothOfMatcher<Matcher5, internal::BothOfMatcher<Matcher6, return typename internal::AllOfResult7<M1, M2, M3, M4, M5, M6, M7>::type(
Matcher7> > > > > > ::testing::AllOf(m1, m2, m3),
AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5, ::testing::AllOf(m4, m5, m6, m7));
Matcher6 m6, Matcher7 m7) {
return ::testing::AllOf(m1, ::testing::AllOf(m2, m3, m4, m5, m6, m7));
} }
template <typename Matcher1, typename Matcher2, typename Matcher3, template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename Matcher4, typename Matcher5, typename Matcher6, typename Matcher7, typename M6, typename M7, typename M8>
typename Matcher8> inline typename internal::AllOfResult8<M1, M2, M3, M4, M5, M6, M7, M8>::type
inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2, AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8) {
internal::BothOfMatcher<Matcher3, internal::BothOfMatcher<Matcher4, return typename internal::AllOfResult8<M1, M2, M3, M4, M5, M6, M7, M8>::type(
internal::BothOfMatcher<Matcher5, internal::BothOfMatcher<Matcher6, ::testing::AllOf(m1, m2, m3, m4),
internal::BothOfMatcher<Matcher7, Matcher8> > > > > > > ::testing::AllOf(m5, m6, m7, m8));
AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5,
Matcher6 m6, Matcher7 m7, Matcher8 m8) {
return ::testing::AllOf(m1, ::testing::AllOf(m2, m3, m4, m5, m6, m7, m8));
} }
template <typename Matcher1, typename Matcher2, typename Matcher3, template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename Matcher4, typename Matcher5, typename Matcher6, typename Matcher7, typename M6, typename M7, typename M8, typename M9>
typename Matcher8, typename Matcher9> inline typename internal::AllOfResult9<M1, M2, M3, M4, M5, M6, M7, M8, M9>::type
inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2, AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9) {
internal::BothOfMatcher<Matcher3, internal::BothOfMatcher<Matcher4, return typename internal::AllOfResult9<M1, M2, M3, M4, M5, M6, M7, M8,
internal::BothOfMatcher<Matcher5, internal::BothOfMatcher<Matcher6, M9>::type(
internal::BothOfMatcher<Matcher7, internal::BothOfMatcher<Matcher8, ::testing::AllOf(m1, m2, m3, m4),
Matcher9> > > > > > > > ::testing::AllOf(m5, m6, m7, m8, m9));
AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5,
Matcher6 m6, Matcher7 m7, Matcher8 m8, Matcher9 m9) {
return ::testing::AllOf(m1, ::testing::AllOf(m2, m3, m4, m5, m6, m7, m8, m9));
} }
template <typename Matcher1, typename Matcher2, typename Matcher3, template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename Matcher4, typename Matcher5, typename Matcher6, typename Matcher7, typename M6, typename M7, typename M8, typename M9, typename M10>
typename Matcher8, typename Matcher9, typename Matcher10> inline typename internal::AllOfResult10<M1, M2, M3, M4, M5, M6, M7, M8, M9,
inline internal::BothOfMatcher<Matcher1, internal::BothOfMatcher<Matcher2, M10>::type
internal::BothOfMatcher<Matcher3, internal::BothOfMatcher<Matcher4, AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) {
internal::BothOfMatcher<Matcher5, internal::BothOfMatcher<Matcher6, return typename internal::AllOfResult10<M1, M2, M3, M4, M5, M6, M7, M8, M9,
internal::BothOfMatcher<Matcher7, internal::BothOfMatcher<Matcher8, M10>::type(
internal::BothOfMatcher<Matcher9, Matcher10> > > > > > > > > ::testing::AllOf(m1, m2, m3, m4, m5),
AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5, ::testing::AllOf(m6, m7, m8, m9, m10));
Matcher6 m6, Matcher7 m7, Matcher8 m8, Matcher9 m9, Matcher10 m10) {
return ::testing::AllOf(m1, ::testing::AllOf(m2, m3, m4, m5, m6, m7, m8, m9,
m10));
} }
// AnyOf(m1, m2, ..., mk) matches any value that matches any of the given // AnyOf(m1, m2, ..., mk) matches any value that matches any of the given
// sub-matchers. AnyOf is called fully qualified to prevent ADL from firing. // sub-matchers. AnyOf is called fully qualified to prevent ADL from firing.
template <typename Matcher1, typename Matcher2> template <typename M1, typename M2>
inline internal::EitherOfMatcher<Matcher1, Matcher2> inline typename internal::AnyOfResult2<M1, M2>::type
AnyOf(Matcher1 m1, Matcher2 m2) { AnyOf(M1 m1, M2 m2) {
return internal::EitherOfMatcher<Matcher1, Matcher2>(m1, m2); return typename internal::AnyOfResult2<M1, M2>::type(
m1,
m2);
} }
template <typename Matcher1, typename Matcher2, typename Matcher3> template <typename M1, typename M2, typename M3>
inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2, inline typename internal::AnyOfResult3<M1, M2, M3>::type
Matcher3> > AnyOf(M1 m1, M2 m2, M3 m3) {
AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3) { return typename internal::AnyOfResult3<M1, M2, M3>::type(
return ::testing::AnyOf(m1, ::testing::AnyOf(m2, m3)); m1,
::testing::AnyOf(m2, m3));
} }
template <typename Matcher1, typename Matcher2, typename Matcher3, template <typename M1, typename M2, typename M3, typename M4>
typename Matcher4> inline typename internal::AnyOfResult4<M1, M2, M3, M4>::type
inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2, AnyOf(M1 m1, M2 m2, M3 m3, M4 m4) {
internal::EitherOfMatcher<Matcher3, Matcher4> > > return typename internal::AnyOfResult4<M1, M2, M3, M4>::type(
AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4) { ::testing::AnyOf(m1, m2),
return ::testing::AnyOf(m1, ::testing::AnyOf(m2, m3, m4)); ::testing::AnyOf(m3, m4));
} }
template <typename Matcher1, typename Matcher2, typename Matcher3, template <typename M1, typename M2, typename M3, typename M4, typename M5>
typename Matcher4, typename Matcher5> inline typename internal::AnyOfResult5<M1, M2, M3, M4, M5>::type
inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2, AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5) {
internal::EitherOfMatcher<Matcher3, internal::EitherOfMatcher<Matcher4, return typename internal::AnyOfResult5<M1, M2, M3, M4, M5>::type(
Matcher5> > > > ::testing::AnyOf(m1, m2),
AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5) { ::testing::AnyOf(m3, m4, m5));
return ::testing::AnyOf(m1, ::testing::AnyOf(m2, m3, m4, m5));
} }
template <typename Matcher1, typename Matcher2, typename Matcher3, template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename Matcher4, typename Matcher5, typename Matcher6> typename M6>
inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2, inline typename internal::AnyOfResult6<M1, M2, M3, M4, M5, M6>::type
internal::EitherOfMatcher<Matcher3, internal::EitherOfMatcher<Matcher4, AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6) {
internal::EitherOfMatcher<Matcher5, Matcher6> > > > > return typename internal::AnyOfResult6<M1, M2, M3, M4, M5, M6>::type(
AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5, ::testing::AnyOf(m1, m2, m3),
Matcher6 m6) { ::testing::AnyOf(m4, m5, m6));
return ::testing::AnyOf(m1, ::testing::AnyOf(m2, m3, m4, m5, m6));
} }
template <typename Matcher1, typename Matcher2, typename Matcher3, template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename Matcher4, typename Matcher5, typename Matcher6, typename Matcher7> typename M6, typename M7>
inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2, inline typename internal::AnyOfResult7<M1, M2, M3, M4, M5, M6, M7>::type
internal::EitherOfMatcher<Matcher3, internal::EitherOfMatcher<Matcher4, AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7) {
internal::EitherOfMatcher<Matcher5, internal::EitherOfMatcher<Matcher6, return typename internal::AnyOfResult7<M1, M2, M3, M4, M5, M6, M7>::type(
Matcher7> > > > > > ::testing::AnyOf(m1, m2, m3),
AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5, ::testing::AnyOf(m4, m5, m6, m7));
Matcher6 m6, Matcher7 m7) {
return ::testing::AnyOf(m1, ::testing::AnyOf(m2, m3, m4, m5, m6, m7));
} }
template <typename Matcher1, typename Matcher2, typename Matcher3, template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename Matcher4, typename Matcher5, typename Matcher6, typename Matcher7, typename M6, typename M7, typename M8>
typename Matcher8> inline typename internal::AnyOfResult8<M1, M2, M3, M4, M5, M6, M7, M8>::type
inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2, AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8) {
internal::EitherOfMatcher<Matcher3, internal::EitherOfMatcher<Matcher4, return typename internal::AnyOfResult8<M1, M2, M3, M4, M5, M6, M7, M8>::type(
internal::EitherOfMatcher<Matcher5, internal::EitherOfMatcher<Matcher6, ::testing::AnyOf(m1, m2, m3, m4),
internal::EitherOfMatcher<Matcher7, Matcher8> > > > > > > ::testing::AnyOf(m5, m6, m7, m8));
AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5,
Matcher6 m6, Matcher7 m7, Matcher8 m8) {
return ::testing::AnyOf(m1, ::testing::AnyOf(m2, m3, m4, m5, m6, m7, m8));
} }
template <typename Matcher1, typename Matcher2, typename Matcher3, template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename Matcher4, typename Matcher5, typename Matcher6, typename Matcher7, typename M6, typename M7, typename M8, typename M9>
typename Matcher8, typename Matcher9> inline typename internal::AnyOfResult9<M1, M2, M3, M4, M5, M6, M7, M8, M9>::type
inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2, AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9) {
internal::EitherOfMatcher<Matcher3, internal::EitherOfMatcher<Matcher4, return typename internal::AnyOfResult9<M1, M2, M3, M4, M5, M6, M7, M8,
internal::EitherOfMatcher<Matcher5, internal::EitherOfMatcher<Matcher6, M9>::type(
internal::EitherOfMatcher<Matcher7, internal::EitherOfMatcher<Matcher8, ::testing::AnyOf(m1, m2, m3, m4),
Matcher9> > > > > > > > ::testing::AnyOf(m5, m6, m7, m8, m9));
AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5,
Matcher6 m6, Matcher7 m7, Matcher8 m8, Matcher9 m9) {
return ::testing::AnyOf(m1, ::testing::AnyOf(m2, m3, m4, m5, m6, m7, m8, m9));
} }
template <typename Matcher1, typename Matcher2, typename Matcher3, template <typename M1, typename M2, typename M3, typename M4, typename M5,
typename Matcher4, typename Matcher5, typename Matcher6, typename Matcher7, typename M6, typename M7, typename M8, typename M9, typename M10>
typename Matcher8, typename Matcher9, typename Matcher10> inline typename internal::AnyOfResult10<M1, M2, M3, M4, M5, M6, M7, M8, M9,
inline internal::EitherOfMatcher<Matcher1, internal::EitherOfMatcher<Matcher2, M10>::type
internal::EitherOfMatcher<Matcher3, internal::EitherOfMatcher<Matcher4, AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) {
internal::EitherOfMatcher<Matcher5, internal::EitherOfMatcher<Matcher6, return typename internal::AnyOfResult10<M1, M2, M3, M4, M5, M6, M7, M8, M9,
internal::EitherOfMatcher<Matcher7, internal::EitherOfMatcher<Matcher8, M10>::type(
internal::EitherOfMatcher<Matcher9, Matcher10> > > > > > > > > ::testing::AnyOf(m1, m2, m3, m4, m5),
AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5, ::testing::AnyOf(m6, m7, m8, m9, m10));
Matcher6 m6, Matcher7 m7, Matcher8 m8, Matcher9 m9, Matcher10 m10) {
return ::testing::AnyOf(m1, ::testing::AnyOf(m2, m3, m4, m5, m6, m7, m8, m9,
m10));
} }
} // namespace testing } // namespace testing

View File

@ -242,6 +242,66 @@ $for j [[
]] ]]
// A set of metafunctions for computing the result type of AllOf.
// AllOf(m1, ..., mN) returns
// AllOfResultN<decltype(m1), ..., decltype(mN)>::type.
// Although AllOf isn't defined for one argument, AllOfResult1 is defined
// to simplify the implementation.
template <typename M1>
struct AllOfResult1 {
typedef M1 type;
};
$range i 1..n
$range i 2..n
$for i [[
$range j 2..i
$var m = i/2
$range k 1..m
$range t m+1..i
template <typename M1$for j [[, typename M$j]]>
struct AllOfResult$i {
typedef BothOfMatcher<
typename AllOfResult$m<$for k, [[M$k]]>::type,
typename AllOfResult$(i-m)<$for t, [[M$t]]>::type
> type;
};
]]
// A set of metafunctions for computing the result type of AnyOf.
// AnyOf(m1, ..., mN) returns
// AnyOfResultN<decltype(m1), ..., decltype(mN)>::type.
// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined
// to simplify the implementation.
template <typename M1>
struct AnyOfResult1 {
typedef M1 type;
};
$range i 1..n
$range i 2..n
$for i [[
$range j 2..i
$var m = i/2
$range k 1..m
$range t m+1..i
template <typename M1$for j [[, typename M$j]]>
struct AnyOfResult$i {
typedef EitherOfMatcher<
typename AnyOfResult$m<$for k, [[M$k]]>::type,
typename AnyOfResult$(i-m)<$for t, [[M$t]]>::type
> type;
};
]]
} // namespace internal } // namespace internal
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected // Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
@ -308,19 +368,16 @@ ElementsAreArray(const T (&array)[N]) {
$range i 2..n $range i 2..n
$for i [[ $for i [[
$range j 1..i $range j 1..i
$range k 1..i-1 $var m = i/2
$range k 1..m
template <$for j, [[typename Matcher$j]]> $range t m+1..i
inline $for k[[internal::BothOfMatcher<Matcher$k, ]]Matcher$i[[]]$for k [[> ]]
AllOf($for j, [[Matcher$j m$j]]) {
$if i == 2 [[
return internal::BothOfMatcher<Matcher1, Matcher2>(m1, m2);
]] $else [[
return ::testing::AllOf(m1, ::testing::AllOf($for k, [[m$(k + 1)]]));
]]
template <$for j, [[typename M$j]]>
inline typename internal::AllOfResult$i<$for j, [[M$j]]>::type
AllOf($for j, [[M$j m$j]]) {
return typename internal::AllOfResult$i<$for j, [[M$j]]>::type(
$if m == 1 [[m1]] $else [[::testing::AllOf($for k, [[m$k]])]],
$if m+1 == i [[m$i]] $else [[::testing::AllOf($for t, [[m$t]])]]);
} }
]] ]]
@ -331,19 +388,16 @@ $if i == 2 [[
$range i 2..n $range i 2..n
$for i [[ $for i [[
$range j 1..i $range j 1..i
$range k 1..i-1 $var m = i/2
$range k 1..m
template <$for j, [[typename Matcher$j]]> $range t m+1..i
inline $for k[[internal::EitherOfMatcher<Matcher$k, ]]Matcher$i[[]]$for k [[> ]]
AnyOf($for j, [[Matcher$j m$j]]) {
$if i == 2 [[
return internal::EitherOfMatcher<Matcher1, Matcher2>(m1, m2);
]] $else [[
return ::testing::AnyOf(m1, ::testing::AnyOf($for k, [[m$(k + 1)]]));
]]
template <$for j, [[typename M$j]]>
inline typename internal::AnyOfResult$i<$for j, [[M$j]]>::type
AnyOf($for j, [[M$j m$j]]) {
return typename internal::AnyOfResult$i<$for j, [[M$j]]>::type(
$if m == 1 [[m1]] $else [[::testing::AnyOf($for k, [[m$k]])]],
$if m+1 == i [[m$i]] $else [[::testing::AnyOf($for t, [[m$t]])]]);
} }
]] ]]

View File

@ -384,12 +384,119 @@ inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {
return PolymorphicMatcher<Impl>(impl); return PolymorphicMatcher<Impl>(impl);
} }
// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
// and MUST NOT BE USED IN USER CODE!!!
namespace internal {
// The MatcherCastImpl class template is a helper for implementing
// MatcherCast(). We need this helper in order to partially
// specialize the implementation of MatcherCast() (C++ allows
// class/struct templates to be partially specialized, but not
// function templates.).
// This general version is used when MatcherCast()'s argument is a
// polymorphic matcher (i.e. something that can be converted to a
// Matcher but is not one yet; for example, Eq(value)) or a value (for
// example, "hello").
template <typename T, typename M>
class MatcherCastImpl {
public:
static Matcher<T> Cast(M polymorphic_matcher_or_value) {
// M can be a polymorhic matcher, in which case we want to use
// its conversion operator to create Matcher<T>. Or it can be a value
// that should be passed to the Matcher<T>'s constructor.
//
// 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
// constructor from M (this usually happens when T has an implicit
// constructor from any type).
//
// It won't work to unconditionally implict_cast
// 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 value).
return CastImpl(
polymorphic_matcher_or_value,
BooleanConstant<
internal::ImplicitlyConvertible<M, Matcher<T> >::value>());
}
private:
static Matcher<T> CastImpl(M value, BooleanConstant<false>) {
// M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic
// matcher. It must be a value then. Use direct initialization to create
// a matcher.
return Matcher<T>(ImplicitCast_<T>(value));
}
static Matcher<T> CastImpl(M polymorphic_matcher_or_value,
BooleanConstant<true>) {
// M is implicitly convertible to Matcher<T>, which means that either
// M is a polymorhpic matcher or Matcher<T> has an implicit constructor
// from M. In both cases using the implicit conversion will produce a
// matcher.
//
// 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
// (first to create T from M and then to create Matcher<T> from T).
return polymorphic_matcher_or_value;
}
};
// This more specialized version is used when MatcherCast()'s argument
// is already a Matcher. This only compiles when type T can be
// statically converted to type U.
template <typename T, typename U>
class MatcherCastImpl<T, Matcher<U> > {
public:
static Matcher<T> Cast(const Matcher<U>& source_matcher) {
return Matcher<T>(new Impl(source_matcher));
}
private:
class Impl : public MatcherInterface<T> {
public:
explicit Impl(const Matcher<U>& source_matcher)
: source_matcher_(source_matcher) {}
// We delegate the matching logic to the source matcher.
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
return source_matcher_.MatchAndExplain(static_cast<U>(x), listener);
}
virtual void DescribeTo(::std::ostream* os) const {
source_matcher_.DescribeTo(os);
}
virtual void DescribeNegationTo(::std::ostream* os) const {
source_matcher_.DescribeNegationTo(os);
}
private:
const Matcher<U> source_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
};
// This even more specialized version is used for efficiently casting
// a matcher to its own type.
template <typename T>
class MatcherCastImpl<T, Matcher<T> > {
public:
static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; }
};
} // 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>
Matcher<T> MatcherCast(M m); inline Matcher<T> MatcherCast(M matcher) {
return internal::MatcherCastImpl<T, M>::Cast(matcher);
}
// Implements SafeMatcherCast(). // Implements SafeMatcherCast().
// //
@ -401,11 +508,11 @@ Matcher<T> MatcherCast(M m);
template <typename T> template <typename T>
class SafeMatcherCastImpl { class SafeMatcherCastImpl {
public: public:
// This overload handles polymorphic matchers only since monomorphic // This overload handles polymorphic matchers and values only since
// matchers are handled by the next one. // monomorphic matchers are handled by the next one.
template <typename M> template <typename M>
static inline Matcher<T> Cast(M polymorphic_matcher) { static inline Matcher<T> Cast(M polymorphic_matcher_or_value) {
return Matcher<T>(polymorphic_matcher); return internal::MatcherCastImpl<T, M>::Cast(polymorphic_matcher_or_value);
} }
// This overload handles monomorphic matchers. // This overload handles monomorphic matchers.
@ -600,67 +707,6 @@ void ExplainMatchFailureTupleTo(const MatcherTuple& matchers,
matchers, values, os); matchers, values, os);
} }
// The MatcherCastImpl class template is a helper for implementing
// MatcherCast(). We need this helper in order to partially
// specialize the implementation of MatcherCast() (C++ allows
// class/struct templates to be partially specialized, but not
// function templates.).
// This general version is used when MatcherCast()'s argument is a
// polymorphic matcher (i.e. something that can be converted to a
// Matcher but is not one yet; for example, Eq(value)).
template <typename T, typename M>
class MatcherCastImpl {
public:
static Matcher<T> Cast(M polymorphic_matcher) {
return Matcher<T>(polymorphic_matcher);
}
};
// This more specialized version is used when MatcherCast()'s argument
// is already a Matcher. This only compiles when type T can be
// statically converted to type U.
template <typename T, typename U>
class MatcherCastImpl<T, Matcher<U> > {
public:
static Matcher<T> Cast(const Matcher<U>& source_matcher) {
return Matcher<T>(new Impl(source_matcher));
}
private:
class Impl : public MatcherInterface<T> {
public:
explicit Impl(const Matcher<U>& source_matcher)
: source_matcher_(source_matcher) {}
// We delegate the matching logic to the source matcher.
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
return source_matcher_.MatchAndExplain(static_cast<U>(x), listener);
}
virtual void DescribeTo(::std::ostream* os) const {
source_matcher_.DescribeTo(os);
}
virtual void DescribeNegationTo(::std::ostream* os) const {
source_matcher_.DescribeNegationTo(os);
}
private:
const Matcher<U> source_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
};
// This even more specialized version is used for efficiently casting
// a matcher to its own type.
template <typename T>
class MatcherCastImpl<T, Matcher<T> > {
public:
static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; }
};
// Implements A<T>(). // Implements A<T>().
template <typename T> template <typename T>
class AnyMatcherImpl : public MatcherInterface<T> { class AnyMatcherImpl : public MatcherInterface<T> {
@ -1596,6 +1642,7 @@ class FloatingEqMatcher {
operator Matcher<FloatType&>() const { operator Matcher<FloatType&>() const {
return MakeMatcher(new Impl<FloatType&>(rhs_, nan_eq_nan_)); return MakeMatcher(new Impl<FloatType&>(rhs_, nan_eq_nan_));
} }
private: private:
const FloatType rhs_; const FloatType rhs_;
const bool nan_eq_nan_; const bool nan_eq_nan_;
@ -2633,12 +2680,6 @@ GTEST_API_ string FormatMatcherDescription(bool negation,
} // namespace internal } // namespace internal
// Implements MatcherCast().
template <typename T, typename M>
inline Matcher<T> MatcherCast(M matcher) {
return internal::MatcherCastImpl<T, M>::Cast(matcher);
}
// _ is a matcher that matches anything of any type. // _ is a matcher that matches anything of any type.
// //
// This definition is fine as: // This definition is fine as:

View File

@ -384,6 +384,7 @@ class GTEST_API_ Mock {
// verification was successful. // verification was successful.
static bool VerifyAndClear(void* mock_obj) static bool VerifyAndClear(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
private: private:
friend class internal::UntypedFunctionMockerBase; friend class internal::UntypedFunctionMockerBase;

View File

@ -1,4 +1,6 @@
// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! // This file was GENERATED by command:
// pump.py gmock-generated-internal-utils.h.pump
// DO NOT EDIT BY HAND!!!
// Copyright 2007, Google Inc. // Copyright 2007, Google Inc.
// All rights reserved. // All rights reserved.
@ -58,7 +60,7 @@ class IgnoredValue {
// deliberately omit the 'explicit' keyword in order to allow the // deliberately omit the 'explicit' keyword in order to allow the
// conversion to be implicit. // conversion to be implicit.
template <typename T> template <typename T>
IgnoredValue(const T&) {} IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
}; };
// MatcherTuple<T>::type is a tuple type where each field is a Matcher // MatcherTuple<T>::type is a tuple type where each field is a Matcher

View File

@ -61,7 +61,7 @@ class IgnoredValue {
// deliberately omit the 'explicit' keyword in order to allow the // deliberately omit the 'explicit' keyword in order to allow the
// conversion to be implicit. // conversion to be implicit.
template <typename T> template <typename T>
IgnoredValue(const T&) {} IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
}; };
// MatcherTuple<T>::type is a tuple type where each field is a Matcher // MatcherTuple<T>::type is a tuple type where each field is a Matcher

View File

@ -354,7 +354,8 @@ template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT
// crashes). // crashes).
template <typename T> template <typename T>
inline T Invalid() { inline T Invalid() {
return *static_cast<typename remove_reference<T>::type*>(NULL); return const_cast<typename remove_reference<T>::type&>(
*static_cast<volatile typename remove_reference<T>::type*>(NULL));
} }
template <> template <>
inline void Invalid<void>() {} inline void Invalid<void>() {}
@ -459,6 +460,11 @@ class StlContainerView< ::std::tr1::tuple<ElementPointer, Size> > {
// StlContainer with a reference type. // StlContainer with a reference type.
template <typename T> class StlContainerView<T&>; template <typename T> class StlContainerView<T&>;
// Mapping from booleans to types. Similar to boost::bool_<kValue> and
// std::integral_constant<bool, kValue>.
template <bool kValue>
struct BooleanConstant {};
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing

View File

@ -416,7 +416,7 @@ def _NeedToUseReturnNullDiagnoser(msg):
'::operator testing::Action<Func>\(\) const.*\n' + '::operator testing::Action<Func>\(\) const.*\n' +
_GCC_FILE_LINE_RE + r'instantiated from here\n' _GCC_FILE_LINE_RE + r'instantiated from here\n'
r'.*error: no matching function for call to \'ImplicitCast_\(' r'.*error: no matching function for call to \'ImplicitCast_\('
r'long int&\)') r'(:?long )?int&\)')
clang_regex = (r'\bgmock-actions.h:.* error: no matching function for ' clang_regex = (r'\bgmock-actions.h:.* error: no matching function for '
r'call to \'ImplicitCast_\'\r?\n' r'call to \'ImplicitCast_\'\r?\n'
r'(.*\n)*?' + r'(.*\n)*?' +

View File

@ -83,6 +83,7 @@ class BetweenCardinalityImpl : public CardinalityInterface {
} }
virtual void DescribeTo(::std::ostream* os) const; virtual void DescribeTo(::std::ostream* os) const;
private: private:
const int min_; const int min_;
const int max_; const int max_;

View File

@ -579,6 +579,7 @@ class MockObjectRegistry {
} }
StateMap& states() { return states_; } StateMap& states() { return states_; }
private: private:
StateMap states_; StateMap states_;
}; };

View File

@ -518,7 +518,7 @@ TEST(ReturnTest, IsCovariant) {
// gmock-actions.h for more information. // gmock-actions.h for more information.
class FromType { class FromType {
public: public:
FromType(bool* is_converted) : converted_(is_converted) {} explicit FromType(bool* is_converted) : converted_(is_converted) {}
bool* converted() const { return converted_; } bool* converted() const { return converted_; }
private: private:
@ -529,7 +529,8 @@ class FromType {
class ToType { class ToType {
public: public:
ToType(const FromType& x) { *x.converted() = true; } // Must allow implicit conversion due to use in ImplicitCast_<T>.
ToType(const FromType& x) { *x.converted() = true; } // NOLINT
}; };
TEST(ReturnTest, ConvertsArgumentWhenConverted) { TEST(ReturnTest, ConvertsArgumentWhenConverted) {
@ -1226,7 +1227,8 @@ TEST(ByRefTest, IsCopyable) {
const std::string s1 = "Hi"; const std::string s1 = "Hi";
const std::string s2 = "Hello"; const std::string s2 = "Hello";
::testing::internal::ReferenceWrapper<const std::string> ref_wrapper = ByRef(s1); ::testing::internal::ReferenceWrapper<const std::string> ref_wrapper =
ByRef(s1);
const std::string& r1 = ref_wrapper; const std::string& r1 = ref_wrapper;
EXPECT_EQ(&s1, &r1); EXPECT_EQ(&s1, &r1);
@ -1235,7 +1237,8 @@ TEST(ByRefTest, IsCopyable) {
const std::string& r2 = ref_wrapper; const std::string& r2 = ref_wrapper;
EXPECT_EQ(&s2, &r2); EXPECT_EQ(&s2, &r2);
::testing::internal::ReferenceWrapper<const std::string> ref_wrapper1 = ByRef(s1); ::testing::internal::ReferenceWrapper<const std::string> ref_wrapper1 =
ByRef(s1);
// Copies ref_wrapper1 to ref_wrapper. // Copies ref_wrapper1 to ref_wrapper.
ref_wrapper = ref_wrapper1; ref_wrapper = ref_wrapper1;
const std::string& r3 = ref_wrapper; const std::string& r3 = ref_wrapper;

View File

@ -35,11 +35,6 @@
#include "gmock/gmock-generated-function-mockers.h" #include "gmock/gmock-generated-function-mockers.h"
#include <map>
#include <string>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
// MSDN says the header file to be included for STDMETHOD is BaseTyps.h but // MSDN says the header file to be included for STDMETHOD is BaseTyps.h but
// we are getting compiler errors if we use basetyps.h, hence including // we are getting compiler errors if we use basetyps.h, hence including
@ -47,6 +42,11 @@
# include <objbase.h> # include <objbase.h>
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
#include <map>
#include <string>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
// There is a bug in MSVC (fixed in VS 2008) that prevents creating a // There is a bug in MSVC (fixed in VS 2008) that prevents creating a
// mock for a function with const arguments, so we don't test such // mock for a function with const arguments, so we don't test such
// cases for MSVC versions older than 2008. // cases for MSVC versions older than 2008.

View File

@ -1091,6 +1091,20 @@ TEST(ContainsTest, WorksForTwoDimensionalNativeArray) {
EXPECT_THAT(a, Contains(Not(Contains(5)))); EXPECT_THAT(a, Contains(Not(Contains(5))));
} }
TEST(AllOfTest, HugeMatcher) {
// Verify that using AllOf with many arguments doesn't cause
// the compiler to exceed template instantiation depth limit.
EXPECT_THAT(0, testing::AllOf(_, _, _, _, _, _, _, _, _,
testing::AllOf(_, _, _, _, _, _, _, _, _, _)));
}
TEST(AnyOfTest, HugeMatcher) {
// Verify that using AnyOf with many arguments doesn't cause
// the compiler to exceed template instantiation depth limit.
EXPECT_THAT(0, testing::AnyOf(_, _, _, _, _, _, _, _, _,
testing::AnyOf(_, _, _, _, _, _, _, _, _, _)));
}
namespace adl_test { namespace adl_test {
// Verifies that the implementation of ::testing::AllOf and ::testing::AnyOf // Verifies that the implementation of ::testing::AllOf and ::testing::AnyOf

View File

@ -545,6 +545,37 @@ TEST(MatcherCastTest, FromSameType) {
EXPECT_FALSE(m2.Matches(1)); EXPECT_FALSE(m2.Matches(1));
} }
// Implicitly convertible form any type.
struct ConvertibleFromAny {
ConvertibleFromAny(int a_value) : value(a_value) {}
template <typename T>
ConvertibleFromAny(const T& a_value) : value(-1) {
ADD_FAILURE() << "Conversion constructor called";
}
int value;
};
bool operator==(const ConvertibleFromAny& a, const ConvertibleFromAny& b) {
return a.value == b.value;
}
ostream& operator<<(ostream& os, const ConvertibleFromAny& a) {
return os << a.value;
}
TEST(MatcherCastTest, ConversionConstructorIsUsed) {
Matcher<ConvertibleFromAny> m = MatcherCast<ConvertibleFromAny>(1);
EXPECT_TRUE(m.Matches(ConvertibleFromAny(1)));
EXPECT_FALSE(m.Matches(ConvertibleFromAny(2)));
}
TEST(MatcherCastTest, FromConvertibleFromAny) {
Matcher<ConvertibleFromAny> m =
MatcherCast<ConvertibleFromAny>(Eq(ConvertibleFromAny(1)));
EXPECT_TRUE(m.Matches(ConvertibleFromAny(1)));
EXPECT_FALSE(m.Matches(ConvertibleFromAny(2)));
}
class Base {}; class Base {};
class Derived : public Base {}; class Derived : public Base {};
@ -620,6 +651,19 @@ TEST(SafeMatcherCastTest, FromSameType) {
EXPECT_FALSE(m2.Matches(1)); EXPECT_FALSE(m2.Matches(1));
} }
TEST(SafeMatcherCastTest, ConversionConstructorIsUsed) {
Matcher<ConvertibleFromAny> m = SafeMatcherCast<ConvertibleFromAny>(1);
EXPECT_TRUE(m.Matches(ConvertibleFromAny(1)));
EXPECT_FALSE(m.Matches(ConvertibleFromAny(2)));
}
TEST(SafeMatcherCastTest, FromConvertibleFromAny) {
Matcher<ConvertibleFromAny> m =
SafeMatcherCast<ConvertibleFromAny>(Eq(ConvertibleFromAny(1)));
EXPECT_TRUE(m.Matches(ConvertibleFromAny(1)));
EXPECT_FALSE(m.Matches(ConvertibleFromAny(2)));
}
// Tests that A<T>() matches any value of type T. // Tests that A<T>() matches any value of type T.
TEST(ATest, MatchesAnyValue) { TEST(ATest, MatchesAnyValue) {
// Tests a matcher for a value type. // Tests a matcher for a value type.
@ -1940,19 +1984,19 @@ TEST(AllOfTest, CanDescribeSelf) {
m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3)); m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3));
EXPECT_EQ("(is > 0) and " EXPECT_EQ("((is > 0) and "
"((isn't equal to 1) and " "(isn't equal to 1)) and "
"((isn't equal to 2) and " "((isn't equal to 2) and "
"(isn't equal to 3)))", "(isn't equal to 3))",
Describe(m)); Describe(m));
m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7)); m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7));
EXPECT_EQ("(is >= 0) and " EXPECT_EQ("((is >= 0) and "
"((is < 10) and " "(is < 10)) and "
"((isn't equal to 3) and " "((isn't equal to 3) and "
"((isn't equal to 5) and " "((isn't equal to 5) and "
"(isn't equal to 7))))", "(isn't equal to 7)))",
Describe(m)); Describe(m));
} }
@ -1972,19 +2016,19 @@ TEST(AllOfTest, CanDescribeNegation) {
m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3)); m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3));
EXPECT_EQ("(isn't > 0) or " EXPECT_EQ("((isn't > 0) or "
"((is equal to 1) or " "(is equal to 1)) or "
"((is equal to 2) or " "((is equal to 2) or "
"(is equal to 3)))", "(is equal to 3))",
DescribeNegation(m)); DescribeNegation(m));
m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7)); m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7));
EXPECT_EQ("(isn't >= 0) or " EXPECT_EQ("((isn't >= 0) or "
"((isn't < 10) or " "(isn't < 10)) or "
"((is equal to 3) or " "((is equal to 3) or "
"((is equal to 5) or " "((is equal to 5) or "
"(is equal to 7))))", "(is equal to 7)))",
DescribeNegation(m)); DescribeNegation(m));
} }
@ -2112,18 +2156,18 @@ TEST(AnyOfTest, CanDescribeSelf) {
Describe(m)); Describe(m));
m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3)); m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3));
EXPECT_EQ("(is < 0) or " EXPECT_EQ("((is < 0) or "
"((is equal to 1) or " "(is equal to 1)) or "
"((is equal to 2) or " "((is equal to 2) or "
"(is equal to 3)))", "(is equal to 3))",
Describe(m)); Describe(m));
m = AnyOf(Le(0), Gt(10), 3, 5, 7); m = AnyOf(Le(0), Gt(10), 3, 5, 7);
EXPECT_EQ("(is <= 0) or " EXPECT_EQ("((is <= 0) or "
"((is > 10) or " "(is > 10)) or "
"((is equal to 3) or " "((is equal to 3) or "
"((is equal to 5) or " "((is equal to 5) or "
"(is equal to 7))))", "(is equal to 7)))",
Describe(m)); Describe(m));
} }
@ -2140,18 +2184,18 @@ TEST(AnyOfTest, CanDescribeNegation) {
DescribeNegation(m)); DescribeNegation(m));
m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3)); m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3));
EXPECT_EQ("(isn't < 0) and " EXPECT_EQ("((isn't < 0) and "
"((isn't equal to 1) and " "(isn't equal to 1)) and "
"((isn't equal to 2) and " "((isn't equal to 2) and "
"(isn't equal to 3)))", "(isn't equal to 3))",
DescribeNegation(m)); DescribeNegation(m));
m = AnyOf(Le(0), Gt(10), 3, 5, 7); m = AnyOf(Le(0), Gt(10), 3, 5, 7);
EXPECT_EQ("(isn't <= 0) and " EXPECT_EQ("((isn't <= 0) and "
"((isn't > 10) and " "(isn't > 10)) and "
"((isn't equal to 3) and " "((isn't equal to 3) and "
"((isn't equal to 5) and " "((isn't equal to 5) and "
"(isn't equal to 7))))", "(isn't equal to 7)))",
DescribeNegation(m)); DescribeNegation(m));
} }

View File

@ -225,6 +225,7 @@ class Foo {
const char* s10) { const char* s10) {
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10; return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
} }
private: private:
int value_; int value_;
}; };

View File

@ -195,8 +195,8 @@ class Interface {
virtual char* StringFromString(char* str) = 0; virtual char* StringFromString(char* str) = 0;
virtual int IntFromString(char* str) = 0; virtual int IntFromString(char* str) = 0;
virtual int& IntRefFromString(char* str) = 0; virtual int& IntRefFromString(char* str) = 0;
virtual void VoidFromFunc(void(*)(char*)) = 0; virtual void VoidFromFunc(void(*func)(char* str)) = 0;
virtual void VoidFromIntRef(int& n) = 0; virtual void VoidFromIntRef(int& n) = 0; // NOLINT
virtual void VoidFromFloat(float n) = 0; virtual void VoidFromFloat(float n) = 0;
virtual void VoidFromDouble(double n) = 0; virtual void VoidFromDouble(double n) = 0;
virtual void VoidFromVector(const std::vector<int>& v) = 0; virtual void VoidFromVector(const std::vector<int>& v) = 0;
@ -211,7 +211,7 @@ class Mock: public Interface {
MOCK_METHOD1(IntFromString, int(char* str)); MOCK_METHOD1(IntFromString, int(char* str));
MOCK_METHOD1(IntRefFromString, int&(char* str)); MOCK_METHOD1(IntRefFromString, int&(char* str));
MOCK_METHOD1(VoidFromFunc, void(void(*func)(char* str))); MOCK_METHOD1(VoidFromFunc, void(void(*func)(char* str)));
MOCK_METHOD1(VoidFromIntRef, void(int& n)); MOCK_METHOD1(VoidFromIntRef, void(int& n)); // NOLINT
MOCK_METHOD1(VoidFromFloat, void(float n)); MOCK_METHOD1(VoidFromFloat, void(float n));
MOCK_METHOD1(VoidFromDouble, void(double n)); MOCK_METHOD1(VoidFromDouble, void(double n));
MOCK_METHOD1(VoidFromVector, void(const std::vector<int>& v)); MOCK_METHOD1(VoidFromVector, void(const std::vector<int>& v));
@ -224,15 +224,15 @@ class InvokeHelper {
public: public:
static void StaticVoidFromVoid() {} static void StaticVoidFromVoid() {}
void VoidFromVoid() {} void VoidFromVoid() {}
static void StaticVoidFromString(char*) {} static void StaticVoidFromString(char* /* str */) {}
void VoidFromString(char*) {} void VoidFromString(char* /* str */) {}
static int StaticIntFromString(char*) { return 1; } static int StaticIntFromString(char* /* str */) { return 1; }
static bool StaticBoolFromString(const char*) { return true; } static bool StaticBoolFromString(const char* /* str */) { return true; }
}; };
class FieldHelper { class FieldHelper {
public: public:
FieldHelper(int a_field) : field_(a_field) {} explicit FieldHelper(int a_field) : field_(a_field) {}
int field() const { return field_; } int field() const { return field_; }
int field_; // NOLINT -- need external access to field_ to test int field_; // NOLINT -- need external access to field_ to test
// the Field matcher. // the Field matcher.