xref: /aoo42x/main/svl/source/items/nranges.cxx (revision 40df464e)
1*40df464eSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*40df464eSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*40df464eSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*40df464eSAndrew Rist  * distributed with this work for additional information
6*40df464eSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*40df464eSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*40df464eSAndrew Rist  * "License"); you may not use this file except in compliance
9*40df464eSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*40df464eSAndrew Rist  *
11*40df464eSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*40df464eSAndrew Rist  *
13*40df464eSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*40df464eSAndrew Rist  * software distributed under the License is distributed on an
15*40df464eSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*40df464eSAndrew Rist  * KIND, either express or implied.  See the License for the
17*40df464eSAndrew Rist  * specific language governing permissions and limitations
18*40df464eSAndrew Rist  * under the License.
19*40df464eSAndrew Rist  *
20*40df464eSAndrew Rist  *************************************************************/
21*40df464eSAndrew Rist 
22*40df464eSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svl.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir // compiled via include from itemset.cxx only!
28cdf0e10cSrcweir 
29cdf0e10cSrcweir //========================================================================
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #ifdef DBG_UTIL
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #define DBG_CHECK_RANGES(NUMTYPE, pArr)									\
34cdf0e10cSrcweir 	for ( const NUMTYPE *pRange = pArr; *pRange; pRange += 2 )          \
35cdf0e10cSrcweir 	{                                                                   \
36cdf0e10cSrcweir 		DBG_ASSERT( pRange[0] <= pRange[1], "ranges must be sorted" );  \
37cdf0e10cSrcweir 		DBG_ASSERT( !pRange[2] || ( pRange[2] - pRange[1] ) > 1,        \
38cdf0e10cSrcweir 					"ranges must be sorted and discrete" );             \
39cdf0e10cSrcweir 	}
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #else
42cdf0e10cSrcweir 
43cdf0e10cSrcweir #define DBG_CHECK_RANGES(NUMTYPE,pArr)
44cdf0e10cSrcweir 
45cdf0e10cSrcweir #endif
46cdf0e10cSrcweir 
47cdf0e10cSrcweir //============================================================================
Swap_Impl(const NUMTYPE * & rp1,const NUMTYPE * & rp2)48cdf0e10cSrcweir inline void Swap_Impl(const NUMTYPE *& rp1, const NUMTYPE *& rp2)
49cdf0e10cSrcweir {
50cdf0e10cSrcweir 	const NUMTYPE * pTemp = rp1;
51cdf0e10cSrcweir 	rp1 = rp2;
52cdf0e10cSrcweir 	rp2 = pTemp;
53cdf0e10cSrcweir }
54cdf0e10cSrcweir 
55cdf0e10cSrcweir //========================================================================
56cdf0e10cSrcweir 
InitializeRanges_Impl(NUMTYPE * & rpRanges,va_list pArgs,NUMTYPE nWh1,NUMTYPE nWh2,NUMTYPE nNull)57cdf0e10cSrcweir NUMTYPE InitializeRanges_Impl( NUMTYPE *&rpRanges, va_list pArgs,
58cdf0e10cSrcweir 							   NUMTYPE nWh1, NUMTYPE nWh2, NUMTYPE nNull )
59cdf0e10cSrcweir 
60cdf0e10cSrcweir /**	<H3>Description</H3>
61cdf0e10cSrcweir 
62cdf0e10cSrcweir 	Creates an sal_uInt16-ranges-array in 'rpRanges' using 'nWh1' and 'nWh2' as
63cdf0e10cSrcweir 	first range, 'nNull' as terminator or start of 2nd range and 'pArgs' as
64cdf0e10cSrcweir 	remaider.
65cdf0e10cSrcweir 
66cdf0e10cSrcweir 	It returns the number of NUMTYPEs which are contained in the described
67cdf0e10cSrcweir 	set of NUMTYPEs.
68cdf0e10cSrcweir */
69cdf0e10cSrcweir 
70cdf0e10cSrcweir {
71cdf0e10cSrcweir 	NUMTYPE nSize = 0, nIns = 0;
72cdf0e10cSrcweir     sal_uInt16 nCnt = 0;
73cdf0e10cSrcweir 	SvNums aNumArr( 11, 8 );
74cdf0e10cSrcweir 	aNumArr.Insert( nWh1, nCnt++ );
75cdf0e10cSrcweir 	aNumArr.Insert( nWh2, nCnt++ );
76cdf0e10cSrcweir 	DBG_ASSERT( nWh1 <= nWh2, "Ungueltiger Bereich" );
77cdf0e10cSrcweir 	nSize += nWh2 - nWh1 + 1;
78cdf0e10cSrcweir 	aNumArr.Insert( nNull, nCnt++ );
79cdf0e10cSrcweir 	while ( 0 !=
80cdf0e10cSrcweir             ( nIns =
81cdf0e10cSrcweir               sal::static_int_cast< NUMTYPE >(
82cdf0e10cSrcweir                   va_arg( pArgs, NUMTYPE_ARG ) ) ) )
83cdf0e10cSrcweir 	{
84cdf0e10cSrcweir 		aNumArr.Insert( nIns, nCnt++ );
85cdf0e10cSrcweir 		if ( 0 == (nCnt & 1) )		 // 4,6,8, usw.
86cdf0e10cSrcweir 		{
87cdf0e10cSrcweir 			DBG_ASSERT( aNumArr[ nCnt-2 ] <= nIns, "Ungueltiger Bereich" );
88cdf0e10cSrcweir 			nSize += nIns - aNumArr[ nCnt-2 ] + 1;
89cdf0e10cSrcweir 		}
90cdf0e10cSrcweir 	}
91cdf0e10cSrcweir 	va_end( pArgs );
92cdf0e10cSrcweir 
93cdf0e10cSrcweir 	DBG_ASSERT( 0 == (nCnt & 1), "ungerade Anzahl von Which-Paaren!" );
94cdf0e10cSrcweir 
95cdf0e10cSrcweir 	// so, jetzt sind alle Bereiche vorhanden und
96cdf0e10cSrcweir 	rpRanges = new NUMTYPE[ nCnt+1 ];
97cdf0e10cSrcweir 	memcpy( rpRanges, aNumArr.GetData(), sizeof(NUMTYPE) * nCnt );
98cdf0e10cSrcweir 	*(rpRanges+nCnt) = 0;
99cdf0e10cSrcweir 
100cdf0e10cSrcweir 	return nSize;
101cdf0e10cSrcweir }
102cdf0e10cSrcweir 
103cdf0e10cSrcweir //------------------------------------------------------------------------
104cdf0e10cSrcweir 
Count_Impl(const NUMTYPE * pRanges)105cdf0e10cSrcweir NUMTYPE Count_Impl( const NUMTYPE *pRanges )
106cdf0e10cSrcweir 
107cdf0e10cSrcweir /**	<H3>Description</H3>
108cdf0e10cSrcweir 
109cdf0e10cSrcweir 	Determines the number of NUMTYPEs in an 0-terminated array of pairs of
110cdf0e10cSrcweir 	NUMTYPEs. The terminating 0 is not included in the count.
111cdf0e10cSrcweir */
112cdf0e10cSrcweir 
113cdf0e10cSrcweir {
114cdf0e10cSrcweir 	NUMTYPE nCount = 0;
115cdf0e10cSrcweir 	while ( *pRanges )
116cdf0e10cSrcweir 	{
117cdf0e10cSrcweir 		nCount += 2;
118cdf0e10cSrcweir 		pRanges += 2;
119cdf0e10cSrcweir 	}
120cdf0e10cSrcweir 	return nCount;
121cdf0e10cSrcweir }
122cdf0e10cSrcweir 
123cdf0e10cSrcweir //------------------------------------------------------------------------
124cdf0e10cSrcweir 
Capacity_Impl(const NUMTYPE * pRanges)125cdf0e10cSrcweir NUMTYPE Capacity_Impl( const NUMTYPE *pRanges )
126cdf0e10cSrcweir 
127cdf0e10cSrcweir /**	<H3>Description</H3>
128cdf0e10cSrcweir 
129cdf0e10cSrcweir 	Determines the total number of NUMTYPEs described in an 0-terminated
130cdf0e10cSrcweir 	array of pairs of NUMTYPEs, each representing an range of NUMTYPEs.
131cdf0e10cSrcweir */
132cdf0e10cSrcweir 
133cdf0e10cSrcweir {
134cdf0e10cSrcweir 	NUMTYPE nCount = 0;
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 	if ( pRanges )
137cdf0e10cSrcweir 	{
138cdf0e10cSrcweir 		while ( *pRanges )
139cdf0e10cSrcweir 		{
140cdf0e10cSrcweir 			nCount += pRanges[1] - pRanges[0] + 1;
141cdf0e10cSrcweir 			pRanges += 2;
142cdf0e10cSrcweir 		}
143cdf0e10cSrcweir 	}
144cdf0e10cSrcweir 	return nCount;
145cdf0e10cSrcweir }
146cdf0e10cSrcweir 
147cdf0e10cSrcweir //------------------------------------------------------------------------
148cdf0e10cSrcweir 
SfxNumRanges(const SfxNumRanges & rOrig)149cdf0e10cSrcweir SfxNumRanges::SfxNumRanges( const SfxNumRanges &rOrig )
150cdf0e10cSrcweir 
151cdf0e10cSrcweir /**	<H3>Description</H3>
152cdf0e10cSrcweir 
153cdf0e10cSrcweir 	Copy-Ctor.
154cdf0e10cSrcweir */
155cdf0e10cSrcweir 
156cdf0e10cSrcweir {
157cdf0e10cSrcweir 	if ( rOrig._pRanges )
158cdf0e10cSrcweir 	{
159cdf0e10cSrcweir 		NUMTYPE nCount = Count_Impl( rOrig._pRanges ) + 1;
160cdf0e10cSrcweir 		_pRanges = new NUMTYPE[nCount];
161cdf0e10cSrcweir 		memcpy( _pRanges, rOrig._pRanges, sizeof(NUMTYPE) * nCount );
162cdf0e10cSrcweir 	}
163cdf0e10cSrcweir 	else
164cdf0e10cSrcweir 		_pRanges = 0;
165cdf0e10cSrcweir }
166cdf0e10cSrcweir 
167cdf0e10cSrcweir //------------------------------------------------------------------------
168cdf0e10cSrcweir 
SfxNumRanges(NUMTYPE nWhich1,NUMTYPE nWhich2)169cdf0e10cSrcweir SfxNumRanges::SfxNumRanges( NUMTYPE nWhich1, NUMTYPE nWhich2 )
170cdf0e10cSrcweir 
171cdf0e10cSrcweir /**	<H3>Description</H3>
172cdf0e10cSrcweir 
173cdf0e10cSrcweir 	Constructs an SfxNumRanges-instance from one range of NUMTYPEs.
174cdf0e10cSrcweir 
175cdf0e10cSrcweir 	precondition:
176cdf0e10cSrcweir 		nWhich1 <= nWhich2
177cdf0e10cSrcweir */
178cdf0e10cSrcweir 
179cdf0e10cSrcweir :   _pRanges( new NUMTYPE[3] )
180cdf0e10cSrcweir {
181cdf0e10cSrcweir 	_pRanges[0] = nWhich1;
182cdf0e10cSrcweir 	_pRanges[1] = nWhich2;
183cdf0e10cSrcweir 	_pRanges[2] = 0;
184cdf0e10cSrcweir }
185cdf0e10cSrcweir 
186cdf0e10cSrcweir //------------------------------------------------------------------------
187cdf0e10cSrcweir 
SfxNumRanges(NUMTYPE_ARG nWh0,NUMTYPE_ARG nWh1,NUMTYPE_ARG nNull,...)188cdf0e10cSrcweir SfxNumRanges::SfxNumRanges( NUMTYPE_ARG nWh0, NUMTYPE_ARG nWh1, NUMTYPE_ARG nNull, ... )
189cdf0e10cSrcweir 
190cdf0e10cSrcweir /**	<H3>Description</H3>
191cdf0e10cSrcweir 
192cdf0e10cSrcweir 	Constructs an SfxNumRanges-instance from more than one sorted ranges of
193cdf0e10cSrcweir 	NUMTYPEs terminated with one 0.
194cdf0e10cSrcweir 
195cdf0e10cSrcweir 	precondition: for each n >= 0 && n < nArgs
196cdf0e10cSrcweir 		nWh(2n) <= nWh(2n+1) && ( nWh(2n+2)-nWh(2n+1) ) > 1
197cdf0e10cSrcweir */
198cdf0e10cSrcweir 
199cdf0e10cSrcweir {
200cdf0e10cSrcweir 	va_list pArgs;
201cdf0e10cSrcweir 	va_start( pArgs, nNull );
202cdf0e10cSrcweir 	InitializeRanges_Impl(
203cdf0e10cSrcweir         _pRanges, pArgs, sal::static_int_cast< NUMTYPE >(nWh0),
204cdf0e10cSrcweir         sal::static_int_cast< NUMTYPE >(nWh1),
205cdf0e10cSrcweir         sal::static_int_cast< NUMTYPE >(nNull));
206cdf0e10cSrcweir 	DBG_CHECK_RANGES(NUMTYPE, _pRanges);
207cdf0e10cSrcweir }
208cdf0e10cSrcweir 
209cdf0e10cSrcweir //------------------------------------------------------------------------
210cdf0e10cSrcweir 
SfxNumRanges(const NUMTYPE * pArr)211cdf0e10cSrcweir SfxNumRanges::SfxNumRanges( const NUMTYPE* pArr )
212cdf0e10cSrcweir 
213cdf0e10cSrcweir /**	<H3>Description</H3>
214cdf0e10cSrcweir 
215cdf0e10cSrcweir 	Constcurts an SfxNumRanges-instance from an sorted ranges of NUMTYPEs,
216cdf0e10cSrcweir 	terminates with on 0.
217cdf0e10cSrcweir 
218cdf0e10cSrcweir 	precondition: for each n >= 0 && n < (sizeof(pArr)-1)
219cdf0e10cSrcweir 		pArr[2n] <= pArr[2n+1] && ( pArr[2n+2]-pArr[2n+1] ) > 1
220cdf0e10cSrcweir */
221cdf0e10cSrcweir 
222cdf0e10cSrcweir {
223cdf0e10cSrcweir 	DBG_CHECK_RANGES(NUMTYPE, pArr);
224cdf0e10cSrcweir 	NUMTYPE nCount = Count_Impl(pArr) + 1;
225cdf0e10cSrcweir 	_pRanges = new NUMTYPE[ nCount ];
226cdf0e10cSrcweir 	memcpy( _pRanges, pArr, sizeof(NUMTYPE) * nCount );
227cdf0e10cSrcweir }
228cdf0e10cSrcweir 
229cdf0e10cSrcweir //------------------------------------------------------------------------
230cdf0e10cSrcweir 
operator ==(const SfxNumRanges & rOther) const231cdf0e10cSrcweir sal_Bool SfxNumRanges::operator==( const SfxNumRanges &rOther ) const
232cdf0e10cSrcweir {
233cdf0e10cSrcweir 	// Object pointers equal?
234cdf0e10cSrcweir 	if ( this == &rOther )
235cdf0e10cSrcweir 		return sal_True;
236cdf0e10cSrcweir 
237cdf0e10cSrcweir 	// Ranges pointers equal?
238cdf0e10cSrcweir 	if ( _pRanges == rOther._pRanges )
239cdf0e10cSrcweir 		return sal_True;
240cdf0e10cSrcweir 
241cdf0e10cSrcweir 	// Counts equal?
242cdf0e10cSrcweir 	NUMTYPE nCount = Count();
243cdf0e10cSrcweir 	if ( nCount != rOther.Count() )
244cdf0e10cSrcweir 		return sal_False;
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 	// Check arrays.
247cdf0e10cSrcweir 	NUMTYPE n = 0;
248cdf0e10cSrcweir 	while( _pRanges[ n ] != 0 )
249cdf0e10cSrcweir 	{
250cdf0e10cSrcweir 		// Elements at current position equal?
251cdf0e10cSrcweir 		if ( _pRanges[ n ] != rOther._pRanges[ n ] )
252cdf0e10cSrcweir 			return sal_False;
253cdf0e10cSrcweir 
254cdf0e10cSrcweir 		++n;
255cdf0e10cSrcweir 	}
256cdf0e10cSrcweir 
257cdf0e10cSrcweir 	return sal_True;
258cdf0e10cSrcweir }
259cdf0e10cSrcweir 
260cdf0e10cSrcweir //------------------------------------------------------------------------
261cdf0e10cSrcweir 
operator =(const SfxNumRanges & rRanges)262cdf0e10cSrcweir SfxNumRanges& SfxNumRanges::operator =
263cdf0e10cSrcweir (
264cdf0e10cSrcweir 	const SfxNumRanges &rRanges
265cdf0e10cSrcweir )
266cdf0e10cSrcweir 
267cdf0e10cSrcweir /**	<H3>Description</H3>
268cdf0e10cSrcweir 
269cdf0e10cSrcweir 	Assigns ranges from 'rRanges' to '*this'.
270cdf0e10cSrcweir */
271cdf0e10cSrcweir 
272cdf0e10cSrcweir {
273cdf0e10cSrcweir 	// special case: assign itself
274cdf0e10cSrcweir 	if ( &rRanges == this )
275cdf0e10cSrcweir 		return *this;
276cdf0e10cSrcweir 
277cdf0e10cSrcweir 	delete[] _pRanges;
278cdf0e10cSrcweir 
279cdf0e10cSrcweir 	// special case: 'rRanges' is empty
280cdf0e10cSrcweir 	if ( rRanges.IsEmpty() )
281cdf0e10cSrcweir 		_pRanges = 0;
282cdf0e10cSrcweir 	else
283cdf0e10cSrcweir 	{
284cdf0e10cSrcweir 		// copy ranges
285cdf0e10cSrcweir 		NUMTYPE nCount = Count_Impl( rRanges._pRanges ) + 1;
286cdf0e10cSrcweir 		_pRanges = new NUMTYPE[ nCount ];
287cdf0e10cSrcweir 		memcpy( _pRanges, rRanges._pRanges, sizeof(NUMTYPE) * nCount );
288cdf0e10cSrcweir 	}
289cdf0e10cSrcweir 	return *this;
290cdf0e10cSrcweir }
291cdf0e10cSrcweir 
292cdf0e10cSrcweir //------------------------------------------------------------------------
293cdf0e10cSrcweir 
operator +=(const SfxNumRanges & rRanges)294cdf0e10cSrcweir SfxNumRanges& SfxNumRanges::operator +=
295cdf0e10cSrcweir (
296cdf0e10cSrcweir 	const SfxNumRanges &rRanges
297cdf0e10cSrcweir )
298cdf0e10cSrcweir 
299cdf0e10cSrcweir /**	<H3>Description</H3>
300cdf0e10cSrcweir 
301cdf0e10cSrcweir 	Merges *this with 'rRanges'.
302cdf0e10cSrcweir 
303cdf0e10cSrcweir 	for each NUMTYPE n:
304cdf0e10cSrcweir 		this->Contains( n ) || rRanges.Contains( n ) => this'->Contains( n )
305cdf0e10cSrcweir 		!this->Contains( n ) && !rRanges.Contains( n ) => !this'->Contains( n )
306cdf0e10cSrcweir */
307cdf0e10cSrcweir 
308cdf0e10cSrcweir {
309cdf0e10cSrcweir 	// special cases: one is empty
310cdf0e10cSrcweir 	if ( rRanges.IsEmpty() )
311cdf0e10cSrcweir 		return *this;
312cdf0e10cSrcweir 	if ( IsEmpty() )
313cdf0e10cSrcweir 		return *this = rRanges;
314cdf0e10cSrcweir 
315cdf0e10cSrcweir 	// First, run thru _pRanges and rRanges._pRanges and determine the size of
316cdf0e10cSrcweir 	// the new, merged ranges:
317cdf0e10cSrcweir 	NUMTYPE nCount = 0;
318cdf0e10cSrcweir 	const NUMTYPE * pRA = _pRanges;
319cdf0e10cSrcweir 	const NUMTYPE * pRB = rRanges._pRanges;
320cdf0e10cSrcweir 
321cdf0e10cSrcweir 	for (;;)
322cdf0e10cSrcweir 	{
323cdf0e10cSrcweir 		// The first pair of pRA has a lower lower bound than the first pair
324cdf0e10cSrcweir 		// of pRB:
325cdf0e10cSrcweir 		if (pRA[0] > pRB[0])
326cdf0e10cSrcweir 			Swap_Impl(pRA, pRB);
327cdf0e10cSrcweir 
328cdf0e10cSrcweir 		// We are done with the merging if at least pRA is exhausted:
329cdf0e10cSrcweir 		if (!pRA[0])
330cdf0e10cSrcweir 			break;
331cdf0e10cSrcweir 
332cdf0e10cSrcweir 		for (;;)
333cdf0e10cSrcweir 		{
334cdf0e10cSrcweir 			// Skip those pairs in pRB that completely lie in the first pair
335cdf0e10cSrcweir 			// of pRA:
336cdf0e10cSrcweir 			while (pRB[1] <= pRA[1])
337cdf0e10cSrcweir 			{
338cdf0e10cSrcweir 				pRB += 2;
339cdf0e10cSrcweir 
340cdf0e10cSrcweir 				// Watch out for exhaustion of pRB:
341cdf0e10cSrcweir 				if (!pRB[0])
342cdf0e10cSrcweir 				{
343cdf0e10cSrcweir 					Swap_Impl(pRA, pRB);
344cdf0e10cSrcweir 					goto count_rest;
345cdf0e10cSrcweir 				}
346cdf0e10cSrcweir 			}
347cdf0e10cSrcweir 
348cdf0e10cSrcweir 			// If the next pair of pRA does not at least touch the current new
349cdf0e10cSrcweir 			// pair, we are done with the current new pair:
350cdf0e10cSrcweir 			if (pRB[0] > pRA[1] + 1)
351cdf0e10cSrcweir 				break;
352cdf0e10cSrcweir 
353cdf0e10cSrcweir 			// The next pair of pRB extends the current new pair; first,
354cdf0e10cSrcweir 			// extend the current new pair (we are done if pRB is then
355cdf0e10cSrcweir 			// exhausted); second, switch the roles of pRA and pRB in order to
356cdf0e10cSrcweir 			// merge in those following pairs of the original pRA that will
357cdf0e10cSrcweir 			// lie in the (now larger) current new pair or will even extend it
358cdf0e10cSrcweir 			// further:
359cdf0e10cSrcweir 			pRA += 2;
360cdf0e10cSrcweir 			if (!pRA[0])
361cdf0e10cSrcweir 				goto count_rest;
362cdf0e10cSrcweir 			Swap_Impl(pRA, pRB);
363cdf0e10cSrcweir 		}
364cdf0e10cSrcweir 
365cdf0e10cSrcweir 		// Done with the current new pair:
366cdf0e10cSrcweir 		pRA += 2;
367cdf0e10cSrcweir 		nCount += 2;
368cdf0e10cSrcweir 	}
369cdf0e10cSrcweir 
370cdf0e10cSrcweir 	// Only pRB has more pairs available, pRA is already exhausted:
371cdf0e10cSrcweir count_rest:
372cdf0e10cSrcweir 	for (; pRB[0]; pRB += 2)
373cdf0e10cSrcweir 		nCount += 2;
374cdf0e10cSrcweir 
375cdf0e10cSrcweir 	// Now, create new ranges of the correct size and, on a second run thru
376cdf0e10cSrcweir 	// _pRanges and rRanges._pRanges, copy the merged pairs into the new
377cdf0e10cSrcweir 	// ranges:
378cdf0e10cSrcweir 	NUMTYPE * pNew = new NUMTYPE[nCount + 1];
379cdf0e10cSrcweir 	pRA = _pRanges;
380cdf0e10cSrcweir 	pRB = rRanges._pRanges;
381cdf0e10cSrcweir 	NUMTYPE * pRN = pNew;
382cdf0e10cSrcweir 
383cdf0e10cSrcweir 	for (;;)
384cdf0e10cSrcweir 	{
385cdf0e10cSrcweir 		// The first pair of pRA has a lower lower bound than the first pair
386cdf0e10cSrcweir 		// of pRB:
387cdf0e10cSrcweir 		if (pRA[0] > pRB[0])
388cdf0e10cSrcweir 			Swap_Impl(pRA, pRB);
389cdf0e10cSrcweir 
390cdf0e10cSrcweir 		// We are done with the merging if at least pRA is exhausted:
391cdf0e10cSrcweir 		if (!pRA[0])
392cdf0e10cSrcweir 			break;
393cdf0e10cSrcweir 
394cdf0e10cSrcweir 		// Lower bound of current new pair is already known:
395cdf0e10cSrcweir 		*pRN++ = pRA[0];
396cdf0e10cSrcweir 
397cdf0e10cSrcweir 		for (;;)
398cdf0e10cSrcweir 		{
399cdf0e10cSrcweir 			// Skip those pairs in pRB that completely lie in the first pair
400cdf0e10cSrcweir 			// of pRA:
401cdf0e10cSrcweir 			while (pRB[1] <= pRA[1])
402cdf0e10cSrcweir 			{
403cdf0e10cSrcweir 				pRB += 2;
404cdf0e10cSrcweir 
405cdf0e10cSrcweir 				// Watch out for exhaustion of pRB:
406cdf0e10cSrcweir 				if (!pRB[0])
407cdf0e10cSrcweir 				{
408cdf0e10cSrcweir 					Swap_Impl(pRA, pRB);
409cdf0e10cSrcweir 					++pRB;
410cdf0e10cSrcweir 					goto copy_rest;
411cdf0e10cSrcweir 				}
412cdf0e10cSrcweir 			}
413cdf0e10cSrcweir 
414cdf0e10cSrcweir 			// If the next pair of pRA does not at least touch the current new
415cdf0e10cSrcweir 			// pair, we are done with the current new pair:
416cdf0e10cSrcweir 			if (pRB[0] > pRA[1] + 1)
417cdf0e10cSrcweir 				break;
418cdf0e10cSrcweir 
419cdf0e10cSrcweir 			// The next pair of pRB extends the current new pair; first,
420cdf0e10cSrcweir 			// extend the current new pair (we are done if pRB is then
421cdf0e10cSrcweir 			// exhausted); second, switch the roles of pRA and pRB in order to
422cdf0e10cSrcweir 			// merge in those following pairs of the original pRA that will
423cdf0e10cSrcweir 			// lie in the (now larger) current new pair or will even extend it
424cdf0e10cSrcweir 			// further:
425cdf0e10cSrcweir 			pRA += 2;
426cdf0e10cSrcweir 			if (!pRA[0])
427cdf0e10cSrcweir 			{
428cdf0e10cSrcweir 				++pRB;
429cdf0e10cSrcweir 				goto copy_rest;
430cdf0e10cSrcweir 			}
431cdf0e10cSrcweir 			Swap_Impl(pRA, pRB);
432cdf0e10cSrcweir 		}
433cdf0e10cSrcweir 
434cdf0e10cSrcweir 		// Done with the current new pair, now upper bound is also known:
435cdf0e10cSrcweir 		*pRN++ = pRA[1];
436cdf0e10cSrcweir 		pRA += 2;
437cdf0e10cSrcweir 	}
438cdf0e10cSrcweir 
439cdf0e10cSrcweir 	// Only pRB has more pairs available (which are copied to the new ranges
440cdf0e10cSrcweir 	// unchanged), pRA is already exhausted:
441cdf0e10cSrcweir copy_rest:
442cdf0e10cSrcweir 	for (; *pRB;)
443cdf0e10cSrcweir 		*pRN++ = *pRB++;
444cdf0e10cSrcweir 	*pRN = 0;
445cdf0e10cSrcweir 
446cdf0e10cSrcweir 	delete[] _pRanges;
447cdf0e10cSrcweir 	_pRanges = pNew;
448cdf0e10cSrcweir 
449cdf0e10cSrcweir 	return *this;
450cdf0e10cSrcweir }
451cdf0e10cSrcweir 
452cdf0e10cSrcweir //------------------------------------------------------------------------
453cdf0e10cSrcweir 
operator -=(const SfxNumRanges & rRanges)454cdf0e10cSrcweir SfxNumRanges& SfxNumRanges::operator -=
455cdf0e10cSrcweir (
456cdf0e10cSrcweir 	const SfxNumRanges &rRanges
457cdf0e10cSrcweir )
458cdf0e10cSrcweir 
459cdf0e10cSrcweir /**	<H3>Description</H3>
460cdf0e10cSrcweir 
461cdf0e10cSrcweir 	Removes 'rRanges' from '*this'.
462cdf0e10cSrcweir 
463cdf0e10cSrcweir 	for each NUMTYPE n:
464cdf0e10cSrcweir 		this->Contains( n ) && rRanges.Contains( n ) => !this'->Contains( n )
465cdf0e10cSrcweir 		this->Contains( n ) && !rRanges.Contains( n ) => this'->Contains( n )
466cdf0e10cSrcweir 		!this->Contains( n ) => !this'->Contains( n )
467cdf0e10cSrcweir */
468cdf0e10cSrcweir 
469cdf0e10cSrcweir {
470cdf0e10cSrcweir 	// special cases: one is empty
471cdf0e10cSrcweir 	if ( rRanges.IsEmpty() || IsEmpty() )
472cdf0e10cSrcweir 		return *this;
473cdf0e10cSrcweir 
474cdf0e10cSrcweir 	// differentiate 'rRanges' in a temporary copy of '*this'
475cdf0e10cSrcweir 	// (size is computed for maximal possibly split-count plus terminating 0)
476cdf0e10cSrcweir 	NUMTYPE nThisSize = Count_Impl(_pRanges);
477cdf0e10cSrcweir 	NUMTYPE nTargetSize = 1 + (  nThisSize + Count_Impl(rRanges._pRanges) );
478cdf0e10cSrcweir 	NUMTYPE *pTarget = new NUMTYPE[ nTargetSize ];
479cdf0e10cSrcweir 	memset( pTarget, 0, sizeof(NUMTYPE)*nTargetSize );
480cdf0e10cSrcweir 	memcpy( pTarget, _pRanges, sizeof(NUMTYPE)*nThisSize );
481cdf0e10cSrcweir 
482cdf0e10cSrcweir 	NUMTYPE nPos1 = 0, nPos2 = 0, nTargetPos = 0;
483cdf0e10cSrcweir 	while( _pRanges[ nPos1 ] )
484cdf0e10cSrcweir 	{
485cdf0e10cSrcweir 		NUMTYPE l1 = _pRanges[ nPos1 ]; 	 // lower bound of interval 1
486cdf0e10cSrcweir 		NUMTYPE u1 = _pRanges[ nPos1+1 ];	 // upper bound of interval 1
487cdf0e10cSrcweir 		NUMTYPE l2 = rRanges._pRanges[ nPos2 ]; 	 // lower bound of interval 2
488cdf0e10cSrcweir 		NUMTYPE u2 = rRanges._pRanges[ nPos2+1 ];	 // upper bound of interval 2
489cdf0e10cSrcweir 
490cdf0e10cSrcweir 		// boundary cases
491cdf0e10cSrcweir 		// * subtrahend is empty -> copy the minuend
492cdf0e10cSrcweir 		if( !l2 )
493cdf0e10cSrcweir 		{
494cdf0e10cSrcweir 			pTarget[ nTargetPos ] = l1;
495cdf0e10cSrcweir 			pTarget[ nTargetPos+1 ] = u1;
496cdf0e10cSrcweir 			nTargetPos += 2;
497cdf0e10cSrcweir 			nPos1 += 2;
498cdf0e10cSrcweir 			continue;
499cdf0e10cSrcweir 		}
500cdf0e10cSrcweir 		// * next subtrahend interval is completely higher -> copy the minuend
501cdf0e10cSrcweir 		if( u1 < l2 )
502cdf0e10cSrcweir 		{
503cdf0e10cSrcweir 			pTarget[ nTargetPos ] = l1;
504cdf0e10cSrcweir 			pTarget[ nTargetPos+1 ] = u1;
505cdf0e10cSrcweir 			nTargetPos += 2;
506cdf0e10cSrcweir 			nPos1 += 2;
507cdf0e10cSrcweir 			continue;
508cdf0e10cSrcweir 		}
509cdf0e10cSrcweir 
510cdf0e10cSrcweir 		// * next subtrahend interval is completely lower -> try next
511cdf0e10cSrcweir 		if( u2 < l1 )
512cdf0e10cSrcweir 		{
513cdf0e10cSrcweir 			nPos2 += 2;
514cdf0e10cSrcweir 			continue;
515cdf0e10cSrcweir 		}
516cdf0e10cSrcweir 
517cdf0e10cSrcweir 		// intersecting cases
518cdf0e10cSrcweir 		// * subtrahend cuts out from the beginning of the minuend
519cdf0e10cSrcweir 		if( l2 <= l1 && u2 <= u1 )
520cdf0e10cSrcweir 		{
521cdf0e10cSrcweir 			// reduce minuend interval, try again (minuend might be affected by other subtrahend intervals)
522cdf0e10cSrcweir 			_pRanges[ nPos1 ] = u2 + 1;
523cdf0e10cSrcweir 			nPos2 += 2; // this cannot hurt any longer
524cdf0e10cSrcweir 			continue;
525cdf0e10cSrcweir 		}
526cdf0e10cSrcweir 
527cdf0e10cSrcweir 		// * subtrahend cuts out from the end of the minuend
528cdf0e10cSrcweir 		if( l1 <= l2 && u1 <= u2 )
529cdf0e10cSrcweir 		{
530cdf0e10cSrcweir 			// copy remaining part of minuend (cannot be affected by other intervals)
531cdf0e10cSrcweir 			if( l1 < l2 ) // anything left at all?
532cdf0e10cSrcweir 			{
533cdf0e10cSrcweir 				pTarget[ nTargetPos ] = l1;
534cdf0e10cSrcweir 				pTarget[ nTargetPos+1 ] = l2 - 1;
535cdf0e10cSrcweir 				nTargetPos += 2;
536cdf0e10cSrcweir 				// do not increment nPos2, might affect next minuend interval, too
537cdf0e10cSrcweir 			}
538cdf0e10cSrcweir 			nPos1 += 2; // nothing left at all
539cdf0e10cSrcweir 			continue;
540cdf0e10cSrcweir 		}
541cdf0e10cSrcweir 
542cdf0e10cSrcweir 		// * subtrahend completely deletes minuend (larger or same at both ends)
543cdf0e10cSrcweir 		if( l1 >= l2 && u1 <= u2 )
544cdf0e10cSrcweir 		{
545cdf0e10cSrcweir 			nPos1 += 2; // minuend deleted
546cdf0e10cSrcweir 			// do not increment nPos2, might affect next minuend interval, too
547cdf0e10cSrcweir 			continue;
548cdf0e10cSrcweir 		}
549cdf0e10cSrcweir 
550cdf0e10cSrcweir 		// * subtrahend divides minuend into two pieces
551cdf0e10cSrcweir 		if( l1 <= l2 && u1 >= u2 ) // >= and <= since they may be something left only at one side
552cdf0e10cSrcweir 		{
553cdf0e10cSrcweir 			// left side
554cdf0e10cSrcweir 			if( l1 < l2 ) // anything left at all
555cdf0e10cSrcweir 			{
556cdf0e10cSrcweir 				pTarget[ nTargetPos ] = l1;
557cdf0e10cSrcweir 				pTarget[ nTargetPos+1 ] = l2 - 1;
558cdf0e10cSrcweir 				nTargetPos += 2;
559cdf0e10cSrcweir 			}
560cdf0e10cSrcweir 
561cdf0e10cSrcweir 			// right side
562cdf0e10cSrcweir 			if( u1 > u2 ) // anything left at all
563cdf0e10cSrcweir 			{
564cdf0e10cSrcweir 				// reduce minuend interval, try again (minuend might be affected by other subtrahend itnervals )
565cdf0e10cSrcweir 				_pRanges[ nPos1 ] = u2 + 1;
566cdf0e10cSrcweir 			}
567cdf0e10cSrcweir 
568cdf0e10cSrcweir 			// subtrahend is completely used
569cdf0e10cSrcweir 			nPos2 += 2;
570cdf0e10cSrcweir 			continue;
571cdf0e10cSrcweir 		}
572cdf0e10cSrcweir 
573cdf0e10cSrcweir 		// we should never be here
574cdf0e10cSrcweir 		DBG_ERROR( "SfxNumRanges::operator-=: internal error" );
575cdf0e10cSrcweir 	} // while
576cdf0e10cSrcweir 
577cdf0e10cSrcweir 	pTarget[ nTargetPos ] = 0;
578cdf0e10cSrcweir 
579cdf0e10cSrcweir 	// assign the differentiated ranges
580cdf0e10cSrcweir 	delete[] _pRanges;
581cdf0e10cSrcweir 
582cdf0e10cSrcweir 	NUMTYPE nUShorts = Count_Impl(pTarget) + 1;
583cdf0e10cSrcweir 	if ( 1 != nUShorts )
584cdf0e10cSrcweir 	{
585cdf0e10cSrcweir 		_pRanges = new NUMTYPE[ nUShorts ];
586cdf0e10cSrcweir 		memcpy( _pRanges, pTarget, nUShorts * sizeof(NUMTYPE) );
587cdf0e10cSrcweir 	}
588cdf0e10cSrcweir 	else
589cdf0e10cSrcweir 		_pRanges = 0;
590cdf0e10cSrcweir 
591cdf0e10cSrcweir 	delete [] pTarget;
592cdf0e10cSrcweir 	return *this;
593cdf0e10cSrcweir 
594cdf0e10cSrcweir 	/* untested code from MI commented out (MDA, 28.01.97)
595cdf0e10cSrcweir 	do
596cdf0e10cSrcweir 	{
597cdf0e10cSrcweir 		// 1st range is smaller than 2nd range?
598cdf0e10cSrcweir 		if ( pRange1[1] < pRange2[0] )
599cdf0e10cSrcweir 			// => keep 1st range
600cdf0e10cSrcweir 			pRange1 += 2;
601cdf0e10cSrcweir 
602cdf0e10cSrcweir 		// 2nd range is smaller than 1st range?
603cdf0e10cSrcweir 		else if ( pRange2[1] < pRange1[0] )
604cdf0e10cSrcweir 			// => skip 2nd range
605cdf0e10cSrcweir 			pRange2 += 2;
606cdf0e10cSrcweir 
607cdf0e10cSrcweir 		// 2nd range totally overlaps the 1st range?
608cdf0e10cSrcweir 		else if ( pRange2[0] <= pRange1[0] && pRange2[1] >= pRange1[1] )
609cdf0e10cSrcweir 			// => remove 1st range
610cdf0e10cSrcweir 			memmove( pRange1, pRange1+2, sizeof(NUMTYPE) * (pEndOfTarget-pRange1+2) );
611cdf0e10cSrcweir 
612cdf0e10cSrcweir 		// 2nd range overlaps only the beginning of 1st range?
613cdf0e10cSrcweir 		else if ( pRange2[0] <= pRange1[0] && pRange2[1] < pRange1[1] )
614cdf0e10cSrcweir 		{
615cdf0e10cSrcweir 			// => cut the beginning of 1st range and goto next 2nd range
616cdf0e10cSrcweir 			pRange1[0] = pRange2[1] + 1;
617cdf0e10cSrcweir 			pRange2 += 2;
618cdf0e10cSrcweir 		}
619cdf0e10cSrcweir 
620cdf0e10cSrcweir 		// 2nd range overlaps only the end of 1st range?
621cdf0e10cSrcweir 		else if ( pRange2[0] > pRange1[0] && pRange2[1] >= pRange1[0] )
622cdf0e10cSrcweir 			// => cut the beginning of 1st range
623cdf0e10cSrcweir 			pRange1[0] = pRange2[1]+1;
624cdf0e10cSrcweir 
625cdf0e10cSrcweir 		// 2nd range is a real subset of 1st range
626cdf0e10cSrcweir 		else
627cdf0e10cSrcweir 		{
628cdf0e10cSrcweir 			// => split 1st range and goto next 2nd range
629cdf0e10cSrcweir 			memmove( pRange1+3, pRange1+1, sizeof(NUMTYPE) * (pEndOfTarget-pRange1-1) );
630cdf0e10cSrcweir 			pRange1[1] = pRange2[0] - 1;
631cdf0e10cSrcweir 			pRange1[2] = pRange2[1] + 1;
632cdf0e10cSrcweir 			pRange1 += 2;
633cdf0e10cSrcweir 			pRange2 += 2;
634cdf0e10cSrcweir 		}
635cdf0e10cSrcweir 	}
636cdf0e10cSrcweir 	while ( *pRange1 && *pRange2 );
637cdf0e10cSrcweir 
638cdf0e10cSrcweir 	// assign the differentiated ranges
639cdf0e10cSrcweir 	delete[] _pRanges;
640cdf0e10cSrcweir 	NUMTYPE nUShorts = Count_Impl(pTarget) + 1;
641cdf0e10cSrcweir 	if ( 1 != nUShorts )
642cdf0e10cSrcweir 	{
643cdf0e10cSrcweir 		_pRanges = new NUMTYPE[ nUShorts ];
644cdf0e10cSrcweir 		memcpy( _pRanges, pTarget, nUShorts * sizeof(NUMTYPE) );
645cdf0e10cSrcweir 		_pRanges[ nUShorts-1 ] = 0;
646cdf0e10cSrcweir 	}
647cdf0e10cSrcweir 	else
648cdf0e10cSrcweir 		_pRanges = 0;
649cdf0e10cSrcweir 	return *this;
650cdf0e10cSrcweir 	*/
651cdf0e10cSrcweir }
652cdf0e10cSrcweir 
653cdf0e10cSrcweir //------------------------------------------------------------------------
654cdf0e10cSrcweir 
operator /=(const SfxNumRanges & rRanges)655cdf0e10cSrcweir SfxNumRanges& SfxNumRanges::operator /=
656cdf0e10cSrcweir (
657cdf0e10cSrcweir 	const SfxNumRanges &rRanges
658cdf0e10cSrcweir )
659cdf0e10cSrcweir 
660cdf0e10cSrcweir /**	<H3>Description</H3>
661cdf0e10cSrcweir 
662cdf0e10cSrcweir 	Determines intersection of '*this' with 'rRanges'.
663cdf0e10cSrcweir 
664cdf0e10cSrcweir 	for each NUMTYPE n:
665cdf0e10cSrcweir 		this->Contains( n ) && rRanges.Contains( n ) => this'->Contains( n )
666cdf0e10cSrcweir 		!this->Contains( n ) => !this'->Contains( n )
667cdf0e10cSrcweir 		!rRanges.Contains( n ) => !this'->Contains( n )
668cdf0e10cSrcweir */
669cdf0e10cSrcweir 
670cdf0e10cSrcweir {
671cdf0e10cSrcweir 	// boundary cases
672cdf0e10cSrcweir 	// * first set is empty -> nothing to be done
673cdf0e10cSrcweir 	// * second set is empty -> delete first set
674cdf0e10cSrcweir 	if( rRanges.IsEmpty() )
675cdf0e10cSrcweir 	{
676cdf0e10cSrcweir 		delete[] _pRanges;
677cdf0e10cSrcweir 
678cdf0e10cSrcweir 		_pRanges = new NUMTYPE[1];
679cdf0e10cSrcweir 		_pRanges[0] = 0;
680cdf0e10cSrcweir 
681cdf0e10cSrcweir 		return *this;
682cdf0e10cSrcweir 	}
683cdf0e10cSrcweir 
684cdf0e10cSrcweir 	// intersect 'rRanges' in a temporary copy of '*this'
685cdf0e10cSrcweir 	// (size is computed for maximal possibly split-count plus terminating 0)
686cdf0e10cSrcweir 	NUMTYPE nThisSize = Count_Impl(_pRanges);
687cdf0e10cSrcweir 	NUMTYPE nTargetSize = 1 + (  nThisSize + Count_Impl(rRanges._pRanges) );
688cdf0e10cSrcweir 	NUMTYPE *pTarget = new NUMTYPE[ nTargetSize ];
689cdf0e10cSrcweir 	memset( pTarget, 0, sizeof(NUMTYPE)*nTargetSize );
690cdf0e10cSrcweir 	memcpy( pTarget, _pRanges, sizeof(NUMTYPE)*nThisSize );
691cdf0e10cSrcweir 
692cdf0e10cSrcweir 	NUMTYPE nPos1 = 0, nPos2 = 0, nTargetPos = 0;
693cdf0e10cSrcweir 	while( _pRanges[ nPos1 ] != 0 && rRanges._pRanges[ nPos2 ] != 0 )
694cdf0e10cSrcweir 	{
695cdf0e10cSrcweir 		NUMTYPE l1 = _pRanges[ nPos1 ]; 	 // lower bound of interval 1
696cdf0e10cSrcweir 		NUMTYPE u1 = _pRanges[ nPos1+1 ];	 // upper bound of interval 1
697cdf0e10cSrcweir 		NUMTYPE l2 = rRanges._pRanges[ nPos2 ]; 	 // lower bound of interval 2
698cdf0e10cSrcweir 		NUMTYPE u2 = rRanges._pRanges[ nPos2+1 ];	 // upper bound of interval 2
699cdf0e10cSrcweir 
700cdf0e10cSrcweir 		if( u1 < l2 )
701cdf0e10cSrcweir 		{
702cdf0e10cSrcweir 			// current interval in s1 is completely before ci in s2
703cdf0e10cSrcweir 			nPos1 += 2;
704cdf0e10cSrcweir 			continue;
705cdf0e10cSrcweir 		}
706cdf0e10cSrcweir 		if( u2 < l1 )
707cdf0e10cSrcweir 		{
708cdf0e10cSrcweir 			// ci in s2 is completely before ci in s1
709cdf0e10cSrcweir 			nPos2 += 2;
710cdf0e10cSrcweir 			continue;
711cdf0e10cSrcweir 		}
712cdf0e10cSrcweir 
713cdf0e10cSrcweir 		// assert: there exists an intersection between ci1 and ci2
714cdf0e10cSrcweir 
715cdf0e10cSrcweir 		if( l1 <= l2 )
716cdf0e10cSrcweir 		{
717cdf0e10cSrcweir 			// c1 "is more to the left" than c2
718cdf0e10cSrcweir 
719cdf0e10cSrcweir 			if( u1 <= u2 )
720cdf0e10cSrcweir 			{
721cdf0e10cSrcweir 				pTarget[ nTargetPos ] = l2;
722cdf0e10cSrcweir 				pTarget[ nTargetPos+1 ] = u1;
723cdf0e10cSrcweir 				nTargetPos += 2;
724cdf0e10cSrcweir 				nPos1 += 2;
725cdf0e10cSrcweir 				continue;
726cdf0e10cSrcweir 			}
727cdf0e10cSrcweir 			else
728cdf0e10cSrcweir 			{
729cdf0e10cSrcweir 				pTarget[ nTargetPos ] = l2;
730cdf0e10cSrcweir 				pTarget[ nTargetPos+1 ] = u2;
731cdf0e10cSrcweir 				nTargetPos += 2;
732cdf0e10cSrcweir 				nPos2 += 2;
733cdf0e10cSrcweir 			}
734cdf0e10cSrcweir 		}
735cdf0e10cSrcweir 		else
736cdf0e10cSrcweir 		{
737cdf0e10cSrcweir 			// c2 "is more to the left" than c1"
738cdf0e10cSrcweir 
739cdf0e10cSrcweir 			if( u1 > u2 )
740cdf0e10cSrcweir 			{
741cdf0e10cSrcweir 				pTarget[ nTargetPos ] = l1;
742cdf0e10cSrcweir 				pTarget[ nTargetPos+1 ] = u2;
743cdf0e10cSrcweir 				nTargetPos += 2;
744cdf0e10cSrcweir 				nPos2 += 2;
745cdf0e10cSrcweir 			}
746cdf0e10cSrcweir 			else
747cdf0e10cSrcweir 			{
748cdf0e10cSrcweir 				pTarget[ nTargetPos ] = l1;
749cdf0e10cSrcweir 				pTarget[ nTargetPos+1 ] = u1;
750cdf0e10cSrcweir 				nTargetPos += 2;
751cdf0e10cSrcweir 				nPos1 += 2;
752cdf0e10cSrcweir 			}
753cdf0e10cSrcweir 		}
754cdf0e10cSrcweir 	}; // while
755cdf0e10cSrcweir 	pTarget[ nTargetPos ] = 0;
756cdf0e10cSrcweir 
757cdf0e10cSrcweir 	// assign the intersected ranges
758cdf0e10cSrcweir 	delete[] _pRanges;
759cdf0e10cSrcweir 
760cdf0e10cSrcweir 	NUMTYPE nUShorts = Count_Impl(pTarget) + 1;
761cdf0e10cSrcweir 	if ( 1 != nUShorts )
762cdf0e10cSrcweir 	{
763cdf0e10cSrcweir 		_pRanges = new NUMTYPE[ nUShorts ];
764cdf0e10cSrcweir 		memcpy( _pRanges, pTarget, nUShorts * sizeof(NUMTYPE) );
765cdf0e10cSrcweir 	}
766cdf0e10cSrcweir 	else
767cdf0e10cSrcweir 		_pRanges = 0;
768cdf0e10cSrcweir 
769cdf0e10cSrcweir 	delete [] pTarget;
770cdf0e10cSrcweir 	return *this;
771cdf0e10cSrcweir }
772cdf0e10cSrcweir 
773cdf0e10cSrcweir //------------------------------------------------------------------------
774cdf0e10cSrcweir 
Intersects(const SfxNumRanges & rRanges) const775cdf0e10cSrcweir sal_Bool SfxNumRanges::Intersects( const SfxNumRanges &rRanges ) const
776cdf0e10cSrcweir 
777cdf0e10cSrcweir /**	<H3>Description</H3>
778cdf0e10cSrcweir 
779cdf0e10cSrcweir 	Determines if at least one range in 'rRanges' intersects with one
780cdf0e10cSrcweir 	range in '*this'.
781cdf0e10cSrcweir 
782cdf0e10cSrcweir 	sal_True, if there is at least one with:
783cdf0e10cSrcweir 		this->Contains( n ) && rRanges.Contains( n )
784cdf0e10cSrcweir */
785cdf0e10cSrcweir 
786cdf0e10cSrcweir {
787cdf0e10cSrcweir 	// special cases: one is empty
788cdf0e10cSrcweir 	if ( rRanges.IsEmpty() || IsEmpty() )
789cdf0e10cSrcweir 		return sal_False;
790cdf0e10cSrcweir 
791cdf0e10cSrcweir 	// find at least one intersecting range
792cdf0e10cSrcweir 	const NUMTYPE *pRange1 = _pRanges;
793cdf0e10cSrcweir 	const NUMTYPE *pRange2 = rRanges._pRanges;
794cdf0e10cSrcweir 
795cdf0e10cSrcweir 	do
796cdf0e10cSrcweir 	{
797cdf0e10cSrcweir 		// 1st range is smaller than 2nd range?
798cdf0e10cSrcweir 		if ( pRange1[1] < pRange2[0] )
799cdf0e10cSrcweir 			// => keep 1st range
800cdf0e10cSrcweir 			pRange1 += 2;
801cdf0e10cSrcweir 
802cdf0e10cSrcweir 		// 2nd range is smaller than 1st range?
803cdf0e10cSrcweir 		else if ( pRange2[1] < pRange1[0] )
804cdf0e10cSrcweir 			// => skip 2nd range
805cdf0e10cSrcweir 			pRange2 += 2;
806cdf0e10cSrcweir 
807cdf0e10cSrcweir 		// the ranges are overlappung
808cdf0e10cSrcweir 		else
809cdf0e10cSrcweir 			return sal_True;
810cdf0e10cSrcweir 	}
811cdf0e10cSrcweir 	while ( *pRange2 );
812cdf0e10cSrcweir 
813cdf0e10cSrcweir 	// no intersection found
814cdf0e10cSrcweir 	return sal_False;
815cdf0e10cSrcweir }
816cdf0e10cSrcweir 
817cdf0e10cSrcweir //------------------------------------------------------------------------
818cdf0e10cSrcweir 
Count() const819cdf0e10cSrcweir NUMTYPE SfxNumRanges::Count() const
820cdf0e10cSrcweir 
821cdf0e10cSrcweir /**	<H3>Description</H3>
822cdf0e10cSrcweir 
823cdf0e10cSrcweir 	Determines the number of USHORTs in the set described by the ranges
824cdf0e10cSrcweir 	of USHORTs in '*this'.
825cdf0e10cSrcweir */
826cdf0e10cSrcweir 
827cdf0e10cSrcweir {
828cdf0e10cSrcweir 	return Capacity_Impl( _pRanges );
829cdf0e10cSrcweir }
830cdf0e10cSrcweir 
831cdf0e10cSrcweir //------------------------------------------------------------------------
832cdf0e10cSrcweir 
Contains(NUMTYPE n) const833cdf0e10cSrcweir sal_Bool SfxNumRanges::Contains( NUMTYPE n ) const
834cdf0e10cSrcweir 
835cdf0e10cSrcweir /**	<H3>Description</H3>
836cdf0e10cSrcweir 
837cdf0e10cSrcweir 	Determines if '*this' contains 'n'.
838cdf0e10cSrcweir */
839cdf0e10cSrcweir 
840cdf0e10cSrcweir {
841cdf0e10cSrcweir 	for ( NUMTYPE *pRange = _pRanges; *pRange && *pRange <= n; pRange += 2 )
842cdf0e10cSrcweir 		if ( pRange[0] <= n && n <= pRange[1] )
843cdf0e10cSrcweir 			return sal_True;
844cdf0e10cSrcweir 	return sal_False;
845cdf0e10cSrcweir 
846cdf0e10cSrcweir }
847