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