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

Side by Side 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, 10 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // This defines a set of argument wrappers, and related factory methods for
6 // changing the refcounting, and reference semantics of arguments that are bound
7 // by the Prebind() function in base/prebind.h.
8 //
9 // The public functions are base::Unretained() and base::ConstRef().
10 // Unretained() allows Prebind() to bind a non-refcounted class. ConstRef()
11 // allows binding a constant reference to an argument rather than a copy.
12 //
13 //
14 // EXAMPLE OF Unretained():
15 //
16 // class Foo {
17 // public:
18 // void func() { cout << "Foo:f" << endl;
19 // };
20 //
21 // // In some function somewhere.
22 // Foo foo;
23 // Callback<void(void)> foo_callback = Prebind(&Foo::func, Unretained(&foo));
24 // foo_callback.Run(); // Prints "Foo:f".
25 //
26 // Without the Unretained() wrapper on |&foo|, the above call would fail to
27 // compile because Foo does not support the AddRef() and Release() methods.
28 //
29 //
30 // EXAMPLE OF ConstRef();
31 // void foo(int arg) { cout << arg << endl }
32 //
33 // int n = 1;
34 // Callback<void(void)> no_ref = Prebind(&foo, n);
35 // Callback<void(void)> has_ref = Prebind(&foo, ConstRef(n));
36 //
37 // no_ref.Run(); // Prints "1"
38 // has_ref.Run(); // Prints "1"
39 //
40 // n = 2;
41 // no_ref.Run(); // Prints "1"
42 // has_ref.Run(); // Prints "2"
43 //
44 // Note that because ConstRef() takes a reference on |n|, |n| must outlive all
45 // its bound callbacks.
46 //
47
48 #ifndef BASE_PREBIND_HELPERS_H_
49 #define BASE_PREBIND_HELPERS_H_
50 #pragma once
51
52 namespace base {
53
54 namespace internal {
55 template <typename T>
56 class UnretainedWrapper {
57 public:
58 explicit UnretainedWrapper(T* o) : obj_(o) {}
59 T* get() { return obj_; }
60 private:
61 T* obj_;
62 };
63
64 template <typename T>
65 class ConstRefWrapper {
66 public:
67 explicit ConstRefWrapper(const T& o) : ptr_(&o) {}
68 const T& get() { return *ptr_; }
69 private:
70 const T* ptr_;
71 };
72
73
74 // Unwrap the stored parameters for the wrappers above.
75 template <typename T>
76 T Unwrap(T o) { return o; }
77
78 template <typename T>
79 T* Unwrap(UnretainedWrapper<T> unretained) { return unretained.get(); }
80
81 template <typename T>
82 const T& Unwrap(ConstRefWrapper<T> const_ref) { return const_ref.get(); }
83
84
85 // Utility for handling different refcounting semantics in the Prebind()
86 // function.
87 template <bool ref, typename O>
88 struct MaybeRefcount;
89
90 template <typename O>
91 struct MaybeRefcount<false, O> {
92 static void AddRef(const O&) {}
93 static void Release(const O&) {}
94 };
95
96 template <typename O>
97 struct MaybeRefcount<true, UnretainedWrapper<O> > {
98 static void AddRef(const UnretainedWrapper<O>&) {}
99 static void Release(const UnretainedWrapper<O>&) {}
100 };
101
102 template <typename O>
103 struct MaybeRefcount<true, O* > {
104 static void AddRef(O* o) { o->AddRef(); }
105 static void Release(O* o) { o->Release(); }
106 };
107
108 template <typename O>
109 struct MaybeRefcount<true, const O* > {
110 static void AddRef(const O* o) { o->AddRef(); }
111 static void Release(const O* o) { o->Release(); }
112 };
113
114 } // namespace internal
115
116 template <typename T>
117 inline internal::UnretainedWrapper<T> Unretained(T* o) {
118 return internal::UnretainedWrapper<T>(o);
119 }
120
121 template <typename T>
122 inline internal::ConstRefWrapper<T> ConstRef(const T& o) {
123 return internal::ConstRefWrapper<T>(o);
124 }
125
126 } // namespace base
127
128 #endif // BASE_PREBIND_HELPERS_H_
OLDNEW
« 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