1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/bind.h" 6 7#include <memory> 8#include <utility> 9#include <vector> 10 11#include "base/callback.h" 12#include "base/macros.h" 13#include "base/memory/ptr_util.h" 14#include "base/memory/ref_counted.h" 15#include "base/memory/weak_ptr.h" 16#include "build/build_config.h" 17#include "testing/gmock/include/gmock/gmock.h" 18#include "testing/gtest/include/gtest/gtest.h" 19 20using ::testing::Mock; 21using ::testing::Return; 22using ::testing::StrictMock; 23 24namespace base { 25namespace { 26 27class IncompleteType; 28 29class NoRef { 30 public: 31 NoRef() {} 32 33 MOCK_METHOD0(VoidMethod0, void()); 34 MOCK_CONST_METHOD0(VoidConstMethod0, void()); 35 36 MOCK_METHOD0(IntMethod0, int()); 37 MOCK_CONST_METHOD0(IntConstMethod0, int()); 38 39 private: 40 // Particularly important in this test to ensure no copies are made. 41 DISALLOW_COPY_AND_ASSIGN(NoRef); 42}; 43 44class HasRef : public NoRef { 45 public: 46 HasRef() {} 47 48 MOCK_CONST_METHOD0(AddRef, void()); 49 MOCK_CONST_METHOD0(Release, bool()); 50 51 private: 52 // Particularly important in this test to ensure no copies are made. 53 DISALLOW_COPY_AND_ASSIGN(HasRef); 54}; 55 56class HasRefPrivateDtor : public HasRef { 57 private: 58 ~HasRefPrivateDtor() {} 59}; 60 61static const int kParentValue = 1; 62static const int kChildValue = 2; 63 64class Parent { 65 public: 66 virtual ~Parent() {} 67 void AddRef() const {} 68 void Release() const {} 69 virtual void VirtualSet() { value = kParentValue; } 70 void NonVirtualSet() { value = kParentValue; } 71 int value; 72}; 73 74class Child : public Parent { 75 public: 76 ~Child() override {} 77 void VirtualSet() override { value = kChildValue; } 78 void NonVirtualSet() { value = kChildValue; } 79}; 80 81class NoRefParent { 82 public: 83 virtual ~NoRefParent() {} 84 virtual void VirtualSet() { value = kParentValue; } 85 void NonVirtualSet() { value = kParentValue; } 86 int value; 87}; 88 89class NoRefChild : public NoRefParent { 90 public: 91 ~NoRefChild() override {} 92 private: 93 void VirtualSet() override { value = kChildValue; } 94 void NonVirtualSet() { value = kChildValue; } 95}; 96 97// Used for probing the number of copies and moves that occur if a type must be 98// coerced during argument forwarding in the Run() methods. 99struct DerivedCopyMoveCounter { 100 DerivedCopyMoveCounter(int* copies, 101 int* assigns, 102 int* move_constructs, 103 int* move_assigns) 104 : copies_(copies), 105 assigns_(assigns), 106 move_constructs_(move_constructs), 107 move_assigns_(move_assigns) {} 108 int* copies_; 109 int* assigns_; 110 int* move_constructs_; 111 int* move_assigns_; 112}; 113 114// Used for probing the number of copies and moves in an argument. 115class CopyMoveCounter { 116 public: 117 CopyMoveCounter(int* copies, 118 int* assigns, 119 int* move_constructs, 120 int* move_assigns) 121 : copies_(copies), 122 assigns_(assigns), 123 move_constructs_(move_constructs), 124 move_assigns_(move_assigns) {} 125 126 CopyMoveCounter(const CopyMoveCounter& other) 127 : copies_(other.copies_), 128 assigns_(other.assigns_), 129 move_constructs_(other.move_constructs_), 130 move_assigns_(other.move_assigns_) { 131 (*copies_)++; 132 } 133 134 CopyMoveCounter(CopyMoveCounter&& other) 135 : copies_(other.copies_), 136 assigns_(other.assigns_), 137 move_constructs_(other.move_constructs_), 138 move_assigns_(other.move_assigns_) { 139 (*move_constructs_)++; 140 } 141 142 // Probing for copies from coercion. 143 explicit CopyMoveCounter(const DerivedCopyMoveCounter& other) 144 : copies_(other.copies_), 145 assigns_(other.assigns_), 146 move_constructs_(other.move_constructs_), 147 move_assigns_(other.move_assigns_) { 148 (*copies_)++; 149 } 150 151 // Probing for moves from coercion. 152 explicit CopyMoveCounter(DerivedCopyMoveCounter&& other) 153 : copies_(other.copies_), 154 assigns_(other.assigns_), 155 move_constructs_(other.move_constructs_), 156 move_assigns_(other.move_assigns_) { 157 (*move_constructs_)++; 158 } 159 160 const CopyMoveCounter& operator=(const CopyMoveCounter& rhs) { 161 copies_ = rhs.copies_; 162 assigns_ = rhs.assigns_; 163 move_constructs_ = rhs.move_constructs_; 164 move_assigns_ = rhs.move_assigns_; 165 166 (*assigns_)++; 167 168 return *this; 169 } 170 171 const CopyMoveCounter& operator=(CopyMoveCounter&& rhs) { 172 copies_ = rhs.copies_; 173 assigns_ = rhs.assigns_; 174 move_constructs_ = rhs.move_constructs_; 175 move_assigns_ = rhs.move_assigns_; 176 177 (*move_assigns_)++; 178 179 return *this; 180 } 181 182 int copies() const { 183 return *copies_; 184 } 185 186 private: 187 int* copies_; 188 int* assigns_; 189 int* move_constructs_; 190 int* move_assigns_; 191}; 192 193// Used for probing the number of copies in an argument. The instance is a 194// copyable and non-movable type. 195class CopyCounter { 196 public: 197 CopyCounter(int* copies, int* assigns) 198 : counter_(copies, assigns, nullptr, nullptr) {} 199 CopyCounter(const CopyCounter& other) : counter_(other.counter_) {} 200 CopyCounter& operator=(const CopyCounter& other) { 201 counter_ = other.counter_; 202 return *this; 203 } 204 205 explicit CopyCounter(const DerivedCopyMoveCounter& other) : counter_(other) {} 206 207 int copies() const { return counter_.copies(); } 208 209 private: 210 CopyMoveCounter counter_; 211}; 212 213// Used for probing the number of moves in an argument. The instance is a 214// non-copyable and movable type. 215class MoveCounter { 216 public: 217 MoveCounter(int* move_constructs, int* move_assigns) 218 : counter_(nullptr, nullptr, move_constructs, move_assigns) {} 219 MoveCounter(MoveCounter&& other) : counter_(std::move(other.counter_)) {} 220 MoveCounter& operator=(MoveCounter&& other) { 221 counter_ = std::move(other.counter_); 222 return *this; 223 } 224 225 explicit MoveCounter(DerivedCopyMoveCounter&& other) 226 : counter_(std::move(other)) {} 227 228 private: 229 CopyMoveCounter counter_; 230}; 231 232class DeleteCounter { 233 public: 234 explicit DeleteCounter(int* deletes) 235 : deletes_(deletes) { 236 } 237 238 ~DeleteCounter() { 239 (*deletes_)++; 240 } 241 242 void VoidMethod0() {} 243 244 private: 245 int* deletes_; 246}; 247 248template <typename T> 249T PassThru(T scoper) { 250 return scoper; 251} 252 253// Some test functions that we can Bind to. 254template <typename T> 255T PolymorphicIdentity(T t) { 256 return t; 257} 258 259template <typename... Ts> 260struct VoidPolymorphic { 261 static void Run(Ts... t) {} 262}; 263 264int Identity(int n) { 265 return n; 266} 267 268int ArrayGet(const int array[], int n) { 269 return array[n]; 270} 271 272int Sum(int a, int b, int c, int d, int e, int f) { 273 return a + b + c + d + e + f; 274} 275 276const char* CStringIdentity(const char* s) { 277 return s; 278} 279 280int GetCopies(const CopyMoveCounter& counter) { 281 return counter.copies(); 282} 283 284int UnwrapNoRefParent(NoRefParent p) { 285 return p.value; 286} 287 288int UnwrapNoRefParentPtr(NoRefParent* p) { 289 return p->value; 290} 291 292int UnwrapNoRefParentConstRef(const NoRefParent& p) { 293 return p.value; 294} 295 296void RefArgSet(int &n) { 297 n = 2; 298} 299 300void PtrArgSet(int *n) { 301 *n = 2; 302} 303 304int FunctionWithWeakFirstParam(WeakPtr<NoRef> o, int n) { 305 return n; 306} 307 308int FunctionWithScopedRefptrFirstParam(const scoped_refptr<HasRef>& o, int n) { 309 return n; 310} 311 312void TakesACallback(const Closure& callback) { 313 callback.Run(); 314} 315 316class BindTest : public ::testing::Test { 317 public: 318 BindTest() { 319 const_has_ref_ptr_ = &has_ref_; 320 const_no_ref_ptr_ = &no_ref_; 321 static_func_mock_ptr = &static_func_mock_; 322 } 323 324 virtual ~BindTest() { 325 } 326 327 static void VoidFunc0() { 328 static_func_mock_ptr->VoidMethod0(); 329 } 330 331 static int IntFunc0() { return static_func_mock_ptr->IntMethod0(); } 332 333 protected: 334 StrictMock<NoRef> no_ref_; 335 StrictMock<HasRef> has_ref_; 336 const HasRef* const_has_ref_ptr_; 337 const NoRef* const_no_ref_ptr_; 338 StrictMock<NoRef> static_func_mock_; 339 340 // Used by the static functions to perform expectations. 341 static StrictMock<NoRef>* static_func_mock_ptr; 342 343 private: 344 DISALLOW_COPY_AND_ASSIGN(BindTest); 345}; 346 347StrictMock<NoRef>* BindTest::static_func_mock_ptr; 348 349// Sanity check that we can instantiate a callback for each arity. 350TEST_F(BindTest, ArityTest) { 351 Callback<int()> c0 = Bind(&Sum, 32, 16, 8, 4, 2, 1); 352 EXPECT_EQ(63, c0.Run()); 353 354 Callback<int(int)> c1 = Bind(&Sum, 32, 16, 8, 4, 2); 355 EXPECT_EQ(75, c1.Run(13)); 356 357 Callback<int(int,int)> c2 = Bind(&Sum, 32, 16, 8, 4); 358 EXPECT_EQ(85, c2.Run(13, 12)); 359 360 Callback<int(int,int,int)> c3 = Bind(&Sum, 32, 16, 8); 361 EXPECT_EQ(92, c3.Run(13, 12, 11)); 362 363 Callback<int(int,int,int,int)> c4 = Bind(&Sum, 32, 16); 364 EXPECT_EQ(94, c4.Run(13, 12, 11, 10)); 365 366 Callback<int(int,int,int,int,int)> c5 = Bind(&Sum, 32); 367 EXPECT_EQ(87, c5.Run(13, 12, 11, 10, 9)); 368 369 Callback<int(int,int,int,int,int,int)> c6 = Bind(&Sum); 370 EXPECT_EQ(69, c6.Run(13, 12, 11, 10, 9, 14)); 371} 372 373// Test the Currying ability of the Callback system. 374TEST_F(BindTest, CurryingTest) { 375 Callback<int(int,int,int,int,int,int)> c6 = Bind(&Sum); 376 EXPECT_EQ(69, c6.Run(13, 12, 11, 10, 9, 14)); 377 378 Callback<int(int,int,int,int,int)> c5 = Bind(c6, 32); 379 EXPECT_EQ(87, c5.Run(13, 12, 11, 10, 9)); 380 381 Callback<int(int,int,int,int)> c4 = Bind(c5, 16); 382 EXPECT_EQ(94, c4.Run(13, 12, 11, 10)); 383 384 Callback<int(int,int,int)> c3 = Bind(c4, 8); 385 EXPECT_EQ(92, c3.Run(13, 12, 11)); 386 387 Callback<int(int,int)> c2 = Bind(c3, 4); 388 EXPECT_EQ(85, c2.Run(13, 12)); 389 390 Callback<int(int)> c1 = Bind(c2, 2); 391 EXPECT_EQ(75, c1.Run(13)); 392 393 Callback<int()> c0 = Bind(c1, 1); 394 EXPECT_EQ(63, c0.Run()); 395} 396 397// Test that currying the rvalue result of another Bind() works correctly. 398// - rvalue should be usable as argument to Bind(). 399// - multiple runs of resulting Callback remain valid. 400TEST_F(BindTest, CurryingRvalueResultOfBind) { 401 int n = 0; 402 Closure cb = base::Bind(&TakesACallback, base::Bind(&PtrArgSet, &n)); 403 404 // If we implement Bind() such that the return value has auto_ptr-like 405 // semantics, the second call here will fail because ownership of 406 // the internal BindState<> would have been transfered to a *temporary* 407 // constructon of a Callback object on the first call. 408 cb.Run(); 409 EXPECT_EQ(2, n); 410 411 n = 0; 412 cb.Run(); 413 EXPECT_EQ(2, n); 414} 415 416// Function type support. 417// - Normal function. 418// - Normal function bound with non-refcounted first argument. 419// - Method bound to non-const object. 420// - Method bound to scoped_refptr. 421// - Const method bound to non-const object. 422// - Const method bound to const object. 423// - Derived classes can be used with pointers to non-virtual base functions. 424// - Derived classes can be used with pointers to virtual base functions (and 425// preserve virtual dispatch). 426TEST_F(BindTest, FunctionTypeSupport) { 427 EXPECT_CALL(static_func_mock_, VoidMethod0()); 428 EXPECT_CALL(has_ref_, AddRef()).Times(4); 429 EXPECT_CALL(has_ref_, Release()).Times(4); 430 EXPECT_CALL(has_ref_, VoidMethod0()).Times(2); 431 EXPECT_CALL(has_ref_, VoidConstMethod0()).Times(2); 432 433 Closure normal_cb = Bind(&VoidFunc0); 434 Callback<NoRef*()> normal_non_refcounted_cb = 435 Bind(&PolymorphicIdentity<NoRef*>, &no_ref_); 436 normal_cb.Run(); 437 EXPECT_EQ(&no_ref_, normal_non_refcounted_cb.Run()); 438 439 Closure method_cb = Bind(&HasRef::VoidMethod0, &has_ref_); 440 Closure method_refptr_cb = Bind(&HasRef::VoidMethod0, 441 make_scoped_refptr(&has_ref_)); 442 Closure const_method_nonconst_obj_cb = Bind(&HasRef::VoidConstMethod0, 443 &has_ref_); 444 Closure const_method_const_obj_cb = Bind(&HasRef::VoidConstMethod0, 445 const_has_ref_ptr_); 446 method_cb.Run(); 447 method_refptr_cb.Run(); 448 const_method_nonconst_obj_cb.Run(); 449 const_method_const_obj_cb.Run(); 450 451 Child child; 452 child.value = 0; 453 Closure virtual_set_cb = Bind(&Parent::VirtualSet, &child); 454 virtual_set_cb.Run(); 455 EXPECT_EQ(kChildValue, child.value); 456 457 child.value = 0; 458 Closure non_virtual_set_cb = Bind(&Parent::NonVirtualSet, &child); 459 non_virtual_set_cb.Run(); 460 EXPECT_EQ(kParentValue, child.value); 461} 462 463// Return value support. 464// - Function with return value. 465// - Method with return value. 466// - Const method with return value. 467TEST_F(BindTest, ReturnValues) { 468 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337)); 469 EXPECT_CALL(has_ref_, AddRef()).Times(3); 470 EXPECT_CALL(has_ref_, Release()).Times(3); 471 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(31337)); 472 EXPECT_CALL(has_ref_, IntConstMethod0()) 473 .WillOnce(Return(41337)) 474 .WillOnce(Return(51337)); 475 476 Callback<int()> normal_cb = Bind(&IntFunc0); 477 Callback<int()> method_cb = Bind(&HasRef::IntMethod0, &has_ref_); 478 Callback<int()> const_method_nonconst_obj_cb = 479 Bind(&HasRef::IntConstMethod0, &has_ref_); 480 Callback<int()> const_method_const_obj_cb = 481 Bind(&HasRef::IntConstMethod0, const_has_ref_ptr_); 482 EXPECT_EQ(1337, normal_cb.Run()); 483 EXPECT_EQ(31337, method_cb.Run()); 484 EXPECT_EQ(41337, const_method_nonconst_obj_cb.Run()); 485 EXPECT_EQ(51337, const_method_const_obj_cb.Run()); 486} 487 488// IgnoreResult adapter test. 489// - Function with return value. 490// - Method with return value. 491// - Const Method with return. 492// - Method with return value bound to WeakPtr<>. 493// - Const Method with return bound to WeakPtr<>. 494TEST_F(BindTest, IgnoreResult) { 495 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337)); 496 EXPECT_CALL(has_ref_, AddRef()).Times(2); 497 EXPECT_CALL(has_ref_, Release()).Times(2); 498 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10)); 499 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11)); 500 EXPECT_CALL(no_ref_, IntMethod0()).WillOnce(Return(12)); 501 EXPECT_CALL(no_ref_, IntConstMethod0()).WillOnce(Return(13)); 502 503 Closure normal_func_cb = Bind(IgnoreResult(&IntFunc0)); 504 normal_func_cb.Run(); 505 506 Closure non_void_method_cb = 507 Bind(IgnoreResult(&HasRef::IntMethod0), &has_ref_); 508 non_void_method_cb.Run(); 509 510 Closure non_void_const_method_cb = 511 Bind(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_); 512 non_void_const_method_cb.Run(); 513 514 WeakPtrFactory<NoRef> weak_factory(&no_ref_); 515 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_); 516 517 Closure non_void_weak_method_cb = 518 Bind(IgnoreResult(&NoRef::IntMethod0), weak_factory.GetWeakPtr()); 519 non_void_weak_method_cb.Run(); 520 521 Closure non_void_weak_const_method_cb = 522 Bind(IgnoreResult(&NoRef::IntConstMethod0), weak_factory.GetWeakPtr()); 523 non_void_weak_const_method_cb.Run(); 524 525 weak_factory.InvalidateWeakPtrs(); 526 non_void_weak_const_method_cb.Run(); 527 non_void_weak_method_cb.Run(); 528} 529 530// Argument binding tests. 531// - Argument binding to primitive. 532// - Argument binding to primitive pointer. 533// - Argument binding to a literal integer. 534// - Argument binding to a literal string. 535// - Argument binding with template function. 536// - Argument binding to an object. 537// - Argument binding to pointer to incomplete type. 538// - Argument gets type converted. 539// - Pointer argument gets converted. 540// - Const Reference forces conversion. 541TEST_F(BindTest, ArgumentBinding) { 542 int n = 2; 543 544 Callback<int()> bind_primitive_cb = Bind(&Identity, n); 545 EXPECT_EQ(n, bind_primitive_cb.Run()); 546 547 Callback<int*()> bind_primitive_pointer_cb = 548 Bind(&PolymorphicIdentity<int*>, &n); 549 EXPECT_EQ(&n, bind_primitive_pointer_cb.Run()); 550 551 Callback<int()> bind_int_literal_cb = Bind(&Identity, 3); 552 EXPECT_EQ(3, bind_int_literal_cb.Run()); 553 554 Callback<const char*()> bind_string_literal_cb = 555 Bind(&CStringIdentity, "hi"); 556 EXPECT_STREQ("hi", bind_string_literal_cb.Run()); 557 558 Callback<int()> bind_template_function_cb = 559 Bind(&PolymorphicIdentity<int>, 4); 560 EXPECT_EQ(4, bind_template_function_cb.Run()); 561 562 NoRefParent p; 563 p.value = 5; 564 Callback<int()> bind_object_cb = Bind(&UnwrapNoRefParent, p); 565 EXPECT_EQ(5, bind_object_cb.Run()); 566 567 IncompleteType* incomplete_ptr = reinterpret_cast<IncompleteType*>(123); 568 Callback<IncompleteType*()> bind_incomplete_ptr_cb = 569 Bind(&PolymorphicIdentity<IncompleteType*>, incomplete_ptr); 570 EXPECT_EQ(incomplete_ptr, bind_incomplete_ptr_cb.Run()); 571 572 NoRefChild c; 573 c.value = 6; 574 Callback<int()> bind_promotes_cb = Bind(&UnwrapNoRefParent, c); 575 EXPECT_EQ(6, bind_promotes_cb.Run()); 576 577 c.value = 7; 578 Callback<int()> bind_pointer_promotes_cb = 579 Bind(&UnwrapNoRefParentPtr, &c); 580 EXPECT_EQ(7, bind_pointer_promotes_cb.Run()); 581 582 c.value = 8; 583 Callback<int()> bind_const_reference_promotes_cb = 584 Bind(&UnwrapNoRefParentConstRef, c); 585 EXPECT_EQ(8, bind_const_reference_promotes_cb.Run()); 586} 587 588// Unbound argument type support tests. 589// - Unbound value. 590// - Unbound pointer. 591// - Unbound reference. 592// - Unbound const reference. 593// - Unbound unsized array. 594// - Unbound sized array. 595// - Unbound array-of-arrays. 596TEST_F(BindTest, UnboundArgumentTypeSupport) { 597 Callback<void(int)> unbound_value_cb = Bind(&VoidPolymorphic<int>::Run); 598 Callback<void(int*)> unbound_pointer_cb = Bind(&VoidPolymorphic<int*>::Run); 599 Callback<void(int&)> unbound_ref_cb = Bind(&VoidPolymorphic<int&>::Run); 600 Callback<void(const int&)> unbound_const_ref_cb = 601 Bind(&VoidPolymorphic<const int&>::Run); 602 Callback<void(int[])> unbound_unsized_array_cb = 603 Bind(&VoidPolymorphic<int[]>::Run); 604 Callback<void(int[2])> unbound_sized_array_cb = 605 Bind(&VoidPolymorphic<int[2]>::Run); 606 Callback<void(int[][2])> unbound_array_of_arrays_cb = 607 Bind(&VoidPolymorphic<int[][2]>::Run); 608 609 Callback<void(int&)> unbound_ref_with_bound_arg = 610 Bind(&VoidPolymorphic<int, int&>::Run, 1); 611} 612 613// Function with unbound reference parameter. 614// - Original parameter is modified by callback. 615TEST_F(BindTest, UnboundReferenceSupport) { 616 int n = 0; 617 Callback<void(int&)> unbound_ref_cb = Bind(&RefArgSet); 618 unbound_ref_cb.Run(n); 619 EXPECT_EQ(2, n); 620} 621 622// Functions that take reference parameters. 623// - Forced reference parameter type still stores a copy. 624// - Forced const reference parameter type still stores a copy. 625TEST_F(BindTest, ReferenceArgumentBinding) { 626 int n = 1; 627 int& ref_n = n; 628 const int& const_ref_n = n; 629 630 Callback<int()> ref_copies_cb = Bind(&Identity, ref_n); 631 EXPECT_EQ(n, ref_copies_cb.Run()); 632 n++; 633 EXPECT_EQ(n - 1, ref_copies_cb.Run()); 634 635 Callback<int()> const_ref_copies_cb = Bind(&Identity, const_ref_n); 636 EXPECT_EQ(n, const_ref_copies_cb.Run()); 637 n++; 638 EXPECT_EQ(n - 1, const_ref_copies_cb.Run()); 639} 640 641// Check that we can pass in arrays and have them be stored as a pointer. 642// - Array of values stores a pointer. 643// - Array of const values stores a pointer. 644TEST_F(BindTest, ArrayArgumentBinding) { 645 int array[4] = {1, 1, 1, 1}; 646 const int (*const_array_ptr)[4] = &array; 647 648 Callback<int()> array_cb = Bind(&ArrayGet, array, 1); 649 EXPECT_EQ(1, array_cb.Run()); 650 651 Callback<int()> const_array_cb = Bind(&ArrayGet, *const_array_ptr, 1); 652 EXPECT_EQ(1, const_array_cb.Run()); 653 654 array[1] = 3; 655 EXPECT_EQ(3, array_cb.Run()); 656 EXPECT_EQ(3, const_array_cb.Run()); 657} 658 659// Unretained() wrapper support. 660// - Method bound to Unretained() non-const object. 661// - Const method bound to Unretained() non-const object. 662// - Const method bound to Unretained() const object. 663TEST_F(BindTest, Unretained) { 664 EXPECT_CALL(no_ref_, VoidMethod0()); 665 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2); 666 667 Callback<void()> method_cb = 668 Bind(&NoRef::VoidMethod0, Unretained(&no_ref_)); 669 method_cb.Run(); 670 671 Callback<void()> const_method_cb = 672 Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref_)); 673 const_method_cb.Run(); 674 675 Callback<void()> const_method_const_ptr_cb = 676 Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr_)); 677 const_method_const_ptr_cb.Run(); 678} 679 680// WeakPtr() support. 681// - Method bound to WeakPtr<> to non-const object. 682// - Const method bound to WeakPtr<> to non-const object. 683// - Const method bound to WeakPtr<> to const object. 684// - Normal Function with WeakPtr<> as P1 can have return type and is 685// not canceled. 686TEST_F(BindTest, WeakPtr) { 687 EXPECT_CALL(no_ref_, VoidMethod0()); 688 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2); 689 690 WeakPtrFactory<NoRef> weak_factory(&no_ref_); 691 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_); 692 693 Closure method_cb = 694 Bind(&NoRef::VoidMethod0, weak_factory.GetWeakPtr()); 695 method_cb.Run(); 696 697 Closure const_method_cb = 698 Bind(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr()); 699 const_method_cb.Run(); 700 701 Closure const_method_const_ptr_cb = 702 Bind(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr()); 703 const_method_const_ptr_cb.Run(); 704 705 Callback<int(int)> normal_func_cb = 706 Bind(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr()); 707 EXPECT_EQ(1, normal_func_cb.Run(1)); 708 709 weak_factory.InvalidateWeakPtrs(); 710 const_weak_factory.InvalidateWeakPtrs(); 711 712 method_cb.Run(); 713 const_method_cb.Run(); 714 const_method_const_ptr_cb.Run(); 715 716 // Still runs even after the pointers are invalidated. 717 EXPECT_EQ(2, normal_func_cb.Run(2)); 718} 719 720// ConstRef() wrapper support. 721// - Binding w/o ConstRef takes a copy. 722// - Binding a ConstRef takes a reference. 723// - Binding ConstRef to a function ConstRef does not copy on invoke. 724TEST_F(BindTest, ConstRef) { 725 int n = 1; 726 727 Callback<int()> copy_cb = Bind(&Identity, n); 728 Callback<int()> const_ref_cb = Bind(&Identity, ConstRef(n)); 729 EXPECT_EQ(n, copy_cb.Run()); 730 EXPECT_EQ(n, const_ref_cb.Run()); 731 n++; 732 EXPECT_EQ(n - 1, copy_cb.Run()); 733 EXPECT_EQ(n, const_ref_cb.Run()); 734 735 int copies = 0; 736 int assigns = 0; 737 int move_constructs = 0; 738 int move_assigns = 0; 739 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns); 740 Callback<int()> all_const_ref_cb = 741 Bind(&GetCopies, ConstRef(counter)); 742 EXPECT_EQ(0, all_const_ref_cb.Run()); 743 EXPECT_EQ(0, copies); 744 EXPECT_EQ(0, assigns); 745 EXPECT_EQ(0, move_constructs); 746 EXPECT_EQ(0, move_assigns); 747} 748 749TEST_F(BindTest, ScopedRefptr) { 750 EXPECT_CALL(has_ref_, AddRef()).Times(1); 751 EXPECT_CALL(has_ref_, Release()).Times(1); 752 753 const scoped_refptr<HasRef> refptr(&has_ref_); 754 Callback<int()> scoped_refptr_const_ref_cb = 755 Bind(&FunctionWithScopedRefptrFirstParam, base::ConstRef(refptr), 1); 756 EXPECT_EQ(1, scoped_refptr_const_ref_cb.Run()); 757} 758 759// Test Owned() support. 760TEST_F(BindTest, Owned) { 761 int deletes = 0; 762 DeleteCounter* counter = new DeleteCounter(&deletes); 763 764 // If we don't capture, delete happens on Callback destruction/reset. 765 // return the same value. 766 Callback<DeleteCounter*()> no_capture_cb = 767 Bind(&PolymorphicIdentity<DeleteCounter*>, Owned(counter)); 768 ASSERT_EQ(counter, no_capture_cb.Run()); 769 ASSERT_EQ(counter, no_capture_cb.Run()); 770 EXPECT_EQ(0, deletes); 771 no_capture_cb.Reset(); // This should trigger a delete. 772 EXPECT_EQ(1, deletes); 773 774 deletes = 0; 775 counter = new DeleteCounter(&deletes); 776 base::Closure own_object_cb = 777 Bind(&DeleteCounter::VoidMethod0, Owned(counter)); 778 own_object_cb.Run(); 779 EXPECT_EQ(0, deletes); 780 own_object_cb.Reset(); 781 EXPECT_EQ(1, deletes); 782} 783 784TEST_F(BindTest, UniquePtrReceiver) { 785 std::unique_ptr<StrictMock<NoRef>> no_ref(new StrictMock<NoRef>); 786 EXPECT_CALL(*no_ref, VoidMethod0()).Times(1); 787 Bind(&NoRef::VoidMethod0, std::move(no_ref)).Run(); 788} 789 790// Tests for Passed() wrapper support: 791// - Passed() can be constructed from a pointer to scoper. 792// - Passed() can be constructed from a scoper rvalue. 793// - Using Passed() gives Callback Ownership. 794// - Ownership is transferred from Callback to callee on the first Run(). 795// - Callback supports unbound arguments. 796template <typename T> 797class BindMoveOnlyTypeTest : public ::testing::Test { 798}; 799 800struct CustomDeleter { 801 void operator()(DeleteCounter* c) { delete c; } 802}; 803 804using MoveOnlyTypesToTest = 805 ::testing::Types<std::unique_ptr<DeleteCounter>, 806 std::unique_ptr<DeleteCounter>, 807 std::unique_ptr<DeleteCounter, CustomDeleter>>; 808TYPED_TEST_CASE(BindMoveOnlyTypeTest, MoveOnlyTypesToTest); 809 810TYPED_TEST(BindMoveOnlyTypeTest, PassedToBoundCallback) { 811 int deletes = 0; 812 813 TypeParam ptr(new DeleteCounter(&deletes)); 814 Callback<TypeParam()> callback = Bind(&PassThru<TypeParam>, Passed(&ptr)); 815 EXPECT_FALSE(ptr.get()); 816 EXPECT_EQ(0, deletes); 817 818 // If we never invoke the Callback, it retains ownership and deletes. 819 callback.Reset(); 820 EXPECT_EQ(1, deletes); 821} 822 823TYPED_TEST(BindMoveOnlyTypeTest, PassedWithRvalue) { 824 int deletes = 0; 825 Callback<TypeParam()> callback = Bind( 826 &PassThru<TypeParam>, Passed(TypeParam(new DeleteCounter(&deletes)))); 827 EXPECT_EQ(0, deletes); 828 829 // If we never invoke the Callback, it retains ownership and deletes. 830 callback.Reset(); 831 EXPECT_EQ(1, deletes); 832} 833 834// Check that ownership can be transferred back out. 835TYPED_TEST(BindMoveOnlyTypeTest, ReturnMoveOnlyType) { 836 int deletes = 0; 837 DeleteCounter* counter = new DeleteCounter(&deletes); 838 Callback<TypeParam()> callback = 839 Bind(&PassThru<TypeParam>, Passed(TypeParam(counter))); 840 TypeParam result = callback.Run(); 841 ASSERT_EQ(counter, result.get()); 842 EXPECT_EQ(0, deletes); 843 844 // Resetting does not delete since ownership was transferred. 845 callback.Reset(); 846 EXPECT_EQ(0, deletes); 847 848 // Ensure that we actually did get ownership. 849 result.reset(); 850 EXPECT_EQ(1, deletes); 851} 852 853TYPED_TEST(BindMoveOnlyTypeTest, UnboundForwarding) { 854 int deletes = 0; 855 TypeParam ptr(new DeleteCounter(&deletes)); 856 // Test unbound argument forwarding. 857 Callback<TypeParam(TypeParam)> cb_unbound = Bind(&PassThru<TypeParam>); 858 cb_unbound.Run(std::move(ptr)); 859 EXPECT_EQ(1, deletes); 860} 861 862void VerifyVector(const std::vector<std::unique_ptr<int>>& v) { 863 ASSERT_EQ(1u, v.size()); 864 EXPECT_EQ(12345, *v[0]); 865} 866 867std::vector<std::unique_ptr<int>> AcceptAndReturnMoveOnlyVector( 868 std::vector<std::unique_ptr<int>> v) { 869 VerifyVector(v); 870 return v; 871} 872 873// Test that a vector containing move-only types can be used with Callback. 874TEST_F(BindTest, BindMoveOnlyVector) { 875 using MoveOnlyVector = std::vector<std::unique_ptr<int>>; 876 877 MoveOnlyVector v; 878 v.push_back(WrapUnique(new int(12345))); 879 880 // Early binding should work: 881 base::Callback<MoveOnlyVector()> bound_cb = 882 base::Bind(&AcceptAndReturnMoveOnlyVector, Passed(&v)); 883 MoveOnlyVector intermediate_result = bound_cb.Run(); 884 VerifyVector(intermediate_result); 885 886 // As should passing it as an argument to Run(): 887 base::Callback<MoveOnlyVector(MoveOnlyVector)> unbound_cb = 888 base::Bind(&AcceptAndReturnMoveOnlyVector); 889 MoveOnlyVector final_result = unbound_cb.Run(std::move(intermediate_result)); 890 VerifyVector(final_result); 891} 892 893// Argument copy-constructor usage for non-reference copy-only parameters. 894// - Bound arguments are only copied once. 895// - Forwarded arguments are only copied once. 896// - Forwarded arguments with coercions are only copied twice (once for the 897// coercion, and one for the final dispatch). 898TEST_F(BindTest, ArgumentCopies) { 899 int copies = 0; 900 int assigns = 0; 901 902 CopyCounter counter(&copies, &assigns); 903 Bind(&VoidPolymorphic<CopyCounter>::Run, counter); 904 EXPECT_EQ(1, copies); 905 EXPECT_EQ(0, assigns); 906 907 copies = 0; 908 assigns = 0; 909 Bind(&VoidPolymorphic<CopyCounter>::Run, CopyCounter(&copies, &assigns)); 910 EXPECT_EQ(1, copies); 911 EXPECT_EQ(0, assigns); 912 913 copies = 0; 914 assigns = 0; 915 Bind(&VoidPolymorphic<CopyCounter>::Run).Run(counter); 916 EXPECT_EQ(2, copies); 917 EXPECT_EQ(0, assigns); 918 919 copies = 0; 920 assigns = 0; 921 Bind(&VoidPolymorphic<CopyCounter>::Run).Run(CopyCounter(&copies, &assigns)); 922 EXPECT_EQ(1, copies); 923 EXPECT_EQ(0, assigns); 924 925 copies = 0; 926 assigns = 0; 927 DerivedCopyMoveCounter derived(&copies, &assigns, nullptr, nullptr); 928 Bind(&VoidPolymorphic<CopyCounter>::Run).Run(CopyCounter(derived)); 929 EXPECT_EQ(2, copies); 930 EXPECT_EQ(0, assigns); 931 932 copies = 0; 933 assigns = 0; 934 Bind(&VoidPolymorphic<CopyCounter>::Run) 935 .Run(CopyCounter( 936 DerivedCopyMoveCounter(&copies, &assigns, nullptr, nullptr))); 937 EXPECT_EQ(2, copies); 938 EXPECT_EQ(0, assigns); 939} 940 941// Argument move-constructor usage for move-only parameters. 942// - Bound arguments passed by move are not copied. 943TEST_F(BindTest, ArgumentMoves) { 944 int move_constructs = 0; 945 int move_assigns = 0; 946 947 Bind(&VoidPolymorphic<const MoveCounter&>::Run, 948 MoveCounter(&move_constructs, &move_assigns)); 949 EXPECT_EQ(1, move_constructs); 950 EXPECT_EQ(0, move_assigns); 951 952 // TODO(tzik): Support binding move-only type into a non-reference parameter 953 // of a variant of Callback. 954 955 move_constructs = 0; 956 move_assigns = 0; 957 Bind(&VoidPolymorphic<MoveCounter>::Run) 958 .Run(MoveCounter(&move_constructs, &move_assigns)); 959 EXPECT_EQ(1, move_constructs); 960 EXPECT_EQ(0, move_assigns); 961 962 move_constructs = 0; 963 move_assigns = 0; 964 Bind(&VoidPolymorphic<MoveCounter>::Run) 965 .Run(MoveCounter(DerivedCopyMoveCounter( 966 nullptr, nullptr, &move_constructs, &move_assigns))); 967 EXPECT_EQ(2, move_constructs); 968 EXPECT_EQ(0, move_assigns); 969} 970 971// Argument constructor usage for non-reference movable-copyable 972// parameters. 973// - Bound arguments passed by move are not copied. 974// - Forwarded arguments are only copied once. 975// - Forwarded arguments with coercions are only copied once and moved once. 976TEST_F(BindTest, ArgumentCopiesAndMoves) { 977 int copies = 0; 978 int assigns = 0; 979 int move_constructs = 0; 980 int move_assigns = 0; 981 982 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns); 983 Bind(&VoidPolymorphic<CopyMoveCounter>::Run, counter); 984 EXPECT_EQ(1, copies); 985 EXPECT_EQ(0, assigns); 986 EXPECT_EQ(0, move_constructs); 987 EXPECT_EQ(0, move_assigns); 988 989 copies = 0; 990 assigns = 0; 991 move_constructs = 0; 992 move_assigns = 0; 993 Bind(&VoidPolymorphic<CopyMoveCounter>::Run, 994 CopyMoveCounter(&copies, &assigns, &move_constructs, &move_assigns)); 995 EXPECT_EQ(0, copies); 996 EXPECT_EQ(0, assigns); 997 EXPECT_EQ(1, move_constructs); 998 EXPECT_EQ(0, move_assigns); 999 1000 copies = 0; 1001 assigns = 0; 1002 move_constructs = 0; 1003 move_assigns = 0; 1004 Bind(&VoidPolymorphic<CopyMoveCounter>::Run).Run(counter); 1005 EXPECT_EQ(1, copies); 1006 EXPECT_EQ(0, assigns); 1007 EXPECT_EQ(1, move_constructs); 1008 EXPECT_EQ(0, move_assigns); 1009 1010 copies = 0; 1011 assigns = 0; 1012 move_constructs = 0; 1013 move_assigns = 0; 1014 Bind(&VoidPolymorphic<CopyMoveCounter>::Run) 1015 .Run(CopyMoveCounter(&copies, &assigns, &move_constructs, &move_assigns)); 1016 EXPECT_EQ(0, copies); 1017 EXPECT_EQ(0, assigns); 1018 EXPECT_EQ(1, move_constructs); 1019 EXPECT_EQ(0, move_assigns); 1020 1021 DerivedCopyMoveCounter derived_counter(&copies, &assigns, &move_constructs, 1022 &move_assigns); 1023 copies = 0; 1024 assigns = 0; 1025 move_constructs = 0; 1026 move_assigns = 0; 1027 Bind(&VoidPolymorphic<CopyMoveCounter>::Run) 1028 .Run(CopyMoveCounter(derived_counter)); 1029 EXPECT_EQ(1, copies); 1030 EXPECT_EQ(0, assigns); 1031 EXPECT_EQ(1, move_constructs); 1032 EXPECT_EQ(0, move_assigns); 1033 1034 copies = 0; 1035 assigns = 0; 1036 move_constructs = 0; 1037 move_assigns = 0; 1038 Bind(&VoidPolymorphic<CopyMoveCounter>::Run) 1039 .Run(CopyMoveCounter(DerivedCopyMoveCounter( 1040 &copies, &assigns, &move_constructs, &move_assigns))); 1041 EXPECT_EQ(0, copies); 1042 EXPECT_EQ(0, assigns); 1043 EXPECT_EQ(2, move_constructs); 1044 EXPECT_EQ(0, move_assigns); 1045} 1046 1047TEST_F(BindTest, CapturelessLambda) { 1048 EXPECT_FALSE(internal::IsConvertibleToRunType<void>::value); 1049 EXPECT_FALSE(internal::IsConvertibleToRunType<int>::value); 1050 EXPECT_FALSE(internal::IsConvertibleToRunType<void(*)()>::value); 1051 EXPECT_FALSE(internal::IsConvertibleToRunType<void(NoRef::*)()>::value); 1052 1053 auto f = []() {}; 1054 EXPECT_TRUE(internal::IsConvertibleToRunType<decltype(f)>::value); 1055 1056 int i = 0; 1057 auto g = [i]() {}; 1058 EXPECT_FALSE(internal::IsConvertibleToRunType<decltype(g)>::value); 1059 1060 auto h = [](int, double) { return 'k'; }; 1061 EXPECT_TRUE((std::is_same< 1062 char(int, double), 1063 internal::ExtractCallableRunType<decltype(h)>>::value)); 1064 1065 EXPECT_EQ(42, Bind([] { return 42; }).Run()); 1066 EXPECT_EQ(42, Bind([](int i) { return i * 7; }, 6).Run()); 1067 1068 int x = 1; 1069 base::Callback<void(int)> cb = 1070 Bind([](int* x, int i) { *x *= i; }, Unretained(&x)); 1071 cb.Run(6); 1072 EXPECT_EQ(6, x); 1073 cb.Run(7); 1074 EXPECT_EQ(42, x); 1075} 1076 1077// Callback construction and assignment tests. 1078// - Construction from an InvokerStorageHolder should not cause ref/deref. 1079// - Assignment from other callback should only cause one ref 1080// 1081// TODO(ajwong): Is there actually a way to test this? 1082 1083#if defined(OS_WIN) 1084int __fastcall FastCallFunc(int n) { 1085 return n; 1086} 1087 1088int __stdcall StdCallFunc(int n) { 1089 return n; 1090} 1091 1092// Windows specific calling convention support. 1093// - Can bind a __fastcall function. 1094// - Can bind a __stdcall function. 1095TEST_F(BindTest, WindowsCallingConventions) { 1096 Callback<int()> fastcall_cb = Bind(&FastCallFunc, 1); 1097 EXPECT_EQ(1, fastcall_cb.Run()); 1098 1099 Callback<int()> stdcall_cb = Bind(&StdCallFunc, 2); 1100 EXPECT_EQ(2, stdcall_cb.Run()); 1101} 1102#endif 1103 1104#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && GTEST_HAS_DEATH_TEST 1105 1106// Test null callbacks cause a DCHECK. 1107TEST(BindDeathTest, NullCallback) { 1108 base::Callback<void(int)> null_cb; 1109 ASSERT_TRUE(null_cb.is_null()); 1110 EXPECT_DEATH(base::Bind(null_cb, 42), ""); 1111} 1112 1113#endif // (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && 1114 // GTEST_HAS_DEATH_TEST 1115 1116} // namespace 1117} // namespace base 1118