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_ |