| Index: base/prebind_helpers.h
|
| diff --git a/base/prebind_helpers.h b/base/prebind_helpers.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c7f020af0a47693705810cfb5b6f924b94365932
|
| --- /dev/null
|
| +++ b/base/prebind_helpers.h
|
| @@ -0,0 +1,128 @@
|
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +// This defines a set of argument wrappers, and related factory methods for
|
| +// changing the refcounting, and reference semantics of arguments that are bound
|
| +// by the Prebind() function in base/prebind.h.
|
| +//
|
| +// The public functions are base::Unretained() and base::ConstRef().
|
| +// Unretained() allows Prebind() to bind a non-refcounted class. ConstRef()
|
| +// allows binding a constant reference to an argument rather than a copy.
|
| +//
|
| +//
|
| +// EXAMPLE OF Unretained():
|
| +//
|
| +// class Foo {
|
| +// public:
|
| +// void func() { cout << "Foo:f" << endl;
|
| +// };
|
| +//
|
| +// // In some function somewhere.
|
| +// Foo foo;
|
| +// Callback<void(void)> foo_callback = Prebind(&Foo::func, Unretained(&foo));
|
| +// foo_callback.Run(); // Prints "Foo:f".
|
| +//
|
| +// Without the Unretained() wrapper on |&foo|, the above call would fail to
|
| +// compile because Foo does not support the AddRef() and Release() methods.
|
| +//
|
| +//
|
| +// EXAMPLE OF ConstRef();
|
| +// void foo(int arg) { cout << arg << endl }
|
| +//
|
| +// int n = 1;
|
| +// Callback<void(void)> no_ref = Prebind(&foo, n);
|
| +// Callback<void(void)> has_ref = Prebind(&foo, ConstRef(n));
|
| +//
|
| +// no_ref.Run(); // Prints "1"
|
| +// has_ref.Run(); // Prints "1"
|
| +//
|
| +// n = 2;
|
| +// no_ref.Run(); // Prints "1"
|
| +// has_ref.Run(); // Prints "2"
|
| +//
|
| +// Note that because ConstRef() takes a reference on |n|, |n| must outlive all
|
| +// its bound callbacks.
|
| +//
|
| +
|
| +#ifndef BASE_PREBIND_HELPERS_H_
|
| +#define BASE_PREBIND_HELPERS_H_
|
| +#pragma once
|
| +
|
| +namespace base {
|
| +
|
| +namespace internal {
|
| +template <typename T>
|
| +class UnretainedWrapper {
|
| + public:
|
| + explicit UnretainedWrapper(T* o) : obj_(o) {}
|
| + T* get() { return obj_; }
|
| + private:
|
| + T* obj_;
|
| +};
|
| +
|
| +template <typename T>
|
| +class ConstRefWrapper {
|
| + public:
|
| + explicit ConstRefWrapper(const T& o) : ptr_(&o) {}
|
| + const T& get() { return *ptr_; }
|
| + private:
|
| + const T* ptr_;
|
| +};
|
| +
|
| +
|
| +// Unwrap the stored parameters for the wrappers above.
|
| +template <typename T>
|
| +T Unwrap(T o) { return o; }
|
| +
|
| +template <typename T>
|
| +T* Unwrap(UnretainedWrapper<T> unretained) { return unretained.get(); }
|
| +
|
| +template <typename T>
|
| +const T& Unwrap(ConstRefWrapper<T> const_ref) { return const_ref.get(); }
|
| +
|
| +
|
| +// Utility for handling different refcounting semantics in the Prebind()
|
| +// function.
|
| +template <bool ref, typename O>
|
| +struct MaybeRefcount;
|
| +
|
| +template <typename O>
|
| +struct MaybeRefcount<false, O> {
|
| + static void AddRef(const O&) {}
|
| + static void Release(const O&) {}
|
| +};
|
| +
|
| +template <typename O>
|
| +struct MaybeRefcount<true, UnretainedWrapper<O> > {
|
| + static void AddRef(const UnretainedWrapper<O>&) {}
|
| + static void Release(const UnretainedWrapper<O>&) {}
|
| +};
|
| +
|
| +template <typename O>
|
| +struct MaybeRefcount<true, O* > {
|
| + static void AddRef(O* o) { o->AddRef(); }
|
| + static void Release(O* o) { o->Release(); }
|
| +};
|
| +
|
| +template <typename O>
|
| +struct MaybeRefcount<true, const O* > {
|
| + static void AddRef(const O* o) { o->AddRef(); }
|
| + static void Release(const O* o) { o->Release(); }
|
| +};
|
| +
|
| +} // namespace internal
|
| +
|
| +template <typename T>
|
| +inline internal::UnretainedWrapper<T> Unretained(T* o) {
|
| + return internal::UnretainedWrapper<T>(o);
|
| +}
|
| +
|
| +template <typename T>
|
| +inline internal::ConstRefWrapper<T> ConstRef(const T& o) {
|
| + return internal::ConstRefWrapper<T>(o);
|
| +}
|
| +
|
| +} // namespace base
|
| +
|
| +#endif // BASE_PREBIND_HELPERS_H_
|
|
|