Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: webrtc/base/bind_unittest.cc

Issue 1291543006: Update Bind to match its comments and always capture by value. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: CR comments, undid android encoder/decoder change Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/base/bind.h" 11 #include "webrtc/base/bind.h"
12 #include "webrtc/base/gunit.h" 12 #include "webrtc/base/gunit.h"
13 13
14 #include "webrtc/base/refcount.h" 14 #include "webrtc/base/refcount.h"
15 15
16 namespace rtc { 16 namespace rtc {
17 17
18 namespace { 18 namespace {
19 19
20 struct LifeTimeCheck; 20 struct LifeTimeCheck;
21 21
22 struct MethodBindTester { 22 struct MethodBindTester {
23 void NullaryVoid() { ++call_count; } 23 void NullaryVoid() { ++call_count; }
24 int NullaryInt() { ++call_count; return 1; } 24 int NullaryInt() { ++call_count; return 1; }
25 int NullaryConst() const { ++call_count; return 2; } 25 int NullaryConst() const { ++call_count; return 2; }
26 void UnaryVoid(int dummy) { ++call_count; } 26 void UnaryVoid(int dummy) { ++call_count; }
27 template <class T> T Identity(T value) { ++call_count; return value; } 27 template <class T> T Identity(T value) { ++call_count; return value; }
28 int UnaryByRef(int& value) const { ++call_count; return ++value; } // NOLINT 28 int UnaryByPointer(int* value) const {
29 ++call_count;
30 return ++(*value);
31 }
32 int UnaryByRef(const int& value) const {
33 ++call_count;
34 return ++const_cast<int&>(value);
35 }
29 int Multiply(int a, int b) const { ++call_count; return a * b; } 36 int Multiply(int a, int b) const { ++call_count; return a * b; }
30 void RefArgument(const scoped_refptr<LifeTimeCheck>& object) { 37 void RefArgument(const scoped_refptr<LifeTimeCheck>& object) {
31 EXPECT_TRUE(object.get() != nullptr); 38 EXPECT_TRUE(object.get() != nullptr);
32 } 39 }
33 40
34 mutable int call_count; 41 mutable int call_count;
35 }; 42 };
36 43
37 struct A { int dummy; }; 44 struct A { int dummy; };
38 struct B: public RefCountInterface { int dummy; }; 45 struct B: public RefCountInterface { int dummy; };
(...skipping 18 matching lines...) Expand all
57 }; 64 };
58 65
59 int Return42() { return 42; } 66 int Return42() { return 42; }
60 int Negate(int a) { return -a; } 67 int Negate(int a) { return -a; }
61 int Multiply(int a, int b) { return a * b; } 68 int Multiply(int a, int b) { return a * b; }
62 69
63 } // namespace 70 } // namespace
64 71
65 // Try to catch any problem with scoped_refptr type deduction in rtc::Bind at 72 // Try to catch any problem with scoped_refptr type deduction in rtc::Bind at
66 // compile time. 73 // compile time.
67 static_assert(is_same<detail::RemoveScopedPtrRef< 74 static_assert(
68 const scoped_refptr<RefCountInterface>&>::type, 75 is_same<
69 scoped_refptr<RefCountInterface>>::value, 76 rtc::remove_reference<const scoped_refptr<RefCountInterface>&>::type,
70 "const scoped_refptr& should be captured by value"); 77 const scoped_refptr<RefCountInterface>>::value,
78 "const scoped_refptr& should be captured by value");
71 79
72 static_assert(is_same<detail::RemoveScopedPtrRef<const scoped_refptr<F>&>::type, 80 static_assert(is_same<rtc::remove_reference<const scoped_refptr<F>&>::type,
73 scoped_refptr<F>>::value, 81 const scoped_refptr<F>>::value,
74 "const scoped_refptr& should be captured by value"); 82 "const scoped_refptr& should be captured by value");
75 83
76 static_assert( 84 static_assert(
77 is_same<detail::RemoveScopedPtrRef<const int&>::type, const int&>::value, 85 is_same<rtc::remove_reference<const int&>::type, const int>::value,
78 "const int& should be captured as const int&"); 86 "const int& should be captured as const int");
79 87
80 static_assert( 88 static_assert(is_same<rtc::remove_reference<const F&>::type, const F>::value,
81 is_same<detail::RemoveScopedPtrRef<const F&>::type, const F&>::value, 89 "const F& should be captured as const F");
82 "const F& should be captured as const F&");
83 90
84 static_assert( 91 static_assert(is_same<rtc::remove_reference<F&>::type, F>::value,
85 is_same<detail::RemoveScopedPtrRef<F&>::type, F&>::value, 92 "F& should be captured as F");
86 "F& should be captured as F&");
87 93
88 #define EXPECT_IS_CAPTURED_AS_PTR(T) \ 94 #define EXPECT_IS_CAPTURED_AS_PTR(T) \
89 static_assert(is_same<detail::PointerType<T>::type, T*>::value, \ 95 static_assert(is_same<detail::PointerType<T>::type, T*>::value, \
90 "PointerType") 96 "PointerType")
91 #define EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(T) \ 97 #define EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(T) \
92 static_assert( \ 98 static_assert( \
93 is_same<detail::PointerType<T>::type, scoped_refptr<T>>::value, \ 99 is_same<detail::PointerType<T>::type, scoped_refptr<T>>::value, \
94 "PointerType") 100 "PointerType")
95 101
96 EXPECT_IS_CAPTURED_AS_PTR(void); 102 EXPECT_IS_CAPTURED_AS_PTR(void);
(...skipping 25 matching lines...) Expand all
122 EXPECT_EQ(3, object.call_count); 128 EXPECT_EQ(3, object.call_count);
123 Bind(&MethodBindTester::UnaryVoid, &object, 5)(); 129 Bind(&MethodBindTester::UnaryVoid, &object, 5)();
124 EXPECT_EQ(4, object.call_count); 130 EXPECT_EQ(4, object.call_count);
125 EXPECT_EQ(100, Bind(&MethodBindTester::Identity<int>, &object, 100)()); 131 EXPECT_EQ(100, Bind(&MethodBindTester::Identity<int>, &object, 100)());
126 EXPECT_EQ(5, object.call_count); 132 EXPECT_EQ(5, object.call_count);
127 const std::string string_value("test string"); 133 const std::string string_value("test string");
128 EXPECT_EQ(string_value, Bind(&MethodBindTester::Identity<std::string>, 134 EXPECT_EQ(string_value, Bind(&MethodBindTester::Identity<std::string>,
129 &object, string_value)()); 135 &object, string_value)());
130 EXPECT_EQ(6, object.call_count); 136 EXPECT_EQ(6, object.call_count);
131 int value = 11; 137 int value = 11;
132 EXPECT_EQ(12, Bind(&MethodBindTester::UnaryByRef, &object, value)()); 138 // Bind binds by value, even if the method signature is by reference, so
139 // "reference" binds require pointers.
140 EXPECT_EQ(12, Bind(&MethodBindTester::UnaryByPointer, &object, &value)());
133 EXPECT_EQ(12, value); 141 EXPECT_EQ(12, value);
134 EXPECT_EQ(7, object.call_count); 142 EXPECT_EQ(7, object.call_count);
143 // It's possible to bind to a function that takes a const reference, though
144 // the capture will be a copy. See UnaryByRef hackery above where it removes
145 // the const to make sure the underlying storage is, in fact, a copy.
146 EXPECT_EQ(13, Bind(&MethodBindTester::UnaryByRef, &object, value)());
147 // But the original value is unmodified.
148 EXPECT_EQ(12, value);
149 EXPECT_EQ(8, object.call_count);
135 EXPECT_EQ(56, Bind(&MethodBindTester::Multiply, &object, 7, 8)()); 150 EXPECT_EQ(56, Bind(&MethodBindTester::Multiply, &object, 7, 8)());
136 EXPECT_EQ(8, object.call_count); 151 EXPECT_EQ(9, object.call_count);
137 } 152 }
138 153
139 TEST(BindTest, BindToFunction) { 154 TEST(BindTest, BindToFunction) {
140 EXPECT_EQ(42, Bind(&Return42)()); 155 EXPECT_EQ(42, Bind(&Return42)());
141 EXPECT_EQ(3, Bind(&Negate, -3)()); 156 EXPECT_EQ(3, Bind(&Negate, -3)());
142 EXPECT_EQ(56, Bind(&Multiply, 8, 7)()); 157 EXPECT_EQ(56, Bind(&Multiply, 8, 7)());
143 } 158 }
144 159
145 // Test Bind where method object implements RefCountInterface and is passed as a 160 // Test Bind where method object implements RefCountInterface and is passed as a
146 // pointer. 161 // pointer.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 scoped_object = nullptr; 218 scoped_object = nullptr;
204 EXPECT_EQ(object.ref_count_, 0); 219 EXPECT_EQ(object.ref_count_, 0);
205 } 220 }
206 221
207 namespace { 222 namespace {
208 223
209 const int* Ref(const int& a) { return &a; } 224 const int* Ref(const int& a) { return &a; }
210 225
211 } // anonymous namespace 226 } // anonymous namespace
212 227
213 // Test Bind with non-scoped_refptr<> reference argument. 228 // Test Bind with non-scoped_refptr<> reference argument, which should be
229 // modified to a non-reference capture.
214 TEST(BindTest, RefArgument) { 230 TEST(BindTest, RefArgument) {
215 const int x = 42; 231 const int x = 42;
216 EXPECT_TRUE(Ref(x) == &x); 232 EXPECT_EQ(&x, Ref(x));
217 // Bind() should not make a copy of |x|, i.e. the pointers should be the same. 233 // Bind() should make a copy of |x|, i.e. the pointers should be different.
218 auto functor = Bind(&Ref, x); 234 auto functor = Bind(&Ref, x);
219 EXPECT_TRUE(functor() == &x); 235 EXPECT_NE(&x, functor());
220 } 236 }
221 237
222 } // namespace rtc 238 } // namespace rtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698