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/.
13 #include <mdds/multi_type_vector_types.hpp>
17 template<typename SizeT
, typename Ret
= bool>
20 Ret
operator() (mdds::mtv::element_t
, SizeT
, SizeT
) const
27 * Generic algorithm to parse blocks of multi_type_vector either partially
30 template<typename StoreT
, typename Func
>
31 typename
StoreT::const_iterator
33 const typename
StoreT::const_iterator
& itPos
, const StoreT
& rStore
, Func
& rFunc
,
34 typename
StoreT::size_type nStart
, typename
StoreT::size_type nEnd
)
36 typedef std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
> PositionType
;
38 PositionType aPos
= rStore
.position(itPos
, nStart
);
39 typename
StoreT::const_iterator it
= aPos
.first
;
40 typename
StoreT::size_type nOffset
= aPos
.second
;
41 typename
StoreT::size_type nDataSize
= 0;
42 typename
StoreT::size_type nTopRow
= nStart
;
44 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
46 bool bLastBlock
= false;
47 nDataSize
= it
->size
- nOffset
;
48 if (nTopRow
+ nDataSize
- 1 > nEnd
)
50 // Truncate the block.
51 nDataSize
= nEnd
- nTopRow
+ 1;
55 rFunc(*it
, nOffset
, nDataSize
);
65 * Non-const variant of the above function. TODO: Find a way to merge these
66 * two in an elegant way.
68 template<typename StoreT
, typename Func
>
69 typename
StoreT::iterator
70 ProcessBlock(const typename
StoreT::iterator
& itPos
, StoreT
& rStore
, Func
& rFunc
, typename
StoreT::size_type nStart
, typename
StoreT::size_type nEnd
)
72 typedef std::pair
<typename
StoreT::iterator
, typename
StoreT::size_type
> PositionType
;
74 PositionType aPos
= rStore
.position(itPos
, nStart
);
75 typename
StoreT::iterator it
= aPos
.first
;
76 typename
StoreT::size_type nOffset
= aPos
.second
;
77 typename
StoreT::size_type nDataSize
= 0;
78 typename
StoreT::size_type nCurRow
= nStart
;
80 for (; it
!= rStore
.end() && nCurRow
<= nEnd
; ++it
, nOffset
= 0, nCurRow
+= nDataSize
)
82 bool bLastBlock
= false;
83 nDataSize
= it
->size
- nOffset
;
84 if (nCurRow
+ nDataSize
- 1 > nEnd
)
86 // Truncate the block.
87 nDataSize
= nEnd
- nCurRow
+ 1;
91 rFunc(*it
, nOffset
, nDataSize
);
100 template<typename BlkT
, typename ItrT
, typename NodeT
, typename FuncElem
>
101 void EachElem(NodeT
& rNode
, size_t nOffset
, size_t nDataSize
, FuncElem
& rFuncElem
)
103 ItrT it
= BlkT::begin(*rNode
.data
);
104 std::advance(it
, nOffset
);
106 std::advance(itEnd
, nDataSize
);
107 size_t nRow
= rNode
.position
+ nOffset
;
108 for (; it
!= itEnd
; ++it
, ++nRow
)
109 rFuncElem(nRow
, *it
);
112 template<typename BlkT
, typename ItrT
, typename NodeT
, typename FuncElem
>
113 void EachElem(NodeT
& rNode
, FuncElem
& rFuncElem
)
115 auto it
= BlkT::begin(*rNode
.data
);
116 auto itEnd
= BlkT::end(*rNode
.data
);
117 size_t nRow
= rNode
.position
;
118 for (; it
!= itEnd
; ++it
, ++nRow
)
119 rFuncElem(nRow
, *it
);
122 template<typename BlkT
, typename ItrT
, typename NodeT
, typename FuncElem
>
123 void EachElemReverse(NodeT
& rNode
, FuncElem
& rFuncElem
)
125 auto it
= BlkT::rbegin(*rNode
.data
);
126 auto itEnd
= BlkT::rend(*rNode
.data
);
127 size_t nRow
= rNode
.position
;
128 for (; it
!= itEnd
; ++it
, ++nRow
)
129 rFuncElem(nRow
, *it
);
132 template<typename BlkT
, typename StoreT
, typename FuncElem
>
133 std::pair
<typename
StoreT::const_iterator
, size_t>
135 const StoreT
& rStore
, const typename
StoreT::const_iterator
& it
, size_t nOffset
, size_t nDataSize
,
138 typedef std::pair
<typename
StoreT::const_iterator
, size_t> PositionType
;
140 typename
BlkT::const_iterator itData
= BlkT::begin(*it
->data
);
141 std::advance(itData
, nOffset
);
142 typename
BlkT::const_iterator itDataEnd
= itData
;
143 std::advance(itDataEnd
, nDataSize
);
144 size_t nTopRow
= it
->position
+ nOffset
;
145 size_t nRow
= nTopRow
;
146 for (; itData
!= itDataEnd
; ++itData
, ++nRow
)
148 if (rFuncElem(nRow
, *itData
))
149 return PositionType(it
, nRow
- it
->position
);
152 return PositionType(rStore
.end(), 0);
155 template<typename StoreT
, typename BlkT
, typename FuncElem
, typename FuncElse
>
156 void ParseElements1(const StoreT
& rStore
, FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
158 typename
StoreT::size_type nTopRow
= 0, nDataSize
= 0;
159 typename
StoreT::const_iterator it
= rStore
.begin(), itEnd
= rStore
.end();
160 for (; it
!= itEnd
; ++it
, nTopRow
+= nDataSize
)
162 nDataSize
= it
->size
;
163 if (it
->type
!= BlkT::block_type
)
165 rFuncElse(it
->type
, nTopRow
, nDataSize
);
169 EachElem
<BlkT
, typename
BlkT::const_iterator
>(*it
, rFuncElem
);
173 template<typename StoreT
, typename BlkT
, typename FuncElem
, typename FuncElse
>
174 typename
StoreT::const_iterator
176 const typename
StoreT::const_iterator
& itPos
, const StoreT
& rStore
,
177 typename
StoreT::size_type nStart
, typename
StoreT::size_type nEnd
,
178 FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
180 typedef std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
> PositionType
;
182 PositionType aPos
= rStore
.position(itPos
, nStart
);
183 typename
StoreT::const_iterator it
= aPos
.first
;
184 typename
StoreT::size_type nOffset
= aPos
.second
;
185 typename
StoreT::size_type nDataSize
= 0;
186 typename
StoreT::size_type nTopRow
= nStart
;
188 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
190 bool bLastBlock
= false;
191 nDataSize
= it
->size
- nOffset
;
192 if (nTopRow
+ nDataSize
- 1 > nEnd
)
194 // Truncate the block.
195 nDataSize
= nEnd
- nTopRow
+ 1;
199 if (it
->type
== BlkT::block_type
)
200 EachElem
<BlkT
, typename
BlkT::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
202 rFuncElse(it
->type
, nTopRow
, nDataSize
);
211 template<typename StoreT
, typename Blk1
, typename Blk2
, typename FuncElem
, typename FuncElse
>
212 typename
StoreT::const_iterator
214 const typename
StoreT::const_iterator
& itPos
, const StoreT
& rStore
, typename
StoreT::size_type nStart
, typename
StoreT::size_type nEnd
,
215 FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
217 typedef std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
> PositionType
;
219 PositionType aPos
= rStore
.position(itPos
, nStart
);
220 typename
StoreT::const_iterator it
= aPos
.first
;
221 typename
StoreT::size_type nOffset
= aPos
.second
;
222 typename
StoreT::size_type nDataSize
= 0;
223 typename
StoreT::size_type nTopRow
= nStart
;
225 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
227 bool bLastBlock
= false;
228 nDataSize
= it
->size
- nOffset
;
229 if (nTopRow
+ nDataSize
- 1 > nEnd
)
231 // Truncate the block.
232 nDataSize
= nEnd
- nTopRow
+ 1;
238 case Blk1::block_type
:
239 EachElem
<Blk1
, typename
Blk1::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
241 case Blk2::block_type
:
242 EachElem
<Blk2
, typename
Blk2::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
245 rFuncElse(it
->type
, nTopRow
, nDataSize
);
255 template<typename StoreT
, typename Blk1
, typename Blk2
, typename Blk3
, typename Blk4
, typename FuncElem
, typename FuncElse
>
256 typename
StoreT::const_iterator
258 const typename
StoreT::const_iterator
& itPos
, const StoreT
& rStore
, typename
StoreT::size_type nStart
, typename
StoreT::size_type nEnd
,
259 FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
261 typedef std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
> PositionType
;
263 PositionType aPos
= rStore
.position(itPos
, nStart
);
264 typename
StoreT::const_iterator it
= aPos
.first
;
265 typename
StoreT::size_type nOffset
= aPos
.second
;
266 typename
StoreT::size_type nDataSize
= 0;
267 typename
StoreT::size_type nTopRow
= nStart
;
269 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
271 bool bLastBlock
= false;
272 nDataSize
= it
->size
- nOffset
;
273 if (nTopRow
+ nDataSize
- 1 > nEnd
)
275 // Truncate the block.
276 nDataSize
= nEnd
- nTopRow
+ 1;
282 case Blk1::block_type
:
283 EachElem
<Blk1
, typename
Blk1::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
285 case Blk2::block_type
:
286 EachElem
<Blk2
, typename
Blk2::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
288 case Blk3::block_type
:
289 EachElem
<Blk3
, typename
Blk3::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
291 case Blk4::block_type
:
292 EachElem
<Blk4
, typename
Blk4::const_iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
295 rFuncElse(it
->type
, nTopRow
, nDataSize
);
305 template<typename StoreT
, typename BlkT
, typename FuncElem
, typename FuncElse
>
306 void ProcessElements1(StoreT
& rStore
, FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
308 typename
StoreT::size_type nTopRow
= 0, nDataSize
= 0;
309 typename
StoreT::iterator it
= rStore
.begin(), itEnd
= rStore
.end();
310 for (; it
!= itEnd
; ++it
, nTopRow
+= nDataSize
)
312 nDataSize
= it
->size
;
313 if (it
->type
!= BlkT::block_type
)
315 rFuncElse(it
->type
, nTopRow
, nDataSize
);
319 EachElem
<BlkT
, typename
BlkT::iterator
>(*it
, rFuncElem
);
324 * This variant specifies start and end positions.
326 template<typename StoreT
, typename BlkT
, typename FuncElem
, typename FuncElse
>
327 typename
StoreT::iterator
329 const typename
StoreT::iterator
& itPos
, StoreT
& rStore
,
330 typename
StoreT::size_type nStart
, typename
StoreT::size_type nEnd
,
331 FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
333 typedef std::pair
<typename
StoreT::iterator
, typename
StoreT::size_type
> PositionType
;
335 PositionType aPos
= rStore
.position(itPos
, nStart
);
336 typename
StoreT::iterator it
= aPos
.first
;
337 typename
StoreT::size_type nOffset
= aPos
.second
;
338 typename
StoreT::size_type nDataSize
= 0;
339 typename
StoreT::size_type nTopRow
= nStart
;
341 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
343 bool bLastBlock
= false;
344 nDataSize
= it
->size
- nOffset
;
345 if (nTopRow
+ nDataSize
- 1 > nEnd
)
347 // Truncate the block.
348 nDataSize
= nEnd
- nTopRow
+ 1;
352 if (it
->type
== BlkT::block_type
)
353 EachElem
<BlkT
, typename
BlkT::iterator
>(*it
, nOffset
, nDataSize
, rFuncElem
);
355 rFuncElse(it
->type
, nTopRow
, nDataSize
);
364 template<typename StoreT
, typename Blk1
, typename Blk2
, typename FuncElem
, typename FuncElse
>
365 void ProcessElements2(StoreT
& rStore
, FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
367 typename
StoreT::size_type nTopRow
= 0, nDataSize
= 0;
368 typename
StoreT::iterator it
= rStore
.begin(), itEnd
= rStore
.end();
369 for (; it
!= itEnd
; ++it
, nTopRow
+= nDataSize
)
371 nDataSize
= it
->size
;
374 case Blk1::block_type
:
375 EachElem
<Blk1
, typename
Blk1::iterator
>(*it
, rFuncElem
);
377 case Blk2::block_type
:
378 EachElem
<Blk2
, typename
Blk2::iterator
>(*it
, rFuncElem
);
381 rFuncElse(it
->type
, nTopRow
, nDataSize
);
386 template<typename StoreT
, typename Blk1
, typename Blk2
, typename FuncElem
, typename FuncElse
>
387 void ProcessElements2Reverse(StoreT
& rStore
, FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
389 typename
StoreT::size_type nTopRow
= 0, nDataSize
= 0;
390 typename
StoreT::iterator it
= rStore
.begin(), itEnd
= rStore
.end();
391 for (; it
!= itEnd
; ++it
, nTopRow
+= nDataSize
)
393 nDataSize
= it
->size
;
396 case Blk1::block_type
:
397 EachElemReverse
<Blk1
, typename
Blk1::iterator
>(*it
, rFuncElem
);
399 case Blk2::block_type
:
400 EachElemReverse
<Blk2
, typename
Blk2::iterator
>(*it
, rFuncElem
);
403 rFuncElse(it
->type
, nTopRow
, nDataSize
);
408 template<typename StoreT
, typename Blk1
, typename FuncElem
, typename FuncElse
>
409 std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
>
411 const StoreT
& rStore
, typename
StoreT::size_type nStart
, typename
StoreT::size_type nEnd
,
412 FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
414 typedef std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
> PositionType
;
415 typedef std::pair
<typename
StoreT::size_type
, bool> ElseRetType
;
417 PositionType aPos
= rStore
.position(nStart
);
418 typename
StoreT::const_iterator it
= aPos
.first
;
419 typename
StoreT::size_type nOffset
= aPos
.second
;
420 typename
StoreT::size_type nDataSize
= 0;
421 typename
StoreT::size_type nTopRow
= nStart
;
423 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
425 bool bLastBlock
= false;
426 nDataSize
= it
->size
- nOffset
;
427 if (nTopRow
+ nDataSize
- 1 > nEnd
)
429 // Truncate the block.
430 nDataSize
= nEnd
- nTopRow
+ 1;
436 case Blk1::block_type
:
438 PositionType aRet
= CheckElem
<Blk1
>(rStore
, it
, nOffset
, nDataSize
, rFuncElem
);
439 if (aRet
.first
!= rStore
.end())
445 ElseRetType aRet
= rFuncElse(it
->type
, nTopRow
, nDataSize
);
447 return PositionType(it
, aRet
.first
);
455 return PositionType(rStore
.end(), 0);
458 template<typename StoreT
, typename Blk1
, typename Blk2
, typename FuncElem
, typename FuncElse
>
459 std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
>
461 const StoreT
& rStore
, typename
StoreT::size_type nStart
, typename
StoreT::size_type nEnd
,
462 FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
464 typedef std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
> PositionType
;
465 typedef std::pair
<typename
StoreT::size_type
, bool> ElseRetType
;
467 PositionType aPos
= rStore
.position(nStart
);
468 typename
StoreT::const_iterator it
= aPos
.first
;
469 typename
StoreT::size_type nOffset
= aPos
.second
;
470 typename
StoreT::size_type nDataSize
= 0;
471 typename
StoreT::size_type nTopRow
= nStart
;
473 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
475 bool bLastBlock
= false;
476 nDataSize
= it
->size
- nOffset
;
477 if (nTopRow
+ nDataSize
- 1 > nEnd
)
479 // Truncate the block.
480 nDataSize
= nEnd
- nTopRow
+ 1;
486 case Blk1::block_type
:
488 PositionType aRet
= CheckElem
<Blk1
>(rStore
, it
, nOffset
, nDataSize
, rFuncElem
);
489 if (aRet
.first
!= rStore
.end())
493 case Blk2::block_type
:
495 PositionType aRet
= CheckElem
<Blk2
>(rStore
, it
, nOffset
, nDataSize
, rFuncElem
);
496 if (aRet
.first
!= rStore
.end())
502 ElseRetType aRet
= rFuncElse(*it
, nOffset
, nDataSize
);
504 return PositionType(it
, aRet
.first
);
512 return PositionType(rStore
.end(), 0);
517 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */