Diff for /parser3/src/include/pa_memory.h between versions 1.1.2.5 and 1.34

version 1.1.2.5, 2003/03/04 12:38:15 version 1.34, 2017/11/18 17:42:39
Line 1 Line 1
 /** @file  /** @file
         Parser: memory reference counting classes decls.          Parser: memory reference counting classes decls.
   
         Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001-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_MEMORY_H  #ifndef PA_MEMORY_H
 #define PA_MEMORY_H  #define PA_MEMORY_H
   
 static const char* IDENT_MEMORY_H="$Date$";  #define IDENT_PA_MEMORY_H "$Id$"
   
 // include  // include
   
 #include "pa_config_includes.h"  #include "pa_config_includes.h"
   #include "gc.h"
   #include <new>
   
 #ifdef XML  // define destructors use for Array, Hash and VMethodFrame
 #       include "gdome.h"  #define USE_DESTRUCTORS
 // for xmlChar  // std::basic_stringstream used in ^table.csv-string[] is compatible with delete usage check only under Debian 9
 #       include "libxml/tree.h"  // #define CHECK_DELETE_USAGE
 #endif  
   inline void* pa_gc_malloc(size_t size) { return GC_MALLOC(size); }
   inline void* pa_gc_malloc_atomic(size_t size) { return GC_MALLOC_ATOMIC(size); }
   inline void* pa_gc_realloc(void* ptr, size_t size) { return GC_REALLOC(ptr, size); }
   inline void pa_gc_free(void* ptr) { GC_FREE(ptr); }
   
 // forwards  // forwards
   
 void *pa_fail_alloc(char *what, size_t size);  void *pa_fail_alloc(const char* what, size_t size);
   
 // inlines  // inlines
   
 inline void *pa_malloc(size_t size) {  inline void *pa_malloc(size_t size) {
         if(void *result=malloc(size))          if(void *result=pa_gc_malloc(size))
                 return result;                  return result;
   
         return pa_fail_alloc("allocate", size);          return pa_fail_alloc("allocate", size);
 }  }
   
 inline void *pa_calloc(size_t size) {  inline void *pa_malloc_atomic(size_t size) {
         if(void *result=calloc(1, size))          if(void *result=pa_gc_malloc_atomic(size))
                 return result;                  return result;
   
         return pa_fail_alloc("allocate clean", size);          return pa_fail_alloc("allocate clean", size);
 }  }
   
   /// @a length may be null, which mean "autocalc it"
   inline char *pa_strdup(const char* auto_variable_never_null, size_t helper_length=0) {
           size_t known_length= helper_length ? helper_length : strlen(auto_variable_never_null);
   
           size_t size=known_length+1;
           if(char *result=static_cast<char*>(pa_gc_malloc_atomic(size))) {
                   memcpy(result, auto_variable_never_null, known_length);
                   result[known_length]=0;
                   return result;
           }
   
           return static_cast<char*>(pa_fail_alloc("allocate clean", size));
   }
   
 inline void pa_free(void *ptr) {  inline void pa_free(void *ptr) {
         free(ptr);          pa_gc_free(ptr);
 }  }
   
 inline void *pa_realloc(void *ptr, size_t size) {  inline void *pa_realloc(void *ptr, size_t size) {
         if(void *result=realloc(ptr, size))          if(void *result=pa_gc_realloc(ptr, size))
                 return result;                  return result;
   
         return pa_fail_alloc("reallocate to", size);          return pa_fail_alloc("reallocate to", size);
 }  }
   
 // forwards  /// memory allocation/dallocation goes via pa_malloc/pa_free.
   class PA_Allocated {
 class Exception;  
 class String;  
 class Charset;  
 class GdomeDOMString_auto_ptr;  
   
 template<typename T> class object_ptr {  
         T *ptr;  
 public:  public:
         typedef T element_type;          /// the sole: instances allocated using our functions
           static void *operator new(size_t size) {
         explicit object_ptr(T *ptr = 0) {                  return pa_malloc(size);
                 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 {          static void operator delete(void *ptr) {
                 return ptr;                  pa_free(ptr);
         }          }
         operator bool() const {          static void *operator new[](size_t size) {
                 return get()!=0;                  return pa_malloc(size);
         }          }
         bool operator !() const {          static void operator delete[](void *ptr) {
                 return get()==0;                  pa_free(ptr);
         }          }
 };  };
   
 #define DECLARE_OBJECT_PTR(name) \  // new(PointerFreeGC)/new(PointerGC) should be used to allocate types not inherited from PA_Allocated
         typedef object_ptr<name> name##Ptr  
   
 /// TEMPLATE CLASS smart_ptr, stolen  from stl:auto_ptr & renamed field/params [not compiled on gcc]  #define PointerFreeGC (true)
 template<class T>  #define PointerGC (false)
         class smart_ptr {  
         bool owns;  inline void *operator new[] (size_t size, bool pointer_free) {
         T *ptr;          return pointer_free ? pa_malloc_atomic(size) : pa_malloc(size);
 public:  }
         typedef T element_type;  
         explicit smart_ptr(T *aptr = 0)  inline void *operator new (size_t size, bool pointer_free) {
                 : owns(aptr != 0), ptr(aptr) {}          return pointer_free ? pa_malloc_atomic(size) : pa_malloc(size);
         smart_ptr(const smart_ptr<T>& src)  }
                 : owns(src.owns), ptr(src.release()) {}  
         smart_ptr<T>& operator=(const smart_ptr<T>& src)  /// Base for all Parser classes
                 {if (this != &src)  typedef PA_Allocated PA_Object;
                         {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;  
         }  
         bool operator !() const {  
                 return get()==0;  
         }  
         operator T*() const {  
                 return ptr;  
         }  
         };  
   
 // defines  // defines
   
 #define override  #define override
 #define rethrow throw  #define rethrow throw
   
 // memory  #if defined(_MSC_VER) || (__cplusplus>=201103L)
   #define PA_THROW(what)
   #else
   #define PA_THROW(what) throw(what)
   #endif
   
 inline void *operator new[] (size_t size) {  #ifndef _MSC_VER
         return pa_malloc(size);  
 }  
 inline void *operator new[] (size_t size, int /*zero, just flag to use calloc instead of malloc*/) {  
         return pa_calloc(size);  
 }  
 inline void operator delete[] (void *ptr) {  
         pa_free(ptr);  
 }  
 inline void operator delete (void *ptr) {  
         pa_free(ptr);  
 }  
   
 class PA_Allocated {  // regular new/delete are disabled from accidental use
 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);  
         }  
   
 };  void *new_disabled();
   void delete_disabled();
   
 /**   inline void *operator new[] (std::size_t) PA_THROW(std::bad_alloc){ return new_disabled(); }
         Base for all Parser classes, memory allocation/dallocation goes via pa_malloc/pa_free.  inline void operator delete[](void *) throw(){ delete_disabled(); }
 */  
 class PA_Object: public PA_Allocated {  
         mutable unsigned long freferences;  
 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  inline void *operator new(std::size_t) PA_THROW(std::bad_alloc){ return new_disabled(); }
   #ifdef CHECK_DELETE_USAGE
   inline void operator delete(void *) throw(){ delete_disabled(); }
   #endif
   
 typedef smart_ptr<char> CharPtr;  // other regular allocators as disabled from accidental use as well
   
   void *calloc_disabled();
   void *malloc_disabled();
   void *realloc_disabled();
   void free_disabled();
   char *strdup_disabled();
   
   inline void *calloc(size_t) { return calloc_disabled(); }
   inline void *malloc(size_t) { return malloc_disabled(); }
   inline void *realloc(void *, size_t) { return realloc_disabled(); }
   inline void free(void *) { free_disabled(); }
   inline char *strdup(const char*, size_t){ return strdup_disabled(); }
   
   #endif
   
 #endif  #endif

Removed from v.1.1.2.5  
changed lines
  Added in v.1.34


E-mail: