1 /*------------------------------------------------------------------------------
2 * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
3 *
4 * Distributable under the terms of either the Apache License (Version 2.0) or
5 * the GNU Lesser General Public License, as specified in the COPYING file.
6 ------------------------------------------------------------------------------*/
7 #ifndef _lucene_util_Array_
8 #define _lucene_util_Array_
9
10 #include <stdlib.h>
11 #include <string.h>
12
CL_NS_DEF(util)13 CL_NS_DEF(util)
14
15 template<typename T>
16 class CLUCENE_INLINE_EXPORT ArrayBase: LUCENE_BASE{
17 public:
18 T* values;
19 size_t length;
20
21 /**
22 * Delete's the values in the array.
23 * This won't do anything if deleteArray or takeArray is called first.
24 * This is overridden in various implementations to provide the appropriate deletor function.
25 */
26 virtual void deleteValues(){
27 if ( this->values == NULL )
28 return;
29 for (size_t i=0;i<this->length;i++){
30 deleteValue(this->values[i]);
31 }
32 }
33 /**
34 * Delete's a single value. Used when resizing...
35 */
36 virtual void deleteValue(T) = 0;
37
38 /**
39 * Delete's the values in the array and then calls deleteArray().
40 * This won't do anything if deleteArray or takeArray is called first.
41 * This is overridden in various implementations to provide the appropriate deletor function.
42 */
43 void deleteAll(){
44 this->deleteValues();
45 this->deleteArray();
46 }
47
48 /**
49 * Deletes the array holding the values. Do this if you want to take
50 * ownership of the array's values, but not the array containing the values.
51 */
52 void deleteArray(){
53 free(this->values);
54 this->values = NULL;
55 }
56 /**
57 * Empties the array. Do this if you want to take ownership of the array
58 * and the array's values.
59 */
60 T* takeArray(){
61 T* ret = values;
62 values = NULL;
63 return ret;
64 }
65
66 ArrayBase(const size_t initialLength = 0)
67 : values(NULL), length(initialLength)
68 {
69 if (initialLength > 0)
70 {
71 this->values = (T*)malloc(sizeof(T)*length);
72 memset(this->values,0,sizeof(T)*length);
73 }
74 }
75 ArrayBase(T* _values, const size_t _length)
76 : values(_values), length(_length)
77 {
78 }
79 virtual ~ArrayBase(){
80 }
81
82 const T& operator[](const size_t _Pos) const
83 {
84 if (length <= _Pos){
85 _CLTHROWA(CL_ERR_IllegalArgument,"vector subscript out of range");
86 }
87 return (*(values + _Pos));
88 }
89 T& operator[](const size_t _Pos)
90 {
91 if (length <= _Pos){
92 _CLTHROWA(CL_ERR_IllegalArgument,"vector subscript out of range");
93 }
94 return (*(values + _Pos));
95 }
96
97 /**
98 * Resize the array
99 * @param deleteValues if shrinking, delete the values that are lost.
100 */
101 void resize(const size_t newSize, const bool deleteValues=false){
102 if ( length == newSize ) return;
103
104 if ( values == NULL )
105 {
106 values = (T*)malloc(sizeof(T)*newSize);
107 memset(values,0,sizeof(T) * newSize);
108 length = newSize;
109 return;
110 }
111
112 if (length < newSize)
113 {
114 values = (T*)realloc(values, sizeof(T) * newSize);
115 memset(values + length,0,sizeof(T) * (newSize-length));
116 }
117 else // length > newSize, including newSize == 0
118 {
119 if ( deleteValues ){
120 for ( size_t i=newSize;i<length;i++ ){
121 deleteValue(values[i]);
122 }
123 }
124
125 if ( newSize == 0 )
126 {
127 free(values);
128 values = NULL;
129 }else{
130 // TODO: alternatively, we could store the actual array length without really shrinking it and
131 // by that save the deallocation process + possibly another realloc later
132 values = (T*)realloc(values, sizeof(T) * newSize);
133 }
134 }
135
136 length = newSize;
137 }
138 };
139
140 /**
141 * An array of objects. _CLDELETE is called on every contained object.
142 */
143 template<typename T>
144 class CLUCENE_INLINE_EXPORT ObjectArray: public ArrayBase<T*>{
145 public:
ObjectArray()146 ObjectArray():ArrayBase<T*>(){}
ObjectArray(T ** values,size_t length)147 ObjectArray(T** values, size_t length):ArrayBase<T*>(values,length){}
ObjectArray(size_t length)148 ObjectArray(size_t length):ArrayBase<T*>(length){}
149
deleteValues()150 void deleteValues(){
151 if ( this->values == NULL )
152 return;
153 for (size_t i=0;i<this->length;++i){
154 _CLLDELETE(this->values[i]);
155 }
156 this->deleteArray();
157 }
deleteUntilNULL()158 void deleteUntilNULL(){
159 if ( this->values == NULL )
160 return;
161 for (size_t i=0;i<this->length && this->values[i] != NULL;++i){
162 _CLLDELETE(this->values[i]);
163 }
164 this->deleteArray();
165 }
deleteValue(T * v)166 void deleteValue(T* v){
167 _CLLDELETE(v);
168 }
~ObjectArray()169 virtual ~ObjectArray(){
170 deleteValues();
171 }
172
173 /* Initializes all cells in the array with a NULL value */
initArray()174 void initArray(){
175 for (size_t i=0;i<this->length;i++){
176 this->values[i]=NULL;
177 }
178 }
179 };
180
181 /**
182 * Legacy code... don't use, remove all instances of this!
183 */
184 template<typename T>
185 class CLUCENE_INLINE_EXPORT Array: public ArrayBase<T>{
186 public:
_CL_DEPRECATED(ObjectArray or ValueArray)187 _CL_DEPRECATED(ObjectArray or ValueArray) Array():ArrayBase<T>(){}
Array(T * values,size_t length)188 _CL_DEPRECATED(ObjectArray or ValueArray) Array(T* values, size_t length):ArrayBase<T>(values,length){}
Array(size_t length)189 _CL_DEPRECATED(ObjectArray or ValueArray) Array(size_t length):ArrayBase<T>(length){}
deleteValues()190 void deleteValues(){
191 if ( this->values == NULL )
192 return;
193 this->deleteArray();
194 }
deleteValue(T v)195 void deleteValue(T v){} //nothing to do...
~Array()196 virtual ~Array(){
197 }
198 };
199
200 /**
201 * An array where the values do not need to be deleted
202 */
203 template<typename T>
204 class CLUCENE_INLINE_EXPORT ValueArray: public ArrayBase<T>{
205 public:
ValueArray()206 ValueArray():ArrayBase<T>(){}
ValueArray(T * values,size_t length)207 ValueArray(T* values, size_t length):ArrayBase<T>(values,length){}
ValueArray(size_t length)208 ValueArray(size_t length):ArrayBase<T>(length){}
209
deleteValues()210 void deleteValues(){
211 if ( this->values == NULL )
212 return;
213 this->deleteArray();
214 }
deleteValue(T)215 void deleteValue(T /*v*/){} //nothing to do...
~ValueArray()216 virtual ~ValueArray(){
217 deleteValues();
218 }
219 };
220
221 /** A value array for const values (never deleted) */
222 template<typename T>
223 class CLUCENE_INLINE_EXPORT ConstValueArray: public ArrayBase<T>{
224 public:
ConstValueArray()225 ConstValueArray():ArrayBase<T>(){}
ConstValueArray(T * values,size_t length)226 ConstValueArray(T* values, size_t length):ArrayBase<T>(values,length){}
ConstValueArray(size_t length)227 ConstValueArray(size_t length):ArrayBase<T>(length){}
228
deleteValues()229 void deleteValues(){}
deleteValue(T)230 void deleteValue(T /*v*/){} //nothing to do...
~ConstValueArray()231 virtual ~ConstValueArray(){}
232 };
233
234
235 /**
236 * An array of TCHAR strings
237 */
238 class CLUCENE_INLINE_EXPORT TCharArray: public ArrayBase<TCHAR*>{
239 public:
TCharArray()240 TCharArray():ArrayBase<TCHAR*>(){}
TCharArray(size_t length)241 TCharArray(size_t length):ArrayBase<TCHAR*>(length){}
242
deleteValues()243 void deleteValues(){
244 if ( this->values == NULL )
245 return;
246 for (size_t i=0;i<this->length;i++)
247 _CLDELETE_CARRAY(this->values[i]);
248 this->deleteArray();
249 }
deleteValue(TCHAR * v)250 void deleteValue(TCHAR* v){
251 _CLDELETE_LCARRAY(v);
252 }
~TCharArray()253 virtual ~TCharArray(){
254 deleteValues();
255 }
256 };
257
258 /**
259 * An array of char strings
260 */
261 class CLUCENE_INLINE_EXPORT CharArray: public ArrayBase<char*>{
262 public:
CharArray()263 CharArray():ArrayBase<char*>(){}
CharArray(size_t length)264 CharArray(size_t length):ArrayBase<char*>(length){}
265
deleteValues()266 void deleteValues(){
267 if ( this->values == NULL )
268 return;
269 for (size_t i=0;i<this->length;i++)
270 _CLDELETE_CaARRAY(this->values[i]);
271 this->deleteArray();
272 }
~CharArray()273 virtual ~CharArray(){
274 deleteValues();
275 }
276 };
277
278 /**
279 * An array of const TCHAR strings
280 */
281 class CLUCENE_INLINE_EXPORT TCharConstArray: public ArrayBase<const TCHAR*>{
282 public:
TCharConstArray()283 TCharConstArray():ArrayBase<const TCHAR*>(){}
TCharConstArray(size_t length)284 TCharConstArray(size_t length):ArrayBase<const TCHAR*>(length){}
285
deleteValues()286 void deleteValues(){
287 if ( this->values == NULL )
288 return;
289 this->deleteArray();
290 }
~TCharConstArray()291 virtual ~TCharConstArray(){
292 deleteValues();
293 }
294 };
295
296 /**
297 * An array of const char strings
298 */
299 class CLUCENE_INLINE_EXPORT CharConstArray: public ArrayBase<const char*>{
300 public:
CharConstArray()301 CharConstArray():ArrayBase<const char*>(){}
CharConstArray(size_t length)302 CharConstArray(size_t length):ArrayBase<const char*>(length){}
303
deleteValues()304 void deleteValues(){
305 if ( this->values == NULL )
306 return;
307 this->deleteArray();
308 }
~CharConstArray()309 virtual ~CharConstArray(){
310 deleteValues();
311 }
312 };
313
314 /** An array that uses _CLDECDELETE for deletion */
315 template<typename T>
316 class CLUCENE_INLINE_EXPORT RefCountArray: public ArrayBase<T>{
317 public:
RefCountArray()318 RefCountArray():ArrayBase<T>(){}
RefCountArray(T * values,size_t length)319 RefCountArray(T* values, size_t length):ArrayBase<T>(values,length){}
RefCountArray(size_t length)320 RefCountArray(size_t length):ArrayBase<T>(length){}
321
deleteValues()322 void deleteValues(){
323 if ( this->values == NULL )
324 return;
325 ArrayBase<T>::deleteValues();
326 this->deleteArray();
327 }
deleteValue(T v)328 void deleteValue(T v){
329 _CLDECDELETE(v);
330 } //nothing to do...
~RefCountArray()331 virtual ~RefCountArray(){
332 deleteValues();
333 }
334 };
335
336
337 CL_NS_END
338 #endif
339