--- parser3/src/include/pa_pool.h 2001/04/04 10:50:34 1.49 +++ parser3/src/include/pa_pool.h 2003/02/19 16:19:00 1.86.2.30 @@ -1,201 +1,199 @@ /** @file - Parser: pool class decl. + Parser: Parser: reference counting classes decls. - Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com) - Author: Alexander Petrosyan (http://design.ru/paf) - - $Id: pa_pool.h,v 1.49 2001/04/04 10:50:34 paf Exp $ + Author: Alexandr Petrosian (http://paf.design.ru) */ #ifndef PA_POOL_H #define PA_POOL_H -#include - -class Exception; -class Temp_exception; - -/** - Pool mechanizm allows users not to free up allocated memory, - leaving that problem to 'pools'. +static const char* IDENT_POOL_H="$Date: 2003/02/19 16:19:00 $"; - Also holds Exception object, which can be temporary set using - Temp_exception auto-object. +// include - @see Pooled -*/ +#include "pa_config_includes.h" -class Pool { - friend Temp_exception; -public: +#ifdef XML +# include "gdome.h" +// for xmlChar +# include "libxml/tree.h" +#endif - Pool(void *astorage) : fstorage(astorage), fcontext(0), ftag(0), fexception(0) {} +// forwards - void set_context(void *acontext) { fcontext=acontext; } - void *context() { return fcontext; } +void *pa_malloc(size_t size); +void *pa_calloc(size_t size); +void pa_free(void *ptr); +void *pa_realloc(void *ptr, size_t size); - void set_tag(void *atag) { ftag=atag; } - void *tag() { return ftag; } +class Exception; +class String; +class Charset; +class GdomeDOMString_auto_ptr; - /// current exception object of the pool - Exception& exception() const { return *fexception; } +template class object_ptr { + T *ptr; +public: + typedef T element_type; - /// allocates some bytes on pool - void *malloc(size_t size) { - return check(real_malloc(size), size); + explicit object_ptr(T *ptr = 0) { + this->ptr=ptr; + if(ptr) + ptr->ref(); } - /// allocates some bytes clearing them with zeros - void *calloc(size_t size) { - return check(real_calloc(size), size); + template object_ptr(const object_ptr& src) { + this->ptr=src.get(); + if(ptr) + ptr->ref(); } - -private: - - void *fstorage; - void *fcontext; - void *ftag; - -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) { + object_ptr(const object_ptr& src) { + ptr=src.get(); if(ptr) - return ptr; - - fail(size); - - // never reached - return 0; + ptr->ref(); } - /// throws proper exception - void fail(size_t size) const; - -private: // exception handling - - // exception replacement mechanism is 'private'zed from direct usage - // Temp_exception object enforces paired set/restore - Exception *set_exception(Exception *e){ - Exception *r=fexception; - fexception=e; - return r; + object_ptr(T *ptr, int) { + this->ptr=ptr; } - void restore_exception(Exception *e) { - fexception=e; + object_ptr& operator=(const object_ptr& src) { + if(this!=&src) + if(ptr!=src.get()) { + if(ptr) + ptr->unref(); + ptr=src.get(); + if(ptr) + ptr->ref(); + } + return *this; + } + ~object_ptr() { + if(ptr) + ptr->unref(); + } + T& operator*() const { + return *get(); + } + T *operator->() const { + return get(); + } + T *get() const { + return ptr; + } + operator bool() const { + return get()!=0; + } + bool operator !() const { + return get()==0; } - -private: - - // current request's exception object - Exception *fexception; - -private: //disabled - - // Pool(const Pool&) {} - Pool& operator = (const Pool&) { return *this; } }; -/** - Base for all classes that are allocated in 'pools'. +#define DECLARE_OBJECT_PTR(name) \ + typedef object_ptr name##Ptr - Holds Pool object. Contains useful wrappers to it's methods. +/// TEMPLATE CLASS smart_ptr, stolen from stl:auto_ptr & renamed field/params [not compiled on gcc] +template + class smart_ptr { + bool owns; + T *ptr; +public: + typedef T element_type; + explicit smart_ptr(T *aptr = 0) + : owns(aptr != 0), ptr(aptr) {} + smart_ptr(const smart_ptr& src) + : owns(src.owns), ptr(src.release()) {} + smart_ptr& operator=(const smart_ptr& src) + {if (this != &src) + {if (ptr != src.get()) + {if (owns) + delete ptr; + owns = src.owns; } + else if (src.owns) + owns = true; + ptr = src.release(); } + return (*this); } + ~smart_ptr() + {if (owns) + delete ptr; } + T& operator*() const + {return (*get()); } + T *get() const + {return ptr; } + T *release() const + {((smart_ptr *)this)->owns = false; + return (ptr); } + operator bool() const { + return get()!=0; + } + operator T*() const { + return ptr; + } + }; + +// defines + +#define override +#define rethrow throw + +// memory + +inline void *operator new[] (size_t size) { + return pa_malloc(size); +} +inline void operator delete[] (void *ptr) { + pa_free(ptr); +} +inline void operator delete (void *ptr) { + pa_free(ptr); +} - @see NEW, Temp_exception -*/ -class Pooled { - // the pool i'm allocated on - Pool *fpool; +class PA_Allocated { public: + /// the sole: instances allocated using our functions + static void *operator new(size_t size) { + return pa_malloc(size); + } + static void operator delete(void *ptr) { + pa_free(ptr); + } + static void *malloc(size_t size) { + return pa_malloc(size); + } + static void *calloc(size_t size) { + return pa_calloc(size); + } + static void free(void *ptr) { + pa_free(ptr); + } + static void *realloc(void *ptr, size_t size) { + return pa_realloc(ptr, size); + } - /// the Pooled-sole: Pooled instances can be allocated in Pool rather then on heap - static void *operator new(size_t size, Pool& apool) { - return apool.malloc(size); - } - - Pooled(Pool& apool) : fpool(&apool) {} - - /// my pool - Pool& pool() const { return *fpool; } - - /** used for moving objects from one pool to another. - in between object can have no pool and can not be used - @see SQL_Driver_manager - */ - void set_pool(Pool *apool) { fpool=apool; } - - /// useful wrapper around pool - void *malloc(size_t size) const { return fpool->malloc(size); } - /// useful wrapper around pool - void *calloc(size_t size) const { return fpool->calloc(size); } - /// useful wrapper around pool - Exception& exception() const { return fpool->exception(); } }; -/// useful macro for creating objects on current Pooled object Pooled::pool() -#define NEW new(pool()) /** - Auto-object used for temporary changing Pool's exception(). - - Use by with these macros: - @code - TRY { - // ... - if(?) - THROW(?); - // ... - } CATCH(e) { - // code, using e fields - // e.comment() - } - END_CATCH - @endcode - - @see TRY, THROW + Base for all Parser classes, memory allocation/dallocation goes via pa_malloc/pa_free. */ -class Temp_exception { - Pool& fpool; - Exception *saved_exception; +class PA_Object: public PA_Allocated { + mutable unsigned long freferences; public: - Temp_exception(Pool& apool, Exception& exception) : - fpool(apool), - saved_exception(apool.set_exception(&exception)) { - } - ~Temp_exception() { - fpool.restore_exception(saved_exception); + PA_Object(): freferences(0) {} + virtual ~PA_Object() {} + + void ref() const { + freferences++; + } + void unref() const { + if(freferences) { + if(--freferences==0) + delete this; + } } }; +DECLARE_OBJECT_PTR(PA_Object); + +// convinient types -#define XTRY(pool) \ - { \ - Exception temp_exception; \ - Temp_exception le(pool, temp_exception); \ - if(setjmp(temp_exception.mark)==0) - -#define XTHROW(exception) exception._throw -#define XCATCH(e) \ - else{ \ - Exception& e=temp_exception; - -#define XEND_CATCH \ - } \ - } - -//@{ -/// @see Temp_exception -#define TRY XTRY(pool()) -#define THROW XTHROW(exception()) -#define CATCH(e) XCATCH(e) -#define END_CATCH XEND_CATCH - -#define PTRY XTRY(pool) -#define PTHROW XTHROW(pool.exception()) -#define PCATCH(e) XCATCH(e) -#define PEND_CATCH XEND_CATCH -//@} +typedef smart_ptr CharPtr; #endif