1f92157deSopenharmony_ci// Copyright 2007, Google Inc.
2f92157deSopenharmony_ci// All rights reserved.
3f92157deSopenharmony_ci//
4f92157deSopenharmony_ci// Redistribution and use in source and binary forms, with or without
5f92157deSopenharmony_ci// modification, are permitted provided that the following conditions are
6f92157deSopenharmony_ci// met:
7f92157deSopenharmony_ci//
8f92157deSopenharmony_ci//     * Redistributions of source code must retain the above copyright
9f92157deSopenharmony_ci// notice, this list of conditions and the following disclaimer.
10f92157deSopenharmony_ci//     * Redistributions in binary form must reproduce the above
11f92157deSopenharmony_ci// copyright notice, this list of conditions and the following disclaimer
12f92157deSopenharmony_ci// in the documentation and/or other materials provided with the
13f92157deSopenharmony_ci// distribution.
14f92157deSopenharmony_ci//     * Neither the name of Google Inc. nor the names of its
15f92157deSopenharmony_ci// contributors may be used to endorse or promote products derived from
16f92157deSopenharmony_ci// this software without specific prior written permission.
17f92157deSopenharmony_ci//
18f92157deSopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19f92157deSopenharmony_ci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20f92157deSopenharmony_ci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21f92157deSopenharmony_ci// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22f92157deSopenharmony_ci// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23f92157deSopenharmony_ci// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24f92157deSopenharmony_ci// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25f92157deSopenharmony_ci// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26f92157deSopenharmony_ci// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27f92157deSopenharmony_ci// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28f92157deSopenharmony_ci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29f92157deSopenharmony_ci
30f92157deSopenharmony_ci// Google Mock - a framework for writing C++ mock classes.
31f92157deSopenharmony_ci//
32f92157deSopenharmony_ci// This file defines some utilities useful for implementing Google
33f92157deSopenharmony_ci// Mock.  They are subject to change without notice, so please DO NOT
34f92157deSopenharmony_ci// USE THEM IN USER CODE.
35f92157deSopenharmony_ci
36f92157deSopenharmony_ci// IWYU pragma: private, include "gmock/gmock.h"
37f92157deSopenharmony_ci// IWYU pragma: friend gmock/.*
38f92157deSopenharmony_ci
39f92157deSopenharmony_ci#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
40f92157deSopenharmony_ci#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
41f92157deSopenharmony_ci
42f92157deSopenharmony_ci#include <stdio.h>
43f92157deSopenharmony_ci
44f92157deSopenharmony_ci#include <ostream>  // NOLINT
45f92157deSopenharmony_ci#include <string>
46f92157deSopenharmony_ci#include <type_traits>
47f92157deSopenharmony_ci#include <vector>
48f92157deSopenharmony_ci
49f92157deSopenharmony_ci#include "gmock/internal/gmock-port.h"
50f92157deSopenharmony_ci#include "gtest/gtest.h"
51f92157deSopenharmony_ci
52f92157deSopenharmony_cinamespace testing {
53f92157deSopenharmony_ci
54f92157deSopenharmony_citemplate <typename>
55f92157deSopenharmony_ciclass Matcher;
56f92157deSopenharmony_ci
57f92157deSopenharmony_cinamespace internal {
58f92157deSopenharmony_ci
59f92157deSopenharmony_ci// Silence MSVC C4100 (unreferenced formal parameter) and
60f92157deSopenharmony_ci// C4805('==': unsafe mix of type 'const int' and type 'const bool')
61f92157deSopenharmony_ci#ifdef _MSC_VER
62f92157deSopenharmony_ci#pragma warning(push)
63f92157deSopenharmony_ci#pragma warning(disable : 4100)
64f92157deSopenharmony_ci#pragma warning(disable : 4805)
65f92157deSopenharmony_ci#endif
66f92157deSopenharmony_ci
67f92157deSopenharmony_ci// Joins a vector of strings as if they are fields of a tuple; returns
68f92157deSopenharmony_ci// the joined string.
69f92157deSopenharmony_ciGTEST_API_ std::string JoinAsKeyValueTuple(
70f92157deSopenharmony_ci    const std::vector<const char*>& names, const Strings& values);
71f92157deSopenharmony_ci
72f92157deSopenharmony_ci// Converts an identifier name to a space-separated list of lower-case
73f92157deSopenharmony_ci// words.  Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
74f92157deSopenharmony_ci// treated as one word.  For example, both "FooBar123" and
75f92157deSopenharmony_ci// "foo_bar_123" are converted to "foo bar 123".
76f92157deSopenharmony_ciGTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name);
77f92157deSopenharmony_ci
78f92157deSopenharmony_ci// GetRawPointer(p) returns the raw pointer underlying p when p is a
79f92157deSopenharmony_ci// smart pointer, or returns p itself when p is already a raw pointer.
80f92157deSopenharmony_ci// The following default implementation is for the smart pointer case.
81f92157deSopenharmony_citemplate <typename Pointer>
82f92157deSopenharmony_ciinline const typename Pointer::element_type* GetRawPointer(const Pointer& p) {
83f92157deSopenharmony_ci  return p.get();
84f92157deSopenharmony_ci}
85f92157deSopenharmony_ci// This overload version is for std::reference_wrapper, which does not work with
86f92157deSopenharmony_ci// the overload above, as it does not have an `element_type`.
87f92157deSopenharmony_citemplate <typename Element>
88f92157deSopenharmony_ciinline const Element* GetRawPointer(const std::reference_wrapper<Element>& r) {
89f92157deSopenharmony_ci  return &r.get();
90f92157deSopenharmony_ci}
91f92157deSopenharmony_ci
92f92157deSopenharmony_ci// This overloaded version is for the raw pointer case.
93f92157deSopenharmony_citemplate <typename Element>
94f92157deSopenharmony_ciinline Element* GetRawPointer(Element* p) {
95f92157deSopenharmony_ci  return p;
96f92157deSopenharmony_ci}
97f92157deSopenharmony_ci
98f92157deSopenharmony_ci// Default definitions for all compilers.
99f92157deSopenharmony_ci// NOTE: If you implement support for other compilers, make sure to avoid
100f92157deSopenharmony_ci// unexpected overlaps.
101f92157deSopenharmony_ci// (e.g., Clang also processes #pragma GCC, and clang-cl also handles _MSC_VER.)
102f92157deSopenharmony_ci#define GMOCK_INTERNAL_WARNING_PUSH()
103f92157deSopenharmony_ci#define GMOCK_INTERNAL_WARNING_CLANG(Level, Name)
104f92157deSopenharmony_ci#define GMOCK_INTERNAL_WARNING_POP()
105f92157deSopenharmony_ci
106f92157deSopenharmony_ci#if defined(__clang__)
107f92157deSopenharmony_ci#undef GMOCK_INTERNAL_WARNING_PUSH
108f92157deSopenharmony_ci#define GMOCK_INTERNAL_WARNING_PUSH() _Pragma("clang diagnostic push")
109f92157deSopenharmony_ci#undef GMOCK_INTERNAL_WARNING_CLANG
110f92157deSopenharmony_ci#define GMOCK_INTERNAL_WARNING_CLANG(Level, Warning) \
111f92157deSopenharmony_ci  _Pragma(GMOCK_PP_INTERNAL_STRINGIZE(clang diagnostic Level Warning))
112f92157deSopenharmony_ci#undef GMOCK_INTERNAL_WARNING_POP
113f92157deSopenharmony_ci#define GMOCK_INTERNAL_WARNING_POP() _Pragma("clang diagnostic pop")
114f92157deSopenharmony_ci#endif
115f92157deSopenharmony_ci
116f92157deSopenharmony_ci// MSVC treats wchar_t as a native type usually, but treats it as the
117f92157deSopenharmony_ci// same as unsigned short when the compiler option /Zc:wchar_t- is
118f92157deSopenharmony_ci// specified.  It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t
119f92157deSopenharmony_ci// is a native type.
120f92157deSopenharmony_ci#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED)
121f92157deSopenharmony_ci// wchar_t is a typedef.
122f92157deSopenharmony_ci#else
123f92157deSopenharmony_ci#define GMOCK_WCHAR_T_IS_NATIVE_ 1
124f92157deSopenharmony_ci#endif
125f92157deSopenharmony_ci
126f92157deSopenharmony_ci// In what follows, we use the term "kind" to indicate whether a type
127f92157deSopenharmony_ci// is bool, an integer type (excluding bool), a floating-point type,
128f92157deSopenharmony_ci// or none of them.  This categorization is useful for determining
129f92157deSopenharmony_ci// when a matcher argument type can be safely converted to another
130f92157deSopenharmony_ci// type in the implementation of SafeMatcherCast.
131f92157deSopenharmony_cienum TypeKind { kBool, kInteger, kFloatingPoint, kOther };
132f92157deSopenharmony_ci
133f92157deSopenharmony_ci// KindOf<T>::value is the kind of type T.
134f92157deSopenharmony_citemplate <typename T>
135f92157deSopenharmony_cistruct KindOf {
136f92157deSopenharmony_ci  enum { value = kOther };  // The default kind.
137f92157deSopenharmony_ci};
138f92157deSopenharmony_ci
139f92157deSopenharmony_ci// This macro declares that the kind of 'type' is 'kind'.
140f92157deSopenharmony_ci#define GMOCK_DECLARE_KIND_(type, kind) \
141f92157deSopenharmony_ci  template <>                           \
142f92157deSopenharmony_ci  struct KindOf<type> {                 \
143f92157deSopenharmony_ci    enum { value = kind };              \
144f92157deSopenharmony_ci  }
145f92157deSopenharmony_ci
146f92157deSopenharmony_ciGMOCK_DECLARE_KIND_(bool, kBool);
147f92157deSopenharmony_ci
148f92157deSopenharmony_ci// All standard integer types.
149f92157deSopenharmony_ciGMOCK_DECLARE_KIND_(char, kInteger);
150f92157deSopenharmony_ciGMOCK_DECLARE_KIND_(signed char, kInteger);
151f92157deSopenharmony_ciGMOCK_DECLARE_KIND_(unsigned char, kInteger);
152f92157deSopenharmony_ciGMOCK_DECLARE_KIND_(short, kInteger);           // NOLINT
153f92157deSopenharmony_ciGMOCK_DECLARE_KIND_(unsigned short, kInteger);  // NOLINT
154f92157deSopenharmony_ciGMOCK_DECLARE_KIND_(int, kInteger);
155f92157deSopenharmony_ciGMOCK_DECLARE_KIND_(unsigned int, kInteger);
156f92157deSopenharmony_ciGMOCK_DECLARE_KIND_(long, kInteger);                // NOLINT
157f92157deSopenharmony_ciGMOCK_DECLARE_KIND_(unsigned long, kInteger);       // NOLINT
158f92157deSopenharmony_ciGMOCK_DECLARE_KIND_(long long, kInteger);           // NOLINT
159f92157deSopenharmony_ciGMOCK_DECLARE_KIND_(unsigned long long, kInteger);  // NOLINT
160f92157deSopenharmony_ci
161f92157deSopenharmony_ci#if GMOCK_WCHAR_T_IS_NATIVE_
162f92157deSopenharmony_ciGMOCK_DECLARE_KIND_(wchar_t, kInteger);
163f92157deSopenharmony_ci#endif
164f92157deSopenharmony_ci
165f92157deSopenharmony_ci// All standard floating-point types.
166f92157deSopenharmony_ciGMOCK_DECLARE_KIND_(float, kFloatingPoint);
167f92157deSopenharmony_ciGMOCK_DECLARE_KIND_(double, kFloatingPoint);
168f92157deSopenharmony_ciGMOCK_DECLARE_KIND_(long double, kFloatingPoint);
169f92157deSopenharmony_ci
170f92157deSopenharmony_ci#undef GMOCK_DECLARE_KIND_
171f92157deSopenharmony_ci
172f92157deSopenharmony_ci// Evaluates to the kind of 'type'.
173f92157deSopenharmony_ci#define GMOCK_KIND_OF_(type)                   \
174f92157deSopenharmony_ci  static_cast< ::testing::internal::TypeKind>( \
175f92157deSopenharmony_ci      ::testing::internal::KindOf<type>::value)
176f92157deSopenharmony_ci
177f92157deSopenharmony_ci// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value
178f92157deSopenharmony_ci// is true if and only if arithmetic type From can be losslessly converted to
179f92157deSopenharmony_ci// arithmetic type To.
180f92157deSopenharmony_ci//
181f92157deSopenharmony_ci// It's the user's responsibility to ensure that both From and To are
182f92157deSopenharmony_ci// raw (i.e. has no CV modifier, is not a pointer, and is not a
183f92157deSopenharmony_ci// reference) built-in arithmetic types, kFromKind is the kind of
184f92157deSopenharmony_ci// From, and kToKind is the kind of To; the value is
185f92157deSopenharmony_ci// implementation-defined when the above pre-condition is violated.
186f92157deSopenharmony_citemplate <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>
187f92157deSopenharmony_ciusing LosslessArithmeticConvertibleImpl = std::integral_constant<
188f92157deSopenharmony_ci    bool,
189f92157deSopenharmony_ci    // clang-format off
190f92157deSopenharmony_ci      // Converting from bool is always lossless
191f92157deSopenharmony_ci      (kFromKind == kBool) ? true
192f92157deSopenharmony_ci      // Converting between any other type kinds will be lossy if the type
193f92157deSopenharmony_ci      // kinds are not the same.
194f92157deSopenharmony_ci    : (kFromKind != kToKind) ? false
195f92157deSopenharmony_ci    : (kFromKind == kInteger &&
196f92157deSopenharmony_ci       // Converting between integers of different widths is allowed so long
197f92157deSopenharmony_ci       // as the conversion does not go from signed to unsigned.
198f92157deSopenharmony_ci      (((sizeof(From) < sizeof(To)) &&
199f92157deSopenharmony_ci        !(std::is_signed<From>::value && !std::is_signed<To>::value)) ||
200f92157deSopenharmony_ci       // Converting between integers of the same width only requires the
201f92157deSopenharmony_ci       // two types to have the same signedness.
202f92157deSopenharmony_ci       ((sizeof(From) == sizeof(To)) &&
203f92157deSopenharmony_ci        (std::is_signed<From>::value == std::is_signed<To>::value)))
204f92157deSopenharmony_ci       ) ? true
205f92157deSopenharmony_ci      // Floating point conversions are lossless if and only if `To` is at least
206f92157deSopenharmony_ci      // as wide as `From`.
207f92157deSopenharmony_ci    : (kFromKind == kFloatingPoint && (sizeof(From) <= sizeof(To))) ? true
208f92157deSopenharmony_ci    : false
209f92157deSopenharmony_ci    // clang-format on
210f92157deSopenharmony_ci    >;
211f92157deSopenharmony_ci
212f92157deSopenharmony_ci// LosslessArithmeticConvertible<From, To>::value is true if and only if
213f92157deSopenharmony_ci// arithmetic type From can be losslessly converted to arithmetic type To.
214f92157deSopenharmony_ci//
215f92157deSopenharmony_ci// It's the user's responsibility to ensure that both From and To are
216f92157deSopenharmony_ci// raw (i.e. has no CV modifier, is not a pointer, and is not a
217f92157deSopenharmony_ci// reference) built-in arithmetic types; the value is
218f92157deSopenharmony_ci// implementation-defined when the above pre-condition is violated.
219f92157deSopenharmony_citemplate <typename From, typename To>
220f92157deSopenharmony_ciusing LosslessArithmeticConvertible =
221f92157deSopenharmony_ci    LosslessArithmeticConvertibleImpl<GMOCK_KIND_OF_(From), From,
222f92157deSopenharmony_ci                                      GMOCK_KIND_OF_(To), To>;
223f92157deSopenharmony_ci
224f92157deSopenharmony_ci// This interface knows how to report a Google Mock failure (either
225f92157deSopenharmony_ci// non-fatal or fatal).
226f92157deSopenharmony_ciclass FailureReporterInterface {
227f92157deSopenharmony_ci public:
228f92157deSopenharmony_ci  // The type of a failure (either non-fatal or fatal).
229f92157deSopenharmony_ci  enum FailureType { kNonfatal, kFatal };
230f92157deSopenharmony_ci
231f92157deSopenharmony_ci  virtual ~FailureReporterInterface() {}
232f92157deSopenharmony_ci
233f92157deSopenharmony_ci  // Reports a failure that occurred at the given source file location.
234f92157deSopenharmony_ci  virtual void ReportFailure(FailureType type, const char* file, int line,
235f92157deSopenharmony_ci                             const std::string& message) = 0;
236f92157deSopenharmony_ci};
237f92157deSopenharmony_ci
238f92157deSopenharmony_ci// Returns the failure reporter used by Google Mock.
239f92157deSopenharmony_ciGTEST_API_ FailureReporterInterface* GetFailureReporter();
240f92157deSopenharmony_ci
241f92157deSopenharmony_ci// Asserts that condition is true; aborts the process with the given
242f92157deSopenharmony_ci// message if condition is false.  We cannot use LOG(FATAL) or CHECK()
243f92157deSopenharmony_ci// as Google Mock might be used to mock the log sink itself.  We
244f92157deSopenharmony_ci// inline this function to prevent it from showing up in the stack
245f92157deSopenharmony_ci// trace.
246f92157deSopenharmony_ciinline void Assert(bool condition, const char* file, int line,
247f92157deSopenharmony_ci                   const std::string& msg) {
248f92157deSopenharmony_ci  if (!condition) {
249f92157deSopenharmony_ci    GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal, file,
250f92157deSopenharmony_ci                                        line, msg);
251f92157deSopenharmony_ci  }
252f92157deSopenharmony_ci}
253f92157deSopenharmony_ciinline void Assert(bool condition, const char* file, int line) {
254f92157deSopenharmony_ci  Assert(condition, file, line, "Assertion failed.");
255f92157deSopenharmony_ci}
256f92157deSopenharmony_ci
257f92157deSopenharmony_ci// Verifies that condition is true; generates a non-fatal failure if
258f92157deSopenharmony_ci// condition is false.
259f92157deSopenharmony_ciinline void Expect(bool condition, const char* file, int line,
260f92157deSopenharmony_ci                   const std::string& msg) {
261f92157deSopenharmony_ci  if (!condition) {
262f92157deSopenharmony_ci    GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal,
263f92157deSopenharmony_ci                                        file, line, msg);
264f92157deSopenharmony_ci  }
265f92157deSopenharmony_ci}
266f92157deSopenharmony_ciinline void Expect(bool condition, const char* file, int line) {
267f92157deSopenharmony_ci  Expect(condition, file, line, "Expectation failed.");
268f92157deSopenharmony_ci}
269f92157deSopenharmony_ci
270f92157deSopenharmony_ci// Severity level of a log.
271f92157deSopenharmony_cienum LogSeverity { kInfo = 0, kWarning = 1 };
272f92157deSopenharmony_ci
273f92157deSopenharmony_ci// Valid values for the --gmock_verbose flag.
274f92157deSopenharmony_ci
275f92157deSopenharmony_ci// All logs (informational and warnings) are printed.
276f92157deSopenharmony_ciconst char kInfoVerbosity[] = "info";
277f92157deSopenharmony_ci// Only warnings are printed.
278f92157deSopenharmony_ciconst char kWarningVerbosity[] = "warning";
279f92157deSopenharmony_ci// No logs are printed.
280f92157deSopenharmony_ciconst char kErrorVerbosity[] = "error";
281f92157deSopenharmony_ci
282f92157deSopenharmony_ci// Returns true if and only if a log with the given severity is visible
283f92157deSopenharmony_ci// according to the --gmock_verbose flag.
284f92157deSopenharmony_ciGTEST_API_ bool LogIsVisible(LogSeverity severity);
285f92157deSopenharmony_ci
286f92157deSopenharmony_ci// Prints the given message to stdout if and only if 'severity' >= the level
287f92157deSopenharmony_ci// specified by the --gmock_verbose flag.  If stack_frames_to_skip >=
288f92157deSopenharmony_ci// 0, also prints the stack trace excluding the top
289f92157deSopenharmony_ci// stack_frames_to_skip frames.  In opt mode, any positive
290f92157deSopenharmony_ci// stack_frames_to_skip is treated as 0, since we don't know which
291f92157deSopenharmony_ci// function calls will be inlined by the compiler and need to be
292f92157deSopenharmony_ci// conservative.
293f92157deSopenharmony_ciGTEST_API_ void Log(LogSeverity severity, const std::string& message,
294f92157deSopenharmony_ci                    int stack_frames_to_skip);
295f92157deSopenharmony_ci
296f92157deSopenharmony_ci// A marker class that is used to resolve parameterless expectations to the
297f92157deSopenharmony_ci// correct overload. This must not be instantiable, to prevent client code from
298f92157deSopenharmony_ci// accidentally resolving to the overload; for example:
299f92157deSopenharmony_ci//
300f92157deSopenharmony_ci//    ON_CALL(mock, Method({}, nullptr))...
301f92157deSopenharmony_ci//
302f92157deSopenharmony_ciclass WithoutMatchers {
303f92157deSopenharmony_ci private:
304f92157deSopenharmony_ci  WithoutMatchers() {}
305f92157deSopenharmony_ci  friend GTEST_API_ WithoutMatchers GetWithoutMatchers();
306f92157deSopenharmony_ci};
307f92157deSopenharmony_ci
308f92157deSopenharmony_ci// Internal use only: access the singleton instance of WithoutMatchers.
309f92157deSopenharmony_ciGTEST_API_ WithoutMatchers GetWithoutMatchers();
310f92157deSopenharmony_ci
311f92157deSopenharmony_ci// Invalid<T>() is usable as an expression of type T, but will terminate
312f92157deSopenharmony_ci// the program with an assertion failure if actually run.  This is useful
313f92157deSopenharmony_ci// when a value of type T is needed for compilation, but the statement
314f92157deSopenharmony_ci// will not really be executed (or we don't care if the statement
315f92157deSopenharmony_ci// crashes).
316f92157deSopenharmony_citemplate <typename T>
317f92157deSopenharmony_ciinline T Invalid() {
318f92157deSopenharmony_ci  Assert(false, "", -1, "Internal error: attempt to return invalid value");
319f92157deSopenharmony_ci#if defined(__GNUC__) || defined(__clang__)
320f92157deSopenharmony_ci  __builtin_unreachable();
321f92157deSopenharmony_ci#elif defined(_MSC_VER)
322f92157deSopenharmony_ci  __assume(0);
323f92157deSopenharmony_ci#else
324f92157deSopenharmony_ci  return Invalid<T>();
325f92157deSopenharmony_ci#endif
326f92157deSopenharmony_ci}
327f92157deSopenharmony_ci
328f92157deSopenharmony_ci// Given a raw type (i.e. having no top-level reference or const
329f92157deSopenharmony_ci// modifier) RawContainer that's either an STL-style container or a
330f92157deSopenharmony_ci// native array, class StlContainerView<RawContainer> has the
331f92157deSopenharmony_ci// following members:
332f92157deSopenharmony_ci//
333f92157deSopenharmony_ci//   - type is a type that provides an STL-style container view to
334f92157deSopenharmony_ci//     (i.e. implements the STL container concept for) RawContainer;
335f92157deSopenharmony_ci//   - const_reference is a type that provides a reference to a const
336f92157deSopenharmony_ci//     RawContainer;
337f92157deSopenharmony_ci//   - ConstReference(raw_container) returns a const reference to an STL-style
338f92157deSopenharmony_ci//     container view to raw_container, which is a RawContainer.
339f92157deSopenharmony_ci//   - Copy(raw_container) returns an STL-style container view of a
340f92157deSopenharmony_ci//     copy of raw_container, which is a RawContainer.
341f92157deSopenharmony_ci//
342f92157deSopenharmony_ci// This generic version is used when RawContainer itself is already an
343f92157deSopenharmony_ci// STL-style container.
344f92157deSopenharmony_citemplate <class RawContainer>
345f92157deSopenharmony_ciclass StlContainerView {
346f92157deSopenharmony_ci public:
347f92157deSopenharmony_ci  typedef RawContainer type;
348f92157deSopenharmony_ci  typedef const type& const_reference;
349f92157deSopenharmony_ci
350f92157deSopenharmony_ci  static const_reference ConstReference(const RawContainer& container) {
351f92157deSopenharmony_ci    static_assert(!std::is_const<RawContainer>::value,
352f92157deSopenharmony_ci                  "RawContainer type must not be const");
353f92157deSopenharmony_ci    return container;
354f92157deSopenharmony_ci  }
355f92157deSopenharmony_ci  static type Copy(const RawContainer& container) { return container; }
356f92157deSopenharmony_ci};
357f92157deSopenharmony_ci
358f92157deSopenharmony_ci// This specialization is used when RawContainer is a native array type.
359f92157deSopenharmony_citemplate <typename Element, size_t N>
360f92157deSopenharmony_ciclass StlContainerView<Element[N]> {
361f92157deSopenharmony_ci public:
362f92157deSopenharmony_ci  typedef typename std::remove_const<Element>::type RawElement;
363f92157deSopenharmony_ci  typedef internal::NativeArray<RawElement> type;
364f92157deSopenharmony_ci  // NativeArray<T> can represent a native array either by value or by
365f92157deSopenharmony_ci  // reference (selected by a constructor argument), so 'const type'
366f92157deSopenharmony_ci  // can be used to reference a const native array.  We cannot
367f92157deSopenharmony_ci  // 'typedef const type& const_reference' here, as that would mean
368f92157deSopenharmony_ci  // ConstReference() has to return a reference to a local variable.
369f92157deSopenharmony_ci  typedef const type const_reference;
370f92157deSopenharmony_ci
371f92157deSopenharmony_ci  static const_reference ConstReference(const Element (&array)[N]) {
372f92157deSopenharmony_ci    static_assert(std::is_same<Element, RawElement>::value,
373f92157deSopenharmony_ci                  "Element type must not be const");
374f92157deSopenharmony_ci    return type(array, N, RelationToSourceReference());
375f92157deSopenharmony_ci  }
376f92157deSopenharmony_ci  static type Copy(const Element (&array)[N]) {
377f92157deSopenharmony_ci    return type(array, N, RelationToSourceCopy());
378f92157deSopenharmony_ci  }
379f92157deSopenharmony_ci};
380f92157deSopenharmony_ci
381f92157deSopenharmony_ci// This specialization is used when RawContainer is a native array
382f92157deSopenharmony_ci// represented as a (pointer, size) tuple.
383f92157deSopenharmony_citemplate <typename ElementPointer, typename Size>
384f92157deSopenharmony_ciclass StlContainerView< ::std::tuple<ElementPointer, Size> > {
385f92157deSopenharmony_ci public:
386f92157deSopenharmony_ci  typedef typename std::remove_const<
387f92157deSopenharmony_ci      typename std::pointer_traits<ElementPointer>::element_type>::type
388f92157deSopenharmony_ci      RawElement;
389f92157deSopenharmony_ci  typedef internal::NativeArray<RawElement> type;
390f92157deSopenharmony_ci  typedef const type const_reference;
391f92157deSopenharmony_ci
392f92157deSopenharmony_ci  static const_reference ConstReference(
393f92157deSopenharmony_ci      const ::std::tuple<ElementPointer, Size>& array) {
394f92157deSopenharmony_ci    return type(std::get<0>(array), std::get<1>(array),
395f92157deSopenharmony_ci                RelationToSourceReference());
396f92157deSopenharmony_ci  }
397f92157deSopenharmony_ci  static type Copy(const ::std::tuple<ElementPointer, Size>& array) {
398f92157deSopenharmony_ci    return type(std::get<0>(array), std::get<1>(array), RelationToSourceCopy());
399f92157deSopenharmony_ci  }
400f92157deSopenharmony_ci};
401f92157deSopenharmony_ci
402f92157deSopenharmony_ci// The following specialization prevents the user from instantiating
403f92157deSopenharmony_ci// StlContainer with a reference type.
404f92157deSopenharmony_citemplate <typename T>
405f92157deSopenharmony_ciclass StlContainerView<T&>;
406f92157deSopenharmony_ci
407f92157deSopenharmony_ci// A type transform to remove constness from the first part of a pair.
408f92157deSopenharmony_ci// Pairs like that are used as the value_type of associative containers,
409f92157deSopenharmony_ci// and this transform produces a similar but assignable pair.
410f92157deSopenharmony_citemplate <typename T>
411f92157deSopenharmony_cistruct RemoveConstFromKey {
412f92157deSopenharmony_ci  typedef T type;
413f92157deSopenharmony_ci};
414f92157deSopenharmony_ci
415f92157deSopenharmony_ci// Partially specialized to remove constness from std::pair<const K, V>.
416f92157deSopenharmony_citemplate <typename K, typename V>
417f92157deSopenharmony_cistruct RemoveConstFromKey<std::pair<const K, V> > {
418f92157deSopenharmony_ci  typedef std::pair<K, V> type;
419f92157deSopenharmony_ci};
420f92157deSopenharmony_ci
421f92157deSopenharmony_ci// Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to
422f92157deSopenharmony_ci// reduce code size.
423f92157deSopenharmony_ciGTEST_API_ void IllegalDoDefault(const char* file, int line);
424f92157deSopenharmony_ci
425f92157deSopenharmony_citemplate <typename F, typename Tuple, size_t... Idx>
426f92157deSopenharmony_ciauto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>)
427f92157deSopenharmony_ci    -> decltype(std::forward<F>(f)(
428f92157deSopenharmony_ci        std::get<Idx>(std::forward<Tuple>(args))...)) {
429f92157deSopenharmony_ci  return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);
430f92157deSopenharmony_ci}
431f92157deSopenharmony_ci
432f92157deSopenharmony_ci// Apply the function to a tuple of arguments.
433f92157deSopenharmony_citemplate <typename F, typename Tuple>
434f92157deSopenharmony_ciauto Apply(F&& f, Tuple&& args) -> decltype(ApplyImpl(
435f92157deSopenharmony_ci    std::forward<F>(f), std::forward<Tuple>(args),
436f92157deSopenharmony_ci    MakeIndexSequence<std::tuple_size<
437f92157deSopenharmony_ci        typename std::remove_reference<Tuple>::type>::value>())) {
438f92157deSopenharmony_ci  return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
439f92157deSopenharmony_ci                   MakeIndexSequence<std::tuple_size<
440f92157deSopenharmony_ci                       typename std::remove_reference<Tuple>::type>::value>());
441f92157deSopenharmony_ci}
442f92157deSopenharmony_ci
443f92157deSopenharmony_ci// Template struct Function<F>, where F must be a function type, contains
444f92157deSopenharmony_ci// the following typedefs:
445f92157deSopenharmony_ci//
446f92157deSopenharmony_ci//   Result:               the function's return type.
447f92157deSopenharmony_ci//   Arg<N>:               the type of the N-th argument, where N starts with 0.
448f92157deSopenharmony_ci//   ArgumentTuple:        the tuple type consisting of all parameters of F.
449f92157deSopenharmony_ci//   ArgumentMatcherTuple: the tuple type consisting of Matchers for all
450f92157deSopenharmony_ci//                         parameters of F.
451f92157deSopenharmony_ci//   MakeResultVoid:       the function type obtained by substituting void
452f92157deSopenharmony_ci//                         for the return type of F.
453f92157deSopenharmony_ci//   MakeResultIgnoredValue:
454f92157deSopenharmony_ci//                         the function type obtained by substituting Something
455f92157deSopenharmony_ci//                         for the return type of F.
456f92157deSopenharmony_citemplate <typename T>
457f92157deSopenharmony_cistruct Function;
458f92157deSopenharmony_ci
459f92157deSopenharmony_citemplate <typename R, typename... Args>
460f92157deSopenharmony_cistruct Function<R(Args...)> {
461f92157deSopenharmony_ci  using Result = R;
462f92157deSopenharmony_ci  static constexpr size_t ArgumentCount = sizeof...(Args);
463f92157deSopenharmony_ci  template <size_t I>
464f92157deSopenharmony_ci  using Arg = ElemFromList<I, Args...>;
465f92157deSopenharmony_ci  using ArgumentTuple = std::tuple<Args...>;
466f92157deSopenharmony_ci  using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
467f92157deSopenharmony_ci  using MakeResultVoid = void(Args...);
468f92157deSopenharmony_ci  using MakeResultIgnoredValue = IgnoredValue(Args...);
469f92157deSopenharmony_ci};
470f92157deSopenharmony_ci
471f92157deSopenharmony_citemplate <typename R, typename... Args>
472f92157deSopenharmony_ciconstexpr size_t Function<R(Args...)>::ArgumentCount;
473f92157deSopenharmony_ci
474f92157deSopenharmony_ci// Workaround for MSVC error C2039: 'type': is not a member of 'std'
475f92157deSopenharmony_ci// when std::tuple_element is used.
476f92157deSopenharmony_ci// See: https://github.com/google/googletest/issues/3931
477f92157deSopenharmony_ci// Can be replaced with std::tuple_element_t in C++14.
478f92157deSopenharmony_citemplate <size_t I, typename T>
479f92157deSopenharmony_ciusing TupleElement = typename std::tuple_element<I, T>::type;
480f92157deSopenharmony_ci
481f92157deSopenharmony_cibool Base64Unescape(const std::string& encoded, std::string* decoded);
482f92157deSopenharmony_ci
483f92157deSopenharmony_ci#ifdef _MSC_VER
484f92157deSopenharmony_ci#pragma warning(pop)
485f92157deSopenharmony_ci#endif
486f92157deSopenharmony_ci
487f92157deSopenharmony_ci}  // namespace internal
488f92157deSopenharmony_ci}  // namespace testing
489f92157deSopenharmony_ci
490f92157deSopenharmony_ci#endif  // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
491