Diff for /parser3/src/include/pa_pool.h between versions 1.35 and 1.88

version 1.35, 2001/03/19 16:44:00 version 1.88, 2003/11/07 13:59:21
Line 1 Line 1
 /** @file  /** @file
         Parser          Parser: pool class decl.
         Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)  
         Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)  
   
         $Id$          Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com)
   
           Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
 */  */
   
 #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$";
   
 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           @see Pooled
         Temp_exception auto-object.  
 */  */
   
 class Pool {  class Pool {
         friend Temp_exception;  
 public:  public:
   
         Pool() : fexception(0) {}          struct Cleanup {
         ~Pool() {}                  void (*cleanup) (void *);
                   void *data;
         /// current exception object of the pool  
         Exception& exception() const { return *fexception; }                  Cleanup(void (*acleanup) (void *), void *adata): cleanup(acleanup), data(adata) {}
           };
         /// allocates some bytes on pool  
         void *malloc(size_t size) {          Pool();
                 return check(real_malloc(size), size);          ~Pool();
         }  
         /// allocates some bytes clearing them with zeros          /// registers a routine to clean up non-pooled allocations
         void *calloc(size_t size) {          void register_cleanup(void (*cleanup) (void *), void *data);
                 return check(real_calloc(size), size);          /// 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.  
 */  */
 class Pooled {  class Pooled {
         // the pool i'm allocated on          // the pool i'm allocated on
         Pool& fpool;          Pool& fpool;
 public:  public:
           
         static void *operator new(size_t size, Pool& apool) {   
                 return apool.malloc(size);  
         }  
   
         Pooled(Pool& apool) : fpool(apool) {          Pooled(Pool& apool);
         }  
   
         /// my pool          /// my pool
         Pool& pool() const { return fpool; }          //Pool& pool() const { return *fpool; }
   
         /// useful wrapper around pool          /// Sole: this got called automatically from Pool::~Pool()
         void *malloc(size_t size) const { return fpool.malloc(size); }          virtual ~Pooled();
         /// 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:  
         \code  
                 TRY {   
                         ...   
                         if(?)   
                                 THROW(?);   
                         ...;  
                 } CATCH(e) {   
                         code, using e fields  
                         e.comment()   
                 }  
                 END_CATCH  
         \endcode  
 */  
 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.35  
changed lines
  Added in v.1.88


E-mail: