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 :
10 : #ifndef SC_MTVFUNCTIONS_HXX
11 : #define SC_MTVFUNCTIONS_HXX
12 :
13 : #include <cstdlib>
14 : #include <mdds/multi_type_vector_types.hpp>
15 :
16 : namespace sc {
17 :
18 : template<typename _SizeT, typename _Ret = bool>
19 : struct FuncElseNoOp
20 : {
21 3651805 : _Ret operator() (mdds::mtv::element_t, _SizeT, _SizeT) const
22 : {
23 3651805 : return _Ret();
24 : }
25 : };
26 :
27 : /**
28 : * Generic algorithm to parse blocks of multi_type_vector either partially
29 : * or fully.
30 : */
31 : template<typename _StoreT, typename _Func>
32 : typename _StoreT::const_iterator
33 1696089 : ParseBlock(
34 : const typename _StoreT::const_iterator& itPos, const _StoreT& rStore, _Func& rFunc,
35 : typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd)
36 : {
37 : typedef std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type> PositionType;
38 :
39 1696089 : PositionType aPos = rStore.position(itPos, nStart);
40 1696089 : typename _StoreT::const_iterator it = aPos.first;
41 1696089 : typename _StoreT::size_type nOffset = aPos.second;
42 1696089 : typename _StoreT::size_type nDataSize = 0;
43 1696089 : typename _StoreT::size_type nTopRow = nStart;
44 :
45 1953536 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
46 : {
47 1699369 : bool bLastBlock = false;
48 1699369 : nDataSize = it->size - nOffset;
49 1699369 : if (nTopRow + nDataSize - 1 > nEnd)
50 : {
51 : // Truncate the block.
52 1441922 : nDataSize = nEnd - nTopRow + 1;
53 1441922 : bLastBlock = true;
54 : }
55 :
56 1699369 : rFunc(*it, nOffset, nDataSize);
57 :
58 1699369 : if (bLastBlock)
59 1441922 : break;
60 : }
61 :
62 1696089 : return it;
63 : }
64 :
65 : /**
66 : * Non-const variant of the above function. TODO: Find a way to merge these
67 : * two in an elegant way.
68 : */
69 : template<typename _StoreT, typename _Func>
70 : typename _StoreT::iterator
71 10611 : ProcessBlock(const typename _StoreT::iterator& itPos, _StoreT& rStore, _Func& rFunc, typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd)
72 : {
73 : typedef std::pair<typename _StoreT::iterator, typename _StoreT::size_type> PositionType;
74 :
75 10611 : PositionType aPos = rStore.position(itPos, nStart);
76 10611 : typename _StoreT::iterator it = aPos.first;
77 10611 : typename _StoreT::size_type nOffset = aPos.second;
78 10611 : typename _StoreT::size_type nDataSize = 0;
79 10611 : typename _StoreT::size_type nCurRow = nStart;
80 :
81 21911 : for (; it != rStore.end() && nCurRow <= nEnd; ++it, nOffset = 0, nCurRow += nDataSize)
82 : {
83 11750 : bool bLastBlock = false;
84 11750 : nDataSize = it->size - nOffset;
85 11750 : if (nCurRow + nDataSize - 1 > nEnd)
86 : {
87 : // Truncate the block.
88 450 : nDataSize = nEnd - nCurRow + 1;
89 450 : bLastBlock = true;
90 : }
91 :
92 11750 : rFunc(*it, nOffset, nDataSize);
93 :
94 11750 : if (bLastBlock)
95 450 : break;
96 : }
97 :
98 10611 : return it;
99 : }
100 :
101 : template<typename _BlkT, typename _ItrT, typename _NodeT, typename _FuncElem>
102 122888 : void EachElem(_NodeT& rNode, size_t nOffset, size_t nDataSize, _FuncElem& rFuncElem)
103 : {
104 122888 : _ItrT it = _BlkT::begin(*rNode.data);
105 122888 : std::advance(it, nOffset);
106 122888 : _ItrT itEnd = it;
107 122888 : std::advance(itEnd, nDataSize);
108 122888 : size_t nRow = rNode.position + nOffset;
109 570341 : for (; it != itEnd; ++it, ++nRow)
110 447453 : rFuncElem(nRow, *it);
111 122888 : }
112 :
113 : template<typename _BlkT, typename _ItrT, typename _NodeT, typename _FuncElem>
114 3394 : void EachElem(_NodeT& rNode, _FuncElem& rFuncElem)
115 : {
116 3394 : _ItrT it = _BlkT::begin(*rNode.data);
117 3394 : _ItrT itEnd = _BlkT::end(*rNode.data);
118 3394 : size_t nRow = rNode.position;
119 14024 : for (; it != itEnd; ++it, ++nRow)
120 10630 : rFuncElem(nRow, *it);
121 3394 : }
122 :
123 : template<typename _BlkT, typename _StoreT, typename _FuncElem>
124 : std::pair<typename _StoreT::const_iterator, size_t>
125 279 : CheckElem(
126 : const _StoreT& rStore, const typename _StoreT::const_iterator& it, size_t nOffset, size_t nDataSize,
127 : _FuncElem& rFuncElem)
128 : {
129 : typedef std::pair<typename _StoreT::const_iterator, size_t> PositionType;
130 :
131 279 : typename _BlkT::const_iterator itData = _BlkT::begin(*it->data);
132 279 : std::advance(itData, nOffset);
133 279 : typename _BlkT::const_iterator itDataEnd = itData;
134 279 : std::advance(itDataEnd, nDataSize);
135 279 : size_t nTopRow = it->position + nOffset;
136 279 : size_t nRow = nTopRow;
137 502 : for (; itData != itDataEnd; ++itData, ++nRow)
138 : {
139 314 : if (rFuncElem(nRow, *itData))
140 91 : return PositionType(it, nRow - it->position);
141 : }
142 :
143 188 : return PositionType(rStore.end(), 0);
144 : }
145 :
146 : template<typename _StoreT, typename _BlkT, typename _FuncElem, typename _FuncElse>
147 4 : void ParseElements1(const _StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
148 : {
149 4 : typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
150 4 : typename _StoreT::const_iterator it = rStore.begin(), itEnd = rStore.end();
151 18 : for (; it != itEnd; ++it, nTopRow += nDataSize)
152 : {
153 14 : nDataSize = it->size;
154 14 : if (it->type != _BlkT::block_type)
155 : {
156 12 : rFuncElse(it->type, nTopRow, nDataSize);
157 12 : continue;
158 : }
159 :
160 2 : EachElem<_BlkT, typename _BlkT::const_iterator>(*it, rFuncElem);
161 : }
162 4 : }
163 :
164 : template<typename _StoreT, typename _BlkT, typename _FuncElem, typename _FuncElse>
165 : typename _StoreT::const_iterator
166 51500 : ParseElements1(
167 : const typename _StoreT::const_iterator& itPos, const _StoreT& rStore,
168 : typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
169 : _FuncElem& rFuncElem, _FuncElse& rFuncElse)
170 : {
171 : typedef std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type> PositionType;
172 :
173 51500 : PositionType aPos = rStore.position(itPos, nStart);
174 51500 : typename _StoreT::const_iterator it = aPos.first;
175 51500 : typename _StoreT::size_type nOffset = aPos.second;
176 51500 : typename _StoreT::size_type nDataSize = 0;
177 51500 : typename _StoreT::size_type nTopRow = nStart;
178 :
179 81272 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
180 : {
181 51520 : bool bLastBlock = false;
182 51520 : nDataSize = it->size - nOffset;
183 51520 : if (nTopRow + nDataSize - 1 > nEnd)
184 : {
185 : // Truncate the block.
186 21748 : nDataSize = nEnd - nTopRow + 1;
187 21748 : bLastBlock = true;
188 : }
189 :
190 51520 : if (it->type == _BlkT::block_type)
191 44 : EachElem<_BlkT, typename _BlkT::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
192 : else
193 51476 : rFuncElse(it->type, nTopRow, nDataSize);
194 :
195 :
196 51520 : if (bLastBlock)
197 21748 : break;
198 : }
199 :
200 51500 : return it;
201 : };
202 :
203 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
204 : typename _StoreT::const_iterator
205 1312 : ParseElements2(
206 : const typename _StoreT::const_iterator& itPos, const _StoreT& rStore, typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
207 : _FuncElem& rFuncElem, _FuncElse& rFuncElse)
208 : {
209 : typedef std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type> PositionType;
210 :
211 1312 : PositionType aPos = rStore.position(itPos, nStart);
212 1312 : typename _StoreT::const_iterator it = aPos.first;
213 1312 : typename _StoreT::size_type nOffset = aPos.second;
214 1312 : typename _StoreT::size_type nDataSize = 0;
215 1312 : typename _StoreT::size_type nTopRow = nStart;
216 :
217 2309 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
218 : {
219 1495 : bool bLastBlock = false;
220 1495 : nDataSize = it->size - nOffset;
221 1495 : if (nTopRow + nDataSize - 1 > nEnd)
222 : {
223 : // Truncate the block.
224 498 : nDataSize = nEnd - nTopRow + 1;
225 498 : bLastBlock = true;
226 : }
227 :
228 1495 : switch (it->type)
229 : {
230 : case _Blk1::block_type:
231 1001 : EachElem<_Blk1, typename _Blk1::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
232 1001 : break;
233 : case _Blk2::block_type:
234 195 : EachElem<_Blk2, typename _Blk2::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
235 195 : break;
236 : default:
237 299 : rFuncElse(it->type, nTopRow, nDataSize);
238 : }
239 :
240 1495 : if (bLastBlock)
241 498 : break;
242 : }
243 :
244 1312 : return it;
245 : }
246 :
247 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _Blk3, typename _Blk4, typename _FuncElem, typename _FuncElse>
248 : typename _StoreT::const_iterator
249 104976 : ParseElements4(
250 : const typename _StoreT::const_iterator& itPos, const _StoreT& rStore, typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
251 : _FuncElem& rFuncElem, _FuncElse& rFuncElse)
252 : {
253 : typedef std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type> PositionType;
254 :
255 104976 : PositionType aPos = rStore.position(itPos, nStart);
256 104976 : typename _StoreT::const_iterator it = aPos.first;
257 104976 : typename _StoreT::size_type nOffset = aPos.second;
258 104976 : typename _StoreT::size_type nDataSize = 0;
259 104976 : typename _StoreT::size_type nTopRow = nStart;
260 :
261 265613 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
262 : {
263 253717 : bool bLastBlock = false;
264 253717 : nDataSize = it->size - nOffset;
265 253717 : if (nTopRow + nDataSize - 1 > nEnd)
266 : {
267 : // Truncate the block.
268 93080 : nDataSize = nEnd - nTopRow + 1;
269 93080 : bLastBlock = true;
270 : }
271 :
272 253717 : switch (it->type)
273 : {
274 : case _Blk1::block_type:
275 79280 : EachElem<_Blk1, typename _Blk1::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
276 79280 : break;
277 : case _Blk2::block_type:
278 37379 : EachElem<_Blk2, typename _Blk2::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
279 37379 : break;
280 : case _Blk3::block_type:
281 486 : EachElem<_Blk3, typename _Blk3::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
282 486 : break;
283 : case _Blk4::block_type:
284 4047 : EachElem<_Blk4, typename _Blk4::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
285 4047 : break;
286 : default:
287 132525 : rFuncElse(it->type, nTopRow, nDataSize);
288 : }
289 :
290 253717 : if (bLastBlock)
291 93080 : break;
292 : }
293 :
294 104976 : return it;
295 : }
296 :
297 : template<typename _StoreT, typename _BlkT, typename _FuncElem, typename _FuncElse>
298 3062784 : void ProcessElements1(_StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
299 : {
300 3062784 : typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
301 3062784 : typename _StoreT::iterator it = rStore.begin(), itEnd = rStore.end();
302 6165852 : for (; it != itEnd; ++it, nTopRow += nDataSize)
303 : {
304 3103068 : nDataSize = it->size;
305 3103068 : if (it->type != _BlkT::block_type)
306 : {
307 3099753 : rFuncElse(it->type, nTopRow, nDataSize);
308 3099753 : continue;
309 : }
310 :
311 3315 : EachElem<_BlkT, typename _BlkT::iterator>(*it, rFuncElem);
312 : }
313 3062784 : }
314 :
315 : /**
316 : * This variant specifies start and end positions.
317 : */
318 : template<typename _StoreT, typename _BlkT, typename _FuncElem, typename _FuncElse>
319 : typename _StoreT::iterator
320 36456 : ProcessElements1(
321 : const typename _StoreT::iterator& itPos, _StoreT& rStore,
322 : typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
323 : _FuncElem& rFuncElem, _FuncElse& rFuncElse)
324 : {
325 : typedef std::pair<typename _StoreT::iterator, typename _StoreT::size_type> PositionType;
326 :
327 36456 : PositionType aPos = rStore.position(itPos, nStart);
328 36456 : typename _StoreT::iterator it = aPos.first;
329 36456 : typename _StoreT::size_type nOffset = aPos.second;
330 36456 : typename _StoreT::size_type nDataSize = 0;
331 36456 : typename _StoreT::size_type nTopRow = nStart;
332 :
333 57840 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
334 : {
335 52739 : bool bLastBlock = false;
336 52739 : nDataSize = it->size - nOffset;
337 52739 : if (nTopRow + nDataSize - 1 > nEnd)
338 : {
339 : // Truncate the block.
340 31355 : nDataSize = nEnd - nTopRow + 1;
341 31355 : bLastBlock = true;
342 : }
343 :
344 52739 : if (it->type == _BlkT::block_type)
345 456 : EachElem<_BlkT, typename _BlkT::iterator>(*it, nOffset, nDataSize, rFuncElem);
346 : else
347 52283 : rFuncElse(it->type, nTopRow, nDataSize);
348 :
349 52739 : if (bLastBlock)
350 31355 : break;
351 : }
352 :
353 36456 : return it;
354 : };
355 :
356 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
357 316416 : void ProcessElements2(_StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
358 : {
359 316416 : typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
360 316416 : typename _StoreT::iterator it = rStore.begin(), itEnd = rStore.end();
361 635459 : for (; it != itEnd; ++it, nTopRow += nDataSize)
362 : {
363 319043 : nDataSize = it->size;
364 319043 : switch (it->type)
365 : {
366 : case _Blk1::block_type:
367 8 : EachElem<_Blk1, typename _Blk1::iterator>(*it, rFuncElem);
368 8 : break;
369 : case _Blk2::block_type:
370 69 : EachElem<_Blk2, typename _Blk2::iterator>(*it, rFuncElem);
371 69 : break;
372 : default:
373 318966 : rFuncElse(it->type, nTopRow, nDataSize);
374 : }
375 : }
376 316416 : }
377 :
378 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
379 : typename _StoreT::iterator
380 : ProcessElements2(
381 : const typename _StoreT::iterator& itPos, _StoreT& rStore,
382 : typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
383 : _FuncElem& rFuncElem, _FuncElse& rFuncElse)
384 : {
385 : typedef std::pair<typename _StoreT::iterator, typename _StoreT::size_type> PositionType;
386 :
387 : PositionType aPos = rStore.position(itPos, nStart);
388 : typename _StoreT::iterator it = aPos.first;
389 : typename _StoreT::size_type nOffset = aPos.second;
390 : typename _StoreT::size_type nDataSize = 0;
391 : typename _StoreT::size_type nTopRow = nStart;
392 :
393 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
394 : {
395 : bool bLastBlock = false;
396 : nDataSize = it->size - nOffset;
397 : if (nTopRow + nDataSize - 1 > nEnd)
398 : {
399 : // Truncate the block.
400 : nDataSize = nEnd - nTopRow + 1;
401 : bLastBlock = true;
402 : }
403 :
404 : switch (it->type)
405 : {
406 : case _Blk1::block_type:
407 : EachElem<_Blk1, typename _Blk1::iterator>(*it, nOffset, nDataSize, rFuncElem);
408 : break;
409 : case _Blk2::block_type:
410 : EachElem<_Blk2, typename _Blk2::iterator>(*it, nOffset, nDataSize, rFuncElem);
411 : break;
412 : default:
413 : rFuncElse(it->type, nTopRow, nDataSize);
414 : }
415 :
416 : if (bLastBlock)
417 : break;
418 : }
419 :
420 : return it;
421 : }
422 :
423 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _Blk3, typename _FuncElem, typename _FuncElse>
424 : void ProcessElements3(_StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
425 : {
426 : typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
427 : typename _StoreT::iterator it = rStore.begin(), itEnd = rStore.end();
428 : for (; it != itEnd; ++it, nTopRow += nDataSize)
429 : {
430 : nDataSize = it->size;
431 : switch (it->type)
432 : {
433 : case _Blk1::block_type:
434 : EachElem<_Blk1, typename _Blk1::iterator>(*it, rFuncElem);
435 : break;
436 : case _Blk2::block_type:
437 : EachElem<_Blk2, typename _Blk2::iterator>(*it, rFuncElem);
438 : break;
439 : case _Blk3::block_type:
440 : EachElem<_Blk3, typename _Blk3::iterator>(*it, rFuncElem);
441 : break;
442 : default:
443 : rFuncElse(it->type, nTopRow, nDataSize);
444 : }
445 : }
446 : }
447 :
448 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _Blk3, typename _Blk4, typename _FuncElem, typename _FuncElse>
449 : void ProcessElements4(_StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
450 : {
451 : typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
452 : typename _StoreT::iterator it = rStore.begin(), itEnd = rStore.end();
453 : for (; it != itEnd; ++it, nTopRow += nDataSize)
454 : {
455 : nDataSize = it->size;
456 : switch (it->type)
457 : {
458 : case _Blk1::block_type:
459 : EachElem<_Blk1, typename _Blk1::iterator>(*it, rFuncElem);
460 : break;
461 : case _Blk2::block_type:
462 : EachElem<_Blk2, typename _Blk2::iterator>(*it, rFuncElem);
463 : break;
464 : case _Blk3::block_type:
465 : EachElem<_Blk3, typename _Blk3::iterator>(*it, rFuncElem);
466 : break;
467 : case _Blk4::block_type:
468 : EachElem<_Blk4, typename _Blk4::iterator>(*it, rFuncElem);
469 : break;
470 : default:
471 : rFuncElse(it->type, nTopRow, nDataSize);
472 : }
473 : }
474 : }
475 :
476 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _Blk3, typename _Blk4, typename _FuncElem, typename _FuncElse>
477 : typename _StoreT::iterator
478 : ProcessElements4(
479 : const typename _StoreT::iterator& itPos, _StoreT& rStore,
480 : typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
481 : _FuncElem& rFuncElem, _FuncElse& rFuncElse)
482 : {
483 : typedef std::pair<typename _StoreT::iterator, typename _StoreT::size_type> PositionType;
484 :
485 : PositionType aPos = rStore.position(itPos, nStart);
486 : typename _StoreT::iterator it = aPos.first;
487 : typename _StoreT::size_type nOffset = aPos.second;
488 : typename _StoreT::size_type nDataSize = 0;
489 : typename _StoreT::size_type nTopRow = nStart;
490 :
491 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
492 : {
493 : bool bLastBlock = false;
494 : nDataSize = it->size - nOffset;
495 : if (nTopRow + nDataSize - 1 > nEnd)
496 : {
497 : // Truncate the block.
498 : nDataSize = nEnd - nTopRow + 1;
499 : bLastBlock = true;
500 : }
501 :
502 : switch (it->type)
503 : {
504 : case _Blk1::block_type:
505 : EachElem<_Blk1, typename _Blk1::iterator>(*it, nOffset, nDataSize, rFuncElem);
506 : break;
507 : case _Blk2::block_type:
508 : EachElem<_Blk2, typename _Blk2::iterator>(*it, nOffset, nDataSize, rFuncElem);
509 : break;
510 : case _Blk3::block_type:
511 : EachElem<_Blk3, typename _Blk3::iterator>(*it, nOffset, nDataSize, rFuncElem);
512 : break;
513 : case _Blk4::block_type:
514 : EachElem<_Blk4, typename _Blk4::iterator>(*it, nOffset, nDataSize, rFuncElem);
515 : break;
516 : default:
517 : rFuncElse(it->type, nTopRow, nDataSize);
518 : }
519 :
520 : if (bLastBlock)
521 : break;
522 : }
523 :
524 : return it;
525 : }
526 :
527 : template<typename _StoreT, typename _Blk1, typename _FuncElem, typename _FuncElse>
528 : std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type>
529 16 : FindElement1(
530 : const _StoreT& rStore, typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
531 : _FuncElem& rFuncElem, _FuncElse& rFuncElse)
532 : {
533 : typedef std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type> PositionType;
534 : typedef std::pair<typename _StoreT::size_type, bool> ElseRetType;
535 :
536 16 : PositionType aPos = rStore.position(nStart);
537 16 : typename _StoreT::const_iterator it = aPos.first;
538 16 : typename _StoreT::size_type nOffset = aPos.second;
539 16 : typename _StoreT::size_type nDataSize = 0;
540 16 : typename _StoreT::size_type nTopRow = nStart;
541 :
542 57 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
543 : {
544 50 : bool bLastBlock = false;
545 50 : nDataSize = it->size - nOffset;
546 50 : if (nTopRow + nDataSize - 1 > nEnd)
547 : {
548 : // Truncate the block.
549 9 : nDataSize = nEnd - nTopRow + 1;
550 9 : bLastBlock = true;
551 : }
552 :
553 50 : switch (it->type)
554 : {
555 : case _Blk1::block_type:
556 : {
557 4 : PositionType aRet = CheckElem<_Blk1>(rStore, it, nOffset, nDataSize, rFuncElem);
558 4 : if (aRet.first != rStore.end())
559 0 : return aRet;
560 : }
561 4 : break;
562 : default:
563 : {
564 46 : ElseRetType aRet = rFuncElse(it->type, nTopRow, nDataSize);
565 46 : if (aRet.second)
566 0 : return PositionType(it, aRet.first);
567 : }
568 : }
569 :
570 50 : if (bLastBlock)
571 9 : break;
572 : }
573 :
574 16 : return PositionType(rStore.end(), 0);
575 : }
576 :
577 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
578 : std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type>
579 1435466 : FindElement2(
580 : const _StoreT& rStore, typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
581 : _FuncElem& rFuncElem, _FuncElse& rFuncElse)
582 : {
583 : typedef std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type> PositionType;
584 : typedef std::pair<typename _StoreT::size_type, bool> ElseRetType;
585 :
586 1435466 : PositionType aPos = rStore.position(nStart);
587 1435466 : typename _StoreT::const_iterator it = aPos.first;
588 1435466 : typename _StoreT::size_type nOffset = aPos.second;
589 1435466 : typename _StoreT::size_type nDataSize = 0;
590 1435466 : typename _StoreT::size_type nTopRow = nStart;
591 :
592 1595143 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
593 : {
594 1436100 : bool bLastBlock = false;
595 1436100 : nDataSize = it->size - nOffset;
596 1436100 : if (nTopRow + nDataSize - 1 > nEnd)
597 : {
598 : // Truncate the block.
599 1276332 : nDataSize = nEnd - nTopRow + 1;
600 1276332 : bLastBlock = true;
601 : }
602 :
603 1436100 : switch (it->type)
604 : {
605 : case _Blk1::block_type:
606 : {
607 91 : PositionType aRet = CheckElem<_Blk1>(rStore, it, nOffset, nDataSize, rFuncElem);
608 91 : if (aRet.first != rStore.end())
609 91 : return aRet;
610 : }
611 0 : break;
612 : case _Blk2::block_type:
613 : {
614 184 : PositionType aRet = CheckElem<_Blk2>(rStore, it, nOffset, nDataSize, rFuncElem);
615 184 : if (aRet.first != rStore.end())
616 0 : return aRet;
617 : }
618 184 : break;
619 : default:
620 : {
621 1435825 : ElseRetType aRet = rFuncElse(*it, nOffset, nDataSize);
622 1435825 : if (aRet.second)
623 2 : return PositionType(it, aRet.first);
624 : }
625 : }
626 :
627 1436007 : if (bLastBlock)
628 1276330 : break;
629 : }
630 :
631 1435373 : return PositionType(rStore.end(), 0);
632 : }
633 :
634 : }
635 :
636 : #endif
637 :
638 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|