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 auto it
= BlkT::begin(*rNode
.data
);
117 auto 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 ItrT
, typename NodeT
, typename FuncElem
>
124 void EachElemReverse(NodeT
& rNode
, FuncElem
& rFuncElem
)
126 auto it
= BlkT::rbegin(*rNode
.data
);
127 auto itEnd
= BlkT::rend(*rNode
.data
);
128 size_t nRow
= rNode
.position
;
129 for (; it
!= itEnd
; ++it
, ++nRow
)
130 rFuncElem(nRow
, *it
);
133 template<typename BlkT
, typename StoreT
, typename FuncElem
>
134 std::pair
<typename
StoreT::const_iterator
, size_t>
136 const StoreT
& rStore
, const typename
StoreT::const_iterator
& it
, size_t nOffset
, size_t nDataSize
,
139 typedef std::pair
<typename
StoreT::const_iterator
, size_t> PositionType
;
141 typename
BlkT::const_iterator itData
= BlkT::begin(*it
->data
);
142 std::advance(itData
, nOffset
);
143 typename
BlkT::const_iterator itDataEnd
= itData
;
144 std::advance(itDataEnd
, nDataSize
);
145 size_t nTopRow
= it
->position
+ nOffset
;
146 size_t nRow
= nTopRow
;
147 for (; itData
!= itDataEnd
; ++itData
, ++nRow
)
149 if (rFuncElem(nRow
, *itData
))
150 return PositionType(it
, nRow
- it
->position
);
153 return PositionType(rStore
.end(), 0);
156 template<typename StoreT
, typename BlkT
, typename FuncElem
, typename FuncElse
>
157 void ParseElements1(const StoreT
& rStore
, FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
159 typename
StoreT::size_type nTopRow
= 0, nDataSize
= 0;
160 typename
StoreT::const_iterator it
= rStore
.begin(), itEnd
= rStore
.end();
161 for (; it
!= itEnd
; ++it
, nTopRow
+= nDataSize
)
163 nDataSize
= it
->size
;
164 if (it
->type
!= BlkT::block_type
)
166 rFuncElse(it
->type
, nTopRow
, nDataSize
);
170 EachElem
<BlkT
, typename
BlkT::const_iterator
>(*it
, rFuncElem
);
174 template<typename StoreT
, typename BlkT
, typename FuncElem
, typename FuncElse
>
175 typename
StoreT::const_iterator
177 const typename
StoreT::const_iterator
& itPos
, const StoreT
& rStore
,
178 typename
StoreT::size_type nStart
, typename
StoreT::size_type nEnd
,
179 FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
181 typedef std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
> PositionType
;
183 PositionType aPos
= rStore
.position(itPos
, nStart
);
184 typename
StoreT::const_iterator it
= aPos
.first
;
185 typename
StoreT::size_type nOffset
= aPos
.second
;
186 typename
StoreT::size_type nDataSize
= 0;
187 typename
StoreT::size_type nTopRow
= nStart
;
189 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
191 bool bLastBlock
= false;
192 nDataSize
= it
->size
- nOffset
;
193 if (nTopRow
+ nDataSize
- 1 > nEnd
)
195 // Truncate the block.
196 nDataSize
= nEnd
- nTopRow
+ 1;
200 if (it
->type
== BlkT::block_type
)
201 EachElem
<BlkT
, typename
BlkT::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
203 rFuncElse(it
->type
, nTopRow
, nDataSize
);
212 template<typename StoreT
, typename Blk1
, typename Blk2
, typename FuncElem
, typename FuncElse
>
213 typename
StoreT::const_iterator
215 const typename
StoreT::const_iterator
& itPos
, const StoreT
& rStore
, typename
StoreT::size_type nStart
, typename
StoreT::size_type nEnd
,
216 FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
218 typedef std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
> PositionType
;
220 PositionType aPos
= rStore
.position(itPos
, nStart
);
221 typename
StoreT::const_iterator it
= aPos
.first
;
222 typename
StoreT::size_type nOffset
= aPos
.second
;
223 typename
StoreT::size_type nDataSize
= 0;
224 typename
StoreT::size_type nTopRow
= nStart
;
226 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
228 bool bLastBlock
= false;
229 nDataSize
= it
->size
- nOffset
;
230 if (nTopRow
+ nDataSize
- 1 > nEnd
)
232 // Truncate the block.
233 nDataSize
= nEnd
- nTopRow
+ 1;
239 case Blk1::block_type
:
240 EachElem
<Blk1
, typename
Blk1::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
242 case Blk2::block_type
:
243 EachElem
<Blk2
, typename
Blk2::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
246 rFuncElse(it
->type
, nTopRow
, nDataSize
);
256 template<typename StoreT
, typename Blk1
, typename Blk2
, typename Blk3
, typename Blk4
, typename FuncElem
, typename FuncElse
>
257 typename
StoreT::const_iterator
259 const typename
StoreT::const_iterator
& itPos
, const StoreT
& rStore
, typename
StoreT::size_type nStart
, typename
StoreT::size_type nEnd
,
260 FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
262 typedef std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
> PositionType
;
264 PositionType aPos
= rStore
.position(itPos
, nStart
);
265 typename
StoreT::const_iterator it
= aPos
.first
;
266 typename
StoreT::size_type nOffset
= aPos
.second
;
267 typename
StoreT::size_type nDataSize
= 0;
268 typename
StoreT::size_type nTopRow
= nStart
;
270 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
272 bool bLastBlock
= false;
273 nDataSize
= it
->size
- nOffset
;
274 if (nTopRow
+ nDataSize
- 1 > nEnd
)
276 // Truncate the block.
277 nDataSize
= nEnd
- nTopRow
+ 1;
283 case Blk1::block_type
:
284 EachElem
<Blk1
, typename
Blk1::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
286 case Blk2::block_type
:
287 EachElem
<Blk2
, typename
Blk2::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
289 case Blk3::block_type
:
290 EachElem
<Blk3
, typename
Blk3::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
292 case Blk4::block_type
:
293 EachElem
<Blk4
, typename
Blk4::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
296 rFuncElse(it
->type
, nTopRow
, nDataSize
);
306 template<typename StoreT
, typename BlkT
, typename FuncElem
, typename FuncElse
>
307 void ProcessElements1(StoreT
& rStore
, FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
309 typename
StoreT::size_type nTopRow
= 0, nDataSize
= 0;
310 typename
StoreT::iterator it
= rStore
.begin(), itEnd
= rStore
.end();
311 for (; it
!= itEnd
; ++it
, nTopRow
+= nDataSize
)
313 nDataSize
= it
->size
;
314 if (it
->type
!= BlkT::block_type
)
316 rFuncElse(it
->type
, nTopRow
, nDataSize
);
320 EachElem
<BlkT
, typename
BlkT::iterator
>(*it
, rFuncElem
);
325 * This variant specifies start and end positions.
327 template<typename StoreT
, typename BlkT
, typename FuncElem
, typename FuncElse
>
328 typename
StoreT::iterator
330 const typename
StoreT::iterator
& itPos
, StoreT
& rStore
,
331 typename
StoreT::size_type nStart
, typename
StoreT::size_type nEnd
,
332 FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
334 typedef std::pair
<typename
StoreT::iterator
, typename
StoreT::size_type
> PositionType
;
336 PositionType aPos
= rStore
.position(itPos
, nStart
);
337 typename
StoreT::iterator it
= aPos
.first
;
338 typename
StoreT::size_type nOffset
= aPos
.second
;
339 typename
StoreT::size_type nDataSize
= 0;
340 typename
StoreT::size_type nTopRow
= nStart
;
342 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
344 bool bLastBlock
= false;
345 nDataSize
= it
->size
- nOffset
;
346 if (nTopRow
+ nDataSize
- 1 > nEnd
)
348 // Truncate the block.
349 nDataSize
= nEnd
- nTopRow
+ 1;
353 if (it
->type
== BlkT::block_type
)
354 EachElem
<BlkT
, typename
BlkT::iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
356 rFuncElse(it
->type
, nTopRow
, nDataSize
);
365 template<typename StoreT
, typename Blk1
, typename Blk2
, typename FuncElem
, typename FuncElse
>
366 void ProcessElements2(StoreT
& rStore
, FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
368 typename
StoreT::size_type nTopRow
= 0, nDataSize
= 0;
369 typename
StoreT::iterator it
= rStore
.begin(), itEnd
= rStore
.end();
370 for (; it
!= itEnd
; ++it
, nTopRow
+= nDataSize
)
372 nDataSize
= it
->size
;
375 case Blk1::block_type
:
376 EachElem
<Blk1
, typename
Blk1::iterator
>(*it
, rFuncElem
);
378 case Blk2::block_type
:
379 EachElem
<Blk2
, typename
Blk2::iterator
>(*it
, rFuncElem
);
382 rFuncElse(it
->type
, nTopRow
, nDataSize
);
387 template<typename StoreT
, typename Blk1
, typename Blk2
, typename FuncElem
, typename FuncElse
>
388 void ProcessElements2Reverse(StoreT
& rStore
, FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
390 typename
StoreT::size_type nTopRow
= 0, nDataSize
= 0;
391 typename
StoreT::iterator it
= rStore
.begin(), itEnd
= rStore
.end();
392 for (; it
!= itEnd
; ++it
, nTopRow
+= nDataSize
)
394 nDataSize
= it
->size
;
397 case Blk1::block_type
:
398 EachElemReverse
<Blk1
, typename
Blk1::iterator
>(*it
, rFuncElem
);
400 case Blk2::block_type
:
401 EachElemReverse
<Blk2
, typename
Blk2::iterator
>(*it
, rFuncElem
);
404 rFuncElse(it
->type
, nTopRow
, nDataSize
);
409 template<typename StoreT
, typename Blk1
, typename FuncElem
, typename FuncElse
>
410 std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
>
412 const StoreT
& rStore
, typename
StoreT::size_type nStart
, typename
StoreT::size_type nEnd
,
413 FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
415 typedef std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
> PositionType
;
416 typedef std::pair
<typename
StoreT::size_type
, bool> ElseRetType
;
418 PositionType aPos
= rStore
.position(nStart
);
419 typename
StoreT::const_iterator it
= aPos
.first
;
420 typename
StoreT::size_type nOffset
= aPos
.second
;
421 typename
StoreT::size_type nDataSize
= 0;
422 typename
StoreT::size_type nTopRow
= nStart
;
424 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
426 bool bLastBlock
= false;
427 nDataSize
= it
->size
- nOffset
;
428 if (nTopRow
+ nDataSize
- 1 > nEnd
)
430 // Truncate the block.
431 nDataSize
= nEnd
- nTopRow
+ 1;
437 case Blk1::block_type
:
439 PositionType aRet
= CheckElem
<Blk1
>(rStore
, it
, nOffset
, nDataSize
, rFuncElem
);
440 if (aRet
.first
!= rStore
.end())
446 ElseRetType aRet
= rFuncElse(it
->type
, nTopRow
, nDataSize
);
448 return PositionType(it
, aRet
.first
);
456 return PositionType(rStore
.end(), 0);
459 template<typename StoreT
, typename Blk1
, typename Blk2
, typename FuncElem
, typename FuncElse
>
460 std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
>
462 const StoreT
& rStore
, typename
StoreT::size_type nStart
, typename
StoreT::size_type nEnd
,
463 FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
465 typedef std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
> PositionType
;
466 typedef std::pair
<typename
StoreT::size_type
, bool> ElseRetType
;
468 PositionType aPos
= rStore
.position(nStart
);
469 typename
StoreT::const_iterator it
= aPos
.first
;
470 typename
StoreT::size_type nOffset
= aPos
.second
;
471 typename
StoreT::size_type nDataSize
= 0;
472 typename
StoreT::size_type nTopRow
= nStart
;
474 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
476 bool bLastBlock
= false;
477 nDataSize
= it
->size
- nOffset
;
478 if (nTopRow
+ nDataSize
- 1 > nEnd
)
480 // Truncate the block.
481 nDataSize
= nEnd
- nTopRow
+ 1;
487 case Blk1::block_type
:
489 PositionType aRet
= CheckElem
<Blk1
>(rStore
, it
, nOffset
, nDataSize
, rFuncElem
);
490 if (aRet
.first
!= rStore
.end())
494 case Blk2::block_type
:
496 PositionType aRet
= CheckElem
<Blk2
>(rStore
, it
, nOffset
, nDataSize
, rFuncElem
);
497 if (aRet
.first
!= rStore
.end())
503 ElseRetType aRet
= rFuncElse(*it
, nOffset
, nDataSize
);
505 return PositionType(it
, aRet
.first
);
513 return PositionType(rStore
.end(), 0);
520 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */