LibreOffice Module sc (master)  1
mtvfunctions.hxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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  */
9 
10 #ifndef INCLUDED_SC_INC_MTVFUNCTIONS_HXX
11 #define INCLUDED_SC_INC_MTVFUNCTIONS_HXX
12 
13 #include <cstdlib>
14 #include <mdds/multi_type_vector_types.hpp>
15 
16 namespace sc {
17 
18 template<typename SizeT, typename Ret = bool>
20 {
21  Ret operator() (mdds::mtv::element_t, SizeT, SizeT) const
22  {
23  return Ret();
24  }
25 };
26 
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)
36 {
37  typedef std::pair<typename StoreT::const_iterator, typename StoreT::size_type> PositionType;
38 
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;
44 
45  for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
46  {
47  bool bLastBlock = false;
48  nDataSize = it->size - nOffset;
49  if (nTopRow + nDataSize - 1 > nEnd)
50  {
51  // Truncate the block.
52  nDataSize = nEnd - nTopRow + 1;
53  bLastBlock = true;
54  }
55 
56  rFunc(*it, nOffset, nDataSize);
57 
58  if (bLastBlock)
59  break;
60  }
61 
62  return it;
63 }
64 
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)
72 {
73  typedef std::pair<typename StoreT::iterator, typename StoreT::size_type> PositionType;
74 
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;
80 
81  for (; it != rStore.end() && nCurRow <= nEnd; ++it, nOffset = 0, nCurRow += nDataSize)
82  {
83  bool bLastBlock = false;
84  nDataSize = it->size - nOffset;
85  if (nCurRow + nDataSize - 1 > nEnd)
86  {
87  // Truncate the block.
88  nDataSize = nEnd - nCurRow + 1;
89  bLastBlock = true;
90  }
91 
92  rFunc(*it, nOffset, nDataSize);
93 
94  if (bLastBlock)
95  break;
96  }
97 
98  return it;
99 }
100 
101 template<typename BlkT, typename ItrT, typename NodeT, typename FuncElem>
102 void EachElem(NodeT& rNode, size_t nOffset, size_t nDataSize, FuncElem& rFuncElem)
103 {
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);
111 }
112 
113 template<typename BlkT, typename ItrT, typename NodeT, typename FuncElem>
114 void EachElem(NodeT& rNode, FuncElem& rFuncElem)
115 {
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);
121 }
122 
123 template<typename BlkT, typename ItrT, typename NodeT, typename FuncElem>
124 void EachElemReverse(NodeT& rNode, FuncElem& rFuncElem)
125 {
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);
131 }
132 
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,
137  FuncElem& rFuncElem)
138 {
139  typedef std::pair<typename StoreT::const_iterator, size_t> PositionType;
140 
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)
148  {
149  if (rFuncElem(nRow, *itData))
150  return PositionType(it, nRow - it->position);
151  }
152 
153  return PositionType(rStore.end(), 0);
154 }
155 
156 template<typename StoreT, typename BlkT, typename FuncElem, typename FuncElse>
157 void ParseElements1(const StoreT& rStore, FuncElem& rFuncElem, FuncElse& rFuncElse)
158 {
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)
162  {
163  nDataSize = it->size;
164  if (it->type != BlkT::block_type)
165  {
166  rFuncElse(it->type, nTopRow, nDataSize);
167  continue;
168  }
169 
170  EachElem<BlkT, typename BlkT::const_iterator>(*it, rFuncElem);
171  }
172 }
173 
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)
180 {
181  typedef std::pair<typename StoreT::const_iterator, typename StoreT::size_type> PositionType;
182 
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;
188 
189  for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
190  {
191  bool bLastBlock = false;
192  nDataSize = it->size - nOffset;
193  if (nTopRow + nDataSize - 1 > nEnd)
194  {
195  // Truncate the block.
196  nDataSize = nEnd - nTopRow + 1;
197  bLastBlock = true;
198  }
199 
200  if (it->type == BlkT::block_type)
201  EachElem<BlkT, typename BlkT::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
202  else
203  rFuncElse(it->type, nTopRow, nDataSize);
204 
205  if (bLastBlock)
206  break;
207  }
208 
209  return it;
210 };
211 
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)
217 {
218  typedef std::pair<typename StoreT::const_iterator, typename StoreT::size_type> PositionType;
219 
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;
225 
226  for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
227  {
228  bool bLastBlock = false;
229  nDataSize = it->size - nOffset;
230  if (nTopRow + nDataSize - 1 > nEnd)
231  {
232  // Truncate the block.
233  nDataSize = nEnd - nTopRow + 1;
234  bLastBlock = true;
235  }
236 
237  switch (it->type)
238  {
239  case Blk1::block_type:
240  EachElem<Blk1, typename Blk1::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
241  break;
242  case Blk2::block_type:
243  EachElem<Blk2, typename Blk2::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
244  break;
245  default:
246  rFuncElse(it->type, nTopRow, nDataSize);
247  }
248 
249  if (bLastBlock)
250  break;
251  }
252 
253  return it;
254 }
255 
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)
261 {
262  typedef std::pair<typename StoreT::const_iterator, typename StoreT::size_type> PositionType;
263 
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;
269 
270  for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
271  {
272  bool bLastBlock = false;
273  nDataSize = it->size - nOffset;
274  if (nTopRow + nDataSize - 1 > nEnd)
275  {
276  // Truncate the block.
277  nDataSize = nEnd - nTopRow + 1;
278  bLastBlock = true;
279  }
280 
281  switch (it->type)
282  {
283  case Blk1::block_type:
284  EachElem<Blk1, typename Blk1::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
285  break;
286  case Blk2::block_type:
287  EachElem<Blk2, typename Blk2::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
288  break;
289  case Blk3::block_type:
290  EachElem<Blk3, typename Blk3::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
291  break;
292  case Blk4::block_type:
293  EachElem<Blk4, typename Blk4::const_iterator>(*it, nOffset, nDataSize, rFuncElem);
294  break;
295  default:
296  rFuncElse(it->type, nTopRow, nDataSize);
297  }
298 
299  if (bLastBlock)
300  break;
301  }
302 
303  return it;
304 }
305 
306 template<typename StoreT, typename BlkT, typename FuncElem, typename FuncElse>
307 void ProcessElements1(StoreT& rStore, FuncElem& rFuncElem, FuncElse& rFuncElse)
308 {
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)
312  {
313  nDataSize = it->size;
314  if (it->type != BlkT::block_type)
315  {
316  rFuncElse(it->type, nTopRow, nDataSize);
317  continue;
318  }
319 
320  EachElem<BlkT, typename BlkT::iterator>(*it, rFuncElem);
321  }
322 }
323 
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)
333 {
334  typedef std::pair<typename StoreT::iterator, typename StoreT::size_type> PositionType;
335 
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;
341 
342  for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
343  {
344  bool bLastBlock = false;
345  nDataSize = it->size - nOffset;
346  if (nTopRow + nDataSize - 1 > nEnd)
347  {
348  // Truncate the block.
349  nDataSize = nEnd - nTopRow + 1;
350  bLastBlock = true;
351  }
352 
353  if (it->type == BlkT::block_type)
354  EachElem<BlkT, typename BlkT::iterator>(*it, nOffset, nDataSize, rFuncElem);
355  else
356  rFuncElse(it->type, nTopRow, nDataSize);
357 
358  if (bLastBlock)
359  break;
360  }
361 
362  return it;
363 };
364 
365 template<typename StoreT, typename Blk1, typename Blk2, typename FuncElem, typename FuncElse>
366 void ProcessElements2(StoreT& rStore, FuncElem& rFuncElem, FuncElse& rFuncElse)
367 {
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)
371  {
372  nDataSize = it->size;
373  switch (it->type)
374  {
375  case Blk1::block_type:
376  EachElem<Blk1, typename Blk1::iterator>(*it, rFuncElem);
377  break;
378  case Blk2::block_type:
379  EachElem<Blk2, typename Blk2::iterator>(*it, rFuncElem);
380  break;
381  default:
382  rFuncElse(it->type, nTopRow, nDataSize);
383  }
384  }
385 }
386 
387 template<typename StoreT, typename Blk1, typename Blk2, typename FuncElem, typename FuncElse>
388 void ProcessElements2Reverse(StoreT& rStore, FuncElem& rFuncElem, FuncElse& rFuncElse)
389 {
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)
393  {
394  nDataSize = it->size;
395  switch (it->type)
396  {
397  case Blk1::block_type:
398  EachElemReverse<Blk1, typename Blk1::iterator>(*it, rFuncElem);
399  break;
400  case Blk2::block_type:
401  EachElemReverse<Blk2, typename Blk2::iterator>(*it, rFuncElem);
402  break;
403  default:
404  rFuncElse(it->type, nTopRow, nDataSize);
405  }
406  }
407 }
408 
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)
414 {
415  typedef std::pair<typename StoreT::const_iterator, typename StoreT::size_type> PositionType;
416  typedef std::pair<typename StoreT::size_type, bool> ElseRetType;
417 
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;
423 
424  for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
425  {
426  bool bLastBlock = false;
427  nDataSize = it->size - nOffset;
428  if (nTopRow + nDataSize - 1 > nEnd)
429  {
430  // Truncate the block.
431  nDataSize = nEnd - nTopRow + 1;
432  bLastBlock = true;
433  }
434 
435  switch (it->type)
436  {
437  case Blk1::block_type:
438  {
439  PositionType aRet = CheckElem<Blk1>(rStore, it, nOffset, nDataSize, rFuncElem);
440  if (aRet.first != rStore.end())
441  return aRet;
442  }
443  break;
444  default:
445  {
446  ElseRetType aRet = rFuncElse(it->type, nTopRow, nDataSize);
447  if (aRet.second)
448  return PositionType(it, aRet.first);
449  }
450  }
451 
452  if (bLastBlock)
453  break;
454  }
455 
456  return PositionType(rStore.end(), 0);
457 }
458 
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)
464 {
465  typedef std::pair<typename StoreT::const_iterator, typename StoreT::size_type> PositionType;
466  typedef std::pair<typename StoreT::size_type, bool> ElseRetType;
467 
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;
473 
474  for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
475  {
476  bool bLastBlock = false;
477  nDataSize = it->size - nOffset;
478  if (nTopRow + nDataSize - 1 > nEnd)
479  {
480  // Truncate the block.
481  nDataSize = nEnd - nTopRow + 1;
482  bLastBlock = true;
483  }
484 
485  switch (it->type)
486  {
487  case Blk1::block_type:
488  {
489  PositionType aRet = CheckElem<Blk1>(rStore, it, nOffset, nDataSize, rFuncElem);
490  if (aRet.first != rStore.end())
491  return aRet;
492  }
493  break;
494  case Blk2::block_type:
495  {
496  PositionType aRet = CheckElem<Blk2>(rStore, it, nOffset, nDataSize, rFuncElem);
497  if (aRet.first != rStore.end())
498  return aRet;
499  }
500  break;
501  default:
502  {
503  ElseRetType aRet = rFuncElse(*it, nOffset, nDataSize);
504  if (aRet.second)
505  return PositionType(it, aRet.first);
506  }
507  }
508 
509  if (bLastBlock)
510  break;
511  }
512 
513  return PositionType(rStore.end(), 0);
514 }
515 
516 }
517 
518 #endif
519 
520 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void ProcessElements2Reverse(StoreT &rStore, FuncElem &rFuncElem, FuncElse &rFuncElse)
Ret operator()(mdds::mtv::element_t, SizeT, SizeT) const
void EachElem(NodeT &rNode, size_t nOffset, size_t nDataSize, FuncElem &rFuncElem)
StoreT::const_iterator ParseBlock(const typename StoreT::const_iterator &itPos, const StoreT &rStore, Func &rFunc, typename StoreT::size_type nStart, typename StoreT::size_type nEnd)
Generic algorithm to parse blocks of multi_type_vector either partially or fully. ...
void ProcessElements2(StoreT &rStore, FuncElem &rFuncElem, FuncElse &rFuncElse)
StoreT::iterator ProcessBlock(const typename StoreT::iterator &itPos, StoreT &rStore, Func &rFunc, typename StoreT::size_type nStart, typename StoreT::size_type nEnd)
Non-const variant of the above function.
std::pair< typename StoreT::const_iterator, typename StoreT::size_type > FindElement2(const StoreT &rStore, typename StoreT::size_type nStart, typename StoreT::size_type nEnd, FuncElem &rFuncElem, FuncElse &rFuncElse)
StoreT::const_iterator ParseElements4(const typename StoreT::const_iterator &itPos, const StoreT &rStore, typename StoreT::size_type nStart, typename StoreT::size_type nEnd, FuncElem &rFuncElem, FuncElse &rFuncElse)
std::pair< typename StoreT::const_iterator, size_t > CheckElem(const StoreT &rStore, const typename StoreT::const_iterator &it, size_t nOffset, size_t nDataSize, FuncElem &rFuncElem)
std::pair< typename StoreT::const_iterator, typename StoreT::size_type > FindElement1(const StoreT &rStore, typename StoreT::size_type nStart, typename StoreT::size_type nEnd, FuncElem &rFuncElem, FuncElse &rFuncElse)
StoreT::const_iterator ParseElements2(const typename StoreT::const_iterator &itPos, const StoreT &rStore, typename StoreT::size_type nStart, typename StoreT::size_type nEnd, FuncElem &rFuncElem, FuncElse &rFuncElse)
void ProcessElements1(StoreT &rStore, FuncElem &rFuncElem, FuncElse &rFuncElse)
void ParseElements1(const StoreT &rStore, FuncElem &rFuncElem, FuncElse &rFuncElse)
void EachElemReverse(NodeT &rNode, FuncElem &rFuncElem)