GNU Octave  9.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-2024 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 <atomic>
32 #include <cstddef>
33 #include <functional>
34 
35 // This class allows registering actions in a list for later
36 // execution, either explicitly or when the container goes out of
37 // scope.
38 
39 // FIXME: is there a better name for this class?
40 
42 
44 
45 template <typename T>
47 {
48  typedef T type;
49 };
50 
51 template <typename T>
52 struct atomic_traits<std::atomic<T>>
53 {
54  typedef T type;
55 };
56 
57 OCTAVE_END_NAMESPACE(util)
58 
59 class
61 {
62 public:
63 
64  // A generic unwind_protect element. Knows how to run itself and
65  // discard itself. Also, contains a pointer to the next element.
66  class elem
67  {
68  public:
69 
70  friend class action_container;
71 
72  elem () { }
73 
74  OCTAVE_DISABLE_COPY_MOVE (elem)
75 
76  virtual ~elem () = default;
77 
78  virtual void run () { }
79  };
80 
81  // An element that merely runs a void (*)() function.
82 
83  class fcn_elem : public elem
84  {
85  public:
86 
87  // FIXME: Do we need to apply std::forward to the arguments to
88  // std::bind here?
89 
90  template <typename F, typename... Args>
91  fcn_elem (F&& fcn, Args&& ... args)
92  : m_fcn (std::bind (fcn, args...))
93  { }
94 
95  void run () { m_fcn (); }
96 
97  private:
98 
99  std::function<void ()> m_fcn;
100  };
101 
102  // An element that stores arbitrary variable, and restores it.
103 
104  template <typename T>
105  class restore_var_elem : public elem
106  {
107  public:
108 
109  restore_var_elem (T& ref, const T& val)
110  : m_ptr (&ref), m_val (val) { }
111 
112  OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (restore_var_elem)
113 
114  ~restore_var_elem () = default;
115 
116  void run () { *m_ptr = m_val; }
117 
118  private:
119 
120  T *m_ptr;
121  typename util::atomic_traits<T>::type m_val;
122  };
123 
124  // Deletes a class allocated using new.
125 
126  template <typename T>
127  class delete_ptr_elem : public elem
128  {
129  public:
130 
132  : m_ptr (ptr) { }
133 
134  OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (delete_ptr_elem)
135 
136  ~delete_ptr_elem () = default;
137 
138  void run () { delete m_ptr; }
139 
140  private:
141 
142  T *m_ptr;
143  };
144 
146 
147  OCTAVE_DISABLE_COPY_MOVE (action_container)
148 
149  virtual ~action_container () = default;
150 
151  template <typename F, typename... Args>
152  void add (F&& fcn, Args&& ... args)
153  {
154  add_action (new fcn_elem (std::forward<F> (fcn),
155  std::forward<Args> (args)...));
156  }
157 
158  // Use separate template types for function pointer parameter
159  // declarations and captured arguments so that differences in
160  // const are handled properly.
161 
162  template <typename... Params, typename... Args>
163  void add_fcn (void (*fcn) (Params...), Args&& ... args)
164  {
165  add_action (new fcn_elem (fcn, 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  template <typename T, typename... Params, typename... Args>
175  void add_method (T& obj, void (T::*method) (Params...), Args&& ... args)
176  {
177  add_action (new fcn_elem (method, &obj, std::forward<Args> (args)...));
178  }
179 
180  // Call to delete (T*).
181 
182  template <typename T>
183  void add_delete (T *obj)
184  {
185  add_action (new delete_ptr_elem<T> (obj));
186  }
187 
188  // Protect any variable.
189  template <typename T>
190  void protect_var (T& var)
191  {
192  add_action (new restore_var_elem<T> (var, var));
193  }
194 
195  // Protect any variable, value given.
196  template <typename T>
197  void protect_var (T& var, const T& val)
198  {
199  add_action (new restore_var_elem<T> (var, val));
200  }
201 
202  operator bool () const { return ! empty (); }
203 
204  virtual void run_first () = 0;
205 
206  OCTAVE_API void run (std::size_t num);
207 
208  void run () { run (size ()); }
209 
210  virtual void discard_first () = 0;
211 
212  void discard (std::size_t num)
213  {
214  if (num > size ())
215  num = size ();
216 
217  for (std::size_t i = 0; i < num; i++)
218  discard_first ();
219  }
220 
221  void discard () { discard (size ()); }
222 
223  virtual std::size_t size () const = 0;
224 
225  bool empty () const { return size () == 0; }
226 
227 protected:
228 
229  virtual void add_action (elem *new_elem) = 0;
230 };
231 
232 OCTAVE_END_NAMESPACE(octave)
233 
234 #endif
fcn_elem(F &&fcn, Args &&... args)
restore_var_elem(T &ref, const T &val)
void add_method(T *obj, void(T::*method)(Params...), Args &&... args)
virtual std::size_t size() const =0
void add_delete(T *obj)
void add_method(T &obj, void(T::*method)(Params...), Args &&... args)
virtual void run_first()=0
virtual void add_action(elem *new_elem)=0
void protect_var(T &var, const T &val)
void discard(std::size_t num)
bool empty() const
void protect_var(T &var)
void add_fcn(void(*fcn)(Params...), Args &&... args)
virtual void discard_first()=0
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define OCTAVE_API
Definition: main.cc:55