Annotation of parser3/src/include/pa_memory.h, revision 1.1.2.9

1.1.2.1   paf         1: /** @file
                      2:        Parser: memory reference counting classes decls.
                      3: 
                      4:        Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)
                      5: 
                      6:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
                      7: */
                      8: 
                      9: #ifndef PA_MEMORY_H
                     10: #define PA_MEMORY_H
                     11: 
1.1.2.9 ! paf        12: static const char* IDENT_MEMORY_H="$Date: 2003/03/06 16:15:25 $";
        !            13: 
        !            14: #define PA_DEBUG_REFERENCES
1.1.2.1   paf        15: 
                     16: // include
                     17: 
                     18: #include "pa_config_includes.h"
                     19: 
                     20: #ifdef XML
                     21: #      include "gdome.h"
                     22: // for xmlChar
                     23: #      include "libxml/tree.h"
                     24: #endif
                     25: 
                     26: // forwards
                     27: 
1.1.2.2   paf        28: void *pa_fail_alloc(char *what, size_t size);
                     29: 
                     30: // inlines
                     31: 
                     32: inline void *pa_malloc(size_t size) {
                     33:        if(void *result=malloc(size))
                     34:                return result;
                     35: 
                     36:        return pa_fail_alloc("allocate", size);
                     37: }
                     38: 
                     39: inline void *pa_calloc(size_t size) {
                     40:        if(void *result=calloc(1, size))
                     41:                return result;
                     42: 
                     43:        return pa_fail_alloc("allocate clean", size);
                     44: }
                     45: inline void pa_free(void *ptr) {
                     46:        free(ptr);
                     47: }
                     48: 
                     49: inline void *pa_realloc(void *ptr, size_t size) {
                     50:        if(void *result=realloc(ptr, size))
                     51:                return result;
                     52: 
                     53:        return pa_fail_alloc("reallocate to", size);
                     54: }
1.1.2.1   paf        55: 
                     56: template<typename T> class object_ptr {
                     57:        T *ptr;
                     58: public:
                     59:        typedef T element_type;
                     60: 
                     61:        explicit object_ptr(T *ptr = 0) {
                     62:                this->ptr=ptr;
                     63:                if(ptr)
                     64:                        ptr->ref();
                     65:        }
                     66:        template<class B> object_ptr(const object_ptr<B>& src) {
                     67:                this->ptr=src.get();
                     68:                if(ptr)
                     69:                        ptr->ref();
                     70:        }
                     71:        object_ptr(const object_ptr<T>& src) {
                     72:                ptr=src.get();
                     73:                if(ptr)
                     74:                        ptr->ref();
                     75:        }
                     76:        object_ptr(T *ptr, int) {
                     77:                this->ptr=ptr;
                     78:        }
                     79:    object_ptr<T>& operator=(const object_ptr<T>& src) {
                     80:                if(this!=&src)
                     81:                        if(ptr!=src.get()) {
                     82:                                if(ptr)
                     83:                                        ptr->unref();
                     84:                                ptr=src.get();
                     85:                                if(ptr)
                     86:                                        ptr->ref();
                     87:                        }
                     88:                return *this;
                     89:        }
                     90:     ~object_ptr() {
                     91:                if(ptr)
                     92:                        ptr->unref();
                     93:        }
                     94:     T& operator*() const {
                     95:                return *get();
                     96:        }
                     97:     T *operator->() const {
                     98:                return get();
                     99:        }
                    100:     T *get() const {
                    101:                return ptr;
                    102:        }
                    103:        operator bool() const {
                    104:                return get()!=0;
                    105:        }
                    106:        bool operator !() const {
                    107:                return get()==0;
                    108:        }
                    109: };
                    110: 
                    111: #define DECLARE_OBJECT_PTR(name) \
                    112:        typedef object_ptr<name> name##Ptr
                    113: 
                    114: /// TEMPLATE CLASS smart_ptr, stolen  from stl:auto_ptr & renamed field/params [not compiled on gcc]
                    115: template<class T>
                    116:        class smart_ptr {
                    117:        bool owns;
                    118:        T *ptr;
                    119: public:
                    120:        typedef T element_type;
                    121:        explicit smart_ptr(T *aptr = 0)
                    122:                : owns(aptr != 0), ptr(aptr) {}
                    123:        smart_ptr(const smart_ptr<T>& src)
                    124:                : owns(src.owns), ptr(src.release()) {}
                    125:        smart_ptr<T>& operator=(const smart_ptr<T>& src)
                    126:                {if (this != &src)
                    127:                        {if (ptr != src.get())
                    128:                                {if (owns)
1.1.2.5   paf       129:                                        delete[] ptr;
1.1.2.1   paf       130:                                owns = src.owns; }
                    131:                        else if (src.owns)
                    132:                                owns = true;
                    133:                        ptr = src.release(); }
                    134:                return (*this); }
                    135:        ~smart_ptr()
                    136:                {if (owns)
1.1.2.5   paf       137:                        delete[] ptr; }
1.1.2.1   paf       138:        T& operator*() const
                    139:                {return (*get()); }
                    140:        T *get() const
                    141:                {return ptr; }
                    142:        T *release() const
                    143:                {((smart_ptr<T> *)this)->owns = false;
                    144:                return (ptr); }
                    145:        operator bool() const {
                    146:                return get()!=0;
1.1.2.4   paf       147:        }
                    148:        bool operator !() const {
                    149:                return get()==0;
1.1.2.1   paf       150:        }
                    151:        operator T*() const {
                    152:                return ptr;
                    153:        }
                    154:        };
