1b89a7cc2SEnji Cooper // Copyright 2007, Google Inc.
2b89a7cc2SEnji Cooper // All rights reserved.
3b89a7cc2SEnji Cooper //
4b89a7cc2SEnji Cooper // Redistribution and use in source and binary forms, with or without
5b89a7cc2SEnji Cooper // modification, are permitted provided that the following conditions are
6b89a7cc2SEnji Cooper // met:
7b89a7cc2SEnji Cooper //
8b89a7cc2SEnji Cooper // * Redistributions of source code must retain the above copyright
9b89a7cc2SEnji Cooper // notice, this list of conditions and the following disclaimer.
10b89a7cc2SEnji Cooper // * Redistributions in binary form must reproduce the above
11b89a7cc2SEnji Cooper // copyright notice, this list of conditions and the following disclaimer
12b89a7cc2SEnji Cooper // in the documentation and/or other materials provided with the
13b89a7cc2SEnji Cooper // distribution.
14b89a7cc2SEnji Cooper // * Neither the name of Google Inc. nor the names of its
15b89a7cc2SEnji Cooper // contributors may be used to endorse or promote products derived from
16b89a7cc2SEnji Cooper // this software without specific prior written permission.
17b89a7cc2SEnji Cooper //
18b89a7cc2SEnji Cooper // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19b89a7cc2SEnji Cooper // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20b89a7cc2SEnji Cooper // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21b89a7cc2SEnji Cooper // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22b89a7cc2SEnji Cooper // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23b89a7cc2SEnji Cooper // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24b89a7cc2SEnji Cooper // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25b89a7cc2SEnji Cooper // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26b89a7cc2SEnji Cooper // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27b89a7cc2SEnji Cooper // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28b89a7cc2SEnji Cooper // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29b89a7cc2SEnji Cooper
30b89a7cc2SEnji Cooper // Google Mock - a framework for writing C++ mock classes.
31b89a7cc2SEnji Cooper //
32b89a7cc2SEnji Cooper // This file defines some utilities useful for implementing Google
33b89a7cc2SEnji Cooper // Mock. They are subject to change without notice, so please DO NOT
34b89a7cc2SEnji Cooper // USE THEM IN USER CODE.
35b89a7cc2SEnji Cooper
3628f6c2f2SEnji Cooper // IWYU pragma: private, include "gmock/gmock.h"
3728f6c2f2SEnji Cooper // IWYU pragma: friend gmock/.*
38b89a7cc2SEnji Cooper
3928f6c2f2SEnji Cooper #ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
4028f6c2f2SEnji Cooper #define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
41b89a7cc2SEnji Cooper
42b89a7cc2SEnji Cooper #include <stdio.h>
4328f6c2f2SEnji Cooper
44b89a7cc2SEnji Cooper #include <ostream> // NOLINT
45b89a7cc2SEnji Cooper #include <string>
4628f6c2f2SEnji Cooper #include <type_traits>
47*5ca8c28cSEnji Cooper #include <utility>
4828f6c2f2SEnji Cooper #include <vector>
4928f6c2f2SEnji Cooper
50b89a7cc2SEnji Cooper #include "gmock/internal/gmock-port.h"
51b89a7cc2SEnji Cooper #include "gtest/gtest.h"
52b89a7cc2SEnji Cooper
53b89a7cc2SEnji Cooper namespace testing {
5428f6c2f2SEnji Cooper
5528f6c2f2SEnji Cooper template <typename>
5628f6c2f2SEnji Cooper class Matcher;
5728f6c2f2SEnji Cooper
58b89a7cc2SEnji Cooper namespace internal {
59b89a7cc2SEnji Cooper
60b89a7cc2SEnji Cooper // Silence MSVC C4100 (unreferenced formal parameter) and
61b89a7cc2SEnji Cooper // C4805('==': unsafe mix of type 'const int' and type 'const bool')
6228f6c2f2SEnji Cooper GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100 4805)
63b89a7cc2SEnji Cooper
64b89a7cc2SEnji Cooper // Joins a vector of strings as if they are fields of a tuple; returns
65b89a7cc2SEnji Cooper // the joined string.
6628f6c2f2SEnji Cooper GTEST_API_ std::string JoinAsKeyValueTuple(
6728f6c2f2SEnji Cooper const std::vector<const char*>& names, const Strings& values);
68b89a7cc2SEnji Cooper
69b89a7cc2SEnji Cooper // Converts an identifier name to a space-separated list of lower-case
70b89a7cc2SEnji Cooper // words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
71b89a7cc2SEnji Cooper // treated as one word. For example, both "FooBar123" and
72b89a7cc2SEnji Cooper // "foo_bar_123" are converted to "foo bar 123".
73b89a7cc2SEnji Cooper GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name);
74b89a7cc2SEnji Cooper
75b89a7cc2SEnji Cooper // GetRawPointer(p) returns the raw pointer underlying p when p is a
76b89a7cc2SEnji Cooper // smart pointer, or returns p itself when p is already a raw pointer.
77b89a7cc2SEnji Cooper // The following default implementation is for the smart pointer case.
78b89a7cc2SEnji Cooper template <typename Pointer>
GetRawPointer(const Pointer & p)79b89a7cc2SEnji Cooper inline const typename Pointer::element_type* GetRawPointer(const Pointer& p) {
80b89a7cc2SEnji Cooper return p.get();
81b89a7cc2SEnji Cooper }
8228f6c2f2SEnji Cooper // This overload version is for std::reference_wrapper, which does not work with
8328f6c2f2SEnji Cooper // the overload above, as it does not have an `element_type`.
8428f6c2f2SEnji Cooper template <typename Element>
GetRawPointer(const std::reference_wrapper<Element> & r)8528f6c2f2SEnji Cooper inline const Element* GetRawPointer(const std::reference_wrapper<Element>& r) {
8628f6c2f2SEnji Cooper return &r.get();
8728f6c2f2SEnji Cooper }
8828f6c2f2SEnji Cooper
89b89a7cc2SEnji Cooper // This overloaded version is for the raw pointer case.
90b89a7cc2SEnji Cooper template <typename Element>
GetRawPointer(Element * p)9128f6c2f2SEnji Cooper inline Element* GetRawPointer(Element* p) {
9228f6c2f2SEnji Cooper return p;
93b89a7cc2SEnji Cooper }
94b89a7cc2SEnji Cooper
9528f6c2f2SEnji Cooper // Default definitions for all compilers.
9628f6c2f2SEnji Cooper // NOTE: If you implement support for other compilers, make sure to avoid
9728f6c2f2SEnji Cooper // unexpected overlaps.
9828f6c2f2SEnji Cooper // (e.g., Clang also processes #pragma GCC, and clang-cl also handles _MSC_VER.)
9928f6c2f2SEnji Cooper #define GMOCK_INTERNAL_WARNING_PUSH()
10028f6c2f2SEnji Cooper #define GMOCK_INTERNAL_WARNING_CLANG(Level, Name)
10128f6c2f2SEnji Cooper #define GMOCK_INTERNAL_WARNING_POP()
10228f6c2f2SEnji Cooper
10328f6c2f2SEnji Cooper #if defined(__clang__)
10428f6c2f2SEnji Cooper #undef GMOCK_INTERNAL_WARNING_PUSH
10528f6c2f2SEnji Cooper #define GMOCK_INTERNAL_WARNING_PUSH() _Pragma("clang diagnostic push")
10628f6c2f2SEnji Cooper #undef GMOCK_INTERNAL_WARNING_CLANG
10728f6c2f2SEnji Cooper #define GMOCK_INTERNAL_WARNING_CLANG(Level, Warning) \
10828f6c2f2SEnji Cooper _Pragma(GMOCK_PP_INTERNAL_STRINGIZE(clang diagnostic Level Warning))
10928f6c2f2SEnji Cooper #undef GMOCK_INTERNAL_WARNING_POP
11028f6c2f2SEnji Cooper #define GMOCK_INTERNAL_WARNING_POP() _Pragma("clang diagnostic pop")
11128f6c2f2SEnji Cooper #endif
11228f6c2f2SEnji Cooper
113b89a7cc2SEnji Cooper // MSVC treats wchar_t as a native type usually, but treats it as the
114b89a7cc2SEnji Cooper // same as unsigned short when the compiler option /Zc:wchar_t- is
115b89a7cc2SEnji Cooper // specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t
116b89a7cc2SEnji Cooper // is a native type.
11728f6c2f2SEnji Cooper #if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED)
118b89a7cc2SEnji Cooper // wchar_t is a typedef.
119b89a7cc2SEnji Cooper #else
120b89a7cc2SEnji Cooper #define GMOCK_WCHAR_T_IS_NATIVE_ 1
121b89a7cc2SEnji Cooper #endif
122b89a7cc2SEnji Cooper
123b89a7cc2SEnji Cooper // In what follows, we use the term "kind" to indicate whether a type
124b89a7cc2SEnji Cooper // is bool, an integer type (excluding bool), a floating-point type,
125b89a7cc2SEnji Cooper // or none of them. This categorization is useful for determining
126b89a7cc2SEnji Cooper // when a matcher argument type can be safely converted to another
127b89a7cc2SEnji Cooper // type in the implementation of SafeMatcherCast.
12828f6c2f2SEnji Cooper enum TypeKind { kBool, kInteger, kFloatingPoint, kOther };
129b89a7cc2SEnji Cooper
130b89a7cc2SEnji Cooper // KindOf<T>::value is the kind of type T.
13128f6c2f2SEnji Cooper template <typename T>
13228f6c2f2SEnji Cooper struct KindOf {
133b89a7cc2SEnji Cooper enum { value = kOther }; // The default kind.
134b89a7cc2SEnji Cooper };
135b89a7cc2SEnji Cooper
136b89a7cc2SEnji Cooper // This macro declares that the kind of 'type' is 'kind'.
137b89a7cc2SEnji Cooper #define GMOCK_DECLARE_KIND_(type, kind) \
13828f6c2f2SEnji Cooper template <> \
13928f6c2f2SEnji Cooper struct KindOf<type> { \
14028f6c2f2SEnji Cooper enum { value = kind }; \
14128f6c2f2SEnji Cooper }
142b89a7cc2SEnji Cooper
143b89a7cc2SEnji Cooper GMOCK_DECLARE_KIND_(bool, kBool);
144b89a7cc2SEnji Cooper
145b89a7cc2SEnji Cooper // All standard integer types.
146b89a7cc2SEnji Cooper GMOCK_DECLARE_KIND_(char, kInteger);
147b89a7cc2SEnji Cooper GMOCK_DECLARE_KIND_(signed char, kInteger);
148b89a7cc2SEnji Cooper GMOCK_DECLARE_KIND_(unsigned char, kInteger);
149b89a7cc2SEnji Cooper GMOCK_DECLARE_KIND_(short, kInteger); // NOLINT
150b89a7cc2SEnji Cooper GMOCK_DECLARE_KIND_(unsigned short, kInteger); // NOLINT
151b89a7cc2SEnji Cooper GMOCK_DECLARE_KIND_(int, kInteger);
152b89a7cc2SEnji Cooper GMOCK_DECLARE_KIND_(unsigned int, kInteger);
153b89a7cc2SEnji Cooper GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT
154b89a7cc2SEnji Cooper GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT
15528f6c2f2SEnji Cooper GMOCK_DECLARE_KIND_(long long, kInteger); // NOLINT
15628f6c2f2SEnji Cooper GMOCK_DECLARE_KIND_(unsigned long long, kInteger); // NOLINT
157b89a7cc2SEnji Cooper
158b89a7cc2SEnji Cooper #if GMOCK_WCHAR_T_IS_NATIVE_
159b89a7cc2SEnji Cooper GMOCK_DECLARE_KIND_(wchar_t, kInteger);
160b89a7cc2SEnji Cooper #endif
161b89a7cc2SEnji Cooper
162b89a7cc2SEnji Cooper // All standard floating-point types.
163b89a7cc2SEnji Cooper GMOCK_DECLARE_KIND_(float, kFloatingPoint);
164b89a7cc2SEnji Cooper GMOCK_DECLARE_KIND_(double, kFloatingPoint);
165b89a7cc2SEnji Cooper GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
166b89a7cc2SEnji Cooper
167b89a7cc2SEnji Cooper #undef GMOCK_DECLARE_KIND_
168b89a7cc2SEnji Cooper
169b89a7cc2SEnji Cooper // Evaluates to the kind of 'type'.
170b89a7cc2SEnji Cooper #define GMOCK_KIND_OF_(type) \
171b89a7cc2SEnji Cooper static_cast< ::testing::internal::TypeKind>( \
172b89a7cc2SEnji Cooper ::testing::internal::KindOf<type>::value)
173b89a7cc2SEnji Cooper
174b89a7cc2SEnji Cooper // LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value
17528f6c2f2SEnji Cooper // is true if and only if arithmetic type From can be losslessly converted to
176b89a7cc2SEnji Cooper // arithmetic type To.
177b89a7cc2SEnji Cooper //
178b89a7cc2SEnji Cooper // It's the user's responsibility to ensure that both From and To are
179b89a7cc2SEnji Cooper // raw (i.e. has no CV modifier, is not a pointer, and is not a
180b89a7cc2SEnji Cooper // reference) built-in arithmetic types, kFromKind is the kind of
181b89a7cc2SEnji Cooper // From, and kToKind is the kind of To; the value is
182b89a7cc2SEnji Cooper // implementation-defined when the above pre-condition is violated.
183b89a7cc2SEnji Cooper template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>
18428f6c2f2SEnji Cooper using LosslessArithmeticConvertibleImpl = std::integral_constant<
18528f6c2f2SEnji Cooper bool,
18628f6c2f2SEnji Cooper // clang-format off
18728f6c2f2SEnji Cooper // Converting from bool is always lossless
18828f6c2f2SEnji Cooper (kFromKind == kBool) ? true
18928f6c2f2SEnji Cooper // Converting between any other type kinds will be lossy if the type
19028f6c2f2SEnji Cooper // kinds are not the same.
19128f6c2f2SEnji Cooper : (kFromKind != kToKind) ? false
19228f6c2f2SEnji Cooper : (kFromKind == kInteger &&
19328f6c2f2SEnji Cooper // Converting between integers of different widths is allowed so long
19428f6c2f2SEnji Cooper // as the conversion does not go from signed to unsigned.
19528f6c2f2SEnji Cooper (((sizeof(From) < sizeof(To)) &&
19628f6c2f2SEnji Cooper !(std::is_signed<From>::value && !std::is_signed<To>::value)) ||
19728f6c2f2SEnji Cooper // Converting between integers of the same width only requires the
19828f6c2f2SEnji Cooper // two types to have the same signedness.
199b89a7cc2SEnji Cooper ((sizeof(From) == sizeof(To)) &&
20028f6c2f2SEnji Cooper (std::is_signed<From>::value == std::is_signed<To>::value)))
20128f6c2f2SEnji Cooper ) ? true
20228f6c2f2SEnji Cooper // Floating point conversions are lossless if and only if `To` is at least
20328f6c2f2SEnji Cooper // as wide as `From`.
20428f6c2f2SEnji Cooper : (kFromKind == kFloatingPoint && (sizeof(From) <= sizeof(To))) ? true
20528f6c2f2SEnji Cooper : false
20628f6c2f2SEnji Cooper // clang-format on
20728f6c2f2SEnji Cooper >;
208b89a7cc2SEnji Cooper
20928f6c2f2SEnji Cooper // LosslessArithmeticConvertible<From, To>::value is true if and only if
21028f6c2f2SEnji Cooper // arithmetic type From can be losslessly converted to arithmetic type To.
211b89a7cc2SEnji Cooper //
212b89a7cc2SEnji Cooper // It's the user's responsibility to ensure that both From and To are
213b89a7cc2SEnji Cooper // raw (i.e. has no CV modifier, is not a pointer, and is not a
214b89a7cc2SEnji Cooper // reference) built-in arithmetic types; the value is
215b89a7cc2SEnji Cooper // implementation-defined when the above pre-condition is violated.
216b89a7cc2SEnji Cooper template <typename From, typename To>
21728f6c2f2SEnji Cooper using LosslessArithmeticConvertible =
21828f6c2f2SEnji Cooper LosslessArithmeticConvertibleImpl<GMOCK_KIND_OF_(From), From,
21928f6c2f2SEnji Cooper GMOCK_KIND_OF_(To), To>;
220b89a7cc2SEnji Cooper
221b89a7cc2SEnji Cooper // This interface knows how to report a Google Mock failure (either
222b89a7cc2SEnji Cooper // non-fatal or fatal).
223b89a7cc2SEnji Cooper class FailureReporterInterface {
224b89a7cc2SEnji Cooper public:
225b89a7cc2SEnji Cooper // The type of a failure (either non-fatal or fatal).
22628f6c2f2SEnji Cooper enum FailureType { kNonfatal, kFatal };
227b89a7cc2SEnji Cooper
22828f6c2f2SEnji Cooper virtual ~FailureReporterInterface() = default;
229b89a7cc2SEnji Cooper
230b89a7cc2SEnji Cooper // Reports a failure that occurred at the given source file location.
231b89a7cc2SEnji Cooper virtual void ReportFailure(FailureType type, const char* file, int line,
232b89a7cc2SEnji Cooper const std::string& message) = 0;
233b89a7cc2SEnji Cooper };
234b89a7cc2SEnji Cooper
235b89a7cc2SEnji Cooper // Returns the failure reporter used by Google Mock.
236b89a7cc2SEnji Cooper GTEST_API_ FailureReporterInterface* GetFailureReporter();
237b89a7cc2SEnji Cooper
238b89a7cc2SEnji Cooper // Asserts that condition is true; aborts the process with the given
239b89a7cc2SEnji Cooper // message if condition is false. We cannot use LOG(FATAL) or CHECK()
240b89a7cc2SEnji Cooper // as Google Mock might be used to mock the log sink itself. We
241b89a7cc2SEnji Cooper // inline this function to prevent it from showing up in the stack
242b89a7cc2SEnji Cooper // trace.
Assert(bool condition,const char * file,int line,const std::string & msg)243b89a7cc2SEnji Cooper inline void Assert(bool condition, const char* file, int line,
244b89a7cc2SEnji Cooper const std::string& msg) {
245b89a7cc2SEnji Cooper if (!condition) {
24628f6c2f2SEnji Cooper GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal, file,
24728f6c2f2SEnji Cooper line, msg);
248b89a7cc2SEnji Cooper }
249b89a7cc2SEnji Cooper }
Assert(bool condition,const char * file,int line)250b89a7cc2SEnji Cooper inline void Assert(bool condition, const char* file, int line) {
251b89a7cc2SEnji Cooper Assert(condition, file, line, "Assertion failed.");
252b89a7cc2SEnji Cooper }
253b89a7cc2SEnji Cooper
254b89a7cc2SEnji Cooper // Verifies that condition is true; generates a non-fatal failure if
255b89a7cc2SEnji Cooper // condition is false.
Expect(bool condition,const char * file,int line,const std::string & msg)256b89a7cc2SEnji Cooper inline void Expect(bool condition, const char* file, int line,
257b89a7cc2SEnji Cooper const std::string& msg) {
258b89a7cc2SEnji Cooper if (!condition) {
259b89a7cc2SEnji Cooper GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal,
260b89a7cc2SEnji Cooper file, line, msg);
261b89a7cc2SEnji Cooper }
262b89a7cc2SEnji Cooper }
Expect(bool condition,const char * file,int line)263b89a7cc2SEnji Cooper inline void Expect(bool condition, const char* file, int line) {
264b89a7cc2SEnji Cooper Expect(condition, file, line, "Expectation failed.");
265b89a7cc2SEnji Cooper }
266b89a7cc2SEnji Cooper
267b89a7cc2SEnji Cooper // Severity level of a log.
26828f6c2f2SEnji Cooper enum LogSeverity { kInfo = 0, kWarning = 1 };
269b89a7cc2SEnji Cooper
270b89a7cc2SEnji Cooper // Valid values for the --gmock_verbose flag.
271b89a7cc2SEnji Cooper
272b89a7cc2SEnji Cooper // All logs (informational and warnings) are printed.
273b89a7cc2SEnji Cooper const char kInfoVerbosity[] = "info";
274b89a7cc2SEnji Cooper // Only warnings are printed.
275b89a7cc2SEnji Cooper const char kWarningVerbosity[] = "warning";
276b89a7cc2SEnji Cooper // No logs are printed.
277b89a7cc2SEnji Cooper const char kErrorVerbosity[] = "error";
278b89a7cc2SEnji Cooper
27928f6c2f2SEnji Cooper // Returns true if and only if a log with the given severity is visible
28028f6c2f2SEnji Cooper // according to the --gmock_verbose flag.
281b89a7cc2SEnji Cooper GTEST_API_ bool LogIsVisible(LogSeverity severity);
282b89a7cc2SEnji Cooper
28328f6c2f2SEnji Cooper // Prints the given message to stdout if and only if 'severity' >= the level
284b89a7cc2SEnji Cooper // specified by the --gmock_verbose flag. If stack_frames_to_skip >=
285b89a7cc2SEnji Cooper // 0, also prints the stack trace excluding the top
286b89a7cc2SEnji Cooper // stack_frames_to_skip frames. In opt mode, any positive
287b89a7cc2SEnji Cooper // stack_frames_to_skip is treated as 0, since we don't know which
288b89a7cc2SEnji Cooper // function calls will be inlined by the compiler and need to be
289b89a7cc2SEnji Cooper // conservative.
290b89a7cc2SEnji Cooper GTEST_API_ void Log(LogSeverity severity, const std::string& message,
291b89a7cc2SEnji Cooper int stack_frames_to_skip);
292b89a7cc2SEnji Cooper
293b89a7cc2SEnji Cooper // A marker class that is used to resolve parameterless expectations to the
294b89a7cc2SEnji Cooper // correct overload. This must not be instantiable, to prevent client code from
295b89a7cc2SEnji Cooper // accidentally resolving to the overload; for example:
296b89a7cc2SEnji Cooper //
297b89a7cc2SEnji Cooper // ON_CALL(mock, Method({}, nullptr))...
298b89a7cc2SEnji Cooper //
299b89a7cc2SEnji Cooper class WithoutMatchers {
300b89a7cc2SEnji Cooper private:
WithoutMatchers()301b89a7cc2SEnji Cooper WithoutMatchers() {}
302b89a7cc2SEnji Cooper friend GTEST_API_ WithoutMatchers GetWithoutMatchers();
303b89a7cc2SEnji Cooper };
304b89a7cc2SEnji Cooper
305b89a7cc2SEnji Cooper // Internal use only: access the singleton instance of WithoutMatchers.
306b89a7cc2SEnji Cooper GTEST_API_ WithoutMatchers GetWithoutMatchers();
307b89a7cc2SEnji Cooper
308b89a7cc2SEnji Cooper // Invalid<T>() is usable as an expression of type T, but will terminate
309b89a7cc2SEnji Cooper // the program with an assertion failure if actually run. This is useful
310b89a7cc2SEnji Cooper // when a value of type T is needed for compilation, but the statement
311b89a7cc2SEnji Cooper // will not really be executed (or we don't care if the statement
312b89a7cc2SEnji Cooper // crashes).
313b89a7cc2SEnji Cooper template <typename T>
Invalid()314b89a7cc2SEnji Cooper inline T Invalid() {
31528f6c2f2SEnji Cooper Assert(/*condition=*/false, /*file=*/"", /*line=*/-1,
31628f6c2f2SEnji Cooper "Internal error: attempt to return invalid value");
31728f6c2f2SEnji Cooper #if defined(__GNUC__) || defined(__clang__)
31828f6c2f2SEnji Cooper __builtin_unreachable();
31928f6c2f2SEnji Cooper #elif defined(_MSC_VER)
32028f6c2f2SEnji Cooper __assume(0);
32128f6c2f2SEnji Cooper #else
322b89a7cc2SEnji Cooper return Invalid<T>();
323b89a7cc2SEnji Cooper #endif
32428f6c2f2SEnji Cooper }
325b89a7cc2SEnji Cooper
326b89a7cc2SEnji Cooper // Given a raw type (i.e. having no top-level reference or const
327b89a7cc2SEnji Cooper // modifier) RawContainer that's either an STL-style container or a
328b89a7cc2SEnji Cooper // native array, class StlContainerView<RawContainer> has the
329b89a7cc2SEnji Cooper // following members:
330b89a7cc2SEnji Cooper //
331b89a7cc2SEnji Cooper // - type is a type that provides an STL-style container view to
332b89a7cc2SEnji Cooper // (i.e. implements the STL container concept for) RawContainer;
333b89a7cc2SEnji Cooper // - const_reference is a type that provides a reference to a const
334b89a7cc2SEnji Cooper // RawContainer;
335b89a7cc2SEnji Cooper // - ConstReference(raw_container) returns a const reference to an STL-style
336b89a7cc2SEnji Cooper // container view to raw_container, which is a RawContainer.
337b89a7cc2SEnji Cooper // - Copy(raw_container) returns an STL-style container view of a
338b89a7cc2SEnji Cooper // copy of raw_container, which is a RawContainer.
339b89a7cc2SEnji Cooper //
340b89a7cc2SEnji Cooper // This generic version is used when RawContainer itself is already an
341b89a7cc2SEnji Cooper // STL-style container.
342b89a7cc2SEnji Cooper template <class RawContainer>
343b89a7cc2SEnji Cooper class StlContainerView {
344b89a7cc2SEnji Cooper public:
345b89a7cc2SEnji Cooper typedef RawContainer type;
346b89a7cc2SEnji Cooper typedef const type& const_reference;
347b89a7cc2SEnji Cooper
ConstReference(const RawContainer & container)348b89a7cc2SEnji Cooper static const_reference ConstReference(const RawContainer& container) {
34928f6c2f2SEnji Cooper static_assert(!std::is_const<RawContainer>::value,
35028f6c2f2SEnji Cooper "RawContainer type must not be const");
351b89a7cc2SEnji Cooper return container;
352b89a7cc2SEnji Cooper }
Copy(const RawContainer & container)353b89a7cc2SEnji Cooper static type Copy(const RawContainer& container) { return container; }
354b89a7cc2SEnji Cooper };
355b89a7cc2SEnji Cooper
356b89a7cc2SEnji Cooper // This specialization is used when RawContainer is a native array type.
357b89a7cc2SEnji Cooper template <typename Element, size_t N>
358b89a7cc2SEnji Cooper class StlContainerView<Element[N]> {
359b89a7cc2SEnji Cooper public:
36028f6c2f2SEnji Cooper typedef typename std::remove_const<Element>::type RawElement;
361b89a7cc2SEnji Cooper typedef internal::NativeArray<RawElement> type;
362b89a7cc2SEnji Cooper // NativeArray<T> can represent a native array either by value or by
363b89a7cc2SEnji Cooper // reference (selected by a constructor argument), so 'const type'
364b89a7cc2SEnji Cooper // can be used to reference a const native array. We cannot
365b89a7cc2SEnji Cooper // 'typedef const type& const_reference' here, as that would mean
366b89a7cc2SEnji Cooper // ConstReference() has to return a reference to a local variable.
367b89a7cc2SEnji Cooper typedef const type const_reference;
368b89a7cc2SEnji Cooper
ConstReference(const Element (& array)[N])369b89a7cc2SEnji Cooper static const_reference ConstReference(const Element (&array)[N]) {
37028f6c2f2SEnji Cooper static_assert(std::is_same<Element, RawElement>::value,
37128f6c2f2SEnji Cooper "Element type must not be const");
372b89a7cc2SEnji Cooper return type(array, N, RelationToSourceReference());
373b89a7cc2SEnji Cooper }
Copy(const Element (& array)[N])374b89a7cc2SEnji Cooper static type Copy(const Element (&array)[N]) {
375b89a7cc2SEnji Cooper return type(array, N, RelationToSourceCopy());
376b89a7cc2SEnji Cooper }
377b89a7cc2SEnji Cooper };
378b89a7cc2SEnji Cooper
379b89a7cc2SEnji Cooper // This specialization is used when RawContainer is a native array
380b89a7cc2SEnji Cooper // represented as a (pointer, size) tuple.
381b89a7cc2SEnji Cooper template <typename ElementPointer, typename Size>
38228f6c2f2SEnji Cooper class StlContainerView< ::std::tuple<ElementPointer, Size> > {
383b89a7cc2SEnji Cooper public:
38428f6c2f2SEnji Cooper typedef typename std::remove_const<
38528f6c2f2SEnji Cooper typename std::pointer_traits<ElementPointer>::element_type>::type
38628f6c2f2SEnji Cooper RawElement;
387b89a7cc2SEnji Cooper typedef internal::NativeArray<RawElement> type;
388b89a7cc2SEnji Cooper typedef const type const_reference;
389b89a7cc2SEnji Cooper
ConstReference(const::std::tuple<ElementPointer,Size> & array)390b89a7cc2SEnji Cooper static const_reference ConstReference(
39128f6c2f2SEnji Cooper const ::std::tuple<ElementPointer, Size>& array) {
39228f6c2f2SEnji Cooper return type(std::get<0>(array), std::get<1>(array),
39328f6c2f2SEnji Cooper RelationToSourceReference());
394b89a7cc2SEnji Cooper }
Copy(const::std::tuple<ElementPointer,Size> & array)39528f6c2f2SEnji Cooper static type Copy(const ::std::tuple<ElementPointer, Size>& array) {
39628f6c2f2SEnji Cooper return type(std::get<0>(array), std::get<1>(array), RelationToSourceCopy());
397b89a7cc2SEnji Cooper }
398b89a7cc2SEnji Cooper };
399b89a7cc2SEnji Cooper
400b89a7cc2SEnji Cooper // The following specialization prevents the user from instantiating
401b89a7cc2SEnji Cooper // StlContainer with a reference type.
40228f6c2f2SEnji Cooper template <typename T>
40328f6c2f2SEnji Cooper class StlContainerView<T&>;
404b89a7cc2SEnji Cooper
405b89a7cc2SEnji Cooper // A type transform to remove constness from the first part of a pair.
406b89a7cc2SEnji Cooper // Pairs like that are used as the value_type of associative containers,
407b89a7cc2SEnji Cooper // and this transform produces a similar but assignable pair.
408b89a7cc2SEnji Cooper template <typename T>
409b89a7cc2SEnji Cooper struct RemoveConstFromKey {
410b89a7cc2SEnji Cooper typedef T type;
411b89a7cc2SEnji Cooper };
412b89a7cc2SEnji Cooper
413b89a7cc2SEnji Cooper // Partially specialized to remove constness from std::pair<const K, V>.
414b89a7cc2SEnji Cooper template <typename K, typename V>
415b89a7cc2SEnji Cooper struct RemoveConstFromKey<std::pair<const K, V> > {
416b89a7cc2SEnji Cooper typedef std::pair<K, V> type;
417b89a7cc2SEnji Cooper };
418b89a7cc2SEnji Cooper
419b89a7cc2SEnji Cooper // Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to
420b89a7cc2SEnji Cooper // reduce code size.
421b89a7cc2SEnji Cooper GTEST_API_ void IllegalDoDefault(const char* file, int line);
422b89a7cc2SEnji Cooper
423b89a7cc2SEnji Cooper template <typename F, typename Tuple, size_t... Idx>
424*5ca8c28cSEnji Cooper auto ApplyImpl(F&& f, Tuple&& args, std::index_sequence<Idx...>)
42528f6c2f2SEnji Cooper -> decltype(std::forward<F>(f)(
42628f6c2f2SEnji Cooper std::get<Idx>(std::forward<Tuple>(args))...)) {
427b89a7cc2SEnji Cooper return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);
428b89a7cc2SEnji Cooper }
429b89a7cc2SEnji Cooper
430b89a7cc2SEnji Cooper // Apply the function to a tuple of arguments.
431b89a7cc2SEnji Cooper template <typename F, typename Tuple>
432*5ca8c28cSEnji Cooper auto Apply(F&& f, Tuple&& args)
433*5ca8c28cSEnji Cooper -> decltype(ApplyImpl(
43428f6c2f2SEnji Cooper std::forward<F>(f), std::forward<Tuple>(args),
435*5ca8c28cSEnji Cooper std::make_index_sequence<std::tuple_size<
43628f6c2f2SEnji Cooper typename std::remove_reference<Tuple>::type>::value>())) {
437b89a7cc2SEnji Cooper return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
438*5ca8c28cSEnji Cooper std::make_index_sequence<std::tuple_size<
43928f6c2f2SEnji Cooper typename std::remove_reference<Tuple>::type>::value>());
440b89a7cc2SEnji Cooper }
44128f6c2f2SEnji Cooper
44228f6c2f2SEnji Cooper // Template struct Function<F>, where F must be a function type, contains
44328f6c2f2SEnji Cooper // the following typedefs:
44428f6c2f2SEnji Cooper //
44528f6c2f2SEnji Cooper // Result: the function's return type.
44628f6c2f2SEnji Cooper // Arg<N>: the type of the N-th argument, where N starts with 0.
44728f6c2f2SEnji Cooper // ArgumentTuple: the tuple type consisting of all parameters of F.
44828f6c2f2SEnji Cooper // ArgumentMatcherTuple: the tuple type consisting of Matchers for all
44928f6c2f2SEnji Cooper // parameters of F.
45028f6c2f2SEnji Cooper // MakeResultVoid: the function type obtained by substituting void
45128f6c2f2SEnji Cooper // for the return type of F.
45228f6c2f2SEnji Cooper // MakeResultIgnoredValue:
45328f6c2f2SEnji Cooper // the function type obtained by substituting Something
45428f6c2f2SEnji Cooper // for the return type of F.
45528f6c2f2SEnji Cooper template <typename T>
45628f6c2f2SEnji Cooper struct Function;
45728f6c2f2SEnji Cooper
45828f6c2f2SEnji Cooper template <typename R, typename... Args>
45928f6c2f2SEnji Cooper struct Function<R(Args...)> {
46028f6c2f2SEnji Cooper using Result = R;
46128f6c2f2SEnji Cooper static constexpr size_t ArgumentCount = sizeof...(Args);
46228f6c2f2SEnji Cooper template <size_t I>
46328f6c2f2SEnji Cooper using Arg = ElemFromList<I, Args...>;
46428f6c2f2SEnji Cooper using ArgumentTuple = std::tuple<Args...>;
46528f6c2f2SEnji Cooper using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
46628f6c2f2SEnji Cooper using MakeResultVoid = void(Args...);
46728f6c2f2SEnji Cooper using MakeResultIgnoredValue = IgnoredValue(Args...);
46828f6c2f2SEnji Cooper };
46928f6c2f2SEnji Cooper
47028f6c2f2SEnji Cooper #ifdef GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
47128f6c2f2SEnji Cooper template <typename R, typename... Args>
47228f6c2f2SEnji Cooper constexpr size_t Function<R(Args...)>::ArgumentCount;
473b89a7cc2SEnji Cooper #endif
474b89a7cc2SEnji Cooper
47528f6c2f2SEnji Cooper // Workaround for MSVC error C2039: 'type': is not a member of 'std'
47628f6c2f2SEnji Cooper // when std::tuple_element is used.
47728f6c2f2SEnji Cooper // See: https://github.com/google/googletest/issues/3931
47828f6c2f2SEnji Cooper // Can be replaced with std::tuple_element_t in C++14.
47928f6c2f2SEnji Cooper template <size_t I, typename T>
48028f6c2f2SEnji Cooper using TupleElement = typename std::tuple_element<I, T>::type;
481b89a7cc2SEnji Cooper
48228f6c2f2SEnji Cooper bool Base64Unescape(const std::string& encoded, std::string* decoded);
48328f6c2f2SEnji Cooper
48428f6c2f2SEnji Cooper GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 4805
485b89a7cc2SEnji Cooper
486b89a7cc2SEnji Cooper } // namespace internal
487b89a7cc2SEnji Cooper } // namespace testing
488b89a7cc2SEnji Cooper
48928f6c2f2SEnji Cooper #endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
490