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 "index.hxx"
21 :
22 : #include <assert.h>
23 : #include <sal/log.hxx>
24 :
25 3770 : TYPEINIT0(SwIndexReg);
26 :
27 : // SwIndex
28 :
29 1167460 : SwIndex::SwIndex(SwIndexReg *const pReg, sal_Int32 const nIdx)
30 : : m_nIndex( nIdx )
31 : , m_pIndexReg( pReg )
32 : , m_pNext( 0 )
33 1167460 : , m_pPrev( 0 )
34 : {
35 1167460 : Init(m_nIndex);
36 1167460 : }
37 :
38 78 : SwIndex::SwIndex( const SwIndex& rIdx, short nDiff )
39 : : m_pIndexReg( rIdx.m_pIndexReg )
40 : , m_pNext( 0 )
41 78 : , m_pPrev( 0 )
42 : {
43 78 : ChgValue( rIdx, rIdx.m_nIndex + nDiff );
44 78 : }
45 :
46 1326204 : SwIndex::SwIndex( const SwIndex& rIdx )
47 : : m_nIndex( rIdx.m_nIndex )
48 : , m_pIndexReg( rIdx.m_pIndexReg )
49 : , m_pNext( 0 )
50 1326204 : , m_pPrev( 0 )
51 : {
52 1326204 : ChgValue( rIdx, rIdx.m_nIndex );
53 1326204 : }
54 :
55 1482489 : void SwIndex::Init(sal_Int32 const nIdx)
56 : {
57 1482489 : if (!m_pIndexReg)
58 : {
59 998151 : m_nIndex = 0; // always 0 if no IndexReg
60 : }
61 484338 : else if (!m_pIndexReg->m_pFirst) // first Index?
62 : {
63 : assert(!m_pIndexReg->m_pLast);
64 196027 : m_pIndexReg->m_pFirst = m_pIndexReg->m_pLast = this;
65 196027 : m_nIndex = nIdx;
66 : }
67 288311 : else if (nIdx > ((m_pIndexReg->m_pLast->m_nIndex
68 288311 : - m_pIndexReg->m_pFirst->m_nIndex) / 2))
69 : {
70 45885 : ChgValue( *m_pIndexReg->m_pLast, nIdx );
71 : }
72 : else
73 : {
74 242426 : ChgValue( *m_pIndexReg->m_pFirst, nIdx );
75 : }
76 1482489 : }
77 :
78 2191415 : SwIndex& SwIndex::ChgValue( const SwIndex& rIdx, sal_Int32 nNewValue )
79 : {
80 : assert(m_pIndexReg == rIdx.m_pIndexReg);
81 2191415 : if (!m_pIndexReg)
82 : {
83 360229 : return *this; // no IndexReg => no list to sort into; m_nIndex is 0
84 : }
85 1831186 : SwIndex* pFnd = const_cast<SwIndex*>(&rIdx);
86 1831186 : if (rIdx.m_nIndex > nNewValue) // move forwards
87 : {
88 : SwIndex* pPrv;
89 1017413 : while ((0 != (pPrv = pFnd->m_pPrev)) && (pPrv->m_nIndex > nNewValue))
90 666489 : pFnd = pPrv;
91 :
92 175462 : if( pFnd != this )
93 : {
94 : // remove from list at old position
95 133051 : Remove();
96 :
97 133051 : m_pNext = pFnd;
98 133051 : m_pPrev = pFnd->m_pPrev;
99 133051 : if (m_pPrev)
100 25336 : m_pPrev->m_pNext = this;
101 : else
102 107715 : m_pIndexReg->m_pFirst = this;
103 133051 : pFnd->m_pPrev = this;
104 : }
105 : }
106 1655724 : else if (rIdx.m_nIndex < nNewValue)
107 : {
108 : SwIndex* pNxt;
109 4163138 : while ((0 != (pNxt = pFnd->m_pNext)) && (pNxt->m_nIndex < nNewValue))
110 3918040 : pFnd = pNxt;
111 :
112 122549 : if( pFnd != this )
113 : {
114 : // remove from list at old position
115 72718 : Remove();
116 :
117 72718 : m_pPrev = pFnd;
118 72718 : m_pNext = pFnd->m_pNext;
119 72718 : if (m_pNext)
120 34051 : m_pNext->m_pPrev = this;
121 : else
122 38667 : m_pIndexReg->m_pLast = this;
123 72718 : pFnd->m_pNext = this;
124 : }
125 : }
126 1533175 : else if( pFnd != this )
127 : {
128 : // remove from list at old position
129 1528532 : Remove();
130 :
131 1528532 : m_pPrev = pFnd; // == &rIdx here
132 1528532 : m_pNext = rIdx.m_pNext;
133 1528532 : m_pPrev->m_pNext = this;
134 :
135 1528532 : if (!m_pNext) // last in the list
136 701644 : m_pIndexReg->m_pLast = this;
137 : else
138 826888 : m_pNext->m_pPrev = this;
139 : }
140 :
141 1831186 : if (m_pIndexReg->m_pFirst == m_pNext)
142 0 : m_pIndexReg->m_pFirst = this;
143 1831186 : if (m_pIndexReg->m_pLast == m_pPrev)
144 0 : m_pIndexReg->m_pLast = this;
145 :
146 1831186 : m_nIndex = nNewValue;
147 :
148 1831186 : return *this;
149 : }
150 :
151 4885057 : void SwIndex::Remove()
152 : {
153 4885057 : if (!m_pIndexReg)
154 : {
155 : assert(!m_pPrev && !m_pNext);
156 6243389 : return;
157 : }
158 :
159 3526725 : if (m_pPrev)
160 : {
161 1493733 : m_pPrev->m_pNext = m_pNext;
162 : }
163 2032992 : else if (m_pIndexReg->m_pFirst == this)
164 : {
165 436593 : m_pIndexReg->m_pFirst = m_pNext;
166 : }
167 :
168 3526725 : if (m_pNext)
169 : {
170 1300493 : m_pNext->m_pPrev = m_pPrev;
171 : }
172 2226232 : else if (m_pIndexReg->m_pLast == this)
173 : {
174 629833 : m_pIndexReg->m_pLast = m_pPrev;
175 : }
176 : }
177 :
178 516443 : SwIndex& SwIndex::operator=( const SwIndex& rIdx )
179 : {
180 : bool bEqual;
181 516443 : if (rIdx.m_pIndexReg != m_pIndexReg) // unregister!
182 : {
183 342028 : Remove();
184 342028 : m_pIndexReg = rIdx.m_pIndexReg;
185 342028 : m_pNext = m_pPrev = 0;
186 342028 : bEqual = false;
187 : }
188 : else
189 174415 : bEqual = rIdx.m_nIndex == m_nIndex;
190 :
191 516443 : if( !bEqual )
192 379250 : ChgValue( rIdx, rIdx.m_nIndex );
193 516443 : return *this;
194 : }
195 :
196 765371 : SwIndex& SwIndex::Assign( SwIndexReg* pArr, sal_Int32 nIdx )
197 : {
198 765371 : if (pArr != m_pIndexReg) // unregister!
199 : {
200 315029 : Remove();
201 315029 : m_pIndexReg = pArr;
202 315029 : m_pNext = m_pPrev = 0;
203 315029 : Init(nIdx);
204 : }
205 450342 : else if (m_nIndex != nIdx)
206 : {
207 60445 : ChgValue( *this, nIdx );
208 : }
209 765371 : return *this;
210 : }
211 :
212 : // SwIndexReg
213 :
214 143521 : SwIndexReg::SwIndexReg()
215 143521 : : m_pFirst( 0 ), m_pLast( 0 )
216 : {
217 143521 : }
218 :
219 143473 : SwIndexReg::~SwIndexReg()
220 : {
221 : assert(!m_pFirst && !m_pLast); // There are still indices registered
222 143473 : }
223 :
224 105614 : void SwIndexReg::Update(
225 : SwIndex const & rIdx,
226 : const sal_Int32 nDiff,
227 : const bool bNeg,
228 : const bool /* argument is only used in derived class*/ )
229 : {
230 105614 : SwIndex* pStt = const_cast<SwIndex*>(&rIdx);
231 105614 : const sal_Int32 nNewVal = rIdx.m_nIndex;
232 105614 : if( bNeg )
233 : {
234 2763 : const sal_Int32 nLast = rIdx.GetIndex() + nDiff;
235 10003 : while (pStt && pStt->m_nIndex == nNewVal)
236 : {
237 4477 : pStt->m_nIndex = nNewVal;
238 4477 : pStt = pStt->m_pPrev;
239 : }
240 2763 : pStt = rIdx.m_pNext;
241 16761 : while (pStt && pStt->m_nIndex >= nNewVal
242 11851 : && pStt->m_nIndex <= nLast)
243 : {
244 11235 : pStt->m_nIndex = nNewVal;
245 11235 : pStt = pStt->m_pNext;
246 : }
247 93652 : while( pStt )
248 : {
249 88126 : pStt->m_nIndex = pStt->m_nIndex - nDiff;
250 88126 : pStt = pStt->m_pNext;
251 : }
252 : }
253 : else
254 : {
255 359512 : while (pStt && pStt->m_nIndex == nNewVal)
256 : {
257 153810 : pStt->m_nIndex = pStt->m_nIndex + nDiff;
258 153810 : pStt = pStt->m_pPrev;
259 : }
260 102851 : pStt = rIdx.m_pNext;
261 913799 : while( pStt )
262 : {
263 708097 : pStt->m_nIndex = pStt->m_nIndex + nDiff;
264 708097 : pStt = pStt->m_pNext;
265 : }
266 : }
267 105614 : }
268 :
269 105614 : void SwIndexReg::MoveTo( SwIndexReg& rArr )
270 : {
271 105614 : if (this != &rArr && m_pFirst)
272 : {
273 9258 : SwIndex * pIdx = const_cast<SwIndex*>(m_pFirst);
274 : SwIndex * pNext;
275 31321 : while( pIdx )
276 : {
277 12805 : pNext = pIdx->m_pNext;
278 12805 : pIdx->Assign( &rArr, pIdx->GetIndex() );
279 12805 : pIdx = pNext;
280 : }
281 9258 : m_pFirst = 0, m_pLast = 0;
282 : }
283 105614 : }
284 :
285 : #ifdef DBG_UTIL
286 :
287 : // SwIndex
288 :
289 : sal_Int32 SwIndex::operator++(int)
290 : {
291 : SAL_WARN_IF( !(m_nIndex < SAL_MAX_INT32), "sw.core",
292 : "SwIndex::operator++(int) wraps around" );
293 :
294 : const sal_Int32 nOldIndex = m_nIndex;
295 : ChgValue( *this, m_nIndex+1 );
296 : return nOldIndex;
297 : }
298 :
299 : sal_Int32 SwIndex::operator++()
300 : {
301 : SAL_WARN_IF( !(m_nIndex < SAL_MAX_INT32), "sw.core",
302 : "SwIndex::operator++() wraps around" );
303 :
304 : ChgValue( *this, m_nIndex+1 );
305 : return m_nIndex;
306 : }
307 :
308 : sal_Int32 SwIndex::operator--(int)
309 : {
310 : SAL_WARN_IF( !(m_nIndex > 0), "sw.core",
311 : "SwIndex::operator--(int) wraps around" );
312 :
313 : const sal_Int32 nOldIndex = m_nIndex;
314 : ChgValue( *this, m_nIndex-1 );
315 : return nOldIndex;
316 : }
317 :
318 : sal_Int32 SwIndex::operator--()
319 : {
320 : SAL_WARN_IF( !( m_nIndex > 0), "sw.core",
321 : "SwIndex::operator--() wraps around" );
322 : return ChgValue( *this, m_nIndex-1 ).m_nIndex;
323 : }
324 :
325 : sal_Int32 SwIndex::operator+=( sal_Int32 const nVal )
326 : {
327 : SAL_WARN_IF( !(m_nIndex <= SAL_MAX_INT32 - nVal), "sw.core",
328 : "SwIndex SwIndex::operator+=(sal_Int32) wraps around" );
329 : return ChgValue( *this, m_nIndex + nVal ).m_nIndex;
330 : }
331 :
332 : sal_Int32 SwIndex::operator-=( sal_Int32 const nVal )
333 : {
334 : SAL_WARN_IF( !(m_nIndex >= nVal), "sw.core",
335 : "SwIndex::operator-=(sal_Int32) wraps around" );
336 : return ChgValue( *this, m_nIndex - nVal ).m_nIndex;
337 : }
338 :
339 : sal_Int32 SwIndex::operator+=( const SwIndex & rIndex )
340 : {
341 : SAL_WARN_IF( !(m_nIndex <= SAL_MAX_INT32 - rIndex.m_nIndex), "sw.core",
342 : "SwIndex::operator+=(SwIndex) wraps around" );
343 : return ChgValue( *this, m_nIndex + rIndex.m_nIndex ).m_nIndex;
344 : }
345 :
346 : sal_Int32 SwIndex::operator-=( const SwIndex & rIndex )
347 : {
348 : SAL_WARN_IF( !(m_nIndex >= rIndex.m_nIndex), "sw.core",
349 : "SwIndex::operator-=(SwIndex) wraps around" );
350 : return ChgValue( *this, m_nIndex - rIndex.m_nIndex ).m_nIndex;
351 : }
352 :
353 : bool SwIndex::operator< ( const SwIndex & rIndex ) const
354 : {
355 : // Attempt to compare indices into different arrays
356 : assert(m_pIndexReg == rIndex.m_pIndexReg);
357 : return m_nIndex < rIndex.m_nIndex;
358 : }
359 :
360 : bool SwIndex::operator<=( const SwIndex & rIndex ) const
361 : {
362 : // Attempt to compare indices into different arrays
363 : assert(m_pIndexReg == rIndex.m_pIndexReg);
364 : return m_nIndex <= rIndex.m_nIndex;
365 : }
366 :
367 : bool SwIndex::operator> ( const SwIndex & rIndex ) const
368 : {
369 : // Attempt to compare indices into different arrays
370 : assert(m_pIndexReg == rIndex.m_pIndexReg);
371 : return m_nIndex > rIndex.m_nIndex;
372 : }
373 :
374 : bool SwIndex::operator>=( const SwIndex & rIndex ) const
375 : {
376 : // Attempt to compare indices into different arrays
377 : assert(m_pIndexReg == rIndex.m_pIndexReg);
378 : return m_nIndex >= rIndex.m_nIndex;
379 : }
380 :
381 : SwIndex& SwIndex::operator= ( sal_Int32 const nVal )
382 : {
383 : if (m_nIndex != nVal)
384 : ChgValue( *this, nVal );
385 :
386 : return *this;
387 : }
388 :
389 : #endif
390 :
391 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|