security/sandbox/chromium/base/bind_helpers.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/sandbox/chromium/base/bind_helpers.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,544 @@
     1.4 +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
     1.5 +// Use of this source code is governed by a BSD-style license that can be
     1.6 +// found in the LICENSE file.
     1.7 +
     1.8 +// This defines a set of argument wrappers and related factory methods that
     1.9 +// can be used specify the refcounting and reference semantics of arguments
    1.10 +// that are bound by the Bind() function in base/bind.h.
    1.11 +//
    1.12 +// It also defines a set of simple functions and utilities that people want
    1.13 +// when using Callback<> and Bind().
    1.14 +//
    1.15 +//
    1.16 +// ARGUMENT BINDING WRAPPERS
    1.17 +//
    1.18 +// The wrapper functions are base::Unretained(), base::Owned(), bass::Passed(),
    1.19 +// base::ConstRef(), and base::IgnoreResult().
    1.20 +//
    1.21 +// Unretained() allows Bind() to bind a non-refcounted class, and to disable
    1.22 +// refcounting on arguments that are refcounted objects.
    1.23 +//
    1.24 +// Owned() transfers ownership of an object to the Callback resulting from
    1.25 +// bind; the object will be deleted when the Callback is deleted.
    1.26 +//
    1.27 +// Passed() is for transferring movable-but-not-copyable types (eg. scoped_ptr)
    1.28 +// through a Callback. Logically, this signifies a destructive transfer of
    1.29 +// the state of the argument into the target function.  Invoking
    1.30 +// Callback::Run() twice on a Callback that was created with a Passed()
    1.31 +// argument will CHECK() because the first invocation would have already
    1.32 +// transferred ownership to the target function.
    1.33 +//
    1.34 +// ConstRef() allows binding a constant reference to an argument rather
    1.35 +// than a copy.
    1.36 +//
    1.37 +// IgnoreResult() is used to adapt a function or Callback with a return type to
    1.38 +// one with a void return. This is most useful if you have a function with,
    1.39 +// say, a pesky ignorable bool return that you want to use with PostTask or
    1.40 +// something else that expect a Callback with a void return.
    1.41 +//
    1.42 +// EXAMPLE OF Unretained():
    1.43 +//
    1.44 +//   class Foo {
    1.45 +//    public:
    1.46 +//     void func() { cout << "Foo:f" << endl; }
    1.47 +//   };
    1.48 +//
    1.49 +//   // In some function somewhere.
    1.50 +//   Foo foo;
    1.51 +//   Closure foo_callback =
    1.52 +//       Bind(&Foo::func, Unretained(&foo));
    1.53 +//   foo_callback.Run();  // Prints "Foo:f".
    1.54 +//
    1.55 +// Without the Unretained() wrapper on |&foo|, the above call would fail
    1.56 +// to compile because Foo does not support the AddRef() and Release() methods.
    1.57 +//
    1.58 +//
    1.59 +// EXAMPLE OF Owned():
    1.60 +//
    1.61 +//   void foo(int* arg) { cout << *arg << endl }
    1.62 +//
    1.63 +//   int* pn = new int(1);
    1.64 +//   Closure foo_callback = Bind(&foo, Owned(pn));
    1.65 +//
    1.66 +//   foo_callback.Run();  // Prints "1"
    1.67 +//   foo_callback.Run();  // Prints "1"
    1.68 +//   *n = 2;
    1.69 +//   foo_callback.Run();  // Prints "2"
    1.70 +//
    1.71 +//   foo_callback.Reset();  // |pn| is deleted.  Also will happen when
    1.72 +//                          // |foo_callback| goes out of scope.
    1.73 +//
    1.74 +// Without Owned(), someone would have to know to delete |pn| when the last
    1.75 +// reference to the Callback is deleted.
    1.76 +//
    1.77 +//
    1.78 +// EXAMPLE OF ConstRef():
    1.79 +//
    1.80 +//   void foo(int arg) { cout << arg << endl }
    1.81 +//
    1.82 +//   int n = 1;
    1.83 +//   Closure no_ref = Bind(&foo, n);
    1.84 +//   Closure has_ref = Bind(&foo, ConstRef(n));
    1.85 +//
    1.86 +//   no_ref.Run();  // Prints "1"
    1.87 +//   has_ref.Run();  // Prints "1"
    1.88 +//
    1.89 +//   n = 2;
    1.90 +//   no_ref.Run();  // Prints "1"
    1.91 +//   has_ref.Run();  // Prints "2"
    1.92 +//
    1.93 +// Note that because ConstRef() takes a reference on |n|, |n| must outlive all
    1.94 +// its bound callbacks.
    1.95 +//
    1.96 +//
    1.97 +// EXAMPLE OF IgnoreResult():
    1.98 +//
    1.99 +//   int DoSomething(int arg) { cout << arg << endl; }
   1.100 +//
   1.101 +//   // Assign to a Callback with a void return type.
   1.102 +//   Callback<void(int)> cb = Bind(IgnoreResult(&DoSomething));
   1.103 +//   cb->Run(1);  // Prints "1".
   1.104 +//
   1.105 +//   // Prints "1" on |ml|.
   1.106 +//   ml->PostTask(FROM_HERE, Bind(IgnoreResult(&DoSomething), 1);
   1.107 +//
   1.108 +//
   1.109 +// EXAMPLE OF Passed():
   1.110 +//
   1.111 +//   void TakesOwnership(scoped_ptr<Foo> arg) { }
   1.112 +//   scoped_ptr<Foo> CreateFoo() { return scoped_ptr<Foo>(new Foo()); }
   1.113 +//
   1.114 +//   scoped_ptr<Foo> f(new Foo());
   1.115 +//
   1.116 +//   // |cb| is given ownership of Foo(). |f| is now NULL.
   1.117 +//   // You can use f.Pass() in place of &f, but it's more verbose.
   1.118 +//   Closure cb = Bind(&TakesOwnership, Passed(&f));
   1.119 +//
   1.120 +//   // Run was never called so |cb| still owns Foo() and deletes
   1.121 +//   // it on Reset().
   1.122 +//   cb.Reset();
   1.123 +//
   1.124 +//   // |cb| is given a new Foo created by CreateFoo().
   1.125 +//   cb = Bind(&TakesOwnership, Passed(CreateFoo()));
   1.126 +//
   1.127 +//   // |arg| in TakesOwnership() is given ownership of Foo(). |cb|
   1.128 +//   // no longer owns Foo() and, if reset, would not delete Foo().
   1.129 +//   cb.Run();  // Foo() is now transferred to |arg| and deleted.
   1.130 +//   cb.Run();  // This CHECK()s since Foo() already been used once.
   1.131 +//
   1.132 +// Passed() is particularly useful with PostTask() when you are transferring
   1.133 +// ownership of an argument into a task, but don't necessarily know if the
   1.134 +// task will always be executed. This can happen if the task is cancellable
   1.135 +// or if it is posted to a MessageLoopProxy.
   1.136 +//
   1.137 +//
   1.138 +// SIMPLE FUNCTIONS AND UTILITIES.
   1.139 +//
   1.140 +//   DoNothing() - Useful for creating a Closure that does nothing when called.
   1.141 +//   DeletePointer<T>() - Useful for creating a Closure that will delete a
   1.142 +//                        pointer when invoked. Only use this when necessary.
   1.143 +//                        In most cases MessageLoop::DeleteSoon() is a better
   1.144 +//                        fit.
   1.145 +
   1.146 +#ifndef BASE_BIND_HELPERS_H_
   1.147 +#define BASE_BIND_HELPERS_H_
   1.148 +
   1.149 +#include "base/basictypes.h"
   1.150 +#include "base/callback.h"
   1.151 +#include "base/memory/weak_ptr.h"
   1.152 +#include "base/template_util.h"
   1.153 +
   1.154 +namespace base {
   1.155 +namespace internal {
   1.156 +
   1.157 +// Use the Substitution Failure Is Not An Error (SFINAE) trick to inspect T
   1.158 +// for the existence of AddRef() and Release() functions of the correct
   1.159 +// signature.
   1.160 +//
   1.161 +// http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error
   1.162 +// http://stackoverflow.com/questions/257288/is-it-possible-to-write-a-c-template-to-check-for-a-functions-existence
   1.163 +// http://stackoverflow.com/questions/4358584/sfinae-approach-comparison
   1.164 +// http://stackoverflow.com/questions/1966362/sfinae-to-check-for-inherited-member-functions
   1.165 +//
   1.166 +// The last link in particular show the method used below.
   1.167 +//
   1.168 +// For SFINAE to work with inherited methods, we need to pull some extra tricks
   1.169 +// with multiple inheritance.  In the more standard formulation, the overloads
   1.170 +// of Check would be:
   1.171 +//
   1.172 +//   template <typename C>
   1.173 +//   Yes NotTheCheckWeWant(Helper<&C::TargetFunc>*);
   1.174 +//
   1.175 +//   template <typename C>
   1.176 +//   No NotTheCheckWeWant(...);
   1.177 +//
   1.178 +//   static const bool value = sizeof(NotTheCheckWeWant<T>(0)) == sizeof(Yes);
   1.179 +//
   1.180 +// The problem here is that template resolution will not match
   1.181 +// C::TargetFunc if TargetFunc does not exist directly in C.  That is, if
   1.182 +// TargetFunc in inherited from an ancestor, &C::TargetFunc will not match,
   1.183 +// |value| will be false.  This formulation only checks for whether or
   1.184 +// not TargetFunc exist directly in the class being introspected.
   1.185 +//
   1.186 +// To get around this, we play a dirty trick with multiple inheritance.
   1.187 +// First, We create a class BaseMixin that declares each function that we
   1.188 +// want to probe for.  Then we create a class Base that inherits from both T
   1.189 +// (the class we wish to probe) and BaseMixin.  Note that the function
   1.190 +// signature in BaseMixin does not need to match the signature of the function
   1.191 +// we are probing for; thus it's easiest to just use void(void).
   1.192 +//
   1.193 +// Now, if TargetFunc exists somewhere in T, then &Base::TargetFunc has an
   1.194 +// ambiguous resolution between BaseMixin and T.  This lets us write the
   1.195 +// following:
   1.196 +//
   1.197 +//   template <typename C>
   1.198 +//   No GoodCheck(Helper<&C::TargetFunc>*);
   1.199 +//
   1.200 +//   template <typename C>
   1.201 +//   Yes GoodCheck(...);
   1.202 +//
   1.203 +//   static const bool value = sizeof(GoodCheck<Base>(0)) == sizeof(Yes);
   1.204 +//
   1.205 +// Notice here that the variadic version of GoodCheck() returns Yes here
   1.206 +// instead of No like the previous one. Also notice that we calculate |value|
   1.207 +// by specializing GoodCheck() on Base instead of T.
   1.208 +//
   1.209 +// We've reversed the roles of the variadic, and Helper overloads.
   1.210 +// GoodCheck(Helper<&C::TargetFunc>*), when C = Base, fails to be a valid
   1.211 +// substitution if T::TargetFunc exists. Thus GoodCheck<Base>(0) will resolve
   1.212 +// to the variadic version if T has TargetFunc.  If T::TargetFunc does not
   1.213 +// exist, then &C::TargetFunc is not ambiguous, and the overload resolution
   1.214 +// will prefer GoodCheck(Helper<&C::TargetFunc>*).
   1.215 +//
   1.216 +// This method of SFINAE will correctly probe for inherited names, but it cannot
   1.217 +// typecheck those names.  It's still a good enough sanity check though.
   1.218 +//
   1.219 +// Works on gcc-4.2, gcc-4.4, and Visual Studio 2008.
   1.220 +//
   1.221 +// TODO(ajwong): Move to ref_counted.h or template_util.h when we've vetted
   1.222 +// this works well.
   1.223 +//
   1.224 +// TODO(ajwong): Make this check for Release() as well.
   1.225 +// See http://crbug.com/82038.
   1.226 +template <typename T>
   1.227 +class SupportsAddRefAndRelease {
   1.228 +  typedef char Yes[1];
   1.229 +  typedef char No[2];
   1.230 +
   1.231 +  struct BaseMixin {
   1.232 +    void AddRef();
   1.233 +  };
   1.234 +
   1.235 +// MSVC warns when you try to use Base if T has a private destructor, the
   1.236 +// common pattern for refcounted types. It does this even though no attempt to
   1.237 +// instantiate Base is made.  We disable the warning for this definition.
   1.238 +#if defined(OS_WIN)
   1.239 +#pragma warning(push)
   1.240 +#pragma warning(disable:4624)
   1.241 +#endif
   1.242 +  struct Base : public T, public BaseMixin {
   1.243 +  };
   1.244 +#if defined(OS_WIN)
   1.245 +#pragma warning(pop)
   1.246 +#endif
   1.247 +
   1.248 +  template <void(BaseMixin::*)(void)> struct Helper {};
   1.249 +
   1.250 +  template <typename C>
   1.251 +  static No& Check(Helper<&C::AddRef>*);
   1.252 +
   1.253 +  template <typename >
   1.254 +  static Yes& Check(...);
   1.255 +
   1.256 + public:
   1.257 +  static const bool value = sizeof(Check<Base>(0)) == sizeof(Yes);
   1.258 +};
   1.259 +
   1.260 +// Helpers to assert that arguments of a recounted type are bound with a
   1.261 +// scoped_refptr.
   1.262 +template <bool IsClasstype, typename T>
   1.263 +struct UnsafeBindtoRefCountedArgHelper : false_type {
   1.264 +};
   1.265 +
   1.266 +template <typename T>
   1.267 +struct UnsafeBindtoRefCountedArgHelper<true, T>
   1.268 +    : integral_constant<bool, SupportsAddRefAndRelease<T>::value> {
   1.269 +};
   1.270 +
   1.271 +template <typename T>
   1.272 +struct UnsafeBindtoRefCountedArg : false_type {
   1.273 +};
   1.274 +
   1.275 +template <typename T>
   1.276 +struct UnsafeBindtoRefCountedArg<T*>
   1.277 +    : UnsafeBindtoRefCountedArgHelper<is_class<T>::value, T> {
   1.278 +};
   1.279 +
   1.280 +template <typename T>
   1.281 +class HasIsMethodTag {
   1.282 +  typedef char Yes[1];
   1.283 +  typedef char No[2];
   1.284 +
   1.285 +  template <typename U>
   1.286 +  static Yes& Check(typename U::IsMethod*);
   1.287 +
   1.288 +  template <typename U>
   1.289 +  static No& Check(...);
   1.290 +
   1.291 + public:
   1.292 +  static const bool value = sizeof(Check<T>(0)) == sizeof(Yes);
   1.293 +};
   1.294 +
   1.295 +template <typename T>
   1.296 +class UnretainedWrapper {
   1.297 + public:
   1.298 +  explicit UnretainedWrapper(T* o) : ptr_(o) {}
   1.299 +  T* get() const { return ptr_; }
   1.300 + private:
   1.301 +  T* ptr_;
   1.302 +};
   1.303 +
   1.304 +template <typename T>
   1.305 +class ConstRefWrapper {
   1.306 + public:
   1.307 +  explicit ConstRefWrapper(const T& o) : ptr_(&o) {}
   1.308 +  const T& get() const { return *ptr_; }
   1.309 + private:
   1.310 +  const T* ptr_;
   1.311 +};
   1.312 +
   1.313 +template <typename T>
   1.314 +struct IgnoreResultHelper {
   1.315 +  explicit IgnoreResultHelper(T functor) : functor_(functor) {}
   1.316 +
   1.317 +  T functor_;
   1.318 +};
   1.319 +
   1.320 +template <typename T>
   1.321 +struct IgnoreResultHelper<Callback<T> > {
   1.322 +  explicit IgnoreResultHelper(const Callback<T>& functor) : functor_(functor) {}
   1.323 +
   1.324 +  const Callback<T>& functor_;
   1.325 +};
   1.326 +
   1.327 +// An alternate implementation is to avoid the destructive copy, and instead
   1.328 +// specialize ParamTraits<> for OwnedWrapper<> to change the StorageType to
   1.329 +// a class that is essentially a scoped_ptr<>.
   1.330 +//
   1.331 +// The current implementation has the benefit though of leaving ParamTraits<>
   1.332 +// fully in callback_internal.h as well as avoiding type conversions during
   1.333 +// storage.
   1.334 +template <typename T>
   1.335 +class OwnedWrapper {
   1.336 + public:
   1.337 +  explicit OwnedWrapper(T* o) : ptr_(o) {}
   1.338 +  ~OwnedWrapper() { delete ptr_; }
   1.339 +  T* get() const { return ptr_; }
   1.340 +  OwnedWrapper(const OwnedWrapper& other) {
   1.341 +    ptr_ = other.ptr_;
   1.342 +    other.ptr_ = NULL;
   1.343 +  }
   1.344 +
   1.345 + private:
   1.346 +  mutable T* ptr_;
   1.347 +};
   1.348 +
   1.349 +// PassedWrapper is a copyable adapter for a scoper that ignores const.
   1.350 +//
   1.351 +// It is needed to get around the fact that Bind() takes a const reference to
   1.352 +// all its arguments.  Because Bind() takes a const reference to avoid
   1.353 +// unnecessary copies, it is incompatible with movable-but-not-copyable
   1.354 +// types; doing a destructive "move" of the type into Bind() would violate
   1.355 +// the const correctness.
   1.356 +//
   1.357 +// This conundrum cannot be solved without either C++11 rvalue references or
   1.358 +// a O(2^n) blowup of Bind() templates to handle each combination of regular
   1.359 +// types and movable-but-not-copyable types.  Thus we introduce a wrapper type
   1.360 +// that is copyable to transmit the correct type information down into
   1.361 +// BindState<>. Ignoring const in this type makes sense because it is only
   1.362 +// created when we are explicitly trying to do a destructive move.
   1.363 +//
   1.364 +// Two notes:
   1.365 +//  1) PassedWrapper supports any type that has a "Pass()" function.
   1.366 +//     This is intentional. The whitelisting of which specific types we
   1.367 +//     support is maintained by CallbackParamTraits<>.
   1.368 +//  2) is_valid_ is distinct from NULL because it is valid to bind a "NULL"
   1.369 +//     scoper to a Callback and allow the Callback to execute once.
   1.370 +template <typename T>
   1.371 +class PassedWrapper {
   1.372 + public:
   1.373 +  explicit PassedWrapper(T scoper) : is_valid_(true), scoper_(scoper.Pass()) {}
   1.374 +  PassedWrapper(const PassedWrapper& other)
   1.375 +      : is_valid_(other.is_valid_), scoper_(other.scoper_.Pass()) {
   1.376 +  }
   1.377 +  T Pass() const {
   1.378 +    CHECK(is_valid_);
   1.379 +    is_valid_ = false;
   1.380 +    return scoper_.Pass();
   1.381 +  }
   1.382 +
   1.383 + private:
   1.384 +  mutable bool is_valid_;
   1.385 +  mutable T scoper_;
   1.386 +};
   1.387 +
   1.388 +// Unwrap the stored parameters for the wrappers above.
   1.389 +template <typename T>
   1.390 +struct UnwrapTraits {
   1.391 +  typedef const T& ForwardType;
   1.392 +  static ForwardType Unwrap(const T& o) { return o; }
   1.393 +};
   1.394 +
   1.395 +template <typename T>
   1.396 +struct UnwrapTraits<UnretainedWrapper<T> > {
   1.397 +  typedef T* ForwardType;
   1.398 +  static ForwardType Unwrap(UnretainedWrapper<T> unretained) {
   1.399 +    return unretained.get();
   1.400 +  }
   1.401 +};
   1.402 +
   1.403 +template <typename T>
   1.404 +struct UnwrapTraits<ConstRefWrapper<T> > {
   1.405 +  typedef const T& ForwardType;
   1.406 +  static ForwardType Unwrap(ConstRefWrapper<T> const_ref) {
   1.407 +    return const_ref.get();
   1.408 +  }
   1.409 +};
   1.410 +
   1.411 +template <typename T>
   1.412 +struct UnwrapTraits<scoped_refptr<T> > {
   1.413 +  typedef T* ForwardType;
   1.414 +  static ForwardType Unwrap(const scoped_refptr<T>& o) { return o.get(); }
   1.415 +};
   1.416 +
   1.417 +template <typename T>
   1.418 +struct UnwrapTraits<WeakPtr<T> > {
   1.419 +  typedef const WeakPtr<T>& ForwardType;
   1.420 +  static ForwardType Unwrap(const WeakPtr<T>& o) { return o; }
   1.421 +};
   1.422 +
   1.423 +template <typename T>
   1.424 +struct UnwrapTraits<OwnedWrapper<T> > {
   1.425 +  typedef T* ForwardType;
   1.426 +  static ForwardType Unwrap(const OwnedWrapper<T>& o) {
   1.427 +    return o.get();
   1.428 +  }
   1.429 +};
   1.430 +
   1.431 +template <typename T>
   1.432 +struct UnwrapTraits<PassedWrapper<T> > {
   1.433 +  typedef T ForwardType;
   1.434 +  static T Unwrap(PassedWrapper<T>& o) {
   1.435 +    return o.Pass();
   1.436 +  }
   1.437 +};
   1.438 +
   1.439 +// Utility for handling different refcounting semantics in the Bind()
   1.440 +// function.
   1.441 +template <bool is_method, typename T>
   1.442 +struct MaybeRefcount;
   1.443 +
   1.444 +template <typename T>
   1.445 +struct MaybeRefcount<false, T> {
   1.446 +  static void AddRef(const T&) {}
   1.447 +  static void Release(const T&) {}
   1.448 +};
   1.449 +
   1.450 +template <typename T, size_t n>
   1.451 +struct MaybeRefcount<false, T[n]> {
   1.452 +  static void AddRef(const T*) {}
   1.453 +  static void Release(const T*) {}
   1.454 +};
   1.455 +
   1.456 +template <typename T>
   1.457 +struct MaybeRefcount<true, T> {
   1.458 +  static void AddRef(const T&) {}
   1.459 +  static void Release(const T&) {}
   1.460 +};
   1.461 +
   1.462 +template <typename T>
   1.463 +struct MaybeRefcount<true, T*> {
   1.464 +  static void AddRef(T* o) { o->AddRef(); }
   1.465 +  static void Release(T* o) { o->Release(); }
   1.466 +};
   1.467 +
   1.468 +// No need to additionally AddRef() and Release() since we are storing a
   1.469 +// scoped_refptr<> inside the storage object already.
   1.470 +template <typename T>
   1.471 +struct MaybeRefcount<true, scoped_refptr<T> > {
   1.472 +  static void AddRef(const scoped_refptr<T>& o) {}
   1.473 +  static void Release(const scoped_refptr<T>& o) {}
   1.474 +};
   1.475 +
   1.476 +template <typename T>
   1.477 +struct MaybeRefcount<true, const T*> {
   1.478 +  static void AddRef(const T* o) { o->AddRef(); }
   1.479 +  static void Release(const T* o) { o->Release(); }
   1.480 +};
   1.481 +
   1.482 +// IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a
   1.483 +// method.  It is used internally by Bind() to select the correct
   1.484 +// InvokeHelper that will no-op itself in the event the WeakPtr<> for
   1.485 +// the target object is invalidated.
   1.486 +//
   1.487 +// P1 should be the type of the object that will be received of the method.
   1.488 +template <bool IsMethod, typename P1>
   1.489 +struct IsWeakMethod : public false_type {};
   1.490 +
   1.491 +template <typename T>
   1.492 +struct IsWeakMethod<true, WeakPtr<T> > : public true_type {};
   1.493 +
   1.494 +template <typename T>
   1.495 +struct IsWeakMethod<true, ConstRefWrapper<WeakPtr<T> > > : public true_type {};
   1.496 +
   1.497 +}  // namespace internal
   1.498 +
   1.499 +template <typename T>
   1.500 +static inline internal::UnretainedWrapper<T> Unretained(T* o) {
   1.501 +  return internal::UnretainedWrapper<T>(o);
   1.502 +}
   1.503 +
   1.504 +template <typename T>
   1.505 +static inline internal::ConstRefWrapper<T> ConstRef(const T& o) {
   1.506 +  return internal::ConstRefWrapper<T>(o);
   1.507 +}
   1.508 +
   1.509 +template <typename T>
   1.510 +static inline internal::OwnedWrapper<T> Owned(T* o) {
   1.511 +  return internal::OwnedWrapper<T>(o);
   1.512 +}
   1.513 +
   1.514 +// We offer 2 syntaxes for calling Passed().  The first takes a temporary and
   1.515 +// is best suited for use with the return value of a function. The second
   1.516 +// takes a pointer to the scoper and is just syntactic sugar to avoid having
   1.517 +// to write Passed(scoper.Pass()).
   1.518 +template <typename T>
   1.519 +static inline internal::PassedWrapper<T> Passed(T scoper) {
   1.520 +  return internal::PassedWrapper<T>(scoper.Pass());
   1.521 +}
   1.522 +template <typename T>
   1.523 +static inline internal::PassedWrapper<T> Passed(T* scoper) {
   1.524 +  return internal::PassedWrapper<T>(scoper->Pass());
   1.525 +}
   1.526 +
   1.527 +template <typename T>
   1.528 +static inline internal::IgnoreResultHelper<T> IgnoreResult(T data) {
   1.529 +  return internal::IgnoreResultHelper<T>(data);
   1.530 +}
   1.531 +
   1.532 +template <typename T>
   1.533 +static inline internal::IgnoreResultHelper<Callback<T> >
   1.534 +IgnoreResult(const Callback<T>& data) {
   1.535 +  return internal::IgnoreResultHelper<Callback<T> >(data);
   1.536 +}
   1.537 +
   1.538 +BASE_EXPORT void DoNothing();
   1.539 +
   1.540 +template<typename T>
   1.541 +void DeletePointer(T* obj) {
   1.542 +  delete obj;
   1.543 +}
   1.544 +
   1.545 +}  // namespace base
   1.546 +
   1.547 +#endif  // BASE_BIND_HELPERS_H_

mercurial