|
|
| version 1.17, 2001/01/30 11:51:07 | version 1.24, 2001/02/22 11:08:06 |
|---|---|
| Line 7 | Line 7 |
| #include <stddef.h> | #include <stddef.h> |
| #include "pa_string.h" | //class String; |
| #include "pa_hash.h" | class Exception; |
| #include "pa_array.h" | class Temp_exception_change; |
| //#include "pa_table.h" | |
| #include "pa_exception.h" | |
| class Pool { | class Pool { |
| friend Temp_exception_change; | |
| public: | public: |
| Pool(); | |
| ~Pool(); | |
| virtual void *malloc(size_t size)=0; | |
| virtual void *calloc(size_t size)=0; | |
| String& make_string() { | Pool() : fexception(0) {} |
| return *new(*this) String(*this); | ~Pool() {} |
| Exception& exception() const { return *fexception; } | |
| void *malloc(size_t size) { | |
| return check(real_malloc(size), size); | |
| } | } |
| Hash& make_hash() { | void *calloc(size_t size) { |
| return *new(*this) Hash(*this, false); | return check(real_calloc(size), size); |
| } | } |
| Hash& make_thread_safe_hash() { | |
| return *new(*this) Hash(*this, true); | private: // implementation defined |
| void *real_malloc(size_t size); | |
| void *real_calloc(size_t size); | |
| private: | |
| // checks whether mem allocated OK. throws exception otherwise | |
| void *check(void *ptr, size_t size) { | |
| if(ptr) | |
| return ptr; | |
| fail(size); | |
| // never reached | |
| return 0; | |
| } | } |
| Array& make_array() { | // throws proper exception |
| return *new(*this) Array(*this); | void fail(size_t size) const; |
| protected: // exception handling | |
| // exception replacement mechanism is 'protected' from direct usage | |
| // Temp_exception_change object enforces paired set/restore | |
| Exception *set_exception(Exception *e){ | |
| Exception *r=fexception; | |
| fexception=e; | |
| return r; | |
| } | } |
| Array& make_array(int initial_rows) { | void restore_exception(Exception *e) { |
| return *new(*this) Array(*this, initial_rows); | fexception=e; |
| } | } |
| /*Table& make_table(char *afile, uint aline, Array *acolumns, int initial_rows) { | |
| return *new(this) Table(this, afile, aline, acolumns, initial_rows); | |
| }*/ | |
| Exception *global_exception() { return fglobal_exception; } | private: |
| Exception *set_global_exception(Exception *e); | |
| void restore_global_exception(Exception *e); | |
| Exception *local_exception() { return flocal_exception; } | // current request's exception object |
| Exception *set_local_exception(Exception *e); | Exception *fexception; |
| void restore_local_exception(Exception *e); | |
| protected: | private: //disabled |
| Exception *fglobal_exception; | // Pool(const Pool&) {} |
| Exception *flocal_exception; | Pool& operator = (const Pool&) { return *this; } |
| }; | |
| // checks whether mem allocated OK. throws exceptions | class Pooled { |
| void *check(void *ptr); | // the pool i'm allocated on |
| Pool& fpool; | |
| public: | |
| static void *operator new(size_t size, Pool& apool) { | |
| return apool.malloc(size); | |
| } | |
| private: //disabled | Pooled(Pool& apool) : fpool(apool) { |
| } | |
| Pool(const Pool&) {} | Pool& pool() const { return fpool; } |
| Pool& operator = (const Pool&) { return *this; } | |
| void *malloc(size_t size) const { return fpool.malloc(size); } | |
| void *calloc(size_t size) const { return fpool.calloc(size); } | |
| Exception& exception() const { return fpool.exception(); } | |
| }; | }; |
| #define NEW new(pool()) | |
| class Temp_exception_change { | |
| Pool pool; | |
| Exception *saved_exception; | |
| public: | |
| Temp_exception_change(Pool& apool, Exception& exception) : | |
| pool(apool), | |
| saved_exception(apool.set_exception(&exception)) { | |
| } | |
| ~Temp_exception_change() { | |
| pool.restore_exception(saved_exception); | |
| } | |
| }; | |
| #define TRY \ | |
| { \ | |
| Exception temp_exception; \ | |
| Temp_exception_change le(pool(), temp_exception); \ | |
| if(setjmp(temp_exception.mark)==0) | |
| #define THROW exception()._throw | |
| #define CATCH(e) \ | |
| else{ \ | |
| Exception& e=temp_exception; | |
| #define END_CATCH \ | |
| } \ | |
| } | |
| // usage: | |
| // TRY { ...; if(?) RAISE(?); ...; } CATCH(e) { catch-code e.comment() } END_CATCH | |
| #endif | #endif |