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