File indexing completed on 2026-11-04 10:05:13
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
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130 #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
0131 #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
0132
0133 #ifndef _WIN32_WCE
0134 #include <errno.h>
0135 #endif
0136
0137 #include <algorithm>
0138 #include <exception>
0139 #include <functional>
0140 #include <memory>
0141 #include <string>
0142 #include <tuple>
0143 #include <type_traits>
0144 #include <utility>
0145
0146 #include "gmock/internal/gmock-internal-utils.h"
0147 #include "gmock/internal/gmock-port.h"
0148 #include "gmock/internal/gmock-pp.h"
0149
0150 GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
0151
0152 namespace testing {
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163 namespace internal {
0164
0165
0166
0167
0168
0169
0170 template <typename T, bool kDefaultConstructible>
0171 struct BuiltInDefaultValueGetter {
0172 static T Get() { return T(); }
0173 };
0174 template <typename T>
0175 struct BuiltInDefaultValueGetter<T, false> {
0176 static T Get() {
0177 Assert(false, __FILE__, __LINE__,
0178 "Default action undefined for the function return type.");
0179 #if defined(__GNUC__) || defined(__clang__)
0180 __builtin_unreachable();
0181 #elif defined(_MSC_VER)
0182 __assume(0);
0183 #else
0184 return Invalid<T>();
0185
0186
0187 #endif
0188 }
0189 };
0190
0191
0192
0193
0194
0195
0196
0197
0198 template <typename T>
0199 class [[nodiscard]] BuiltInDefaultValue {
0200 public:
0201
0202
0203 static bool Exists() { return ::std::is_default_constructible<T>::value; }
0204
0205 static T Get() {
0206 return BuiltInDefaultValueGetter<
0207 T, ::std::is_default_constructible<T>::value>::Get();
0208 }
0209 };
0210
0211
0212
0213 template <typename T>
0214 class [[nodiscard]] BuiltInDefaultValue<const T> {
0215 public:
0216 static bool Exists() { return BuiltInDefaultValue<T>::Exists(); }
0217 static T Get() { return BuiltInDefaultValue<T>::Get(); }
0218 };
0219
0220
0221
0222 template <typename T>
0223 class [[nodiscard]] BuiltInDefaultValue<T*> {
0224 public:
0225 static bool Exists() { return true; }
0226 static T* Get() { return nullptr; }
0227 };
0228
0229
0230
0231 #define GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(type, value) \
0232 template <> \
0233 class BuiltInDefaultValue<type> { \
0234 public: \
0235 static bool Exists() { return true; } \
0236 static type Get() { return value; } \
0237 }
0238
0239 GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(void, );
0240 GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::std::string, "");
0241 GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(bool, false);
0242 GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned char, '\0');
0243 GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed char, '\0');
0244 GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(char, '\0');
0245
0246
0247
0248
0249
0250
0251
0252 #if GMOCK_WCHAR_T_IS_NATIVE_
0253 GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(wchar_t, 0U);
0254 #endif
0255
0256 GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned short, 0U);
0257 GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed short, 0);
0258 GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned int, 0U);
0259 GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed int, 0);
0260 GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long, 0UL);
0261 GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long, 0L);
0262 GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long long, 0);
0263 GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long long, 0);
0264 GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(float, 0);
0265 GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0);
0266
0267 #undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_
0268
0269
0270
0271
0272 template <typename P>
0273 struct negation
0274
0275 : std::integral_constant<bool, bool(!P::value)> {};
0276
0277
0278 template <typename...>
0279 struct conjunction : std::true_type {};
0280
0281
0282 template <typename P1>
0283 struct conjunction<P1> : P1 {};
0284
0285
0286
0287 template <typename P1, typename... Ps>
0288 struct conjunction<P1, Ps...>
0289 : std::conditional<bool(P1::value), conjunction<Ps...>, P1>::type {};
0290
0291 template <typename...>
0292 struct disjunction : std::false_type {};
0293
0294 template <typename P1>
0295 struct disjunction<P1> : P1 {};
0296
0297 template <typename P1, typename... Ps>
0298 struct disjunction<P1, Ps...>
0299
0300 : std::conditional<!bool(P1::value), disjunction<Ps...>, P1>::type {};
0301
0302 template <typename...>
0303 using void_t = void;
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327 template <typename From, typename To>
0328 struct is_implicitly_convertible {
0329 private:
0330
0331
0332 template <typename T>
0333 static void Accept(T);
0334
0335
0336 template <typename T>
0337 static T Make();
0338
0339
0340 template <typename T, typename = decltype(Accept<To>(Make<T>()))>
0341 static std::true_type TestImplicitConversion(int);
0342
0343
0344 template <typename T>
0345 static std::false_type TestImplicitConversion(...);
0346
0347 public:
0348 using type = decltype(TestImplicitConversion<From>(0));
0349 static constexpr bool value = type::value;
0350 };
0351
0352
0353
0354
0355 template <typename F, typename... Args>
0356 using call_result_t = decltype(std::declval<F>()(std::declval<Args>()...));
0357
0358 template <typename Void, typename R, typename F, typename... Args>
0359 struct is_callable_r_impl : std::false_type {};
0360
0361
0362
0363
0364 template <typename R, typename F, typename... Args>
0365 struct is_callable_r_impl<void_t<call_result_t<F, Args...>>, R, F, Args...>
0366 : std::conditional<
0367 std::is_void<R>::value,
0368 std::true_type,
0369 is_implicitly_convertible<call_result_t<F, Args...>, R>>::type {};
0370
0371
0372
0373 template <typename R, typename F, typename... Args>
0374 using is_callable_r = is_callable_r_impl<void, R, F, Args...>;
0375
0376
0377 template <typename T>
0378 typename std::add_const<T>::type& as_const(T& t) {
0379 return t;
0380 }
0381
0382 }
0383
0384
0385 template <typename F>
0386 class [[nodiscard]] OnceAction;
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423 template <typename Result, typename... Args>
0424 class [[nodiscard]] OnceAction<Result(Args...)> final {
0425 private:
0426
0427
0428 template <typename Callable>
0429 using IsDirectlyCompatible = internal::conjunction<
0430
0431 internal::is_callable_r<Result, std::decay_t<Callable>, Args...>,
0432
0433 std::is_constructible<std::decay_t<Callable>, Callable>>;
0434
0435
0436
0437 template <typename Callable>
0438 using IsCompatibleAfterIgnoringArguments = internal::conjunction<
0439
0440
0441 internal::is_callable_r<Result, std::decay_t<Callable>>,
0442
0443 std::is_constructible<std::decay_t<Callable>, Callable>>;
0444
0445 public:
0446
0447
0448
0449 template <typename Callable,
0450 typename std::enable_if<
0451 internal::conjunction<
0452
0453
0454
0455
0456 internal::negation<std::is_same<
0457 OnceAction, typename std::decay<Callable>::type>>,
0458 IsDirectlyCompatible<Callable>>
0459 ::value,
0460 int>::type = 0>
0461 OnceAction(Callable&& callable)
0462 : function_(StdFunctionAdaptor<typename std::decay<Callable>::type>(
0463 {}, std::forward<Callable>(callable))) {}
0464
0465
0466 template <typename Callable,
0467 typename std::enable_if<
0468 internal::conjunction<
0469
0470
0471
0472
0473 internal::negation<std::is_same<
0474 OnceAction, typename std::decay<Callable>::type>>,
0475
0476
0477 internal::negation<IsDirectlyCompatible<Callable>>,
0478 IsCompatibleAfterIgnoringArguments<Callable>>::value,
0479 int>::type = 0>
0480 OnceAction(Callable&& callable)
0481
0482
0483 : OnceAction(IgnoreIncomingArguments<typename std::decay<Callable>::type>{
0484 std::forward<Callable>(callable)}) {}
0485
0486
0487
0488 OnceAction(const OnceAction&) = delete;
0489 OnceAction& operator=(const OnceAction&) = delete;
0490 OnceAction(OnceAction&&) = default;
0491
0492
0493
0494 Result Call(Args... args) && {
0495 return function_(std::forward<Args>(args)...);
0496 }
0497
0498 private:
0499
0500
0501
0502
0503
0504
0505
0506 template <typename Callable>
0507 class StdFunctionAdaptor final {
0508 public:
0509
0510
0511
0512 struct CallableTag final {};
0513
0514 template <typename F>
0515 explicit StdFunctionAdaptor(CallableTag, F&& callable)
0516 : callable_(std::make_shared<Callable>(std::forward<F>(callable))) {}
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536 template <typename... ArgRefs>
0537 internal::call_result_t<Callable, ArgRefs...> operator()(
0538 ArgRefs&&... args) const {
0539 return std::move(*callable_)(std::forward<ArgRefs>(args)...);
0540 }
0541
0542 private:
0543
0544
0545 std::shared_ptr<Callable> callable_;
0546 };
0547
0548
0549
0550 template <typename Callable>
0551 struct IgnoreIncomingArguments {
0552 internal::call_result_t<Callable> operator()(Args&&...) {
0553 return std::move(callable)();
0554 }
0555
0556 Callable callable;
0557 };
0558
0559 std::function<Result(Args...)> function_;
0560 };
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575 template <typename T>
0576 class [[nodiscard]] DefaultValue {
0577 public:
0578
0579
0580 static void Set(T x) {
0581 delete producer_;
0582 producer_ = new FixedValueProducer(x);
0583 }
0584
0585
0586
0587
0588 typedef T (*FactoryFunction)();
0589 static void SetFactory(FactoryFunction factory) {
0590 delete producer_;
0591 producer_ = new FactoryValueProducer(factory);
0592 }
0593
0594
0595 static void Clear() {
0596 delete producer_;
0597 producer_ = nullptr;
0598 }
0599
0600
0601 static bool IsSet() { return producer_ != nullptr; }
0602
0603
0604
0605 static bool Exists() {
0606 return IsSet() || internal::BuiltInDefaultValue<T>::Exists();
0607 }
0608
0609
0610
0611
0612 static T Get() {
0613 return producer_ == nullptr ? internal::BuiltInDefaultValue<T>::Get()
0614 : producer_->Produce();
0615 }
0616
0617 private:
0618 class ValueProducer {
0619 public:
0620 virtual ~ValueProducer() = default;
0621 virtual T Produce() = 0;
0622 };
0623
0624 class FixedValueProducer : public ValueProducer {
0625 public:
0626 explicit FixedValueProducer(T value) : value_(value) {}
0627 T Produce() override { return value_; }
0628
0629 private:
0630 const T value_;
0631 FixedValueProducer(const FixedValueProducer&) = delete;
0632 FixedValueProducer& operator=(const FixedValueProducer&) = delete;
0633 };
0634
0635 class FactoryValueProducer : public ValueProducer {
0636 public:
0637 explicit FactoryValueProducer(FactoryFunction factory)
0638 : factory_(factory) {}
0639 T Produce() override { return factory_(); }
0640
0641 private:
0642 const FactoryFunction factory_;
0643 FactoryValueProducer(const FactoryValueProducer&) = delete;
0644 FactoryValueProducer& operator=(const FactoryValueProducer&) = delete;
0645 };
0646
0647 static ValueProducer* producer_;
0648 };
0649
0650
0651
0652 template <typename T>
0653 class [[nodiscard]] DefaultValue<T&> {
0654 public:
0655
0656 static void Set(T& x) {
0657 address_ = &x;
0658 }
0659
0660
0661 static void Clear() { address_ = nullptr; }
0662
0663
0664 static bool IsSet() { return address_ != nullptr; }
0665
0666
0667
0668 static bool Exists() {
0669 return IsSet() || internal::BuiltInDefaultValue<T&>::Exists();
0670 }
0671
0672
0673
0674
0675 static T& Get() {
0676 return address_ == nullptr ? internal::BuiltInDefaultValue<T&>::Get()
0677 : *address_;
0678 }
0679
0680 private:
0681 static T* address_;
0682 };
0683
0684
0685
0686 template <>
0687 class [[nodiscard]] DefaultValue<void> {
0688 public:
0689 static bool Exists() { return true; }
0690 static void Get() {}
0691 };
0692
0693
0694 template <typename T>
0695 typename DefaultValue<T>::ValueProducer* DefaultValue<T>::producer_ = nullptr;
0696
0697
0698 template <typename T>
0699 T* DefaultValue<T&>::address_ = nullptr;
0700
0701
0702 template <typename F>
0703 class [[nodiscard]] ActionInterface {
0704 public:
0705 typedef typename internal::Function<F>::Result Result;
0706 typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
0707
0708 ActionInterface() = default;
0709 virtual ~ActionInterface() = default;
0710
0711
0712
0713
0714
0715 virtual Result Perform(const ArgumentTuple& args) = 0;
0716
0717 private:
0718 ActionInterface(const ActionInterface&) = delete;
0719 ActionInterface& operator=(const ActionInterface&) = delete;
0720 };
0721
0722 template <typename F>
0723 class [[nodiscard]] Action;
0724
0725
0726
0727
0728
0729
0730
0731 template <typename R, typename... Args>
0732 class [[nodiscard]] Action<R(Args...)> {
0733 private:
0734 using F = R(Args...);
0735
0736
0737
0738 struct ActionAdapter {
0739
0740 ::std::shared_ptr<ActionInterface<F>> impl_;
0741
0742 template <typename... InArgs>
0743 typename internal::Function<F>::Result operator()(InArgs&&... args) {
0744 return impl_->Perform(
0745 ::std::forward_as_tuple(::std::forward<InArgs>(args)...));
0746 }
0747 };
0748
0749 template <typename G>
0750 using IsCompatibleFunctor = std::is_constructible<std::function<F>, G>;
0751
0752 public:
0753 typedef typename internal::Function<F>::Result Result;
0754 typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
0755
0756
0757
0758 Action() = default;
0759
0760
0761
0762
0763 template <
0764 typename G,
0765 typename = typename std::enable_if<internal::disjunction<
0766 IsCompatibleFunctor<G>, std::is_constructible<std::function<Result()>,
0767 G>>::value>::type>
0768 Action(G&& fun) {
0769 Init(::std::forward<G>(fun), IsCompatibleFunctor<G>());
0770 }
0771
0772
0773 explicit Action(ActionInterface<F>* impl)
0774 : fun_(ActionAdapter{::std::shared_ptr<ActionInterface<F>>(impl)}) {}
0775
0776
0777
0778
0779 template <typename Func>
0780 Action(const Action<Func>& action)
0781 : fun_(action.fun_) {}
0782
0783
0784 bool IsDoDefault() const { return fun_ == nullptr; }
0785
0786
0787
0788
0789
0790
0791
0792 Result Perform(ArgumentTuple args) const {
0793 if (IsDoDefault()) {
0794 internal::IllegalDoDefault(__FILE__, __LINE__);
0795 }
0796 return internal::Apply(fun_, ::std::move(args));
0797 }
0798
0799
0800
0801 operator OnceAction<F>() const {
0802
0803
0804
0805 struct OA {
0806 Action<F> action;
0807
0808 R operator()(Args... args) && {
0809 return action.Perform(
0810 std::forward_as_tuple(std::forward<Args>(args)...));
0811 }
0812 };
0813
0814 return OA{*this};
0815 }
0816
0817 private:
0818 template <typename G>
0819 friend class Action;
0820
0821 template <typename G>
0822 void Init(G&& g, ::std::true_type) {
0823 fun_ = ::std::forward<G>(g);
0824 }
0825
0826 template <typename G>
0827 void Init(G&& g, ::std::false_type) {
0828 fun_ = IgnoreArgs<typename ::std::decay<G>::type>{::std::forward<G>(g)};
0829 }
0830
0831 template <typename FunctionImpl>
0832 struct IgnoreArgs {
0833 template <typename... InArgs>
0834 Result operator()(const InArgs&...) const {
0835 return function_impl();
0836 }
0837 template <typename... InArgs>
0838 Result operator()(const InArgs&...) {
0839 return function_impl();
0840 }
0841
0842 FunctionImpl function_impl;
0843 };
0844
0845
0846 ::std::function<F> fun_;
0847 };
0848
0849
0850
0851
0852
0853
0854
0855
0856
0857
0858
0859
0860
0861
0862
0863
0864
0865
0866
0867
0868
0869
0870 template <typename Impl>
0871 class [[nodiscard]] PolymorphicAction {
0872 public:
0873 explicit PolymorphicAction(const Impl& impl) : impl_(impl) {}
0874
0875 template <typename F>
0876 operator Action<F>() const {
0877 return Action<F>(new MonomorphicImpl<F>(impl_));
0878 }
0879
0880 private:
0881 template <typename F>
0882 class MonomorphicImpl : public ActionInterface<F> {
0883 public:
0884 typedef typename internal::Function<F>::Result Result;
0885 typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
0886
0887 explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
0888
0889 Result Perform(const ArgumentTuple& args) override {
0890 return impl_.template Perform<Result>(args);
0891 }
0892
0893 private:
0894 Impl impl_;
0895 };
0896
0897 Impl impl_;
0898 };
0899
0900
0901
0902 template <typename F>
0903 Action<F> MakeAction(ActionInterface<F>* impl) {
0904 return Action<F>(impl);
0905 }
0906
0907
0908
0909
0910
0911
0912
0913
0914 template <typename Impl>
0915 inline PolymorphicAction<Impl> MakePolymorphicAction(const Impl& impl) {
0916 return PolymorphicAction<Impl>(impl);
0917 }
0918
0919 namespace internal {
0920
0921
0922
0923 template <typename T>
0924 struct ByMoveWrapper {
0925 explicit ByMoveWrapper(T value) : payload(std::move(value)) {}
0926 T payload;
0927 };
0928
0929
0930 template <typename R>
0931 class [[nodiscard]] ReturnAction final {
0932 public:
0933 explicit ReturnAction(R value) : value_(std::move(value)) {}
0934
0935 template <typename U, typename... Args,
0936 typename = typename std::enable_if<conjunction<
0937
0938 negation<std::is_same<void, U>>,
0939 negation<std::is_reference<U>>,
0940 std::is_convertible<R, U>,
0941 std::is_move_constructible<U>>::value>::type>
0942 operator OnceAction<U(Args...)>() && {
0943 return Impl<U>(std::move(value_));
0944 }
0945
0946 template <typename U, typename... Args,
0947 typename = typename std::enable_if<conjunction<
0948
0949 negation<std::is_same<void, U>>,
0950 negation<std::is_reference<U>>,
0951 std::is_convertible<const R&, U>,
0952 std::is_copy_constructible<U>>::value>::type>
0953 operator Action<U(Args...)>() const {
0954 return Impl<U>(value_);
0955 }
0956
0957 private:
0958
0959 template <typename U>
0960 class Impl final {
0961 public:
0962
0963
0964 explicit Impl(R&& input_value)
0965 : state_(new State(std::move(input_value))) {}
0966
0967
0968
0969 explicit Impl(const R& input_value) : state_(new State(input_value)) {}
0970
0971 U operator()() && { return std::move(state_->value); }
0972 U operator()() const& { return state_->value; }
0973
0974 private:
0975
0976
0977
0978
0979
0980
0981
0982
0983
0984
0985
0986 struct State {
0987 explicit State(const R& input_value_in)
0988 : input_value(input_value_in),
0989
0990
0991
0992
0993
0994
0995
0996
0997 value(ImplicitCast_<U>(internal::as_const(input_value))) {}
0998
0999
1000
1001 explicit State(R&& input_value_in)
1002 : input_value(std::move(input_value_in)),
1003
1004
1005
1006
1007
1008
1009 value(ImplicitCast_<U>(std::move(input_value))) {}
1010
1011
1012
1013
1014
1015 R input_value;
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082 U value;
1083 };
1084
1085 const std::shared_ptr<State> state_;
1086 };
1087
1088 R value_;
1089 };
1090
1091
1092
1093
1094
1095
1096 template <typename T>
1097 class [[nodiscard]] ReturnAction<ByMoveWrapper<T>> final {
1098 public:
1099 explicit ReturnAction(ByMoveWrapper<T> wrapper)
1100 : state_(new State(std::move(wrapper.payload))) {}
1101
1102 T operator()() const {
1103 GTEST_CHECK_(!state_->called)
1104 << "A ByMove() action must be performed at most once.";
1105
1106 state_->called = true;
1107 return std::move(state_->value);
1108 }
1109
1110 private:
1111
1112
1113 struct State {
1114 explicit State(T&& value_in) : value(std::move(value_in)) {}
1115
1116 T value;
1117 bool called = false;
1118 };
1119
1120 const std::shared_ptr<State> state_;
1121 };
1122
1123
1124 class [[nodiscard]] ReturnNullAction {
1125 public:
1126
1127
1128
1129 template <typename Result, typename ArgumentTuple>
1130 static Result Perform(const ArgumentTuple&) {
1131 return nullptr;
1132 }
1133 };
1134
1135
1136 class [[nodiscard]] ReturnVoidAction {
1137 public:
1138
1139 template <typename Result, typename ArgumentTuple>
1140 static void Perform(const ArgumentTuple&) {
1141 static_assert(std::is_void<Result>::value, "Result should be void.");
1142 }
1143 };
1144
1145
1146
1147
1148 template <typename T>
1149 class [[nodiscard]] ReturnRefAction {
1150 public:
1151
1152 explicit ReturnRefAction(T& ref) : ref_(ref) {}
1153
1154
1155
1156 template <typename F>
1157 operator Action<F>() const {
1158 typedef typename Function<F>::Result Result;
1159
1160
1161
1162 static_assert(std::is_reference<Result>::value,
1163 "use Return instead of ReturnRef to return a value");
1164 return Action<F>(new Impl<F>(ref_));
1165 }
1166
1167 private:
1168
1169 template <typename F>
1170 class Impl : public ActionInterface<F> {
1171 public:
1172 typedef typename Function<F>::Result Result;
1173 typedef typename Function<F>::ArgumentTuple ArgumentTuple;
1174
1175 explicit Impl(T& ref) : ref_(ref) {}
1176
1177 Result Perform(const ArgumentTuple&) override { return ref_; }
1178
1179 private:
1180 T& ref_;
1181 };
1182
1183 T& ref_;
1184 };
1185
1186
1187
1188
1189 template <typename T>
1190 class [[nodiscard]] ReturnRefOfCopyAction {
1191 public:
1192
1193
1194 explicit ReturnRefOfCopyAction(const T& value) : value_(value) {}
1195
1196
1197
1198 template <typename F>
1199 operator Action<F>() const {
1200 typedef typename Function<F>::Result Result;
1201
1202
1203
1204 static_assert(std::is_reference<Result>::value,
1205 "use Return instead of ReturnRefOfCopy to return a value");
1206 return Action<F>(new Impl<F>(value_));
1207 }
1208
1209 private:
1210
1211 template <typename F>
1212 class Impl : public ActionInterface<F> {
1213 public:
1214 typedef typename Function<F>::Result Result;
1215 typedef typename Function<F>::ArgumentTuple ArgumentTuple;
1216
1217 explicit Impl(const T& value) : value_(value) {}
1218
1219 Result Perform(const ArgumentTuple&) override { return value_; }
1220
1221 private:
1222 T value_;
1223 };
1224
1225 const T value_;
1226 };
1227
1228
1229
1230 template <typename T>
1231 class [[nodiscard]] ReturnRoundRobinAction {
1232 public:
1233 explicit ReturnRoundRobinAction(std::vector<T> values) {
1234 GTEST_CHECK_(!values.empty())
1235 << "ReturnRoundRobin requires at least one element.";
1236 state_->values = std::move(values);
1237 }
1238
1239 template <typename... Args>
1240 T operator()(Args&&...) const {
1241 return state_->Next();
1242 }
1243
1244 private:
1245 struct State {
1246 T Next() {
1247 T ret_val = values[i++];
1248 if (i == values.size()) i = 0;
1249 return ret_val;
1250 }
1251
1252 std::vector<T> values;
1253 size_t i = 0;
1254 };
1255 std::shared_ptr<State> state_ = std::make_shared<State>();
1256 };
1257
1258
1259 class [[nodiscard]] DoDefaultAction {
1260 public:
1261
1262
1263 template <typename F>
1264 operator Action<F>() const {
1265 return Action<F>();
1266 }
1267 };
1268
1269
1270
1271 template <typename T1, typename T2>
1272 class [[nodiscard]] AssignAction {
1273 public:
1274 AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {}
1275
1276 template <typename Result, typename ArgumentTuple>
1277 void Perform(const ArgumentTuple& ) const {
1278 *ptr_ = value_;
1279 }
1280
1281 private:
1282 T1* const ptr_;
1283 const T2 value_;
1284 };
1285
1286 #ifndef GTEST_OS_WINDOWS_MOBILE
1287
1288
1289
1290 template <typename T>
1291 class [[nodiscard]] SetErrnoAndReturnAction {
1292 public:
1293 SetErrnoAndReturnAction(int errno_value, T result)
1294 : errno_(errno_value), result_(result) {}
1295 template <typename Result, typename ArgumentTuple>
1296 Result Perform(const ArgumentTuple& ) const {
1297 errno = errno_;
1298 return result_;
1299 }
1300
1301 private:
1302 const int errno_;
1303 const T result_;
1304 };
1305
1306 #endif
1307
1308
1309
1310 template <size_t N, typename A, typename = void>
1311 struct SetArgumentPointeeAction {
1312 A value;
1313
1314 template <typename... Args>
1315 void operator()(const Args&... args) const {
1316 *::std::get<N>(std::tie(args...)) = value;
1317 }
1318 };
1319
1320
1321 template <class Class, typename MethodPtr>
1322 struct InvokeMethodAction {
1323 Class* const obj_ptr;
1324 const MethodPtr method_ptr;
1325
1326 template <typename... Args>
1327 auto operator()(Args&&... args) const
1328 -> decltype((obj_ptr->*method_ptr)(std::forward<Args>(args)...)) {
1329 return (obj_ptr->*method_ptr)(std::forward<Args>(args)...);
1330 }
1331 };
1332
1333
1334 template <class Class, typename MethodPtr>
1335 struct InvokeMethodWithoutArgsAction {
1336 Class* const obj_ptr;
1337 const MethodPtr method_ptr;
1338
1339 using ReturnType =
1340 decltype((std::declval<Class*>()->*std::declval<MethodPtr>())());
1341
1342 template <typename... Args>
1343 ReturnType operator()(const Args&...) const {
1344 return (obj_ptr->*method_ptr)();
1345 }
1346 };
1347
1348
1349 template <typename A>
1350 class IgnoreResultAction {
1351 public:
1352 explicit IgnoreResultAction(const A& action) : action_(action) {}
1353
1354 template <typename F>
1355 operator Action<F>() const {
1356
1357
1358
1359
1360
1361
1362
1363
1364 typedef typename internal::Function<F>::Result Result;
1365
1366
1367 static_assert(std::is_void<Result>::value, "Result type should be void.");
1368
1369 return Action<F>(new Impl<F>(action_));
1370 }
1371
1372 private:
1373 template <typename F>
1374 class Impl : public ActionInterface<F> {
1375 public:
1376 typedef typename internal::Function<F>::Result Result;
1377 typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
1378
1379 explicit Impl(const A& action) : action_(action) {}
1380
1381 void Perform(const ArgumentTuple& args) override {
1382
1383 (void)action_.Perform(args);
1384 }
1385
1386 private:
1387
1388
1389 typedef
1390 typename internal::Function<F>::MakeResultIgnoredValue OriginalFunction;
1391
1392 const Action<OriginalFunction> action_;
1393 };
1394
1395 const A action_;
1396 };
1397
1398 template <typename InnerAction, size_t... I>
1399 struct WithArgsAction {
1400 InnerAction inner_action;
1401
1402
1403
1404 template <typename R, typename... Args>
1405 using InnerSignature =
1406 R(typename std::tuple_element<I, std::tuple<Args...>>::type...);
1407
1408
1409
1410
1411
1412
1413
1414 template <
1415 typename R, typename... Args,
1416 typename std::enable_if<
1417 std::is_convertible<InnerAction,
1418
1419
1420
1421
1422
1423
1424 OnceAction<R(internal::TupleElement<
1425 I, std::tuple<Args...>>...)>>::value,
1426 int>::type = 0>
1427 operator OnceAction<R(Args...)>() && {
1428 struct OA {
1429 OnceAction<InnerSignature<R, Args...>> inner_action;
1430
1431 R operator()(Args&&... args) && {
1432 return std::move(inner_action)
1433 .Call(std::get<I>(
1434 std::forward_as_tuple(std::forward<Args>(args)...))...);
1435 }
1436 };
1437
1438 return OA{std::move(inner_action)};
1439 }
1440
1441
1442
1443
1444 template <
1445 typename R, typename... Args,
1446 typename std::enable_if<
1447 std::is_convertible<const InnerAction&,
1448 OnceAction<R(internal::TupleElement<
1449 I, std::tuple<Args...>>...)>>::value,
1450 int>::type = 0>
1451 operator OnceAction<R(Args...)>() const& {
1452 struct OA {
1453 OnceAction<InnerSignature<R, Args...>> inner_action;
1454
1455 R operator()(Args&&... args) && {
1456 return std::move(inner_action)
1457 .Call(std::get<I>(
1458 std::forward_as_tuple(std::forward<Args>(args)...))...);
1459 }
1460 };
1461
1462 return OA{inner_action};
1463 }
1464
1465 template <
1466 typename R, typename... Args,
1467 typename std::enable_if<
1468 std::is_convertible<const InnerAction&,
1469
1470
1471
1472
1473
1474
1475 Action<R(internal::TupleElement<
1476 I, std::tuple<Args...>>...)>>::value,
1477 int>::type = 0>
1478 operator Action<R(Args...)>() const {
1479 Action<InnerSignature<R, Args...>> converted(inner_action);
1480
1481 return [converted](Args&&... args) -> R {
1482 return converted.Perform(std::forward_as_tuple(
1483 std::get<I>(std::forward_as_tuple(std::forward<Args>(args)...))...));
1484 };
1485 }
1486 };
1487
1488 template <typename... Actions>
1489 class [[nodiscard]] DoAllAction;
1490
1491
1492 template <typename FinalAction>
1493 class [[nodiscard]] DoAllAction<FinalAction> {
1494 public:
1495 struct UserConstructorTag {};
1496
1497 template <typename T>
1498 explicit DoAllAction(UserConstructorTag, T&& action)
1499 : final_action_(std::forward<T>(action)) {}
1500
1501
1502
1503
1504
1505
1506
1507
1508 template <typename R, typename... Args,
1509 typename std::enable_if<
1510 std::is_convertible<FinalAction, OnceAction<R(Args...)>>::value,
1511 int>::type = 0>
1512 operator OnceAction<R(Args...)>() && {
1513 return std::move(final_action_);
1514 }
1515
1516
1517
1518 template <
1519 typename R, typename... Args,
1520 typename std::enable_if<
1521 conjunction<
1522 negation<
1523 std::is_convertible<FinalAction, OnceAction<R(Args...)>>>,
1524 std::is_convertible<FinalAction, Action<R(Args...)>>>::value,
1525 int>::type = 0>
1526 operator OnceAction<R(Args...)>() && {
1527 return Action<R(Args...)>(std::move(final_action_));
1528 }
1529
1530
1531 template <
1532 typename R, typename... Args,
1533 typename std::enable_if<
1534 std::is_convertible<const FinalAction&, Action<R(Args...)>>::value,
1535 int>::type = 0>
1536 operator Action<R(Args...)>() const {
1537 return final_action_;
1538 }
1539
1540 private:
1541 FinalAction final_action_;
1542 };
1543
1544
1545
1546 template <typename InitialAction, typename... OtherActions>
1547 class [[nodiscard]] DoAllAction<InitialAction, OtherActions...>
1548 : private DoAllAction<OtherActions...> {
1549 private:
1550 using Base = DoAllAction<OtherActions...>;
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597 template <typename T>
1598 using InitialActionArgType =
1599 typename std::conditional<std::is_scalar<T>::value, T, const T&>::type;
1600
1601 public:
1602 struct UserConstructorTag {};
1603
1604 template <typename T, typename... U>
1605 explicit DoAllAction(UserConstructorTag, T&& initial_action,
1606 U&&... other_actions)
1607 : Base({}, std::forward<U>(other_actions)...),
1608 initial_action_(std::forward<T>(initial_action)) {}
1609
1610
1611
1612 template <
1613 typename R, typename... Args,
1614 typename std::enable_if<
1615 conjunction<std::is_convertible<
1616 InitialAction,
1617 OnceAction<void(InitialActionArgType<Args>...)>>,
1618 std::is_convertible<Base, OnceAction<R(Args...)>>>::value,
1619 int>::type = 0>
1620 operator OnceAction<R(Args...)>() && {
1621
1622
1623
1624 struct OA {
1625 OnceAction<void(InitialActionArgType<Args>...)> initial_action;
1626 OnceAction<R(Args...)> remaining_actions;
1627
1628 R operator()(Args... args) && {
1629 std::move(initial_action)
1630 .Call(static_cast<InitialActionArgType<Args>>(args)...);
1631
1632 return std::move(remaining_actions).Call(std::forward<Args>(args)...);
1633 }
1634 };
1635
1636 return OA{
1637 std::move(initial_action_),
1638 std::move(static_cast<Base&>(*this)),
1639 };
1640 }
1641
1642
1643
1644
1645
1646
1647 template <
1648 typename R, typename... Args,
1649 typename std::enable_if<
1650 conjunction<
1651 negation<std::is_convertible<
1652 InitialAction,
1653 OnceAction<void(InitialActionArgType<Args>...)>>>,
1654 std::is_convertible<InitialAction,
1655 Action<void(InitialActionArgType<Args>...)>>,
1656 std::is_convertible<Base, OnceAction<R(Args...)>>>::value,
1657 int>::type = 0>
1658 operator OnceAction<R(Args...)>() && {
1659 return DoAll(
1660 Action<void(InitialActionArgType<Args>...)>(std::move(initial_action_)),
1661 std::move(static_cast<Base&>(*this)));
1662 }
1663
1664
1665
1666 template <
1667 typename R, typename... Args,
1668 typename std::enable_if<
1669 conjunction<
1670 std::is_convertible<const InitialAction&,
1671 Action<void(InitialActionArgType<Args>...)>>,
1672 std::is_convertible<const Base&, Action<R(Args...)>>>::value,
1673 int>::type = 0>
1674 operator Action<R(Args...)>() const {
1675
1676
1677
1678 struct OA {
1679 Action<void(InitialActionArgType<Args>...)> initial_action;
1680 Action<R(Args...)> remaining_actions;
1681
1682 R operator()(Args... args) const {
1683 initial_action.Perform(std::forward_as_tuple(
1684 static_cast<InitialActionArgType<Args>>(args)...));
1685
1686 return remaining_actions.Perform(
1687 std::forward_as_tuple(std::forward<Args>(args)...));
1688 }
1689 };
1690
1691 return OA{
1692 initial_action_,
1693 static_cast<const Base&>(*this),
1694 };
1695 }
1696
1697 private:
1698 InitialAction initial_action_;
1699 };
1700
1701 template <typename T, typename... Params>
1702 struct ReturnNewAction {
1703 T* operator()() const {
1704 return internal::Apply(
1705 [](const Params&... unpacked_params) {
1706 return new T(unpacked_params...);
1707 },
1708 params);
1709 }
1710 std::tuple<Params...> params;
1711 };
1712
1713 template <size_t k>
1714 struct ReturnArgAction {
1715 template <typename... Args,
1716 typename = typename std::enable_if<(k < sizeof...(Args))>::type>
1717 auto operator()(Args&&... args) const -> decltype(std::get<k>(
1718 std::forward_as_tuple(std::forward<Args>(args)...))) {
1719 return std::get<k>(std::forward_as_tuple(std::forward<Args>(args)...));
1720 }
1721 };
1722
1723 template <size_t k, typename Ptr>
1724 struct SaveArgAction {
1725 Ptr pointer;
1726
1727 template <typename... Args>
1728 void operator()(const Args&... args) const {
1729 *pointer = std::get<k>(std::tie(args...));
1730 }
1731 };
1732
1733 template <size_t k, typename Ptr>
1734 struct SaveArgByMoveAction {
1735 Ptr pointer;
1736
1737 template <typename... Args>
1738 void operator()(Args&&... args) const {
1739 *pointer = std::move(std::get<k>(std::tie(args...)));
1740 }
1741 };
1742
1743 template <size_t k, typename Ptr>
1744 struct SaveArgPointeeAction {
1745 Ptr pointer;
1746
1747 template <typename... Args>
1748 void operator()(const Args&... args) const {
1749 *pointer = *std::get<k>(std::tie(args...));
1750 }
1751 };
1752
1753 template <size_t k, typename T>
1754 struct SetArgRefereeAction {
1755 T value;
1756
1757 template <typename... Args>
1758 void operator()(Args&&... args) const {
1759 using argk_type =
1760 typename ::std::tuple_element<k, std::tuple<Args...>>::type;
1761 static_assert(std::is_lvalue_reference<argk_type>::value,
1762 "Argument must be a reference type.");
1763 std::get<k>(std::tie(args...)) = value;
1764 }
1765 };
1766
1767 template <size_t k, typename I1, typename I2>
1768 struct SetArrayArgumentAction {
1769 I1 first;
1770 I2 last;
1771
1772 template <typename... Args>
1773 void operator()(const Args&... args) const {
1774 auto value = std::get<k>(std::tie(args...));
1775 for (auto it = first; it != last; ++it, (void)++value) {
1776 *value = *it;
1777 }
1778 }
1779 };
1780
1781 template <size_t k>
1782 class [[nodiscard]] DeleteArgAction {
1783 public:
1784 template <typename... Args>
1785 void operator()(const Args&... args) const {
1786 DoDelete(std::get<k>(std::tie(args...)));
1787 }
1788
1789 private:
1790 template <typename T>
1791 static void DoDelete(T* ptr) {
1792 delete ptr;
1793 }
1794
1795 template <typename T>
1796 [[deprecated(
1797 "DeleteArg<N> used for a non-pointer argument, it was likely migrated "
1798 "to a smart pointer type. This action should be removed.")]]
1799 static void DoDelete(T&) {}
1800 };
1801
1802 template <typename Ptr>
1803 struct ReturnPointeeAction {
1804 Ptr pointer;
1805 template <typename... Args>
1806 auto operator()(const Args&...) const -> decltype(*pointer) {
1807 return *pointer;
1808 }
1809 };
1810
1811 #if GTEST_HAS_EXCEPTIONS
1812 template <typename T>
1813 struct ThrowAction {
1814 T exception;
1815
1816 template <typename R, typename... Args>
1817 operator Action<R(Args...)>() const {
1818 T copy = exception;
1819 return [copy](Args...) -> R { throw copy; };
1820 }
1821 };
1822 struct RethrowAction {
1823 std::exception_ptr exception;
1824 template <typename R, typename... Args>
1825 operator Action<R(Args...)>() const {
1826 return [ex = exception](Args...) -> R { std::rethrow_exception(ex); };
1827 }
1828 };
1829 #endif
1830
1831 }
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863 typedef internal::IgnoredValue Unused;
1864
1865
1866 template <typename Action>
1867 GTEST_INTERNAL_DEPRECATE_AND_INLINE("Avoid using DoAll() for single actions")
1868 typename std::decay<Action>::type DoAll(Action&& action) {
1869 return std::forward<Action>(action);
1870 }
1871
1872
1873
1874
1875 template <typename... Action>
1876 internal::DoAllAction<typename std::decay<Action>::type...> DoAll(
1877 Action&&... action) {
1878 return internal::DoAllAction<typename std::decay<Action>::type...>(
1879 {}, std::forward<Action>(action)...);
1880 }
1881
1882
1883
1884
1885
1886
1887 template <size_t k, typename InnerAction>
1888 internal::WithArgsAction<typename std::decay<InnerAction>::type, k> WithArg(
1889 InnerAction&& action) {
1890 return {std::forward<InnerAction>(action)};
1891 }
1892
1893
1894
1895
1896
1897 template <size_t k, size_t... ks, typename InnerAction>
1898 internal::WithArgsAction<typename std::decay<InnerAction>::type, k, ks...>
1899 WithArgs(InnerAction&& action) {
1900 return {std::forward<InnerAction>(action)};
1901 }
1902
1903
1904
1905
1906
1907 template <typename InnerAction>
1908 internal::WithArgsAction<typename std::decay<InnerAction>::type> WithoutArgs(
1909 InnerAction&& action) {
1910 return {std::forward<InnerAction>(action)};
1911 }
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937 template <typename R>
1938 internal::ReturnAction<R> Return(R value) {
1939 return internal::ReturnAction<R>(std::move(value));
1940 }
1941
1942
1943 inline PolymorphicAction<internal::ReturnNullAction> ReturnNull() {
1944 return MakePolymorphicAction(internal::ReturnNullAction());
1945 }
1946
1947
1948 inline PolymorphicAction<internal::ReturnVoidAction> Return() {
1949 return MakePolymorphicAction(internal::ReturnVoidAction());
1950 }
1951
1952
1953 template <typename R>
1954 inline internal::ReturnRefAction<R> ReturnRef(R& x) {
1955 return internal::ReturnRefAction<R>(x);
1956 }
1957
1958
1959 template <typename R, R* = nullptr>
1960 internal::ReturnRefAction<R> ReturnRef(R&&) = delete;
1961
1962
1963
1964
1965 template <typename R>
1966 inline internal::ReturnRefOfCopyAction<R> ReturnRefOfCopy(const R& x) {
1967 return internal::ReturnRefOfCopyAction<R>(x);
1968 }
1969
1970
1971
1972
1973
1974
1975
1976 template <typename R>
1977 internal::ByMoveWrapper<R> ByMove(R x) {
1978 return internal::ByMoveWrapper<R>(std::move(x));
1979 }
1980
1981
1982
1983
1984 template <typename T>
1985 internal::ReturnRoundRobinAction<T> ReturnRoundRobin(std::vector<T> vals) {
1986 return internal::ReturnRoundRobinAction<T>(std::move(vals));
1987 }
1988
1989
1990
1991
1992 template <typename T>
1993 internal::ReturnRoundRobinAction<T> ReturnRoundRobin(
1994 std::initializer_list<T> vals) {
1995 return internal::ReturnRoundRobinAction<T>(std::vector<T>(vals));
1996 }
1997
1998
1999 inline internal::DoDefaultAction DoDefault() {
2000 return internal::DoDefaultAction();
2001 }
2002
2003
2004
2005 template <size_t N, typename T>
2006 internal::SetArgumentPointeeAction<N, T> SetArgPointee(T value) {
2007 return {std::move(value)};
2008 }
2009
2010
2011 template <size_t N, typename T>
2012 internal::SetArgumentPointeeAction<N, T> SetArgumentPointee(T value) {
2013 return {std::move(value)};
2014 }
2015
2016
2017 template <typename T1, typename T2>
2018 PolymorphicAction<internal::AssignAction<T1, T2>> Assign(T1* ptr, T2 val) {
2019 return MakePolymorphicAction(internal::AssignAction<T1, T2>(ptr, val));
2020 }
2021
2022 #ifndef GTEST_OS_WINDOWS_MOBILE
2023
2024
2025 template <typename T>
2026 PolymorphicAction<internal::SetErrnoAndReturnAction<T>> SetErrnoAndReturn(
2027 int errval, T result) {
2028 return MakePolymorphicAction(
2029 internal::SetErrnoAndReturnAction<T>(errval, result));
2030 }
2031
2032 #endif
2033
2034
2035
2036
2037
2038 template <typename FunctionImpl>
2039 GTEST_INTERNAL_DEPRECATE_AND_INLINE(
2040 "Actions can now be implicitly constructed from callables. No need to "
2041 "create wrapper objects using Invoke().")
2042 typename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) {
2043 return std::forward<FunctionImpl>(function_impl);
2044 }
2045
2046
2047
2048 template <class Class, typename MethodPtr>
2049 internal::InvokeMethodAction<Class, MethodPtr> Invoke(Class* obj_ptr,
2050 MethodPtr method_ptr) {
2051 return {obj_ptr, method_ptr};
2052 }
2053
2054
2055 template <typename FunctionImpl>
2056 GTEST_INTERNAL_DEPRECATE_AND_INLINE(
2057 "Actions can now be implicitly constructed from zero-argument callables. "
2058 "No need to create wrapper objects using InvokeWithoutArgs().")
2059 std::decay_t<FunctionImpl> InvokeWithoutArgs(FunctionImpl&& function_impl) {
2060 return std::forward<FunctionImpl>(function_impl);
2061 }
2062
2063
2064
2065 template <class Class, typename MethodPtr>
2066 internal::InvokeMethodWithoutArgsAction<Class, MethodPtr> InvokeWithoutArgs(
2067 Class* obj_ptr, MethodPtr method_ptr) {
2068 return {obj_ptr, method_ptr};
2069 }
2070
2071
2072
2073
2074 template <typename A>
2075 inline internal::IgnoreResultAction<A> IgnoreResult(const A& an_action) {
2076 return internal::IgnoreResultAction<A>(an_action);
2077 }
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089 template <typename T>
2090 inline ::std::reference_wrapper<T> ByRef(T& l_value) {
2091 return ::std::reference_wrapper<T>(l_value);
2092 }
2093
2094
2095
2096
2097 template <typename T, typename... Params>
2098 internal::ReturnNewAction<T, typename std::decay<Params>::type...> ReturnNew(
2099 Params&&... params) {
2100 return {std::forward_as_tuple(std::forward<Params>(params)...)};
2101 }
2102
2103
2104 template <size_t k>
2105 internal::ReturnArgAction<k> ReturnArg() {
2106 return {};
2107 }
2108
2109
2110
2111 template <size_t k, typename Ptr>
2112 internal::SaveArgAction<k, Ptr> SaveArg(Ptr pointer) {
2113 return {pointer};
2114 }
2115
2116
2117
2118 template <size_t k, typename Ptr>
2119 internal::SaveArgByMoveAction<k, Ptr> SaveArgByMove(Ptr pointer) {
2120 return {pointer};
2121 }
2122
2123
2124
2125 template <size_t k, typename Ptr>
2126 internal::SaveArgPointeeAction<k, Ptr> SaveArgPointee(Ptr pointer) {
2127 return {pointer};
2128 }
2129
2130
2131
2132 template <size_t k, typename T>
2133 internal::SetArgRefereeAction<k, typename std::decay<T>::type> SetArgReferee(
2134 T&& value) {
2135 return {std::forward<T>(value)};
2136 }
2137
2138
2139
2140
2141
2142
2143 template <size_t k, typename I1, typename I2>
2144 internal::SetArrayArgumentAction<k, I1, I2> SetArrayArgument(I1 first,
2145 I2 last) {
2146 return {first, last};
2147 }
2148
2149
2150
2151 template <size_t k>
2152 internal::DeleteArgAction<k> DeleteArg() {
2153 return {};
2154 }
2155
2156
2157 template <typename Ptr>
2158 internal::ReturnPointeeAction<Ptr> ReturnPointee(Ptr pointer) {
2159 return {pointer};
2160 }
2161
2162 #if GTEST_HAS_EXCEPTIONS
2163
2164
2165
2166
2167 template <typename T>
2168 typename std::enable_if<
2169 !std::is_base_of<std::exception_ptr, typename std::decay<T>::type>::value,
2170 internal::ThrowAction<typename std::decay<T>::type>>::type
2171 Throw(T&& exception) {
2172 return {std::forward<T>(exception)};
2173 }
2174
2175
2176 inline internal::RethrowAction Rethrow(std::exception_ptr exception) {
2177 return {std::move(exception)};
2178 }
2179 #endif
2180
2181 namespace internal {
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197 struct ExcessiveArg {};
2198
2199
2200
2201 template <typename F, typename Impl>
2202 struct ActionImpl;
2203
2204 template <typename Impl>
2205 struct ImplBase {
2206 struct Holder {
2207
2208 explicit operator const Impl&() const { return *ptr; }
2209 std::shared_ptr<Impl> ptr;
2210 };
2211 using type = typename std::conditional<std::is_constructible<Impl>::value,
2212 Impl, Holder>::type;
2213 };
2214
2215 template <typename R, typename... Args, typename Impl>
2216 struct ActionImpl<R(Args...), Impl> : ImplBase<Impl>::type {
2217 using Base = typename ImplBase<Impl>::type;
2218 using function_type = R(Args...);
2219 using args_type = std::tuple<Args...>;
2220
2221 ActionImpl() = default;
2222 explicit ActionImpl(std::shared_ptr<Impl> impl) : Base{std::move(impl)} {}
2223
2224 R operator()(Args&&... arg) const {
2225 static constexpr size_t kMaxArgs =
2226 sizeof...(Args) <= 10 ? sizeof...(Args) : 10;
2227 return Apply(std::make_index_sequence<kMaxArgs>{},
2228 std::make_index_sequence<10 - kMaxArgs>{},
2229 args_type{std::forward<Args>(arg)...});
2230 }
2231
2232 template <std::size_t... arg_id, std::size_t... excess_id>
2233 R Apply(std::index_sequence<arg_id...>, std::index_sequence<excess_id...>,
2234 const args_type& args) const {
2235
2236
2237
2238
2239
2240 static constexpr ExcessiveArg kExcessArg{};
2241 return static_cast<const Impl&>(*this)
2242 .template gmock_PerformImpl<
2243 function_type, R,
2244 args_type,
2245
2246 typename std::tuple_element<arg_id, args_type>::type...>(
2247 args, std::get<arg_id>(args)...,
2248 ((void)excess_id, kExcessArg)...);
2249 }
2250 };
2251
2252
2253
2254 template <typename F, typename Impl>
2255 ::testing::Action<F> MakeAction() {
2256 return ::testing::Action<F>(ActionImpl<F, Impl>());
2257 }
2258
2259
2260 template <typename F, typename Impl>
2261 ::testing::Action<F> MakeAction(std::shared_ptr<Impl> impl) {
2262 return ::testing::Action<F>(ActionImpl<F, Impl>(std::move(impl)));
2263 }
2264
2265 #define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \
2266 , [[maybe_unused]] const arg##i##_type& arg##i
2267 #define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \
2268 [[maybe_unused]] const args_type& args GMOCK_PP_REPEAT( \
2269 GMOCK_INTERNAL_ARG_UNUSED, , 10)
2270
2271 #define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i
2272 #define GMOCK_ACTION_ARG_TYPES_AND_NAMES_ \
2273 const args_type& args GMOCK_PP_REPEAT(GMOCK_INTERNAL_ARG, , 10)
2274
2275 #define GMOCK_INTERNAL_TEMPLATE_ARG(i, data, el) , typename arg##i##_type
2276 #define GMOCK_ACTION_TEMPLATE_ARGS_NAMES_ \
2277 GMOCK_PP_TAIL(GMOCK_PP_REPEAT(GMOCK_INTERNAL_TEMPLATE_ARG, , 10))
2278
2279 #define GMOCK_INTERNAL_TYPENAME_PARAM(i, data, param) , typename param##_type
2280 #define GMOCK_ACTION_TYPENAME_PARAMS_(params) \
2281 GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPENAME_PARAM, , params))
2282
2283 #define GMOCK_INTERNAL_TYPE_PARAM(i, data, param) , param##_type
2284 #define GMOCK_ACTION_TYPE_PARAMS_(params) \
2285 GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPE_PARAM, , params))
2286
2287 #define GMOCK_INTERNAL_TYPE_GVALUE_PARAM(i, data, param) \
2288 , param##_type gmock_p##i
2289 #define GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params) \
2290 GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPE_GVALUE_PARAM, , params))
2291
2292 #define GMOCK_INTERNAL_GVALUE_PARAM(i, data, param) \
2293 , std::forward<param##_type>(gmock_p##i)
2294 #define GMOCK_ACTION_GVALUE_PARAMS_(params) \
2295 GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GVALUE_PARAM, , params))
2296
2297 #define GMOCK_INTERNAL_INIT_PARAM(i, data, param) \
2298 , param(::std::forward<param##_type>(gmock_p##i))
2299 #define GMOCK_ACTION_INIT_PARAMS_(params) \
2300 GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_INIT_PARAM, , params))
2301
2302 #define GMOCK_INTERNAL_FIELD_PARAM(i, data, param) param##_type param;
2303 #define GMOCK_ACTION_FIELD_PARAMS_(params) \
2304 GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_FIELD_PARAM, , params)
2305
2306 #define GMOCK_INTERNAL_ACTION(name, full_name, params) \
2307 template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
2308 class full_name { \
2309 public: \
2310 explicit full_name(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) \
2311 : impl_(std::make_shared<gmock_Impl>( \
2312 GMOCK_ACTION_GVALUE_PARAMS_(params))) {} \
2313 full_name(const full_name&) = default; \
2314 full_name(full_name&&) noexcept = default; \
2315 template <typename F> \
2316 operator ::testing::Action<F>() const { \
2317 return ::testing::internal::MakeAction<F>(impl_); \
2318 } \
2319 \
2320 private: \
2321 class gmock_Impl { \
2322 public: \
2323 explicit gmock_Impl(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) \
2324 : GMOCK_ACTION_INIT_PARAMS_(params) {} \
2325 template <typename function_type, typename return_type, \
2326 typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
2327 return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
2328 GMOCK_ACTION_FIELD_PARAMS_(params) \
2329 }; \
2330 std::shared_ptr<const gmock_Impl> impl_; \
2331 }; \
2332 template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
2333 [[nodiscard]] inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
2334 GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)); \
2335 template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
2336 inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \
2337 GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) { \
2338 return full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>( \
2339 GMOCK_ACTION_GVALUE_PARAMS_(params)); \
2340 } \
2341 template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \
2342 template <typename function_type, typename return_type, typename args_type, \
2343 GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
2344 return_type \
2345 full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>::gmock_Impl::gmock_PerformImpl( \
2346 GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
2347
2348 }
2349
2350
2351 #define ACTION(name) \
2352 class name##Action { \
2353 public: \
2354 explicit name##Action() noexcept {} \
2355 name##Action(const name##Action&) noexcept {} \
2356 template <typename F> \
2357 operator ::testing::Action<F>() const { \
2358 return ::testing::internal::MakeAction<F, gmock_Impl>(); \
2359 } \
2360 \
2361 private: \
2362 class gmock_Impl { \
2363 public: \
2364 template <typename function_type, typename return_type, \
2365 typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
2366 return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \
2367 }; \
2368 }; \
2369 [[nodiscard]] inline name##Action name(); \
2370 inline name##Action name() { return name##Action(); } \
2371 template <typename function_type, typename return_type, typename args_type, \
2372 GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \
2373 return_type name##Action::gmock_Impl::gmock_PerformImpl( \
2374 GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const
2375
2376 #define ACTION_P(name, ...) \
2377 GMOCK_INTERNAL_ACTION(name, name##ActionP, (__VA_ARGS__))
2378
2379 #define ACTION_P2(name, ...) \
2380 GMOCK_INTERNAL_ACTION(name, name##ActionP2, (__VA_ARGS__))
2381
2382 #define ACTION_P3(name, ...) \
2383 GMOCK_INTERNAL_ACTION(name, name##ActionP3, (__VA_ARGS__))
2384
2385 #define ACTION_P4(name, ...) \
2386 GMOCK_INTERNAL_ACTION(name, name##ActionP4, (__VA_ARGS__))
2387
2388 #define ACTION_P5(name, ...) \
2389 GMOCK_INTERNAL_ACTION(name, name##ActionP5, (__VA_ARGS__))
2390
2391 #define ACTION_P6(name, ...) \
2392 GMOCK_INTERNAL_ACTION(name, name##ActionP6, (__VA_ARGS__))
2393
2394 #define ACTION_P7(name, ...) \
2395 GMOCK_INTERNAL_ACTION(name, name##ActionP7, (__VA_ARGS__))
2396
2397 #define ACTION_P8(name, ...) \
2398 GMOCK_INTERNAL_ACTION(name, name##ActionP8, (__VA_ARGS__))
2399
2400 #define ACTION_P9(name, ...) \
2401 GMOCK_INTERNAL_ACTION(name, name##ActionP9, (__VA_ARGS__))
2402
2403 #define ACTION_P10(name, ...) \
2404 GMOCK_INTERNAL_ACTION(name, name##ActionP10, (__VA_ARGS__))
2405
2406 }
2407
2408 GTEST_DISABLE_MSC_WARNINGS_POP_()
2409
2410 #endif