csutil/pooledscfclass.h
Go to the documentation of this file.00001 /* 00002 Copyright (C) 2004 by Jorrit Tyberghein 00003 (C) 2004 by Frank Richter 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public 00016 License along with this library; if not, write to the Free 00017 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 */ 00019 00020 #ifndef __CS_UTIL_POOLEDSCFCLASS_H__ 00021 #define __CS_UTIL_POOLEDSCFCLASS_H__ 00022 00031 #include "csutil/scf.h" 00032 00033 #include "csutil/custom_new_disable.h" 00034 00060 template<typename Super, typename Allocator = CS::Memory::AllocatorMalloc> 00061 class scfImplementationPooled : public Super 00062 { 00063 typedef typename Super::scfClassType scfClassType; 00064 public: 00065 typedef scfImplementationPooled<Super, Allocator> scfPooledImplementationType; 00066 00067 class Pool 00068 { 00069 friend class scfImplementationPooled<Super, Allocator>; 00070 struct Entry 00071 { 00072 Entry* next; 00073 }; 00074 CS::Memory::AllocatorPointerWrapper<Entry, Allocator> pool; 00075 size_t allocedEntries; 00076 public: 00077 Pool () : pool ((Entry*)0), allocedEntries (0) 00078 { 00079 } 00080 Pool (const Allocator& alloc) : pool (alloc, 0), allocedEntries (0) 00081 { 00082 } 00083 ~Pool () 00084 { 00085 while (pool.p != 0) 00086 { 00087 Entry* n = pool.p->next; 00088 pool.Free (pool.p); 00089 pool.p = n; 00090 } 00091 CS_ASSERT_MSG ("not all SCF-pooled instances released", 00092 allocedEntries == 0); 00093 } 00094 }; 00095 protected: 00097 Pool* scfPool; 00098 public: 00100 inline void* operator new (size_t n, Pool& p) 00101 { 00102 typedef typename Pool::Entry PoolEntry; 00103 CS_ASSERT_MSG ("Alloc size mismatches class size expected for pooled " 00104 "allocation", n == sizeof (scfClassType)); 00105 PoolEntry* newEntry; 00106 if (p.pool.p != 0) 00107 { 00108 newEntry = p.pool.p; 00109 p.pool.p = p.pool.p->next; 00110 } 00111 else 00112 { 00113 newEntry = static_cast<PoolEntry*> (p.pool.Alloc (n)); 00114 } 00115 p.allocedEntries++; 00116 scfClassType* newInst = reinterpret_cast<scfClassType*> (newEntry); 00117 /* A bit nasty: set scfPool member of the (still unconstructed!) 00118 * instance... */ 00119 static_cast<scfPooledImplementationType*> (newInst)->scfPool = &p; 00120 return newInst; 00121 } 00122 00124 00125 inline void operator delete (void* instance, Pool& p) 00126 { 00127 typedef typename Pool::Entry PoolEntry; 00128 PoolEntry* entry = static_cast<PoolEntry*> (instance); 00129 entry->next = p.pool.p; 00130 p.pool.p = entry; 00131 p.allocedEntries--; 00132 } 00133 inline void operator delete (void* instance) 00134 { 00135 scfClassType* object = static_cast<scfClassType*> (instance); 00136 Pool& p = *(static_cast<scfImplementationPooled*> (object)->scfPool); 00137 scfImplementationPooled::operator delete (object, p); 00138 } 00140 00142 void DecRef () 00143 { 00144 csRefTrackerAccess::TrackDecRef (this->scfObject, this->scfRefCount); 00145 this->scfRefCount--; 00146 if (this->scfRefCount == 0) 00147 { 00148 delete this->scfObject; 00149 } 00150 } 00151 00153 00156 scfImplementationPooled (scfClassType* object) : 00157 Super (object) {} 00158 template<typename A> 00159 scfImplementationPooled (scfClassType* object, A a) : 00160 Super (object, a) {} 00161 template<typename A, typename B> 00162 scfImplementationPooled (scfClassType* object, A a, B b) : 00163 Super (object, a, b) {} 00164 template<typename A, typename B, typename C> 00165 scfImplementationPooled (scfClassType* object, A a, B b, C c) : 00166 Super (object, a, b, c) {} 00167 template<typename A, typename B, typename C, typename D> 00168 scfImplementationPooled (scfClassType* object, A a, B b, C c, D d) : 00169 Super (object, a, b, c, d) {} 00170 template<typename A, typename B, typename C, typename D, typename E> 00171 scfImplementationPooled (scfClassType* object, A a, B b, C c, D d, E e) : 00172 Super (object, a, b, c, d, e) {} 00174 }; 00175 00178 #include "csutil/custom_new_enable.h" 00179 00180 #endif // __CS_UTIL_POOLEDSCFCLASS_H__
Generated for Crystal Space 1.2 by doxygen 1.4.7