GNU Octave 7.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-2022 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
40namespace 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 // 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
125
126 delete_ptr_elem operator = (const delete_ptr_elem&) = delete;
127
128 void run (void) { delete m_ptr; }
129
130 private:
131
133 };
134
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}
226
227#endif
delete_ptr_elem(const delete_ptr_elem &)=delete
virtual ~elem(void)=default
elem(const elem &)=delete
fcn_elem(F &&fcn, Args &&... args)
std::function< void(void)> m_fcn
restore_var_elem(const restore_var_elem &)=delete
void add_method(T &obj, void(T::*method)(Params...), Args &&... args)
action_container(const action_container &)=delete
virtual void run_first(void)=0
void add_method(T *obj, void(T::*method)(Params...), Args &&... args)
void add_fcn(void(*fcn)(Params...), Args &&... args)
void add(F &&fcn, Args &&... args)
virtual void add_action(elem *new_elem)=0
virtual std::size_t size(void) const =0
virtual ~action_container(void)=default
void discard(std::size_t num)
virtual void discard_first(void)=0
void protect_var(T &var, const T &val)
#define OCTAVE_API
Definition: main.in.cc:55
void F(const TSRC *v, TRES *r, octave_idx_type m, octave_idx_type n)
Definition: mx-inlines.cc:757
STL namespace.