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

Side by Side Diff: base/prebind.h.pump

Issue 6109007: Unified callback system. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/base
Patch Set: pumped up 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 $$ This is a pump file for generating file templates. Pump is a python
2 $$ script that is part of the Google Test suite of utilities. Description
3 $$ can be found here:
4 $$
5 $$ http://code.google.com/p/googletest/wiki/PumpManual
6 $$
7 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
8 // Use of this source code is governed by a BSD-style license that can be
9 // found in the LICENSE file.
10
11 #ifndef BASE_PREBIND_H_
12 #define BASE_PREBIND_H_
13
14 #include "base/uber_callback.h"
15
16 namespace base {
17
18 namespace internal {
19 // These classes are argument wrappers that affect the refcounting, and storage
20 // semantics for prebound arguments.
21
22 template <typename T>
23 class UnretainedWrapper {
24 public:
25 explicit UnretainedWrapper(T* o) : obj_(o) {}
26 T* get() { return obj_; }
27 private:
28 T* obj_;
29 };
30
31 template <typename T>
32 class ConstRefWrapper {
33 public:
34 explicit ConstRefWrapper(const T& o) : ptr_(&o) {}
35 const T* get() { return ptr_; }
36 private:
37 const T* ptr_;
38 };
39
40 // Unwrap for the wrappers above.
41 template <typename T>
42 T Unwrap(T o) { return o; }
43
44 template <typename T>
45 T* Unwrap(UnretainedWrapper<T> unretained) { return unretained.get(); }
46
47 template <typename T>
48 const T* Unwrap(ConstRefWrapper<T> const_ref) { return const_ref.get(); }
49
50 // Optional Refcounting.
51
52 template <bool ref, typename O>
53 struct MaybeRefcount;
54
55 template <typename O>
56 struct MaybeRefcount<false, O> {
57 static void AddRef(const O&) {}
58 static void Release(const O&) {}
59 };
60
61 template <typename O>
62 struct MaybeRefcount<true, UnretainedWrapper<O> > {
63 static void AddRef(const UnretainedWrapper<O>&) {}
64 static void Release(const UnretainedWrapper<O>&) {}
65 };
66
67 template <typename O>
68 struct MaybeRefcount<true, ConstRefWrapper<O> > {
69 static void AddRef(ConstRefWrapper<O> o) { o.get()->AddRef(); }
70 static void Release(ConstRefWrapper<O> o) { o.get()->Release(); }
71 };
72
73 template <typename O>
74 struct MaybeRefcount<true, O* > {
75 static void AddRef(O* o) { o->AddRef(); }
76 static void Release(O* o) { o->Release(); }
77 };
78
79 // The method by which a function is invoked is determined by 3 different
80 // dimensions:
81 //
82 // 1) The type of function (normal, method, const-method)
83 // 2) The arity of the function
84 // 3) The number of bound parameters.
85 //
86 // The FunctionTraitsN classes unwrap the function signature type to
87 // specialize based on the first two dimensions. The N in FunctionTraitsN
88 // specifies the 3rd dimension.
89
90 $var MAX_ARITY = 6
91
92 $range PREBOUND 1..MAX_ARITY
93 $for PREBOUND [[
94
95 template <typename StorageType, typename Sig>
96 struct FunctionTraits$(PREBOUND);
97
98 $range ARITY 1..MAX_ARITY
99 $for ARITY [[
100
101 $var UNBOUND = ARITY - PREBOUND
102 $if UNBOUND >= 0 [[
103
104 $$ Variables for function traits generation.
105 $range ARG 1..ARITY
106 $range BOUND_ARG 1..PREBOUND
107 $range UNBOUND_ARG (ARITY - UNBOUND + 1)..ARITY
108
109 $$ Variables for method traits generation. We are always short one arity since
110 $$ the first bound parameter is the object.
111 $var M_ARITY = ARITY - 1
112 $range M_ARG 1..M_ARITY
113 $range M_BOUND_ARG 2..PREBOUND
114 $range M_UNBOUND_ARG (M_ARITY - UNBOUND + 1)..M_ARITY
115
116 // Function: Arity $(ARITY) -> $(UNBOUND).
117 template <typename StorageType, typename R, $for ARG , [[typename X$(ARG)]]>
118 struct FunctionTraits$(PREBOUND)<StorageType, R(*)($for ARG , [[X$(ARG)]])> {
119 static const bool kShouldRef = false;
120 static R DoInvoke(InvokerStorageBase* base[[]]
121 $if UNBOUND != 0 [[, ]] $for UNBOUND_ARG , [[X$(UNBOUND_ARG) x$(UNBOUND_ARG)]]) {
122 StorageType* invoker = static_cast<StorageType*>(base);
123 return invoker->f_($for BOUND_ARG , [[Unwrap(invoker->p$(BOUND_ARG)_)]][[]]
124 $if UNBOUND > 0 [[, ]] $for UNBOUND_ARG , [[x$(UNBOUND_ARG)]]);
125 }
126 };
127
128 // Method: Arity $(M_ARITY) -> $(UNBOUND).
129 template <typename StorageType, typename R, typename T[[]]
130 $if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]>
131 struct FunctionTraits$(PREBOUND)<StorageType, R(T::*)($for M_ARG , [[X$(M_ARG)]] )> {
132 static const bool kShouldRef = true;
133 static R DoInvoke(InvokerStorageBase* base[[]]
134 $if UNBOUND > 0 [[, ]] $for M_UNBOUND_ARG , [[X$(M_UNBOUND_ARG) x$(M_UNBOUND_ARG )]]) {
135 StorageType* invoker = static_cast<StorageType*>(base);
136 return (Unwrap(invoker->p1_)->*invoker->f_)([[]]
137 $for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]]
138 $if UNBOUND > 0 [[$if PREBOUND > 1 [[, ]]]][[]]
139 $for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]);
140 }
141 };
142
143 // Const Method: Arity $(M_ARITY) -> $(UNBOUND).
144 template <typename StorageType, typename R, typename T[[]]
145 $if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]>
146 struct FunctionTraits$(PREBOUND)<StorageType, R(T::*)($for M_ARG , [[X$(M_ARG)]] ) const> {
147 static const bool kShouldRef = true;
148 static R DoInvoke(InvokerStorageBase* base[[]]
149 $if UNBOUND > 0 [[, ]] $for M_UNBOUND_ARG , [[X$(M_UNBOUND_ARG) x$(M_UNBOUND_ARG )]]) {
150 StorageType* invoker = static_cast<StorageType*>(base);
151 return (Unwrap(invoker->p1_)->*invoker->f_)([[]]
152 $for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]]
153 $if UNBOUND > 0 [[$if PREBOUND > 1 [[, ]]]][[]]
154 $for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]);
155 }
156 };
157
158 ]] $$ if UNBOUND
159 ]] $$ for ARITY
160 ]] $$ for PREBOUND
161
162
163 // These are the actual storage classes for the invokers.
164
165 $for PREBOUND [[
166 $range BOUND_ARG 1..PREBOUND
167
168 template <typename Sig, $for BOUND_ARG , [[typename P$(BOUND_ARG)]]>
169 class InvokerStorage$(PREBOUND) : public InvokerStorageBase {
170 public:
171 typedef InvokerStorage$(PREBOUND) StorageType;
172 typedef FunctionTraits$(PREBOUND)<StorageType, Sig> FunctionTraits;
173
174 InvokerStorage$(PREBOUND)(Sig f, [[]]
175 $for BOUND_ARG , [[const P$(BOUND_ARG)& p$(BOUND_ARG)]])
176 : f_(f), $for BOUND_ARG , [[p$(BOUND_ARG)_(p$(BOUND_ARG))]] {
177 MaybeRefcount<FunctionTraits::kShouldRef, P1>::AddRef(p1_);
178 }
179
180 virtual ~InvokerStorage$(PREBOUND)() {
181 MaybeRefcount<FunctionTraits::kShouldRef, P1>::Release(p1_);
182 }
183
184 Sig f_;
185
186 $for BOUND_ARG [[
187 P$(BOUND_ARG) p$(BOUND_ARG)_;
188
189 ]]
190 };
191
192 ]] $$ for PREBOUND
193
194 } // namespace internal
195
196
197 $for PREBOUND [[
198 $range BOUND_ARG 1..PREBOUND
199
200 template <typename Sig, $for BOUND_ARG , [[typename P$(BOUND_ARG)]]>
201 InvokerStorageHolder<internal::InvokerStorage$(PREBOUND)<Sig, [[]]
202 $for BOUND_ARG , [[P$(BOUND_ARG)]]> >
203 Prebind(Sig f, $for BOUND_ARG , [[const P$(BOUND_ARG)& p$(BOUND_ARG)]]) {
204 return MakeInvokerStorageHolder(
205 new internal::InvokerStorage$(PREBOUND)<Sig, [[]]
206 $for BOUND_ARG , [[P$(BOUND_ARG)]]>(
207 f, [[]] $for BOUND_ARG , [[p$(BOUND_ARG)]]));
208 }
209
210 ]] $$ for PREBOUND
211
212 template <typename T>
213 inline internal::UnretainedWrapper<T> Unretained(T* o) {
214 return internal::UnretainedWrapper<T>(o);
215 }
216
217 template <typename T>
218 inline internal::ConstRefWrapper<T> ConstRef(const T& o) {
219 return internal::ConstRefWrapper<T>(o);
220 }
221
222
223 } // namespace base
224
225 #endif // BASE_PREBIND_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698