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 INCLUDED_SC_INC_MTVFUNCTIONS_HXX
11 : #define INCLUDED_SC_INC_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 5066639 : _Ret operator() (mdds::mtv::element_t, _SizeT, _SizeT) const
22 : {
23 5066639 : 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 1055694 : 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 1055694 : PositionType aPos = rStore.position(itPos, nStart);
40 1055694 : typename _StoreT::const_iterator it = aPos.first;
41 1055694 : typename _StoreT::size_type nOffset = aPos.second;
42 1055694 : typename _StoreT::size_type nDataSize = 0;
43 1055694 : typename _StoreT::size_type nTopRow = nStart;
44 :
45 1298050 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
46 : {
47 1059564 : bool bLastBlock = false;
48 1059564 : nDataSize = it->size - nOffset;
49 1059564 : if (nTopRow + nDataSize - 1 > nEnd)
50 : {
51 : // Truncate the block.
52 817208 : nDataSize = nEnd - nTopRow + 1;
53 817208 : bLastBlock = true;
54 : }
55 :
56 1059564 : rFunc(*it, nOffset, nDataSize);
57 :
58 1059564 : if (bLastBlock)
59 817208 : break;
60 : }
61 :
62 1055694 : 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 64811 : 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 64811 : PositionType aPos = rStore.position(itPos, nStart);
76 64811 : typename _StoreT::iterator it = aPos.first;
77 64811 : typename _StoreT::size_type nOffset = aPos.second;
78 64811 : typename _StoreT::size_type nDataSize = 0;
79 64811 : typename _StoreT::size_type nCurRow = nStart;
80 :
81 129561 : for (; it != rStore.end() && nCurRow <= nEnd; ++it, nOffset = 0, nCurRow += nDataSize)
82 : {
83 67414 : bool bLastBlock = false;
84 67414 : nDataSize = it->size - nOffset;
85 67414 : if (nCurRow + nDataSize - 1 > nEnd)
86 : {
87 : // Truncate the block.
88 2664 : nDataSize = nEnd - nCurRow + 1;
89 2664 : bLastBlock = true;
90 : }
91 :
92 67414 : rFunc(*it, nOffset, nDataSize);
93 :
94 67414 : if (bLastBlock)
95 2664 : break;
96 : }
97 :
98 64811 : return it;
99 : }
100 :
101 : template<typename _BlkT, typename _ItrT, typename _NodeT, typename _FuncElem>
102 130305 : void EachElem(_NodeT& rNode, size_t nOffset, size_t nDataSize, _FuncElem& rFuncElem)
103 : {
104 130305 : _ItrT it = _BlkT::begin(*rNode.data);
105 130305 : std::advance(it, nOffset);
106 130305 : _ItrT itEnd = it;
107 130305 : std::advance(itEnd, nDataSize);
108 130305 : size_t nRow = rNode.position + nOffset;
109 558422 : for (; it != itEnd; ++it, ++nRow)
110 428117 : rFuncElem(nRow, *it);
111 130305 : }
112 :
113 : template<typename _BlkT, typename _ItrT, typename _NodeT, typename _FuncElem>
114 5291 : void EachElem(_NodeT& rNode, _FuncElem& rFuncElem)
115 : {
116 5291 : _ItrT it = _BlkT::begin(*rNode.data);
117 5291 : _ItrT itEnd = _BlkT::end(*rNode.data);
118 5291 : size_t nRow = rNode.position;
119 25512 : for (; it != itEnd; ++it, ++nRow)
120 20221 : rFuncElem(nRow, *it);
121 5291 : }
122 :
123 : template<typename _BlkT, typename _StoreT, typename _FuncElem>
124 : std::pair<typename _StoreT::const_iterator, size_t>
125 332 : 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 332 : typename _BlkT::const_iterator itData = _BlkT::begin(*it->data);
132 332 : std::advance(itData, nOffset);
133 332 : typename _BlkT::const_iterator itDataEnd = itData;
134 332 : std::advance(itDataEnd, nDataSize);
135 332 : size_t nTopRow = it->position + nOffset;
136 332 : size_t nRow = nTopRow;
137 1134 : for (; itData != itDataEnd; ++itData, ++nRow)
138 : {
139 909 : if (rFuncElem(nRow, *itData))
140 107 : return PositionType(it, nRow - it->position);
141 : }
142 :
143 225 : return PositionType(rStore.end(), 0);
144 : }
145 :
146 : template<typename _StoreT, typename _BlkT, typename _FuncElem, typename _FuncElse>
147 1065 : void ParseElements1(const _StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
148 : {
149 1065 : typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
150 1065 : typename _StoreT::const_iterator it = rStore.begin(), itEnd = rStore.end();
151 2231 : for (; it != itEnd; ++it, nTopRow += nDataSize)
152 : {
153 1166 : nDataSize = it->size;
154 1166 : if (it->type != _BlkT::block_type)
155 : {
156 1145 : rFuncElse(it->type, nTopRow, nDataSize);
157 1145 : continue;
158 : }
159 :
160 21 : EachElem<_BlkT, typename _BlkT::const_iterator>(*it, rFuncElem);
161 : }
162 1065 : }
163 :
164 : template<typename _StoreT, typename _BlkT, typename _FuncElem, typename _FuncElse>
165 : typename _StoreT::const_iterator
166 61 : 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 61 : PositionType aPos = rStore.position(itPos, nStart);
174 61 : typename _StoreT::const_iterator it = aPos.first;
175 61 : typename _StoreT::size_type nOffset = aPos.second;
176 61 : typename _StoreT::size_type nDataSize = 0;
177 61 : typename _StoreT::size_type nTopRow = nStart;
178 :
179 125 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
180 : {
181 80 : bool bLastBlock = false;
182 80 : nDataSize = it->size - nOffset;
183 80 : if (nTopRow + nDataSize - 1 > nEnd)
184 : {
185 : // Truncate the block.
186 16 : nDataSize = nEnd - nTopRow + 1;
187 16 : bLastBlock = true;
188 : }
189 :
190 80 : if (it->type == _BlkT::block_type)
191 47 : EachElem<_BlkT, typename _BlkT::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
192 : else
193 33 : rFuncElse(it->type, nTopRow, nDataSize);
194 :
195 80 : if (bLastBlock)
196 16 : break;
197 : }
198 :
199 61 : return it;
200 : };
201 :
202 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
203 : typename _StoreT::const_iterator
204 3088 : ParseElements2(
205 : const typename _StoreT::const_iterator& itPos, const _StoreT& rStore, typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
206 : _FuncElem& rFuncElem, _FuncElse& rFuncElse)
207 : {
208 : typedef std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type> PositionType;
209 :
210 3088 : PositionType aPos = rStore.position(itPos, nStart);
211 3088 : typename _StoreT::const_iterator it = aPos.first;
212 3088 : typename _StoreT::size_type nOffset = aPos.second;
213 3088 : typename _StoreT::size_type nDataSize = 0;
214 3088 : typename _StoreT::size_type nTopRow = nStart;
215 :
216 4278 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
217 : {
218 3291 : bool bLastBlock = false;
219 3291 : nDataSize = it->size - nOffset;
220 3291 : if (nTopRow + nDataSize - 1 > nEnd)
221 : {
222 : // Truncate the block.
223 2101 : nDataSize = nEnd - nTopRow + 1;
224 2101 : bLastBlock = true;
225 : }
226 :
227 3291 : switch (it->type)
228 : {
229 : case _Blk1::block_type:
230 1211 : EachElem<_Blk1, typename _Blk1::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
231 1211 : break;
232 : case _Blk2::block_type:
233 230 : EachElem<_Blk2, typename _Blk2::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
234 230 : break;
235 : default:
236 1850 : rFuncElse(it->type, nTopRow, nDataSize);
237 : }
238 :
239 3291 : if (bLastBlock)
240 2101 : break;
241 : }
242 :
243 3088 : return it;
244 : }
245 :
246 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _Blk3, typename _Blk4, typename _FuncElem, typename _FuncElse>
247 : typename _StoreT::const_iterator
248 137003 : ParseElements4(
249 : const typename _StoreT::const_iterator& itPos, const _StoreT& rStore, typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
250 : _FuncElem& rFuncElem, _FuncElse& rFuncElse)
251 : {
252 : typedef std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type> PositionType;
253 :
254 137003 : PositionType aPos = rStore.position(itPos, nStart);
255 137003 : typename _StoreT::const_iterator it = aPos.first;
256 137003 : typename _StoreT::size_type nOffset = aPos.second;
257 137003 : typename _StoreT::size_type nDataSize = 0;
258 137003 : typename _StoreT::size_type nTopRow = nStart;
259 :
260 292037 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
261 : {
262 287208 : bool bLastBlock = false;
263 287208 : nDataSize = it->size - nOffset;
264 287208 : if (nTopRow + nDataSize - 1 > nEnd)
265 : {
266 : // Truncate the block.
267 132174 : nDataSize = nEnd - nTopRow + 1;
268 132174 : bLastBlock = true;
269 : }
270 :
271 287208 : switch (it->type)
272 : {
273 : case _Blk1::block_type:
274 81459 : EachElem<_Blk1, typename _Blk1::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
275 81459 : break;
276 : case _Blk2::block_type:
277 41527 : EachElem<_Blk2, typename _Blk2::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
278 41527 : break;
279 : case _Blk3::block_type:
280 702 : EachElem<_Blk3, typename _Blk3::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
281 702 : break;
282 : case _Blk4::block_type:
283 4232 : EachElem<_Blk4, typename _Blk4::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
284 4232 : break;
285 : default:
286 159288 : rFuncElse(it->type, nTopRow, nDataSize);
287 : }
288 :
289 287208 : if (bLastBlock)
290 132174 : break;
291 : }
292 :
293 137003 : return it;
294 : }
295 :
296 : template<typename _StoreT, typename _BlkT, typename _FuncElem, typename _FuncElse>
297 4149248 : void ProcessElements1(_StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
298 : {
299 4149248 : typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
300 4149248 : typename _StoreT::iterator it = rStore.begin(), itEnd = rStore.end();
301 8345929 : for (; it != itEnd; ++it, nTopRow += nDataSize)
302 : {
303 4196681 : nDataSize = it->size;
304 4196681 : if (it->type != _BlkT::block_type)
305 : {
306 4191770 : rFuncElse(it->type, nTopRow, nDataSize);
307 4191770 : continue;
308 : }
309 :
310 4911 : EachElem<_BlkT, typename _BlkT::iterator>(*it, rFuncElem);
311 : }
312 4149248 : }
313 :
314 : /**
315 : * This variant specifies start and end positions.
316 : */
317 : template<typename _StoreT, typename _BlkT, typename _FuncElem, typename _FuncElse>
318 : typename _StoreT::iterator
319 243631 : ProcessElements1(
320 : const typename _StoreT::iterator& itPos, _StoreT& rStore,
321 : typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
322 : _FuncElem& rFuncElem, _FuncElse& rFuncElse)
323 : {
324 : typedef std::pair<typename _StoreT::iterator, typename _StoreT::size_type> PositionType;
325 :
326 243631 : PositionType aPos = rStore.position(itPos, nStart);
327 243631 : typename _StoreT::iterator it = aPos.first;
328 243631 : typename _StoreT::size_type nOffset = aPos.second;
329 243631 : typename _StoreT::size_type nDataSize = 0;
330 243631 : typename _StoreT::size_type nTopRow = nStart;
331 :
332 463146 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
333 : {
334 270427 : bool bLastBlock = false;
335 270427 : nDataSize = it->size - nOffset;
336 270427 : if (nTopRow + nDataSize - 1 > nEnd)
337 : {
338 : // Truncate the block.
339 50912 : nDataSize = nEnd - nTopRow + 1;
340 50912 : bLastBlock = true;
341 : }
342 :
343 270427 : if (it->type == _BlkT::block_type)
344 897 : EachElem<_BlkT, typename _BlkT::iterator>(*it, nOffset, nDataSize, rFuncElem);
345 : else
346 269530 : rFuncElse(it->type, nTopRow, nDataSize);
347 :
348 270427 : if (bLastBlock)
349 50912 : break;
350 : }
351 :
352 243631 : return it;
353 : };
354 :
355 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
356 453632 : void ProcessElements2(_StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
357 : {
358 453632 : typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
359 453632 : typename _StoreT::iterator it = rStore.begin(), itEnd = rStore.end();
360 910767 : for (; it != itEnd; ++it, nTopRow += nDataSize)
361 : {
362 457135 : nDataSize = it->size;
363 457135 : switch (it->type)
364 : {
365 : case _Blk1::block_type:
366 8 : EachElem<_Blk1, typename _Blk1::iterator>(*it, rFuncElem);
367 8 : break;
368 : case _Blk2::block_type:
369 351 : EachElem<_Blk2, typename _Blk2::iterator>(*it, rFuncElem);
370 351 : break;
371 : default:
372 456776 : rFuncElse(it->type, nTopRow, nDataSize);
373 : }
374 : }
375 453632 : }
376 :
377 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
378 : typename _StoreT::iterator
379 : ProcessElements2(
380 : const typename _StoreT::iterator& itPos, _StoreT& rStore,
381 : typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
382 : _FuncElem& rFuncElem, _FuncElse& rFuncElse)
383 : {
384 : typedef std::pair<typename _StoreT::iterator, typename _StoreT::size_type> PositionType;
385 :
386 : PositionType aPos = rStore.position(itPos, nStart);
387 : typename _StoreT::iterator it = aPos.first;
388 : typename _StoreT::size_type nOffset = aPos.second;
389 : typename _StoreT::size_type nDataSize = 0;
390 : typename _StoreT::size_type nTopRow = nStart;
391 :
392 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
393 : {
394 : bool bLastBlock = false;
395 : nDataSize = it->size - nOffset;
396 : if (nTopRow + nDataSize - 1 > nEnd)
397 : {
398 : // Truncate the block.
399 : nDataSize = nEnd - nTopRow + 1;
400 : bLastBlock = true;
401 : }
402 :
403 : switch (it->type)
404 : {
405 : case _Blk1::block_type:
406 : EachElem<_Blk1, typename _Blk1::iterator>(*it, nOffset, nDataSize, rFuncElem);
407 : break;
408 : case _Blk2::block_type:
409 : EachElem<_Blk2, typename _Blk2::iterator>(*it, nOffset, nDataSize, rFuncElem);
410 : break;
411 : default:
412 : rFuncElse(it->type, nTopRow, nDataSize);
413 : }
414 :
415 : if (bLastBlock)
416 : break;
417 : }
418 :
419 : return it;
420 : }
421 :
422 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _Blk3, typename _FuncElem, typename _FuncElse>
423 : void ProcessElements3(_StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
424 : {
425 : typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
426 : typename _StoreT::iterator it = rStore.begin(), itEnd = rStore.end();
427 : for (; it != itEnd; ++it, nTopRow += nDataSize)
428 : {
429 : nDataSize = it->size;
430 : switch (it->type)
431 : {
432 : case _Blk1::block_type:
433 : EachElem<_Blk1, typename _Blk1::iterator>(*it, rFuncElem);
434 : break;
435 : case _Blk2::block_type:
436 : EachElem<_Blk2, typename _Blk2::iterator>(*it, rFuncElem);
437 : break;
438 : case _Blk3::block_type:
439 : EachElem<_Blk3, typename _Blk3::iterator>(*it, rFuncElem);
440 : break;
441 : default:
442 : rFuncElse(it->type, nTopRow, nDataSize);
443 : }
444 : }
445 : }
446 :
447 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _Blk3, typename _Blk4, typename _FuncElem, typename _FuncElse>
448 : void ProcessElements4(_StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
449 : {
450 : typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
451 : typename _StoreT::iterator it = rStore.begin(), itEnd = rStore.end();
452 : for (; it != itEnd; ++it, nTopRow += nDataSize)
453 : {
454 : nDataSize = it->size;
455 : switch (it->type)
456 : {
457 : case _Blk1::block_type:
458 : EachElem<_Blk1, typename _Blk1::iterator>(*it, rFuncElem);
459 : break;
460 : case _Blk2::block_type:
461 : EachElem<_Blk2, typename _Blk2::iterator>(*it, rFuncElem);
462 : break;
463 : case _Blk3::block_type:
464 : EachElem<_Blk3, typename _Blk3::iterator>(*it, rFuncElem);
465 : break;
466 : case _Blk4::block_type:
467 : EachElem<_Blk4, typename _Blk4::iterator>(*it, rFuncElem);
468 : break;
469 : default:
470 : rFuncElse(it->type, nTopRow, nDataSize);
471 : }
472 : }
473 : }
474 :
475 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _Blk3, typename _Blk4, typename _FuncElem, typename _FuncElse>
476 : typename _StoreT::iterator
477 : ProcessElements4(
478 : const typename _StoreT::iterator& itPos, _StoreT& rStore,
479 : typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
480 : _FuncElem& rFuncElem, _FuncElse& rFuncElse)
481 : {
482 : typedef std::pair<typename _StoreT::iterator, typename _StoreT::size_type> PositionType;
483 :
484 : PositionType aPos = rStore.position(itPos, nStart);
485 : typename _StoreT::iterator it = aPos.first;
486 : typename _StoreT::size_type nOffset = aPos.second;
487 : typename _StoreT::size_type nDataSize = 0;
488 : typename _StoreT::size_type nTopRow = nStart;
489 :
490 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
491 : {
492 : bool bLastBlock = false;
493 : nDataSize = it->size - nOffset;
494 : if (nTopRow + nDataSize - 1 > nEnd)
495 : {
496 : // Truncate the block.
497 : nDataSize = nEnd - nTopRow + 1;
498 : bLastBlock = true;
499 : }
500 :
501 : switch (it->type)
502 : {
503 : case _Blk1::block_type:
504 : EachElem<_Blk1, typename _Blk1::iterator>(*it, nOffset, nDataSize, rFuncElem);
505 : break;
506 : case _Blk2::block_type:
507 : EachElem<_Blk2, typename _Blk2::iterator>(*it, nOffset, nDataSize, rFuncElem);
508 : break;
509 : case _Blk3::block_type:
510 : EachElem<_Blk3, typename _Blk3::iterator>(*it, nOffset, nDataSize, rFuncElem);
511 : break;
512 : case _Blk4::block_type:
513 : EachElem<_Blk4, typename _Blk4::iterator>(*it, nOffset, nDataSize, rFuncElem);
514 : break;
515 : default:
516 : rFuncElse(it->type, nTopRow, nDataSize);
517 : }
518 :
519 : if (bLastBlock)
520 : break;
521 : }
522 :
523 : return it;
524 : }
525 :
526 : template<typename _StoreT, typename _Blk1, typename _FuncElem, typename _FuncElse>
527 : std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type>
528 16 : FindElement1(
529 : const _StoreT& rStore, typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
530 : _FuncElem& rFuncElem, _FuncElse& rFuncElse)
531 : {
532 : typedef std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type> PositionType;
533 : typedef std::pair<typename _StoreT::size_type, bool> ElseRetType;
534 :
535 16 : PositionType aPos = rStore.position(nStart);
536 16 : typename _StoreT::const_iterator it = aPos.first;
537 16 : typename _StoreT::size_type nOffset = aPos.second;
538 16 : typename _StoreT::size_type nDataSize = 0;
539 16 : typename _StoreT::size_type nTopRow = nStart;
540 :
541 57 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
542 : {
543 50 : bool bLastBlock = false;
544 50 : nDataSize = it->size - nOffset;
545 50 : if (nTopRow + nDataSize - 1 > nEnd)
546 : {
547 : // Truncate the block.
548 9 : nDataSize = nEnd - nTopRow + 1;
549 9 : bLastBlock = true;
550 : }
551 :
552 50 : switch (it->type)
553 : {
554 : case _Blk1::block_type:
555 : {
556 4 : PositionType aRet = CheckElem<_Blk1>(rStore, it, nOffset, nDataSize, rFuncElem);
557 4 : if (aRet.first != rStore.end())
558 0 : return aRet;
559 : }
560 4 : break;
561 : default:
562 : {
563 46 : ElseRetType aRet = rFuncElse(it->type, nTopRow, nDataSize);
564 46 : if (aRet.second)
565 0 : return PositionType(it, aRet.first);
566 : }
567 : }
568 :
569 50 : if (bLastBlock)
570 9 : break;
571 : }
572 :
573 16 : return PositionType(rStore.end(), 0);
574 : }
575 :
576 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
577 : std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type>
578 718653 : FindElement2(
579 : const _StoreT& rStore, typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
580 : _FuncElem& rFuncElem, _FuncElse& rFuncElse)
581 : {
582 : typedef std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type> PositionType;
583 : typedef std::pair<typename _StoreT::size_type, bool> ElseRetType;
584 :
585 718653 : PositionType aPos = rStore.position(nStart);
586 718653 : typename _StoreT::const_iterator it = aPos.first;
587 718653 : typename _StoreT::size_type nOffset = aPos.second;
588 718653 : typename _StoreT::size_type nDataSize = 0;
589 718653 : typename _StoreT::size_type nTopRow = nStart;
590 :
591 805023 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
592 : {
593 719487 : bool bLastBlock = false;
594 719487 : nDataSize = it->size - nOffset;
595 719487 : if (nTopRow + nDataSize - 1 > nEnd)
596 : {
597 : // Truncate the block.
598 633010 : nDataSize = nEnd - nTopRow + 1;
599 633010 : bLastBlock = true;
600 : }
601 :
602 719487 : switch (it->type)
603 : {
604 : case _Blk1::block_type:
605 : {
606 107 : PositionType aRet = CheckElem<_Blk1>(rStore, it, nOffset, nDataSize, rFuncElem);
607 107 : if (aRet.first != rStore.end())
608 107 : return aRet;
609 : }
610 0 : break;
611 : case _Blk2::block_type:
612 : {
613 221 : PositionType aRet = CheckElem<_Blk2>(rStore, it, nOffset, nDataSize, rFuncElem);
614 221 : if (aRet.first != rStore.end())
615 0 : return aRet;
616 : }
617 221 : break;
618 : default:
619 : {
620 719159 : ElseRetType aRet = rFuncElse(*it, nOffset, nDataSize);
621 719159 : if (aRet.second)
622 2 : return PositionType(it, aRet.first);
623 : }
624 : }
625 :
626 719378 : if (bLastBlock)
627 633008 : break;
628 : }
629 :
630 718544 : return PositionType(rStore.end(), 0);
631 : }
632 :
633 : }
634 :
635 : #endif
636 :
637 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|