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 INCLUDED_SC_INC_MTVFUNCTIONS_HXX
11 #define INCLUDED_SC_INC_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
);
202 template<typename _StoreT
, typename _Blk1
, typename _Blk2
, typename _FuncElem
, typename _FuncElse
>
203 typename
_StoreT::const_iterator
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
)
208 typedef std::pair
<typename
_StoreT::const_iterator
, typename
_StoreT::size_type
> PositionType
;
210 PositionType aPos
= rStore
.position(itPos
, nStart
);
211 typename
_StoreT::const_iterator it
= aPos
.first
;
212 typename
_StoreT::size_type nOffset
= aPos
.second
;
213 typename
_StoreT::size_type nDataSize
= 0;
214 typename
_StoreT::size_type nTopRow
= nStart
;
216 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
218 bool bLastBlock
= false;
219 nDataSize
= it
->size
- nOffset
;
220 if (nTopRow
+ nDataSize
- 1 > nEnd
)
222 // Truncate the block.
223 nDataSize
= nEnd
- nTopRow
+ 1;
229 case _Blk1::block_type
:
230 EachElem
<_Blk1
, typename
_Blk1::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
232 case _Blk2::block_type
:
233 EachElem
<_Blk2
, typename
_Blk2::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
236 rFuncElse(it
->type
, nTopRow
, nDataSize
);
246 template<typename _StoreT
, typename _Blk1
, typename _Blk2
, typename _Blk3
, typename _Blk4
, typename _FuncElem
, typename _FuncElse
>
247 typename
_StoreT::const_iterator
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
)
252 typedef std::pair
<typename
_StoreT::const_iterator
, typename
_StoreT::size_type
> PositionType
;
254 PositionType aPos
= rStore
.position(itPos
, nStart
);
255 typename
_StoreT::const_iterator it
= aPos
.first
;
256 typename
_StoreT::size_type nOffset
= aPos
.second
;
257 typename
_StoreT::size_type nDataSize
= 0;
258 typename
_StoreT::size_type nTopRow
= nStart
;
260 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
262 bool bLastBlock
= false;
263 nDataSize
= it
->size
- nOffset
;
264 if (nTopRow
+ nDataSize
- 1 > nEnd
)
266 // Truncate the block.
267 nDataSize
= nEnd
- nTopRow
+ 1;
273 case _Blk1::block_type
:
274 EachElem
<_Blk1
, typename
_Blk1::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
276 case _Blk2::block_type
:
277 EachElem
<_Blk2
, typename
_Blk2::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
279 case _Blk3::block_type
:
280 EachElem
<_Blk3
, typename
_Blk3::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
282 case _Blk4::block_type
:
283 EachElem
<_Blk4
, typename
_Blk4::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
286 rFuncElse(it
->type
, nTopRow
, nDataSize
);
296 template<typename _StoreT
, typename _BlkT
, typename _FuncElem
, typename _FuncElse
>
297 void ProcessElements1(_StoreT
& rStore
, _FuncElem
& rFuncElem
, _FuncElse
& rFuncElse
)
299 typename
_StoreT::size_type nTopRow
= 0, nDataSize
= 0;
300 typename
_StoreT::iterator it
= rStore
.begin(), itEnd
= rStore
.end();
301 for (; it
!= itEnd
; ++it
, nTopRow
+= nDataSize
)
303 nDataSize
= it
->size
;
304 if (it
->type
!= _BlkT::block_type
)
306 rFuncElse(it
->type
, nTopRow
, nDataSize
);
310 EachElem
<_BlkT
, typename
_BlkT::iterator
>(*it
, rFuncElem
);
315 * This variant specifies start and end positions.
317 template<typename _StoreT
, typename _BlkT
, typename _FuncElem
, typename _FuncElse
>
318 typename
_StoreT::iterator
320 const typename
_StoreT::iterator
& itPos
, _StoreT
& rStore
,
321 typename
_StoreT::size_type nStart
, typename
_StoreT::size_type nEnd
,
322 _FuncElem
& rFuncElem
, _FuncElse
& rFuncElse
)
324 typedef std::pair
<typename
_StoreT::iterator
, typename
_StoreT::size_type
> PositionType
;
326 PositionType aPos
= rStore
.position(itPos
, nStart
);
327 typename
_StoreT::iterator it
= aPos
.first
;
328 typename
_StoreT::size_type nOffset
= aPos
.second
;
329 typename
_StoreT::size_type nDataSize
= 0;
330 typename
_StoreT::size_type nTopRow
= nStart
;
332 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
334 bool bLastBlock
= false;
335 nDataSize
= it
->size
- nOffset
;
336 if (nTopRow
+ nDataSize
- 1 > nEnd
)
338 // Truncate the block.
339 nDataSize
= nEnd
- nTopRow
+ 1;
343 if (it
->type
== _BlkT::block_type
)
344 EachElem
<_BlkT
, typename
_BlkT::iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
346 rFuncElse(it
->type
, nTopRow
, nDataSize
);
355 template<typename _StoreT
, typename _Blk1
, typename _Blk2
, typename _FuncElem
, typename _FuncElse
>
356 void ProcessElements2(_StoreT
& rStore
, _FuncElem
& rFuncElem
, _FuncElse
& rFuncElse
)
358 typename
_StoreT::size_type nTopRow
= 0, nDataSize
= 0;
359 typename
_StoreT::iterator it
= rStore
.begin(), itEnd
= rStore
.end();
360 for (; it
!= itEnd
; ++it
, nTopRow
+= nDataSize
)
362 nDataSize
= it
->size
;
365 case _Blk1::block_type
:
366 EachElem
<_Blk1
, typename
_Blk1::iterator
>(*it
, rFuncElem
);
368 case _Blk2::block_type
:
369 EachElem
<_Blk2
, typename
_Blk2::iterator
>(*it
, rFuncElem
);
372 rFuncElse(it
->type
, nTopRow
, nDataSize
);
377 template<typename _StoreT
, typename _Blk1
, typename _Blk2
, typename _FuncElem
, typename _FuncElse
>
378 typename
_StoreT::iterator
380 const typename
_StoreT::iterator
& itPos
, _StoreT
& rStore
,
381 typename
_StoreT::size_type nStart
, typename
_StoreT::size_type nEnd
,
382 _FuncElem
& rFuncElem
, _FuncElse
& rFuncElse
)
384 typedef std::pair
<typename
_StoreT::iterator
, typename
_StoreT::size_type
> PositionType
;
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
;
392 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
394 bool bLastBlock
= false;
395 nDataSize
= it
->size
- nOffset
;
396 if (nTopRow
+ nDataSize
- 1 > nEnd
)
398 // Truncate the block.
399 nDataSize
= nEnd
- nTopRow
+ 1;
405 case _Blk1::block_type
:
406 EachElem
<_Blk1
, typename
_Blk1::iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
408 case _Blk2::block_type
:
409 EachElem
<_Blk2
, typename
_Blk2::iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
412 rFuncElse(it
->type
, nTopRow
, nDataSize
);
422 template<typename _StoreT
, typename _Blk1
, typename _Blk2
, typename _Blk3
, typename _FuncElem
, typename _FuncElse
>
423 void ProcessElements3(_StoreT
& rStore
, _FuncElem
& rFuncElem
, _FuncElse
& rFuncElse
)
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
)
429 nDataSize
= it
->size
;
432 case _Blk1::block_type
:
433 EachElem
<_Blk1
, typename
_Blk1::iterator
>(*it
, rFuncElem
);
435 case _Blk2::block_type
:
436 EachElem
<_Blk2
, typename
_Blk2::iterator
>(*it
, rFuncElem
);
438 case _Blk3::block_type
:
439 EachElem
<_Blk3
, typename
_Blk3::iterator
>(*it
, rFuncElem
);
442 rFuncElse(it
->type
, nTopRow
, nDataSize
);
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
)
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
)
454 nDataSize
= it
->size
;
457 case _Blk1::block_type
:
458 EachElem
<_Blk1
, typename
_Blk1::iterator
>(*it
, rFuncElem
);
460 case _Blk2::block_type
:
461 EachElem
<_Blk2
, typename
_Blk2::iterator
>(*it
, rFuncElem
);
463 case _Blk3::block_type
:
464 EachElem
<_Blk3
, typename
_Blk3::iterator
>(*it
, rFuncElem
);
466 case _Blk4::block_type
:
467 EachElem
<_Blk4
, typename
_Blk4::iterator
>(*it
, rFuncElem
);
470 rFuncElse(it
->type
, nTopRow
, nDataSize
);
475 template<typename _StoreT
, typename _Blk1
, typename _Blk2
, typename _Blk3
, typename _Blk4
, typename _FuncElem
, typename _FuncElse
>
476 typename
_StoreT::iterator
478 const typename
_StoreT::iterator
& itPos
, _StoreT
& rStore
,
479 typename
_StoreT::size_type nStart
, typename
_StoreT::size_type nEnd
,
480 _FuncElem
& rFuncElem
, _FuncElse
& rFuncElse
)
482 typedef std::pair
<typename
_StoreT::iterator
, typename
_StoreT::size_type
> PositionType
;
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
;
490 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
492 bool bLastBlock
= false;
493 nDataSize
= it
->size
- nOffset
;
494 if (nTopRow
+ nDataSize
- 1 > nEnd
)
496 // Truncate the block.
497 nDataSize
= nEnd
- nTopRow
+ 1;
503 case _Blk1::block_type
:
504 EachElem
<_Blk1
, typename
_Blk1::iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
506 case _Blk2::block_type
:
507 EachElem
<_Blk2
, typename
_Blk2::iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
509 case _Blk3::block_type
:
510 EachElem
<_Blk3
, typename
_Blk3::iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
512 case _Blk4::block_type
:
513 EachElem
<_Blk4
, typename
_Blk4::iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
516 rFuncElse(it
->type
, nTopRow
, nDataSize
);
526 template<typename _StoreT
, typename _Blk1
, typename _FuncElem
, typename _FuncElse
>
527 std::pair
<typename
_StoreT::const_iterator
, typename
_StoreT::size_type
>
529 const _StoreT
& rStore
, typename
_StoreT::size_type nStart
, typename
_StoreT::size_type nEnd
,
530 _FuncElem
& rFuncElem
, _FuncElse
& rFuncElse
)
532 typedef std::pair
<typename
_StoreT::const_iterator
, typename
_StoreT::size_type
> PositionType
;
533 typedef std::pair
<typename
_StoreT::size_type
, bool> ElseRetType
;
535 PositionType aPos
= rStore
.position(nStart
);
536 typename
_StoreT::const_iterator it
= aPos
.first
;
537 typename
_StoreT::size_type nOffset
= aPos
.second
;
538 typename
_StoreT::size_type nDataSize
= 0;
539 typename
_StoreT::size_type nTopRow
= nStart
;
541 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
543 bool bLastBlock
= false;
544 nDataSize
= it
->size
- nOffset
;
545 if (nTopRow
+ nDataSize
- 1 > nEnd
)
547 // Truncate the block.
548 nDataSize
= nEnd
- nTopRow
+ 1;
554 case _Blk1::block_type
:
556 PositionType aRet
= CheckElem
<_Blk1
>(rStore
, it
, nOffset
, nDataSize
, rFuncElem
);
557 if (aRet
.first
!= rStore
.end())
563 ElseRetType aRet
= rFuncElse(it
->type
, nTopRow
, nDataSize
);
565 return PositionType(it
, aRet
.first
);
573 return PositionType(rStore
.end(), 0);
576 template<typename _StoreT
, typename _Blk1
, typename _Blk2
, typename _FuncElem
, typename _FuncElse
>
577 std::pair
<typename
_StoreT::const_iterator
, typename
_StoreT::size_type
>
579 const _StoreT
& rStore
, typename
_StoreT::size_type nStart
, typename
_StoreT::size_type nEnd
,
580 _FuncElem
& rFuncElem
, _FuncElse
& rFuncElse
)
582 typedef std::pair
<typename
_StoreT::const_iterator
, typename
_StoreT::size_type
> PositionType
;
583 typedef std::pair
<typename
_StoreT::size_type
, bool> ElseRetType
;
585 PositionType aPos
= rStore
.position(nStart
);
586 typename
_StoreT::const_iterator it
= aPos
.first
;
587 typename
_StoreT::size_type nOffset
= aPos
.second
;
588 typename
_StoreT::size_type nDataSize
= 0;
589 typename
_StoreT::size_type nTopRow
= nStart
;
591 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
593 bool bLastBlock
= false;
594 nDataSize
= it
->size
- nOffset
;
595 if (nTopRow
+ nDataSize
- 1 > nEnd
)
597 // Truncate the block.
598 nDataSize
= nEnd
- nTopRow
+ 1;
604 case _Blk1::block_type
:
606 PositionType aRet
= CheckElem
<_Blk1
>(rStore
, it
, nOffset
, nDataSize
, rFuncElem
);
607 if (aRet
.first
!= rStore
.end())
611 case _Blk2::block_type
:
613 PositionType aRet
= CheckElem
<_Blk2
>(rStore
, it
, nOffset
, nDataSize
, rFuncElem
);
614 if (aRet
.first
!= rStore
.end())
620 ElseRetType aRet
= rFuncElse(*it
, nOffset
, nDataSize
);
622 return PositionType(it
, aRet
.first
);
630 return PositionType(rStore
.end(), 0);
637 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */