xref: /trunk/main/sfx2/inc/sfx2/minarray.hxx (revision 353d8f4d)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #ifndef _SFXVARARR_HXX
24 #define _SFXVARARR_HXX
25 
26 #include "sal/config.h"
27 #include "sfx2/dllapi.h"
28 
29 #include <limits.h>
30 #include <string.h>
31 #include <tools/solar.h>
32 #include <tools/debug.hxx>
33 //#include "typecast.hxx"
34 
35 #if defined (ALPHA) && defined (UNX)
36 #define DEL_ARRAY( X )
37 #else
38 #define DEL_ARRAY( X ) X
39 #endif
40 
41 #define DECL_OBJARRAY( ARR, T, nI, nG ) \
42 class ARR\
43 {\
44 private:\
45 	T*	 pData;\
46     sal_uInt16  nUsed;\
47 	sal_uInt8	nGrow;\
48     sal_uInt8    nUnused;\
49 public:\
50 	ARR( sal_uInt8 nInitSize = nI, sal_uInt8 nGrowSize = nG );\
51 	ARR( const ARR& rOrig );\
52 	~ARR();\
53 \
54 	ARR& operator= ( const ARR& rOrig );\
55 \
56 	const T& GetObject( sal_uInt16 nPos ) const; \
57 	T& GetObject( sal_uInt16 nPos ); \
58 \
59 	void Insert( sal_uInt16 nPos, ARR& rIns, sal_uInt16 nStart = 0, sal_uInt16 nEnd = USHRT_MAX );\
60 	void Insert( sal_uInt16 nPos, const T& rElem );\
61 	void Insert( sal_uInt16 nPos, const T& rElems, sal_uInt16 nLen );\
62 	void Append( const T& rElem );\
63 \
64 	sal_Bool Remove( const T& rElem );\
65 	sal_uInt16 Remove( sal_uInt16 nPos, sal_uInt16 nLen );\
66 \
67 	sal_uInt16 Count() const { return nUsed; }\
68 	T* operator*();\
69 	const T& operator[]( sal_uInt16 nPos ) const;\
70 	T& operator[]( sal_uInt16 nPos );\
71 \
72 	sal_Bool Contains( const T& rItem ) const;\
73 	void Clear() { Remove( 0, Count() ); }\
74 };\
75 \
76 inline void ARR::Insert( sal_uInt16 nPos, ARR& rIns, sal_uInt16 nStart, sal_uInt16 nEnd )\
77 {\
78 	Insert( nPos, *(rIns.pData+(sizeof(T)*nStart)), nStart-nEnd+1 );\
79 }\
80 \
81 inline void ARR::Insert( sal_uInt16 nPos, const T& rElem )\
82 {\
83 	Insert( nPos, rElem, 1 );\
84 }\
85 \
86 inline T* ARR::operator*()\
87 {\
88 	return ( nUsed==0 ? 0 : pData );\
89 } \
90 inline const T& ARR::operator[]( sal_uInt16 nPos ) const\
91 {\
92     DBG_ASSERT( nPos < nUsed, "" ); \
93     return *(pData+nPos);\
94 } \
95 inline T& ARR::operator [] (sal_uInt16 nPos) \
96 {\
97     DBG_ASSERT( nPos < nUsed, "" ); \
98     return *(pData+nPos); \
99 } \
100 inline const T& ARR::GetObject( sal_uInt16 nPos ) const { return operator[](nPos); } \
101 inline T& ARR::GetObject( sal_uInt16 nPos ) { return operator[](nPos); } \
102 
103 #ifndef _lint
104 // String too long
105 
106 #define IMPL_OBJARRAY( ARR, T ) \
107 ARR::ARR( sal_uInt8 nInitSize, sal_uInt8 nGrowSize ): \
108 	nUsed(0), \
109 	nGrow( nGrowSize ? nGrowSize : 1 ), \
110 	nUnused(nInitSize) \
111 { \
112 	if ( nInitSize != 0 ) \
113 	{ \
114 		size_t nBytes = nInitSize * sizeof(T); \
115 		pData = (T*) new char[ nBytes ]; \
116 		memset( pData, 0, nBytes ); \
117 	} \
118 	else \
119 		pData = 0; \
120 } \
121 \
122 ARR::ARR( const ARR& rOrig ) \
123 { \
124 	nUsed = rOrig.nUsed; \
125 	nGrow = rOrig.nGrow; \
126 	nUnused = rOrig.nUnused; \
127 \
128 	if ( rOrig.pData != 0 ) \
129 	{ \
130 		size_t nBytes = (nUsed + nUnused) * sizeof(T); \
131 		pData = (T*) new char [ nBytes ]; \
132 		memset( pData, 0, nBytes ); \
133         for ( sal_uInt16 n = 0; n < nUsed; ++n ) \
134             *(pData+n) = *(rOrig.pData+n); \
135 	} \
136 	else \
137 		pData = 0; \
138 } \
139 \
140 ARR::~ARR() \
141 { \
142 	for ( sal_uInt16 n = 0; n < nUsed; ++n ) \
143 		( pData+n )->T::~T(); \
144 	delete[] (char*) pData;\
145 } \
146 \
147 ARR& ARR::operator= ( const ARR& rOrig )\
148 { \
149 	for ( sal_uInt16 n = 0; n < nUsed; ++n ) \
150 		( pData+n )->T::~T(); \
151     delete[] (char*) pData;\
152 \
153 	nUsed = rOrig.nUsed; \
154 	nGrow = rOrig.nGrow; \
155 	nUnused = rOrig.nUnused; \
156 \
157 	if ( rOrig.pData != 0 ) \
158 	{ \
159 		size_t nBytes = (nUsed + nUnused) * sizeof(T); \
160 		pData = (T*) new char[ nBytes ]; \
161 		memset( pData, 0, nBytes ); \
162         for ( sal_uInt16 n = 0; n < nUsed; ++n ) \
163             *(pData+n) = *(rOrig.pData+n); \
164 	} \
165 	else \
166 		pData = 0; \
167 	return *this; \
168 } \
169 \
170 void ARR::Append( const T& aElem ) \
171 { \
172 	 \
173 	if ( nUnused == 0 ) \
174 	{ \
175 		sal_uInt16 nNewSize = (nUsed == 1) ? (nGrow==1 ? 2 : nGrow) : nUsed+nGrow; \
176 		size_t nBytes = nNewSize * sizeof(T); \
177 		T* pNewData = (T*) new char[ nBytes ]; \
178 		memset( pNewData, 0, nBytes ); \
179         if ( pData ) \
180 		{ \
181 			memcpy( pNewData, pData, nUsed * sizeof(T) ); \
182 			delete[] (char*) pData;\
183 		} \
184 		nUnused = (sal_uInt8)(nNewSize-nUsed); \
185 		pData = pNewData; \
186 	} \
187 \
188 	 \
189 	pData[nUsed] = aElem; \
190 	++nUsed; \
191 	--nUnused; \
192 } \
193 \
194 sal_uInt16 ARR::Remove( sal_uInt16 nPos, sal_uInt16 nLen ) \
195 { \
196 	DBG_ASSERT( (nPos+nLen) < (nUsed+1), "" ); \
197 	DBG_ASSERT( nLen > 0, "" ); \
198 \
199 	nLen = Min( (sal_uInt16)(nUsed-nPos), (sal_uInt16)nLen ); \
200 \
201 	if ( nLen == 0 ) \
202 		return 0; \
203 \
204 	for ( sal_uInt16 n = nPos; n < (nPos+nLen); ++n ) \
205 		( pData+n )->T::~T(); \
206 \
207 	if ( (nUsed-nLen) == 0 ) \
208 	{ \
209 		delete[] (char*) pData;\
210 		pData = 0; \
211 		nUsed = 0; \
212 		nUnused = 0; \
213 		return nLen; \
214 	} \
215 \
216 	if ( (nUnused+nLen) >= nGrow ) \
217 	{ \
218 		sal_uInt16 nNewUsed = nUsed-nLen; \
219 		sal_uInt16 nNewSize = ((nNewUsed+nGrow-1)/nGrow) * nGrow; \
220 		DBG_ASSERT( nNewUsed <= nNewSize && nNewUsed+nGrow > nNewSize, \
221 					"shrink size computation failed" ); \
222 		size_t nBytes = nNewSize * sizeof(T); \
223 		T* pNewData = (T*) new char[ nBytes ]; \
224 		memset( pNewData, 0, nBytes ); \
225 		if ( nPos > 0 ) \
226 			memcpy( pNewData, pData, nPos * sizeof(T) ); \
227 		if ( nNewUsed != nPos ) \
228 			memcpy(pNewData+nPos, pData+nPos+nLen, (nNewUsed-nPos) * sizeof(T) ); \
229 		delete[] (char*) pData;\
230 		pData = pNewData; \
231 		nUsed = nNewUsed; \
232 		nUnused = (sal_uInt8)(nNewSize - nNewUsed); \
233 		return nLen; \
234 	} \
235 \
236 	 \
237 	if ( nUsed-nPos-nLen > 0 ) \
238 	{ \
239 		memmove(pData+nPos, pData+nPos+nLen, (nUsed-nPos-nLen) * sizeof(T));\
240 	} \
241 	nUsed = nUsed - nLen; \
242 	nUnused = sal::static_int_cast< sal_uInt8 >(nUnused + nLen); \
243 	return nLen; \
244 } \
245 \
246 sal_Bool ARR::Remove( const T& aElem ) \
247 { \
248 	if ( nUsed == 0 ) \
249 		return sal_False; \
250 \
251 	const T *pIter = pData + nUsed - 1; \
252 	for ( sal_uInt16 n = 0; n < nUsed; ++n, --pIter ) \
253 		if ( *pIter == aElem ) \
254 		{ \
255 			Remove(nUsed-n-1, 1); \
256 			return sal_True; \
257 		} \
258 	return sal_False; \
259 } \
260 \
261 sal_Bool ARR::Contains( const T& rItem ) const \
262 { \
263 	if ( !nUsed ) \
264 		return sal_False; \
265 	for ( sal_uInt16 n = 0; n < nUsed; ++n ) \
266 	{ \
267 		const T& r2ndItem = GetObject(n); \
268 		if ( r2ndItem == rItem ) \
269 			return sal_True; \
270 	} \
271 	return sal_False; \
272 } \
273 \
274 void ARR::Insert( sal_uInt16 nPos, const T& rElems, sal_uInt16 nLen ) \
275 { \
276 	DBG_ASSERT( nPos <= nUsed, "" ); \
277 	 \
278 	if ( nUnused == 0 ) \
279 	{ \
280 		\
281 		/* auf die naechste Grow-Grenze aufgerundet vergroeszern */ \
282 		sal_uInt16 nNewSize; \
283 		for ( nNewSize = nUsed+nGrow; nNewSize < (nUsed + nLen); ++nNewSize ) \
284 			/* empty loop */; \
285 		size_t nBytes = nNewSize * sizeof(T); \
286 		T* pNewData = (T*) new char[ nBytes ]; \
287 		memset( pNewData, 0, nBytes ); \
288 		\
289 		if ( pData ) \
290 		{ \
291 			DBG_ASSERT( nUsed < nNewSize, "" ); \
292 			memcpy( pNewData, pData, nUsed * sizeof(T) ); \
293 			delete (char*) pData;\
294 		} \
295 		nUnused = (sal_uInt8)(nNewSize-nUsed); \
296 		pData = pNewData; \
297 	} \
298 \
299 	 \
300 	if ( nPos < nUsed ) \
301 	{ \
302         memmove(pData+nPos+nLen-1, pData+nPos-1, sizeof(T) * (nUsed-nPos));	\
303 	} \
304 \
305     memmove(pData+nPos, &rElems, sizeof(T) * nLen);	\
306 	nUsed = nUsed + nLen; \
307 	nUnused = sal::static_int_cast< sal_uInt8 >(nUnused - nLen); \
308 }
309 
310 // _lint
311 #endif
312 
313 class SFX2_DLLPUBLIC SfxPtrArr
314 {
315 private:
316 	void** pData;
317 	sal_uInt16 nUsed;
318 	sal_uInt8 nGrow;
319 	sal_uInt8 nUnused;
320 public:
321 	SfxPtrArr( sal_uInt8 nInitSize = 0, sal_uInt8 nGrowSize = 8 );
322 	SfxPtrArr( const SfxPtrArr& rOrig );
323 	~SfxPtrArr();
324 	SfxPtrArr& operator= ( const SfxPtrArr& rOrig );
GetObject(sal_uInt16 nPos) const325 	void* GetObject( sal_uInt16 nPos ) const { return operator[](nPos); }
GetObject(sal_uInt16 nPos)326 	void*& GetObject( sal_uInt16 nPos ) { return operator[](nPos); }
327 	void Insert( sal_uInt16 nPos, void* rElem );
328 	void Append( void* rElem );
329 	sal_Bool Replace( void* pOldElem, void* pNewElem );
330 	sal_Bool Remove( void* rElem );
331 	sal_uInt16 Remove( sal_uInt16 nPos, sal_uInt16 nLen );
Count() const332 	sal_uInt16 Count() const { return nUsed; }
333 	inline void** operator*();
334 	inline void* operator[]( sal_uInt16 nPos ) const;
335 	inline void*& operator[]( sal_uInt16 nPos );
336 	sal_Bool Contains( const void* rItem ) const;
Clear()337 	void Clear() { Remove( 0, Count() ); }
338 };
339 
operator *()340 inline void** SfxPtrArr::operator*()
341 {
342 	return ( nUsed==0 ? 0 : pData );
343 }
344 
operator [](sal_uInt16 nPos) const345 inline void* SfxPtrArr::operator[]( sal_uInt16 nPos ) const
346 {
347 	DBG_ASSERT( nPos < nUsed, "" );
348 	return *(pData+nPos);
349 }
350 
operator [](sal_uInt16 nPos)351 inline void*& SfxPtrArr::operator [] (sal_uInt16 nPos)
352 {
353 	DBG_ASSERT( nPos < nUsed, "" );
354 	return *(pData+nPos);
355 }
356 
357 
358 #define DECL_PTRARRAY(ARR, T, nI, nG)\
359 class ARR: public SfxPtrArr\
360 {\
361 public:\
362    ARR( sal_uInt8 nIni=nI, sal_uInt8 nGrowValue=nG ):\
363 	   SfxPtrArr(nIni,nGrowValue) \
364    {}\
365    ARR( const ARR& rOrig ):\
366 	   SfxPtrArr(rOrig) \
367    {}\
368    T GetObject( sal_uInt16 nPos ) const { return operator[](nPos); } \
369    T& GetObject( sal_uInt16 nPos ) { return operator[](nPos); } \
370    void Insert( sal_uInt16 nPos, T aElement ) {\
371 	   SfxPtrArr::Insert(nPos,(void *)aElement);\
372    }\
373    void Append( T aElement ) {\
374 	   SfxPtrArr::Append((void *)aElement);\
375    }\
376    sal_Bool Replace( T aOldElem, T aNewElem ) {\
377        return SfxPtrArr::Replace((void *)aOldElem, (void*) aNewElem);\
378    }\
379    void Remove( T aElement ) {\
380 	   SfxPtrArr::Remove((void*)aElement);\
381    }\
382    void Remove( sal_uInt16 nPos, sal_uInt16 nLen = 1 ) {\
383 	   SfxPtrArr::Remove( nPos, nLen ); \
384    }\
385    T* operator *() {\
386 	   return (T*) SfxPtrArr::operator*();\
387    }\
388    T operator[]( sal_uInt16 nPos ) const { \
389 	   return (T) SfxPtrArr::operator[](nPos); } \
390    T& operator[]( sal_uInt16 nPos ) { \
391 	   return (T&) SfxPtrArr::operator[](nPos); } \
392    void Clear() { Remove( 0, Count() ); }\
393 };
394 
395 class ByteArr
396 {
397 private:
398 	char* pData;
399 	sal_uInt16 nUsed;
400 	sal_uInt8 nGrow;
401 	sal_uInt8 nUnused;
402 public:
403 	ByteArr( sal_uInt8 nInitSize = 0, sal_uInt8 nGrowSize = 8 );
404 	ByteArr( const ByteArr& rOrig );
405 	~ByteArr();
406 	ByteArr& operator= ( const ByteArr& rOrig );
GetObject(sal_uInt16 nPos) const407 	char GetObject( sal_uInt16 nPos ) const { return operator[](nPos); }
GetObject(sal_uInt16 nPos)408 	char& GetObject( sal_uInt16 nPos ) { return operator[](nPos); }
409 	void Insert( sal_uInt16 nPos, char rElem );
410 	void Append( char rElem );
411 	sal_Bool Remove( char rElem );
412 	sal_uInt16 Remove( sal_uInt16 nPos, sal_uInt16 nLen );
Count() const413 	sal_uInt16 Count() const { return nUsed; }
414 	char* operator*();
415 	char operator[]( sal_uInt16 nPos ) const;
416 	char& operator[]( sal_uInt16 nPos );
417 	sal_Bool Contains( const char rItem ) const;
Clear()418 	void Clear() { Remove( 0, Count() ); }
419 };
420 
operator *()421 inline char* ByteArr::operator*()
422 {
423 	return ( nUsed==0 ? 0 : pData );
424 }
425 
426 #define DECL_1BYTEARRAY(ARR, T, nI, nG)\
427 class ARR: public ByteArr\
428 {\
429 public:\
430 		ARR( sal_uInt8 nIni=nI, sal_uInt8 nGrow=nG ):\
431 			ByteArr(nIni,nGrow) \
432 		{}\
433 		ARR( const ARR& rOrig ):\
434 			ByteArr(rOrig) \
435 		{}\
436 		T GetObject( sal_uInt16 nPos ) const { return operator[](nPos); } \
437 		T& GetObject( sal_uInt16 nPos ) { return operator[](nPos); } \
438 		void Insert( sal_uInt16 nPos, T aElement ) {\
439 			ByteArr::Insert(nPos,(char)aElement);\
440 		}\
441 		void Append( T aElement ) {\
442 			ByteArr::Append((char)aElement);\
443 		}\
444 		void Remove( T aElement ) {\
445 			ByteArr::Remove((char)aElement);\
446 		}\
447 		void Remove( sal_uInt16 nPos, sal_uInt16 nLen = 1 ) {\
448 			ByteArr::Remove( nPos, nLen ); \
449 		}\
450 		T* operator *() {\
451 			return (T*) ByteArr::operator*();\
452 		}\
453 		T operator[]( sal_uInt16 nPos ) const { \
454 			return (T) ByteArr::operator[](nPos); } \
455 		T& operator[]( sal_uInt16 nPos ) { \
456 			return (T&) ByteArr::operator[](nPos); } \
457 		void Clear() { Remove( 0, Count() ); }\
458 };
459 
460 class WordArr
461 {
462 private:
463 	short* pData;
464 	sal_uInt16 nUsed;
465 	sal_uInt8 nGrow;
466 	sal_uInt8 nUnused;
467 public:
468 	WordArr( sal_uInt8 nInitSize = 0, sal_uInt8 nGrowSize = 8 );
469 	WordArr( const WordArr& rOrig );
470 	~WordArr();
471 	WordArr& operator= ( const WordArr& rOrig );
GetObject(sal_uInt16 nPos) const472 	short GetObject( sal_uInt16 nPos ) const { return operator[](nPos); }
GetObject(sal_uInt16 nPos)473 	short& GetObject( sal_uInt16 nPos ) { return operator[](nPos); }
474 	void Insert( sal_uInt16 nPos, short rElem );
475 	void Append( short rElem );
476 	sal_Bool Remove( short rElem );
477 	sal_uInt16 Remove( sal_uInt16 nPos, sal_uInt16 nLen );
Count() const478 	sal_uInt16 Count() const { return nUsed; }
479 	short* operator*();
480 	short operator[]( sal_uInt16 nPos ) const;
481 	short& operator[]( sal_uInt16 nPos );
482 	sal_Bool Contains( const short rItem ) const;
Clear()483 	void Clear() { Remove( 0, Count() ); }
484 };
485 
operator *()486 inline short* WordArr::operator*()
487 {
488 	return ( nUsed==0 ? 0 : pData );
489 }
490 
491 #define DECL_2BYTEARRAY(ARR, T, nI, nG)\
492 class ARR: public WordArr\
493 {\
494 public:\
495 		ARR( sal_uInt8 nIni=nI, sal_uInt8 nGrowValue=nG ):\
496 			WordArr(nIni,nGrowValue) \
497 		{}\
498 		ARR( const ARR& rOrig ):\
499 			WordArr(rOrig) \
500 		{}\
501 		T GetObject( sal_uInt16 nPos ) const { return operator[](nPos); } \
502 		T& GetObject( sal_uInt16 nPos ) { return operator[](nPos); } \
503 		void Insert( sal_uInt16 nPos, T aElement ) {\
504 			WordArr::Insert(nPos,(short)aElement);\
505 		}\
506 		void Append( T aElement ) {\
507 			WordArr::Append((short)aElement);\
508 		}\
509 		void Remove( T aElement ) {\
510 			WordArr::Remove((short)aElement);\
511 		}\
512 		void Remove( sal_uInt16 nPos, sal_uInt16 nLen = 1 ) {\
513 			WordArr::Remove( nPos, nLen ); \
514 		}\
515 		T* operator *() {\
516 			return (T*) WordArr::operator*();\
517 		}\
518 		T operator[]( sal_uInt16 nPos ) const { \
519 			return (T) WordArr::operator[](nPos); } \
520 		T& operator[]( sal_uInt16 nPos ) { \
521 			return (T&) WordArr::operator[](nPos); } \
522 		void Clear() { Remove( 0, Count() ); }\
523 };
524 
525 #endif
526