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