function_ref_test.cc (8439B)
1 // Copyright 2019 The Abseil Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "absl/functional/function_ref.h" 16 17 #include <functional> 18 #include <memory> 19 20 #include "gmock/gmock.h" 21 #include "gtest/gtest.h" 22 #include "absl/container/internal/test_instance_tracker.h" 23 #include "absl/functional/any_invocable.h" 24 #include "absl/memory/memory.h" 25 26 namespace absl { 27 ABSL_NAMESPACE_BEGIN 28 namespace { 29 30 void RunFun(FunctionRef<void()> f) { f(); } 31 32 TEST(FunctionRefTest, Lambda) { 33 bool ran = false; 34 RunFun([&] { ran = true; }); 35 EXPECT_TRUE(ran); 36 } 37 38 int Function() { return 1337; } 39 40 TEST(FunctionRefTest, Function1) { 41 FunctionRef<int()> ref(&Function); 42 EXPECT_EQ(1337, ref()); 43 } 44 45 TEST(FunctionRefTest, Function2) { 46 FunctionRef<int()> ref(Function); 47 EXPECT_EQ(1337, ref()); 48 } 49 50 TEST(FunctionRefTest, ConstFunction) { 51 FunctionRef<int() const> ref(Function); 52 EXPECT_EQ(1337, ref()); 53 } 54 55 int NoExceptFunction() noexcept { return 1337; } 56 57 // TODO(jdennett): Add a test for noexcept member functions. 58 TEST(FunctionRefTest, NoExceptFunction) { 59 FunctionRef<int()> ref(NoExceptFunction); 60 EXPECT_EQ(1337, ref()); 61 } 62 63 TEST(FunctionRefTest, ForwardsArgs) { 64 auto l = [](std::unique_ptr<int> i) { return *i; }; 65 FunctionRef<int(std::unique_ptr<int>)> ref(l); 66 EXPECT_EQ(42, ref(absl::make_unique<int>(42))); 67 } 68 69 TEST(FunctionRef, ReturnMoveOnly) { 70 auto l = [] { return absl::make_unique<int>(29); }; 71 FunctionRef<std::unique_ptr<int>()> ref(l); 72 EXPECT_EQ(29, *ref()); 73 } 74 75 TEST(FunctionRef, ManyArgs) { 76 auto l = [](int a, int b, int c) { return a + b + c; }; 77 FunctionRef<int(int, int, int)> ref(l); 78 EXPECT_EQ(6, ref(1, 2, 3)); 79 } 80 81 TEST(FunctionRef, VoidResultFromNonVoidFunctor) { 82 bool ran = false; 83 auto l = [&]() -> int { 84 ran = true; 85 return 2; 86 }; 87 FunctionRef<void()> ref(l); 88 ref(); 89 EXPECT_TRUE(ran); 90 } 91 92 TEST(FunctionRef, CastFromDerived) { 93 struct Base {}; 94 struct Derived : public Base {}; 95 96 Derived d; 97 auto l1 = [&](Base* b) { EXPECT_EQ(&d, b); }; 98 FunctionRef<void(Derived*)> ref1(l1); 99 ref1(&d); 100 101 auto l2 = [&]() -> Derived* { return &d; }; 102 FunctionRef<Base*()> ref2(l2); 103 EXPECT_EQ(&d, ref2()); 104 } 105 106 TEST(FunctionRef, VoidResultFromNonVoidFuncton) { 107 FunctionRef<void()> ref(Function); 108 ref(); 109 } 110 111 TEST(FunctionRef, MemberPtr) { 112 struct S { 113 int i; 114 }; 115 116 S s{1100111}; 117 auto mem_ptr = &S::i; 118 FunctionRef<int(const S& s)> ref(mem_ptr); 119 EXPECT_EQ(1100111, ref(s)); 120 } 121 122 TEST(FunctionRef, MemberFun) { 123 struct S { 124 int i; 125 int get_i() const { return i; } 126 }; 127 128 S s{22}; 129 auto mem_fun_ptr = &S::get_i; 130 FunctionRef<int(const S& s)> ref(mem_fun_ptr); 131 EXPECT_EQ(22, ref(s)); 132 } 133 134 TEST(FunctionRef, MemberFunRefqualified) { 135 struct S { 136 int i; 137 int get_i() && { return i; } 138 }; 139 auto mem_fun_ptr = &S::get_i; 140 S s{22}; 141 FunctionRef<int(S && s)> ref(mem_fun_ptr); 142 EXPECT_EQ(22, ref(std::move(s))); 143 } 144 145 #if !defined(_WIN32) && defined(GTEST_HAS_DEATH_TEST) 146 147 TEST(FunctionRef, MemberFunRefqualifiedNull) { 148 struct S { 149 int i; 150 int get_i() && { return i; } 151 }; 152 auto mem_fun_ptr = &S::get_i; 153 mem_fun_ptr = nullptr; 154 EXPECT_DEBUG_DEATH({ FunctionRef<int(S && s)> ref(mem_fun_ptr); }, ""); 155 } 156 157 TEST(FunctionRef, NullMemberPtrAssertFails) { 158 struct S { 159 int i; 160 }; 161 using MemberPtr = int S::*; 162 MemberPtr mem_ptr = nullptr; 163 EXPECT_DEBUG_DEATH({ FunctionRef<int(const S& s)> ref(mem_ptr); }, ""); 164 } 165 166 TEST(FunctionRef, NullStdFunctionAssertPasses) { 167 std::function<void()> function = []() {}; 168 FunctionRef<void()> ref(function); 169 } 170 171 TEST(FunctionRef, NullStdFunctionAssertFails) { 172 std::function<void()> function = nullptr; 173 EXPECT_DEBUG_DEATH({ FunctionRef<void()> ref(function); }, ""); 174 } 175 176 TEST(FunctionRef, NullAnyInvocableAssertPasses) { 177 AnyInvocable<void() const> invocable = []() {}; 178 FunctionRef<void()> ref(invocable); 179 } 180 TEST(FunctionRef, NullAnyInvocableAssertFails) { 181 AnyInvocable<void() const> invocable = nullptr; 182 EXPECT_DEBUG_DEATH({ FunctionRef<void()> ref(invocable); }, ""); 183 } 184 185 #endif // GTEST_HAS_DEATH_TEST 186 187 TEST(FunctionRef, CopiesAndMovesPerPassByValue) { 188 absl::test_internal::InstanceTracker tracker; 189 absl::test_internal::CopyableMovableInstance instance(0); 190 auto l = [](absl::test_internal::CopyableMovableInstance) {}; 191 FunctionRef<void(absl::test_internal::CopyableMovableInstance)> ref(l); 192 ref(instance); 193 EXPECT_EQ(tracker.copies(), 1); 194 EXPECT_EQ(tracker.moves(), 1); 195 } 196 197 TEST(FunctionRef, CopiesAndMovesPerPassByRef) { 198 absl::test_internal::InstanceTracker tracker; 199 absl::test_internal::CopyableMovableInstance instance(0); 200 auto l = [](const absl::test_internal::CopyableMovableInstance&) {}; 201 FunctionRef<void(const absl::test_internal::CopyableMovableInstance&)> ref(l); 202 ref(instance); 203 EXPECT_EQ(tracker.copies(), 0); 204 EXPECT_EQ(tracker.moves(), 0); 205 } 206 207 TEST(FunctionRef, CopiesAndMovesPerPassByValueCallByMove) { 208 absl::test_internal::InstanceTracker tracker; 209 absl::test_internal::CopyableMovableInstance instance(0); 210 auto l = [](absl::test_internal::CopyableMovableInstance) {}; 211 FunctionRef<void(absl::test_internal::CopyableMovableInstance)> ref(l); 212 ref(std::move(instance)); 213 EXPECT_EQ(tracker.copies(), 0); 214 EXPECT_EQ(tracker.moves(), 2); 215 } 216 217 TEST(FunctionRef, CopiesAndMovesPerPassByValueToRef) { 218 absl::test_internal::InstanceTracker tracker; 219 absl::test_internal::CopyableMovableInstance instance(0); 220 auto l = [](const absl::test_internal::CopyableMovableInstance&) {}; 221 FunctionRef<void(absl::test_internal::CopyableMovableInstance)> ref(l); 222 ref(std::move(instance)); 223 EXPECT_EQ(tracker.copies(), 0); 224 EXPECT_EQ(tracker.moves(), 1); 225 } 226 227 TEST(FunctionRef, PassByValueTypes) { 228 using absl::functional_internal::Invoker; 229 using absl::functional_internal::VoidPtr; 230 using absl::test_internal::CopyableMovableInstance; 231 struct Trivial { 232 void* p[2]; 233 }; 234 struct LargeTrivial { 235 void* p[3]; 236 }; 237 238 static_assert(std::is_same<Invoker<void, int>, void (*)(VoidPtr, int)>::value, 239 "Scalar types should be passed by value"); 240 static_assert( 241 std::is_same<Invoker<void, Trivial>, void (*)(VoidPtr, Trivial)>::value, 242 "Small trivial types should be passed by value"); 243 static_assert(std::is_same<Invoker<void, LargeTrivial>, 244 void (*)(VoidPtr, LargeTrivial &&)>::value, 245 "Large trivial types should be passed by rvalue reference"); 246 static_assert( 247 std::is_same<Invoker<void, CopyableMovableInstance>, 248 void (*)(VoidPtr, CopyableMovableInstance &&)>::value, 249 "Types with copy/move ctor should be passed by rvalue reference"); 250 251 // References are passed as references. 252 static_assert( 253 std::is_same<Invoker<void, int&>, void (*)(VoidPtr, int&)>::value, 254 "Reference types should be preserved"); 255 static_assert( 256 std::is_same<Invoker<void, CopyableMovableInstance&>, 257 void (*)(VoidPtr, CopyableMovableInstance&)>::value, 258 "Reference types should be preserved"); 259 static_assert( 260 std::is_same<Invoker<void, CopyableMovableInstance&&>, 261 void (*)(VoidPtr, CopyableMovableInstance &&)>::value, 262 "Reference types should be preserved"); 263 264 // Make sure the address of an object received by reference is the same as the 265 // address of the object passed by the caller. 266 { 267 LargeTrivial obj; 268 auto test = [&obj](LargeTrivial& input) { ASSERT_EQ(&input, &obj); }; 269 absl::FunctionRef<void(LargeTrivial&)> ref(test); 270 ref(obj); 271 } 272 273 { 274 Trivial obj; 275 auto test = [&obj](Trivial& input) { ASSERT_EQ(&input, &obj); }; 276 absl::FunctionRef<void(Trivial&)> ref(test); 277 ref(obj); 278 } 279 } 280 281 TEST(FunctionRef, ReferenceToIncompleteType) { 282 struct IncompleteType; 283 auto test = [](IncompleteType&) {}; 284 absl::FunctionRef<void(IncompleteType&)> ref(test); 285 286 struct IncompleteType {}; 287 IncompleteType obj; 288 ref(obj); 289 } 290 291 } // namespace 292 ABSL_NAMESPACE_END 293 } // namespace absl