GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
action-container.h
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 1993-2025 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
45template <typename T>
47{
48 typedef T type;
49};
50
51template <typename T>
52struct atomic_traits<std::atomic<T>>
53{
54 typedef T type;
55};
56
57OCTAVE_END_NAMESPACE(util)
58
60{
61public:
62
63 // A generic unwind_protect element. Knows how to run itself and
64 // discard itself. Also, contains a pointer to the next element.
65 class elem
66 {
67 public:
68
69 friend class action_container;
70
71 elem () { }
72
73 OCTAVE_DISABLE_COPY_MOVE (elem)
74
75 virtual ~elem () = default;
76
77 virtual void run () { }
78 };
79
80 // An element that merely runs a void (*)() function.
81
82 class fcn_elem : public elem
83 {
84 public:
85
86 // FIXME: Do we need to apply std::forward to the arguments to
87 // std::bind here?
88
89 template <typename F, typename... Args>
90 fcn_elem (F&& fcn, Args&& ... args)
91 : m_fcn (std::bind (fcn, args...))
92 { }
93
94 void run () { m_fcn (); }
95
96 private:
97
98 std::function<void ()> m_fcn;
99 };
100
101 // An element that stores arbitrary variable, and restores it.
102
103 template <typename T>
104 class restore_var_elem : public elem
105 {
106 public:
107
108 restore_var_elem (T& ref, const T& val)
109 : m_ptr (&ref), m_val (val) { }
110
111 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (restore_var_elem)
112
113 ~restore_var_elem () = default;
114
115 void run () { *m_ptr = m_val; }
116
117 private:
118
119 T *m_ptr;
120 typename util::atomic_traits<T>::type m_val;
121 };
122
123 // Deletes a class allocated using new.
124
125 template <typename T>
126 class delete_ptr_elem : public elem
127 {
128 public:
129
131 : m_ptr (ptr) { }
132
133 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (delete_ptr_elem)
134
135 ~delete_ptr_elem () = default;
136
137 void run () { delete m_ptr; }
138
139 private:
140
141 T *m_ptr;
142 };
143
145
146 OCTAVE_DISABLE_COPY_MOVE (action_container)
147
148 virtual ~action_container () = default;
149
150 template <typename F, typename... Args>
151 void add (F&& fcn, Args&& ... args)
152 {
153 add_action (new fcn_elem (std::forward<F> (fcn),
154 std::forward<Args> (args)...));
155 }
156
157 // Use separate template types for function pointer parameter
158 // declarations and captured arguments so that differences in
159 // const are handled properly.
160
161 template <typename... Params, typename... Args>
162 void add_fcn (void (*fcn) (Params...), Args&& ... args)
163 {
164 add_action (new fcn_elem (fcn, std::forward<Args> (args)...));
165 }
166
167 template <typename T, typename... Params, typename... Args>
168 void add_method (T *obj, void (T::*method) (Params...), Args&& ... args)
169 {
170 add_action (new fcn_elem (method, obj, std::forward<Args> (args)...));
171 }
172
173 template <typename T, typename... Params, typename... Args>
174 void add_method (T& obj, void (T::*method) (Params...), Args&& ... args)
175 {
176 add_action (new fcn_elem (method, &obj, std::forward<Args> (args)...));
177 }
178
179 // Call to delete (T*).
180
181 template <typename T>
182 void add_delete (T *obj)
183 {
184 add_action (new delete_ptr_elem<T> (obj));
185 }
186
187 // Protect any variable.
188 template <typename T>
189 void protect_var (T& var)
190 {
191 add_action (new restore_var_elem<T> (var, var));
192 }
193
194 // Protect any variable, value given.
195 template <typename T>
196 void protect_var (T& var, const T& val)
197 {
198 add_action (new restore_var_elem<T> (var, val));
199 }
200
201 operator bool () const { return ! empty (); }
202
203 virtual void run_first () = 0;
204
205 OCTAVE_API void run (std::size_t num);
206
207 void run () { run (size ()); }
208
209 virtual void discard_first () = 0;
210
211 void discard (std::size_t num)
212 {
213 if (num > size ())
214 num = size ();
215
216 for (std::size_t i = 0; i < num; i++)
217 discard_first ();
218 }
219
220 void discard () { discard (size ()); }
221
222 virtual std::size_t size () const = 0;
223
224 bool empty () const { return size () == 0; }
225
226protected:
227
228 virtual void add_action (elem *new_elem) = 0;
229};
230
231OCTAVE_END_NAMESPACE(octave)
232
233#endif
fcn_elem(F &&fcn, Args &&... args)
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)
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.in.cc:55