Teh first one
[mldemos:kalians-mldemos.git] / _AlgorithmsPlugins / KernelMethods / newmat11 / myexcept.h
1 // Copyright (C) 2004: R B Davies\r
2 /// \ingroup rbd_common\r
3 ///@{\r
4 \r
5 /// \file myexcept.h\r
6 /// Exception handler.\r
7 /// The low level classes for\r
8 /// - my exception class hierarchy\r
9 /// - the functions needed for my simulated exceptions\r
10 /// - the Tracer mechanism\r
11 /// - routines for checking whether new and delete calls are balanced\r
12 ///\r
13 \r
14 \r
15 // A set of classes to simulate exceptions in C++\r
16 //\r
17 //   Partially copied from Carlos Vidal s article in the C users  journal\r
18 //   September 1992, pp 19-28\r
19 //\r
20 //   Operations defined\r
21 //      Try {     }\r
22 //      Throw ( exception object )\r
23 //      ReThrow\r
24 //      Catch ( exception class ) {      }\r
25 //      CatchAll {      }\r
26 //      CatchAndThrow\r
27 //\r
28 //   All catch lists must end with a CatchAll or CatchAndThrow statement\r
29 //   but not both.\r
30 //\r
31 //   When exceptions are finally implemented replace Try, Throw(E), Rethrow,\r
32 //   Catch, CatchAll, CatchAndThrow by try, throw E, throw, catch,\r
33 //   catch(...), and {}.\r
34 //\r
35 //   All exception classes must be derived from BaseException, have no\r
36 //   non-static variables and must include the statement\r
37 //\r
38 //      static unsigned long Select;\r
39 //\r
40 //   Any constructor in one of these exception classes must include\r
41 //\r
42 //      Select = BaseException::Select;\r
43 //\r
44 //   For each exceptions class, EX_1, some .cpp file must include\r
45 //\r
46 //      unsigned long EX_1::Select;\r
47 //\r
48 \r
49 \r
50 #ifndef EXCEPTION_LIB\r
51 #define EXCEPTION_LIB\r
52 \r
53 #include "include.h"\r
54 \r
55 #ifdef use_namespace\r
56 namespace RBD_COMMON {\r
57 #endif\r
58 \r
59 \r
60 void Terminate();\r
61 \r
62 \r
63 //********** classes for setting up exceptions and reporting ************//\r
64 \r
65 class BaseException;\r
66 \r
67 class Tracer                             // linked list showing how\r
68 {                                        // we got here\r
69    const char* entry;\r
70    Tracer* previous;\r
71 public:\r
72    Tracer(const char*);\r
73    ~Tracer();\r
74    void ReName(const char*);\r
75    static void PrintTrace();             // for printing trace\r
76    static void AddTrace();               // insert trace in exception record\r
77    static Tracer* last;                  // points to Tracer list\r
78    static void clear() {}                // for compatibility\r
79    friend class BaseException;\r
80 };\r
81 \r
82 \r
83 class BaseException                          // The base exception class\r
84 {\r
85 protected:\r
86    static char* what_error;              // error message\r
87    static int SoFar;                     // no. characters already entered\r
88    static int LastOne;                   // last location in error buffer\r
89 public:\r
90    static void AddMessage(const char* a_what);\r
91                                          // messages about exception\r
92    static void AddInt(int value);        // integer to error message\r
93    static unsigned long Select;          // for identifying exception\r
94    BaseException(const char* a_what = 0);\r
95    static const char* what() { return what_error; }\r
96                                          // for getting error message\r
97    static void clear() {}                // for compatibility\r
98 };\r
99 \r
100 #ifdef TypeDefException\r
101 typedef BaseException Exception;        // for compatibility with my older libraries\r
102 #endif\r
103 \r
104 inline Tracer::Tracer(const char* e)\r
105    : entry(e), previous(last) { last = this; }\r
106 \r
107 inline Tracer::~Tracer() { last = previous; }\r
108 \r
109 inline void Tracer::ReName(const char* e) { entry=e; }\r
110 \r
111 #ifdef SimulateExceptions                // SimulateExceptions\r
112 \r
113 #include <setjmp.h>\r
114 \r
115 \r
116 //************* the definitions of Try, Throw and Catch *****************//\r
117 \r
118 \r
119 class JumpItem;\r
120 class Janitor;\r
121 \r
122 class JumpBase         // pointer to a linked list of jmp_buf s\r
123 {\r
124 public:\r
125    static JumpItem *jl;\r
126    static jmp_buf env;\r
127 };\r
128 \r
129 class JumpItem         // an item in a linked list of jmp_buf s\r
130 {\r
131 public:\r
132    JumpItem *ji;\r
133    jmp_buf env;\r
134    Tracer* trace;                     // to keep check on Tracer items\r
135    Janitor* janitor;                  // list of items for cleanup\r
136    JumpItem() : ji(JumpBase::jl), trace(0), janitor(0)\r
137       { JumpBase::jl = this; }\r
138    ~JumpItem() { JumpBase::jl = ji; }\r
139 };\r
140 \r
141 void Throw();\r
142 \r
143 inline void Throw(const BaseException&) { Throw(); }\r
144 \r
145 #define Try                                             \\r
146    if (!setjmp( JumpBase::jl->env )) {                  \\r
147    JumpBase::jl->trace = Tracer::last;               \\r
148    JumpItem JI387256156;\r
149 \r
150 #define ReThrow Throw()\r
151 \r
152 #define Catch(EXCEPTION)                                \\r
153    } else if (BaseException::Select == EXCEPTION::Select) {\r
154 \r
155 #define CatchAll } else\r
156 \r
157 #define CatchAndThrow  } else Throw();\r
158 \r
159 \r
160 //****************** cleanup heap following Throw ***********************//\r
161 \r
162 class Janitor\r
163 {\r
164 protected:\r
165    static bool do_not_link;                  // set when new is called\r
166    bool OnStack;                             // false if created by new\r
167 public:\r
168    Janitor* NextJanitor;\r
169    virtual void CleanUp() {}\r
170    Janitor();\r
171    virtual ~Janitor();\r
172 };\r
173 \r
174 \r
175 // The tiresome old trick for initializing the Janitor class\r
176 // this is needed for classes derived from Janitor which have objects\r
177 // declared globally\r
178 \r
179 class JanitorInitializer\r
180 {\r
181 public:\r
182    JanitorInitializer();\r
183 private:\r
184    static int ref_count;\r
185 };\r
186 \r
187 static JanitorInitializer JanInit;\r
188 \r
189 #endif                                // end of SimulateExceptions\r
190 \r
191 #ifdef UseExceptions\r
192 \r
193 #define Try try\r
194 #define Throw(E) throw E\r
195 #define ReThrow throw\r
196 #define Catch catch\r
197 #define CatchAll catch(...)\r
198 #define CatchAndThrow {}\r
199 \r
200 #endif                                // end of UseExceptions\r
201 \r
202 \r
203 #ifdef DisableExceptions              // Disable exceptions\r
204 \r
205 #define Try {\r
206 #define ReThrow Throw()\r
207 #define Catch(EXCEPTION) } if (false) {\r
208 #define CatchAll } if (false)\r
209 #define CatchAndThrow }\r
210 \r
211 inline void Throw() { Terminate(); }\r
212 inline void Throw(const BaseException&) { Terminate(); }\r
213 \r
214 \r
215 #endif                                // end of DisableExceptions\r
216 \r
217 #ifndef SimulateExceptions            // ! SimulateExceptions\r
218 \r
219 class Janitor                         // a dummy version\r
220 {\r
221 public:\r
222    virtual void CleanUp() {}\r
223    Janitor() {}\r
224    virtual ~Janitor() {}\r
225 };\r
226 \r
227 #endif                                // end of ! SimulateExceptions\r
228 \r
229 \r
230 //******************** FREE_CHECK and NEW_DELETE ***********************//\r
231 \r
232 #ifdef DO_FREE_CHECK                          // DO_FREE_CHECK\r
233 // Routines for tracing whether new and delete calls are balanced\r
234 \r
235 class FreeCheck;\r
236 \r
237 class FreeCheckLink\r
238 {\r
239 protected:\r
240    FreeCheckLink* next;\r
241    void* ClassStore;\r
242    FreeCheckLink();\r
243    virtual void Report()=0;                   // print details of link\r
244    friend class FreeCheck;\r
245 };\r
246 \r
247 class FCLClass : public FreeCheckLink         // for registering objects\r
248 {\r
249    char* ClassName;\r
250    FCLClass(void* t, char* name);\r
251    void Report();\r
252    friend class FreeCheck;\r
253 };\r
254 \r
255 class FCLRealArray : public FreeCheckLink     // for registering real arrays\r
256 {\r
257    char* Operation;\r
258    int size;\r
259    FCLRealArray(void* t, char* o, int s);\r
260    void Report();\r
261    friend class FreeCheck;\r
262 };\r
263 \r
264 class FCLIntArray : public FreeCheckLink     // for registering int arrays\r
265 {\r
266    char* Operation;\r
267    int size;\r
268    FCLIntArray(void* t, char* o, int s);\r
269    void Report();\r
270    friend class FreeCheck;\r
271 };\r
272 \r
273 \r
274 class FreeCheck\r
275 {\r
276    static FreeCheckLink* next;\r
277    static int BadDelete;\r
278 public:\r
279    static void Register(void*, char*);\r
280    static void DeRegister(void*, char*);\r
281    static void RegisterR(void*, char*, int);\r
282    static void DeRegisterR(void*, char*, int);\r
283    static void RegisterI(void*, char*, int);\r
284    static void DeRegisterI(void*, char*, int);\r
285    static void Status();\r
286    friend class FreeCheckLink;\r
287    friend class FCLClass;\r
288    friend class FCLRealArray;\r
289    friend class FCLIntArray;\r
290 };\r
291 \r
292 #define FREE_CHECK(Class)                                                  \\r
293 public:                                                                    \\r
294    void* operator new(size_t size)                                         \\r
295    {                                                                       \\r
296       void* t = ::operator new(size); FreeCheck::Register(t,#Class);       \\r
297       return t;                                                            \\r
298    }                                                                       \\r
299    void operator delete(void* t)                                           \\r
300    { FreeCheck::DeRegister(t,#Class); ::operator delete(t); }\r
301 \r
302 \r
303 #ifdef SimulateExceptions         // SimulateExceptions\r
304 \r
305 #define NEW_DELETE(Class)                                                  \\r
306 public:                                                                    \\r
307    void* operator new(size_t size)                                         \\r
308    {                                                                       \\r
309       do_not_link=true;                                                    \\r
310       void* t = ::operator new(size); FreeCheck::Register(t,#Class);       \\r
311       return t;                                                            \\r
312    }                                                                       \\r
313    void operator delete(void* t)                                           \\r
314    { FreeCheck::DeRegister(t,#Class); ::operator delete(t); }\r
315 \r
316 \r
317 #endif                           // end of SimulateExceptions\r
318 \r
319 \r
320 #define MONITOR_REAL_NEW(Operation, Size, Pointer)                         \\r
321         FreeCheck::RegisterR(Pointer, Operation, Size);\r
322 #define MONITOR_INT_NEW(Operation, Size, Pointer)                          \\r
323         FreeCheck::RegisterI(Pointer, Operation, Size);\r
324 #define MONITOR_REAL_DELETE(Operation, Size, Pointer)                      \\r
325         FreeCheck::DeRegisterR(Pointer, Operation, Size);\r
326 #define MONITOR_INT_DELETE(Operation, Size, Pointer)                       \\r
327         FreeCheck::DeRegisterI(Pointer, Operation, Size);\r
328 \r
329 #else                            // DO_FREE_CHECK not defined\r
330 \r
331 #define FREE_CHECK(Class) public:\r
332 #define MONITOR_REAL_NEW(Operation, Size, Pointer) {}\r
333 #define MONITOR_INT_NEW(Operation, Size, Pointer) {}\r
334 #define MONITOR_REAL_DELETE(Operation, Size, Pointer) {}\r
335 #define MONITOR_INT_DELETE(Operation, Size, Pointer) {}\r
336 \r
337 \r
338 #ifdef SimulateExceptions         // SimulateExceptions\r
339 \r
340 \r
341 #define NEW_DELETE(Class)                                                  \\r
342 public:                                                                    \\r
343         void* operator new(size_t size)                                    \\r
344         { do_not_link=true; void* t = ::operator new(size); return t; }    \\r
345         void operator delete(void* t) { ::operator delete(t); }\r
346 \r
347 #endif                            // end of SimulateExceptions\r
348 \r
349 #endif                            // end of ! DO_FREE_CHECK\r
350 \r
351 #ifndef SimulateExceptions        // ! SimulateExceptions\r
352 \r
353 #define NEW_DELETE(Class) FREE_CHECK(Class)\r
354 \r
355 #endif                            // end of ! SimulateExceptions\r
356 \r
357 \r
358 //********************* derived exceptions ******************************//\r
359 \r
360 class Logic_error : public BaseException\r
361 {\r
362 public:\r
363    static unsigned long Select;\r
364    Logic_error(const char* a_what = 0);\r
365 };\r
366 \r
367 class Runtime_error : public BaseException\r
368 {\r
369 public:\r
370    static unsigned long Select;\r
371    Runtime_error(const char* a_what = 0);\r
372 };\r
373 \r
374 class Domain_error : public Logic_error\r
375 {\r
376 public:\r
377    static unsigned long Select;\r
378    Domain_error(const char* a_what = 0);\r
379 };\r
380 \r
381 class Invalid_argument : public Logic_error\r
382 {\r
383 public:\r
384    static unsigned long Select;\r
385    Invalid_argument(const char* a_what = 0);\r
386 };\r
387 \r
388 class Length_error : public Logic_error\r
389 {\r
390 public:\r
391    static unsigned long Select;\r
392    Length_error(const char* a_what = 0);\r
393 };\r
394 \r
395 class Out_of_range : public Logic_error\r
396 {\r
397 public:\r
398    static unsigned long Select;\r
399    Out_of_range(const char* a_what = 0);\r
400 };\r
401 \r
402 //class Bad_cast : public Logic_error\r
403 //{\r
404 //public:\r
405 //   static unsigned long Select;\r
406 //   Bad_cast(const char* a_what = 0);\r
407 //};\r
408 \r
409 //class Bad_typeid : public Logic_error\r
410 //{\r
411 //public:\r
412 //   static unsigned long Select;\r
413 //   Bad_typeid(const char* a_what = 0);\r
414 //};\r
415 \r
416 class Range_error : public Runtime_error\r
417 {\r
418 public:\r
419    static unsigned long Select;\r
420    Range_error(const char* a_what = 0);\r
421 };\r
422 \r
423 class Overflow_error : public Runtime_error\r
424 {\r
425 public:\r
426    static unsigned long Select;\r
427    Overflow_error(const char* a_what = 0);\r
428 };\r
429 \r
430 class Bad_alloc : public BaseException\r
431 {\r
432 public:\r
433    static unsigned long Select;\r
434    Bad_alloc(const char* a_what = 0);\r
435 };\r
436 \r
437 #ifdef use_namespace\r
438 }\r
439 #endif\r
440 \r
441 \r
442 #endif                            // end of EXCEPTION_LIB\r
443 \r
444 \r
445 // body file: myexcept.cpp\r
446 \r
447 \r
448 ///@}\r
449 \r