1 | // Copyright 2007, Google Inc. |
2 | // All rights reserved. |
3 | // |
4 | // Redistribution and use in source and binary forms, with or without |
5 | // modification, are permitted provided that the following conditions are |
6 | // met: |
7 | // |
8 | // * Redistributions of source code must retain the above copyright |
9 | // notice, this list of conditions and the following disclaimer. |
10 | // * Redistributions in binary form must reproduce the above |
11 | // copyright notice, this list of conditions and the following disclaimer |
12 | // in the documentation and/or other materials provided with the |
13 | // distribution. |
14 | // * Neither the name of Google Inc. nor the names of its |
15 | // contributors may be used to endorse or promote products derived from |
16 | // this software without specific prior written permission. |
17 | // |
18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | |
30 | |
31 | // Google Mock - a framework for writing C++ mock classes. |
32 | // |
33 | // This file defines some utilities useful for implementing Google |
34 | // Mock. They are subject to change without notice, so please DO NOT |
35 | // USE THEM IN USER CODE. |
36 | |
37 | // GOOGLETEST_CM0002 DO NOT DELETE |
38 | |
39 | #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ |
40 | #define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ |
41 | |
42 | #include <stdio.h> |
43 | #include <ostream> // NOLINT |
44 | #include <string> |
45 | #include <type_traits> |
46 | #include "gmock/internal/gmock-port.h" |
47 | #include "gtest/gtest.h" |
48 | |
49 | namespace testing { |
50 | |
51 | template <typename> |
52 | class Matcher; |
53 | |
54 | namespace internal { |
55 | |
56 | // Silence MSVC C4100 (unreferenced formal parameter) and |
57 | // C4805('==': unsafe mix of type 'const int' and type 'const bool') |
58 | #ifdef _MSC_VER |
59 | # pragma warning(push) |
60 | # pragma warning(disable:4100) |
61 | # pragma warning(disable:4805) |
62 | #endif |
63 | |
64 | // Joins a vector of strings as if they are fields of a tuple; returns |
65 | // the joined string. |
66 | GTEST_API_ std::string JoinAsTuple(const Strings& fields); |
67 | |
68 | // Converts an identifier name to a space-separated list of lower-case |
69 | // words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is |
70 | // treated as one word. For example, both "FooBar123" and |
71 | // "foo_bar_123" are converted to "foo bar 123". |
72 | GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name); |
73 | |
74 | // PointeeOf<Pointer>::type is the type of a value pointed to by a |
75 | // Pointer, which can be either a smart pointer or a raw pointer. The |
76 | // following default implementation is for the case where Pointer is a |
77 | // smart pointer. |
78 | template <typename Pointer> |
79 | struct PointeeOf { |
80 | // Smart pointer classes define type element_type as the type of |
81 | // their pointees. |
82 | typedef typename Pointer::element_type type; |
83 | }; |
84 | // This specialization is for the raw pointer case. |
85 | template <typename T> |
86 | struct PointeeOf<T*> { typedef T type; }; // NOLINT |
87 | |
88 | // GetRawPointer(p) returns the raw pointer underlying p when p is a |
89 | // smart pointer, or returns p itself when p is already a raw pointer. |
90 | // The following default implementation is for the smart pointer case. |
91 | template <typename Pointer> |
92 | inline const typename Pointer::element_type* GetRawPointer(const Pointer& p) { |
93 | return p.get(); |
94 | } |
95 | // This overloaded version is for the raw pointer case. |
96 | template <typename Element> |
97 | inline Element* GetRawPointer(Element* p) { return p; } |
98 | |
99 | // MSVC treats wchar_t as a native type usually, but treats it as the |
100 | // same as unsigned short when the compiler option /Zc:wchar_t- is |
101 | // specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t |
102 | // is a native type. |
103 | #if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED) |
104 | // wchar_t is a typedef. |
105 | #else |
106 | # define GMOCK_WCHAR_T_IS_NATIVE_ 1 |
107 | #endif |
108 | |
109 | // signed wchar_t and unsigned wchar_t are NOT in the C++ standard. |
110 | // Using them is a bad practice and not portable. So DON'T use them. |
111 | // |
112 | // Still, Google Mock is designed to work even if the user uses signed |
113 | // wchar_t or unsigned wchar_t (obviously, assuming the compiler |
114 | // supports them). |
115 | // |
116 | // To gcc, |
117 | // wchar_t == signed wchar_t != unsigned wchar_t == unsigned int |
118 | // |
119 | // gcc-9 appears to treat signed/unsigned wchar_t as ill-formed |
120 | // regardless of the signage of its underlying type. |
121 | #ifdef __GNUC__ |
122 | #if !defined(__WCHAR_UNSIGNED__) && (__GNUC__ < 9) |
123 | // signed/unsigned wchar_t are valid types. |
124 | # define GMOCK_HAS_SIGNED_WCHAR_T_ 1 |
125 | #endif |
126 | #endif |
127 | |
128 | // In what follows, we use the term "kind" to indicate whether a type |
129 | // is bool, an integer type (excluding bool), a floating-point type, |
130 | // or none of them. This categorization is useful for determining |
131 | // when a matcher argument type can be safely converted to another |
132 | // type in the implementation of SafeMatcherCast. |
133 | enum TypeKind { |
134 | kBool, kInteger, kFloatingPoint, kOther |
135 | }; |
136 | |
137 | // KindOf<T>::value is the kind of type T. |
138 | template <typename T> struct KindOf { |
139 | enum { value = kOther }; // The default kind. |
140 | }; |
141 | |
142 | // This macro declares that the kind of 'type' is 'kind'. |
143 | #define GMOCK_DECLARE_KIND_(type, kind) \ |
144 | template <> struct KindOf<type> { enum { value = kind }; } |
145 | |
146 | GMOCK_DECLARE_KIND_(bool, kBool); |
147 | |
148 | // All standard integer types. |
149 | GMOCK_DECLARE_KIND_(char, kInteger); |
150 | GMOCK_DECLARE_KIND_(signed char, kInteger); |
151 | GMOCK_DECLARE_KIND_(unsigned char, kInteger); |
152 | GMOCK_DECLARE_KIND_(short, kInteger); // NOLINT |
153 | GMOCK_DECLARE_KIND_(unsigned short, kInteger); // NOLINT |
154 | GMOCK_DECLARE_KIND_(int, kInteger); |
155 | GMOCK_DECLARE_KIND_(unsigned int, kInteger); |
156 | GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT |
157 | GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT |
158 | |
159 | #if GMOCK_WCHAR_T_IS_NATIVE_ |
160 | GMOCK_DECLARE_KIND_(wchar_t, kInteger); |
161 | #endif |
162 | |
163 | // Non-standard integer types. |
164 | GMOCK_DECLARE_KIND_(Int64, kInteger); |
165 | GMOCK_DECLARE_KIND_(UInt64, kInteger); |
166 | |
167 | // All standard floating-point types. |
168 | GMOCK_DECLARE_KIND_(float, kFloatingPoint); |
169 | GMOCK_DECLARE_KIND_(double, kFloatingPoint); |
170 | GMOCK_DECLARE_KIND_(long double, kFloatingPoint); |
171 | |
172 | #undef GMOCK_DECLARE_KIND_ |
173 | |
174 | // Evaluates to the kind of 'type'. |
175 | #define GMOCK_KIND_OF_(type) \ |
176 | static_cast< ::testing::internal::TypeKind>( \ |
177 | ::testing::internal::KindOf<type>::value) |
178 | |
179 | // Evaluates to true iff integer type T is signed. |
180 | #define GMOCK_IS_SIGNED_(T) (static_cast<T>(-1) < 0) |
181 | |
182 | // LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value |
183 | // is true iff arithmetic type From can be losslessly converted to |
184 | // arithmetic type To. |
185 | // |
186 | // It's the user's responsibility to ensure that both From and To are |
187 | // raw (i.e. has no CV modifier, is not a pointer, and is not a |
188 | // reference) built-in arithmetic types, kFromKind is the kind of |
189 | // From, and kToKind is the kind of To; the value is |
190 | // implementation-defined when the above pre-condition is violated. |
191 | template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To> |
192 | struct LosslessArithmeticConvertibleImpl : public false_type {}; |
193 | |
194 | // Converting bool to bool is lossless. |
195 | template <> |
196 | struct LosslessArithmeticConvertibleImpl<kBool, bool, kBool, bool> |
197 | : public true_type {}; // NOLINT |
198 | |
199 | // Converting bool to any integer type is lossless. |
200 | template <typename To> |
201 | struct LosslessArithmeticConvertibleImpl<kBool, bool, kInteger, To> |
202 | : public true_type {}; // NOLINT |
203 | |
204 | // Converting bool to any floating-point type is lossless. |
205 | template <typename To> |
206 | struct LosslessArithmeticConvertibleImpl<kBool, bool, kFloatingPoint, To> |
207 | : public true_type {}; // NOLINT |
208 | |
209 | // Converting an integer to bool is lossy. |
210 | template <typename From> |
211 | struct LosslessArithmeticConvertibleImpl<kInteger, From, kBool, bool> |
212 | : public false_type {}; // NOLINT |
213 | |
214 | // Converting an integer to another non-bool integer is lossless iff |
215 | // the target type's range encloses the source type's range. |
216 | template <typename From, typename To> |
217 | struct LosslessArithmeticConvertibleImpl<kInteger, From, kInteger, To> |
218 | : public bool_constant< |
219 | // When converting from a smaller size to a larger size, we are |
220 | // fine as long as we are not converting from signed to unsigned. |
221 | ((sizeof(From) < sizeof(To)) && |
222 | (!GMOCK_IS_SIGNED_(From) || GMOCK_IS_SIGNED_(To))) || |
223 | // When converting between the same size, the signedness must match. |
224 | ((sizeof(From) == sizeof(To)) && |
225 | (GMOCK_IS_SIGNED_(From) == GMOCK_IS_SIGNED_(To)))> {}; // NOLINT |
226 | |
227 | #undef GMOCK_IS_SIGNED_ |
228 | |
229 | // Converting an integer to a floating-point type may be lossy, since |
230 | // the format of a floating-point number is implementation-defined. |
231 | template <typename From, typename To> |
232 | struct LosslessArithmeticConvertibleImpl<kInteger, From, kFloatingPoint, To> |
233 | : public false_type {}; // NOLINT |
234 | |
235 | // Converting a floating-point to bool is lossy. |
236 | template <typename From> |
237 | struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kBool, bool> |
238 | : public false_type {}; // NOLINT |
239 | |
240 | // Converting a floating-point to an integer is lossy. |
241 | template <typename From, typename To> |
242 | struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kInteger, To> |
243 | : public false_type {}; // NOLINT |
244 | |
245 | // Converting a floating-point to another floating-point is lossless |
246 | // iff the target type is at least as big as the source type. |
247 | template <typename From, typename To> |
248 | struct LosslessArithmeticConvertibleImpl< |
249 | kFloatingPoint, From, kFloatingPoint, To> |
250 | : public bool_constant<sizeof(From) <= sizeof(To)> {}; // NOLINT |
251 | |
252 | // LosslessArithmeticConvertible<From, To>::value is true iff arithmetic |
253 | // type From can be losslessly converted to arithmetic type To. |
254 | // |
255 | // It's the user's responsibility to ensure that both From and To are |
256 | // raw (i.e. has no CV modifier, is not a pointer, and is not a |
257 | // reference) built-in arithmetic types; the value is |
258 | // implementation-defined when the above pre-condition is violated. |
259 | template <typename From, typename To> |
260 | struct LosslessArithmeticConvertible |
261 | : public LosslessArithmeticConvertibleImpl< |
262 | GMOCK_KIND_OF_(From), From, GMOCK_KIND_OF_(To), To> {}; // NOLINT |
263 | |
264 | // This interface knows how to report a Google Mock failure (either |
265 | // non-fatal or fatal). |
266 | class FailureReporterInterface { |
267 | public: |
268 | // The type of a failure (either non-fatal or fatal). |
269 | enum FailureType { |
270 | kNonfatal, kFatal |
271 | }; |
272 | |
273 | virtual ~FailureReporterInterface() {} |
274 | |
275 | // Reports a failure that occurred at the given source file location. |
276 | virtual void ReportFailure(FailureType type, const char* file, int line, |
277 | const std::string& message) = 0; |
278 | }; |
279 | |
280 | // Returns the failure reporter used by Google Mock. |
281 | GTEST_API_ FailureReporterInterface* GetFailureReporter(); |
282 | |
283 | // Asserts that condition is true; aborts the process with the given |
284 | // message if condition is false. We cannot use LOG(FATAL) or CHECK() |
285 | // as Google Mock might be used to mock the log sink itself. We |
286 | // inline this function to prevent it from showing up in the stack |
287 | // trace. |
288 | inline void Assert(bool condition, const char* file, int line, |
289 | const std::string& msg) { |
290 | if (!condition) { |
291 | GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal, |
292 | file, line, msg); |
293 | } |
294 | } |
295 | inline void Assert(bool condition, const char* file, int line) { |
296 | Assert(condition, file, line, "Assertion failed." ); |
297 | } |
298 | |
299 | // Verifies that condition is true; generates a non-fatal failure if |
300 | // condition is false. |
301 | inline void Expect(bool condition, const char* file, int line, |
302 | const std::string& msg) { |
303 | if (!condition) { |
304 | GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal, |
305 | file, line, msg); |
306 | } |
307 | } |
308 | inline void Expect(bool condition, const char* file, int line) { |
309 | Expect(condition, file, line, "Expectation failed." ); |
310 | } |
311 | |
312 | // Severity level of a log. |
313 | enum LogSeverity { |
314 | kInfo = 0, |
315 | kWarning = 1 |
316 | }; |
317 | |
318 | // Valid values for the --gmock_verbose flag. |
319 | |
320 | // All logs (informational and warnings) are printed. |
321 | const char kInfoVerbosity[] = "info" ; |
322 | // Only warnings are printed. |
323 | const char kWarningVerbosity[] = "warning" ; |
324 | // No logs are printed. |
325 | const char kErrorVerbosity[] = "error" ; |
326 | |
327 | // Returns true iff a log with the given severity is visible according |
328 | // to the --gmock_verbose flag. |
329 | GTEST_API_ bool LogIsVisible(LogSeverity severity); |
330 | |
331 | // Prints the given message to stdout iff 'severity' >= the level |
332 | // specified by the --gmock_verbose flag. If stack_frames_to_skip >= |
333 | // 0, also prints the stack trace excluding the top |
334 | // stack_frames_to_skip frames. In opt mode, any positive |
335 | // stack_frames_to_skip is treated as 0, since we don't know which |
336 | // function calls will be inlined by the compiler and need to be |
337 | // conservative. |
338 | GTEST_API_ void Log(LogSeverity severity, const std::string& message, |
339 | int stack_frames_to_skip); |
340 | |
341 | // A marker class that is used to resolve parameterless expectations to the |
342 | // correct overload. This must not be instantiable, to prevent client code from |
343 | // accidentally resolving to the overload; for example: |
344 | // |
345 | // ON_CALL(mock, Method({}, nullptr))... |
346 | // |
347 | class WithoutMatchers { |
348 | private: |
349 | WithoutMatchers() {} |
350 | friend GTEST_API_ WithoutMatchers GetWithoutMatchers(); |
351 | }; |
352 | |
353 | // Internal use only: access the singleton instance of WithoutMatchers. |
354 | GTEST_API_ WithoutMatchers GetWithoutMatchers(); |
355 | |
356 | // Type traits. |
357 | |
358 | // is_reference<T>::value is non-zero iff T is a reference type. |
359 | template <typename T> struct is_reference : public false_type {}; |
360 | template <typename T> struct is_reference<T&> : public true_type {}; |
361 | |
362 | // type_equals<T1, T2>::value is non-zero iff T1 and T2 are the same type. |
363 | template <typename T1, typename T2> struct type_equals : public false_type {}; |
364 | template <typename T> struct type_equals<T, T> : public true_type {}; |
365 | |
366 | // remove_reference<T>::type removes the reference from type T, if any. |
367 | template <typename T> struct remove_reference { typedef T type; }; // NOLINT |
368 | template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT |
369 | |
370 | // DecayArray<T>::type turns an array type U[N] to const U* and preserves |
371 | // other types. Useful for saving a copy of a function argument. |
372 | template <typename T> struct DecayArray { typedef T type; }; // NOLINT |
373 | template <typename T, size_t N> struct DecayArray<T[N]> { |
374 | typedef const T* type; |
375 | }; |
376 | // Sometimes people use arrays whose size is not available at the use site |
377 | // (e.g. extern const char kNamePrefix[]). This specialization covers that |
378 | // case. |
379 | template <typename T> struct DecayArray<T[]> { |
380 | typedef const T* type; |
381 | }; |
382 | |
383 | // Disable MSVC warnings for infinite recursion, since in this case the |
384 | // the recursion is unreachable. |
385 | #ifdef _MSC_VER |
386 | # pragma warning(push) |
387 | # pragma warning(disable:4717) |
388 | #endif |
389 | |
390 | // Invalid<T>() is usable as an expression of type T, but will terminate |
391 | // the program with an assertion failure if actually run. This is useful |
392 | // when a value of type T is needed for compilation, but the statement |
393 | // will not really be executed (or we don't care if the statement |
394 | // crashes). |
395 | template <typename T> |
396 | inline T Invalid() { |
397 | Assert(false, "" , -1, "Internal error: attempt to return invalid value" ); |
398 | // This statement is unreachable, and would never terminate even if it |
399 | // could be reached. It is provided only to placate compiler warnings |
400 | // about missing return statements. |
401 | return Invalid<T>(); |
402 | } |
403 | |
404 | #ifdef _MSC_VER |
405 | # pragma warning(pop) |
406 | #endif |
407 | |
408 | // Given a raw type (i.e. having no top-level reference or const |
409 | // modifier) RawContainer that's either an STL-style container or a |
410 | // native array, class StlContainerView<RawContainer> has the |
411 | // following members: |
412 | // |
413 | // - type is a type that provides an STL-style container view to |
414 | // (i.e. implements the STL container concept for) RawContainer; |
415 | // - const_reference is a type that provides a reference to a const |
416 | // RawContainer; |
417 | // - ConstReference(raw_container) returns a const reference to an STL-style |
418 | // container view to raw_container, which is a RawContainer. |
419 | // - Copy(raw_container) returns an STL-style container view of a |
420 | // copy of raw_container, which is a RawContainer. |
421 | // |
422 | // This generic version is used when RawContainer itself is already an |
423 | // STL-style container. |
424 | template <class RawContainer> |
425 | class StlContainerView { |
426 | public: |
427 | typedef RawContainer type; |
428 | typedef const type& const_reference; |
429 | |
430 | static const_reference ConstReference(const RawContainer& container) { |
431 | // Ensures that RawContainer is not a const type. |
432 | testing::StaticAssertTypeEq<RawContainer, |
433 | GTEST_REMOVE_CONST_(RawContainer)>(); |
434 | return container; |
435 | } |
436 | static type Copy(const RawContainer& container) { return container; } |
437 | }; |
438 | |
439 | // This specialization is used when RawContainer is a native array type. |
440 | template <typename Element, size_t N> |
441 | class StlContainerView<Element[N]> { |
442 | public: |
443 | typedef GTEST_REMOVE_CONST_(Element) RawElement; |
444 | typedef internal::NativeArray<RawElement> type; |
445 | // NativeArray<T> can represent a native array either by value or by |
446 | // reference (selected by a constructor argument), so 'const type' |
447 | // can be used to reference a const native array. We cannot |
448 | // 'typedef const type& const_reference' here, as that would mean |
449 | // ConstReference() has to return a reference to a local variable. |
450 | typedef const type const_reference; |
451 | |
452 | static const_reference ConstReference(const Element (&array)[N]) { |
453 | // Ensures that Element is not a const type. |
454 | testing::StaticAssertTypeEq<Element, RawElement>(); |
455 | return type(array, N, RelationToSourceReference()); |
456 | } |
457 | static type Copy(const Element (&array)[N]) { |
458 | return type(array, N, RelationToSourceCopy()); |
459 | } |
460 | }; |
461 | |
462 | // This specialization is used when RawContainer is a native array |
463 | // represented as a (pointer, size) tuple. |
464 | template <typename ElementPointer, typename Size> |
465 | class StlContainerView< ::std::tuple<ElementPointer, Size> > { |
466 | public: |
467 | typedef GTEST_REMOVE_CONST_( |
468 | typename internal::PointeeOf<ElementPointer>::type) RawElement; |
469 | typedef internal::NativeArray<RawElement> type; |
470 | typedef const type const_reference; |
471 | |
472 | static const_reference ConstReference( |
473 | const ::std::tuple<ElementPointer, Size>& array) { |
474 | return type(std::get<0>(array), std::get<1>(array), |
475 | RelationToSourceReference()); |
476 | } |
477 | static type Copy(const ::std::tuple<ElementPointer, Size>& array) { |
478 | return type(std::get<0>(array), std::get<1>(array), RelationToSourceCopy()); |
479 | } |
480 | }; |
481 | |
482 | // The following specialization prevents the user from instantiating |
483 | // StlContainer with a reference type. |
484 | template <typename T> class StlContainerView<T&>; |
485 | |
486 | // A type transform to remove constness from the first part of a pair. |
487 | // Pairs like that are used as the value_type of associative containers, |
488 | // and this transform produces a similar but assignable pair. |
489 | template <typename T> |
490 | struct RemoveConstFromKey { |
491 | typedef T type; |
492 | }; |
493 | |
494 | // Partially specialized to remove constness from std::pair<const K, V>. |
495 | template <typename K, typename V> |
496 | struct RemoveConstFromKey<std::pair<const K, V> > { |
497 | typedef std::pair<K, V> type; |
498 | }; |
499 | |
500 | // Mapping from booleans to types. Similar to boost::bool_<kValue> and |
501 | // std::integral_constant<bool, kValue>. |
502 | template <bool kValue> |
503 | struct BooleanConstant {}; |
504 | |
505 | // Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to |
506 | // reduce code size. |
507 | GTEST_API_ void IllegalDoDefault(const char* file, int line); |
508 | |
509 | // Helper types for Apply() below. |
510 | template <size_t... Is> struct int_pack { typedef int_pack type; }; |
511 | |
512 | template <class Pack, size_t I> struct append; |
513 | template <size_t... Is, size_t I> |
514 | struct append<int_pack<Is...>, I> : int_pack<Is..., I> {}; |
515 | |
516 | template <size_t C> |
517 | struct make_int_pack : append<typename make_int_pack<C - 1>::type, C - 1> {}; |
518 | template <> struct make_int_pack<0> : int_pack<> {}; |
519 | |
520 | template <typename F, typename Tuple, size_t... Idx> |
521 | auto ApplyImpl(F&& f, Tuple&& args, int_pack<Idx...>) -> decltype( |
522 | std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...)) { |
523 | return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...); |
524 | } |
525 | |
526 | // Apply the function to a tuple of arguments. |
527 | template <typename F, typename Tuple> |
528 | auto Apply(F&& f, Tuple&& args) |
529 | -> decltype(ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args), |
530 | make_int_pack<std::tuple_size<Tuple>::value>())) { |
531 | return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args), |
532 | make_int_pack<std::tuple_size<Tuple>::value>()); |
533 | } |
534 | |
535 | // Template struct Function<F>, where F must be a function type, contains |
536 | // the following typedefs: |
537 | // |
538 | // Result: the function's return type. |
539 | // Arg<N>: the type of the N-th argument, where N starts with 0. |
540 | // ArgumentTuple: the tuple type consisting of all parameters of F. |
541 | // ArgumentMatcherTuple: the tuple type consisting of Matchers for all |
542 | // parameters of F. |
543 | // MakeResultVoid: the function type obtained by substituting void |
544 | // for the return type of F. |
545 | // MakeResultIgnoredValue: |
546 | // the function type obtained by substituting Something |
547 | // for the return type of F. |
548 | template <typename T> |
549 | struct Function; |
550 | |
551 | template <typename R, typename... Args> |
552 | struct Function<R(Args...)> { |
553 | using Result = R; |
554 | static constexpr size_t ArgumentCount = sizeof...(Args); |
555 | template <size_t I> |
556 | using Arg = ElemFromList<I, typename MakeIndexSequence<sizeof...(Args)>::type, |
557 | Args...>; |
558 | using ArgumentTuple = std::tuple<Args...>; |
559 | using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>; |
560 | using MakeResultVoid = void(Args...); |
561 | using MakeResultIgnoredValue = IgnoredValue(Args...); |
562 | }; |
563 | |
564 | template <typename R, typename... Args> |
565 | constexpr size_t Function<R(Args...)>::ArgumentCount; |
566 | |
567 | #ifdef _MSC_VER |
568 | # pragma warning(pop) |
569 | #endif |
570 | |
571 | } // namespace internal |
572 | } // namespace testing |
573 | |
574 | #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ |
575 | |