File indexing completed on 2025-02-22 10:39:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
0040 #define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
0041
0042 #include <stdio.h>
0043
0044 #include <ostream> // NOLINT
0045 #include <string>
0046 #include <type_traits>
0047 #include <vector>
0048
0049 #include "gmock/internal/gmock-port.h"
0050 #include "gtest/gtest.h"
0051
0052 namespace testing {
0053
0054 template <typename>
0055 class Matcher;
0056
0057 namespace internal {
0058
0059
0060
0061 #ifdef _MSC_VER
0062 #pragma warning(push)
0063 #pragma warning(disable : 4100)
0064 #pragma warning(disable : 4805)
0065 #endif
0066
0067
0068
0069 GTEST_API_ std::string JoinAsKeyValueTuple(
0070 const std::vector<const char*>& names, const Strings& values);
0071
0072
0073
0074
0075
0076 GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name);
0077
0078
0079
0080
0081 template <typename Pointer>
0082 inline const typename Pointer::element_type* GetRawPointer(const Pointer& p) {
0083 return p.get();
0084 }
0085
0086
0087 template <typename Element>
0088 inline const Element* GetRawPointer(const std::reference_wrapper<Element>& r) {
0089 return &r.get();
0090 }
0091
0092
0093 template <typename Element>
0094 inline Element* GetRawPointer(Element* p) {
0095 return p;
0096 }
0097
0098
0099
0100
0101
0102 #if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED)
0103
0104 #else
0105 #define GMOCK_WCHAR_T_IS_NATIVE_ 1
0106 #endif
0107
0108
0109
0110
0111
0112
0113 enum TypeKind { kBool, kInteger, kFloatingPoint, kOther };
0114
0115
0116 template <typename T>
0117 struct KindOf {
0118 enum { value = kOther };
0119 };
0120
0121
0122 #define GMOCK_DECLARE_KIND_(type, kind) \
0123 template <> \
0124 struct KindOf<type> { \
0125 enum { value = kind }; \
0126 }
0127
0128 GMOCK_DECLARE_KIND_(bool, kBool);
0129
0130
0131 GMOCK_DECLARE_KIND_(char, kInteger);
0132 GMOCK_DECLARE_KIND_(signed char, kInteger);
0133 GMOCK_DECLARE_KIND_(unsigned char, kInteger);
0134 GMOCK_DECLARE_KIND_(short, kInteger);
0135 GMOCK_DECLARE_KIND_(unsigned short, kInteger);
0136 GMOCK_DECLARE_KIND_(int, kInteger);
0137 GMOCK_DECLARE_KIND_(unsigned int, kInteger);
0138 GMOCK_DECLARE_KIND_(long, kInteger);
0139 GMOCK_DECLARE_KIND_(unsigned long, kInteger);
0140 GMOCK_DECLARE_KIND_(long long, kInteger);
0141 GMOCK_DECLARE_KIND_(unsigned long long, kInteger);
0142
0143 #if GMOCK_WCHAR_T_IS_NATIVE_
0144 GMOCK_DECLARE_KIND_(wchar_t, kInteger);
0145 #endif
0146
0147
0148 GMOCK_DECLARE_KIND_(float, kFloatingPoint);
0149 GMOCK_DECLARE_KIND_(double, kFloatingPoint);
0150 GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
0151
0152 #undef GMOCK_DECLARE_KIND_
0153
0154
0155 #define GMOCK_KIND_OF_(type) \
0156 static_cast< ::testing::internal::TypeKind>( \
0157 ::testing::internal::KindOf<type>::value)
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168 template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>
0169 using LosslessArithmeticConvertibleImpl = std::integral_constant<
0170 bool,
0171
0172
0173 (kFromKind == kBool) ? true
0174
0175
0176 : (kFromKind != kToKind) ? false
0177 : (kFromKind == kInteger &&
0178
0179
0180 (((sizeof(From) < sizeof(To)) &&
0181 !(std::is_signed<From>::value && !std::is_signed<To>::value)) ||
0182
0183
0184 ((sizeof(From) == sizeof(To)) &&
0185 (std::is_signed<From>::value == std::is_signed<To>::value)))
0186 ) ? true
0187
0188
0189 : (kFromKind == kFloatingPoint && (sizeof(From) <= sizeof(To))) ? true
0190 : false
0191
0192 >;
0193
0194
0195
0196
0197
0198
0199
0200
0201 template <typename From, typename To>
0202 using LosslessArithmeticConvertible =
0203 LosslessArithmeticConvertibleImpl<GMOCK_KIND_OF_(From), From,
0204 GMOCK_KIND_OF_(To), To>;
0205
0206
0207
0208 class FailureReporterInterface {
0209 public:
0210
0211 enum FailureType { kNonfatal, kFatal };
0212
0213 virtual ~FailureReporterInterface() {}
0214
0215
0216 virtual void ReportFailure(FailureType type, const char* file, int line,
0217 const std::string& message) = 0;
0218 };
0219
0220
0221 GTEST_API_ FailureReporterInterface* GetFailureReporter();
0222
0223
0224
0225
0226
0227
0228 inline void Assert(bool condition, const char* file, int line,
0229 const std::string& msg) {
0230 if (!condition) {
0231 GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal, file,
0232 line, msg);
0233 }
0234 }
0235 inline void Assert(bool condition, const char* file, int line) {
0236 Assert(condition, file, line, "Assertion failed.");
0237 }
0238
0239
0240
0241 inline void Expect(bool condition, const char* file, int line,
0242 const std::string& msg) {
0243 if (!condition) {
0244 GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal,
0245 file, line, msg);
0246 }
0247 }
0248 inline void Expect(bool condition, const char* file, int line) {
0249 Expect(condition, file, line, "Expectation failed.");
0250 }
0251
0252
0253 enum LogSeverity { kInfo = 0, kWarning = 1 };
0254
0255
0256
0257
0258 const char kInfoVerbosity[] = "info";
0259
0260 const char kWarningVerbosity[] = "warning";
0261
0262 const char kErrorVerbosity[] = "error";
0263
0264
0265
0266 GTEST_API_ bool LogIsVisible(LogSeverity severity);
0267
0268
0269
0270
0271
0272
0273
0274
0275 GTEST_API_ void Log(LogSeverity severity, const std::string& message,
0276 int stack_frames_to_skip);
0277
0278
0279
0280
0281
0282
0283
0284 class WithoutMatchers {
0285 private:
0286 WithoutMatchers() {}
0287 friend GTEST_API_ WithoutMatchers GetWithoutMatchers();
0288 };
0289
0290
0291 GTEST_API_ WithoutMatchers GetWithoutMatchers();
0292
0293
0294
0295 #ifdef _MSC_VER
0296 #pragma warning(push)
0297 #pragma warning(disable : 4717)
0298 #endif
0299
0300
0301
0302
0303
0304
0305 template <typename T>
0306 inline T Invalid() {
0307 Assert(false, "", -1, "Internal error: attempt to return invalid value");
0308 #if defined(__GNUC__) || defined(__clang__)
0309 __builtin_unreachable();
0310 #elif defined(_MSC_VER)
0311 __assume(0);
0312 #else
0313 return Invalid<T>();
0314 #endif
0315 }
0316
0317 #ifdef _MSC_VER
0318 #pragma warning(pop)
0319 #endif
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337 template <class RawContainer>
0338 class StlContainerView {
0339 public:
0340 typedef RawContainer type;
0341 typedef const type& const_reference;
0342
0343 static const_reference ConstReference(const RawContainer& container) {
0344 static_assert(!std::is_const<RawContainer>::value,
0345 "RawContainer type must not be const");
0346 return container;
0347 }
0348 static type Copy(const RawContainer& container) { return container; }
0349 };
0350
0351
0352 template <typename Element, size_t N>
0353 class StlContainerView<Element[N]> {
0354 public:
0355 typedef typename std::remove_const<Element>::type RawElement;
0356 typedef internal::NativeArray<RawElement> type;
0357
0358
0359
0360
0361
0362 typedef const type const_reference;
0363
0364 static const_reference ConstReference(const Element (&array)[N]) {
0365 static_assert(std::is_same<Element, RawElement>::value,
0366 "Element type must not be const");
0367 return type(array, N, RelationToSourceReference());
0368 }
0369 static type Copy(const Element (&array)[N]) {
0370 return type(array, N, RelationToSourceCopy());
0371 }
0372 };
0373
0374
0375
0376 template <typename ElementPointer, typename Size>
0377 class StlContainerView< ::std::tuple<ElementPointer, Size> > {
0378 public:
0379 typedef typename std::remove_const<
0380 typename std::pointer_traits<ElementPointer>::element_type>::type
0381 RawElement;
0382 typedef internal::NativeArray<RawElement> type;
0383 typedef const type const_reference;
0384
0385 static const_reference ConstReference(
0386 const ::std::tuple<ElementPointer, Size>& array) {
0387 return type(std::get<0>(array), std::get<1>(array),
0388 RelationToSourceReference());
0389 }
0390 static type Copy(const ::std::tuple<ElementPointer, Size>& array) {
0391 return type(std::get<0>(array), std::get<1>(array), RelationToSourceCopy());
0392 }
0393 };
0394
0395
0396
0397 template <typename T>
0398 class StlContainerView<T&>;
0399
0400
0401
0402
0403 template <typename T>
0404 struct RemoveConstFromKey {
0405 typedef T type;
0406 };
0407
0408
0409 template <typename K, typename V>
0410 struct RemoveConstFromKey<std::pair<const K, V> > {
0411 typedef std::pair<K, V> type;
0412 };
0413
0414
0415
0416 GTEST_API_ void IllegalDoDefault(const char* file, int line);
0417
0418 template <typename F, typename Tuple, size_t... Idx>
0419 auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>)
0420 -> decltype(std::forward<F>(f)(
0421 std::get<Idx>(std::forward<Tuple>(args))...)) {
0422 return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);
0423 }
0424
0425
0426 template <typename F, typename Tuple>
0427 auto Apply(F&& f, Tuple&& args) -> decltype(ApplyImpl(
0428 std::forward<F>(f), std::forward<Tuple>(args),
0429 MakeIndexSequence<std::tuple_size<
0430 typename std::remove_reference<Tuple>::type>::value>())) {
0431 return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
0432 MakeIndexSequence<std::tuple_size<
0433 typename std::remove_reference<Tuple>::type>::value>());
0434 }
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449 template <typename T>
0450 struct Function;
0451
0452 template <typename R, typename... Args>
0453 struct Function<R(Args...)> {
0454 using Result = R;
0455 static constexpr size_t ArgumentCount = sizeof...(Args);
0456 template <size_t I>
0457 using Arg = ElemFromList<I, Args...>;
0458 using ArgumentTuple = std::tuple<Args...>;
0459 using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
0460 using MakeResultVoid = void(Args...);
0461 using MakeResultIgnoredValue = IgnoredValue(Args...);
0462 };
0463
0464 template <typename R, typename... Args>
0465 constexpr size_t Function<R(Args...)>::ArgumentCount;
0466
0467 bool Base64Unescape(const std::string& encoded, std::string* decoded);
0468
0469 #ifdef _MSC_VER
0470 #pragma warning(pop)
0471 #endif
0472
0473 }
0474 }
0475
0476 #endif