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 2524683 : _Ret operator() (mdds::mtv::element_t, _SizeT, _SizeT) const
22 : {
23 2524683 : 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 966800 : 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 966800 : PositionType aPos = rStore.position(itPos, nStart);
40 966800 : typename _StoreT::const_iterator it = aPos.first;
41 966800 : typename _StoreT::size_type nOffset = aPos.second;
42 966800 : typename _StoreT::size_type nDataSize = 0;
43 966800 : typename _StoreT::size_type nTopRow = nStart;
44 :
45 1057423 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
46 : {
47 970165 : bool bLastBlock = false;
48 970165 : nDataSize = it->size - nOffset;
49 970165 : if (nTopRow + nDataSize - 1 > nEnd)
50 : {
51 : // Truncate the block.
52 879542 : nDataSize = nEnd - nTopRow + 1;
53 879542 : bLastBlock = true;
54 : }
55 :
56 970165 : rFunc(*it, nOffset, nDataSize);
57 :
58 970165 : if (bLastBlock)
59 879542 : break;
60 : }
61 :
62 966800 : 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 9414 : 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 9414 : PositionType aPos = rStore.position(itPos, nStart);
76 9414 : typename _StoreT::iterator it = aPos.first;
77 9414 : typename _StoreT::size_type nOffset = aPos.second;
78 9414 : typename _StoreT::size_type nDataSize = 0;
79 9414 : typename _StoreT::size_type nCurRow = nStart;
80 :
81 19376 : for (; it != rStore.end() && nCurRow <= nEnd; ++it, nOffset = 0, nCurRow += nDataSize)
82 : {
83 10324 : bool bLastBlock = false;
84 10324 : nDataSize = it->size - nOffset;
85 10324 : if (nCurRow + nDataSize - 1 > nEnd)
86 : {
87 : // Truncate the block.
88 362 : nDataSize = nEnd - nCurRow + 1;
89 362 : bLastBlock = true;
90 : }
91 :
92 10324 : rFunc(*it, nOffset, nDataSize);
93 :
94 10324 : if (bLastBlock)
95 362 : break;
96 : }
97 :
98 9414 : return it;
99 : }
100 :
101 : template<typename _BlkT, typename _ItrT, typename _NodeT, typename _FuncElem>
102 124900 : void EachElem(_NodeT& rNode, size_t nOffset, size_t nDataSize, _FuncElem& rFuncElem)
103 : {
104 124900 : _ItrT it = _BlkT::begin(*rNode.data);
105 124900 : std::advance(it, nOffset);
106 124900 : _ItrT itEnd = it;
107 124900 : std::advance(itEnd, nDataSize);
108 124900 : size_t nRow = rNode.position + nOffset;
109 582143 : for (; it != itEnd; ++it, ++nRow)
110 457243 : rFuncElem(nRow, *it);
111 124900 : }
112 :
113 : template<typename _BlkT, typename _ItrT, typename _NodeT, typename _FuncElem>
114 2503 : void EachElem(_NodeT& rNode, _FuncElem& rFuncElem)
115 : {
116 2503 : _ItrT it = _BlkT::begin(*rNode.data);
117 2503 : _ItrT itEnd = _BlkT::end(*rNode.data);
118 2503 : size_t nRow = rNode.position;
119 9509 : for (; it != itEnd; ++it, ++nRow)
120 7006 : rFuncElem(nRow, *it);
121 2503 : }
122 :
123 : template<typename _BlkT, typename _StoreT, typename _FuncElem>
124 : std::pair<typename _StoreT::const_iterator, size_t>
125 309 : 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 309 : typename _BlkT::const_iterator itData = _BlkT::begin(*it->data);
132 309 : std::advance(itData, nOffset);
133 309 : typename _BlkT::const_iterator itDataEnd = itData;
134 309 : std::advance(itDataEnd, nDataSize);
135 309 : size_t nTopRow = it->position + nOffset;
136 309 : size_t nRow = nTopRow;
137 533 : for (; itData != itDataEnd; ++itData, ++nRow)
138 : {
139 345 : if (rFuncElem(nRow, *itData))
140 121 : 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 21 : 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 21 : PositionType aPos = rStore.position(itPos, nStart);
174 21 : typename _StoreT::const_iterator it = aPos.first;
175 21 : typename _StoreT::size_type nOffset = aPos.second;
176 21 : typename _StoreT::size_type nDataSize = 0;
177 21 : typename _StoreT::size_type nTopRow = nStart;
178 :
179 45 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
180 : {
181 33 : bool bLastBlock = false;
182 33 : nDataSize = it->size - nOffset;
183 33 : if (nTopRow + nDataSize - 1 > nEnd)
184 : {
185 : // Truncate the block.
186 9 : nDataSize = nEnd - nTopRow + 1;
187 9 : bLastBlock = true;
188 : }
189 :
190 33 : if (it->type == _BlkT::block_type)
191 6 : EachElem<_BlkT, typename _BlkT::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
192 : else
193 27 : rFuncElse(it->type, nTopRow, nDataSize);
194 :
195 :
196 33 : if (bLastBlock)
197 9 : break;
198 : }
199 :
200 21 : return it;
201 : };
202 :
203 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
204 : typename _StoreT::const_iterator
205 967 : 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 967 : PositionType aPos = rStore.position(itPos, nStart);
212 967 : typename _StoreT::const_iterator it = aPos.first;
213 967 : typename _StoreT::size_type nOffset = aPos.second;
214 967 : typename _StoreT::size_type nDataSize = 0;
215 967 : typename _StoreT::size_type nTopRow = nStart;
216 :
217 1761 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
218 : {
219 1085 : bool bLastBlock = false;
220 1085 : nDataSize = it->size - nOffset;
221 1085 : if (nTopRow + nDataSize - 1 > nEnd)
222 : {
223 : // Truncate the block.
224 291 : nDataSize = nEnd - nTopRow + 1;
225 291 : bLastBlock = true;
226 : }
227 :
228 1085 : switch (it->type)
229 : {
230 : case _Blk1::block_type:
231 855 : EachElem<_Blk1, typename _Blk1::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
232 855 : break;
233 : case _Blk2::block_type:
234 171 : EachElem<_Blk2, typename _Blk2::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
235 171 : break;
236 : default:
237 59 : rFuncElse(it->type, nTopRow, nDataSize);
238 : }
239 :
240 1085 : if (bLastBlock)
241 291 : break;
242 : }
243 :
244 967 : 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 111323 : 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 111323 : PositionType aPos = rStore.position(itPos, nStart);
256 111323 : typename _StoreT::const_iterator it = aPos.first;
257 111323 : typename _StoreT::size_type nOffset = aPos.second;
258 111323 : typename _StoreT::size_type nDataSize = 0;
259 111323 : typename _StoreT::size_type nTopRow = nStart;
260 :
261 275550 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
262 : {
263 264831 : bool bLastBlock = false;
264 264831 : nDataSize = it->size - nOffset;
265 264831 : if (nTopRow + nDataSize - 1 > nEnd)
266 : {
267 : // Truncate the block.
268 100604 : nDataSize = nEnd - nTopRow + 1;
269 100604 : bLastBlock = true;
270 : }
271 :
272 264831 : switch (it->type)
273 : {
274 : case _Blk1::block_type:
275 78732 : EachElem<_Blk1, typename _Blk1::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
276 78732 : break;
277 : case _Blk2::block_type:
278 40088 : EachElem<_Blk2, typename _Blk2::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
279 40088 : break;
280 : case _Blk3::block_type:
281 487 : EachElem<_Blk3, typename _Blk3::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
282 487 : break;
283 : case _Blk4::block_type:
284 4134 : EachElem<_Blk4, typename _Blk4::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
285 4134 : break;
286 : default:
287 141390 : rFuncElse(it->type, nTopRow, nDataSize);
288 : }
289 :
290 264831 : if (bLastBlock)
291 100604 : break;
292 : }
293 :
294 111323 : return it;
295 : }
296 :
297 : template<typename _StoreT, typename _BlkT, typename _FuncElem, typename _FuncElse>
298 2109440 : void ProcessElements1(_StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
299 : {
300 2109440 : typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
301 2109440 : typename _StoreT::iterator it = rStore.begin(), itEnd = rStore.end();
302 4254541 : for (; it != itEnd; ++it, nTopRow += nDataSize)
303 : {
304 2145101 : nDataSize = it->size;
305 2145101 : if (it->type != _BlkT::block_type)
306 : {
307 2142626 : rFuncElse(it->type, nTopRow, nDataSize);
308 2142626 : continue;
309 : }
310 :
311 2475 : EachElem<_BlkT, typename _BlkT::iterator>(*it, rFuncElem);
312 : }
313 2109440 : }
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 30234 : 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 30234 : PositionType aPos = rStore.position(itPos, nStart);
328 30234 : typename _StoreT::iterator it = aPos.first;
329 30234 : typename _StoreT::size_type nOffset = aPos.second;
330 30234 : typename _StoreT::size_type nDataSize = 0;
331 30234 : typename _StoreT::size_type nTopRow = nStart;
332 :
333 48460 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
334 : {
335 44193 : bool bLastBlock = false;
336 44193 : nDataSize = it->size - nOffset;
337 44193 : if (nTopRow + nDataSize - 1 > nEnd)
338 : {
339 : // Truncate the block.
340 25967 : nDataSize = nEnd - nTopRow + 1;
341 25967 : bLastBlock = true;
342 : }
343 :
344 44193 : if (it->type == _BlkT::block_type)
345 408 : EachElem<_BlkT, typename _BlkT::iterator>(*it, nOffset, nDataSize, rFuncElem);
346 : else
347 43785 : rFuncElse(it->type, nTopRow, nDataSize);
348 :
349 44193 : if (bLastBlock)
350 25967 : break;
351 : }
352 :
353 30234 : return it;
354 : };
355 :
356 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
357 197632 : void ProcessElements2(_StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
358 : {
359 197632 : typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
360 197632 : typename _StoreT::iterator it = rStore.begin(), itEnd = rStore.end();
361 397694 : for (; it != itEnd; ++it, nTopRow += nDataSize)
362 : {
363 200062 : nDataSize = it->size;
364 200062 : switch (it->type)
365 : {
366 : case _Blk1::block_type:
367 0 : EachElem<_Blk1, typename _Blk1::iterator>(*it, rFuncElem);
368 0 : break;
369 : case _Blk2::block_type:
370 26 : EachElem<_Blk2, typename _Blk2::iterator>(*it, rFuncElem);
371 26 : break;
372 : default:
373 200036 : rFuncElse(it->type, nTopRow, nDataSize);
374 : }
375 : }
376 197632 : }
377 :
378 : template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
379 : typename _StoreT::iterator
380 193 : 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 193 : PositionType aPos = rStore.position(itPos, nStart);
388 193 : typename _StoreT::iterator it = aPos.first;
389 193 : typename _StoreT::size_type nOffset = aPos.second;
390 193 : typename _StoreT::size_type nDataSize = 0;
391 193 : typename _StoreT::size_type nTopRow = nStart;
392 :
393 237 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
394 : {
395 206 : bool bLastBlock = false;
396 206 : nDataSize = it->size - nOffset;
397 206 : if (nTopRow + nDataSize - 1 > nEnd)
398 : {
399 : // Truncate the block.
400 162 : nDataSize = nEnd - nTopRow + 1;
401 162 : bLastBlock = true;
402 : }
403 :
404 206 : switch (it->type)
405 : {
406 : case _Blk1::block_type:
407 19 : EachElem<_Blk1, typename _Blk1::iterator>(*it, nOffset, nDataSize, rFuncElem);
408 19 : break;
409 : case _Blk2::block_type:
410 0 : EachElem<_Blk2, typename _Blk2::iterator>(*it, nOffset, nDataSize, rFuncElem);
411 0 : break;
412 : default:
413 187 : rFuncElse(it->type, nTopRow, nDataSize);
414 : }
415 :
416 206 : if (bLastBlock)
417 162 : break;
418 : }
419 :
420 193 : 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 61 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
543 : {
544 54 : bool bLastBlock = false;
545 54 : nDataSize = it->size - nOffset;
546 54 : if (nTopRow + nDataSize - 1 > nEnd)
547 : {
548 : // Truncate the block.
549 9 : nDataSize = nEnd - nTopRow + 1;
550 9 : bLastBlock = true;
551 : }
552 :
553 54 : switch (it->type)
554 : {
555 : case _Blk1::block_type:
556 : {
557 6 : PositionType aRet = CheckElem<_Blk1>(rStore, it, nOffset, nDataSize, rFuncElem);
558 6 : if (aRet.first != rStore.end())
559 0 : return aRet;
560 : }
561 6 : break;
562 : default:
563 : {
564 48 : ElseRetType aRet = rFuncElse(it->type, nTopRow, nDataSize);
565 48 : if (aRet.second)
566 0 : return PositionType(it, aRet.first);
567 : }
568 : }
569 :
570 54 : 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 751402 : 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 751402 : PositionType aPos = rStore.position(nStart);
587 751402 : typename _StoreT::const_iterator it = aPos.first;
588 751402 : typename _StoreT::size_type nOffset = aPos.second;
589 751402 : typename _StoreT::size_type nDataSize = 0;
590 751402 : typename _StoreT::size_type nTopRow = nStart;
591 :
592 772159 : for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
593 : {
594 752261 : bool bLastBlock = false;
595 752261 : nDataSize = it->size - nOffset;
596 752261 : if (nTopRow + nDataSize - 1 > nEnd)
597 : {
598 : // Truncate the block.
599 731383 : nDataSize = nEnd - nTopRow + 1;
600 731383 : bLastBlock = true;
601 : }
602 :
603 752261 : switch (it->type)
604 : {
605 : case _Blk1::block_type:
606 : {
607 121 : PositionType aRet = CheckElem<_Blk1>(rStore, it, nOffset, nDataSize, rFuncElem);
608 121 : if (aRet.first != rStore.end())
609 121 : return aRet;
610 : }
611 0 : break;
612 : case _Blk2::block_type:
613 : {
614 182 : PositionType aRet = CheckElem<_Blk2>(rStore, it, nOffset, nDataSize, rFuncElem);
615 182 : if (aRet.first != rStore.end())
616 0 : return aRet;
617 : }
618 182 : break;
619 : default:
620 : {
621 751958 : ElseRetType aRet = rFuncElse(it->type, nTopRow, nDataSize);
622 751958 : if (aRet.second)
623 0 : return PositionType(it, aRet.first);
624 : }
625 : }
626 :
627 752140 : if (bLastBlock)
628 731383 : break;
629 : }
630 :
631 751281 : return PositionType(rStore.end(), 0);
632 : }
633 :
634 : }
635 :
636 : #endif
637 :
638 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|