00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "absl/base/internal/invoke.h"
00016
00017 #include <functional>
00018 #include <memory>
00019 #include <string>
00020 #include <utility>
00021
00022 #include "gmock/gmock.h"
00023 #include "gtest/gtest.h"
00024 #include "absl/memory/memory.h"
00025 #include "absl/strings/str_cat.h"
00026
00027 namespace absl {
00028 namespace base_internal {
00029 namespace {
00030
00031 int Function(int a, int b) { return a - b; }
00032
00033 int Sink(std::unique_ptr<int> p) {
00034 return *p;
00035 }
00036
00037 std::unique_ptr<int> Factory(int n) {
00038 return make_unique<int>(n);
00039 }
00040
00041 void NoOp() {}
00042
00043 struct ConstFunctor {
00044 int operator()(int a, int b) const { return a - b; }
00045 };
00046
00047 struct MutableFunctor {
00048 int operator()(int a, int b) { return a - b; }
00049 };
00050
00051 struct EphemeralFunctor {
00052 int operator()(int a, int b) && { return a - b; }
00053 };
00054
00055 struct OverloadedFunctor {
00056 template <typename... Args>
00057 std::string operator()(const Args&... args) & {
00058 return StrCat("&", args...);
00059 }
00060 template <typename... Args>
00061 std::string operator()(const Args&... args) const& {
00062 return StrCat("const&", args...);
00063 }
00064 template <typename... Args>
00065 std::string operator()(const Args&... args) && {
00066 return StrCat("&&", args...);
00067 }
00068 };
00069
00070 struct Class {
00071 int Method(int a, int b) { return a - b; }
00072 int ConstMethod(int a, int b) const { return a - b; }
00073
00074 int member;
00075 };
00076
00077 struct FlipFlop {
00078 int ConstMethod() const { return member; }
00079 FlipFlop operator*() const { return {-member}; }
00080
00081 int member;
00082 };
00083
00084
00085
00086 template <typename F>
00087 decltype(Invoke(std::declval<const F&>())) CallMaybeWithArg(const F& f) {
00088 return Invoke(f);
00089 }
00090
00091 template <typename F>
00092 decltype(Invoke(std::declval<const F&>(), 42)) CallMaybeWithArg(const F& f) {
00093 return Invoke(f, 42);
00094 }
00095
00096 TEST(InvokeTest, Function) {
00097 EXPECT_EQ(1, Invoke(Function, 3, 2));
00098 EXPECT_EQ(1, Invoke(&Function, 3, 2));
00099 }
00100
00101 TEST(InvokeTest, NonCopyableArgument) {
00102 EXPECT_EQ(42, Invoke(Sink, make_unique<int>(42)));
00103 }
00104
00105 TEST(InvokeTest, NonCopyableResult) {
00106 EXPECT_THAT(Invoke(Factory, 42), ::testing::Pointee(42));
00107 }
00108
00109 TEST(InvokeTest, VoidResult) {
00110 Invoke(NoOp);
00111 }
00112
00113 TEST(InvokeTest, ConstFunctor) {
00114 EXPECT_EQ(1, Invoke(ConstFunctor(), 3, 2));
00115 }
00116
00117 TEST(InvokeTest, MutableFunctor) {
00118 MutableFunctor f;
00119 EXPECT_EQ(1, Invoke(f, 3, 2));
00120 EXPECT_EQ(1, Invoke(MutableFunctor(), 3, 2));
00121 }
00122
00123 TEST(InvokeTest, EphemeralFunctor) {
00124 EphemeralFunctor f;
00125 EXPECT_EQ(1, Invoke(std::move(f), 3, 2));
00126 EXPECT_EQ(1, Invoke(EphemeralFunctor(), 3, 2));
00127 }
00128
00129 TEST(InvokeTest, OverloadedFunctor) {
00130 OverloadedFunctor f;
00131 const OverloadedFunctor& cf = f;
00132
00133 EXPECT_EQ("&", Invoke(f));
00134 EXPECT_EQ("& 42", Invoke(f, " 42"));
00135
00136 EXPECT_EQ("const&", Invoke(cf));
00137 EXPECT_EQ("const& 42", Invoke(cf, " 42"));
00138
00139 EXPECT_EQ("&&", Invoke(std::move(f)));
00140 EXPECT_EQ("&& 42", Invoke(std::move(f), " 42"));
00141 }
00142
00143 TEST(InvokeTest, ReferenceWrapper) {
00144 ConstFunctor cf;
00145 MutableFunctor mf;
00146 EXPECT_EQ(1, Invoke(std::cref(cf), 3, 2));
00147 EXPECT_EQ(1, Invoke(std::ref(cf), 3, 2));
00148 EXPECT_EQ(1, Invoke(std::ref(mf), 3, 2));
00149 }
00150
00151 TEST(InvokeTest, MemberFunction) {
00152 std::unique_ptr<Class> p(new Class);
00153 std::unique_ptr<const Class> cp(new Class);
00154 EXPECT_EQ(1, Invoke(&Class::Method, p, 3, 2));
00155 EXPECT_EQ(1, Invoke(&Class::Method, p.get(), 3, 2));
00156
00157 EXPECT_EQ(1, Invoke(&Class::ConstMethod, p, 3, 2));
00158 EXPECT_EQ(1, Invoke(&Class::ConstMethod, p.get(), 3, 2));
00159 EXPECT_EQ(1, Invoke(&Class::ConstMethod, *p, 3, 2));
00160
00161 EXPECT_EQ(1, Invoke(&Class::ConstMethod, cp, 3, 2));
00162 EXPECT_EQ(1, Invoke(&Class::ConstMethod, cp.get(), 3, 2));
00163 EXPECT_EQ(1, Invoke(&Class::ConstMethod, *cp, 3, 2));
00164
00165 EXPECT_EQ(1, Invoke(&Class::Method, make_unique<Class>(), 3, 2));
00166 EXPECT_EQ(1, Invoke(&Class::ConstMethod, make_unique<Class>(), 3, 2));
00167 EXPECT_EQ(1, Invoke(&Class::ConstMethod, make_unique<const Class>(), 3, 2));
00168 }
00169
00170 TEST(InvokeTest, DataMember) {
00171 std::unique_ptr<Class> p(new Class{42});
00172 std::unique_ptr<const Class> cp(new Class{42});
00173 EXPECT_EQ(42, Invoke(&Class::member, p));
00174 EXPECT_EQ(42, Invoke(&Class::member, *p));
00175 EXPECT_EQ(42, Invoke(&Class::member, p.get()));
00176
00177 Invoke(&Class::member, p) = 42;
00178 Invoke(&Class::member, p.get()) = 42;
00179
00180 EXPECT_EQ(42, Invoke(&Class::member, cp));
00181 EXPECT_EQ(42, Invoke(&Class::member, *cp));
00182 EXPECT_EQ(42, Invoke(&Class::member, cp.get()));
00183 }
00184
00185 TEST(InvokeTest, FlipFlop) {
00186 FlipFlop obj = {42};
00187
00188
00189 EXPECT_EQ(42, Invoke(&FlipFlop::ConstMethod, obj));
00190 EXPECT_EQ(42, Invoke(&FlipFlop::member, obj));
00191 }
00192
00193 TEST(InvokeTest, SfinaeFriendly) {
00194 CallMaybeWithArg(NoOp);
00195 EXPECT_THAT(CallMaybeWithArg(Factory), ::testing::Pointee(42));
00196 }
00197
00198 }
00199 }
00200 }