Mercurial > octave
annotate liboctave/util/action-container.h @ 23219:3ac9f9ecfae5 stable
maint: Update copyright dates.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 22 Feb 2017 12:39:29 -0500 |
parents | e9a0469dedd9 |
children | 092078913d54 |
rev | line source |
---|---|
15396 | 1 /* |
2 | |
23219
3ac9f9ecfae5
maint: Update copyright dates.
John W. Eaton <jwe@octave.org>
parents:
23083
diff
changeset
|
3 Copyright (C) 1993-2017 John W. Eaton |
15396 | 4 Copyright (C) 2009-2010 VZLU Prague |
5 | |
6 This file is part of Octave. | |
7 | |
8 Octave is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
10 Free Software Foundation; either version 3 of the License, or (at your | |
11 option) any later version. | |
12 | |
13 Octave is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with Octave; see the file COPYING. If not, see | |
20 <http://www.gnu.org/licenses/>. | |
21 | |
22 */ | |
23 | |
20791
f7084eae3318
maint: Use Octave coding conventions for #if statements.
Rik <rik@octave.org>
parents:
19697
diff
changeset
|
24 #if ! defined (octave_action_container_h) |
15396 | 25 #define octave_action_container_h 1 |
26 | |
21244
1473547f50f5
include octave-config.h in public header files
John W. Eaton <jwe@octave.org>
parents:
21139
diff
changeset
|
27 #include "octave-config.h" |
1473547f50f5
include octave-config.h in public header files
John W. Eaton <jwe@octave.org>
parents:
21139
diff
changeset
|
28 |
15396 | 29 // This class allows registering actions in a list for later |
30 // execution, either explicitly or when the container goes out of | |
31 // scope. | |
32 | |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
33 // FIXME: is there a better name for this class? |
15396 | 34 |
35 class | |
36 action_container | |
37 { | |
38 public: | |
39 | |
21751
b571fc85953f
maint: Use two spaces after period to indicate sentence break.
Rik <rik@octave.org>
parents:
21244
diff
changeset
|
40 // A generic unwind_protect element. Knows how to run itself and |
15396 | 41 // discard itself. Also, contains a pointer to the next element. |
42 class elem | |
43 { | |
44 public: | |
45 elem (void) { } | |
46 | |
47 virtual void run (void) { } | |
48 | |
49 virtual ~elem (void) { } | |
50 | |
51 friend class action_container; | |
52 | |
53 private: | |
54 | |
55 // No copying! | |
56 | |
57 elem (const elem&); | |
58 | |
59 elem& operator = (const elem&); | |
60 }; | |
61 | |
62 // An element that merely runs a void (*)(void) function. | |
63 | |
64 class fcn_elem : public elem | |
65 { | |
66 public: | |
67 fcn_elem (void (*fptr) (void)) | |
68 : e_fptr (fptr) { } | |
69 | |
70 void run (void) { e_fptr (); } | |
71 | |
72 private: | |
73 void (*e_fptr) (void); | |
74 }; | |
75 | |
76 // An element that stores a variable of type T along with a void (*) (T) | |
77 // function pointer, and calls the function with the parameter. | |
78 | |
21139
538b57866b90
consistently use "typename" intead of "class" in template declarations
John W. Eaton <jwe@octave.org>
parents:
20791
diff
changeset
|
79 template <typename T> |
15396 | 80 class fcn_arg_elem : public elem |
81 { | |
82 public: | |
83 fcn_arg_elem (void (*fcn) (T), T arg) | |
84 : e_fcn (fcn), e_arg (arg) { } | |
85 | |
86 void run (void) { e_fcn (e_arg); } | |
87 | |
88 private: | |
89 | |
90 // No copying! | |
91 | |
92 fcn_arg_elem (const fcn_arg_elem&); | |
93 | |
94 fcn_arg_elem& operator = (const fcn_arg_elem&); | |
95 | |
96 void (*e_fcn) (T); | |
97 T e_arg; | |
98 }; | |
99 | |
100 // An element that stores a variable of type T along with a | |
101 // void (*) (const T&) function pointer, and calls the function with | |
102 // the parameter. | |
103 | |
21139
538b57866b90
consistently use "typename" intead of "class" in template declarations
John W. Eaton <jwe@octave.org>
parents:
20791
diff
changeset
|
104 template <typename T> |
15396 | 105 class fcn_crefarg_elem : public elem |
106 { | |
107 public: | |
108 fcn_crefarg_elem (void (*fcn) (const T&), const T& arg) | |
109 : e_fcn (fcn), e_arg (arg) { } | |
110 | |
111 void run (void) { e_fcn (e_arg); } | |
112 | |
113 private: | |
114 void (*e_fcn) (const T&); | |
115 T e_arg; | |
116 }; | |
117 | |
118 // An element for calling a member function. | |
119 | |
21139
538b57866b90
consistently use "typename" intead of "class" in template declarations
John W. Eaton <jwe@octave.org>
parents:
20791
diff
changeset
|
120 template <typename T> |
15396 | 121 class method_elem : public elem |
122 { | |
123 public: | |
124 method_elem (T *obj, void (T::*method) (void)) | |
125 : e_obj (obj), e_method (method) { } | |
126 | |
127 void run (void) { (e_obj->*e_method) (); } | |
128 | |
129 private: | |
130 | |
131 T *e_obj; | |
132 void (T::*e_method) (void); | |
133 | |
134 // No copying! | |
135 | |
136 method_elem (const method_elem&); | |
137 | |
138 method_elem operator = (const method_elem&); | |
139 }; | |
140 | |
141 // An element for calling a member function with a single argument | |
142 | |
21139
538b57866b90
consistently use "typename" intead of "class" in template declarations
John W. Eaton <jwe@octave.org>
parents:
20791
diff
changeset
|
143 template <typename T, typename A> |
15396 | 144 class method_arg_elem : public elem |
145 { | |
146 public: | |
147 method_arg_elem (T *obj, void (T::*method) (A), A arg) | |
148 : e_obj (obj), e_method (method), e_arg (arg) { } | |
149 | |
150 void run (void) { (e_obj->*e_method) (e_arg); } | |
151 | |
152 private: | |
153 | |
154 T *e_obj; | |
155 void (T::*e_method) (A); | |
156 A e_arg; | |
157 | |
158 // No copying! | |
159 | |
160 method_arg_elem (const method_arg_elem&); | |
161 | |
162 method_arg_elem operator = (const method_arg_elem&); | |
163 }; | |
164 | |
165 // An element for calling a member function with a single argument | |
166 | |
21139
538b57866b90
consistently use "typename" intead of "class" in template declarations
John W. Eaton <jwe@octave.org>
parents:
20791
diff
changeset
|
167 template <typename T, typename A> |
15396 | 168 class method_crefarg_elem : public elem |
169 { | |
170 public: | |
171 method_crefarg_elem (T *obj, void (T::*method) (const A&), const A& arg) | |
172 : e_obj (obj), e_method (method), e_arg (arg) { } | |
173 | |
174 void run (void) { (e_obj->*e_method) (e_arg); } | |
175 | |
176 private: | |
177 | |
178 T *e_obj; | |
179 void (T::*e_method) (const A&); | |
180 A e_arg; | |
181 | |
182 // No copying! | |
183 | |
184 method_crefarg_elem (const method_crefarg_elem&); | |
185 | |
186 method_crefarg_elem operator = (const method_crefarg_elem&); | |
187 }; | |
188 | |
189 // An element that stores arbitrary variable, and restores it. | |
190 | |
21139
538b57866b90
consistently use "typename" intead of "class" in template declarations
John W. Eaton <jwe@octave.org>
parents:
20791
diff
changeset
|
191 template <typename T> |
15396 | 192 class restore_var_elem : public elem |
193 { | |
194 public: | |
195 restore_var_elem (T& ref, const T& val) | |
196 : e_ptr (&ref), e_val (val) { } | |
197 | |
198 void run (void) { *e_ptr = e_val; } | |
199 | |
200 private: | |
201 | |
202 // No copying! | |
203 | |
204 restore_var_elem (const restore_var_elem&); | |
205 | |
206 restore_var_elem& operator = (const restore_var_elem&); | |
207 | |
208 T *e_ptr, e_val; | |
209 }; | |
210 | |
211 // Deletes a class allocated using new. | |
212 | |
21139
538b57866b90
consistently use "typename" intead of "class" in template declarations
John W. Eaton <jwe@octave.org>
parents:
20791
diff
changeset
|
213 template <typename T> |
15396 | 214 class delete_ptr_elem : public elem |
215 { | |
216 public: | |
217 delete_ptr_elem (T *ptr) | |
218 : e_ptr (ptr) { } | |
219 | |
220 void run (void) { delete e_ptr; } | |
221 | |
222 private: | |
223 | |
224 T *e_ptr; | |
225 | |
226 // No copying! | |
227 | |
228 delete_ptr_elem (const delete_ptr_elem&); | |
229 | |
230 delete_ptr_elem operator = (const delete_ptr_elem&); | |
231 }; | |
232 | |
233 action_container (void) { } | |
234 | |
235 virtual ~action_container (void) { } | |
236 | |
237 virtual void add (elem *new_elem) = 0; | |
238 | |
239 // Call to void func (void). | |
240 void add_fcn (void (*fcn) (void)) | |
241 { | |
242 add (new fcn_elem (fcn)); | |
243 } | |
244 | |
245 // Call to void func (T). | |
21139
538b57866b90
consistently use "typename" intead of "class" in template declarations
John W. Eaton <jwe@octave.org>
parents:
20791
diff
changeset
|
246 template <typename T> |
15396 | 247 void add_fcn (void (*action) (T), T val) |
248 { | |
249 add (new fcn_arg_elem<T> (action, val)); | |
250 } | |
251 | |
252 // Call to void func (const T&). | |
21139
538b57866b90
consistently use "typename" intead of "class" in template declarations
John W. Eaton <jwe@octave.org>
parents:
20791
diff
changeset
|
253 template <typename T> |
15396 | 254 void add_fcn (void (*action) (const T&), const T& val) |
255 { | |
256 add (new fcn_crefarg_elem<T> (action, val)); | |
257 } | |
258 | |
259 // Call to T::method (void). | |
21139
538b57866b90
consistently use "typename" intead of "class" in template declarations
John W. Eaton <jwe@octave.org>
parents:
20791
diff
changeset
|
260 template <typename T> |
15396 | 261 void add_method (T *obj, void (T::*method) (void)) |
262 { | |
263 add (new method_elem<T> (obj, method)); | |
264 } | |
265 | |
266 // Call to T::method (A). | |
21139
538b57866b90
consistently use "typename" intead of "class" in template declarations
John W. Eaton <jwe@octave.org>
parents:
20791
diff
changeset
|
267 template <typename T, typename A> |
15396 | 268 void add_method (T *obj, void (T::*method) (A), A arg) |
269 { | |
270 add (new method_arg_elem<T, A> (obj, method, arg)); | |
271 } | |
272 | |
273 // Call to T::method (const A&). | |
21139
538b57866b90
consistently use "typename" intead of "class" in template declarations
John W. Eaton <jwe@octave.org>
parents:
20791
diff
changeset
|
274 template <typename T, typename A> |
15396 | 275 void add_method (T *obj, void (T::*method) (const A&), const A& arg) |
276 { | |
277 add (new method_crefarg_elem<T, A> (obj, method, arg)); | |
278 } | |
279 | |
280 // Call to delete (T*). | |
281 | |
21139
538b57866b90
consistently use "typename" intead of "class" in template declarations
John W. Eaton <jwe@octave.org>
parents:
20791
diff
changeset
|
282 template <typename T> |
15396 | 283 void add_delete (T *obj) |
284 { | |
285 add (new delete_ptr_elem<T> (obj)); | |
286 } | |
287 | |
288 // Protect any variable. | |
21139
538b57866b90
consistently use "typename" intead of "class" in template declarations
John W. Eaton <jwe@octave.org>
parents:
20791
diff
changeset
|
289 template <typename T> |
15396 | 290 void protect_var (T& var) |
291 { | |
292 add (new restore_var_elem<T> (var, var)); | |
293 } | |
294 | |
295 // Protect any variable, value given. | |
21139
538b57866b90
consistently use "typename" intead of "class" in template declarations
John W. Eaton <jwe@octave.org>
parents:
20791
diff
changeset
|
296 template <typename T> |
15396 | 297 void protect_var (T& var, const T& val) |
298 { | |
299 add (new restore_var_elem<T> (var, val)); | |
300 } | |
301 | |
302 operator bool (void) const { return ! empty (); } | |
303 | |
304 virtual void run_first (void) = 0; | |
305 | |
306 void run (size_t num) | |
307 { | |
308 if (num > size ()) | |
309 num = size (); | |
310 | |
311 for (size_t i = 0; i < num; i++) | |
312 run_first (); | |
313 } | |
314 | |
315 void run (void) { run (size ()); } | |
316 | |
317 virtual void discard_first (void) = 0; | |
318 | |
319 void discard (size_t num) | |
320 { | |
321 if (num > size ()) | |
322 num = size (); | |
323 | |
324 for (size_t i = 0; i < num; i++) | |
325 discard_first (); | |
326 } | |
327 | |
328 void discard (void) { discard (size ()); } | |
329 | |
330 virtual size_t size (void) const = 0; | |
331 | |
332 bool empty (void) const { return size () == 0; } | |
333 | |
334 private: | |
335 | |
336 // No copying! | |
337 | |
338 action_container (const action_container&); | |
339 | |
340 action_container& operator = (const action_container&); | |
341 }; | |
342 | |
343 #endif |