Mercurial > hg > octave-lyh
annotate src/unwind-prot.h @ 10066:2cd940306a06
make unwind_protect frames local
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Wed, 06 Jan 2010 13:18:41 +0100 |
parents | 17af7cce7d1b |
children | cd96d29c5efa |
rev | line source |
---|---|
1 | 1 /* |
2 | |
7017 | 3 Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2004, |
8920 | 4 2005, 2006, 2007, 2008 John W. Eaton |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
5 Copyright (C) 2009, 2010 VZLU Prague |
1 | 6 |
7 This file is part of Octave. | |
8 | |
9 Octave is free software; you can redistribute it and/or modify it | |
10 under the terms of the GNU General Public License as published by the | |
7016 | 11 Free Software Foundation; either version 3 of the License, or (at your |
12 option) any later version. | |
1 | 13 |
14 Octave is distributed in the hope that it will be useful, but WITHOUT | |
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
7016 | 20 along with Octave; see the file COPYING. If not, see |
21 <http://www.gnu.org/licenses/>. | |
1 | 22 |
23 */ | |
24 | |
383 | 25 #if !defined (octave_unwind_prot_h) |
26 #define octave_unwind_prot_h 1 | |
1 | 27 |
1342 | 28 #include <cstddef> |
529 | 29 |
1755 | 30 #include <string> |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
31 #include <memory> |
240 | 32 |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
33 // This class allows registering cleanup actions. |
2985 | 34 class |
6109 | 35 OCTINTERP_API |
2985 | 36 unwind_protect |
37 { | |
38 public: | |
39 | |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
40 // A generic unwind_protect element. Knows how to run itself and discard itself. |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
41 // Also, contains a pointer to the next element. |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
42 class elem |
9376
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
43 { |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
44 elem *next; |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
45 |
9376
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
46 public: |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
47 virtual void run (void) { } |
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
48 virtual ~elem (void) { } |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
49 |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
50 friend class unwind_protect; |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
51 }; |
2985 | 52 |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
53 // An element that merely runs a void (*)(void) function. |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
54 |
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
55 class fcn_elem : public elem |
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
56 { |
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
57 public: |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
58 fcn_elem (void (*fptr) (void)) |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
59 : e_fptr (fptr) { } |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
60 |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
61 void run (void) { e_fptr (); } |
9376
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
62 |
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
63 private: |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
64 void (*e_fptr) (void); |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
65 }; |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
66 |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
67 // An element that stores a variable of type T along with a void (*) (T) |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
68 // function pointer, and calls the function with the parameter. |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
69 |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
70 template <class T> |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
71 class fcn_arg_elem : public elem |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
72 { |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
73 public: |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
74 fcn_arg_elem (void (*fcn) (T), T arg) |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
75 : e_fcn (fcn), e_arg (arg) { } |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
76 |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
77 void run (void) { e_fcn (e_arg); } |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
78 |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
79 private: |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
80 void (*e_fcn) (T); |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
81 T e_arg; |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
82 }; |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
83 |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
84 // An element for calling a member function. |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
85 |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
86 template <class T> |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
87 class method_elem : public elem |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
88 { |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
89 public: |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
90 method_elem (T *obj, void (T::*method) (void)) |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
91 : e_obj (obj), e_method (method) { } |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
92 |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
93 void run (void) { (e_obj->*e_method) (); } |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
94 |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
95 private: |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
96 T *e_obj; |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
97 void (T::*e_method) (void); |
9376
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
98 }; |
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
99 |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
100 // An element that stores arbitrary variable, and restores it. |
2985 | 101 |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
102 template <class T> |
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
103 class restore_var_elem : public elem |
9376
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
104 { |
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
105 public: |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
106 restore_var_elem (T& ref, const T& val) |
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
107 : e_ptr (&ref), e_val (val) { } |
2985 | 108 |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
109 void run (void) { *e_ptr = e_val; } |
9376
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
110 |
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
111 private: |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
112 T *e_ptr, e_val; |
9376
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
113 }; |
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
114 |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
115 // Deletes a class allocated using new. |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
116 |
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
117 template <class T> |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
118 class delete_ptr_elem : public elem |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
119 { |
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
120 public: |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
121 delete_ptr_elem (T *ptr) |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
122 : e_ptr (ptr) { } |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
123 |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
124 void run (void) { delete e_ptr; } |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
125 |
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
126 private: |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
127 T *e_ptr; |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
128 }; |
9376
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
129 |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
130 unwind_protect (void) : head () { } |
9376
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
131 |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
132 void add (elem *new_elem) |
9376
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
133 { |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
134 new_elem->next = head; |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
135 head = new_elem; |
9376
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
136 } |
2985 | 137 |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
138 // For backward compatibility. |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
139 void add (void (*fcn) (void *), void *ptr = 0) |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
140 { |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
141 add (new fcn_arg_elem<void *> (fcn, ptr)); |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
142 } |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
143 |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
144 // Call to void func (void). |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
145 void add_fcn (void (*fcn) (void)) |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
146 { |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
147 add (new fcn_elem (fcn)); |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
148 } |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
149 |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
150 // Call to void func (T). |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
151 template <class T> |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
152 void add_fcn (void (*action) (T), T val) |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
153 { |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
154 add (new fcn_arg_elem<T> (action, val)); |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
155 } |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
156 |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
157 // Call to T::method (void). |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
158 template <class T> |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
159 void add_method (T *obj, void (T::*method) (void)) |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
160 { |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
161 add (new method_elem<T> (obj, method)); |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
162 } |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
163 |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
164 // Call to delete (T*). |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
165 |
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
166 template <class T> |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
167 void add_delete (T *obj) |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9394
diff
changeset
|
168 { |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
169 add (new delete_ptr_elem<T> (obj)); |
9394
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
170 } |
b3ab22ee8544
further improve unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
9384
diff
changeset
|
171 |
9376
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
172 // Protect any variable. |
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
173 template <class T> |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
174 void protect_var (T& var) |
9376
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
175 { |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
176 add (new restore_var_elem<T> (var, var)); |
9376
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
177 } |
2985 | 178 |
9376
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
179 // Protect any variable, value given. |
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
180 template <class T> |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
181 void protect_var (T& var, const T& val) |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
182 { |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
183 add (new restore_var_elem<T> (var, val)); |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
184 } |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
185 |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
186 operator bool (void) const |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
187 { |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
188 return head != 0; |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
189 } |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
190 |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
191 void run_top (void) |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
192 { |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
193 if (head) |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
194 { |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
195 // No leak on exception! |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
196 std::auto_ptr<elem> ptr (head); |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
197 head = ptr->next; |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
198 ptr->run (); |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
199 } |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
200 } |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
201 |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
202 void run_top (int num) |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
203 { |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
204 while (num-- > 0) |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
205 run_top (); |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
206 } |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
207 |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
208 void discard_top (void) |
9376
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
209 { |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
210 if (head) |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
211 { |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
212 elem *ptr = head; |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
213 head = ptr->next; |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
214 delete ptr; |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
215 } |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
216 } |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
217 |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
218 void discard_top (int num) |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
219 { |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
220 while (num-- > 0) |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
221 discard_top (); |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
222 } |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
223 |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
224 void run (void) |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
225 { |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
226 while (head) |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
227 run_top (); |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
228 } |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
229 |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
230 void discard (void) |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
231 { |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
232 while (head) |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
233 discard_top (); |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
234 } |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
235 |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
236 // Destructor should not raise an exception, so all actions registered should |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
237 // be exception-safe (but setting error_state is allowed). If you're not sure, |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
238 // see unwind_protect_safe. |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
239 ~unwind_protect (void) |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
240 { |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
241 run (); |
9376
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
242 } |
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
243 |
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
244 private: |
d58086453171
refactor unwind_protect
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
245 |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
246 elem *head; |
2985 | 247 }; |
248 | |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
249 // Like unwind_protect, but this one will guard against the possibility of seeing |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
250 // an exception (or interrupt) in the cleanup actions. Not that we can do much about |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
251 // it, but at least we won't crash. |
2985 | 252 |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
253 class unwind_protect_safe : public unwind_protect |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
254 { |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
255 static void gripe_exception (void); |
7752
40c428ea3408
initial implementation of dbup and dbdown
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
256 |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
257 public: |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
258 ~unwind_protect_safe (void) |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
259 { |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
260 while (*this) |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
261 { |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
262 try |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
263 { |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
264 run_top (); |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
265 } |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
266 catch (...) // Yes, the black hole. Remember we're in a dtor. |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
267 { |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
268 gripe_exception (); |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
269 } |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
270 } |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
271 } |
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9396
diff
changeset
|
272 }; |
2985 | 273 |
1 | 274 #endif |
275 | |
276 /* | |
277 ;;; Local Variables: *** | |
278 ;;; mode: C++ *** | |
279 ;;; End: *** | |
280 */ |