1.1.2.6   paf       155: 
                    156: #define DECLARE_SMART_PTR(name) \
                    157:        typedef smart_ptr<name> name##Ptr
1.1.2.1   paf       158: 
                    159: // defines
                    160: 
                    161: #define override
                    162: #define rethrow throw
                    163: 
                    164: // memory
                    165: 
                    166: inline void *operator new[] (size_t size) {
                    167:        return pa_malloc(size);
1.1.2.3   paf       168: }
                    169: inline void *operator new[] (size_t size, int /*zero, just flag to use calloc instead of malloc*/) {
                    170:        return pa_calloc(size);
1.1.2.1   paf       171: }
                    172: inline void operator delete[] (void *ptr) {
                    173:        pa_free(ptr);
                    174: }
                    175: inline void operator delete (void *ptr) {
                    176:        pa_free(ptr);
                    177: }
                    178: 
                    179: class PA_Allocated {
                    180: public:
                    181:        /// the sole: instances allocated using our functions
                    182:        static void *operator new(size_t size) { 
                    183:                return pa_malloc(size);
                    184:        }
                    185:        static void operator delete(void *ptr) {
                    186:                pa_free(ptr);
                    187:        }
                    188:        static void *malloc(size_t size) {
                    189:                return pa_malloc(size);
                    190:        }
                    191:        static void *calloc(size_t size) {
                    192:                return pa_calloc(size);
                    193:        }
                    194:        static void free(void *ptr) {
                    195:                pa_free(ptr);
                    196:        }
                    197:        static void *realloc(void *ptr, size_t size) {
                    198:                return pa_realloc(ptr, size);
                    199:        }
                    200: 
                    201: };
                    202: 
1.1.2.9 ! paf       203: #ifdef PA_DEBUG_REFERENCES
        !           204: extern const void *refdbg_this;
        !           205: void pa_stack_dump(const char *msg);
        !           206: #endif
        !           207: 
1.1.2.1   paf       208: /** 
                    209:        Base for all Parser classes, memory allocation/dallocation goes via pa_malloc/pa_free.
                    210: */
                    211: class PA_Object: public PA_Allocated {
                    212:        mutable unsigned long freferences;
                    213: public:
                    214:        PA_Object(): freferences(0) {}
                    215:        virtual ~PA_Object() {}
                    216:         
                    217:        void ref() const {
1.1.2.9 ! paf       218: #ifdef PA_DEBUG_REFERENCES
        !           219:                if(this==refdbg_this) {
        !           220:                        char buf[0x400];
        !           221:                        _snprintf(buf, sizeof(buf), "[0x%p#%d++]\n", this, freferences);
        !           222:                        pa_stack_dump(buf);                     
        !           223:                }
        !           224: #endif
1.1.2.1   paf       225:                freferences++;
                    226:        }
                    227:        void unref() const {
                    228:                if(freferences) {
1.1.2.9 ! paf       229: #ifdef PA_DEBUG_REFERENCES
        !           230:                        if(this==refdbg_this) {
        !           231:                                char buf[0x400];
        !           232:                                _snprintf(buf, sizeof(buf), "[0x%p#%d--]\n", this, freferences);
        !           233:                                pa_stack_dump(buf);
        !           234:                        }
        !           235: #endif
1.1.2.1   paf       236:                        if(--freferences==0)
                    237:                                delete this;
                    238:                }
                    239:        }
1.1.2.7   paf       240:        unsigned long references() { return freferences; }
1.1.2.1   paf       241: };
                    242: DECLARE_OBJECT_PTR(PA_Object);
                    243: 
                    244: // convinient types
                    245: 
                    246: typedef smart_ptr<char> CharPtr;
                    247: 
                    248: #endif

E-mail: