bind_helpers.h revision ddb351dbec246cf1fab5ec20d2d5520909041de1
172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// found in the LICENSE file. 472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// This defines a set of argument wrappers and related factory methods that 672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// can be used specify the refcounting and reference semantics of arguments 772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// that are bound by the Bind() function in base/bind.h. 872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// The public functions are base::Unretained() and base::ConstRef(). 1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Unretained() allows Bind() to bind a non-refcounted class. 1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// ConstRef() allows binding a constant reference to an argument rather 1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// than a copy. 1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// EXAMPLE OF Unretained(): 1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// class Foo { 1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// public: 1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// void func() { cout << "Foo:f" << endl; 2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// }; 2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// // In some function somewhere. 2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Foo foo; 2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Callback<void(void)> foo_callback = 2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Bind(&Foo::func, Unretained(&foo)); 2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// foo_callback.Run(); // Prints "Foo:f". 2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Without the Unretained() wrapper on |&foo|, the above call would fail 2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// to compile because Foo does not support the AddRef() and Release() methods. 3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// EXAMPLE OF ConstRef(); 3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// void foo(int arg) { cout << arg << endl } 3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// int n = 1; 3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Callback<void(void)> no_ref = Bind(&foo, n); 3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Callback<void(void)> has_ref = Bind(&foo, ConstRef(n)); 3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// no_ref.Run(); // Prints "1" 4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// has_ref.Run(); // Prints "1" 4172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// n = 2; 4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// no_ref.Run(); // Prints "1" 4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// has_ref.Run(); // Prints "2" 4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Note that because ConstRef() takes a reference on |n|, |n| must outlive all 4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// its bound callbacks. 4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#ifndef BASE_BIND_HELPERS_H_ 5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#define BASE_BIND_HELPERS_H_ 5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#pragma once 5372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/basictypes.h" 5572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/template_util.h" 5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsennamespace base { 5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsennamespace internal { 5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Use the Substitution Failure Is Not An Error (SFINAE) trick to inspect T 6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// for the existence of AddRef() and Release() functions of the correct 6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// signature. 6372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 6472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error 6572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// http://stackoverflow.com/questions/257288/is-it-possible-to-write-a-c-template-to-check-for-a-functions-existence 6672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// http://stackoverflow.com/questions/4358584/sfinae-approach-comparison 6772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// http://stackoverflow.com/questions/1966362/sfinae-to-check-for-inherited-member-functions 6872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 6972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// The last link in particular show the method used below. 7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// For SFINAE to work with inherited methods, we need to pull some extra tricks 7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// with multiple inheritance. In the more standard formulation, the overloads 7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// of Check would be: 7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// template <typename C> 7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Yes NotTheCheckWeWant(Helper<&C::TargetFunc>*); 7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// template <typename C> 7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// No NotTheCheckWeWant(...); 8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 8172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static const bool value = sizeof(NotTheCheckWeWant<T>(0)) == sizeof(Yes); 8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// The problem here is that template resolution will not match 8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// C::TargetFunc if TargetFunc does not exist directly in C. That is, if 8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// TargetFunc in inherited from an ancestor, &C::TargetFunc will not match, 8672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// |value| will be false. This formulation only checks for whether or 8772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// not TargetFunc exist directly in the class being introspected. 8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// To get around this, we play a dirty trick with multiple inheritance. 9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// First, We create a class BaseMixin that declares each function that we 9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// want to probe for. Then we create a class Base that inherits from both T 9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// (the class we wish to probe) and BaseMixin. Note that the function 9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// signature in BaseMixin does not need to match the signature of the function 9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// we are probing for; thus it's easiest to just use void(void). 9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Now, if TargetFunc exists somewhere in T, then &Base::TargetFunc has an 9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// ambiguous resolution between BaseMixin and T. This lets us write the 9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// following: 9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// template <typename C> 10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// No GoodCheck(Helper<&C::TargetFunc>*); 10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// template <typename C> 10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Yes GoodCheck(...); 10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static const bool value = sizeof(GoodCheck<Base>(0)) == sizeof(Yes); 10772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Notice here that the variadic version of GoodCheck() returns Yes here 10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// instead of No like the previous one. Also notice that we calculate |value| 11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// by specializing GoodCheck() on Base instead of T. 11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// We've reversed the roles of the variadic, and Helper overloads. 11372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// GoodCheck(Helper<&C::TargetFunc>*), when C = Base, fails to be a valid 11472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// substitution if T::TargetFunc exists. Thus GoodCheck<Base>(0) will resolve 11572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// to the variadic version if T has TargetFunc. If T::TargetFunc does not 11672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// exist, then &C::TargetFunc is not ambiguous, and the overload resolution 11772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// will prefer GoodCheck(Helper<&C::TargetFunc>*). 11872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 11972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// This method of SFINAE will correctly probe for inherited names, but it cannot 12072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// typecheck those names. It's still a good enough sanity check though. 12172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 12272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Works on gcc-4.2, gcc-4.4, and Visual Studio 2008. 12372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// TODO(ajwong): Move to ref_counted.h or template_util.h when we've vetted 12572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// this works well. 12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename T> 12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass SupportsAddRefAndRelease { 12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen typedef char Yes[1]; 12972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen typedef char No[2]; 13072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen struct BaseMixin { 13272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen void AddRef(); 13372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen void Release(); 13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }; 13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// MSVC warns when you try to use Base if T has a private destructor, the 137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// common pattern for refcounted types. It does this even though no attempt to 138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// instantiate Base is made. We disable the warning for this definition. 139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_WIN) 140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#pragma warning(disable:4624) 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif 14272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen struct Base : public T, public BaseMixin { 14372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }; 144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_WIN) 145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#pragma warning(default:4624) 146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif 14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 14872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen template <void(BaseMixin::*)(void)> struct Helper {}; 14972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 15072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen template <typename C> 15172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static No& Check(Helper<&C::AddRef>*, Helper<&C::Release>*); 15272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 15372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen template <typename > 15472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static Yes& Check(...); 15572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 15672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public: 15772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static const bool value = sizeof(Check<Base>(0,0)) == sizeof(Yes); 15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 16072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 16172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Helpers to assert that arguments of a recounted type are bound with a 16272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// scoped_refptr. 16372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <bool IsClasstype, typename T> 16472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct UnsafeBindtoRefCountedArgHelper : false_type { 16572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 16672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 16772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename T> 16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct UnsafeBindtoRefCountedArgHelper<true, T> 16972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : integral_constant<bool, SupportsAddRefAndRelease<T>::value> { 17072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 17172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 17272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename T> 173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstruct UnsafeBindtoRefCountedArg : false_type { 174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}; 175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsentemplate <typename T> 177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstruct UnsafeBindtoRefCountedArg<T*> 17872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : UnsafeBindtoRefCountedArgHelper<is_class<T>::value, T> { 17972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 18072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename T> 18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass UnretainedWrapper { 18472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public: 18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen explicit UnretainedWrapper(T* o) : obj_(o) {} 18672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen T* get() { return obj_; } 18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen private: 18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen T* obj_; 18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 19072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename T> 19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass ConstRefWrapper { 19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public: 19472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen explicit ConstRefWrapper(const T& o) : ptr_(&o) {} 19572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const T& get() { return *ptr_; } 19672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen private: 19772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const T* ptr_; 19872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 19972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 20072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 20172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Unwrap the stored parameters for the wrappers above. 20272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename T> 20372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenT Unwrap(T o) { return o; } 20472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 20572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename T> 20672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenT* Unwrap(UnretainedWrapper<T> unretained) { return unretained.get(); } 20772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 20872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename T> 20972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst T& Unwrap(ConstRefWrapper<T> const_ref) { 21072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return const_ref.get(); 21172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 21272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 21372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Utility for handling different refcounting semantics in the Bind() 21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// function. 21672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename ref, typename T> 21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct MaybeRefcount; 21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 21972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename T> 22072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct MaybeRefcount<base::false_type, T> { 22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static void AddRef(const T&) {} 22272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static void Release(const T&) {} 22372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 22472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 22572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename T, size_t n> 22672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct MaybeRefcount<base::false_type, T[n]> { 22772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static void AddRef(const T*) {} 22872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static void Release(const T*) {} 22972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 23072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 23172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename T> 23272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct MaybeRefcount<base::true_type, UnretainedWrapper<T> > { 23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static void AddRef(const UnretainedWrapper<T>&) {} 23472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static void Release(const UnretainedWrapper<T>&) {} 23572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename T> 23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct MaybeRefcount<base::true_type, T*> { 23972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static void AddRef(T* o) { o->AddRef(); } 24072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static void Release(T* o) { o->Release(); } 24172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 24272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 24372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename T> 24472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct MaybeRefcount<base::true_type, const T*> { 24572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static void AddRef(const T* o) { o->AddRef(); } 24672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static void Release(const T* o) { o->Release(); } 24772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 24872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} // namespace internal 25072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename T> 25272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monseninline internal::UnretainedWrapper<T> Unretained(T* o) { 25372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return internal::UnretainedWrapper<T>(o); 25472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 25672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename T> 25772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monseninline internal::ConstRefWrapper<T> ConstRef(const T& o) { 25872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return internal::ConstRefWrapper<T>(o); 25972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 26072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 26172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} // namespace base 26272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif // BASE_BIND_HELPERS_H_ 264