update emoji autocorrect entries from po-files
[LibreOffice.git] / sc / inc / mtvfunctions.hxx
blob2f701de0efa4bb4dbbc3088233123053d70da497
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #ifndef INCLUDED_SC_INC_MTVFUNCTIONS_HXX
11 #define INCLUDED_SC_INC_MTVFUNCTIONS_HXX
13 #include <cstdlib>
14 #include <mdds/multi_type_vector_types.hpp>
16 namespace sc {
18 template<typename _SizeT, typename _Ret = bool>
19 struct FuncElseNoOp
21 _Ret operator() (mdds::mtv::element_t, _SizeT, _SizeT) const
23 return _Ret();
27 /**
28 * Generic algorithm to parse blocks of multi_type_vector either partially
29 * or fully.
31 template<typename _StoreT, typename _Func>
32 typename _StoreT::const_iterator
33 ParseBlock(
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;
53 bLastBlock = true;
56 rFunc(*it, nOffset, nDataSize);
58 if (bLastBlock)
59 break;
62 return it;
65 /**
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;
89 bLastBlock = true;
92 rFunc(*it, nOffset, nDataSize);
94 if (bLastBlock)
95 break;
98 return it;
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);
106 _ItrT itEnd = it;
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>
125 CheckElem(
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);
157 continue;
160 EachElem<_BlkT, typename _BlkT::const_iterator>(*it, rFuncElem);
164 template<typename _StoreT, typename _BlkT, typename _FuncElem, typename _FuncElse>
165 typename _StoreT::const_iterator
166 ParseElements1(
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;
187 bLastBlock = true;
190 if (it->type == _BlkT::block_type)
191 EachElem<_BlkT, typename _BlkT::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
192 else
193 rFuncElse(it->type, nTopRow, nDataSize);
195 if (bLastBlock)
196 break;
199 return it;
202 template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
203 typename _StoreT::const_iterator
204 ParseElements2(
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;
224 bLastBlock = true;
227 switch (it->type)
229 case _Blk1::block_type:
230 EachElem<_Blk1, typename _Blk1::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
231 break;
232 case _Blk2::block_type:
233 EachElem<_Blk2, typename _Blk2::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
234 break;
235 default:
236 rFuncElse(it->type, nTopRow, nDataSize);
239 if (bLastBlock)
240 break;
243 return it;
246 template<typename _StoreT, typename _Blk1, typename _Blk2, typename _Blk3, typename _Blk4, typename _FuncElem, typename _FuncElse>
247 typename _StoreT::const_iterator
248 ParseElements4(
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;
268 bLastBlock = true;
271 switch (it->type)
273 case _Blk1::block_type:
274 EachElem<_Blk1, typename _Blk1::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
275 break;
276 case _Blk2::block_type:
277 EachElem<_Blk2, typename _Blk2::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
278 break;
279 case _Blk3::block_type:
280 EachElem<_Blk3, typename _Blk3::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
281 break;
282 case _Blk4::block_type:
283 EachElem<_Blk4, typename _Blk4::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
284 break;
285 default:
286 rFuncElse(it->type, nTopRow, nDataSize);
289 if (bLastBlock)
290 break;
293 return it;
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);
307 continue;
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
319 ProcessElements1(
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;
340 bLastBlock = true;
343 if (it->type == _BlkT::block_type)
344 EachElem<_BlkT, typename _BlkT::iterator>(*it, nOffset, nDataSize, rFuncElem);
345 else
346 rFuncElse(it->type, nTopRow, nDataSize);
348 if (bLastBlock)
349 break;
352 return it;
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;
363 switch (it->type)
365 case _Blk1::block_type:
366 EachElem<_Blk1, typename _Blk1::iterator>(*it, rFuncElem);
367 break;
368 case _Blk2::block_type:
369 EachElem<_Blk2, typename _Blk2::iterator>(*it, rFuncElem);
370 break;
371 default:
372 rFuncElse(it->type, nTopRow, nDataSize);
377 template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
378 typename _StoreT::iterator
379 ProcessElements2(
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;
400 bLastBlock = true;
403 switch (it->type)
405 case _Blk1::block_type:
406 EachElem<_Blk1, typename _Blk1::iterator>(*it, nOffset, nDataSize, rFuncElem);
407 break;
408 case _Blk2::block_type:
409 EachElem<_Blk2, typename _Blk2::iterator>(*it, nOffset, nDataSize, rFuncElem);
410 break;
411 default:
412 rFuncElse(it->type, nTopRow, nDataSize);
415 if (bLastBlock)
416 break;
419 return it;
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;
430 switch (it->type)
432 case _Blk1::block_type:
433 EachElem<_Blk1, typename _Blk1::iterator>(*it, rFuncElem);
434 break;
435 case _Blk2::block_type:
436 EachElem<_Blk2, typename _Blk2::iterator>(*it, rFuncElem);
437 break;
438 case _Blk3::block_type:
439 EachElem<_Blk3, typename _Blk3::iterator>(*it, rFuncElem);
440 break;
441 default:
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;
455 switch (it->type)
457 case _Blk1::block_type:
458 EachElem<_Blk1, typename _Blk1::iterator>(*it, rFuncElem);
459 break;
460 case _Blk2::block_type:
461 EachElem<_Blk2, typename _Blk2::iterator>(*it, rFuncElem);
462 break;
463 case _Blk3::block_type:
464 EachElem<_Blk3, typename _Blk3::iterator>(*it, rFuncElem);
465 break;
466 case _Blk4::block_type:
467 EachElem<_Blk4, typename _Blk4::iterator>(*it, rFuncElem);
468 break;
469 default:
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
477 ProcessElements4(
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;
498 bLastBlock = true;
501 switch (it->type)
503 case _Blk1::block_type:
504 EachElem<_Blk1, typename _Blk1::iterator>(*it, nOffset, nDataSize, rFuncElem);
505 break;
506 case _Blk2::block_type:
507 EachElem<_Blk2, typename _Blk2::iterator>(*it, nOffset, nDataSize, rFuncElem);
508 break;
509 case _Blk3::block_type:
510 EachElem<_Blk3, typename _Blk3::iterator>(*it, nOffset, nDataSize, rFuncElem);
511 break;
512 case _Blk4::block_type:
513 EachElem<_Blk4, typename _Blk4::iterator>(*it, nOffset, nDataSize, rFuncElem);
514 break;
515 default:
516 rFuncElse(it->type, nTopRow, nDataSize);
519 if (bLastBlock)
520 break;
523 return it;
526 template<typename _StoreT, typename _Blk1, typename _FuncElem, typename _FuncElse>
527 std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type>
528 FindElement1(
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;
549 bLastBlock = true;
552 switch (it->type)
554 case _Blk1::block_type:
556 PositionType aRet = CheckElem<_Blk1>(rStore, it, nOffset, nDataSize, rFuncElem);
557 if (aRet.first != rStore.end())
558 return aRet;
560 break;
561 default:
563 ElseRetType aRet = rFuncElse(it->type, nTopRow, nDataSize);
564 if (aRet.second)
565 return PositionType(it, aRet.first);
569 if (bLastBlock)
570 break;
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>
578 FindElement2(
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;
599 bLastBlock = true;
602 switch (it->type)
604 case _Blk1::block_type:
606 PositionType aRet = CheckElem<_Blk1>(rStore, it, nOffset, nDataSize, rFuncElem);
607 if (aRet.first != rStore.end())
608 return aRet;
610 break;
611 case _Blk2::block_type:
613 PositionType aRet = CheckElem<_Blk2>(rStore, it, nOffset, nDataSize, rFuncElem);
614 if (aRet.first != rStore.end())
615 return aRet;
617 break;
618 default:
620 ElseRetType aRet = rFuncElse(*it, nOffset, nDataSize);
621 if (aRet.second)
622 return PositionType(it, aRet.first);
626 if (bLastBlock)
627 break;
630 return PositionType(rStore.end(), 0);
635 #endif
637 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */