diff --git a/talk/media/webrtc/webrtcvideocapturer.cc b/talk/media/webrtc/webrtcvideocapturer.cc index 9f1f32af4f..5ba5fb9ba2 100644 --- a/talk/media/webrtc/webrtcvideocapturer.cc +++ b/talk/media/webrtc/webrtcvideocapturer.cc @@ -382,10 +382,12 @@ void WebRtcVideoCapturer::OnIncomingCapturedFrame( // consistency with other capturers such as in Chrome, we need to do a // thread hop. // Note that Stop() can cause the async invoke call to be cancelled. - async_invoker_->AsyncInvoke(start_thread_, - // Note that this results in a shallow copying of the frame. - rtc::Bind(&WebRtcVideoCapturer::SignalFrameCapturedOnStartThread, - this, sample)); + async_invoker_->AsyncInvoke( + start_thread_, + // Note that Bind captures by value, so there's an intermediate copy + // of sample. + rtc::Bind(&WebRtcVideoCapturer::SignalFrameCapturedOnStartThread, this, + sample)); } } @@ -395,7 +397,7 @@ void WebRtcVideoCapturer::OnCaptureDelayChanged(const int32_t id, } void WebRtcVideoCapturer::SignalFrameCapturedOnStartThread( - const webrtc::VideoFrame frame) { + const webrtc::VideoFrame& frame) { // This can only happen between Start() and Stop(). RTC_DCHECK(start_thread_); RTC_DCHECK(start_thread_->IsCurrent()); diff --git a/talk/media/webrtc/webrtcvideocapturer.h b/talk/media/webrtc/webrtcvideocapturer.h index 66991e097f..0a99884fe1 100644 --- a/talk/media/webrtc/webrtcvideocapturer.h +++ b/talk/media/webrtc/webrtcvideocapturer.h @@ -92,7 +92,7 @@ class WebRtcVideoCapturer : public VideoCapturer, // directly from OnIncomingCapturedFrame. // TODO(tommi): Remove this workaround when we've updated the WebRTC capturers // to follow the same contract. - void SignalFrameCapturedOnStartThread(const webrtc::VideoFrame frame); + void SignalFrameCapturedOnStartThread(const webrtc::VideoFrame& frame); rtc::scoped_ptr factory_; webrtc::VideoCaptureModule* module_; diff --git a/webrtc/base/bind.h b/webrtc/base/bind.h index 923fda21b5..b50afc21ac 100644 --- a/webrtc/base/bind.h +++ b/webrtc/base/bind.h @@ -65,6 +65,7 @@ #define WEBRTC_BASE_BIND_H_ #include "webrtc/base/scoped_ref_ptr.h" +#include "webrtc/base/template_util.h" #define NONAME @@ -128,18 +129,6 @@ struct PointerType { T*>::type type; }; -// RemoveScopedPtrRef will capture scoped_refptr by-value instead of -// by-reference. -template struct RemoveScopedPtrRef { typedef T type; }; -template -struct RemoveScopedPtrRef&> { - typedef scoped_refptr type; -}; -template -struct RemoveScopedPtrRef&> { - typedef scoped_refptr type; -}; - } // namespace detail template @@ -220,7 +209,7 @@ class MethodFunctor1 { private: MethodT method_; typename detail::PointerType::type object_; - typename detail::RemoveScopedPtrRef::type p1_; + typename rtc::remove_reference::type p1_; }; template ::type p1_; + typename rtc::remove_reference::type p1_; }; @@ -303,8 +292,8 @@ class MethodFunctor2 { private: MethodT method_; typename detail::PointerType::type object_; - typename detail::RemoveScopedPtrRef::type p1_; - typename detail::RemoveScopedPtrRef::type p2_; + typename rtc::remove_reference::type p1_; + typename rtc::remove_reference::type p2_; }; template ::type p1_; - typename detail::RemoveScopedPtrRef::type p2_; + typename rtc::remove_reference::type p1_; + typename rtc::remove_reference::type p2_; }; @@ -401,9 +390,9 @@ class MethodFunctor3 { private: MethodT method_; typename detail::PointerType::type object_; - typename detail::RemoveScopedPtrRef::type p1_; - typename detail::RemoveScopedPtrRef::type p2_; - typename detail::RemoveScopedPtrRef::type p3_; + typename rtc::remove_reference::type p1_; + typename rtc::remove_reference::type p2_; + typename rtc::remove_reference::type p3_; }; template ::type p1_; - typename detail::RemoveScopedPtrRef::type p2_; - typename detail::RemoveScopedPtrRef::type p3_; + typename rtc::remove_reference::type p1_; + typename rtc::remove_reference::type p2_; + typename rtc::remove_reference::type p3_; }; @@ -514,10 +503,10 @@ class MethodFunctor4 { private: MethodT method_; typename detail::PointerType::type object_; - typename detail::RemoveScopedPtrRef::type p1_; - typename detail::RemoveScopedPtrRef::type p2_; - typename detail::RemoveScopedPtrRef::type p3_; - typename detail::RemoveScopedPtrRef::type p4_; + typename rtc::remove_reference::type p1_; + typename rtc::remove_reference::type p2_; + typename rtc::remove_reference::type p3_; + typename rtc::remove_reference::type p4_; }; template ::type p1_; - typename detail::RemoveScopedPtrRef::type p2_; - typename detail::RemoveScopedPtrRef::type p3_; - typename detail::RemoveScopedPtrRef::type p4_; + typename rtc::remove_reference::type p1_; + typename rtc::remove_reference::type p2_; + typename rtc::remove_reference::type p3_; + typename rtc::remove_reference::type p4_; }; @@ -642,11 +631,11 @@ class MethodFunctor5 { private: MethodT method_; typename detail::PointerType::type object_; - typename detail::RemoveScopedPtrRef::type p1_; - typename detail::RemoveScopedPtrRef::type p2_; - typename detail::RemoveScopedPtrRef::type p3_; - typename detail::RemoveScopedPtrRef::type p4_; - typename detail::RemoveScopedPtrRef::type p5_; + typename rtc::remove_reference::type p1_; + typename rtc::remove_reference::type p2_; + typename rtc::remove_reference::type p3_; + typename rtc::remove_reference::type p4_; + typename rtc::remove_reference::type p5_; }; template ::type p1_; - typename detail::RemoveScopedPtrRef::type p2_; - typename detail::RemoveScopedPtrRef::type p3_; - typename detail::RemoveScopedPtrRef::type p4_; - typename detail::RemoveScopedPtrRef::type p5_; + typename rtc::remove_reference::type p1_; + typename rtc::remove_reference::type p2_; + typename rtc::remove_reference::type p3_; + typename rtc::remove_reference::type p4_; + typename rtc::remove_reference::type p5_; }; @@ -785,12 +774,12 @@ class MethodFunctor6 { private: MethodT method_; typename detail::PointerType::type object_; - typename detail::RemoveScopedPtrRef::type p1_; - typename detail::RemoveScopedPtrRef::type p2_; - typename detail::RemoveScopedPtrRef::type p3_; - typename detail::RemoveScopedPtrRef::type p4_; - typename detail::RemoveScopedPtrRef::type p5_; - typename detail::RemoveScopedPtrRef::type p6_; + typename rtc::remove_reference::type p1_; + typename rtc::remove_reference::type p2_; + typename rtc::remove_reference::type p3_; + typename rtc::remove_reference::type p4_; + typename rtc::remove_reference::type p5_; + typename rtc::remove_reference::type p6_; }; template ::type p1_; - typename detail::RemoveScopedPtrRef::type p2_; - typename detail::RemoveScopedPtrRef::type p3_; - typename detail::RemoveScopedPtrRef::type p4_; - typename detail::RemoveScopedPtrRef::type p5_; - typename detail::RemoveScopedPtrRef::type p6_; + typename rtc::remove_reference::type p1_; + typename rtc::remove_reference::type p2_; + typename rtc::remove_reference::type p3_; + typename rtc::remove_reference::type p4_; + typename rtc::remove_reference::type p5_; + typename rtc::remove_reference::type p6_; }; @@ -912,6 +901,640 @@ Bind(FP_T(function), #undef FP_T +template +class MethodFunctor7 { + public: + MethodFunctor7(MethodT method, + ObjectT* object, + P1 p1, + P2 p2, + P3 p3, + P4 p4, + P5 p5, + P6 p6, + P7 p7) + : method_(method), + object_(object), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6), + p7_(p7) {} + R operator()() const { + return (object_->*method_)(p1_, p2_, p3_, p4_, p5_, p6_, p7_); + } + + private: + MethodT method_; + typename detail::PointerType::type object_; + typename rtc::remove_reference::type p1_; + typename rtc::remove_reference::type p2_; + typename rtc::remove_reference::type p3_; + typename rtc::remove_reference::type p4_; + typename rtc::remove_reference::type p5_; + typename rtc::remove_reference::type p6_; + typename rtc::remove_reference::type p7_; +}; + +template +class Functor7 { + public: + Functor7(const FunctorT& functor, + P1 p1, + P2 p2, + P3 p3, + P4 p4, + P5 p5, + P6 p6, + P7 p7) + : functor_(functor), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6), + p7_(p7) {} + R operator()() const { return functor_(p1_, p2_, p3_, p4_, p5_, p6_, p7_); } + + private: + FunctorT functor_; + typename rtc::remove_reference::type p1_; + typename rtc::remove_reference::type p2_; + typename rtc::remove_reference::type p3_; + typename rtc::remove_reference::type p4_; + typename rtc::remove_reference::type p5_; + typename rtc::remove_reference::type p6_; + typename rtc::remove_reference::type p7_; +}; + +#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6, P7) + +template +MethodFunctor7 Bind( + FP_T(method), + ObjectT* object, + typename detail::identity::type p1, + typename detail::identity::type p2, + typename detail::identity::type p3, + typename detail::identity::type p4, + typename detail::identity::type p5, + typename detail::identity::type p6, + typename detail::identity::type p7) { + return MethodFunctor7( + method, object, p1, p2, p3, p4, p5, p6, p7); +} + +#undef FP_T +#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6, P7) const + +template +MethodFunctor7 Bind( + FP_T(method), + const ObjectT* object, + typename detail::identity::type p1, + typename detail::identity::type p2, + typename detail::identity::type p3, + typename detail::identity::type p4, + typename detail::identity::type p5, + typename detail::identity::type p6, + typename detail::identity::type p7) { + return MethodFunctor7(method, object, p1, p2, p3, p4, p5, p6, p7); +} + +#undef FP_T +#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6, P7) + +template +MethodFunctor7 Bind( + FP_T(method), + const scoped_refptr& object, + typename detail::identity::type p1, + typename detail::identity::type p2, + typename detail::identity::type p3, + typename detail::identity::type p4, + typename detail::identity::type p5, + typename detail::identity::type p6, + typename detail::identity::type p7) { + return MethodFunctor7( + method, object.get(), p1, p2, p3, p4, p5, p6, p7); +} + +#undef FP_T +#define FP_T(x) R (*x)(P1, P2, P3, P4, P5, P6, P7) + +template +Functor7 Bind( + FP_T(function), + typename detail::identity::type p1, + typename detail::identity::type p2, + typename detail::identity::type p3, + typename detail::identity::type p4, + typename detail::identity::type p5, + typename detail::identity::type p6, + typename detail::identity::type p7) { + return Functor7( + function, p1, p2, p3, p4, p5, p6, p7); +} + +#undef FP_T + +template +class MethodFunctor8 { + public: + MethodFunctor8(MethodT method, + ObjectT* object, + P1 p1, + P2 p2, + P3 p3, + P4 p4, + P5 p5, + P6 p6, + P7 p7, + P8 p8) + : method_(method), + object_(object), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6), + p7_(p7), + p8_(p8) {} + R operator()() const { + return (object_->*method_)(p1_, p2_, p3_, p4_, p5_, p6_, p7_, p8_); + } + + private: + MethodT method_; + typename detail::PointerType::type object_; + typename rtc::remove_reference::type p1_; + typename rtc::remove_reference::type p2_; + typename rtc::remove_reference::type p3_; + typename rtc::remove_reference::type p4_; + typename rtc::remove_reference::type p5_; + typename rtc::remove_reference::type p6_; + typename rtc::remove_reference::type p7_; + typename rtc::remove_reference::type p8_; +}; + +template +class Functor8 { + public: + Functor8(const FunctorT& functor, + P1 p1, + P2 p2, + P3 p3, + P4 p4, + P5 p5, + P6 p6, + P7 p7, + P8 p8) + : functor_(functor), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6), + p7_(p7), + p8_(p8) {} + R operator()() const { + return functor_(p1_, p2_, p3_, p4_, p5_, p6_, p7_, p8_); + } + + private: + FunctorT functor_; + typename rtc::remove_reference::type p1_; + typename rtc::remove_reference::type p2_; + typename rtc::remove_reference::type p3_; + typename rtc::remove_reference::type p4_; + typename rtc::remove_reference::type p5_; + typename rtc::remove_reference::type p6_; + typename rtc::remove_reference::type p7_; + typename rtc::remove_reference::type p8_; +}; + +#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6, P7, P8) + +template +MethodFunctor8 Bind( + FP_T(method), + ObjectT* object, + typename detail::identity::type p1, + typename detail::identity::type p2, + typename detail::identity::type p3, + typename detail::identity::type p4, + typename detail::identity::type p5, + typename detail::identity::type p6, + typename detail::identity::type p7, + typename detail::identity::type p8) { + return MethodFunctor8(method, object, p1, p2, p3, p4, p5, p6, p7, p8); +} + +#undef FP_T +#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6, P7, P8) const + +template +MethodFunctor8 +Bind(FP_T(method), + const ObjectT* object, + typename detail::identity::type p1, + typename detail::identity::type p2, + typename detail::identity::type p3, + typename detail::identity::type p4, + typename detail::identity::type p5, + typename detail::identity::type p6, + typename detail::identity::type p7, + typename detail::identity::type p8) { + return MethodFunctor8(method, object, p1, p2, p3, p4, p5, p6, p7, p8); +} + +#undef FP_T +#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6, P7, P8) + +template +MethodFunctor8 Bind( + FP_T(method), + const scoped_refptr& object, + typename detail::identity::type p1, + typename detail::identity::type p2, + typename detail::identity::type p3, + typename detail::identity::type p4, + typename detail::identity::type p5, + typename detail::identity::type p6, + typename detail::identity::type p7, + typename detail::identity::type p8) { + return MethodFunctor8(method, object.get(), p1, p2, p3, p4, p5, p6, p7, + p8); +} + +#undef FP_T +#define FP_T(x) R (*x)(P1, P2, P3, P4, P5, P6, P7, P8) + +template +Functor8 Bind( + FP_T(function), + typename detail::identity::type p1, + typename detail::identity::type p2, + typename detail::identity::type p3, + typename detail::identity::type p4, + typename detail::identity::type p5, + typename detail::identity::type p6, + typename detail::identity::type p7, + typename detail::identity::type p8) { + return Functor8( + function, p1, p2, p3, p4, p5, p6, p7, p8); +} + +#undef FP_T + +template +class MethodFunctor9 { + public: + MethodFunctor9(MethodT method, + ObjectT* object, + P1 p1, + P2 p2, + P3 p3, + P4 p4, + P5 p5, + P6 p6, + P7 p7, + P8 p8, + P9 p9) + : method_(method), + object_(object), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6), + p7_(p7), + p8_(p8), + p9_(p9) {} + R operator()() const { + return (object_->*method_)(p1_, p2_, p3_, p4_, p5_, p6_, p7_, p8_, p9_); + } + + private: + MethodT method_; + typename detail::PointerType::type object_; + typename rtc::remove_reference::type p1_; + typename rtc::remove_reference::type p2_; + typename rtc::remove_reference::type p3_; + typename rtc::remove_reference::type p4_; + typename rtc::remove_reference::type p5_; + typename rtc::remove_reference::type p6_; + typename rtc::remove_reference::type p7_; + typename rtc::remove_reference::type p8_; + typename rtc::remove_reference::type p9_; +}; + +template +class Functor9 { + public: + Functor9(const FunctorT& functor, + P1 p1, + P2 p2, + P3 p3, + P4 p4, + P5 p5, + P6 p6, + P7 p7, + P8 p8, + P9 p9) + : functor_(functor), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4), + p5_(p5), + p6_(p6), + p7_(p7), + p8_(p8), + p9_(p9) {} + R operator()() const { + return functor_(p1_, p2_, p3_, p4_, p5_, p6_, p7_, p8_, p9_); + } + + private: + FunctorT functor_; + typename rtc::remove_reference::type p1_; + typename rtc::remove_reference::type p2_; + typename rtc::remove_reference::type p3_; + typename rtc::remove_reference::type p4_; + typename rtc::remove_reference::type p5_; + typename rtc::remove_reference::type p6_; + typename rtc::remove_reference::type p7_; + typename rtc::remove_reference::type p8_; + typename rtc::remove_reference::type p9_; +}; + +#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6, P7, P8, P9) + +template +MethodFunctor9 +Bind(FP_T(method), + ObjectT* object, + typename detail::identity::type p1, + typename detail::identity::type p2, + typename detail::identity::type p3, + typename detail::identity::type p4, + typename detail::identity::type p5, + typename detail::identity::type p6, + typename detail::identity::type p7, + typename detail::identity::type p8, + typename detail::identity::type p9) { + return MethodFunctor9(method, object, p1, p2, p3, p4, p5, p6, p7, p8, + p9); +} + +#undef FP_T +#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6, P7, P8, P9) const + +template +MethodFunctor9 +Bind(FP_T(method), + const ObjectT* object, + typename detail::identity::type p1, + typename detail::identity::type p2, + typename detail::identity::type p3, + typename detail::identity::type p4, + typename detail::identity::type p5, + typename detail::identity::type p6, + typename detail::identity::type p7, + typename detail::identity::type p8, + typename detail::identity::type p9) { + return MethodFunctor9(method, object, p1, p2, p3, p4, p5, p6, p7, + p8, p9); +} + +#undef FP_T +#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6, P7, P8, P9) + +template +MethodFunctor9 +Bind(FP_T(method), + const scoped_refptr& object, + typename detail::identity::type p1, + typename detail::identity::type p2, + typename detail::identity::type p3, + typename detail::identity::type p4, + typename detail::identity::type p5, + typename detail::identity::type p6, + typename detail::identity::type p7, + typename detail::identity::type p8, + typename detail::identity::type p9) { + return MethodFunctor9(method, object.get(), p1, p2, p3, p4, p5, p6, + p7, p8, p9); +} + +#undef FP_T +#define FP_T(x) R (*x)(P1, P2, P3, P4, P5, P6, P7, P8, P9) + +template +Functor9 Bind( + FP_T(function), + typename detail::identity::type p1, + typename detail::identity::type p2, + typename detail::identity::type p3, + typename detail::identity::type p4, + typename detail::identity::type p5, + typename detail::identity::type p6, + typename detail::identity::type p7, + typename detail::identity::type p8, + typename detail::identity::type p9) { + return Functor9( + function, p1, p2, p3, p4, p5, p6, p7, p8, p9); +} + +#undef FP_T + } // namespace rtc #undef NONAME diff --git a/webrtc/base/bind.h.pump b/webrtc/base/bind.h.pump index e1cea61fc2..6fb849095d 100644 --- a/webrtc/base/bind.h.pump +++ b/webrtc/base/bind.h.pump @@ -61,6 +61,7 @@ #define WEBRTC_BASE_BIND_H_ #include "webrtc/base/scoped_ref_ptr.h" +#include "webrtc/base/template_util.h" #define NONAME @@ -124,21 +125,9 @@ struct PointerType { T*>::type type; }; -// RemoveScopedPtrRef will capture scoped_refptr by-value instead of -// by-reference. -template struct RemoveScopedPtrRef { typedef T type; }; -template -struct RemoveScopedPtrRef&> { - typedef scoped_refptr type; -}; -template -struct RemoveScopedPtrRef&> { - typedef scoped_refptr type; -}; - } // namespace detail -$var n = 6 +$var n = 9 $range i 0..n $for i [[ $range j 1..i @@ -157,7 +146,7 @@ class MethodFunctor$i { MethodT method_; typename detail::PointerType::type object_;$for j [[ - typename detail::RemoveScopedPtrRef::type p$(j)_;]] + typename rtc::remove_reference::type p$(j)_;]] }; @@ -174,7 +163,7 @@ Functor$i(const FunctorT& functor$for j [[, P$j p$j]]) private: FunctorT functor_;$for j [[ - typename detail::RemoveScopedPtrRef::type p$(j)_;]] + typename rtc::remove_reference::type p$(j)_;]] }; diff --git a/webrtc/base/bind_unittest.cc b/webrtc/base/bind_unittest.cc index fa47d279f5..be8d79cb6a 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 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(value); + } int Multiply(int a, int b) const { ++call_count; return a * b; } void RefArgument(const scoped_refptr& 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&>::type, - scoped_refptr>::value, - "const scoped_refptr& should be captured by value"); +static_assert( + is_same< + rtc::remove_reference&>::type, + const scoped_refptr>::value, + "const scoped_refptr& should be captured by value"); -static_assert(is_same&>::type, - scoped_refptr>::value, +static_assert(is_same&>::type, + const scoped_refptr>::value, "const scoped_refptr& should be captured by value"); static_assert( - is_same::type, const int&>::value, - "const int& should be captured as const int&"); + is_same::type, const int>::value, + "const int& should be captured as const int"); -static_assert( - is_same::type, const F&>::value, - "const F& should be captured as const F&"); +static_assert(is_same::type, const F>::value, + "const F& should be captured as const F"); -static_assert( - is_same::type, F&>::value, - "F& should be captured as F&"); +static_assert(is_same::type, F>::value, + "F& should be captured as F"); #define EXPECT_IS_CAPTURED_AS_PTR(T) \ static_assert(is_same::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 diff --git a/webrtc/base/template_util.h b/webrtc/base/template_util.h index 86e541d8cf..31464cf35d 100644 --- a/webrtc/base/template_util.h +++ b/webrtc/base/template_util.h @@ -48,6 +48,19 @@ template struct is_non_const_reference : false_type {}; template struct is_void : false_type {}; template <> struct is_void : true_type {}; +template +struct remove_reference { + typedef T type; +}; +template +struct remove_reference { + typedef T type; +}; +template +struct remove_reference { + typedef T type; +}; + namespace internal { // Types YesType and NoType are guaranteed such that sizeof(YesType) < diff --git a/webrtc/p2p/base/transport.cc b/webrtc/p2p/base/transport.cc index 58817df79d..2328e4587c 100644 --- a/webrtc/p2p/base/transport.cc +++ b/webrtc/p2p/base/transport.cc @@ -22,8 +22,6 @@ namespace cricket { -using rtc::Bind; - static bool VerifyIceParams(const TransportDescription& desc) { // For legacy protocols. if (desc.ice_ufrag.empty() && desc.ice_pwd.empty())