| Index: webrtc/base/bind.h
|
| diff --git a/webrtc/base/bind.h b/webrtc/base/bind.h
|
| index 397a4d5c876608a07ecc5584c2f7f06d42250304..94eb164986f9b717766a68f6c85d4c10b2e1501a 100644
|
| --- a/webrtc/base/bind.h
|
| +++ b/webrtc/base/bind.h
|
| @@ -17,6 +17,10 @@
|
| // ref-counted method object or any arguments passed by pointer, and calling the
|
| // functor with a destroyed object will surely do bad things.
|
| //
|
| +// To prevent the method object from being captured as a scoped_refptr<>, you
|
| +// can use Unretained. But this should only be done when absolutely necessary,
|
| +// and when the caller knows the extra reference isn't needed.
|
| +//
|
| // Example usage:
|
| // struct Foo {
|
| // int Test1() { return 42; }
|
| @@ -125,8 +129,23 @@ struct PointerType {
|
| T*>::type type;
|
| };
|
|
|
| +template <typename T>
|
| +class UnretainedWrapper {
|
| + public:
|
| + explicit UnretainedWrapper(T* o) : ptr_(o) {}
|
| + T* get() const { return ptr_; }
|
| +
|
| + private:
|
| + T* ptr_;
|
| +};
|
| +
|
| } // namespace detail
|
|
|
| +template <typename T>
|
| +static inline detail::UnretainedWrapper<T> Unretained(T* o) {
|
| + return detail::UnretainedWrapper<T>(o);
|
| +}
|
| +
|
| template <class ObjectT, class MethodT, class R, typename... Args>
|
| class MethodFunctor {
|
| public:
|
| @@ -150,6 +169,31 @@ class MethodFunctor {
|
| typename std::tuple<typename std::remove_reference<Args>::type...> args_;
|
| };
|
|
|
| +template <class ObjectT, class MethodT, class R, typename... Args>
|
| +class UnretainedMethodFunctor {
|
| + public:
|
| + UnretainedMethodFunctor(MethodT method,
|
| + detail::UnretainedWrapper<ObjectT> object,
|
| + Args... args)
|
| + : method_(method), object_(object.get()), args_(args...) {}
|
| + R operator()() const {
|
| + return CallMethod(typename sequence_generator<sizeof...(Args)>::type());
|
| + }
|
| +
|
| + private:
|
| + // Use sequence_generator (see template_util.h) to expand an
|
| + // UnretainedMethodFunctor with 2 arguments to (std::get<0>(args_),
|
| + // std::get<1>(args_)), for instance.
|
| + template <int... S>
|
| + R CallMethod(sequence<S...>) const {
|
| + return (object_->*method_)(std::get<S>(args_)...);
|
| + }
|
| +
|
| + MethodT method_;
|
| + ObjectT* object_;
|
| + typename std::tuple<typename std::remove_reference<Args>::type...> args_;
|
| +};
|
| +
|
| template <class FunctorT, class R, typename... Args>
|
| class Functor {
|
| public:
|
| @@ -183,6 +227,24 @@ MethodFunctor<ObjectT, FP_T(NONAME), R, Args...> Bind(
|
| args...);
|
| }
|
|
|
| +template <class ObjectT, class R, typename... Args>
|
| +MethodFunctor<ObjectT, FP_T(NONAME), R, Args...> Bind(
|
| + FP_T(method),
|
| + const scoped_refptr<ObjectT>& object,
|
| + typename detail::identity<Args>::type... args) {
|
| + return MethodFunctor<ObjectT, FP_T(NONAME), R, Args...>(method, object.get(),
|
| + args...);
|
| +}
|
| +
|
| +template <class ObjectT, class R, typename... Args>
|
| +UnretainedMethodFunctor<ObjectT, FP_T(NONAME), R, Args...> Bind(
|
| + FP_T(method),
|
| + detail::UnretainedWrapper<ObjectT> object,
|
| + typename detail::identity<Args>::type... args) {
|
| + return UnretainedMethodFunctor<ObjectT, FP_T(NONAME), R, Args...>(
|
| + method, object, args...);
|
| +}
|
| +
|
| #undef FP_T
|
| #define FP_T(x) R (ObjectT::*x)(Args...) const
|
|
|
| @@ -194,17 +256,13 @@ MethodFunctor<const ObjectT, FP_T(NONAME), R, Args...> Bind(
|
| return MethodFunctor<const ObjectT, FP_T(NONAME), R, Args...>(method, object,
|
| args...);
|
| }
|
| -
|
| -#undef FP_T
|
| -#define FP_T(x) R (ObjectT::*x)(Args...)
|
| -
|
| template <class ObjectT, class R, typename... Args>
|
| -MethodFunctor<ObjectT, FP_T(NONAME), R, Args...> Bind(
|
| +UnretainedMethodFunctor<const ObjectT, FP_T(NONAME), R, Args...> Bind(
|
| FP_T(method),
|
| - const scoped_refptr<ObjectT>& object,
|
| + detail::UnretainedWrapper<const ObjectT> object,
|
| typename detail::identity<Args>::type... args) {
|
| - return MethodFunctor<ObjectT, FP_T(NONAME), R, Args...>(method, object.get(),
|
| - args...);
|
| + return UnretainedMethodFunctor<const ObjectT, FP_T(NONAME), R, Args...>(
|
| + method, object, args...);
|
| }
|
|
|
| #undef FP_T
|
|
|