GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
action-container.h
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1993-2018 John W. Eaton
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
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License 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 <https://www.gnu.org/licenses/>.
21 
22 */
23 
24 #if ! defined (octave_action_container_h)
25 #define octave_action_container_h 1
26 
27 #include "octave-config.h"
28 
29 #include <cstddef>
30 
31 // This class allows registering actions in a list for later
32 // execution, either explicitly or when the container goes out of
33 // scope.
34 
35 // FIXME: is there a better name for this class?
36 
37 // FIXME: we should probably be using std::function, std::bind, and
38 // related c++11 features to implement this functionality.
39 
40 namespace octave
41 {
42  class
44  {
45  public:
46 
47  // A generic unwind_protect element. Knows how to run itself and
48  // discard itself. Also, contains a pointer to the next element.
49  class elem
50  {
51  public:
52 
53  friend class action_container;
54 
55  elem (void) { }
56 
57  // No copying!
58 
59  elem (const elem&) = delete;
60 
61  elem& operator = (const elem&) = delete;
62 
63  virtual ~elem (void) = default;
64 
65  virtual void run (void) { }
66  };
67 
68  // An element that merely runs a void (*)(void) function.
69 
70  class fcn_elem : public elem
71  {
72  public:
73 
74  fcn_elem (void (*fptr) (void))
75  : e_fptr (fptr) { }
76 
77  void run (void) { e_fptr (); }
78 
79  private:
80 
81  void (*e_fptr) (void);
82  };
83 
84  // An element that stores a variable of type T along with a void (*) (T)
85  // function pointer, and calls the function with the parameter.
86 
87  template <typename T>
88  class fcn_arg_elem : public elem
89  {
90  public:
91 
92  fcn_arg_elem (void (*fcn) (T), T arg)
93  : e_fcn (fcn), e_arg (arg) { }
94 
95  // No copying!
96 
97  fcn_arg_elem (const fcn_arg_elem&) = delete;
98 
99  fcn_arg_elem& operator = (const fcn_arg_elem&) = delete;
100 
101  void run (void) { e_fcn (e_arg); }
102 
103  private:
104 
105  void (*e_fcn) (T);
106 
107  T e_arg;
108  };
109 
110  // An element that stores a variable of type T along with a
111  // void (*) (const T&) function pointer, and calls the function with
112  // the parameter.
113 
114  template <typename T>
115  class fcn_crefarg_elem : public elem
116  {
117  public:
118 
119  fcn_crefarg_elem (void (*fcn) (const T&), const T& arg)
120  : e_fcn (fcn), e_arg (arg) { }
121 
122  void run (void) { e_fcn (e_arg); }
123 
124  private:
125 
126  void (*e_fcn) (const T&);
127 
128  T e_arg;
129  };
130 
131  // An element for calling a member function.
132 
133  template <typename T>
134  class method_elem : public elem
135  {
136  public:
137 
138  method_elem (T *obj, void (T::*method) (void))
139  : e_obj (obj), e_method (method) { }
140 
141  method_elem (T& obj, void (T::*method) (void))
142  : e_obj (&obj), e_method (method) { }
143 
144  // No copying!
145 
146  method_elem (const method_elem&) = delete;
147 
148  method_elem operator = (const method_elem&) = delete;
149 
150  void run (void) { (e_obj->*e_method) (); }
151 
152  private:
153 
154  T *e_obj;
155 
156  void (T::*e_method) (void);
157  };
158 
159  // An element for calling a member function with a single argument
160 
161  template <typename T, typename A>
162  class method_arg_elem : public elem
163  {
164  public:
165 
166  method_arg_elem (T *obj, void (T::*method) (A), A arg)
167  : e_obj (obj), e_method (method), e_arg (arg) { }
168 
169  method_arg_elem (T& obj, void (T::*method) (A), A arg)
170  : e_obj (&obj), e_method (method), e_arg (arg) { }
171 
172  // No copying!
173 
174  method_arg_elem (const method_arg_elem&) = delete;
175 
176  method_arg_elem operator = (const method_arg_elem&) = delete;
177 
178  void run (void) { (e_obj->*e_method) (e_arg); }
179 
180  private:
181 
182  T *e_obj;
183 
184  void (T::*e_method) (A);
185 
187  };
188 
189  // An element for calling a member function with a single argument
190 
191  template <typename T, typename A>
192  class method_crefarg_elem : public elem
193  {
194  public:
195 
196  method_crefarg_elem (T *obj, void (T::*method) (const A&), const A& arg)
197  : e_obj (obj), e_method (method), e_arg (arg) { }
198 
199  method_crefarg_elem (T& obj, void (T::*method) (const A&), const A& arg)
200  : e_obj (&obj), e_method (method), e_arg (arg) { }
201 
202  // No copying!
203 
204  method_crefarg_elem (const method_crefarg_elem&) = delete;
205 
206  method_crefarg_elem operator = (const method_crefarg_elem&) = delete;
207 
208  void run (void) { (e_obj->*e_method) (e_arg); }
209 
210  private:
211 
212  T *e_obj;
213 
214  void (T::*e_method) (const A&);
215 
217  };
218 
219  /// An element for calling a member function with two arguments
220  template <class T, class A, class B>
221  class method_arg2_elem : public elem
222  {
223  public:
224  method_arg2_elem (T *obj, void (T::*method) (const A&, const B&),
225  const A& arg_a, const B& arg_b)
226  : e_obj (obj), e_method (method),
227  e_arg_a (arg_a), e_arg_b (arg_b) { }
228 
229  void run (void) { (e_obj->*e_method) (e_arg_a, e_arg_b); }
230 
231  private:
232 
233  T *e_obj;
234  void (T::*e_method) (const A&, const B&);
237 
238  // No copying!
239 
241 
242  method_arg2_elem operator = (const method_arg2_elem&);
243  };
244 
245  /// An element for calling a member function with three arguments
246  template <class T, class A, class B, class C>
247  class method_arg3_elem : public elem
248  {
249  public:
251  void (T::*method) (const A&, const B&, const C&),
252  const A& arg_a, const B& arg_b, const C& arg_c)
253  : e_obj (obj), e_method (method),
254  e_arg_a (arg_a), e_arg_b (arg_b), e_arg_c (arg_c)
255  { }
256 
257  void run (void) { (e_obj->*e_method) (e_arg_a, e_arg_b, e_arg_c); }
258 
259  private:
260 
261  T *e_obj;
262  void (T::*e_method) (const A&, const B&, const C&);
266 
267  // No copying!
268 
270 
271  method_arg3_elem operator = (const method_arg3_elem&);
272  };
273 
274  /// An element for calling a member function with three arguments
275  template <class T, class A, class B, class C, class D>
276  class method_arg4_elem : public elem
277  {
278  public:
280  void (T::*method) (const A&, const B&, const C&, const D&),
281  const A& arg_a, const B& arg_b, const C& arg_c,
282  const D& arg_d)
283  : e_obj (obj), e_method (method),
284  e_arg_a (arg_a), e_arg_b (arg_b), e_arg_c (arg_c), e_arg_d (arg_d)
285  { }
286 
287  void run (void)
288  {
289  (e_obj->*e_method) (e_arg_a, e_arg_b, e_arg_c, e_arg_d);
290  }
291 
292  private:
293 
294  T *e_obj;
295  void (T::*e_method) (const A&, const B&, const C&, const D&);
300 
301  // No copying!
302 
304 
305  method_arg4_elem operator = (const method_arg4_elem&);
306  };
307 
308  // An element that stores arbitrary variable, and restores it.
309 
310  template <typename T>
311  class restore_var_elem : public elem
312  {
313  public:
314 
315  restore_var_elem (T& ref, const T& val)
316  : e_ptr (&ref), e_val (val) { }
317 
318  // No copying!
319 
320  restore_var_elem (const restore_var_elem&) = delete;
321 
322  restore_var_elem& operator = (const restore_var_elem&) = delete;
323 
324  void run (void) { *e_ptr = e_val; }
325 
326  private:
327 
328  T *e_ptr, e_val;
329  };
330 
331  // Deletes a class allocated using new.
332 
333  template <typename T>
334  class delete_ptr_elem : public elem
335  {
336  public:
337 
339  : e_ptr (ptr) { }
340 
341  // No copying!
342 
343  delete_ptr_elem (const delete_ptr_elem&) = delete;
344 
345  delete_ptr_elem operator = (const delete_ptr_elem&) = delete;
346 
347  void run (void) { delete e_ptr; }
348 
349  private:
350 
351  T *e_ptr;
352  };
353 
354  action_container (void) { }
355 
356  // No copying!
357 
358  action_container (const action_container&) = delete;
359 
360  action_container& operator = (const action_container&) = delete;
361 
362  virtual ~action_container (void) = default;
363 
364  virtual void add (elem *new_elem) = 0;
365 
366  // Call to void func (void).
367  void add_fcn (void (*fcn) (void))
368  {
369  add (new fcn_elem (fcn));
370  }
371 
372  // Call to void func (T).
373  template <typename T>
374  void add_fcn (void (*action) (T), T val)
375  {
376  add (new fcn_arg_elem<T> (action, val));
377  }
378 
379  // Call to void func (const T&).
380  template <typename T>
381  void add_fcn (void (*action) (const T&), const T& val)
382  {
383  add (new fcn_crefarg_elem<T> (action, val));
384  }
385 
386  // Call to T::method (void).
387  template <typename T>
388  void add_method (T *obj, void (T::*method) (void))
389  {
390  add (new method_elem<T> (obj, method));
391  }
392 
393  template <typename T>
394  void add_method (T& obj, void (T::*method) (void))
395  {
396  add (new method_elem<T> (obj, method));
397  }
398 
399  // Call to T::method (A).
400  template <typename T, typename A>
401  void add_method (T *obj, void (T::*method) (A), A arg)
402  {
403  add (new method_arg_elem<T, A> (obj, method, arg));
404  }
405 
406  template <typename T, typename A>
407  void add_method (T& obj, void (T::*method) (A), A arg)
408  {
409  add (new method_arg_elem<T, A> (obj, method, arg));
410  }
411 
412  // Call to T::method (const A&).
413  template <typename T, typename A>
414  void add_method (T *obj, void (T::*method) (const A&), const A& arg)
415  {
416  add (new method_crefarg_elem<T, A> (obj, method, arg));
417  }
418 
419  template <typename T, typename A>
420  void add_method (T& obj, void (T::*method) (const A&), const A& arg)
421  {
422  add (new method_crefarg_elem<T, A> (obj, method, arg));
423  }
424 
425  // Call to T::method (A, B).
426  template <class T, class A, class B>
427  void add_method (T *obj, void (T::*method) (const A&, const B&),
428  const A& arg_a, const B& arg_b)
429  {
430  add (new method_arg2_elem<T, A, B> (obj, method, arg_a, arg_b));
431  }
432 
433  // Call to T::method (A, B, C).
434  template <class T, class A, class B, class C>
435  void add_method (T *obj,
436  void (T::*method) (const A&, const B&, const C&),
437  const A& arg_a, const B& arg_b, const C& arg_c)
438  {
439  add (new method_arg3_elem<T, A, B, C> (obj, method, arg_a,
440  arg_b, arg_c));
441  }
442 
443  // Call to T::method (A, B, C, D).
444  template <class T, class A, class B, class C, class D>
445  void add_method (T *obj,
446  void (T::*method) (const A&, const B&, const C&, const D&),
447  const A& arg_a, const B& arg_b,
448  const C& arg_c, const D& arg_d)
449  {
451  arg_b, arg_c, arg_d));
452  }
453 
454  // Call to delete (T*).
455 
456  template <typename T>
457  void add_delete (T *obj)
458  {
459  add (new delete_ptr_elem<T> (obj));
460  }
461 
462  // Protect any variable.
463  template <typename T>
464  void protect_var (T& var)
465  {
466  add (new restore_var_elem<T> (var, var));
467  }
468 
469  // Protect any variable, value given.
470  template <typename T>
471  void protect_var (T& var, const T& val)
472  {
473  add (new restore_var_elem<T> (var, val));
474  }
475 
476  operator bool (void) const { return ! empty (); }
477 
478  virtual void run_first (void) = 0;
479 
480  void run (size_t num)
481  {
482  if (num > size ())
483  num = size ();
484 
485  for (size_t i = 0; i < num; i++)
486  run_first ();
487  }
488 
489  void run (void) { run (size ()); }
490 
491  virtual void discard_first (void) = 0;
492 
493  void discard (size_t num)
494  {
495  if (num > size ())
496  num = size ();
497 
498  for (size_t i = 0; i < num; i++)
499  discard_first ();
500  }
501 
502  void discard (void) { discard (size ()); }
503 
504  virtual size_t size (void) const = 0;
505 
506  bool empty (void) const { return size () == 0; }
507  };
508 }
509 
510 #if defined (OCTAVE_USE_DEPRECATED_FUNCTIONS)
511 
512 OCTAVE_DEPRECATED (4.4, "use 'octave::action_container' instead")
513 typedef octave::action_container action_container;
514 
515 #endif
516 
517 #endif
octave_value arg_c
Definition: sylvester.cc:71
void add_method(T &obj, void(T::*method)(const A &), const A &arg)
F77_RET_T const F77_INT F77_CMPLX const F77_INT F77_CMPLX * B
#define C(a, b)
Definition: Faddeeva.cc:246
void add_fcn(void(*action)(T), T val)
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:4986
method_elem(T &obj, void(T::*method)(void))
void add_method(T *obj, void(T::*method)(const A &, const B &), const A &arg_a, const B &arg_b)
method_arg3_elem(T *obj, void(T::*method)(const A &, const B &, const C &), const A &arg_a, const B &arg_b, const C &arg_c)
void add_fcn(void(*fcn)(void))
method_arg2_elem(T *obj, void(T::*method)(const A &, const B &), const A &arg_a, const B &arg_b)
void protect_var(T &var, const T &val)
var
Definition: givens.cc:88
octave_value arg
Definition: pr-output.cc:3244
octave_function * fcn
Definition: ov-class.cc:1754
octave_value arg_b
Definition: sylvester.cc:70
method_arg4_elem(T *obj, void(T::*method)(const A &, const B &, const C &, const D &), const A &arg_a, const B &arg_b, const C &arg_c, const D &arg_d)
fcn_crefarg_elem(void(*fcn)(const T &), const T &arg)
void add_method(T *obj, void(T::*method)(const A &), const A &arg)
create a structure array and initialize its values The dimensions of each cell array of values must match Singleton cells and non cell values are repeated so that they fill the entire array If the cells are empty
Definition: ov-struct.cc:1736
void add_method(T &obj, void(T::*method)(A), A arg)
void add_method(T *obj, void(T::*method)(const A &, const B &, const C &, const D &), const A &arg_a, const B &arg_b, const C &arg_c, const D &arg_d)
F77_RET_T const F77_INT F77_CMPLX * A
void add_method(T *obj, void(T::*method)(const A &, const B &, const C &), const A &arg_a, const B &arg_b, const C &arg_c)
An element for calling a member function with three arguments.
method_arg_elem(T *obj, void(T::*method)(A), A arg)
static int elem
Definition: __contourc__.cc:47
An element for calling a member function with three arguments.
void add_method(T *obj, void(T::*method)(A), A arg)
method_crefarg_elem(T *obj, void(T::*method)(const A &), const A &arg)
An element for calling a member function with two arguments.
octave_value arg_a
Definition: sylvester.cc:69
FloatComplex(* fptr)(const FloatComplex &, float, int, octave_idx_type &)
Definition: lo-specfun.cc:1129
std::string method
Definition: urlwrite.cc:123
void add_method(T *obj, void(T::*method)(void))
method_elem(T *obj, void(T::*method)(void))
for i
Definition: data.cc:5264
void add_fcn(void(*action)(const T &), const T &val)
method_crefarg_elem(T &obj, void(T::*method)(const A &), const A &arg)
method_arg_elem(T &obj, void(T::*method)(A), A arg)
void add_method(T &obj, void(T::*method)(void))