GNU Octave  8.1.0
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-2023 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if ! defined (octave_action_container_h)
27 #define octave_action_container_h 1
28 
29 #include "octave-config.h"
30 
31 #include <cstddef>
32 #include <functional>
33 
34 // This class allows registering actions in a list for later
35 // execution, either explicitly or when the container goes out of
36 // scope.
37 
38 // FIXME: is there a better name for this class?
39 
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  // FIXME: Do we need to apply std::forward to the arguments to
75  // std::bind here?
76 
77  template <typename F, typename... Args>
78  fcn_elem (F&& fcn, Args&& ... args)
79  : m_fcn (std::bind (fcn, args...))
80  { }
81 
82  void run (void) { m_fcn (); }
83 
84  private:
85 
86  std::function<void (void)> m_fcn;
87  };
88 
89  // An element that stores arbitrary variable, and restores it.
90 
91  template <typename T>
92  class restore_var_elem : public elem
93  {
94  public:
95 
96  restore_var_elem (T& ref, const T& val)
97  : m_ptr (&ref), m_val (val) { }
98 
99  // No copying!
100 
102 
103  restore_var_elem& operator = (const restore_var_elem&) = delete;
104 
105  void run (void) { *m_ptr = m_val; }
106 
107  private:
108 
109  T *m_ptr, m_val;
110  };
111 
112  // Deletes a class allocated using new.
113 
114  template <typename T>
115  class delete_ptr_elem : public elem
116  {
117  public:
118 
120  : m_ptr (ptr) { }
121 
122  // No copying!
123 
124  delete_ptr_elem (const delete_ptr_elem&) = delete;
125 
126  delete_ptr_elem operator = (const delete_ptr_elem&) = delete;
127 
128  void run (void) { delete m_ptr; }
129 
130  private:
131 
132  T *m_ptr;
133  };
134 
135  action_container (void) { }
136 
137  // No copying!
138 
140 
141  action_container& operator = (const action_container&) = delete;
142 
143  virtual ~action_container (void) = default;
144 
145  template <typename F, typename... Args>
146  void add (F&& fcn, Args&& ... args)
147  {
148  add_action (new fcn_elem (std::forward<F> (fcn),
149  std::forward<Args> (args)...));
150  }
151 
152  // Use separate template types for function pointer parameter
153  // declarations and captured arguments so that differences in
154  // const are handled properly.
155 
156  template <typename... Params, typename... Args>
157  void add_fcn (void (*fcn) (Params...), Args&& ... args)
158  {
159  add_action (new fcn_elem (fcn, std::forward<Args> (args)...));
160  }
161 
162  template <typename T, typename... Params, typename... Args>
163  void add_method (T *obj, void (T::*method) (Params...), Args&& ... args)
164  {
165  add_action (new fcn_elem (method, obj, std::forward<Args> (args)...));
166  }
167 
168  template <typename T, typename... Params, typename... Args>
169  void add_method (T& obj, void (T::*method) (Params...), Args&& ... args)
170  {
171  add_action (new fcn_elem (method, &obj, std::forward<Args> (args)...));
172  }
173 
174  // Call to delete (T*).
175 
176  template <typename T>
177  void add_delete (T *obj)
178  {
179  add_action (new delete_ptr_elem<T> (obj));
180  }
181 
182  // Protect any variable.
183  template <typename T>
184  void protect_var (T& var)
185  {
186  add_action (new restore_var_elem<T> (var, var));
187  }
188 
189  // Protect any variable, value given.
190  template <typename T>
191  void protect_var (T& var, const T& val)
192  {
193  add_action (new restore_var_elem<T> (var, val));
194  }
195 
196  operator bool (void) const { return ! empty (); }
197 
198  virtual void run_first (void) = 0;
199 
200  OCTAVE_API void run (std::size_t num);
201 
202  void run (void) { run (size ()); }
203 
204  virtual void discard_first (void) = 0;
205 
206  void discard (std::size_t num)
207  {
208  if (num > size ())
209  num = size ();
210 
211  for (std::size_t i = 0; i < num; i++)
212  discard_first ();
213  }
214 
215  void discard (void) { discard (size ()); }
216 
217  virtual std::size_t size (void) const = 0;
218 
219  bool empty (void) const { return size () == 0; }
220 
221 protected:
222 
223  virtual void add_action (elem *new_elem) = 0;
224 };
225 
227 
228 #endif
OCTAVE_END_NAMESPACE(octave)
delete_ptr_elem(const delete_ptr_elem &)=delete
virtual ~elem(void)=default
elem & operator=(const elem &)=delete
virtual void run(void)
elem(const elem &)=delete
std::function< void(void)> m_fcn
fcn_elem(F &&fcn, Args &&... args)
restore_var_elem(const restore_var_elem &)=delete
restore_var_elem(T &ref, const T &val)
void add(F &&fcn, Args &&... args)
void add_method(T *obj, void(T::*method)(Params...), Args &&... args)
void add_delete(T *obj)
virtual void run_first(void)=0
void add_method(T &obj, void(T::*method)(Params...), Args &&... args)
virtual std::size_t size(void) const =0
action_container(const action_container &)=delete
virtual void add_action(elem *new_elem)=0
bool empty(void) const
virtual void discard_first(void)=0
void protect_var(T &var, const T &val)
virtual ~action_container(void)=default
void discard(std::size_t num)
void protect_var(T &var)
void add_fcn(void(*fcn)(Params...), Args &&... args)
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define OCTAVE_API
Definition: main.in.cc:55