source: Sophya/trunk/Poubelle/DPC:FitsIOServer/Blitz/blitz/memblock.h@ 658

Last change on this file since 658 was 658, checked in by ansari, 26 years ago

no message

File size: 7.8 KB
Line 
1/***************************************************************************
2 * blitz/memblock.h MemoryBlock<T> and MemoryBlockReference<T>
3 *
4 * $Id: memblock.h,v 1.1.1.1 1999-11-26 16:37:04 ansari Exp $
5 *
6 * Copyright (C) 1997,1998 Todd Veldhuizen <tveldhui@seurat.uwaterloo.ca>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * Suggestions: blitz-suggest@cybervision.com
19 * Bugs: blitz-bugs@cybervision.com
20 *
21 * For more information, please see the Blitz++ Home Page:
22 * http://seurat.uwaterloo.ca/blitz/
23 *
24 ***************************************************************************
25 * $Log: not supported by cvs2svn $
26 * Revision 1.1.1.1 1999/04/09 17:58:59 ansari
27 * Creation module DPC/Blitz (blitz 0.4) Reza 09/04/99
28 *
29 * Revision 1.7 1998/06/15 16:07:01 tveldhui
30 * When a memory block is created from an existing block of data,
31 * add an additional reference count so that makeUnique() will
32 * create a copy of the data.
33 *
34 * Revision 1.6 1998/03/14 00:04:47 tveldhui
35 * 0.2-alpha-05
36 *
37 * Revision 1.5 1997/07/16 14:51:20 tveldhui
38 * Update: Alpha release 0.2 (Arrays)
39 *
40 * Revision 1.4 1997/01/24 14:42:00 tveldhui
41 * Periodic RCS update
42 *
43 * Revision 1.3 1997/01/23 03:28:28 tveldhui
44 * Periodic RCS update
45 *
46 * Revision 1.2 1997/01/13 22:19:58 tveldhui
47 * Periodic RCS update
48 *
49 * Revision 1.1 1996/11/11 17:29:13 tveldhui
50 * Initial revision
51 *
52 *
53 ***************************************************************************
54 *
55 */
56
57#ifndef __BZ_MEMBLOCK_H__
58#define __BZ_MEMBLOCK_H__
59
60#ifndef BZ_BLITZ_H
61 #include <blitz/blitz.h>
62#endif
63
64#include <stddef.h> // ptrdiff_t
65
66BZ_NAMESPACE(blitz)
67
68// Forward declaration of MemoryBlockReference
69template<class T_type> class MemoryBlockReference;
70
71// Class MemoryBlock provides a reference-counted block of memory. This block
72// may be referred to by multiple vector, matrix and array objects. The memory
73// is automatically deallocated when the last referring object is destructed.
74// MemoryBlock may be subclassed to provide special allocators.
75template<class P_type>
76class MemoryBlock {
77
78 friend class MemoryBlockReference<P_type>;
79
80public:
81 typedef P_type T_type;
82
83protected:
84 MemoryBlock()
85 {
86 length_ = 0;
87 data_ = 0;
88 dataBlockAddress_ = 0;
89 references_ = 0;
90 ownData_ = 0;
91 }
92
93 _bz_explicit MemoryBlock(size_t items)
94 {
95 length_ = items;
96 allocate(length_);
97
98#ifdef BZ_DEBUG_LOG_ALLOCATIONS
99 cout << "MemoryBlock: allocated " << setw(8) << length_
100 << " at " << ((void *)dataBlockAddress_) << endl;
101#endif
102
103 BZASSERT(dataBlockAddress_ != 0);
104
105 references_ = 0;
106 ownData_ = 1;
107 }
108
109 MemoryBlock(size_t length, T_type* _bz_restrict data)
110 {
111 length_ = length;
112 data_ = data;
113 dataBlockAddress_ = 0;
114 references_ = 0;
115 ownData_ = 0;
116 }
117
118 virtual ~MemoryBlock()
119 {
120 if ((dataBlockAddress_) && (ownData_))
121 {
122
123#ifdef BZ_DEBUG_LOG_ALLOCATIONS
124 cout << "MemoryBlock: freed " << setw(8) << length_
125 << " at " << ((void *)dataBlockAddress_) << endl;
126#endif
127
128 delete [] dataBlockAddress_;
129 }
130 }
131
132 void addReference()
133 {
134 ++references_;
135
136#ifdef BZ_DEBUG_LOG_REFERENCES
137 cout << "MemoryBlock: reffed " << setw(8) << length_
138 << " at " << ((void *)dataBlockAddress_) << " (r="
139 << references_ << ")" << endl;
140#endif
141
142 }
143
144 T_type* _bz_restrict data()
145 {
146 return data_;
147 }
148
149 const T_type* _bz_restrict data() const
150 {
151 return data_;
152 }
153
154 size_t length() const
155 {
156 return length_;
157 }
158
159 void removeReference()
160 {
161 --references_;
162
163#ifdef BZ_DEBUG_LOG_REFERENCES
164 cout << "MemoryBlock: dereffed " << setw(8) << length_
165 << " at " << ((void *)dataBlockAddress_) << " (r=" << references_
166 << ")" << endl;
167#endif
168
169 if (!references_)
170 delete this;
171 }
172
173 int references() const
174 {
175 return references_;
176 }
177
178protected:
179 inline void allocate(int length);
180
181private: // Disabled member functions
182 MemoryBlock(const MemoryBlock<T_type>&)
183 { }
184
185 void operator=(const MemoryBlock<T_type>&)
186 { }
187
188private: // Data members
189 T_type * _bz_restrict data_;
190 T_type * _bz_restrict dataBlockAddress_;
191 int references_;
192 size_t length_;
193 int ownData_;
194};
195
196template<class P_type>
197class NullMemoryBlock : public MemoryBlock<P_type> {
198public:
199 NullMemoryBlock()
200 {
201 // This ensures that the delete operator will not be invoked
202 // on an instance of NullMemoryBlock in removeReference().
203 this->addReference();
204 }
205
206 virtual ~NullMemoryBlock()
207 { }
208};
209
210template<class P_type>
211class MemoryBlockReference {
212
213public:
214 typedef P_type T_type;
215
216 MemoryBlockReference()
217 {
218 block_ = &nullBlock_;
219 block_->addReference();
220
221#ifndef BZ_TEMPLATE_STATIC_INIT
222 // This compiler doesn't handle static initialization
223 // and templates properly. Give the NullMemoryBlock
224 // another reference to make sure it doesn't delete
225 // itself and cause a seg fault when we dereference it.
226 block_->addReference();
227#endif
228
229 data_ = 0;
230 }
231
232 MemoryBlockReference(MemoryBlockReference<T_type>& ref)
233 {
234 block_ = ref.block_;
235 block_->addReference();
236 data_ = block_->data();
237 }
238
239 MemoryBlockReference(MemoryBlockReference<T_type>& ref, size_t offset)
240 {
241 block_ = ref.block_;
242 block_->addReference();
243 data_ = block_->data() + offset;
244 }
245
246 MemoryBlockReference(size_t length, T_type* data)
247 {
248 // Create a memory block using already allocated memory. Note
249 // that the memory will not be freed when no longer being
250 // referenced.
251 block_ = new MemoryBlock<T_type>(length, data);
252 block_->addReference();
253
254 // This extra reference indicates that another object somewhere
255 // has a pointer to the data. This is necessary so that makeUnique()
256 // will create a copy of the data. -- TV 19980615
257 block_->addReference();
258 data_ = data;
259 }
260
261 _bz_explicit MemoryBlockReference(size_t items)
262 {
263 block_ = new MemoryBlock<T_type>(items);
264 block_->addReference();
265 data_ = block_->data();
266 }
267
268 ~MemoryBlockReference()
269 {
270 block_->removeReference();
271 }
272
273 int numReferences() const
274 {
275 return block_->references();
276 }
277
278protected:
279
280 void changeToNullBlock()
281 {
282 block_->removeReference();
283 block_ = &nullBlock_;
284 block_->addReference();
285 data_ = 0;
286 }
287
288 void changeBlock(MemoryBlockReference<T_type>& ref, size_t offset)
289 {
290 block_->removeReference();
291 block_ = ref.block_;
292 block_->addReference();
293 data_ = block_->data() + offset;
294 }
295
296 void newBlock(size_t items)
297 {
298 block_->removeReference();
299 block_ = new MemoryBlock<T_type>(items);
300 block_->addReference();
301 data_ = block_->data();
302 }
303
304private:
305 void operator=(const MemoryBlockReference<T_type>&)
306 { }
307
308private:
309 MemoryBlock<T_type>* block_;
310 static NullMemoryBlock<T_type> nullBlock_;
311
312protected:
313 T_type * _bz_restrict data_;
314};
315
316
317BZ_NAMESPACE_END
318
319#include <blitz/memblock.cc>
320
321#endif // __BZ_MEMBLOCK_H__
Note: See TracBrowser for help on using the repository browser.