Diff for /parser3/src/include/pa_pool.h between versions 1.49 and 1.93

version 1.49, 2001/04/04 10:50:34 version 1.93, 2017/11/15 22:48:57
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) 2000-2017 Art. Lebedev Studio (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>  #define IDENT_PA_POOL_H "$Id$"
   
 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 : public PA_Allocated {
         friend Temp_exception;  
 public:  public:
   
         Pool(void *astorage) : fstorage(astorage), fcontext(0), ftag(0), fexception(0) {}          struct Cleanup : public PA_Allocated {
                   void (*cleanup) (void *);
         void set_context(void *acontext) { fcontext=acontext; }                  void *data;
         void *context() { return fcontext; }  
                   Cleanup(void (*acleanup) (void *), void *adata): cleanup(acleanup), data(adata) {}
         void set_tag(void *atag) { ftag=atag; }          };
         void *tag() { return ftag; }  
           Pool();
         /// current exception object of the pool          ~Pool();
         Exception& exception() const { return *fexception; }  
           /// registers a routine to clean up non-pooled allocations
         /// allocates some bytes on pool          void register_cleanup(void (*cleanup) (void *), void *data);
         void *malloc(size_t size) {          /// unregister it, looking it up by it's data
                 return check(real_malloc(size), size);          void unregister_cleanup(void *cleanup_data);
         }  
         /// allocates some bytes clearing them with zeros  
         void *calloc(size_t size) {  
                 return check(real_calloc(size), size);  
         }  
   
 private:  private:
   
         void *fstorage;          Array<Cleanup> cleanups;
         void *fcontext;  
         void *ftag;  
   
 private: // implementation defined  
   
     void *real_malloc(size_t size);  
     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 'private'zed 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 : public PA_Allocated {
         // 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; }
   
         /** used for moving objects from one pool to another.           /// Sole: this got called automatically from Pool::~Pool()
                 in between object can have no pool and can not be used          virtual ~Pooled();
                 @see SQL_Driver_manager  
         */  
         void set_pool(Pool *apool) { fpool=apool; }  
   
         /// 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:  
         @code  
                 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   
 //@}  
   
 #endif  #endif

Removed from v.1.49  
changed lines
  Added in v.1.93


E-mail: