Index: webrtc/base/bind_unittest.cc |
diff --git a/webrtc/base/bind_unittest.cc b/webrtc/base/bind_unittest.cc |
index fa47d279f5da271005dd30b44ee02e7644cdb0b9..be8d79cb6af25cfd62948d7eb4852a41045276ee 100644 |
--- a/webrtc/base/bind_unittest.cc |
+++ b/webrtc/base/bind_unittest.cc |
@@ -25,7 +25,14 @@ struct MethodBindTester { |
int NullaryConst() const { ++call_count; return 2; } |
void UnaryVoid(int dummy) { ++call_count; } |
template <class T> T Identity(T value) { ++call_count; return value; } |
- int UnaryByRef(int& value) const { ++call_count; return ++value; } // NOLINT |
+ int UnaryByPointer(int* value) const { |
+ ++call_count; |
+ return ++(*value); |
+ } |
+ int UnaryByRef(const int& value) const { |
+ ++call_count; |
+ return ++const_cast<int&>(value); |
+ } |
int Multiply(int a, int b) const { ++call_count; return a * b; } |
void RefArgument(const scoped_refptr<LifeTimeCheck>& object) { |
EXPECT_TRUE(object.get() != nullptr); |
@@ -64,26 +71,25 @@ int Multiply(int a, int b) { return a * b; } |
// Try to catch any problem with scoped_refptr type deduction in rtc::Bind at |
// compile time. |
-static_assert(is_same<detail::RemoveScopedPtrRef< |
- const scoped_refptr<RefCountInterface>&>::type, |
- scoped_refptr<RefCountInterface>>::value, |
- "const scoped_refptr& should be captured by value"); |
+static_assert( |
+ is_same< |
+ rtc::remove_reference<const scoped_refptr<RefCountInterface>&>::type, |
+ const scoped_refptr<RefCountInterface>>::value, |
+ "const scoped_refptr& should be captured by value"); |
-static_assert(is_same<detail::RemoveScopedPtrRef<const scoped_refptr<F>&>::type, |
- scoped_refptr<F>>::value, |
+static_assert(is_same<rtc::remove_reference<const scoped_refptr<F>&>::type, |
+ const scoped_refptr<F>>::value, |
"const scoped_refptr& should be captured by value"); |
static_assert( |
- is_same<detail::RemoveScopedPtrRef<const int&>::type, const int&>::value, |
- "const int& should be captured as const int&"); |
+ is_same<rtc::remove_reference<const int&>::type, const int>::value, |
+ "const int& should be captured as const int"); |
-static_assert( |
- is_same<detail::RemoveScopedPtrRef<const F&>::type, const F&>::value, |
- "const F& should be captured as const F&"); |
+static_assert(is_same<rtc::remove_reference<const F&>::type, const F>::value, |
+ "const F& should be captured as const F"); |
-static_assert( |
- is_same<detail::RemoveScopedPtrRef<F&>::type, F&>::value, |
- "F& should be captured as F&"); |
+static_assert(is_same<rtc::remove_reference<F&>::type, F>::value, |
+ "F& should be captured as F"); |
#define EXPECT_IS_CAPTURED_AS_PTR(T) \ |
static_assert(is_same<detail::PointerType<T>::type, T*>::value, \ |
@@ -129,11 +135,20 @@ TEST(BindTest, BindToMethod) { |
&object, string_value)()); |
EXPECT_EQ(6, object.call_count); |
int value = 11; |
- EXPECT_EQ(12, Bind(&MethodBindTester::UnaryByRef, &object, value)()); |
+ // Bind binds by value, even if the method signature is by reference, so |
+ // "reference" binds require pointers. |
+ EXPECT_EQ(12, Bind(&MethodBindTester::UnaryByPointer, &object, &value)()); |
EXPECT_EQ(12, value); |
EXPECT_EQ(7, object.call_count); |
- EXPECT_EQ(56, Bind(&MethodBindTester::Multiply, &object, 7, 8)()); |
+ // It's possible to bind to a function that takes a const reference, though |
+ // the capture will be a copy. See UnaryByRef hackery above where it removes |
+ // the const to make sure the underlying storage is, in fact, a copy. |
+ EXPECT_EQ(13, Bind(&MethodBindTester::UnaryByRef, &object, value)()); |
+ // But the original value is unmodified. |
+ EXPECT_EQ(12, value); |
EXPECT_EQ(8, object.call_count); |
+ EXPECT_EQ(56, Bind(&MethodBindTester::Multiply, &object, 7, 8)()); |
+ EXPECT_EQ(9, object.call_count); |
} |
TEST(BindTest, BindToFunction) { |
@@ -210,13 +225,14 @@ const int* Ref(const int& a) { return &a; } |
} // anonymous namespace |
-// Test Bind with non-scoped_refptr<> reference argument. |
+// Test Bind with non-scoped_refptr<> reference argument, which should be |
+// modified to a non-reference capture. |
TEST(BindTest, RefArgument) { |
const int x = 42; |
- EXPECT_TRUE(Ref(x) == &x); |
- // Bind() should not make a copy of |x|, i.e. the pointers should be the same. |
+ EXPECT_EQ(&x, Ref(x)); |
+ // Bind() should make a copy of |x|, i.e. the pointers should be different. |
auto functor = Bind(&Ref, x); |
- EXPECT_TRUE(functor() == &x); |
+ EXPECT_NE(&x, functor()); |
} |
} // namespace rtc |