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
,
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 FuncElem
, typename FuncElse
>
378 std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
>
380 const StoreT
& rStore
, typename
StoreT::size_type nStart
, typename
StoreT::size_type nEnd
,
381 FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
383 typedef std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
> PositionType
;
384 typedef std::pair
<typename
StoreT::size_type
, bool> ElseRetType
;
386 PositionType aPos
= rStore
.position(nStart
);
387 typename
StoreT::const_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
:
407 PositionType aRet
= CheckElem
<Blk1
>(rStore
, it
, nOffset
, nDataSize
, rFuncElem
);
408 if (aRet
.first
!= rStore
.end())
414 ElseRetType aRet
= rFuncElse(it
->type
, nTopRow
, nDataSize
);
416 return PositionType(it
, aRet
.first
);
424 return PositionType(rStore
.end(), 0);
427 template<typename StoreT
, typename Blk1
, typename Blk2
, typename FuncElem
, typename FuncElse
>
428 std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
>
430 const StoreT
& rStore
, typename
StoreT::size_type nStart
, typename
StoreT::size_type nEnd
,
431 FuncElem
& rFuncElem
, FuncElse
& rFuncElse
)
433 typedef std::pair
<typename
StoreT::const_iterator
, typename
StoreT::size_type
> PositionType
;
434 typedef std::pair
<typename
StoreT::size_type
, bool> ElseRetType
;
436 PositionType aPos
= rStore
.position(nStart
);
437 typename
StoreT::const_iterator it
= aPos
.first
;
438 typename
StoreT::size_type nOffset
= aPos
.second
;
439 typename
StoreT::size_type nDataSize
= 0;
440 typename
StoreT::size_type nTopRow
= nStart
;
442 for (; it
!= rStore
.end() && nTopRow
<= nEnd
; ++it
, nOffset
= 0, nTopRow
+= nDataSize
)
444 bool bLastBlock
= false;
445 nDataSize
= it
->size
- nOffset
;
446 if (nTopRow
+ nDataSize
- 1 > nEnd
)
448 // Truncate the block.
449 nDataSize
= nEnd
- nTopRow
+ 1;
455 case Blk1::block_type
:
457 PositionType aRet
= CheckElem
<Blk1
>(rStore
, it
, nOffset
, nDataSize
, rFuncElem
);
458 if (aRet
.first
!= rStore
.end())
462 case Blk2::block_type
:
464 PositionType aRet
= CheckElem
<Blk2
>(rStore
, it
, nOffset
, nDataSize
, rFuncElem
);
465 if (aRet
.first
!= rStore
.end())
471 ElseRetType aRet
= rFuncElse(*it
, nOffset
, nDataSize
);
473 return PositionType(it
, aRet
.first
);
481 return PositionType(rStore
.end(), 0);
488 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */