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 10643400 : _Ret operator() (mdds::mtv::element_t, _SizeT, _SizeT) const
22 : {
23 10643400 : 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 3171928 : 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 3171928 : PositionType aPos = rStore.position(itPos, nStart);
40 3171928 : typename _StoreT::const_iterator it = aPos.first;
41 3171928 : typename _StoreT::size_type nOffset = aPos.second;
42 3171928 : typename _StoreT::size_type nDataSize = 0;
43 3171928 : typename _StoreT::size_type nTopRow = nStart;
44 :
45 3633664 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
46 : {
47 3179656 : bool bLastBlock = false;
48 3179656 : nDataSize = it->size - nOffset;
49 3179656 : if (nTopRow + nDataSize - 1 > nEnd)
50 : {
51 : // Truncate the block.
52 2717920 : nDataSize = nEnd - nTopRow + 1;
53 2717920 : bLastBlock = true;
54 : }
55 :
56 3179656 : rFunc(*it, nOffset, nDataSize);
57 :
58 3179656 : if (bLastBlock)
59 2717920 : break;
60 : }
61 :
62 3171928 : 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 43982 : 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 43982 : PositionType aPos = rStore.position(itPos, nStart);
76 43982 : typename _StoreT::iterator it = aPos.first;
77 43982 : typename _StoreT::size_type nOffset = aPos.second;
78 43982 : typename _StoreT::size_type nDataSize = 0;
79 43982 : typename _StoreT::size_type nCurRow = nStart;
80 :
81 89700 : for (; it != rStore.end() && nCurRow <= nEnd; ++it, nOffset = 0, nCurRow += nDataSize)
82 : {
83 46692 : bool bLastBlock = false;
84 46692 : nDataSize = it->size - nOffset;
85 46692 : if (nCurRow + nDataSize - 1 > nEnd)
86 : {
87 : // Truncate the block.
88 974 : nDataSize = nEnd - nCurRow + 1;
89 974 : bLastBlock = true;
90 : }
91 :
92 46692 : rFunc(*it, nOffset, nDataSize);
93 :
94 46692 : if (bLastBlock)
95 974 : break;
96 : }
97 :
98 43982 : return it;
99 : }
100 :
101 : template<typename _BlkT, typename _ItrT, typename _NodeT, typename _FuncElem>
102 241748 : void EachElem(_NodeT& rNode, size_t nOffset, size_t nDataSize, _FuncElem& rFuncElem)
103 : {
104 241748 : _ItrT it = _BlkT::begin(*rNode.data);
105 241748 : std::advance(it, nOffset);
106 241748 : _ItrT itEnd = it;
107 241748 : std::advance(itEnd, nDataSize);
108 241748 : size_t nRow = rNode.position + nOffset;
109 1062173 : for (; it != itEnd; ++it, ++nRow)
110 820425 : rFuncElem(nRow, *it);
111 241748 : }
112 :
113 : template<typename _BlkT, typename _ItrT, typename _NodeT, typename _FuncElem>
114 10554 : void EachElem(_NodeT& rNode, _FuncElem& rFuncElem)
115 : {
116 10554 : _ItrT it = _BlkT::begin(*rNode.data);
117 10554 : _ItrT itEnd = _BlkT::end(*rNode.data);
118 10554 : size_t nRow = rNode.position;
119 47382 : for (; it != itEnd; ++it, ++nRow)
120 36828 : rFuncElem(nRow, *it);
121 10554 : }
122 :
123 : template<typename _BlkT, typename _StoreT, typename _FuncElem>
124 : std::pair<typename _StoreT::const_iterator, size_t>
125 688 : 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 688 : typename _BlkT::const_iterator itData = _BlkT::begin(*it->data);
132 688 : std::advance(itData, nOffset);
133 688 : typename _BlkT::const_iterator itDataEnd = itData;
134 688 : std::advance(itDataEnd, nDataSize);
135 688 : size_t nTopRow = it->position + nOffset;
136 688 : size_t nRow = nTopRow;
137 2316 : for (; itData != itDataEnd; ++itData, ++nRow)
138 : {
139 1842 : if (rFuncElem(nRow, *itData))
140 214 : return PositionType(it, nRow - it->position);
141 : }
142 :
143 474 : return PositionType(rStore.end(), 0);
144 : }
145 :
146 : template<typename _StoreT, typename _BlkT, typename _FuncElem, typename _FuncElse>
147 2130 : void ParseElements1(const _StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
148 : {
149 2130 : typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
150 2130 : typename _StoreT::const_iterator it = rStore.begin(), itEnd = rStore.end();
151 4462 : for (; it != itEnd; ++it, nTopRow += nDataSize)
152 : {
153 2332 : nDataSize = it->size;
154 2332 : if (it->type != _BlkT::block_type)
155 : {
156 2290 : rFuncElse(it->type, nTopRow, nDataSize);
157 2290 : continue;
158 : }
159 :
160 42 : EachElem<_BlkT, typename _BlkT::const_iterator>(*it, rFuncElem);
161 : }
162 2130 : }
163 :
164 : template<typename _StoreT, typename _BlkT, typename _FuncElem, typename _FuncElse>
165 : typename _StoreT::const_iterator
166 128 : 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 128 : PositionType aPos = rStore.position(itPos, nStart);
174 128 : typename _StoreT::const_iterator it = aPos.first;
175 128 : typename _StoreT::size_type nOffset = aPos.second;
176 128 : typename _StoreT::size_type nDataSize = 0;
177 128 : typename _StoreT::size_type nTopRow = nStart;
178 :
179 262 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
180 : {
181 166 : bool bLastBlock = false;
182 166 : nDataSize = it->size - nOffset;
183 166 : if (nTopRow + nDataSize - 1 > nEnd)
184 : {
185 : // Truncate the block.
186 32 : nDataSize = nEnd - nTopRow + 1;
187 32 : bLastBlock = true;
188 : }
189 :
190 166 : if (it->type == _BlkT::block_type)
191 100 : EachElem<_BlkT, typename _BlkT::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
192 : else
193 66 : rFuncElse(it->type, nTopRow, nDataSize);
194 :
195 166 : if (bLastBlock)
196 32 : break;
197 : }
198 :
199 128 : return it;
200 : };
201 :
202 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
203 : typename _StoreT::const_iterator
204 2830 : 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 2830 : PositionType aPos = rStore.position(itPos, nStart);
211 2830 : typename _StoreT::const_iterator it = aPos.first;
212 2830 : typename _StoreT::size_type nOffset = aPos.second;
213 2830 : typename _StoreT::size_type nDataSize = 0;
214 2830 : typename _StoreT::size_type nTopRow = nStart;
215 :
216 5030 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
217 : {
218 3222 : bool bLastBlock = false;
219 3222 : nDataSize = it->size - nOffset;
220 3222 : if (nTopRow + nDataSize - 1 > nEnd)
221 : {
222 : // Truncate the block.
223 1022 : nDataSize = nEnd - nTopRow + 1;
224 1022 : bLastBlock = true;
225 : }
226 :
227 3222 : switch (it->type)
228 : {
229 : case _Blk1::block_type:
230 2214 : EachElem<_Blk1, typename _Blk1::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
231 2214 : break;
232 : case _Blk2::block_type:
233 414 : EachElem<_Blk2, typename _Blk2::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
234 414 : break;
235 : default:
236 594 : rFuncElse(it->type, nTopRow, nDataSize);
237 : }
238 :
239 3222 : if (bLastBlock)
240 1022 : break;
241 : }
242 :
243 2830 : 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 1331450 : 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 1331450 : PositionType aPos = rStore.position(itPos, nStart);
255 1331450 : typename _StoreT::const_iterator it = aPos.first;
256 1331450 : typename _StoreT::size_type nOffset = aPos.second;
257 1331450 : typename _StoreT::size_type nDataSize = 0;
258 1331450 : typename _StoreT::size_type nTopRow = nStart;
259 :
260 1629758 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
261 : {
262 1625729 : bool bLastBlock = false;
263 1625729 : nDataSize = it->size - nOffset;
264 1625729 : if (nTopRow + nDataSize - 1 > nEnd)
265 : {
266 : // Truncate the block.
267 1327421 : nDataSize = nEnd - nTopRow + 1;
268 1327421 : bLastBlock = true;
269 : }
270 :
271 1625729 : switch (it->type)
272 : {
273 : case _Blk1::block_type:
274 155858 : EachElem<_Blk1, typename _Blk1::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
275 155858 : break;
276 : case _Blk2::block_type:
277 72714 : EachElem<_Blk2, typename _Blk2::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
278 72714 : break;
279 : case _Blk3::block_type:
280 1144 : EachElem<_Blk3, typename _Blk3::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
281 1144 : break;
282 : case _Blk4::block_type:
283 8138 : EachElem<_Blk4, typename _Blk4::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
284 8138 : break;
285 : default:
286 1387875 : rFuncElse(it->type, nTopRow, nDataSize);
287 : }
288 :
289 1625729 : if (bLastBlock)
290 1327421 : break;
291 : }
292 :
293 1331450 : return it;
294 : }
295 :
296 : template<typename _StoreT, typename _BlkT, typename _FuncElem, typename _FuncElse>
297 7919616 : void ProcessElements1(_StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
298 : {
299 7919616 : typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
300 7919616 : typename _StoreT::iterator it = rStore.begin(), itEnd = rStore.end();
301 15937126 : for (; it != itEnd; ++it, nTopRow += nDataSize)
302 : {
303 8017510 : nDataSize = it->size;
304 8017510 : if (it->type != _BlkT::block_type)
305 : {
306 8007624 : rFuncElse(it->type, nTopRow, nDataSize);
307 8007624 : continue;
308 : }
309 :
310 9886 : EachElem<_BlkT, typename _BlkT::iterator>(*it, rFuncElem);
311 : }
312 7919616 : }
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 432266 : 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 432266 : PositionType aPos = rStore.position(itPos, nStart);
327 432266 : typename _StoreT::iterator it = aPos.first;
328 432266 : typename _StoreT::size_type nOffset = aPos.second;
329 432266 : typename _StoreT::size_type nDataSize = 0;
330 432266 : typename _StoreT::size_type nTopRow = nStart;
331 :
332 839579 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
333 : {
334 464919 : bool bLastBlock = false;
335 464919 : nDataSize = it->size - nOffset;
336 464919 : if (nTopRow + nDataSize - 1 > nEnd)
337 : {
338 : // Truncate the block.
339 57606 : nDataSize = nEnd - nTopRow + 1;
340 57606 : bLastBlock = true;
341 : }
342 :
343 464919 : if (it->type == _BlkT::block_type)
344 1166 : EachElem<_BlkT, typename _BlkT::iterator>(*it, nOffset, nDataSize, rFuncElem);
345 : else
346 463753 : rFuncElse(it->type, nTopRow, nDataSize);
347 :
348 464919 : if (bLastBlock)
349 57606 : break;
350 : }
351 :
352 432266 : return it;
353 : };
354 :
355 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
356 804864 : void ProcessElements2(_StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
357 : {
358 804864 : typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
359 804864 : typename _StoreT::iterator it = rStore.begin(), itEnd = rStore.end();
360 1616500 : for (; it != itEnd; ++it, nTopRow += nDataSize)
361 : {
362 811636 : nDataSize = it->size;
363 811636 : switch (it->type)
364 : {
365 : case _Blk1::block_type:
366 16 : EachElem<_Blk1, typename _Blk1::iterator>(*it, rFuncElem);
367 16 : break;
368 : case _Blk2::block_type:
369 610 : EachElem<_Blk2, typename _Blk2::iterator>(*it, rFuncElem);
370 610 : break;
371 : default:
372 811010 : rFuncElse(it->type, nTopRow, nDataSize);
373 : }
374 : }
375 804864 : }
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 32 : 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 32 : PositionType aPos = rStore.position(nStart);
536 32 : typename _StoreT::const_iterator it = aPos.first;
537 32 : typename _StoreT::size_type nOffset = aPos.second;
538 32 : typename _StoreT::size_type nDataSize = 0;
539 32 : typename _StoreT::size_type nTopRow = nStart;
540 :
541 114 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
542 : {
543 100 : bool bLastBlock = false;
544 100 : nDataSize = it->size - nOffset;
545 100 : if (nTopRow + nDataSize - 1 > nEnd)
546 : {
547 : // Truncate the block.
548 18 : nDataSize = nEnd - nTopRow + 1;
549 18 : bLastBlock = true;
550 : }
551 :
552 100 : switch (it->type)
553 : {
554 : case _Blk1::block_type:
555 : {
556 8 : PositionType aRet = CheckElem<_Blk1>(rStore, it, nOffset, nDataSize, rFuncElem);
557 8 : if (aRet.first != rStore.end())
558 0 : return aRet;
559 : }
560 8 : break;
561 : default:
562 : {
563 92 : ElseRetType aRet = rFuncElse(it->type, nTopRow, nDataSize);
564 92 : if (aRet.second)
565 0 : return PositionType(it, aRet.first);
566 : }
567 : }
568 :
569 100 : if (bLastBlock)
570 18 : break;
571 : }
572 :
573 32 : 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 2510394 : 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 2510394 : PositionType aPos = rStore.position(nStart);
586 2510394 : typename _StoreT::const_iterator it = aPos.first;
587 2510394 : typename _StoreT::size_type nOffset = aPos.second;
588 2510394 : typename _StoreT::size_type nDataSize = 0;
589 2510394 : typename _StoreT::size_type nTopRow = nStart;
590 :
591 2674712 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
592 : {
593 2512038 : bool bLastBlock = false;
594 2512038 : nDataSize = it->size - nOffset;
595 2512038 : if (nTopRow + nDataSize - 1 > nEnd)
596 : {
597 : // Truncate the block.
598 2347506 : nDataSize = nEnd - nTopRow + 1;
599 2347506 : bLastBlock = true;
600 : }
601 :
602 2512038 : switch (it->type)
603 : {
604 : case _Blk1::block_type:
605 : {
606 214 : PositionType aRet = CheckElem<_Blk1>(rStore, it, nOffset, nDataSize, rFuncElem);
607 214 : if (aRet.first != rStore.end())
608 214 : return aRet;
609 : }
610 0 : break;
611 : case _Blk2::block_type:
612 : {
613 466 : PositionType aRet = CheckElem<_Blk2>(rStore, it, nOffset, nDataSize, rFuncElem);
614 466 : if (aRet.first != rStore.end())
615 0 : return aRet;
616 : }
617 466 : break;
618 : default:
619 : {
620 2511358 : ElseRetType aRet = rFuncElse(*it, nOffset, nDataSize);
621 2511358 : if (aRet.second)
622 4 : return PositionType(it, aRet.first);
623 : }
624 : }
625 :
626 2511820 : if (bLastBlock)
627 2347502 : break;
628 : }
629 :
630 2510176 : return PositionType(rStore.end(), 0);
631 : }
632 :
633 : }
634 :
635 : #endif
636 :
637 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|