Diff for /parser3/src/include/pa_pool.h between versions 1.40 and 1.89

version 1.40, 2001/03/22 15:30:45 version 1.89, 2003/11/20 16:32:12
Line 1 Line 1
 /** @file  /** @file
         Parser: pool class decl.          Parser: pool class decl.
   
         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 * const IDENT_POOL_H="$Date$";
   
 class Exception;  #include "pa_config_includes.h"
 class Temp_exception;  #include "pa_array.h"
   
 /**   /** 
         Pool mechanizm allows users not to free up allocated memory,          Pool mechanizm allows users not to free up allocated objects,
         leaving that problem to 'pools'.          leaving that problem to 'pools'.
   
         Also holds Exception object, which can be temporary set using   
         Temp_exception auto-object.  
   
         @see Pooled          @see Pooled
 */  */
   
 class Pool {  class Pool {
         friend Temp_exception;  
 public:  public:
   
         Pool() : fstorage(0), fcontext(0), fexception(0) {}          struct Cleanup {
         ~Pool();                  void (*cleanup) (void *);
                   void *data;
   
         void set_storage(void *astorage) { fstorage=astorage; }                  Cleanup(void (*acleanup) (void *), void *adata): cleanup(acleanup), data(adata) {}
         void set_context(void *acontext) { fcontext=acontext; }          };
         void set_tag(void *atag) { ftag=atag; }  
   
         void *storage() { return fstorage; }  
         void *context() { return fcontext; }  
         void *tag() { return ftag; }  
   
         /// current exception object of the pool  
         Exception& exception() const { return *fexception; }  
   
         /// allocates some bytes on pool  
         void *malloc(size_t size) {  
                 return check(real_malloc(size), size);  
         }  
         /// allocates some bytes clearing them with zeros  
         void *calloc(size_t size) {  
                 return check(real_calloc(size), size);  
         }  
   
 private:          Pool();
           ~Pool();
   
         void *fstorage;          /// registers a routine to clean up non-pooled allocations
         void *fcontext;          void register_cleanup(void (*cleanup) (void *), void *data);
         void *ftag;          /// unregister it, looking it up by it's data
           void unregister_cleanup(void *cleanup_data);
   
 private: // implementation defined  private:
   
     void *real_malloc(size_t size);          Array<Cleanup> cleanups;
     void *real_calloc(size_t size);  
   
 private:   private: 
           
           //{
           /// @name implementation defined
           bool real_register_cleanup(void (*cleanup) (void *), void *data);
           //}
   
         /// checks whether mem allocated OK. throws exception otherwise  private: 
         void *check(void *ptr, size_t size) {  
                 if(ptr)  
                         return ptr;  
   
                 fail(size);  
   
                 // never reached  
                 return 0;  
         }  
         /// throws proper exception  
         void fail(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:  
   
         // current request's exception object          /// throws register cleanup exception
         Exception *fexception;          void fail_register_cleanup() const;
   
 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.
         Holds Pool object. Contains useful wrappers to it's methods.  
   
         @see NEW, Temp_exception  
 */  */
 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          Pooled(Pool& apool);
         static void *operator new(size_t size, Pool& apool) {   
                 return apool.malloc(size);  
         }  
   
         Pooled(Pool& apool) : fpool(apool) {  
         }  
   
         /// my pool          /// my pool
         Pool& pool() const { return fpool; }          //Pool& pool() const { return *fpool; }
   
         /// 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:          /// Sole: this got called automatically from Pool::~Pool()
         @code          virtual ~Pooled();
                 TRY {   
                         // ...   
                         if(?)   
                                 THROW(?);   
                         // ...  
                 } CATCH(e) {   
                         // code, using e fields  
                         // e.comment()   
                 }  
                 END_CATCH  
         @endcode  
   
         @see TRY, THROW  
 */  
 class Temp_exception {  
         Pool& fpool;  
         Exception *saved_exception;  
 public:  
         Temp_exception(Pool& apool, Exception& exception) :   
                 fpool(apool),  
                 saved_exception(apool.set_exception(&exception)) {  
         }  
         ~Temp_exception() {   
                 fpool.restore_exception(saved_exception);   
         }  
 };  };
   
 #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())  
 //@}  
   
 #endif  #endif

Removed from v.1.40  
changed lines
  Added in v.1.89


E-mail: