Diff for /parser3/src/include/pa_pool.h between versions 1.37 and 1.86.2.20

version 1.37, 2001/03/19 18:00:26 version 1.86.2.20, 2003/01/30 11:19:30
Line 1 Line 1
 /** @file  /** @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 <paf@design.ru> (http://design.ru/paf)          Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
   
         $Id$  
 */  */
   
 #ifndef PA_POOL_H  #ifndef PA_POOL_H
 #define PA_POOL_H  #define PA_POOL_H
   
 #include <stddef.h>  static const char* IDENT_POOL_H="$Date$";
   
   // include
   
   #include "pa_config_includes.h"
   
   #ifdef XML
   #       include "gdome.h"
   // for xmlChar
   #       include "libxml/tree.h"
   #endif
   
   // forwards
   
   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);
   
 class Exception;  class Exception;
 class Temp_exception;  class String;
   class Charset;
   class GdomeDOMString_auto_ptr;
   
 /**   /* * 
         Pool mechanizm allows users not to free up allocated memory,          Pool mechanizm allows users not to free up allocated memory,
         leaving that problem to 'pools'.          leaving that problem to 'pools'.
   
         Also holds Exception object, which can be temporary set using           @see Pooled
         Temp_exception auto-object.  * /
 */  
   
 class Pool {  class Pool {
         friend Temp_exception;  
 public:  public:
   
         Pool() : fexception(0) {}          Pool(void *astorage);
         ~Pool() {}  
           //{@ statistics
           size_t total_allocated() { return ftotal_allocated; }
           unsigned int total_times() { return ftotal_times; }
           //}@
   
         /// current exception object of the pool          void set_context(void *acontext) { fcontext=acontext; }
         Exception& exception() const { return *fexception; }          void *get_context() { return fcontext; }
   
         /// allocates some bytes on pool          /// allocates some bytes on pool
         void *malloc(size_t size) {          void *malloc(size_t size, int place=0) {
                 return check(real_malloc(size), size);                  return check(real_malloc(size, place), size);
         }          }
         /// allocates some bytes clearing them with zeros          /// allocates some bytes clearing them with zeros
         void *calloc(size_t size) {          void *calloc(size_t size) {
                 return check(real_calloc(size), size);                  return check(real_calloc(size), size);
         }          }
   
 private: // implementation defined          /// registers a routine to clean up non-pooled allocations
           void register_cleanup(void (*cleanup) (void *), void *data) {
                   if(!real_register_cleanup(cleanup, data))
                           fail_register_cleanup();
           }
   
           //{@ helpers
           void *copy(const void *buf, const size_t size);
           char *copy(const char *cstr);
           //}@
   
           //{@ source charset
           void set_source_charset(Charset& acharset);
           Charset& get_source_charset();
           //}@
   
           //{@ client charset
           void set_client_charset(Charset& charset);
           Charset& get_client_charset();
           //}@
   
   #ifdef XML
   
           /// @see Charset::transcode_cstr(xmlChar *s);
           const char *transcode_cstr(xmlChar *s);
           /// @see Charset::transcode(xmlChar *s);
           String& transcode(xmlChar *s
   #ifndef NO_STRING_ORIGIN
                   , const String *origin
   #endif
                   );
           /// @see Charset::transcode_cstr(GdomeDOMString *s);
           const char *transcode_cstr(GdomeDOMString *s);
           /// @see Charset::transcode(GdomeDOMString *s);
           String& transcode(GdomeDOMString *s
   #ifndef NO_STRING_ORIGIN
                   , const String *origin
   #endif
                   );
           /// @see Charset::transcode_cstr(const char *buf, size_t buf_size=0);
           xmlChar *transcode_buf2xchar(const char *buf, size_t buf_size=0);
           /// @see Charset::transcode(const String& s)
           GdomeDOMString_auto_ptr transcode(const String& s);
   
   #endif
   
   private:
   
     void *real_malloc(size_t size);          void *fstorage;
           void *fcontext;
           Charset *source_charset;
           Charset *client_charset;
   
   private: 
           
           //{
           /// @name implementation defined
       void *real_malloc(size_t size, int place);
     void *real_calloc(size_t size);      void *real_calloc(size_t size);
           bool real_register_cleanup(void (*cleanup) (void *), void *data);
           //}
   
 private:   private: 
   
         /// checks whether mem allocated OK. throws exception otherwise          /// checks whether mem allocated OK. throws exception otherwise
         void *check(void *ptr, size_t size) {          void *check(void *ptr, size_t size) {
                 if(ptr)                  if(ptr) {
                           ftotal_allocated+=size;
                           ftotal_times++;
                         return ptr;                          return ptr;
                   }
   
                 fail(size);                  fail_alloc(size);
   
                 // never reached                  // never reached
                 return 0;                  return 0;
         }          }
         /// throws proper exception          /// throws allocation exception
         void fail(size_t size) const;          void fail_alloc(size_t size) const;
   
 private: // exception handling  
   
         // exception replacement mechanism is 'protected' from direct usage  
         // Temp_exception object enforces paired set/restore  
         Exception *set_exception(Exception *e){  
                 Exception *r=fexception;  
                 fexception=e;  
                 return r;  
         }  
         void restore_exception(Exception *e) {  
                 fexception=e;  
         }  
   
 private:          /// throws register cleanup exception
           void fail_register_cleanup() const;
   
         // current request's exception object  private: // statistics
         Exception *fexception;          
           size_t ftotal_allocated;
           unsigned int ftotal_times;
   
 private: //disabled  private: //disabled
   
         // Pool(const Pool&) {}          Pool(const Pool&);
         Pool& operator = (const Pool&) { return *this; }          Pool& operator= (const Pool&);
 };  };
   */
   
   
 /**   /** 
         Base for all classes that are allocated in 'pools'.          Base for all classes that are allocated in 'pools'.
   
         Holds Pool object. Contains useful wrappers to it's methods.          Holds Pool object. Contains useful wrappers to it's methods.
 */  
           @see NEW
   * /
   
   // all classes that are members parents of packed class [String] 
   // sould be packed also to avoid sparc odd st/lduh problem
   #include "pa_pragma_pack_begin.h"
 class Pooled {  class Pooled {
         // the pool i'm allocated on          // the pool i'm allocated on
         Pool& fpool;          Pool *fpool;
 public:  public:
   
         /// the Pooled-sole: Pooled instances can be allocated in Pool rather then on heap          /// the Pooled-sole: Pooled instances can be allocated in Pool rather then on heap
         static void *operator new(size_t size, Pool& apool) {           static void *operator new(size_t size, Pool& apool) { 
                 return apool.malloc(size);                  return apool.malloc(size, 1);
         }          }
   
         Pooled(Pool& apool) : fpool(apool) {          Pooled(Pool& apool) : fpool(&apool) {}
         }  
   
         /// my pool          /// my pool
         Pool& pool() const { return fpool; }          Pool& pool() const { return *fpool; }
   
         /// useful wrapper around pool          /** used for moving objects from one pool to another. 
         void *malloc(size_t size) const { return fpool.malloc(size); }                  in between object can have no pool and can not be used
         /// useful wrapper around pool                  @see SQL_Driver_manager
         void *calloc(size_t size) const { return fpool.calloc(size); }          * /
         /// useful wrapper around pool          void set_pool(Pool *apool) { fpool=apool; }
         Exception& exception() const { return fpool.exception(); }  
           //{
           /// @name useful wrapper around pool
           void *malloc(size_t size, int place=0) const { return fpool->malloc(size, place); }
           void *calloc(size_t size) const { return fpool->calloc(size); }
           void register_cleanup(void (*cleanup) (void *), void *data) { fpool->register_cleanup(cleanup, data); }
           void *copy(const void *buf, const size_t size) { return fpool->copy(buf, size); }
           char *copy(const char *cstr) { return fpool->copy(cstr); }
   #ifdef XML
   
           const char *transcode_cstr(GdomeDOMString *s) { return fpool->transcode_cstr(s); }
           String& transcode(GdomeDOMString *s
   #ifndef NO_STRING_ORIGIN
                   , const String *origin
   #endif
                   ) { 
                   return fpool->transcode(s
   #ifndef NO_STRING_ORIGIN
                           , origin
   #endif          
                           ); 
           }
   
   #endif
           //}
 };  };
   #include "pa_pragma_pack_end.h"
 /// useful macro for creating objects on current Pooled object Pooled::pool()  /// useful macro for creating objects on current Pooled object Pooled::pool()
 #define NEW new(pool())  #define NEW new(pool())
   */
   
 /**   #define override
         Auto-object used for temporary changing Pool's exception().  #define rethrow throw
   
         Use by with these macros:  inline void *operator new(size_t size) { 
         \code          return pa_malloc(size);
                 TRY {   }
                         ...   inline void operator delete(void *ptr) {
                         if(?)           pa_free(ptr);
                                 THROW(?);   }
                         ...;  
                 } CATCH(e) {   class PA_Allocated {
                         code, using e fields  public:
                         e.comment()           /// the sole: instances allocated using our functions
                 }          static void *operator new(size_t size) { 
                 END_CATCH                  return pa_malloc(size);
         \endcode          }
           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 *realloc(void *ptr, size_t size) {
                   return pa_realloc(ptr, size);
           }
   
   };
   
   /** 
           Base for all Parser classes, memory allocation/dallocation goes via pa_malloc/pa_free.
 */  */
 class Temp_exception {  class PA_Object: public PA_Allocated {
         Pool& fpool;          mutable unsigned long freferences;
         Exception *saved_exception;  public:
 public:          PA_Object(): freferences(0) {}
         Temp_exception(Pool& apool, Exception& exception) :           virtual ~PA_Object()=0;
                 fpool(apool),           
                 saved_exception(apool.set_exception(&exception)) {          void ref() const {
                   freferences++;
         }          }
         ~Temp_exception() {           void unref() const {
                 fpool.restore_exception(saved_exception);                   if(freferences) {
                           if(--freferences==0)
                                   delete this;
                   }
         }          }
 };  };
   
 #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   
   
 #define RTHROW XTHROW(r.pool().exception())  template<typename T> class object_ptr {
 //@}          T *ptr;
   public:
           typedef T element_type;
   
           explicit object_ptr(T *ptr = 0) {
                   this->ptr=ptr;
                   if(ptr)
                           ptr->ref();
           }
           object_ptr(const object_ptr<T>& src) {
                   ptr=src.get();
                   ptr->ref();
           }
      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;
           }
           // so one could object_ptr<const T> = object_ptr<T>
           operator object_ptr<const T>() const{
                   return *this;
           }
           operator bool() const {
                   return get()!=0;
           }
           operator !() const {
                   return get()==0;
           }
   };
   
   #define DECLARE_OBJECT_PTR(name) \
           typedef object_ptr<name> name##Ptr
   
   //      typedef object_ptr<name> name##Ptr; \
   //      const object_ptr<name> name##PtrZero(0);
   
   /// TEMPLATE CLASS smart_ptr, stolen from stl:auto_ptr
   template<class T>
           class smart_ptr {
   public:
           typedef T element_type;
           explicit smart_ptr(T *_P = 0)
                   : _Owns(_P != 0), _Ptr(_P) {}
           smart_ptr(const smart_ptr<T>& _Y)
                   : _Owns(_Y._Owns), _Ptr(_Y.release()) {}
           smart_ptr<T>& operator=(const smart_ptr<T>& _Y)
                   {if (this != &_Y)
                           {if (_Ptr != _Y.get())
                                   {if (_Owns)
                                           delete _Ptr;
                                   _Owns = _Y._Owns; }
                           else if (_Y._Owns)
                                   _Owns = true;
                           _Ptr = _Y.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); }
           // so one could smart_ptr<const T> = smart_ptr<T>
           operator smart_ptr<const T>() const {
                   return *this;
           }
           operator bool() const {
                   return get()!=0;
           }
           operator T*() const {
                   return _Ptr;
           }
   private:
           bool _Owns;
           T *_Ptr;
           };
   
   // convinient types
   
   typedef smart_ptr<char> CharPtr;
   const CharPtr CharPtrZero(0);
   
 #endif  #endif

Removed from v.1.37  
changed lines
  Added in v.1.86.2.20


E-mail: