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