xref: /AOO41X/main/sfx2/inc/sfx2/minarray.hxx (revision 353d8f4d17010cd2d0ea815067cad67e477f2bee)
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