|
|
1.1 parser 1: /** @file
2: Parser: CGI: pool storage class decl.
3:
4: Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
5: Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
6:
1.4 ! parser 7: $Id: pool_storage.h,v 1.3 2001/10/24 16:32:07 parser Exp $
1.1 parser 8: */
9:
10: #ifndef PA_POOL_STORAGE_H
11: #define PA_POOL_STORAGE_H
12:
13: #include "pa_config_includes.h"
14:
15: /**
16: Dumb pool allocations accounter
17:
18: @todo implement at least simple suballocations
19: */
20:
1.4 ! parser 21: template<class T> class List {
! 22: public:
! 23: List(int preallocate) :
! 24: items((T *)::malloc(preallocate*sizeof(T))),
! 25: allocated(0),
! 26: used(0) {
! 27: if(items) // successfully preallocated?
! 28: allocated=preallocate;
! 29: }
1.2 parser 30:
1.4 ! parser 31: ~List() {
! 32: ::free(items);
! 33: }
1.1 parser 34:
1.4 ! parser 35: bool add(T item) {
! 36: if(full())
! 37: if(!expand())
! 38: return false;
! 39:
! 40: items[used++]=item;
! 41: return true;
! 42: }
! 43:
! 44: void for_each_reverse(void (*callback)(T& info)) {
! 45: size_t top;
! 46:
! 47: for(top=used; top; )
! 48: callback(items[--top]);
! 49: }
! 50:
! 51: private:
! 52:
! 53: bool full() { return used==allocated; }
! 54: bool expand() {
! 55: size_t new_allocated=allocated*3/2;
! 56: T *new_items=(T *)::realloc(items, new_allocated*sizeof(T));
! 57: if(new_items) {
! 58: items=new_items;
! 59: allocated=new_allocated;
1.1 parser 60: return true;
1.4 ! parser 61: } else
! 62: return false;
! 63: }
1.1 parser 64:
1.4 ! parser 65: private:
1.1 parser 66:
1.4 ! parser 67: T *items;
! 68: size_t allocated;
! 69: size_t used;
1.1 parser 70:
1.4 ! parser 71: };
1.1 parser 72:
1.2 parser 73: class Pool_storage {
1.1 parser 74: struct Cleanup_struct {
75: void (*cleanup) (void *);
76: void *data;
77: };
78:
79:
80: public:
81:
82: Pool_storage() :
83: cleanups(100) {
84: }
85:
86: bool register_cleanup(void (*cleanup) (void *), void *data) {
87: Cleanup_struct item={cleanup, data};
88: return cleanups.add(item)!=0;
89: }
90:
1.4 ! parser 91: static void cleanup(Cleanup_struct& item) {
! 92: item.cleanup(item.data);
! 93: }
! 94:
1.1 parser 95: ~Pool_storage() {
96: // cleanups first, because they use some object's memory pointers
1.4 ! parser 97: cleanups.for_each_reverse(cleanup);
1.1 parser 98: }
99:
100: private:
101:
102: List<Cleanup_struct> cleanups;
103:
104: };
105:
106:
107: #endif