xref: /trunk/main/svl/inc/svl/svarray.hxx (revision c1e8cc3a)
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 
24 #ifndef _SVARRAY_HXX
25 #define _SVARRAY_HXX
26 
27 #if 0
28 // Nobody wants to touch this code, not even with a ten-foot pole.
29 // If one has to read it then the following mapping might be useful:
30 //	"nm" seems to be "type name" of the array
31 //	"AE" means "type of array element"
32 //	"IS" means "initial size", i.e. the initial number of elements
33 //	"GS" means "growth size"
34 ***********************************************************************
35 *
36 *	Hier folgt die Beschreibung fuer die exportierten Makros:
37 *
38 *		SV_DECL_VARARR(nm, AE, IS, GS)
39 *		SV_IMPL_VARARR( nm, AE )
40 *			definiere/implementiere ein Array das einfache Objecte
41 *			enthaelt. (Sie werden im Speicher verschoben, koennen also
42 *			z.B. keine String sein)
43 *
44 *		SV_DECL_PTRARR(nm, AE, IS, GS)
45 *		SV_IMPL_PTRARR(nm, AE)
46 *			definiere/implementiere ein Array das Pointer haelt. Diese
47 *			werden von aussen angelegt und zerstoert. Das IMPL-Makro
48 *			wird nur benoetigt, wenn die DeleteAndDestroy Methode genutzt
49 *			wird, diese loescht dann die Pointer und ruft deren Destruktoren
50 *
51 *		SV_DECL_PTRARR_DEL(nm, AE, IS, GS)
52 *		SV_IMPL_PTRARR(nm, AE)
53 *			definiere/implementiere ein Array das Pointer haelt. Diese
54 *			werden von aussen angelegt und im Destructor zerstoert.
55 *
56 *
57 *		SV_DECL_PTRARR_SORT(nm, AE, IS, GS)
58 *		SV_IMPL_PTRARR_SORT( nm,AE )
59 *			defieniere/implementiere ein Sort-Array mit Pointern, das nach
60 *			Pointern sortiert ist. Basiert auf einem PTRARR
61 *
62 *		SV_DECL_PTRARR_SORT_DEL(nm, AE, IS, GS)
63 *		SV_IMPL_PTRARR_SORT( nm,AE )
64 *			defieniere/implementiere ein Sort-Array mit Pointern, das nach
65 *			Pointern sortiert ist. Basiert auf einem PTRARR_DEL
66 *
67 *		SV_DECL_PTRARR_SORT(nm, AE, IS, GS)
68 *		SV_IMPL_OP_PTRARR_SORT( nm,AE )
69 *			defieniere/implementiere ein Sort-Array mit Pointern, das nach
70 *			Objecten sortiert ist. Basiert auf einem PTRARR.
71 *			Sortierung mit Hilfe der Object-operatoren "<" und "=="
72 *
73 *		SV_DECL_PTRARR_SORT_DEL(nm, AE, IS, GS)
74 *		SV_IMPL_OP_PTRARR_SORT( nm,AE )
75 *			defieniere/implementiere ein Sort-Array mit Pointern, das nach
76 *			Objecten sortiert ist. Basiert auf einem PTRARR_DEL.
77 *			Sortierung mit Hilfe der Object-operatoren "<" und "=="
78 *
79 *		SV_DECL_VARARR_SORT(nm, AE, IS, GS)
80 *		SV_IMPL_VARARR_SORT( nm,AE )
81 *			defieniere/implementiere ein Sort-Array mit einfachen Objecten.
82 *			Basiert auf einem VARARR.
83 *			Sortierung mit Hilfe der Object-operatoren "<" und "=="
84 *
85 * JP 09.10.96:  vordefinierte Arrays:
86 *	VarArr:		SvBools, SvULongs, SvUShorts, SvLongs, SvShorts
87 *	PtrArr:		SvStrings, SvStringsDtor
88 *	SortArr:	SvStringsSort, SvStringsSortDtor,
89 *				SvStringsISort, SvStringsISortDtor
90 ***********************************************************************
91 #endif
92 
93 #include "svl/svldllapi.h"
94 
95 #ifndef INCLUDED_STRING_H
96 #include <string.h> 	// memmove()
97 #define INCLUDED_STRING_H
98 #endif
99 
100 #ifndef INCLUDED_LIMITS_H
101 #include <limits.h> 	// USHRT_MAX
102 #define INCLUDED_LIMITS_H
103 #endif
104 #include <rtl/alloc.h>
105 #include <tools/solar.h>
106 
107 class String;
108 
109 #ifndef CONCAT
110 #define CONCAT(x,y) x##y
111 #endif
112 
113 class DummyType;
operator new(size_t,DummyType * pPtr)114 inline void* operator new( size_t, DummyType* pPtr )
115 {
116 	return pPtr;
117 }
operator delete(void *,DummyType *)118 inline void operator delete( void*, DummyType* ) {}
119 
120 #if defined(PRODUCT)
121 
122 #define _SVVARARR_DEF_GET_OP_INLINE( nm, ArrElem ) \
123 ArrElem& operator[](sal_uInt16 nP) const { return *(pData+nP); }\
124 \
125 void Insert( const nm * pI, sal_uInt16 nP,\
126 			 sal_uInt16 nS = 0, sal_uInt16 nE = USHRT_MAX )\
127 {\
128 	if( USHRT_MAX == nE ) \
129 		nE = pI->nA; \
130 	if( nS < nE ) \
131 		Insert( (const ArrElem*)pI->pData+nS, (sal_uInt16)nE-nS, nP );\
132 }
133 
134 #define _SVVARARR_IMPL_GET_OP_INLINE( nm, ArrElem )
135 
136 #else
137 
138 #define _SVVARARR_DEF_GET_OP_INLINE( nm,ArrElem )\
139 ArrElem& operator[](sal_uInt16 nP) const;\
140 void Insert( const nm *pI, sal_uInt16 nP,\
141 				sal_uInt16 nS = 0, sal_uInt16 nE = USHRT_MAX );
142 
143 #define _SVVARARR_IMPL_GET_OP_INLINE( nm, ArrElem )\
144 ArrElem& nm::operator[](sal_uInt16 nP) const\
145 {\
146 	DBG_ASSERT( pData && nP < nA,"Op[]");\
147 	return *(pData+nP);\
148 }\
149 void nm::Insert( const nm *pI, sal_uInt16 nP, sal_uInt16 nStt, sal_uInt16 nE)\
150 {\
151 	DBG_ASSERT(nP<=nA,"Ins,Ar[Start.End]");\
152 	if( USHRT_MAX == nE ) \
153 		nE = pI->nA; \
154 	if( nStt < nE ) \
155 		Insert( (const ArrElem*)pI->pData+nStt, (sal_uInt16)nE-nStt, nP );\
156 }
157 
158 #endif
159 
160 #define _SV_DECL_VARARR_GEN(nm, AE, IS, GS, AERef, vis )\
161 typedef sal_Bool (*FnForEach_##nm)( const AERef, void* );\
162 class vis nm\
163 {\
164 protected:\
165 	AE    *pData;\
166 	sal_uInt16 nFree;\
167 	sal_uInt16 nA;\
168 \
169 	void _resize(size_t n);\
170 \
171 public:\
172 	nm( sal_uInt16= IS, sal_uInt8= GS );\
173 	~nm() { rtl_freeMemory( pData ); }\
174 \
175 	_SVVARARR_DEF_GET_OP_INLINE(nm, AE )\
176 	AERef GetObject(sal_uInt16 nP) const { return (*this)[nP]; } \
177 \
178 	void Insert( const AERef aE, sal_uInt16 nP );\
179 	void Insert( const AE *pE, sal_uInt16 nL, sal_uInt16 nP );\
180 	void Remove( sal_uInt16 nP, sal_uInt16 nL = 1 );\
181 	void Replace( const AERef aE, sal_uInt16 nP );\
182 	void Replace( const AE *pE, sal_uInt16 nL, sal_uInt16 nP );\
183 	sal_uInt16 Count() const { return nA; }\
184 	const AE* GetData() const { return (const AE*)pData; }\
185 \
186 	void ForEach( CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\
187 	{\
188 		_ForEach( 0, nA, fnForEach, pArgs );\
189 	}\
190 	void ForEach( sal_uInt16 nS, sal_uInt16 nE, \
191 					CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\
192 	{\
193 		_ForEach( nS, nE, fnForEach, pArgs );\
194 	}\
195 \
196 	void _ForEach( sal_uInt16 nStt, sal_uInt16 nE, \
197 			CONCAT( FnForEach_, nm ) fnCall, void* pArgs = 0 );\
198 \
199 
200 #define _SV_DECL_VARARR(nm, AE, IS, GS ) \
201 _SV_DECL_VARARR_GEN(nm, AE, IS, GS, AE & )
202 
203 #define SV_DECL_VARARR_GEN(nm, AE, IS, GS, AERef, vis )\
204 _SV_DECL_VARARR_GEN(nm, AE, IS, GS, AERef, vis )\
205 private:\
206 nm( const nm& );\
207 nm& operator=( const nm& );\
208 };
209 
210 #define SV_DECL_VARARR(nm, AE, IS, GS ) \
211 SV_DECL_VARARR_GEN(nm, AE, IS, GS, AE &, )
212 
213 #define SV_DECL_VARARR_VISIBILITY(nm, AE, IS, GS, vis ) \
214 SV_DECL_VARARR_GEN(nm, AE, IS, GS, AE &, vis )
215 
216 #define SV_IMPL_VARARR_GEN( nm, AE, AERef )\
217 nm::nm( sal_uInt16 nInit, sal_uInt8 )\
218 	: pData (0),\
219 	  nFree (nInit),\
220 	  nA    (0)\
221 {\
222 	if( nInit )\
223 	{\
224 		pData = (AE*)(rtl_allocateMemory(sizeof(AE) * nInit));\
225 		DBG_ASSERT( pData, "CTOR, allocate");\
226 	}\
227 }\
228 \
229 void nm::_resize (size_t n)\
230 {\
231 	sal_uInt16 nL = ((n < USHRT_MAX) ? sal_uInt16(n) : USHRT_MAX);\
232 	AE* pE = (AE*)(rtl_reallocateMemory (pData, sizeof(AE) * nL));\
233 	if ((pE != 0) || (nL == 0))\
234 	{\
235 		pData = pE;\
236 		nFree = nL - nA;\
237 	}\
238 }\
239 \
240 void nm::Insert( const AERef aE, sal_uInt16 nP )\
241 {\
242 	DBG_ASSERT(nP <= nA && nA < USHRT_MAX, "Ins 1");\
243 	if (nFree < 1)\
244 		_resize (nA + ((nA > 1) ? nA : 1));\
245 	if( pData && nP < nA )\
246 		memmove( pData+nP+1, pData+nP, (nA-nP) * sizeof( AE ));\
247 	*(pData+nP) = (AE&)aE;\
248 	++nA; --nFree;\
249 }\
250 \
251 void nm::Insert( const AE* pE, sal_uInt16 nL, sal_uInt16 nP )\
252 {\
253 	DBG_ASSERT(nP<=nA && ((long)nA+nL)<USHRT_MAX,"Ins n");\
254 	if (nFree < nL)\
255 		_resize (nA + ((nA > nL) ? nA : nL));\
256 	if( pData && nP < nA )\
257 		memmove( pData+nP+nL, pData+nP, (nA-nP) * sizeof( AE ));\
258 	if( pE )\
259 		memcpy( pData+nP, pE, nL * sizeof( AE ));\
260 	nA = nA + nL; nFree = nFree - nL;\
261 }\
262 \
263 void nm::Replace( const AERef aE, sal_uInt16 nP )\
264 {\
265 	if( nP < nA )\
266 		*(pData+nP) = (AE&)aE;\
267 }\
268 \
269 void nm::Replace( const AE *pE, sal_uInt16 nL, sal_uInt16 nP )\
270 {\
271 	if( pE && nP < nA )\
272 	{\
273 		if( nP + nL < nA )\
274 			memcpy( pData + nP, pE, nL * sizeof( AE ));\
275 		else if( nP + nL < nA + nFree )\
276 		{\
277 			memcpy( pData + nP, pE, nL * sizeof( AE ));\
278             nP = nP + (nL - nA); \
279             nFree = nP;\
280 		}\
281 		else \
282 		{\
283 			sal_uInt16 nTmpLen = nA + nFree - nP; \
284 			memcpy( pData + nP, pE, nTmpLen * sizeof( AE ));\
285 			nA = nA + nFree; \
286 			nFree = 0; \
287 			Insert( pE + nTmpLen, nL - nTmpLen, nA );\
288 		}\
289 	}\
290 }\
291 \
292 void nm::Remove( sal_uInt16 nP, sal_uInt16 nL )\
293 {\
294 	if( !nL )\
295 		return;\
296 	DBG_ASSERT( nP < nA && nP + nL <= nA,"Del");\
297 	if( pData && nP+1 < nA )\
298 		memmove( pData+nP, pData+nP+nL, (nA-nP-nL) * sizeof( AE ));\
299 	nA = nA - nL; nFree = nFree + nL;\
300 	if (nFree > nA)\
301 		_resize (nA);\
302 }\
303 \
304 void nm::_ForEach( sal_uInt16 nStt, sal_uInt16 nE, \
305 			CONCAT( FnForEach_, nm ) fnCall, void* pArgs )\
306 {\
307 	if( nStt >= nE || nE > nA )\
308 		return;\
309 	for( ; nStt < nE && (*fnCall)( *(const AE*)(pData+nStt), pArgs ); nStt++)\
310 		;\
311 }\
312 \
313 _SVVARARR_IMPL_GET_OP_INLINE(nm, AE )\
314 
315 #define SV_IMPL_VARARR( nm, AE ) \
316 SV_IMPL_VARARR_GEN( nm, AE, AE & )
317 
318 #define _SV_DECL_PTRARR_DEF_GEN( nm, AE, IS, GS, AERef, vis )\
319 _SV_DECL_VARARR_GEN( nm, AE, IS, GS, AERef, vis)\
320 sal_uInt16 GetPos( const AERef aE ) const;\
321 };
322 
323 #define _SV_DECL_PTRARR_DEF( nm, AE, IS, GS, vis )\
324 _SV_DECL_PTRARR_DEF_GEN( nm, AE, IS, GS, AE &, vis )
325 
326 #define SV_DECL_PTRARR_GEN(nm, AE, IS, GS, Base, AERef, VPRef, vis )\
327 typedef sal_Bool (*FnForEach_##nm)( const AERef, void* );\
328 class vis nm: public Base \
329 {\
330 public:\
331 	nm( sal_uInt16 nIni=IS, sal_uInt8 nG=GS )\
332 		: Base(nIni,nG) {}\
333 	void Insert( const nm *pI, sal_uInt16 nP, \
334 			sal_uInt16 nS = 0, sal_uInt16 nE = USHRT_MAX ) {\
335 		Base::Insert((const Base*)pI, nP, nS, nE);\
336 	}\
337 	void Insert( const AERef aE, sal_uInt16 nP ) {\
338 		Base::Insert( (const VPRef )aE, nP );\
339 	}\
340 	void Insert( const AE *pE, sal_uInt16 nL, sal_uInt16 nP ) {\
341 		Base::Insert( (const VoidPtr*)pE, nL, nP );\
342 	}\
343 	void Replace( const AERef aE, sal_uInt16 nP ) {\
344 		Base::Replace( (const VPRef)aE, nP );\
345 	}\
346 	void Replace( const AE *pE, sal_uInt16 nL, sal_uInt16 nP ) {\
347 		Base::Replace( (const VoidPtr*)pE, nL, nP );\
348 	}\
349 	void Remove( sal_uInt16 nP, sal_uInt16 nL = 1) {\
350 		Base::Remove(nP,nL);\
351 	}\
352 	const AE* GetData() const {\
353 		return (const AE*)Base::GetData();\
354 	}\
355 	void ForEach( CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\
356 	{\
357 		_ForEach( 0, nA, (FnForEach_##Base)fnForEach, pArgs );\
358 	}\
359 	void ForEach( sal_uInt16 nS, sal_uInt16 nE, \
360 					CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\
361 	{\
362 		_ForEach( nS, nE, (FnForEach_##Base)fnForEach, pArgs );\
363 	}\
364 	AE operator[]( sal_uInt16 nP )const  { \
365 		return (AE)Base::operator[](nP); }\
366 	AE GetObject(sal_uInt16 nP) const { \
367 		return (AE)Base::GetObject(nP); }\
368 	\
369 	sal_uInt16 GetPos( const AERef aE ) const { \
370 		return Base::GetPos((const VPRef)aE);\
371 	}\
372 	void DeleteAndDestroy( sal_uInt16 nP, sal_uInt16 nL=1 );\
373 private:\
374 	nm( const nm& );\
375 	nm& operator=( const nm& );\
376 };
377 
378 #define SV_DECL_PTRARR(nm, AE, IS, GS )\
379 SV_DECL_PTRARR_GEN(nm, AE, IS, GS, SvPtrarr, AE &, VoidPtr &, )
380 
381 #define SV_DECL_PTRARR_VISIBILITY(nm, AE, IS, GS, vis )\
382 SV_DECL_PTRARR_GEN(nm, AE, IS, GS, SvPtrarr, AE &, VoidPtr &, vis )
383 
384 #define SV_DECL_PTRARR_DEL_GEN(nm, AE, IS, GS, Base, AERef, VPRef, vis )\
385 typedef sal_Bool (*FnForEach_##nm)( const AERef, void* );\
386 class vis nm: public Base \
387 {\
388 public:\
389 	nm( sal_uInt16 nIni=IS, sal_uInt8 nG=GS )\
390 		: Base(nIni,nG) {}\
391 	~nm() { DeleteAndDestroy( 0, Count() ); }\
392 	void Insert( const nm *pI, sal_uInt16 nP, \
393 			sal_uInt16 nS = 0, sal_uInt16 nE = USHRT_MAX ) {\
394 		Base::Insert((const Base*)pI, nP, nS, nE);\
395 	}\
396 	void Insert( const AERef aE, sal_uInt16 nP ) {\
397 		Base::Insert((const VPRef)aE, nP );\
398 	}\
399 	void Insert( const AE *pE, sal_uInt16 nL, sal_uInt16 nP ) {\
400 		Base::Insert( (const VoidPtr *)pE, nL, nP );\
401 	}\
402 	void Replace( const AERef aE, sal_uInt16 nP ) {\
403 		Base::Replace( (const VPRef)aE, nP );\
404 	}\
405 	void Replace( const AE *pE, sal_uInt16 nL, sal_uInt16 nP ) {\
406 		Base::Replace( (const VoidPtr*)pE, nL, nP );\
407 	}\
408 	void Remove( sal_uInt16 nP, sal_uInt16 nL = 1) {\
409 		Base::Remove(nP,nL);\
410 	}\
411 	const AE* GetData() const {\
412 		return (const AE*)Base::GetData();\
413 	}\
414 	void ForEach( CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\
415 	{\
416 		_ForEach( 0, nA, (FnForEach_##Base)fnForEach, pArgs );\
417 	}\
418 	void ForEach( sal_uInt16 nS, sal_uInt16 nE, \
419 					CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\
420 	{\
421 		_ForEach( nS, nE, (FnForEach_##Base)fnForEach, pArgs );\
422 	}\
423 	AE operator[]( sal_uInt16 nP )const  { \
424 		return (AE)Base::operator[](nP); }\
425 	AE GetObject( sal_uInt16 nP )const  { \
426 		return (AE)Base::GetObject(nP); }\
427 	\
428 	sal_uInt16 GetPos( const AERef aE ) const { \
429 		return Base::GetPos((const VPRef)aE);\
430 	} \
431 	void DeleteAndDestroy( sal_uInt16 nP, sal_uInt16 nL=1 );\
432 private:\
433 	nm( const nm& );\
434 	nm& operator=( const nm& );\
435 };
436 
437 #define SV_DECL_PTRARR_DEL(nm, AE, IS, GS )\
438 SV_DECL_PTRARR_DEL_GEN(nm, AE, IS, GS, SvPtrarr, AE &, VoidPtr &, )
439 
440 #define SV_DECL_PTRARR_DEL_VISIBILITY(nm, AE, IS, GS, vis )\
441 SV_DECL_PTRARR_DEL_GEN(nm, AE, IS, GS, SvPtrarr, AE &, VoidPtr &, vis)
442 
443 #define SV_IMPL_PTRARR_GEN(nm, AE, Base)\
444 void nm::DeleteAndDestroy( sal_uInt16 nP, sal_uInt16 nL )\
445 { \
446 	if( nL ) {\
447 		DBG_ASSERT( nP < nA && nP + nL <= nA,"Del");\
448 		for( sal_uInt16 n=nP; n < nP + nL; n++ ) \
449 			delete *((AE*)pData+n); \
450 		Base::Remove( nP, nL ); \
451 	} \
452 }
453 
454 #define SV_IMPL_PTRARR(nm, AE )\
455 SV_IMPL_PTRARR_GEN(nm, AE, SvPtrarr )
456 
457 typedef void* VoidPtr;
458 _SV_DECL_PTRARR_DEF( SvPtrarr, VoidPtr, 0, 1, SVL_DLLPUBLIC )
459 
460 // SORTARR - Begin
461 
462 #ifdef __MWERKS__
463 #define __MWERKS__PRIVATE public
464 #else
465 #define __MWERKS__PRIVATE private
466 #endif
467 
468 #define _SORT_CLASS_DEF(nm, AE, IS, GS, vis)\
469 typedef sal_Bool (*FnForEach_##nm)( const AE&, void* );\
470 class vis nm : __MWERKS__PRIVATE nm##_SAR \
471 {\
472 public:\
473 	nm(sal_uInt16 nSize = IS, sal_uInt8 nG = GS)\
474 		: nm##_SAR(nSize,nG) {}\
475 	void Insert( const nm *pI, sal_uInt16 nS=0, sal_uInt16 nE=USHRT_MAX );\
476 	sal_Bool Insert( const AE& aE );\
477 	sal_Bool Insert( const AE& aE, sal_uInt16& rP );\
478 	void Insert( const AE *pE, sal_uInt16 nL );\
479 	void Remove( sal_uInt16 nP, sal_uInt16 nL = 1 );\
480 	void Remove( const AE& aE, sal_uInt16 nL = 1 );\
481 	sal_uInt16 Count() const  {   return nm##_SAR::Count();	}\
482 	const AE* GetData() const { return (const AE*)pData; }\
483 \
484 /* Das Ende stehe im DECL-Makro !!! */
485 
486 #define _SV_SEEK_PTR(nm,AE)\
487 sal_Bool nm::Seek_Entry( const AE aE, sal_uInt16* pP ) const\
488 {\
489 	sal_uInt16 nO  = nm##_SAR::Count(),\
490 			nM, \
491 			nU = 0;\
492 	if( nO > 0 )\
493 	{\
494 		nO--;\
495 		long rCmp = (long)aE;\
496 		while( nU <= nO )\
497 		{\
498 			nM = nU + ( nO - nU ) / 2;\
499 			if( (long)*(pData + nM) == rCmp )\
500 			{\
501 				if( pP ) *pP = nM;\
502 				return sal_True;\
503 			}\
504 			else if( (long)*(pData+ nM) < (long)aE  )\
505 				nU = nM + 1;\
506 			else if( nM == 0 )\
507 			{\
508 				if( pP ) *pP = nU;\
509 				return sal_False;\
510 			}\
511 			else\
512 				nO = nM - 1;\
513 		}\
514 	}\
515 	if( pP ) *pP = nU;\
516 	return sal_False;\
517 }
518 
519 #define _SV_SEEK_PTR_TO_OBJECT( nm,AE )\
520 sal_Bool nm::Seek_Entry( const AE aE, sal_uInt16* pP ) const\
521 {\
522 	sal_uInt16 nO  = nm##_SAR::Count(),\
523 			nM, \
524 			nU = 0;\
525 	if( nO > 0 )\
526 	{\
527 		nO--;\
528 		while( nU <= nO )\
529 		{\
530 			nM = nU + ( nO - nU ) / 2;\
531 			if( *(*((AE*)pData + nM)) == *(aE) )\
532 			{\
533 				if( pP ) *pP = nM;\
534 				return sal_True;\
535 			}\
536 			else if( *(*((AE*)pData + nM)) < *(aE) )\
537 				nU = nM + 1;\
538 			else if( nM == 0 )\
539 			{\
540 				if( pP ) *pP = nU;\
541 				return sal_False;\
542 			}\
543 			else\
544 				nO = nM - 1;\
545 		}\
546 	}\
547 	if( pP ) *pP = nU;\
548 	return sal_False;\
549 }
550 
551 #define _SV_SEEK_OBJECT( nm,AE )\
552 sal_Bool nm::Seek_Entry( const AE & aE, sal_uInt16* pP ) const\
553 {\
554 	sal_uInt16 nO  = nm##_SAR::Count(),\
555 			nM, \
556 			nU = 0;\
557 	if( nO > 0 )\
558 	{\
559 		nO--;\
560 		while( nU <= nO )\
561 		{\
562 			nM = nU + ( nO - nU ) / 2;\
563 			if( *(pData + nM) == aE )\
564 			{\
565 				if( pP ) *pP = nM;\
566 				return sal_True;\
567 			}\
568 			else if( *(pData + nM) < aE )\
569 				nU = nM + 1;\
570 			else if( nM == 0 )\
571 			{\
572 				if( pP ) *pP = nU;\
573 				return sal_False;\
574 			}\
575 			else\
576 				nO = nM - 1;\
577 		}\
578 	}\
579 	if( pP ) *pP = nU;\
580 	return sal_False;\
581 }
582 
583 #define _SV_IMPL_SORTAR_ALG(nm, AE)\
584 void nm::Insert( const nm * pI, sal_uInt16 nS, sal_uInt16 nE )\
585 {\
586 	if( USHRT_MAX == nE )\
587 		nE = pI->Count();\
588 	sal_uInt16 nP;\
589 	const AE * pIArr = pI->GetData();\
590 	for( ; nS < nE; ++nS )\
591 	{\
592 		if( ! Seek_Entry( *(pIArr+nS), &nP) )\
593 				nm##_SAR::Insert( *(pIArr+nS), nP );\
594 		if( ++nP >= Count() )\
595 		{\
596 			nm##_SAR::Insert( pI, nP, nS+1, nE );\
597 			nS = nE;\
598 		}\
599 	}\
600 }\
601 \
602 sal_Bool nm::Insert( const AE & aE )\
603 {\
604 	sal_uInt16 nP;\
605 	sal_Bool bExist;\
606     bExist = Seek_Entry( aE, &nP );\
607 	if( ! bExist )\
608 		nm##_SAR::Insert( aE, nP );\
609 	return !bExist;\
610 }\
611 sal_Bool nm::Insert( const AE & aE, sal_uInt16& rP )\
612 {\
613 	sal_Bool bExist;\
614     bExist = Seek_Entry( aE, &rP );\
615 	if( ! bExist )\
616 		nm##_SAR::Insert( aE, rP );\
617 	return !bExist;\
618 }\
619 void nm::Insert( const AE* pE, sal_uInt16 nL)\
620 {\
621 	sal_uInt16 nP;\
622 	for( sal_uInt16 n = 0; n < nL; ++n )\
623 		if( ! Seek_Entry( *(pE+n), &nP ))\
624 			nm##_SAR::Insert( *(pE+n), nP );\
625 }\
626 void nm::Remove( sal_uInt16 nP, sal_uInt16 nL )\
627 {\
628 	if( nL )\
629 		nm##_SAR::Remove( nP, nL);\
630 }\
631 \
632 void nm::Remove( const AE &aE, sal_uInt16 nL )\
633 {\
634 	sal_uInt16 nP;\
635 	if( nL && Seek_Entry( aE, &nP ) )   \
636 		nm##_SAR::Remove( nP, nL);\
637 }\
638 
639 #if defined(TCPP)
640 
641 #define _SORTARR_BLC_CASTS(nm, AE )\
642 	sal_Bool Insert(  AE &aE ) {\
643 		return Insert( (const AE&)aE );\
644 	}\
645 	sal_uInt16 GetPos( AE& aE ) const { \
646 		return SvPtrarr::GetPos((const VoidPtr&)aE);\
647 	}\
648 	void Remove( AE& aE, sal_uInt16 nL = 1 ) { \
649 		Remove( (const AE&) aE, nL	);\
650 	}
651 
652 #else
653 
654 #define _SORTARR_BLC_CASTS(nm, AE )\
655 	sal_uInt16 GetPos( const AE& aE ) const { \
656 		return SvPtrarr::GetPos((const VoidPtr&)aE);\
657 	}
658 
659 #endif
660 
661 #define _SV_DECL_PTRARR_SORT_ALG(nm, AE, IS, GS, vis)\
662 SV_DECL_PTRARR_VISIBILITY(nm##_SAR, AE, IS, GS, vis)\
663 _SORT_CLASS_DEF(nm, AE, IS, GS, vis)\
664 	AE operator[](sal_uInt16 nP) const {\
665 		return nm##_SAR::operator[]( nP );\
666 	}\
667 	AE GetObject(sal_uInt16 nP) const {\
668 		return nm##_SAR::GetObject( nP );\
669 	}\
670 	sal_Bool Seek_Entry( const AE aE, sal_uInt16* pP = 0 ) const;\
671 	void ForEach( CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\
672 	{\
673 		_ForEach( 0, nA, (FnForEach_SvPtrarr)fnForEach, pArgs );\
674 	}\
675 	void ForEach( sal_uInt16 nS, sal_uInt16 nE, \
676 					CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\
677 	{\
678 		_ForEach( nS, nE, (FnForEach_SvPtrarr)fnForEach, pArgs );\
679 	}\
680 	void DeleteAndDestroy( sal_uInt16 nP, sal_uInt16 nL=1 ); \
681 	_SORTARR_BLC_CASTS(nm, AE )\
682 \
683 /* Das Ende stehe im DECL-Makro !!! */
684 
685 #define _SV_DECL_PTRARR_SORT(nm, AE, IS, GS, vis)\
686 _SV_DECL_PTRARR_SORT_ALG(nm, AE, IS, GS, vis)\
687 private:\
688 	nm( const nm& );\
689 	nm& operator=( const nm& );\
690 };
691 
692 #define SV_DECL_PTRARR_SORT(nm, AE, IS, GS)\
693 _SV_DECL_PTRARR_SORT(nm, AE, IS, GS, )
694 
695 #define SV_DECL_PTRARR_SORT_VISIBILITY(nm, AE, IS, GS, vis)\
696 _SV_DECL_PTRARR_SORT(nm, AE, IS, GS, vis)
697 
698 
699 #define _SV_DECL_PTRARR_SORT_DEL(nm, AE, IS, GS, vis)\
700 _SV_DECL_PTRARR_SORT_ALG(nm, AE, IS, GS, vis)\
701 	~nm() { DeleteAndDestroy( 0, Count() ); }\
702 private:\
703 	nm( const nm& );\
704 	nm& operator=( const nm& );\
705 };
706 
707 #define SV_DECL_PTRARR_SORT_DEL(nm, AE, IS, GS)\
708 _SV_DECL_PTRARR_SORT_DEL(nm, AE, IS, GS, )
709 
710 #define SV_DECL_PTRARR_SORT_DEL_VISIBILITY(nm, AE, IS, GS, vis)\
711 _SV_DECL_PTRARR_SORT_DEL(nm, AE, IS, GS, vis)
712 
713 #define _SV_DECL_VARARR_SORT(nm, AE, IS, GS, vis)\
714 SV_DECL_VARARR_VISIBILITY(nm##_SAR, AE, IS, GS, vis)\
715 _SORT_CLASS_DEF(nm, AE, IS, GS, vis) \
716 	const AE& operator[](sal_uInt16 nP) const {\
717 		return nm##_SAR::operator[]( nP );\
718 	}\
719 	const AE& GetObject(sal_uInt16 nP) const {\
720 		return nm##_SAR::GetObject( nP );\
721 	}\
722 	sal_Bool Seek_Entry( const AE & aE, sal_uInt16* pP = 0 ) const;\
723 	void ForEach( CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\
724 	{\
725 		_ForEach( 0, nA, (FnForEach_##nm##_SAR)fnForEach, pArgs );\
726 	}\
727 	void ForEach( sal_uInt16 nS, sal_uInt16 nE, \
728 					CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\
729 	{\
730 		_ForEach( nS, nE, (FnForEach_##nm##_SAR)fnForEach, pArgs );\
731 	}\
732 private:\
733 	nm( const nm& );\
734 	nm& operator=( const nm& );\
735 };
736 
737 #define SV_DECL_VARARR_SORT(nm, AE, IS, GS)\
738 _SV_DECL_VARARR_SORT(nm, AE, IS, GS,)
739 
740 #define SV_DECL_VARARR_SORT_VISIBILITY(nm, AE, IS, GS, vis)\
741 _SV_DECL_VARARR_SORT(nm, AE, IS, GS, vis)
742 
743 #define SV_IMPL_PTRARR_SORT( nm,AE )\
744 _SV_IMPL_SORTAR_ALG( nm,AE )\
745 	void nm::DeleteAndDestroy( sal_uInt16 nP, sal_uInt16 nL ) { \
746 		if( nL ) {\
747 			DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );\
748 			for( sal_uInt16 n=nP; n < nP + nL; n++ ) \
749 				delete *((AE*)pData+n); \
750 			SvPtrarr::Remove( nP, nL ); \
751 		} \
752 	} \
753 _SV_SEEK_PTR( nm, AE )
754 
755 #define SV_IMPL_OP_PTRARR_SORT( nm,AE )\
756 _SV_IMPL_SORTAR_ALG( nm,AE )\
757 	void nm::DeleteAndDestroy( sal_uInt16 nP, sal_uInt16 nL ) { \
758 		if( nL ) {\
759 			DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );\
760 			for( sal_uInt16 n=nP; n < nP + nL; n++ ) \
761 				delete *((AE*)pData+n); \
762 			SvPtrarr::Remove( nP, nL ); \
763 		} \
764 	} \
765 _SV_SEEK_PTR_TO_OBJECT( nm,AE )
766 
767 #define SV_IMPL_VARARR_SORT( nm,AE )\
768 SV_IMPL_VARARR(nm##_SAR, AE)\
769 _SV_IMPL_SORTAR_ALG( nm,AE )\
770 _SV_SEEK_OBJECT( nm,AE )
771 
772 #define C40_INSERT( c, p, n ) Insert( (c const *&) p, n )
773 #define C40_PTR_INSERT( c, p ) Insert( (c const *&) p )
774 #define C40_REPLACE( c, p, n ) Replace( (c const *&) p, n )
775 #define C40_GETPOS( c, r) GetPos( (c const *&) r )
776 
777 #endif	//_SVARRAY_HXX
778