|
|
| version 1.86.2.30, 2003/02/19 16:19:00 | version 1.94, 2017/11/18 17:19:27 |
|---|---|
| Line 1 | Line 1 |
| /** @file | /** @file |
| Parser: Parser: reference counting classes decls. | Parser: pool class decl. |
| Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com) | Copyright (c) 2000-2017 Art. Lebedev Studio (http://www.artlebedev.com) |
| Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) | Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) |
| */ | */ |
| Line 9 | Line 9 |
| #ifndef PA_POOL_H | #ifndef PA_POOL_H |
| #define PA_POOL_H | #define PA_POOL_H |
| static const char* IDENT_POOL_H="$Date$"; | #define IDENT_PA_POOL_H "$Id$" |
| // include | |
| #include "pa_config_includes.h" | #include "pa_config_includes.h" |
| #include "pa_array.h" | |
| #ifdef XML | /** |
| # include "gdome.h" | Pool mechanizm allows users not to free up allocated objects, |
| // for xmlChar | leaving that problem to 'pools'. |
| # include "libxml/tree.h" | |
| #endif | |
| // forwards | |
| void *pa_malloc(size_t size); | @see Pooled |
| void *pa_calloc(size_t size); | */ |
| void pa_free(void *ptr); | |
| void *pa_realloc(void *ptr, size_t size); | |
| class Exception; | |
| class String; | |
| class Charset; | |
| class GdomeDOMString_auto_ptr; | |
| template<typename T> class object_ptr { | class Pool { |
| T *ptr; | |
| public: | public: |
| typedef T element_type; | |
| explicit object_ptr(T *ptr = 0) { | |
| this->ptr=ptr; | |
| if(ptr) | |
| ptr->ref(); | |
| } | |
| template<class B> object_ptr(const object_ptr<B>& src) { | |
| this->ptr=src.get(); | |
| if(ptr) | |
| ptr->ref(); | |
| } | |
| object_ptr(const object_ptr<T>& src) { | |
| ptr=src.get(); | |
| if(ptr) | |
| ptr->ref(); | |
| } | |
| object_ptr(T *ptr, int) { | |
| this->ptr=ptr; | |
| } | |
| object_ptr<T>& operator=(const object_ptr<T>& 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; | |
| } | |
| }; | |
| #define DECLARE_OBJECT_PTR(name) \ | struct Cleanup : public PA_Allocated { |
| typedef object_ptr<name> name##Ptr | void (*cleanup) (void *); |
| void *data; | |
| /// TEMPLATE CLASS smart_ptr, stolen from stl:auto_ptr & renamed field/params [not compiled on gcc] | Cleanup(void (*acleanup) (void *), void *adata): cleanup(acleanup), data(adata) {} |
| template<class T> | |
| 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<T>& src) | |
| : owns(src.owns), ptr(src.release()) {} | |
| smart_ptr<T>& operator=(const smart_ptr<T>& 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<T> *)this)->owns = false; | |
| return (ptr); } | |
| operator bool() const { | |
| return get()!=0; | |
| } | |
| operator T*() const { | |
| return ptr; | |
| } | |
| }; | }; |
| // defines | Pool(); |
| ~Pool(); | |
| #define override | /// registers a routine to clean up non-pooled allocations |
| #define rethrow throw | void register_cleanup(void (*cleanup) (void *), void *data); |
| /// unregister it, looking it up by it's data | |
| void unregister_cleanup(void *cleanup_data); | |
| // memory | private: |
| inline void *operator new[] (size_t size) { | Array<Cleanup> cleanups; |
| return pa_malloc(size); | |
| } | |
| inline void operator delete[] (void *ptr) { | |
| pa_free(ptr); | |
| } | |
| inline void operator delete (void *ptr) { | |
| pa_free(ptr); | |
| } | |
| class PA_Allocated { | private: |
| public: | |
| /// the sole: instances allocated using our functions | //{ |
| static void *operator new(size_t size) { | /// @name implementation defined |
| return pa_malloc(size); | bool real_register_cleanup(void (*cleanup) (void *), void *data); |
| } | //} |
| static void operator delete(void *ptr) { | |
| pa_free(ptr); | private: |
| } | |
| static void *malloc(size_t size) { | /// throws register cleanup exception |
| return pa_malloc(size); | void fail_register_cleanup() const; |
| } | |
| static void *calloc(size_t size) { | private: //disabled |
| 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); | |
| } | |
| Pool(const Pool&); | |
| Pool& operator= (const Pool&); | |
| }; | }; |
| /** | /** |
| Base for all Parser classes, memory allocation/dallocation goes via pa_malloc/pa_free. | Base for all classes that are allocated in 'pools'. |
| Holds Pool object. | |
| */ | */ |
| class PA_Object: public PA_Allocated { | class Pooled { |
| mutable unsigned long freferences; | // the pool i'm allocated on |
| Pool& fpool; | |
| public: | public: |
| 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 | Pooled(Pool& apool); |
| /// my pool | |
| //Pool& pool() const { return *fpool; } | |
| typedef smart_ptr<char> CharPtr; | /// Sole: this got called automatically from Pool::~Pool() |
| virtual ~Pooled(); | |
| }; | |
| #endif | #endif |