1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
10 #ifndef SC_MTVFUNCTIONS_HXX
11 #define SC_MTVFUNCTIONS_HXX
14 #include <mdds/multi_type_vector_types.hpp>
18 template<typename _SizeT
, typename _Ret
= bool>
21 _Ret
operator() (mdds::mtv::element_t
, _SizeT
, _SizeT
) const
28 * Generic algorithm to parse blocks of multi_type_vector either partially
31 template<typename _StoreT
, typename _Func
>
32 typename
_StoreT::const_iterator
34 const typename
_StoreT::const_iterator
& itPos
, const _StoreT
& rStore
, _Func
& rFunc
,
35 typename
_StoreT::size_type nStart
, typename
_StoreT::size_type nEnd
)
37 typedef std::pair
<typename
_StoreT::const_iterator
, typename
_StoreT::size_type
> PositionType
;
39 PositionType aPos
= rStore
.position(itPos
, nStart
);
40 typename
_StoreT::const_iterator it
= aPos
.first
;
41 typename
_StoreT::size_type nOffset
= aPos
.second
;
42 typename
_StoreT::size_type nDataSize
= 0;
43 typename
_StoreT::size_type nTopRow
= nStart
;
45 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
47 bool bLastBlock
= false;
48 nDataSize
= it
->size
- nOffset
;
49 if (nTopRow
+ nDataSize
- 1 > nEnd
)
51 // Truncate the block.
52 nDataSize
= nEnd
- nTopRow
+ 1;
56 rFunc(*it
, nOffset
, nDataSize
);
66 * Non-const variant of the above function. TODO: Find a way to merge these
67 * two in an elegant way.
69 template<typename _StoreT
, typename _Func
>
70 typename
_StoreT::iterator
71 ProcessBlock(const typename
_StoreT::iterator
& itPos
, _StoreT
& rStore
, _Func
& rFunc
, typename
_StoreT::size_type nStart
, typename
_StoreT::size_type nEnd
)
73 typedef std::pair
<typename
_StoreT::iterator
, typename
_StoreT::size_type
> PositionType
;
75 PositionType aPos
= rStore
.position(itPos
, nStart
);
76 typename
_StoreT::iterator it
= aPos
.first
;
77 typename
_StoreT::size_type nOffset
= aPos
.second
;
78 typename
_StoreT::size_type nDataSize
= 0;
79 typename
_StoreT::size_type nCurRow
= nStart
;
81 for (; it
!= rStore
.end() && nCurRow
<= nEnd
; ++it
, nOffset
= 0, nCurRow
+= nDataSize
)
83 bool bLastBlock
= false;
84 nDataSize
= it
->size
- nOffset
;
85 if (nCurRow
+ nDataSize
- 1 > nEnd
)
87 // Truncate the block.
88 nDataSize
= nEnd
- nCurRow
+ 1;
92 rFunc(*it
, nOffset
, nDataSize
);
101 template<typename _BlkT
, typename _ItrT
, typename _NodeT
, typename _FuncElem
>
102 void EachElem(_NodeT
& rNode
, size_t nOffset
, size_t nDataSize
, _FuncElem
& rFuncElem
)
104 _ItrT it
= _BlkT::begin(*rNode
.data
);
105 std::advance(it
, nOffset
);
107 std::advance(itEnd
, nDataSize
);
108 size_t nRow
= rNode
.position
+ nOffset
;
109 for (; it
!= itEnd
; ++it
, ++nRow
)
110 rFuncElem(nRow
, *it
);
113 template<typename _BlkT
, typename _ItrT
, typename _NodeT
, typename _FuncElem
>
114 void EachElem(_NodeT
& rNode
, _FuncElem
& rFuncElem
)
116 _ItrT it
= _BlkT::begin(*rNode
.data
);
117 _ItrT itEnd
= _BlkT::end(*rNode
.data
);
118 size_t nRow
= rNode
.position
;
119 for (; it
!= itEnd
; ++it
, ++nRow
)
120 rFuncElem(nRow
, *it
);
123 template<typename _BlkT
, typename _StoreT
, typename _FuncElem
>
124 std::pair
<typename
_StoreT::const_iterator
, size_t>
126 const _StoreT
& rStore
, const typename
_StoreT::const_iterator
& it
, size_t nOffset
, size_t nDataSize
,
127 _FuncElem
& rFuncElem
)
129 typedef std::pair
<typename
_StoreT::const_iterator
, size_t> PositionType
;
131 typename
_BlkT::const_iterator itData
= _BlkT::begin(*it
->data
);
132 std::advance(itData
, nOffset
);
133 typename
_BlkT::const_iterator itDataEnd
= itData
;
134 std::advance(itDataEnd
, nDataSize
);
135 size_t nTopRow
= it
->position
+ nOffset
;
136 size_t nRow
= nTopRow
;
137 for (; itData
!= itDataEnd
; ++itData
, ++nRow
)
139 if (rFuncElem(nRow
, *itData
))
140 return PositionType(it
, nRow
- it
->position
);
143 return PositionType(rStore
.end(), 0);
146 template<typename _StoreT
, typename _BlkT
, typename _FuncElem
, typename _FuncElse
>
147 void ParseElements1(const _StoreT
& rStore
, _FuncElem
& rFuncElem
, _FuncElse
& rFuncElse
)
149 typename
_StoreT::size_type nTopRow
= 0, nDataSize
= 0;
150 typename
_StoreT::const_iterator it
= rStore
.begin(), itEnd
= rStore
.end();
151 for (; it
!= itEnd
; ++it
, nTopRow
+= nDataSize
)
153 nDataSize
= it
->size
;
154 if (it
->type
!= _BlkT::block_type
)
156 rFuncElse(it
->type
, nTopRow
, nDataSize
);
160 EachElem
<_BlkT
, typename
_BlkT::const_iterator
>(*it
, rFuncElem
);
164 template<typename _StoreT
, typename _BlkT
, typename _FuncElem
, typename _FuncElse
>
165 typename
_StoreT::const_iterator
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
)
171 typedef std::pair
<typename
_StoreT::const_iterator
, typename
_StoreT::size_type
> PositionType
;
173 PositionType aPos
= rStore
.position(itPos
, nStart
);
174 typename
_StoreT::const_iterator it
= aPos
.first
;
175 typename
_StoreT::size_type nOffset
= aPos
.second
;
176 typename
_StoreT::size_type nDataSize
= 0;
177 typename
_StoreT::size_type nTopRow
= nStart
;
179 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
181 bool bLastBlock
= false;
182 nDataSize
= it
->size
- nOffset
;
183 if (nTopRow
+ nDataSize
- 1 > nEnd
)
185 // Truncate the block.
186 nDataSize
= nEnd
- nTopRow
+ 1;
190 if (it
->type
== _BlkT::block_type
)
191 EachElem
<_BlkT
, typename
_BlkT::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
193 rFuncElse(it
->type
, nTopRow
, nDataSize
);
203 template<typename _StoreT
, typename _Blk1
, typename _Blk2
, typename _FuncElem
, typename _FuncElse
>
204 typename
_StoreT::const_iterator
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
)
209 typedef std::pair
<typename
_StoreT::const_iterator
, typename
_StoreT::size_type
> PositionType
;
211 PositionType aPos
= rStore
.position(itPos
, nStart
);
212 typename
_StoreT::const_iterator it
= aPos
.first
;
213 typename
_StoreT::size_type nOffset
= aPos
.second
;
214 typename
_StoreT::size_type nDataSize
= 0;
215 typename
_StoreT::size_type nTopRow
= nStart
;
217 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
219 bool bLastBlock
= false;
220 nDataSize
= it
->size
- nOffset
;
221 if (nTopRow
+ nDataSize
- 1 > nEnd
)
223 // Truncate the block.
224 nDataSize
= nEnd
- nTopRow
+ 1;
230 case _Blk1::block_type
:
231 EachElem
<_Blk1
, typename
_Blk1::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
233 case _Blk2::block_type
:
234 EachElem
<_Blk2
, typename
_Blk2::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
237 rFuncElse(it
->type
, nTopRow
, nDataSize
);
247 template<typename _StoreT
, typename _Blk1
, typename _Blk2
, typename _Blk3
, typename _Blk4
, typename _FuncElem
, typename _FuncElse
>
248 typename
_StoreT::const_iterator
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
)
253 typedef std::pair
<typename
_StoreT::const_iterator
, typename
_StoreT::size_type
> PositionType
;
255 PositionType aPos
= rStore
.position(itPos
, nStart
);
256 typename
_StoreT::const_iterator it
= aPos
.first
;
257 typename
_StoreT::size_type nOffset
= aPos
.second
;
258 typename
_StoreT::size_type nDataSize
= 0;
259 typename
_StoreT::size_type nTopRow
= nStart
;
261 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
263 bool bLastBlock
= false;
264 nDataSize
= it
->size
- nOffset
;
265 if (nTopRow
+ nDataSize
- 1 > nEnd
)
267 // Truncate the block.
268 nDataSize
= nEnd
- nTopRow
+ 1;
274 case _Blk1::block_type
:
275 EachElem
<_Blk1
, typename
_Blk1::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
277 case _Blk2::block_type
:
278 EachElem
<_Blk2
, typename
_Blk2::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
280 case _Blk3::block_type
:
281 EachElem
<_Blk3
, typename
_Blk3::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
283 case _Blk4::block_type
:
284 EachElem
<_Blk4
, typename
_Blk4::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
287 rFuncElse(it
->type
, nTopRow
, nDataSize
);
297 template<typename _StoreT
, typename _BlkT
, typename _FuncElem
, typename _FuncElse
>
298 void ProcessElements1(_StoreT
& rStore
, _FuncElem
& rFuncElem
, _FuncElse
& rFuncElse
)
300 typename
_StoreT::size_type nTopRow
= 0, nDataSize
= 0;
301 typename
_StoreT::iterator it
= rStore
.begin(), itEnd
= rStore
.end();
302 for (; it
!= itEnd
; ++it
, nTopRow
+= nDataSize
)
304 nDataSize
= it
->size
;
305 if (it
->type
!= _BlkT::block_type
)
307 rFuncElse(it
->type
, nTopRow
, nDataSize
);
311 EachElem
<_BlkT
, typename
_BlkT::iterator
>(*it
, rFuncElem
);
316 * This variant specifies start and end positions.
318 template<typename _StoreT
, typename _BlkT
, typename _FuncElem
, typename _FuncElse
>
319 typename
_StoreT::iterator
321 const typename
_StoreT::iterator
& itPos
, _StoreT
& rStore
,
322 typename
_StoreT::size_type nStart
, typename
_StoreT::size_type nEnd
,
323 _FuncElem
& rFuncElem
, _FuncElse
& rFuncElse
)
325 typedef std::pair
<typename
_StoreT::iterator
, typename
_StoreT::size_type
> PositionType
;
327 PositionType aPos
= rStore
.position(itPos
, nStart
);
328 typename
_StoreT::iterator it
= aPos
.first
;
329 typename
_StoreT::size_type nOffset
= aPos
.second
;
330 typename
_StoreT::size_type nDataSize
= 0;
331 typename
_StoreT::size_type nTopRow
= nStart
;
333 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
335 bool bLastBlock
= false;
336 nDataSize
= it
->size
- nOffset
;
337 if (nTopRow
+ nDataSize
- 1 > nEnd
)
339 // Truncate the block.
340 nDataSize
= nEnd
- nTopRow
+ 1;
344 if (it
->type
== _BlkT::block_type
)
345 EachElem
<_BlkT
, typename
_BlkT::iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
347 rFuncElse(it
->type
, nTopRow
, nDataSize
);
356 template<typename _StoreT
, typename _Blk1
, typename _Blk2
, typename _FuncElem
, typename _FuncElse
>
357 void ProcessElements2(_StoreT
& rStore
, _FuncElem
& rFuncElem
, _FuncElse
& rFuncElse
)
359 typename
_StoreT::size_type nTopRow
= 0, nDataSize
= 0;
360 typename
_StoreT::iterator it
= rStore
.begin(), itEnd
= rStore
.end();
361 for (; it
!= itEnd
; ++it
, nTopRow
+= nDataSize
)
363 nDataSize
= it
->size
;
366 case _Blk1::block_type
:
367 EachElem
<_Blk1
, typename
_Blk1::iterator
>(*it
, rFuncElem
);
369 case _Blk2::block_type
:
370 EachElem
<_Blk2
, typename
_Blk2::iterator
>(*it
, rFuncElem
);
373 rFuncElse(it
->type
, nTopRow
, nDataSize
);
378 template<typename _StoreT
, typename _Blk1
, typename _Blk2
, typename _FuncElem
, typename _FuncElse
>
379 typename
_StoreT::iterator
381 const typename
_StoreT::iterator
& itPos
, _StoreT
& rStore
,
382 typename
_StoreT::size_type nStart
, typename
_StoreT::size_type nEnd
,
383 _FuncElem
& rFuncElem
, _FuncElse
& rFuncElse
)
385 typedef std::pair
<typename
_StoreT::iterator
, typename
_StoreT::size_type
> PositionType
;
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
;
393 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
395 bool bLastBlock
= false;
396 nDataSize
= it
->size
- nOffset
;
397 if (nTopRow
+ nDataSize
- 1 > nEnd
)
399 // Truncate the block.
400 nDataSize
= nEnd
- nTopRow
+ 1;
406 case _Blk1::block_type
:
407 EachElem
<_Blk1
, typename
_Blk1::iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
409 case _Blk2::block_type
:
410 EachElem
<_Blk2
, typename
_Blk2::iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
413 rFuncElse(it
->type
, nTopRow
, nDataSize
);
423 template<typename _StoreT
, typename _Blk1
, typename _Blk2
, typename _Blk3
, typename _FuncElem
, typename _FuncElse
>
424 void ProcessElements3(_StoreT
& rStore
, _FuncElem
& rFuncElem
, _FuncElse
& rFuncElse
)
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
)
430 nDataSize
= it
->size
;
433 case _Blk1::block_type
:
434 EachElem
<_Blk1
, typename
_Blk1::iterator
>(*it
, rFuncElem
);
436 case _Blk2::block_type
:
437 EachElem
<_Blk2
, typename
_Blk2::iterator
>(*it
, rFuncElem
);
439 case _Blk3::block_type
:
440 EachElem
<_Blk3
, typename
_Blk3::iterator
>(*it
, rFuncElem
);
443 rFuncElse(it
->type
, nTopRow
, nDataSize
);
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
)
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
)
455 nDataSize
= it
->size
;
458 case _Blk1::block_type
:
459 EachElem
<_Blk1
, typename
_Blk1::iterator
>(*it
, rFuncElem
);
461 case _Blk2::block_type
:
462 EachElem
<_Blk2
, typename
_Blk2::iterator
>(*it
, rFuncElem
);
464 case _Blk3::block_type
:
465 EachElem
<_Blk3
, typename
_Blk3::iterator
>(*it
, rFuncElem
);
467 case _Blk4::block_type
:
468 EachElem
<_Blk4
, typename
_Blk4::iterator
>(*it
, rFuncElem
);
471 rFuncElse(it
->type
, nTopRow
, nDataSize
);
476 template<typename _StoreT
, typename _Blk1
, typename _Blk2
, typename _Blk3
, typename _Blk4
, typename _FuncElem
, typename _FuncElse
>
477 typename
_StoreT::iterator
479 const typename
_StoreT::iterator
& itPos
, _StoreT
& rStore
,
480 typename
_StoreT::size_type nStart
, typename
_StoreT::size_type nEnd
,
481 _FuncElem
& rFuncElem
, _FuncElse
& rFuncElse
)
483 typedef std::pair
<typename
_StoreT::iterator
, typename
_StoreT::size_type
> PositionType
;
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
;
491 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
493 bool bLastBlock
= false;
494 nDataSize
= it
->size
- nOffset
;
495 if (nTopRow
+ nDataSize
- 1 > nEnd
)
497 // Truncate the block.
498 nDataSize
= nEnd
- nTopRow
+ 1;
504 case _Blk1::block_type
:
505 EachElem
<_Blk1
, typename
_Blk1::iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
507 case _Blk2::block_type
:
508 EachElem
<_Blk2
, typename
_Blk2::iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
510 case _Blk3::block_type
:
511 EachElem
<_Blk3
, typename
_Blk3::iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
513 case _Blk4::block_type
:
514 EachElem
<_Blk4
, typename
_Blk4::iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
517 rFuncElse(it
->type
, nTopRow
, nDataSize
);
527 template<typename _StoreT
, typename _Blk1
, typename _FuncElem
, typename _FuncElse
>
528 std::pair
<typename
_StoreT::const_iterator
, typename
_StoreT::size_type
>
530 const _StoreT
& rStore
, typename
_StoreT::size_type nStart
, typename
_StoreT::size_type nEnd
,
531 _FuncElem
& rFuncElem
, _FuncElse
& rFuncElse
)
533 typedef std::pair
<typename
_StoreT::const_iterator
, typename
_StoreT::size_type
> PositionType
;
534 typedef std::pair
<typename
_StoreT::size_type
, bool> ElseRetType
;
536 PositionType aPos
= rStore
.position(nStart
);
537 typename
_StoreT::const_iterator it
= aPos
.first
;
538 typename
_StoreT::size_type nOffset
= aPos
.second
;
539 typename
_StoreT::size_type nDataSize
= 0;
540 typename
_StoreT::size_type nTopRow
= nStart
;
542 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
544 bool bLastBlock
= false;
545 nDataSize
= it
->size
- nOffset
;
546 if (nTopRow
+ nDataSize
- 1 > nEnd
)
548 // Truncate the block.
549 nDataSize
= nEnd
- nTopRow
+ 1;
555 case _Blk1::block_type
:
557 PositionType aRet
= CheckElem
<_Blk1
>(rStore
, it
, nOffset
, nDataSize
, rFuncElem
);
558 if (aRet
.first
!= rStore
.end())
564 ElseRetType aRet
= rFuncElse(it
->type
, nTopRow
, nDataSize
);
566 return PositionType(it
, aRet
.first
);
574 return PositionType(rStore
.end(), 0);
577 template<typename _StoreT
, typename _Blk1
, typename _Blk2
, typename _FuncElem
, typename _FuncElse
>
578 std::pair
<typename
_StoreT::const_iterator
, typename
_StoreT::size_type
>
580 const _StoreT
& rStore
, typename
_StoreT::size_type nStart
, typename
_StoreT::size_type nEnd
,
581 _FuncElem
& rFuncElem
, _FuncElse
& rFuncElse
)
583 typedef std::pair
<typename
_StoreT::const_iterator
, typename
_StoreT::size_type
> PositionType
;
584 typedef std::pair
<typename
_StoreT::size_type
, bool> ElseRetType
;
586 PositionType aPos
= rStore
.position(nStart
);
587 typename
_StoreT::const_iterator it
= aPos
.first
;
588 typename
_StoreT::size_type nOffset
= aPos
.second
;
589 typename
_StoreT::size_type nDataSize
= 0;
590 typename
_StoreT::size_type nTopRow
= nStart
;
592 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
594 bool bLastBlock
= false;
595 nDataSize
= it
->size
- nOffset
;
596 if (nTopRow
+ nDataSize
- 1 > nEnd
)
598 // Truncate the block.
599 nDataSize
= nEnd
- nTopRow
+ 1;
605 case _Blk1::block_type
:
607 PositionType aRet
= CheckElem
<_Blk1
>(rStore
, it
, nOffset
, nDataSize
, rFuncElem
);
608 if (aRet
.first
!= rStore
.end())
612 case _Blk2::block_type
:
614 PositionType aRet
= CheckElem
<_Blk2
>(rStore
, it
, nOffset
, nDataSize
, rFuncElem
);
615 if (aRet
.first
!= rStore
.end())
621 ElseRetType aRet
= rFuncElse(it
->type
, nTopRow
, nDataSize
);
623 return PositionType(it
, aRet
.first
);
631 return PositionType(rStore
.end(), 0);
638 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */