| Index: base/bind_helpers.h
|
| diff --git a/base/bind_helpers.h b/base/bind_helpers.h
|
| index 29057baef20cb000b91be992c605cfba18d2834f..a7c2acc09c9703a1e07a8a274f3dc53deb53d428 100644
|
| --- a/base/bind_helpers.h
|
| +++ b/base/bind_helpers.h
|
| @@ -176,86 +176,6 @@ struct IsWeakReceiver;
|
|
|
| namespace internal {
|
|
|
| -// Use the Substitution Failure Is Not An Error (SFINAE) trick to inspect T
|
| -// for the existence of AddRef() and Release() functions of the correct
|
| -// signature.
|
| -//
|
| -// http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error
|
| -// http://stackoverflow.com/questions/257288/is-it-possible-to-write-a-c-template-to-check-for-a-functions-existence
|
| -// http://stackoverflow.com/questions/4358584/sfinae-approach-comparison
|
| -// http://stackoverflow.com/questions/1966362/sfinae-to-check-for-inherited-member-functions
|
| -//
|
| -// The last link in particular show the method used below.
|
| -//
|
| -// For SFINAE to work with inherited methods, we need to pull some extra tricks
|
| -// with multiple inheritance. In the more standard formulation, the overloads
|
| -// of Check would be:
|
| -//
|
| -// template <typename C>
|
| -// Yes NotTheCheckWeWant(Helper<&C::TargetFunc>*);
|
| -//
|
| -// template <typename C>
|
| -// No NotTheCheckWeWant(...);
|
| -//
|
| -// static const bool value = sizeof(NotTheCheckWeWant<T>(0)) == sizeof(Yes);
|
| -//
|
| -// The problem here is that template resolution will not match
|
| -// C::TargetFunc if TargetFunc does not exist directly in C. That is, if
|
| -// TargetFunc in inherited from an ancestor, &C::TargetFunc will not match,
|
| -// |value| will be false. This formulation only checks for whether or
|
| -// not TargetFunc exist directly in the class being introspected.
|
| -//
|
| -// To get around this, we play a dirty trick with multiple inheritance.
|
| -// First, We create a class BaseMixin that declares each function that we
|
| -// want to probe for. Then we create a class Base that inherits from both T
|
| -// (the class we wish to probe) and BaseMixin. Note that the function
|
| -// signature in BaseMixin does not need to match the signature of the function
|
| -// we are probing for; thus it's easiest to just use void().
|
| -//
|
| -// Now, if TargetFunc exists somewhere in T, then &Base::TargetFunc has an
|
| -// ambiguous resolution between BaseMixin and T. This lets us write the
|
| -// following:
|
| -//
|
| -// template <typename C>
|
| -// No GoodCheck(Helper<&C::TargetFunc>*);
|
| -//
|
| -// template <typename C>
|
| -// Yes GoodCheck(...);
|
| -//
|
| -// static const bool value = sizeof(GoodCheck<Base>(0)) == sizeof(Yes);
|
| -//
|
| -// Notice here that the variadic version of GoodCheck() returns Yes here
|
| -// instead of No like the previous one. Also notice that we calculate |value|
|
| -// by specializing GoodCheck() on Base instead of T.
|
| -//
|
| -// We've reversed the roles of the variadic, and Helper overloads.
|
| -// GoodCheck(Helper<&C::TargetFunc>*), when C = Base, fails to be a valid
|
| -// substitution if T::TargetFunc exists. Thus GoodCheck<Base>(0) will resolve
|
| -// to the variadic version if T has TargetFunc. If T::TargetFunc does not
|
| -// exist, then &C::TargetFunc is not ambiguous, and the overload resolution
|
| -// will prefer GoodCheck(Helper<&C::TargetFunc>*).
|
| -//
|
| -// This method of SFINAE will correctly probe for inherited names, but it cannot
|
| -// typecheck those names. It's still a good enough sanity check though.
|
| -//
|
| -// Works on gcc-4.2, gcc-4.4, and Visual Studio 2008.
|
| -//
|
| -
|
| -template <typename T>
|
| -class HasIsMethodTag {
|
| - using Yes = char[1];
|
| - using No = char[2];
|
| -
|
| - template <typename U>
|
| - static Yes& Check(typename U::IsMethod*);
|
| -
|
| - template <typename U>
|
| - static No& Check(...);
|
| -
|
| - public:
|
| - enum { value = sizeof(Check<T>(0)) == sizeof(Yes) };
|
| -};
|
| -
|
| template <typename T>
|
| class UnretainedWrapper {
|
| public:
|
| @@ -287,6 +207,7 @@ class RetainedRefWrapper {
|
| template <typename T>
|
| struct IgnoreResultHelper {
|
| explicit IgnoreResultHelper(T functor) : functor_(std::move(functor)) {}
|
| + explicit operator bool() const { return !!functor_; }
|
|
|
| T functor_;
|
| };
|
|
|