Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(452)

Unified Diff: base/prebind_helpers.h

Issue 6109007: Unified callback system. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/base
Patch Set: Fixing up some comments. Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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_
« no previous file with comments | « base/prebind.h.pump ('k') | base/prebind_unittest.cc » ('j') | base/uber_callback.h.pump » ('J')

Powered by Google App Engine
This is Rietveld 408576698