00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #if !defined (octave_unwind_prot_h)
00026 #define octave_unwind_prot_h 1
00027
00028 #include <cstddef>
00029
00030 #include <string>
00031 #include <stack>
00032 #include <memory>
00033
00034 class
00035 OCTINTERP_API
00036 unwind_protect
00037 {
00038 public:
00039
00040
00041 class elem
00042 {
00043 public:
00044 virtual void run (void) { }
00045 virtual ~elem (void) { }
00046 };
00047
00048
00049
00050 class fcn_elem : public elem
00051 {
00052 public:
00053 fcn_elem (void (*fptr) (void))
00054 : e_fptr (fptr) { }
00055
00056 void run (void) { e_fptr (); }
00057
00058 private:
00059 void (*e_fptr) (void);
00060 };
00061
00062
00063
00064
00065 template <class T>
00066 class fcn_arg_elem : public elem
00067 {
00068 public:
00069 fcn_arg_elem (void (*fcn) (T), T arg)
00070 : e_fcn (fcn), e_arg (arg) { }
00071
00072 void run (void) { e_fcn (e_arg); }
00073
00074 private:
00075 void (*e_fcn) (T);
00076 T e_arg;
00077 };
00078
00079
00080
00081 template <class T>
00082 class method_elem : public elem
00083 {
00084 public:
00085 method_elem (T *obj, void (T::*method) (void))
00086 : e_obj (obj), e_method (method) { }
00087
00088 void run (void) { (e_obj->*e_method) (); }
00089
00090 private:
00091 T *e_obj;
00092 void (T::*e_method) (void);
00093 };
00094
00095
00096
00097 template <class T>
00098 class restore_var_elem : public elem
00099 {
00100 public:
00101 restore_var_elem (T& ref, const T& val)
00102 : e_ptr (&ref), e_val (val) { }
00103
00104 void run (void) { *e_ptr = e_val; }
00105
00106 private:
00107 T *e_ptr, e_val;
00108 };
00109
00110
00111
00112 template <class T>
00113 class delete_ptr_elem : public elem
00114 {
00115 public:
00116 delete_ptr_elem (T *ptr)
00117 : e_ptr (ptr) { }
00118
00119 void run (void) { delete e_ptr; }
00120
00121 private:
00122 T *e_ptr;
00123 };
00124
00125 typedef size_t frame_id_t;
00126
00127
00128 static void add (elem *el)
00129 {
00130 elt_list.push (el);
00131 }
00132
00133 static bool empty (void)
00134 { return elt_list.empty (); }
00135
00136 static void run (void)
00137 {
00138
00139
00140 std::auto_ptr<elem> elt (elt_list.top ());
00141 elt_list.pop ();
00142
00143 elt->run ();
00144 }
00145
00146 static void discard (void)
00147 {
00148
00149 elem *elt = elt_list.top ();
00150 elt_list.pop ();
00151
00152 delete elt;
00153 }
00154
00155 static frame_id_t begin_frame ()
00156 {
00157 return elt_list.size ();
00158 }
00159
00160 static void run_frame (frame_id_t frame_id)
00161 {
00162 while (elt_list.size () > frame_id)
00163 run ();
00164 }
00165
00166 static void discard_frame (frame_id_t frame_id)
00167 {
00168 while (elt_list.size () > frame_id)
00169 discard ();
00170 }
00171
00172
00173
00174 static void begin_frame (const std::string& tag) GCC_ATTR_DEPRECATED;
00175
00176 static void run_frame (const std::string& tag) GCC_ATTR_DEPRECATED;
00177
00178 static void discard_frame (const std::string& tag) GCC_ATTR_DEPRECATED;
00179
00180 static void run_all (void)
00181 {
00182 run_frame (0);
00183 while (! tag_list.empty ())
00184 tag_list.pop ();
00185 }
00186
00187 static void discard_all (void)
00188 {
00189 discard_frame (0);
00190 while (! tag_list.empty ())
00191 tag_list.pop ();
00192 }
00193
00194
00195 static void add (void (*fcn) (void *), void *ptr = 0)
00196 {
00197 elt_list.push (new fcn_arg_elem<void *> (fcn, ptr));
00198 }
00199
00200
00201 static void add_fcn (void (*fcn) (void))
00202 {
00203 elt_list.push (new fcn_elem (fcn));
00204 }
00205
00206
00207 template <class T>
00208 static void add_fcn (void (*action) (T), T val)
00209 {
00210 elt_list.push (new fcn_arg_elem<T> (action, val));
00211 }
00212
00213
00214 template <class T>
00215 static void add_method (T *obj, void (T::*method) (void))
00216 {
00217 elt_list.push (new method_elem<T> (obj, method));
00218 }
00219
00220
00221
00222 template <class T>
00223 static void add_delete (T *obj)
00224 {
00225 elt_list.push (new delete_ptr_elem<T> (obj));
00226 }
00227
00228
00229 template <class T>
00230 static void protect_var (T& var)
00231 {
00232 elt_list.push (new restore_var_elem<T> (var, var));
00233 }
00234
00235
00236 template <class T>
00237 static void protect_var (T& var, const T& val)
00238 {
00239 elt_list.push (new restore_var_elem<T> (var, val));
00240 }
00241
00242 private:
00243
00244 static std::stack<elem *> elt_list;
00245
00246 static std::stack<std::pair <std::string, frame_id_t> > tag_list;
00247 };
00248
00249
00250
00251 #define unwind_protect_bool(b) \
00252 unwind_protect::protect_var (b)
00253
00254 #define unwind_protect_int(i) \
00255 unwind_protect::protect_var (i)
00256
00257 #define unwind_protect_size_t(i) \
00258 unwind_protect::protect_var (i)
00259
00260 #define unwind_protect_str(s) \
00261 unwind_protect::protect_var (s)
00262
00263 #define unwind_protect_ptr(p) \
00264 unwind_protect::protect_var (p)
00265
00266 #define unwind_protect_fptr(p) \
00267 unwind_protect::protect_var (p)
00268
00269 #define unwind_protect_const_ptr(p) \
00270 unwind_protect::protect_var (p)
00271
00272 #endif
00273
00274
00275
00276
00277
00278