diff options
author | jgm <jgm@google.com> | 2012-11-15 15:50:36 +0000 |
---|---|---|
committer | jgm <jgm@google.com> | 2012-11-15 15:50:36 +0000 |
commit | 38513a8bb154f0b6d0a4088814fe92552696d465 (patch) | |
tree | 95e50c814602bcfb0b62cc06f5843feefa9b1a1e /include | |
parent | ada23475e27babd85fb9c13250243f6acfd3ffd8 (diff) | |
download | googletest-38513a8bb154f0b6d0a4088814fe92552696d465.tar.gz googletest-38513a8bb154f0b6d0a4088814fe92552696d465.tar.bz2 googletest-38513a8bb154f0b6d0a4088814fe92552696d465.zip |
Unfortunately, the svn repo is a bit out of date. This commit contains 8
changes that haven't made it to svn. The descriptions of each change are listed
below.
- Fixes some python shebang lines.
- Add ElementsAreArray overloads to gmock. ElementsAreArray now makes a copy of
its input elements before the conversion to a Matcher. ElementsAreArray can
now take a vector as input. ElementsAreArray can now take an iterator pair as
input.
- Templatize MatchAndExplain to allow independent string types for the matcher
and matchee. I also templatized the ConstCharPointer version of
MatchAndExplain to avoid calls with "char*" from using the new templated
MatchAndExplain.
- Fixes the bug where the constructor of the return type of ElementsAre() saves
a reference instead of a copy of the arguments.
- Extends ElementsAre() to accept arrays whose sizes aren't known.
- Switches gTest's internal FilePath class from testing::internal::String to
std::string. testing::internal::String was introduced when gTest couldn't
depend on std::string. It's now deprecated.
- Switches gTest & gMock from using testing::internal::String objects to
std::string. Some static methods of String are still in use. We may be able
to remove some but not all of them. In particular, String::Format() should
eventually be removed as it truncates the result at 4096 characters, often
causing problems.
Diffstat (limited to 'include')
-rw-r--r-- | include/gmock/gmock-generated-matchers.h | 196 | ||||
-rw-r--r-- | include/gmock/gmock-generated-matchers.h.pump | 64 | ||||
-rw-r--r-- | include/gmock/gmock-matchers.h | 151 | ||||
-rw-r--r-- | include/gmock/internal/gmock-internal-utils.h | 13 | ||||
-rw-r--r-- | include/gmock/internal/gmock-port.h | 4 |
5 files changed, 274 insertions, 154 deletions
diff --git a/include/gmock/gmock-generated-matchers.h b/include/gmock/gmock-generated-matchers.h index 5527ed3e..bc3f610c 100644 --- a/include/gmock/gmock-generated-matchers.h +++ b/include/gmock/gmock-generated-matchers.h @@ -38,6 +38,7 @@ #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ +#include <iterator> #include <sstream> #include <string> #include <vector> @@ -305,7 +306,9 @@ class ArgsMatcher { GTEST_DISALLOW_ASSIGN_(ArgsMatcher); }; -// Implements ElementsAre() of 1-10 arguments. +// Implements ElementsAre() of 1-10 arguments. The use of DecayArray in +// the implementation allows ElementsAre() to accept string literals, whose +// inferred type is const char[N] while we want to treat them as const char*. template <typename T1> class ElementsAreMatcher1 { @@ -326,11 +329,12 @@ class ElementsAreMatcher1 { // a local array. const Matcher<const Element&> matcher = MatcherCast<const Element&>(e1_); - return MakeMatcher(new ElementsAreMatcherImpl<Container>(&matcher, 1)); + return MakeMatcher(new ElementsAreMatcherImpl<Container>(&matcher, + &matcher + 1)); } private: - const T1& e1_; + const typename DecayArray<T1>::type e1_; GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher1); }; @@ -351,12 +355,13 @@ class ElementsAreMatcher2 { MatcherCast<const Element&>(e2_), }; - return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 2)); + return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, + matchers + 2)); } private: - const T1& e1_; - const T2& e2_; + const typename DecayArray<T1>::type e1_; + const typename DecayArray<T2>::type e2_; GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher2); }; @@ -379,13 +384,14 @@ class ElementsAreMatcher3 { MatcherCast<const Element&>(e3_), }; - return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 3)); + return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, + matchers + 3)); } private: - const T1& e1_; - const T2& e2_; - const T3& e3_; + const typename DecayArray<T1>::type e1_; + const typename DecayArray<T2>::type e2_; + const typename DecayArray<T3>::type e3_; GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher3); }; @@ -409,14 +415,15 @@ class ElementsAreMatcher4 { MatcherCast<const Element&>(e4_), }; - return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 4)); + return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, + matchers + 4)); } private: - const T1& e1_; - const T2& e2_; - const T3& e3_; - const T4& e4_; + const typename DecayArray<T1>::type e1_; + const typename DecayArray<T2>::type e2_; + const typename DecayArray<T3>::type e3_; + const typename DecayArray<T4>::type e4_; GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher4); }; @@ -441,15 +448,16 @@ class ElementsAreMatcher5 { MatcherCast<const Element&>(e5_), }; - return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 5)); + return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, + matchers + 5)); } private: - const T1& e1_; - const T2& e2_; - const T3& e3_; - const T4& e4_; - const T5& e5_; + const typename DecayArray<T1>::type e1_; + const typename DecayArray<T2>::type e2_; + const typename DecayArray<T3>::type e3_; + const typename DecayArray<T4>::type e4_; + const typename DecayArray<T5>::type e5_; GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher5); }; @@ -477,16 +485,17 @@ class ElementsAreMatcher6 { MatcherCast<const Element&>(e6_), }; - return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 6)); + return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, + matchers + 6)); } private: - const T1& e1_; - const T2& e2_; - const T3& e3_; - const T4& e4_; - const T5& e5_; - const T6& e6_; + const typename DecayArray<T1>::type e1_; + const typename DecayArray<T2>::type e2_; + const typename DecayArray<T3>::type e3_; + const typename DecayArray<T4>::type e4_; + const typename DecayArray<T5>::type e5_; + const typename DecayArray<T6>::type e6_; GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher6); }; @@ -515,17 +524,18 @@ class ElementsAreMatcher7 { MatcherCast<const Element&>(e7_), }; - return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 7)); + return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, + matchers + 7)); } private: - const T1& e1_; - const T2& e2_; - const T3& e3_; - const T4& e4_; - const T5& e5_; - const T6& e6_; - const T7& e7_; + const typename DecayArray<T1>::type e1_; + const typename DecayArray<T2>::type e2_; + const typename DecayArray<T3>::type e3_; + const typename DecayArray<T4>::type e4_; + const typename DecayArray<T5>::type e5_; + const typename DecayArray<T6>::type e6_; + const typename DecayArray<T7>::type e7_; GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher7); }; @@ -555,18 +565,19 @@ class ElementsAreMatcher8 { MatcherCast<const Element&>(e8_), }; - return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 8)); + return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, + matchers + 8)); } private: - const T1& e1_; - const T2& e2_; - const T3& e3_; - const T4& e4_; - const T5& e5_; - const T6& e6_; - const T7& e7_; - const T8& e8_; + const typename DecayArray<T1>::type e1_; + const typename DecayArray<T2>::type e2_; + const typename DecayArray<T3>::type e3_; + const typename DecayArray<T4>::type e4_; + const typename DecayArray<T5>::type e5_; + const typename DecayArray<T6>::type e6_; + const typename DecayArray<T7>::type e7_; + const typename DecayArray<T8>::type e8_; GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher8); }; @@ -598,19 +609,20 @@ class ElementsAreMatcher9 { MatcherCast<const Element&>(e9_), }; - return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 9)); + return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, + matchers + 9)); } private: - const T1& e1_; - const T2& e2_; - const T3& e3_; - const T4& e4_; - const T5& e5_; - const T6& e6_; - const T7& e7_; - const T8& e8_; - const T9& e9_; + const typename DecayArray<T1>::type e1_; + const typename DecayArray<T2>::type e2_; + const typename DecayArray<T3>::type e3_; + const typename DecayArray<T4>::type e4_; + const typename DecayArray<T5>::type e5_; + const typename DecayArray<T6>::type e6_; + const typename DecayArray<T7>::type e7_; + const typename DecayArray<T8>::type e8_; + const typename DecayArray<T9>::type e9_; GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher9); }; @@ -643,20 +655,21 @@ class ElementsAreMatcher10 { MatcherCast<const Element&>(e10_), }; - return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 10)); + return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, + matchers + 10)); } private: - const T1& e1_; - const T2& e2_; - const T3& e3_; - const T4& e4_; - const T5& e5_; - const T6& e6_; - const T7& e7_; - const T8& e8_; - const T9& e9_; - const T10& e10_; + const typename DecayArray<T1>::type e1_; + const typename DecayArray<T2>::type e2_; + const typename DecayArray<T3>::type e3_; + const typename DecayArray<T4>::type e4_; + const typename DecayArray<T5>::type e5_; + const typename DecayArray<T6>::type e6_; + const typename DecayArray<T7>::type e7_; + const typename DecayArray<T8>::type e8_; + const typename DecayArray<T9>::type e9_; + const typename DecayArray<T10>::type e10_; GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher10); }; @@ -1007,24 +1020,55 @@ inline internal::ElementsAreMatcher10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10); } -// ElementsAreArray(array) and ElementAreArray(array, count) are like -// ElementsAre(), except that they take an array of values or -// matchers. The former form infers the size of 'array', which must -// be a static C-style array. In the latter form, 'array' can either -// be a static array or a pointer to a dynamically created array. - +// ElementsAreArray(array) +// ElementsAreArray(pointer, count) +// ElementsAreArray(vector) +// ElementsAreArray(first, last) +// +// The ElementsAreArray() functions are like ElementsAre(...), except that +// they are given a sequence of matchers or values rather than taking each +// element as a function argument. The sequence can be specified as a +// C-style array, a pointer and count, a vector, or an STL iterator range. +// +// * The array form infers the size of 'array', which must be of a +// statically-sized C-style array type. +// +// * The (pointer, count) form can take either a statically-sized C-style +// array or a pointer to a dynamically created array. It does not take +// ownership of the pointer. +// +// * The vector form can take a std::vector either of values or of matchers. +// +// * The (first, last) form can take any STL iterator range. +// +// All forms of ElementsAreArray() make a copy of the input sequence. template <typename T> inline internal::ElementsAreArrayMatcher<T> ElementsAreArray( const T* first, size_t count) { - return internal::ElementsAreArrayMatcher<T>(first, count); + return internal::ElementsAreArrayMatcher<T>(first, first + count); } template <typename T, size_t N> -inline internal::ElementsAreArrayMatcher<T> -ElementsAreArray(const T (&array)[N]) { - return internal::ElementsAreArrayMatcher<T>(array, N); +inline internal::ElementsAreArrayMatcher<T> ElementsAreArray( + const T (&array)[N]) { + return internal::ElementsAreArrayMatcher<T>(array, array + N); +} + +template <typename T, typename A> +inline internal::ElementsAreArrayMatcher<T> ElementsAreArray( + const std::vector<T, A>& vec) { + return internal::ElementsAreArrayMatcher<T>(vec.begin(), vec.end()); } +template <typename Iter> +inline internal::ElementsAreArrayMatcher< + typename std::iterator_traits<Iter>::value_type> +ElementsAreArray(Iter first, Iter last) { + typedef typename std::iterator_traits<Iter>::value_type T; + return internal::ElementsAreArrayMatcher<T>(first, last); +} + + // 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. diff --git a/include/gmock/gmock-generated-matchers.h.pump b/include/gmock/gmock-generated-matchers.h.pump index 7cdb84bf..a8d7612d 100644 --- a/include/gmock/gmock-generated-matchers.h.pump +++ b/include/gmock/gmock-generated-matchers.h.pump @@ -40,6 +40,7 @@ $$ }} This line fixes auto-indentation of the following code in Emacs. #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ +#include <iterator> #include <sstream> #include <string> #include <vector> @@ -186,7 +187,9 @@ class ArgsMatcher { GTEST_DISALLOW_ASSIGN_(ArgsMatcher); }; -// Implements ElementsAre() of 1-$n arguments. +// Implements ElementsAre() of 1-$n arguments. The use of DecayArray in +// the implementation allows ElementsAre() to accept string literals, whose +// inferred type is const char[N] while we want to treat them as const char*. $range i 1..n @@ -214,7 +217,8 @@ $if i==1 [[ // a local array. const Matcher<const Element&> matcher = MatcherCast<const Element&>(e1_); - return MakeMatcher(new ElementsAreMatcherImpl<Container>(&matcher, 1)); + return MakeMatcher(new ElementsAreMatcherImpl<Container>(&matcher, + &matcher + 1)); ]] $else [[ const Matcher<const Element&> matchers[] = { @@ -225,7 +229,8 @@ $for j [[ ]] }; - return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, $i)); + return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, + matchers + $i)); ]] } @@ -233,7 +238,7 @@ $for j [[ private: $for j [[ - const T$j& e$j[[]]_; + const typename DecayArray<T$j>::type e$j[[]]_; ]] @@ -344,24 +349,55 @@ inline internal::ElementsAreMatcher$i<$for j, [[T$j]]> ElementsAre($for j, [[con ]] -// ElementsAreArray(array) and ElementAreArray(array, count) are like -// ElementsAre(), except that they take an array of values or -// matchers. The former form infers the size of 'array', which must -// be a static C-style array. In the latter form, 'array' can either -// be a static array or a pointer to a dynamically created array. - +// ElementsAreArray(array) +// ElementsAreArray(pointer, count) +// ElementsAreArray(vector) +// ElementsAreArray(first, last) +// +// The ElementsAreArray() functions are like ElementsAre(...), except that +// they are given a sequence of matchers or values rather than taking each +// element as a function argument. The sequence can be specified as a +// C-style array, a pointer and count, a vector, or an STL iterator range. +// +// * The array form infers the size of 'array', which must be of a +// statically-sized C-style array type. +// +// * The (pointer, count) form can take either a statically-sized C-style +// array or a pointer to a dynamically created array. It does not take +// ownership of the pointer. +// +// * The vector form can take a std::vector either of values or of matchers. +// +// * The (first, last) form can take any STL iterator range. +// +// All forms of ElementsAreArray() make a copy of the input sequence. template <typename T> inline internal::ElementsAreArrayMatcher<T> ElementsAreArray( const T* first, size_t count) { - return internal::ElementsAreArrayMatcher<T>(first, count); + return internal::ElementsAreArrayMatcher<T>(first, first + count); } template <typename T, size_t N> -inline internal::ElementsAreArrayMatcher<T> -ElementsAreArray(const T (&array)[N]) { - return internal::ElementsAreArrayMatcher<T>(array, N); +inline internal::ElementsAreArrayMatcher<T> ElementsAreArray( + const T (&array)[N]) { + return internal::ElementsAreArrayMatcher<T>(array, array + N); +} + +template <typename T, typename A> +inline internal::ElementsAreArrayMatcher<T> ElementsAreArray( + const std::vector<T, A>& vec) { + return internal::ElementsAreArrayMatcher<T>(vec.begin(), vec.end()); } +template <typename Iter> +inline internal::ElementsAreArrayMatcher< + typename std::iterator_traits<Iter>::value_type> +ElementsAreArray(Iter first, Iter last) { + typedef typename std::iterator_traits<Iter>::value_type T; + return internal::ElementsAreArrayMatcher<T>(first, last); +} + + // 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. diff --git a/include/gmock/gmock-matchers.h b/include/gmock/gmock-matchers.h index 4f1c433c..751574ca 100644 --- a/include/gmock/gmock-matchers.h +++ b/include/gmock/gmock-matchers.h @@ -935,26 +935,33 @@ bool CaseInsensitiveStringEquals(const StringType& s1, template <typename StringType> class StrEqualityMatcher { public: - typedef typename StringType::const_pointer ConstCharPointer; - StrEqualityMatcher(const StringType& str, bool expect_eq, bool case_sensitive) : string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {} - // When expect_eq_ is true, returns true iff s is equal to string_; - // otherwise returns true iff s is not equal to string_. - bool MatchAndExplain(ConstCharPointer s, - MatchResultListener* listener) const { + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template <typename CharType> + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { if (s == NULL) { return !expect_eq_; } return MatchAndExplain(StringType(s), listener); } - bool MatchAndExplain(const StringType& s, + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because StringPiece has some interfering non-explicit constructors. + template <typename MatcheeStringType> + bool MatchAndExplain(const MatcheeStringType& s, MatchResultListener* /* listener */) const { - const bool eq = case_sensitive_ ? s == string_ : - CaseInsensitiveStringEquals(s, string_); + const StringType& s2(s); + const bool eq = case_sensitive_ ? s2 == string_ : + CaseInsensitiveStringEquals(s2, string_); return expect_eq_ == eq; } @@ -989,22 +996,28 @@ class StrEqualityMatcher { template <typename StringType> class HasSubstrMatcher { public: - typedef typename StringType::const_pointer ConstCharPointer; - explicit HasSubstrMatcher(const StringType& substring) : substring_(substring) {} - // These overloaded methods allow HasSubstr(substring) to be used as a - // Matcher<T> as long as T can be converted to string. Returns true - // iff s contains substring_ as a substring. - bool MatchAndExplain(ConstCharPointer s, - MatchResultListener* listener) const { + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template <typename CharType> + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { return s != NULL && MatchAndExplain(StringType(s), listener); } - bool MatchAndExplain(const StringType& s, + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because StringPiece has some interfering non-explicit constructors. + template <typename MatcheeStringType> + bool MatchAndExplain(const MatcheeStringType& s, MatchResultListener* /* listener */) const { - return s.find(substring_) != StringType::npos; + const StringType& s2(s); + return s2.find(substring_) != StringType::npos; } // Describes what this matcher matches. @@ -1030,23 +1043,29 @@ class HasSubstrMatcher { template <typename StringType> class StartsWithMatcher { public: - typedef typename StringType::const_pointer ConstCharPointer; - explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) { } - // These overloaded methods allow StartsWith(prefix) to be used as a - // Matcher<T> as long as T can be converted to string. Returns true - // iff s starts with prefix_. - bool MatchAndExplain(ConstCharPointer s, - MatchResultListener* listener) const { + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template <typename CharType> + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { return s != NULL && MatchAndExplain(StringType(s), listener); } - bool MatchAndExplain(const StringType& s, + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because StringPiece has some interfering non-explicit constructors. + template <typename MatcheeStringType> + bool MatchAndExplain(const MatcheeStringType& s, MatchResultListener* /* listener */) const { - return s.length() >= prefix_.length() && - s.substr(0, prefix_.length()) == prefix_; + const StringType& s2(s); + return s2.length() >= prefix_.length() && + s2.substr(0, prefix_.length()) == prefix_; } void DescribeTo(::std::ostream* os) const { @@ -1071,22 +1090,28 @@ class StartsWithMatcher { template <typename StringType> class EndsWithMatcher { public: - typedef typename StringType::const_pointer ConstCharPointer; - explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {} - // These overloaded methods allow EndsWith(suffix) to be used as a - // Matcher<T> as long as T can be converted to string. Returns true - // iff s ends with suffix_. - bool MatchAndExplain(ConstCharPointer s, - MatchResultListener* listener) const { + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template <typename CharType> + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { return s != NULL && MatchAndExplain(StringType(s), listener); } - bool MatchAndExplain(const StringType& s, + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because StringPiece has some interfering non-explicit constructors. + template <typename MatcheeStringType> + bool MatchAndExplain(const MatcheeStringType& s, MatchResultListener* /* listener */) const { - return s.length() >= suffix_.length() && - s.substr(s.length() - suffix_.length()) == suffix_; + const StringType& s2(s); + return s2.length() >= suffix_.length() && + s2.substr(s2.length() - suffix_.length()) == suffix_; } void DescribeTo(::std::ostream* os) const { @@ -1113,19 +1138,26 @@ class MatchesRegexMatcher { MatchesRegexMatcher(const RE* regex, bool full_match) : regex_(regex), full_match_(full_match) {} - // These overloaded methods allow MatchesRegex(regex) to be used as - // a Matcher<T> as long as T can be converted to string. Returns - // true iff s matches regular expression regex. When full_match_ is - // true, a full match is done; otherwise a partial match is done. - bool MatchAndExplain(const char* s, - MatchResultListener* listener) const { + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template <typename CharType> + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { return s != NULL && MatchAndExplain(internal::string(s), listener); } - bool MatchAndExplain(const internal::string& s, + // Matches anything that can convert to internal::string. + // + // This is a template, not just a plain function with const internal::string&, + // because StringPiece has some interfering non-explicit constructors. + template <class MatcheeStringType> + bool MatchAndExplain(const MatcheeStringType& s, MatchResultListener* /* listener */) const { - return full_match_ ? RE::FullMatch(s, *regex_) : - RE::PartialMatch(s, *regex_); + const internal::string& s2(s); + return full_match_ ? RE::FullMatch(s2, *regex_) : + RE::PartialMatch(s2, *regex_); } void DescribeTo(::std::ostream* os) const { @@ -2527,11 +2559,9 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> { // Constructs the matcher from a sequence of element values or // element matchers. template <typename InputIter> - ElementsAreMatcherImpl(InputIter first, size_t a_count) { - matchers_.reserve(a_count); - InputIter it = first; - for (size_t i = 0; i != a_count; ++i, ++it) { - matchers_.push_back(MatcherCast<const Element&>(*it)); + ElementsAreMatcherImpl(InputIter first, InputIter last) { + while (first != last) { + matchers_.push_back(MatcherCast<const Element&>(*first++)); } } @@ -2642,7 +2672,8 @@ class ElementsAreMatcher0 { Element; const Matcher<const Element&>* const matchers = NULL; - return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, 0)); + return MakeMatcher(new ElementsAreMatcherImpl<Container>(matchers, + matchers)); } }; @@ -2650,21 +2681,17 @@ class ElementsAreMatcher0 { template <typename T> class ElementsAreArrayMatcher { public: - ElementsAreArrayMatcher(const T* first, size_t count) : - first_(first), count_(count) {} + template <typename Iter> + ElementsAreArrayMatcher(Iter first, Iter last) : matchers_(first, last) {} template <typename Container> operator Matcher<Container>() const { - typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; - typedef typename internal::StlContainerView<RawContainer>::type::value_type - Element; - - return MakeMatcher(new ElementsAreMatcherImpl<Container>(first_, count_)); + return MakeMatcher(new ElementsAreMatcherImpl<Container>( + matchers_.begin(), matchers_.end())); } private: - const T* const first_; - const size_t count_; + const std::vector<T> matchers_; GTEST_DISALLOW_ASSIGN_(ElementsAreArrayMatcher); }; diff --git a/include/gmock/internal/gmock-internal-utils.h b/include/gmock/internal/gmock-internal-utils.h index d63fb223..f9b6b809 100644 --- a/include/gmock/internal/gmock-internal-utils.h +++ b/include/gmock/internal/gmock-internal-utils.h @@ -348,6 +348,19 @@ template <typename T> struct type_equals<T, T> : public true_type {}; template <typename T> struct remove_reference { typedef T type; }; // NOLINT template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT +// DecayArray<T>::type turns an array type U[N] to const U* and preserves +// other types. Useful for saving a copy of a function argument. +template <typename T> struct DecayArray { typedef T type; }; // NOLINT +template <typename T, size_t N> struct DecayArray<T[N]> { + typedef const T* type; +}; +// Sometimes people use arrays whose size is not available at the use site +// (e.g. extern const char kNamePrefix[]). This specialization covers that +// case. +template <typename T> struct DecayArray<T[]> { + typedef const T* type; +}; + // Invalid<T>() returns an invalid value of type T. This is useful // when a value of type T is needed for compilation, but the statement // will not really be executed (or we don't care if the statement diff --git a/include/gmock/internal/gmock-port.h b/include/gmock/internal/gmock-port.h index 6a515d87..b6c5c7f1 100644 --- a/include/gmock/internal/gmock-port.h +++ b/include/gmock/internal/gmock-port.h @@ -65,7 +65,7 @@ #define GMOCK_DECLARE_int32_(name) \ extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) #define GMOCK_DECLARE_string_(name) \ - extern GTEST_API_ ::testing::internal::String GMOCK_FLAG(name) + extern GTEST_API_ ::std::string GMOCK_FLAG(name) // Macros for defining flags. #define GMOCK_DEFINE_bool_(name, default_val, doc) \ @@ -73,6 +73,6 @@ #define GMOCK_DEFINE_int32_(name, default_val, doc) \ GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val) #define GMOCK_DEFINE_string_(name, default_val, doc) \ - GTEST_API_ ::testing::internal::String GMOCK_FLAG(name) = (default_val) + GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val) #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ |