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