Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <cassert>
21 : #include <vector>
22 : // compiled via include from itemset.cxx only!
23 :
24 : //========================================================================
25 :
26 : #ifdef DBG_UTIL
27 :
28 : #define DBG_CHECK_RANGES(NUMTYPE, pArr) \
29 : for ( const NUMTYPE *pRange = pArr; *pRange; pRange += 2 ) \
30 : { \
31 : DBG_ASSERT( pRange[0] <= pRange[1], "ranges must be sorted" ); \
32 : DBG_ASSERT( !pRange[2] || ( pRange[2] - pRange[1] ) > 1, \
33 : "ranges must be sorted and discrete" ); \
34 : }
35 :
36 : #else
37 :
38 : #define DBG_CHECK_RANGES(NUMTYPE,pArr)
39 :
40 : #endif
41 :
42 : //============================================================================
43 0 : inline void Swap_Impl(const NUMTYPE *& rp1, const NUMTYPE *& rp2)
44 : {
45 0 : const NUMTYPE * pTemp = rp1;
46 0 : rp1 = rp2;
47 0 : rp2 = pTemp;
48 0 : }
49 :
50 : //========================================================================
51 :
52 12306 : NUMTYPE InitializeRanges_Impl( NUMTYPE *&rpRanges, va_list pArgs,
53 : NUMTYPE nWh1, NUMTYPE nWh2, NUMTYPE nNull )
54 :
55 : /** <H3>Description</H3>
56 :
57 : Creates an sal_uInt16-ranges-array in 'rpRanges' using 'nWh1' and 'nWh2' as
58 : first range, 'nNull' as terminator or start of 2nd range and 'pArgs' as
59 : remaider.
60 :
61 : It returns the number of NUMTYPEs which are contained in the described
62 : set of NUMTYPEs.
63 : */
64 :
65 : {
66 12306 : NUMTYPE nSize = 0, nIns = 0;
67 12306 : std::vector<NUMTYPE> aNumArr;
68 12306 : aNumArr.push_back( nWh1 );
69 12306 : aNumArr.push_back( nWh2 );
70 : DBG_ASSERT( nWh1 <= nWh2, "Ungueltiger Bereich" );
71 12306 : nSize += nWh2 - nWh1 + 1;
72 12306 : aNumArr.push_back( nNull );
73 12306 : bool bEndOfRange = false;
74 108710 : while ( 0 !=
75 : ( nIns =
76 : sal::static_int_cast< NUMTYPE >(
77 96404 : va_arg( pArgs, NUMTYPE_ARG ) ) ) )
78 : {
79 84098 : bEndOfRange = !bEndOfRange;
80 84098 : if ( bEndOfRange )
81 : {
82 48202 : const NUMTYPE nPrev(*aNumArr.rbegin());
83 : DBG_ASSERT( nPrev <= nIns, "Ungueltiger Bereich" );
84 48202 : nSize += nIns - nPrev + 1;
85 : }
86 84098 : aNumArr.push_back( nIns );
87 : }
88 :
89 : assert( bEndOfRange ); // odd number of Which-IDs
90 :
91 : // so, jetzt sind alle Bereiche vorhanden und
92 12306 : rpRanges = new NUMTYPE[ aNumArr.size() + 1 ];
93 12306 : std::copy( aNumArr.begin(), aNumArr.end(), rpRanges);
94 12306 : *(rpRanges + aNumArr.size()) = 0;
95 :
96 12306 : return nSize;
97 : }
98 :
99 : //------------------------------------------------------------------------
100 :
101 0 : NUMTYPE Count_Impl( const NUMTYPE *pRanges )
102 :
103 : /** <H3>Description</H3>
104 :
105 : Determines the number of NUMTYPEs in an 0-terminated array of pairs of
106 : NUMTYPEs. The terminating 0 is not included in the count.
107 : */
108 :
109 : {
110 0 : NUMTYPE nCount = 0;
111 0 : while ( *pRanges )
112 : {
113 0 : nCount += 2;
114 0 : pRanges += 2;
115 : }
116 0 : return nCount;
117 : }
118 :
119 : //------------------------------------------------------------------------
120 :
121 0 : NUMTYPE Capacity_Impl( const NUMTYPE *pRanges )
122 :
123 : /** <H3>Description</H3>
124 :
125 : Determines the total number of NUMTYPEs described in an 0-terminated
126 : array of pairs of NUMTYPEs, each representing an range of NUMTYPEs.
127 : */
128 :
129 : {
130 0 : NUMTYPE nCount = 0;
131 :
132 0 : if ( pRanges )
133 : {
134 0 : while ( *pRanges )
135 : {
136 0 : nCount += pRanges[1] - pRanges[0] + 1;
137 0 : pRanges += 2;
138 : }
139 : }
140 0 : return nCount;
141 : }
142 :
143 : //------------------------------------------------------------------------
144 :
145 0 : SfxNumRanges::SfxNumRanges( const SfxNumRanges &rOrig )
146 :
147 : /** <H3>Description</H3>
148 :
149 : Copy-Ctor.
150 : */
151 :
152 : {
153 0 : if ( rOrig._pRanges )
154 : {
155 0 : NUMTYPE nCount = Count_Impl( rOrig._pRanges ) + 1;
156 0 : _pRanges = new NUMTYPE[nCount];
157 0 : memcpy( _pRanges, rOrig._pRanges, sizeof(NUMTYPE) * nCount );
158 : }
159 : else
160 0 : _pRanges = 0;
161 0 : }
162 :
163 : //------------------------------------------------------------------------
164 :
165 0 : SfxNumRanges::SfxNumRanges( NUMTYPE nWhich1, NUMTYPE nWhich2 )
166 :
167 : /** <H3>Description</H3>
168 :
169 : Constructs an SfxNumRanges-instance from one range of NUMTYPEs.
170 :
171 : precondition:
172 : nWhich1 <= nWhich2
173 : */
174 :
175 0 : : _pRanges( new NUMTYPE[3] )
176 : {
177 0 : _pRanges[0] = nWhich1;
178 0 : _pRanges[1] = nWhich2;
179 0 : _pRanges[2] = 0;
180 0 : }
181 :
182 : //------------------------------------------------------------------------
183 :
184 0 : SfxNumRanges::SfxNumRanges( const NUMTYPE* pArr )
185 :
186 : /** <H3>Description</H3>
187 :
188 : Constcurts an SfxNumRanges-instance from an sorted ranges of NUMTYPEs,
189 : terminates with on 0.
190 :
191 : precondition: for each n >= 0 && n < (sizeof(pArr)-1)
192 : pArr[2n] <= pArr[2n+1] && ( pArr[2n+2]-pArr[2n+1] ) > 1
193 : */
194 :
195 : {
196 : DBG_CHECK_RANGES(NUMTYPE, pArr);
197 0 : NUMTYPE nCount = Count_Impl(pArr) + 1;
198 0 : _pRanges = new NUMTYPE[ nCount ];
199 0 : memcpy( _pRanges, pArr, sizeof(NUMTYPE) * nCount );
200 0 : }
201 :
202 : //------------------------------------------------------------------------
203 :
204 0 : sal_Bool SfxNumRanges::operator==( const SfxNumRanges &rOther ) const
205 : {
206 : // Object pointers equal?
207 0 : if ( this == &rOther )
208 0 : return sal_True;
209 :
210 : // Ranges pointers equal?
211 0 : if ( _pRanges == rOther._pRanges )
212 0 : return sal_True;
213 :
214 : // Counts equal?
215 0 : NUMTYPE nCount = Count();
216 0 : if ( nCount != rOther.Count() )
217 0 : return sal_False;
218 :
219 : // Check arrays.
220 0 : NUMTYPE n = 0;
221 0 : while( _pRanges[ n ] != 0 )
222 : {
223 : // Elements at current position equal?
224 0 : if ( _pRanges[ n ] != rOther._pRanges[ n ] )
225 0 : return sal_False;
226 :
227 0 : ++n;
228 : }
229 :
230 0 : return sal_True;
231 : }
232 :
233 : //------------------------------------------------------------------------
234 :
235 0 : SfxNumRanges& SfxNumRanges::operator =
236 : (
237 : const SfxNumRanges &rRanges
238 : )
239 :
240 : /** <H3>Description</H3>
241 :
242 : Assigns ranges from 'rRanges' to '*this'.
243 : */
244 :
245 : {
246 : // special case: assign itself
247 0 : if ( &rRanges == this )
248 0 : return *this;
249 :
250 0 : delete[] _pRanges;
251 :
252 : // special case: 'rRanges' is empty
253 0 : if ( rRanges.IsEmpty() )
254 0 : _pRanges = 0;
255 : else
256 : {
257 : // copy ranges
258 0 : NUMTYPE nCount = Count_Impl( rRanges._pRanges ) + 1;
259 0 : _pRanges = new NUMTYPE[ nCount ];
260 0 : memcpy( _pRanges, rRanges._pRanges, sizeof(NUMTYPE) * nCount );
261 : }
262 0 : return *this;
263 : }
264 :
265 : //------------------------------------------------------------------------
266 :
267 0 : SfxNumRanges& SfxNumRanges::operator +=
268 : (
269 : const SfxNumRanges &rRanges
270 : )
271 :
272 : /** <H3>Description</H3>
273 :
274 : Merges *this with 'rRanges'.
275 :
276 : for each NUMTYPE n:
277 : this->Contains( n ) || rRanges.Contains( n ) => this'->Contains( n )
278 : !this->Contains( n ) && !rRanges.Contains( n ) => !this'->Contains( n )
279 : */
280 :
281 : {
282 : // special cases: one is empty
283 0 : if ( rRanges.IsEmpty() )
284 0 : return *this;
285 0 : if ( IsEmpty() )
286 0 : return *this = rRanges;
287 :
288 : // First, run thru _pRanges and rRanges._pRanges and determine the size of
289 : // the new, merged ranges:
290 0 : NUMTYPE nCount = 0;
291 0 : const NUMTYPE * pRA = _pRanges;
292 0 : const NUMTYPE * pRB = rRanges._pRanges;
293 :
294 0 : for (;;)
295 : {
296 : // The first pair of pRA has a lower lower bound than the first pair
297 : // of pRB:
298 0 : if (pRA[0] > pRB[0])
299 0 : Swap_Impl(pRA, pRB);
300 :
301 : // We are done with the merging if at least pRA is exhausted:
302 0 : if (!pRA[0])
303 0 : break;
304 :
305 0 : for (;;)
306 : {
307 : // Skip those pairs in pRB that completely lie in the first pair
308 : // of pRA:
309 0 : while (pRB[1] <= pRA[1])
310 : {
311 0 : pRB += 2;
312 :
313 : // Watch out for exhaustion of pRB:
314 0 : if (!pRB[0])
315 : {
316 0 : Swap_Impl(pRA, pRB);
317 0 : goto count_rest;
318 : }
319 : }
320 :
321 : // If the next pair of pRA does not at least touch the current new
322 : // pair, we are done with the current new pair:
323 0 : if (pRB[0] > pRA[1] + 1)
324 0 : break;
325 :
326 : // The next pair of pRB extends the current new pair; first,
327 : // extend the current new pair (we are done if pRB is then
328 : // exhausted); second, switch the roles of pRA and pRB in order to
329 : // merge in those following pairs of the original pRA that will
330 : // lie in the (now larger) current new pair or will even extend it
331 : // further:
332 0 : pRA += 2;
333 0 : if (!pRA[0])
334 0 : goto count_rest;
335 0 : Swap_Impl(pRA, pRB);
336 : }
337 :
338 : // Done with the current new pair:
339 0 : pRA += 2;
340 0 : nCount += 2;
341 : }
342 :
343 : // Only pRB has more pairs available, pRA is already exhausted:
344 : count_rest:
345 0 : for (; pRB[0]; pRB += 2)
346 0 : nCount += 2;
347 :
348 : // Now, create new ranges of the correct size and, on a second run thru
349 : // _pRanges and rRanges._pRanges, copy the merged pairs into the new
350 : // ranges:
351 0 : NUMTYPE * pNew = new NUMTYPE[nCount + 1];
352 0 : pRA = _pRanges;
353 0 : pRB = rRanges._pRanges;
354 0 : NUMTYPE * pRN = pNew;
355 :
356 0 : for (;;)
357 : {
358 : // The first pair of pRA has a lower lower bound than the first pair
359 : // of pRB:
360 0 : if (pRA[0] > pRB[0])
361 0 : Swap_Impl(pRA, pRB);
362 :
363 : // We are done with the merging if at least pRA is exhausted:
364 0 : if (!pRA[0])
365 0 : break;
366 :
367 : // Lower bound of current new pair is already known:
368 0 : *pRN++ = pRA[0];
369 :
370 0 : for (;;)
371 : {
372 : // Skip those pairs in pRB that completely lie in the first pair
373 : // of pRA:
374 0 : while (pRB[1] <= pRA[1])
375 : {
376 0 : pRB += 2;
377 :
378 : // Watch out for exhaustion of pRB:
379 0 : if (!pRB[0])
380 : {
381 0 : Swap_Impl(pRA, pRB);
382 0 : ++pRB;
383 0 : goto copy_rest;
384 : }
385 : }
386 :
387 : // If the next pair of pRA does not at least touch the current new
388 : // pair, we are done with the current new pair:
389 0 : if (pRB[0] > pRA[1] + 1)
390 0 : break;
391 :
392 : // The next pair of pRB extends the current new pair; first,
393 : // extend the current new pair (we are done if pRB is then
394 : // exhausted); second, switch the roles of pRA and pRB in order to
395 : // merge in those following pairs of the original pRA that will
396 : // lie in the (now larger) current new pair or will even extend it
397 : // further:
398 0 : pRA += 2;
399 0 : if (!pRA[0])
400 : {
401 0 : ++pRB;
402 0 : goto copy_rest;
403 : }
404 0 : Swap_Impl(pRA, pRB);
405 : }
406 :
407 : // Done with the current new pair, now upper bound is also known:
408 0 : *pRN++ = pRA[1];
409 0 : pRA += 2;
410 : }
411 :
412 : // Only pRB has more pairs available (which are copied to the new ranges
413 : // unchanged), pRA is already exhausted:
414 : copy_rest:
415 0 : for (; *pRB;)
416 0 : *pRN++ = *pRB++;
417 0 : *pRN = 0;
418 :
419 0 : delete[] _pRanges;
420 0 : _pRanges = pNew;
421 :
422 0 : return *this;
423 : }
424 :
425 : //------------------------------------------------------------------------
426 :
427 0 : SfxNumRanges& SfxNumRanges::operator -=
428 : (
429 : const SfxNumRanges &rRanges
430 : )
431 :
432 : /** <H3>Description</H3>
433 :
434 : Removes 'rRanges' from '*this'.
435 :
436 : for each NUMTYPE n:
437 : this->Contains( n ) && rRanges.Contains( n ) => !this'->Contains( n )
438 : this->Contains( n ) && !rRanges.Contains( n ) => this'->Contains( n )
439 : !this->Contains( n ) => !this'->Contains( n )
440 : */
441 :
442 : {
443 : // special cases: one is empty
444 0 : if ( rRanges.IsEmpty() || IsEmpty() )
445 0 : return *this;
446 :
447 : // differentiate 'rRanges' in a temporary copy of '*this'
448 : // (size is computed for maximal possibly split-count plus terminating 0)
449 0 : NUMTYPE nThisSize = Count_Impl(_pRanges);
450 0 : NUMTYPE nTargetSize = 1 + ( nThisSize + Count_Impl(rRanges._pRanges) );
451 0 : NUMTYPE *pTarget = new NUMTYPE[ nTargetSize ];
452 0 : memset( pTarget, 0, sizeof(NUMTYPE)*nTargetSize );
453 0 : memcpy( pTarget, _pRanges, sizeof(NUMTYPE)*nThisSize );
454 :
455 0 : NUMTYPE nPos1 = 0, nPos2 = 0, nTargetPos = 0;
456 0 : while( _pRanges[ nPos1 ] )
457 : {
458 0 : NUMTYPE l1 = _pRanges[ nPos1 ]; // lower bound of interval 1
459 0 : NUMTYPE u1 = _pRanges[ nPos1+1 ]; // upper bound of interval 1
460 0 : NUMTYPE l2 = rRanges._pRanges[ nPos2 ]; // lower bound of interval 2
461 0 : NUMTYPE u2 = rRanges._pRanges[ nPos2+1 ]; // upper bound of interval 2
462 :
463 : // boundary cases
464 : // * subtrahend is empty -> copy the minuend
465 0 : if( !l2 )
466 : {
467 0 : pTarget[ nTargetPos ] = l1;
468 0 : pTarget[ nTargetPos+1 ] = u1;
469 0 : nTargetPos += 2;
470 0 : nPos1 += 2;
471 0 : continue;
472 : }
473 : // * next subtrahend interval is completely higher -> copy the minuend
474 0 : if( u1 < l2 )
475 : {
476 0 : pTarget[ nTargetPos ] = l1;
477 0 : pTarget[ nTargetPos+1 ] = u1;
478 0 : nTargetPos += 2;
479 0 : nPos1 += 2;
480 0 : continue;
481 : }
482 :
483 : // * next subtrahend interval is completely lower -> try next
484 0 : if( u2 < l1 )
485 : {
486 0 : nPos2 += 2;
487 0 : continue;
488 : }
489 :
490 : // intersecting cases
491 : // * subtrahend cuts out from the beginning of the minuend
492 0 : if( l2 <= l1 && u2 <= u1 )
493 : {
494 : // reduce minuend interval, try again (minuend might be affected by other subtrahend intervals)
495 0 : _pRanges[ nPos1 ] = u2 + 1;
496 0 : nPos2 += 2; // this cannot hurt any longer
497 0 : continue;
498 : }
499 :
500 : // * subtrahend cuts out from the end of the minuend
501 0 : if( l1 <= l2 && u1 <= u2 )
502 : {
503 : // copy remaining part of minuend (cannot be affected by other intervals)
504 0 : if( l1 < l2 ) // anything left at all?
505 : {
506 0 : pTarget[ nTargetPos ] = l1;
507 0 : pTarget[ nTargetPos+1 ] = l2 - 1;
508 0 : nTargetPos += 2;
509 : // do not increment nPos2, might affect next minuend interval, too
510 : }
511 0 : nPos1 += 2; // nothing left at all
512 0 : continue;
513 : }
514 :
515 : // * subtrahend completely deletes minuend (larger or same at both ends)
516 0 : if( l1 >= l2 && u1 <= u2 )
517 : {
518 0 : nPos1 += 2; // minuend deleted
519 : // do not increment nPos2, might affect next minuend interval, too
520 0 : continue;
521 : }
522 :
523 : // * subtrahend divides minuend into two pieces
524 0 : if( l1 <= l2 && u1 >= u2 ) // >= and <= since they may be something left only at one side
525 : {
526 : // left side
527 0 : if( l1 < l2 ) // anything left at all
528 : {
529 0 : pTarget[ nTargetPos ] = l1;
530 0 : pTarget[ nTargetPos+1 ] = l2 - 1;
531 0 : nTargetPos += 2;
532 : }
533 :
534 : // right side
535 0 : if( u1 > u2 ) // anything left at all
536 : {
537 : // reduce minuend interval, try again (minuend might be affected by other subtrahend itnervals )
538 0 : _pRanges[ nPos1 ] = u2 + 1;
539 : }
540 :
541 : // subtrahend is completely used
542 0 : nPos2 += 2;
543 0 : continue;
544 : }
545 :
546 : // we should never be here
547 : OSL_FAIL( "SfxNumRanges::operator-=: internal error" );
548 : } // while
549 :
550 0 : pTarget[ nTargetPos ] = 0;
551 :
552 : // assign the differentiated ranges
553 0 : delete[] _pRanges;
554 :
555 0 : NUMTYPE nUShorts = Count_Impl(pTarget) + 1;
556 0 : if ( 1 != nUShorts )
557 : {
558 0 : _pRanges = new NUMTYPE[ nUShorts ];
559 0 : memcpy( _pRanges, pTarget, nUShorts * sizeof(NUMTYPE) );
560 : }
561 : else
562 0 : _pRanges = 0;
563 :
564 0 : delete [] pTarget;
565 0 : return *this;
566 : }
567 :
568 : //------------------------------------------------------------------------
569 :
570 0 : SfxNumRanges& SfxNumRanges::operator /=
571 : (
572 : const SfxNumRanges &rRanges
573 : )
574 :
575 : /** <H3>Description</H3>
576 :
577 : Determines intersection of '*this' with 'rRanges'.
578 :
579 : for each NUMTYPE n:
580 : this->Contains( n ) && rRanges.Contains( n ) => this'->Contains( n )
581 : !this->Contains( n ) => !this'->Contains( n )
582 : !rRanges.Contains( n ) => !this'->Contains( n )
583 : */
584 :
585 : {
586 : // boundary cases
587 : // * first set is empty -> nothing to be done
588 : // * second set is empty -> delete first set
589 0 : if( rRanges.IsEmpty() )
590 : {
591 0 : delete[] _pRanges;
592 :
593 0 : _pRanges = new NUMTYPE[1];
594 0 : _pRanges[0] = 0;
595 :
596 0 : return *this;
597 : }
598 :
599 : // intersect 'rRanges' in a temporary copy of '*this'
600 : // (size is computed for maximal possibly split-count plus terminating 0)
601 0 : NUMTYPE nThisSize = Count_Impl(_pRanges);
602 0 : NUMTYPE nTargetSize = 1 + ( nThisSize + Count_Impl(rRanges._pRanges) );
603 0 : NUMTYPE *pTarget = new NUMTYPE[ nTargetSize ];
604 0 : memset( pTarget, 0, sizeof(NUMTYPE)*nTargetSize );
605 0 : memcpy( pTarget, _pRanges, sizeof(NUMTYPE)*nThisSize );
606 :
607 0 : NUMTYPE nPos1 = 0, nPos2 = 0, nTargetPos = 0;
608 0 : while( _pRanges[ nPos1 ] != 0 && rRanges._pRanges[ nPos2 ] != 0 )
609 : {
610 0 : NUMTYPE l1 = _pRanges[ nPos1 ]; // lower bound of interval 1
611 0 : NUMTYPE u1 = _pRanges[ nPos1+1 ]; // upper bound of interval 1
612 0 : NUMTYPE l2 = rRanges._pRanges[ nPos2 ]; // lower bound of interval 2
613 0 : NUMTYPE u2 = rRanges._pRanges[ nPos2+1 ]; // upper bound of interval 2
614 :
615 0 : if( u1 < l2 )
616 : {
617 : // current interval in s1 is completely before ci in s2
618 0 : nPos1 += 2;
619 0 : continue;
620 : }
621 0 : if( u2 < l1 )
622 : {
623 : // ci in s2 is completely before ci in s1
624 0 : nPos2 += 2;
625 0 : continue;
626 : }
627 :
628 : // assert: there exists an intersection between ci1 and ci2
629 :
630 0 : if( l1 <= l2 )
631 : {
632 : // c1 "is more to the left" than c2
633 :
634 0 : if( u1 <= u2 )
635 : {
636 0 : pTarget[ nTargetPos ] = l2;
637 0 : pTarget[ nTargetPos+1 ] = u1;
638 0 : nTargetPos += 2;
639 0 : nPos1 += 2;
640 0 : continue;
641 : }
642 : else
643 : {
644 0 : pTarget[ nTargetPos ] = l2;
645 0 : pTarget[ nTargetPos+1 ] = u2;
646 0 : nTargetPos += 2;
647 0 : nPos2 += 2;
648 : }
649 : }
650 : else
651 : {
652 : // c2 "is more to the left" than c1"
653 :
654 0 : if( u1 > u2 )
655 : {
656 0 : pTarget[ nTargetPos ] = l1;
657 0 : pTarget[ nTargetPos+1 ] = u2;
658 0 : nTargetPos += 2;
659 0 : nPos2 += 2;
660 : }
661 : else
662 : {
663 0 : pTarget[ nTargetPos ] = l1;
664 0 : pTarget[ nTargetPos+1 ] = u1;
665 0 : nTargetPos += 2;
666 0 : nPos1 += 2;
667 : }
668 : }
669 : }; // while
670 0 : pTarget[ nTargetPos ] = 0;
671 :
672 : // assign the intersected ranges
673 0 : delete[] _pRanges;
674 :
675 0 : NUMTYPE nUShorts = Count_Impl(pTarget) + 1;
676 0 : if ( 1 != nUShorts )
677 : {
678 0 : _pRanges = new NUMTYPE[ nUShorts ];
679 0 : memcpy( _pRanges, pTarget, nUShorts * sizeof(NUMTYPE) );
680 : }
681 : else
682 0 : _pRanges = 0;
683 :
684 0 : delete [] pTarget;
685 0 : return *this;
686 : }
687 :
688 : //------------------------------------------------------------------------
689 :
690 0 : NUMTYPE SfxNumRanges::Count() const
691 :
692 : /** <H3>Description</H3>
693 :
694 : Determines the number of USHORTs in the set described by the ranges
695 : of USHORTs in '*this'.
696 : */
697 :
698 : {
699 0 : return Capacity_Impl( _pRanges );
700 : }
701 :
702 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|