LibreOffice Module sc (master)  1
address.hxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column:100 -*- */
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  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #ifndef INCLUDED_SC_INC_ADDRESS_HXX
21 #define INCLUDED_SC_INC_ADDRESS_HXX
22 
23 #include <rtl/ustrbuf.hxx>
24 #include <rtl/strbuf.hxx>
25 
26 #include <array>
27 #include <limits>
28 #include <ostream>
29 
30 #include "scdllapi.h"
31 #include "types.hxx"
32 #include <formula/grammar.hxx>
33 
34 #include <o3tl/typed_flags_set.hxx>
36 
37 namespace com::sun::star {
38  namespace sheet {
39  struct ExternalLinkInfo;
40  }
41 }
42 
43 namespace com::sun::star::uno { template <typename > class Sequence; }
44 
45 class ScDocument;
46 
49 typedef size_t SCSIZE;
50 
51 // Maximum possible value of data type, NOT maximum row value.
52 // MSC confuses numeric_limit max() with macro max() if vcl/wintypes.hxx is
53 // included, we should not be using those stupid macros anyway.
54 #undef min
55 #undef max
56 const SCROW SCROW_MAX = ::std::numeric_limits<SCROW>::max();
57 const SCCOL SCCOL_MAX = ::std::numeric_limits<SCCOL>::max();
58 const SCTAB SCTAB_MAX = ::std::numeric_limits<SCTAB>::max();
59 const SCCOLROW SCCOLROW_MAX = ::std::numeric_limits<SCCOLROW>::max();
60 const SCSIZE SCSIZE_MAX = ::std::numeric_limits<SCSIZE>::max();
61 
62 // Count values
63 const SCROW MAXROWCOUNT = 1048576;
64 const SCCOL MAXCOLCOUNT = 1024;
65 const SCCOL INITIALCOLCOUNT = 64; // initial number of columns we allocate memory for
67 const SCTAB MAXTABCOUNT = 10000;
68 // Maximum values
69 const SCROW MAXROW = MAXROWCOUNT - 1;
70 const SCCOL MAXCOL = MAXCOLCOUNT - 1;
71 const SCTAB MAXTAB = MAXTABCOUNT - 1;
73 const SCROW MAXROW_JUMBO = 16 * 1000 * 1000;
74 const SCCOL MAXCOL_JUMBO = 16384;
75 // Maximum tiled rendering values
76 const SCROW MAXTILEDROW = 500000;
77 // Limit the initial tab count to prevent users to set the count too high,
78 // which could cause the memory usage of blank documents to exceed the
79 // available system memory.
80 const SCTAB MAXINITTAB = 1024;
81 const SCTAB MININITTAB = 1;
82 
83 // Special values
85 const SCTAB TABLEID_DOC = SCTAB_MAX; // entire document, e.g. protect
86 const SCROW SCROWS32K = 32000; // for fuzzing
90 
91 const SCROW MAXROW_30 = 8191;
92 
93 [[nodiscard]] inline bool ValidCol( SCCOL nCol, SCCOL nMaxCol )
94 {
95  assert(nMaxCol == MAXCOL || nMaxCol == MAXCOL_JUMBO); // temporary to debug jumbo sheets work
96  return nCol >= 0 && nCol <= nMaxCol;
97 }
98 
99 [[nodiscard]] inline bool ValidRow( SCROW nRow, SCROW nMaxRow)
100 {
101  assert(nMaxRow == MAXROW || nMaxRow == MAXROW_JUMBO); // temporary to debug jumbo sheets work
102  return nRow >= 0 && nRow <= nMaxRow;
103 }
104 
105 [[nodiscard]] inline bool ValidTab( SCTAB nTab )
106 {
107  return nTab >= 0 && nTab <= MAXTAB;
108 }
109 
110 [[nodiscard]] inline bool ValidTab( SCTAB nTab, SCTAB nMaxTab )
111 {
112  return nTab >= 0 && nTab <= nMaxTab;
113 }
114 
115 [[nodiscard]] inline bool ValidColRow( SCCOL nCol, SCROW nRow, SCCOL nMaxCol, SCROW nMaxRow )
116 {
117  assert(nMaxRow == MAXROW || nMaxRow == MAXROW_JUMBO); // temporary to debug jumbo sheets work
118  return ValidCol(nCol,nMaxCol) && ValidRow(nRow,nMaxRow);
119 }
120 
121 [[nodiscard]] inline bool ValidColRowTab( SCCOL nCol, SCROW nRow, SCTAB nTab, SCCOL nMaxCol, SCROW nMaxRow )
122 {
123  assert(nMaxRow == MAXROW || nMaxRow == MAXROW_JUMBO); // temporary to debug jumbo sheets work
124  return ValidCol(nCol,nMaxCol) && ValidRow(nRow,nMaxRow) && ValidTab( nTab);
125 }
126 
127 [[nodiscard]] inline SCCOL SanitizeCol( SCCOL nCol, SCCOL nMaxCol )
128 {
129  assert(nMaxCol == MAXCOL || nMaxCol == MAXCOL_JUMBO); // temporary to debug jumbo sheets work
130  return nCol < 0 ? 0 : (nCol > nMaxCol ? nMaxCol : nCol);
131 }
132 
133 [[nodiscard]] inline SCROW SanitizeRow( SCROW nRow, SCROW nMaxRow )
134 {
135  assert(nMaxRow == MAXROW || nMaxRow == MAXROW_JUMBO); // temporary to debug jumbo sheets work
136  return nRow < 0 ? 0 : (nRow > nMaxRow ? nMaxRow : nRow);
137 }
138 
139 [[nodiscard]] inline SCTAB SanitizeTab( SCTAB nTab )
140 {
141  return nTab < 0 ? 0 : (nTab > MAXTAB ? MAXTAB : nTab);
142 }
143 
144 // The result of ConvertRef() is a bit group of the following:
145 enum class ScRefFlags : sal_uInt16
146 {
147  ZERO = 0x0000,
148  COL_ABS = 0x0001,
149  ROW_ABS = 0x0002,
150  TAB_ABS = 0x0004,
151  TAB_3D = 0x0008,
152  COL2_ABS = 0x0010,
153  ROW2_ABS = 0x0020,
154  TAB2_ABS = 0x0040,
155  TAB2_3D = 0x0080,
156  ROW_VALID = 0x0100,
157  COL_VALID = 0x0200,
158  TAB_VALID = 0x0400,
159  // BITS for convenience
162  // somewhat cheesy kludge to force the display of the document name even for
163  // local references. Requires TAB_3D to be valid
164  FORCE_DOC = 0x0800,
165  ROW2_VALID = 0x1000,
166  COL2_VALID = 0x2000,
167  TAB2_VALID = 0x4000,
168  VALID = 0x8000,
169 
171 
173 
174  RANGE_ABS = ADDR_ABS | COL2_ABS | ROW2_ABS | TAB2_ABS,
175 
176  ADDR_ABS_3D = ADDR_ABS | TAB_3D,
177  RANGE_ABS_3D = RANGE_ABS | TAB_3D
178 };
179 
180 namespace o3tl
181 {
182  template<> struct typed_flags<ScRefFlags> : is_typed_flags<ScRefFlags, 0xffff> {};
183 }
184 inline void applyStartToEndFlags(ScRefFlags &target,const ScRefFlags source)
185 {
186  target |= ScRefFlags(o3tl::underlyingEnumValue(source) << 4);
187 }
188 inline void applyStartToEndFlags(ScRefFlags &target)
189 {
190  target |= ScRefFlags(o3tl::underlyingEnumValue(target) << 4);
191 }
192 
193 // ScAddress
195 {
196 private:
197  // Even if the fields are in the order "row, column, tab", in all (?) the ScAddress and
198  // ScDocument APIs that take separate row, column, and tab parameters, the parameters are in the
199  // order "column, row, tab", which matches the most common (A1) address syntax, if you ignore
200  // the sheet (tab). Don't let this confuse you, like it confused me for a while.
201 
205 
206 public:
207 
208  enum Uninitialized { UNINITIALIZED };
209  enum InitializeInvalid { INITIALIZE_INVALID };
210 
211  struct Details
212  {
216 
218  eConv(eConvP), nRow(nRowP), nCol(nColP)
219  {}
221  eConv(eConvP), nRow(rAddr.Row()), nCol(rAddr.Col())
222  {}
224  eConv(eConvP), nRow(0), nCol(0)
225  {}
226  /* Use the formula::FormulaGrammar::AddressConvention associated with rAddr::Tab() */
227  Details( const ScDocument& rDoc, const ScAddress& rAddr );
228  };
230 
232  {
233  OUString maTabName;
234  sal_uInt16 mnFileId;
236 
238  mnFileId(0), mbExternal(false)
239  {}
240  };
241 
243  nRow(0), nCol(0), nTab(0)
244  {}
245  ScAddress( SCCOL nColP, SCROW nRowP, SCTAB nTabP ) :
246  nRow(nRowP), nCol(nColP), nTab(nTabP)
247  {}
251  {}
253  nRow(-1), nCol(-1), nTab(-1)
254  {}
255  ScAddress( const ScAddress& rAddress ) :
256  nRow(rAddress.nRow), nCol(rAddress.nCol), nTab(rAddress.nTab)
257  {}
258  inline ScAddress& operator=( const ScAddress& rAddress );
259 
260  inline void Set( SCCOL nCol, SCROW nRow, SCTAB nTab );
261 
262  SCROW Row() const
263  {
264  return nRow;
265  }
266 
267  SCCOL Col() const
268  {
269  return nCol;
270  }
271  SCTAB Tab() const
272  {
273  return nTab;
274  }
275  void SetRow( SCROW nRowP )
276  {
277  nRow = nRowP;
278  }
279  void SetCol( SCCOL nColP )
280  {
281  nCol = nColP;
282  }
283  void SetTab( SCTAB nTabP )
284  {
285  nTab = nTabP;
286  }
287  void SetInvalid()
288  {
289  nRow = -1;
290  nCol = -1;
291  nTab = -1;
292  }
293  bool IsValid() const
294  {
295  return (nRow >= 0) && (nCol >= 0) && (nTab >= 0);
296  }
297 
298  inline void PutInOrder( ScAddress& rAddress );
299 
300  void IncRow( SCROW nDelta = 1 )
301  {
302  nRow = sal::static_int_cast<SCROW>(nRow + nDelta);
303  }
304  void IncCol( SCCOL nDelta = 1 )
305  {
306  nCol = sal::static_int_cast<SCCOL>(nCol + nDelta);
307  }
308  void IncTab( SCTAB nDelta = 1 )
309  {
310  nTab = sal::static_int_cast<SCTAB>(nTab + nDelta);
311  }
312  void GetVars( SCCOL& nColP, SCROW& nRowP, SCTAB& nTabP ) const
313  {
314  nColP = nCol;
315  nRowP = nRow;
316  nTabP = nTab;
317  }
318 
326  SC_DLLPUBLIC ScRefFlags Parse(
327  const OUString&, const ScDocument* = nullptr,
328  const Details& rDetails = detailsOOOa1,
329  ExternalInfo* pExtInfo = nullptr,
330  const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = nullptr,
331  sal_Int32* pSheetEndPos = nullptr,
332  const OUString* pErrRef = nullptr );
333 
334  SC_DLLPUBLIC void Format( OStringBuffer& r, ScRefFlags nFlags,
335  const ScDocument* pDocument = nullptr,
336  const Details& rDetails = detailsOOOa1) const;
337 
338  SC_DLLPUBLIC OUString Format( ScRefFlags nFlags,
339  const ScDocument* pDocument = nullptr,
340  const Details& rDetails = detailsOOOa1) const;
341 
349  [[nodiscard]] SC_DLLPUBLIC bool Move( SCCOL nDeltaX, SCROW nDeltaY, SCTAB nDeltaZ,
350  ScAddress& rErrorPos, const ScDocument* pDocument = nullptr );
351 
352  inline bool operator==( const ScAddress& rAddress ) const;
353  inline bool operator!=( const ScAddress& rAddress ) const;
354  inline bool operator<( const ScAddress& rAddress ) const;
355  inline bool operator<=( const ScAddress& rAddress ) const;
356  inline bool lessThanByRow( const ScAddress& rAddress ) const;
357 
358  inline size_t hash() const;
359 
369  OUString GetColRowString() const;
370 };
371 
372 // For use in SAL_DEBUG etc. Output format not guaranteed to be stable.
373 template<typename charT, typename traits>
374 inline std::basic_ostream<charT, traits> & operator <<(std::basic_ostream<charT, traits> & stream, const ScAddress& rAddress)
375 {
376  stream <<
377  rAddress.Tab()+1 << "!"
378  "R" << rAddress.Row()+1 <<
379  "C" << rAddress.Col()+1;
380 
381  return stream;
382 }
383 
384 inline void ScAddress::PutInOrder( ScAddress& rAddress )
385 {
386  if ( rAddress.Col() < Col() )
387  {
388  SCCOL nTmp = rAddress.Col();
389  rAddress.SetCol( Col() );
390  SetCol( nTmp );
391  }
392  if ( rAddress.Row() < Row() )
393  {
394  SCROW nTmp = rAddress.Row();
395  rAddress.SetRow( Row() );
396  SetRow( nTmp );
397  }
398  if ( rAddress.Tab() < Tab() )
399  {
400  SCTAB nTmp = rAddress.Tab();
401  rAddress.SetTab( Tab() );
402  SetTab( nTmp );
403  }
404 }
405 
406 inline void ScAddress::Set( SCCOL nColP, SCROW nRowP, SCTAB nTabP )
407 {
408  nCol = nColP;
409  nRow = nRowP;
410  nTab = nTabP;
411 }
412 
413 inline ScAddress& ScAddress::operator=( const ScAddress& rAddress )
414 {
415  nCol = rAddress.nCol;
416  nRow = rAddress.nRow;
417  nTab = rAddress.nTab;
418  return *this;
419 }
420 
421 inline bool ScAddress::operator==( const ScAddress& rAddress ) const
422 {
423  return nRow == rAddress.nRow && nCol == rAddress.nCol && nTab == rAddress.nTab;
424 }
425 
426 inline bool ScAddress::operator!=( const ScAddress& rAddress ) const
427 {
428  return !operator==( rAddress );
429 }
430 
432 inline bool ScAddress::operator<( const ScAddress& rAddress ) const
433 {
434  if (nTab == rAddress.nTab)
435  {
436  if (nCol == rAddress.nCol)
437  return nRow < rAddress.nRow;
438  else
439  return nCol < rAddress.nCol;
440  }
441  else
442  return nTab < rAddress.nTab;
443 }
444 
445 inline bool ScAddress::operator<=( const ScAddress& rAddress ) const
446 {
447  return operator<( rAddress ) || operator==( rAddress );
448 }
449 
451 inline bool ScAddress::lessThanByRow( const ScAddress& rAddress ) const
452 {
453  if (nTab == rAddress.nTab)
454  {
455  if (nRow == rAddress.nRow)
456  return nCol < rAddress.nCol;
457  else
458  return nRow < rAddress.nRow;
459  }
460  else
461  return nTab < rAddress.nTab;
462 }
463 
464 inline size_t ScAddress::hash() const
465 {
466 #if SAL_TYPES_SIZEOFPOINTER == 8
467  // 16 bits for the columns, and 20 bits for the rows
468  return (static_cast<size_t>(nTab) << 36) ^
469  (static_cast<size_t>(nCol) << 20) ^
470  static_cast<size_t>(nRow);
471 #else
472  // Assume that there are not that many addresses with row > 2^16 AND column
473  // > 2^8 AND sheet > 2^8 so we won't have too many collisions.
474  if (nRow <= 0xffff)
475  return (static_cast<size_t>(nTab) << 24) ^
476  (static_cast<size_t>(nCol) << 16) ^ static_cast<size_t>(nRow);
477  else
478  return (static_cast<size_t>(nTab) << 28) ^
479  (static_cast<size_t>(nCol) << 24) ^ static_cast<size_t>(nRow);
480 #endif
481 }
482 
484 {
485  size_t operator()( const ScAddress & rAddress ) const
486  {
487  return rAddress.hash();
488  }
489 };
490 
491 inline bool ValidAddress( const ScAddress& rAddress, SCCOL nMaxCol = MAXCOL, SCROW nMaxRow = MAXROW )
492 {
493  return ValidCol(rAddress.Col(), nMaxCol) && ValidRow(rAddress.Row(), nMaxRow) && ValidTab(rAddress.Tab());
494 }
495 
496 // ScRange
498 {
499 public:
502 
504  aStart(), aEnd()
505  {}
506 
507  ScRange( ScAddress::Uninitialized eUninitialized ) :
508  aStart( eUninitialized ), aEnd( eUninitialized )
509  {}
511  aStart( eInvalid ), aEnd( eInvalid )
512  {}
513  ScRange( const ScAddress& aInputStart, const ScAddress& aInputEnd ) :
514  aStart( aInputStart ), aEnd( aInputEnd )
515  {
516  aStart.PutInOrder( aEnd );
517  }
518  ScRange( const ScRange& rRange ) :
519  aStart( rRange.aStart ), aEnd( rRange.aEnd )
520  {}
521  ScRange( const ScAddress& rRange ) :
522  aStart( rRange ), aEnd( rRange )
523  {}
524  ScRange( SCCOL nCol, SCROW nRow, SCTAB nTab ) :
525  aStart( nCol, nRow, nTab ), aEnd( aStart )
526  {}
527  ScRange( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2 ) :
528  aStart( nCol1, nRow1, nTab1 ), aEnd( nCol2, nRow2, nTab2 )
529  {}
530 
531  ScRange& operator=( const ScRange& rRange )
532  {
533  aStart = rRange.aStart;
534  aEnd = rRange.aEnd;
535  return *this;
536  }
537  ScRange& operator=( const ScAddress& rPos )
538  {
539  aStart = aEnd = rPos;
540  return *this;
541  }
542  void SetInvalid()
543  {
544  aStart.SetInvalid();
545  aEnd.SetInvalid();
546  }
547  bool IsValid() const
548  {
549  return aStart.IsValid() && aEnd.IsValid();
550  }
551  inline bool In( const ScAddress& ) const;
552  inline bool In( const ScRange& ) const;
553 
554  SC_DLLPUBLIC ScRefFlags Parse( const OUString&, const ScDocument* = nullptr,
556  ScAddress::ExternalInfo* pExtInfo = nullptr,
557  const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = nullptr,
558  const OUString* pErrRef = nullptr );
559 
560  SC_DLLPUBLIC ScRefFlags ParseAny( const OUString&, const ScDocument*,
561  const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
562  SC_DLLPUBLIC ScRefFlags ParseCols( const ScDocument* pDoc,
563  const OUString&,
564  const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
565  SC_DLLPUBLIC void ParseRows( const ScDocument* pDoc,
566  const OUString&,
567  const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
568 
590  const sal_Unicode* Parse_XL_Header( const sal_Unicode* pString, const ScDocument* pDocument,
591  OUString& rExternDocName, OUString& rStartTabName,
592  OUString& rEndTabName, ScRefFlags& nFlags,
593  bool bOnlyAcceptSingle,
594  const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = nullptr,
595  const OUString* pErrRef = nullptr );
596 
617  SC_DLLPUBLIC OUString Format( const ScDocument& rDocument,
618  ScRefFlags nFlags = ScRefFlags::ZERO,
620  bool bFullAddressNotation = false ) const;
621 
622  inline void GetVars( SCCOL& nCol1, SCROW& nRow1, SCTAB& nTab1,
623  SCCOL& nCol2, SCROW& nRow2, SCTAB& nTab2 ) const;
624  SC_DLLPUBLIC void PutInOrder();
625 
633  [[nodiscard]] SC_DLLPUBLIC bool Move( SCCOL aDeltaX, SCROW aDeltaY, SCTAB aDeltaZ,
634  ScRange& rErrorRange, const ScDocument* pDocument = nullptr );
635 
637  [[nodiscard]] SC_DLLPUBLIC bool MoveSticky( const ScDocument& rDoc, SCCOL aDeltaX, SCROW aDeltaY, SCTAB aDeltaZ,
638  ScRange& rErrorRange );
639 
640  SC_DLLPUBLIC void IncColIfNotLessThan(const ScDocument* pDoc, SCCOL nStartCol, SCCOL nOffset);
641  SC_DLLPUBLIC void IncRowIfNotLessThan(const ScDocument* pDoc, SCROW nStartRow, SCROW nOffset);
642 
643  SC_DLLPUBLIC void ExtendTo( const ScRange& rRange );
644  SC_DLLPUBLIC bool Intersects( const ScRange& rRange ) const; // do two ranges intersect?
645 
646  ScRange Intersection( const ScRange& rOther ) const;
647 
649  inline bool IsEndColSticky() const;
651  inline bool IsEndRowSticky() const;
652 
656  void IncEndColSticky( const ScDocument* pDoc, SCCOL nDelta );
657 
661  void IncEndRowSticky( const ScDocument* pDoc, SCROW nDelta );
662 
663  inline bool operator==( const ScRange& rRange ) const;
664  inline bool operator!=( const ScRange& rRange ) const;
665  inline bool operator<( const ScRange& rRange ) const;
666  inline bool operator<=( const ScRange& rRange ) const;
667 
669  inline size_t hashArea() const;
671  inline size_t hashStartColumn() const;
672 };
673 
674 // For use in SAL_DEBUG etc. Output format not guaranteed to be stable.
675 template<typename charT, typename traits>
676 inline std::basic_ostream<charT, traits> & operator <<(std::basic_ostream<charT, traits> & stream, const ScRange& rRange)
677 {
678  stream << rRange.aStart;
679  if (rRange.aEnd != rRange.aStart)
680  {
681  stream << ":";
682  if (rRange.aEnd.Tab() != rRange.aStart.Tab())
683  stream << rRange.aEnd;
684  else
685  stream <<
686  "R" << rRange.aEnd.Row()+1 <<
687  "C" << rRange.aEnd.Col()+1;
688  }
689 
690  return stream;
691 }
692 
693 inline void ScRange::GetVars( SCCOL& nCol1, SCROW& nRow1, SCTAB& nTab1,
694  SCCOL& nCol2, SCROW& nRow2, SCTAB& nTab2 ) const
695 {
696  aStart.GetVars( nCol1, nRow1, nTab1 );
697  aEnd.GetVars( nCol2, nRow2, nTab2 );
698 }
699 
700 inline bool ScRange::IsEndColSticky() const
701 {
702  // Only in an actual column range, i.e. not if both columns are MAXCOL.
703  return aEnd.Col() == MAXCOL && aStart.Col() < aEnd.Col();
704 }
705 
706 inline bool ScRange::IsEndRowSticky() const
707 {
708  // Only in an actual row range, i.e. not if both rows are MAXROW.
709  return aEnd.Row() == MAXROW && aStart.Row() < aEnd.Row();
710 }
711 
712 inline bool ScRange::operator==( const ScRange& rRange ) const
713 {
714  return ( (aStart == rRange.aStart) && (aEnd == rRange.aEnd) );
715 }
716 
717 inline bool ScRange::operator!=( const ScRange& rRange ) const
718 {
719  return !operator==( rRange );
720 }
721 
723 inline bool ScRange::operator<( const ScRange& r ) const
724 {
725  return aStart < r.aStart || (aStart == r.aStart && aEnd < r.aEnd) ;
726 }
727 
728 inline bool ScRange::operator<=( const ScRange& rRange ) const
729 {
730  return operator<( rRange ) || operator==( rRange );
731 }
732 
733 inline bool ScRange::In( const ScAddress& rAddress ) const
734 {
735  return
736  aStart.Col() <= rAddress.Col() && rAddress.Col() <= aEnd.Col() &&
737  aStart.Row() <= rAddress.Row() && rAddress.Row() <= aEnd.Row() &&
738  aStart.Tab() <= rAddress.Tab() && rAddress.Tab() <= aEnd.Tab();
739 }
740 
741 inline bool ScRange::In( const ScRange& rRange ) const
742 {
743  return
744  aStart.Col() <= rRange.aStart.Col() && rRange.aEnd.Col() <= aEnd.Col() &&
745  aStart.Row() <= rRange.aStart.Row() && rRange.aEnd.Row() <= aEnd.Row() &&
746  aStart.Tab() <= rRange.aStart.Tab() && rRange.aEnd.Tab() <= aEnd.Tab();
747 }
748 
749 inline size_t ScRange::hashArea() const
750 {
751 #if SAL_TYPES_SIZEOFPOINTER == 8
752  // 12 bits for the columns and 20 bits for the rows
753  return
754  (static_cast<size_t>(aStart.Row()) << 44) ^
755  (static_cast<size_t>(aStart.Col()) << 32) ^
756  (static_cast<size_t>(aEnd.Col()) << 20) ^
757  static_cast<size_t>(aEnd.Row());
758 #else
759  // Assume that there are not that many ranges with identical corners so we
760  // won't have too many collisions. Also assume that more lower row and
761  // column numbers are used so that there are not too many conflicts with
762  // the columns hashed into the values, and that start row and column
763  // usually don't exceed certain values. High bits are not masked off and
764  // may overlap with lower bits of other values, e.g. if start column is
765  // greater than assumed.
766  return
767  (static_cast<size_t>(aStart.Row()) << 26) ^ // start row <= 2^6
768  (static_cast<size_t>(aStart.Col()) << 21) ^ // start column <= 2^5
769  (static_cast<size_t>(aEnd.Col()) << 15) ^ // end column <= 2^6
770  static_cast<size_t>(aEnd.Row()); // end row <= 2^15
771 #endif
772 }
773 
774 inline size_t ScRange::hashStartColumn() const
775 {
776 #if SAL_TYPES_SIZEOFPOINTER == 8
777  // 20 bits for the rows
778  return
779  (static_cast<size_t>(aStart.Col()) << 40) ^
780  (static_cast<size_t>(aStart.Row()) << 20) ^
781  static_cast<size_t>(aEnd.Row());
782 #else
783  // Assume that for the start row more lower row numbers are used so that
784  // there are not too many conflicts with the column hashed into the higher
785  // values.
786  return
787  (static_cast<size_t>(aStart.Col()) << 24) ^ // start column <= 2^8
788  (static_cast<size_t>(aStart.Row()) << 16) ^ // start row <= 2^8
789  static_cast<size_t>(aEnd.Row());
790 #endif
791 }
792 
793 inline bool ValidRange( const ScRange& rRange, SCCOL nMaxCol = MAXCOL, SCROW nMaxRow = MAXROW )
794 {
795  return ValidAddress(rRange.aStart, nMaxCol, nMaxRow) && ValidAddress(rRange.aEnd, nMaxCol, nMaxRow);
796 }
797 
798 // ScRangePair
800 {
801 private:
802  std::array<ScRange,2> aRange;
803 
804 public:
806  {
807  aRange[0] = r.aRange[0];
808  aRange[1] = r.aRange[1];
809  }
810  ScRangePair( const ScRange& rRange1, const ScRange& rRange2 )
811  {
812  aRange[0] = rRange1;
813  aRange[1] = rRange2;
814  }
815 
816  inline ScRangePair& operator= ( const ScRangePair& rRange );
817  const ScRange& GetRange( sal_uInt16 n ) const
818  {
819  return aRange[n];
820  }
821  ScRange& GetRange( sal_uInt16 n )
822  {
823  return aRange[n];
824  }
825 };
826 
828 {
829  aRange[0] = rRange.aRange[0];
830  aRange[1] = rRange.aRange[1];
831  return *this;
832 }
833 
834 // ScRefAddress
836 {
837 private:
839  bool bRelCol;
840  bool bRelRow;
841  bool bRelTab;
842 public:
844  bRelCol(false), bRelRow(false), bRelTab(false)
845  {}
846  ScRefAddress( SCCOL nCol, SCROW nRow, SCTAB nTab ) :
847  aAdr(nCol, nRow, nTab),
848  bRelCol(false), bRelRow(false), bRelTab(false)
849  {}
850  ScRefAddress( const ScRefAddress& rRef ) :
851  aAdr(rRef.aAdr), bRelCol(rRef.bRelCol), bRelRow(rRef.bRelRow),
852  bRelTab(rRef.bRelTab)
853  {}
854 
855  inline ScRefAddress& operator=( const ScRefAddress& );
856 
857  bool IsRelCol() const
858  {
859  return bRelCol;
860  }
861  bool IsRelRow() const
862  {
863  return bRelRow;
864  }
865  bool IsRelTab() const
866  {
867  return bRelTab;
868  }
869 
870  void SetRelCol(bool bNewRelCol)
871  {
872  bRelCol = bNewRelCol;
873  }
874  void SetRelRow(bool bNewRelRow)
875  {
876  bRelRow = bNewRelRow;
877  }
878  void SetRelTab(bool bNewRelTab)
879  {
880  bRelTab = bNewRelTab;
881  }
882 
883  inline void Set( const ScAddress& rAdr,
884  bool bNewRelCol, bool bNewRelRow, bool bNewRelTab );
885  inline void Set( SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
886  bool bNewRelCol, bool bNewRelRow, bool bNewRelTab );
887 
888  const ScAddress& GetAddress() const
889  {
890  return aAdr;
891  }
892 
893  SCCOL Col() const
894  {
895  return aAdr.Col();
896  }
897  SCROW Row() const
898  {
899  return aAdr.Row();
900  }
901  SCTAB Tab() const
902  {
903  return aAdr.Tab();
904  }
905 
906  inline bool operator == ( const ScRefAddress& r ) const;
907 
908  OUString GetRefString( const ScDocument* pDocument, SCTAB nActTab,
909  const ScAddress::Details& rDetails = ScAddress::detailsOOOa1) const;
910 };
911 
913 {
914  aAdr = rRef.aAdr;
915  bRelCol = rRef.bRelCol;
916  bRelRow = rRef.bRelRow;
917  bRelTab = rRef.bRelTab;
918  return *this;
919 }
920 
921 inline void ScRefAddress::Set( const ScAddress& rAdr,
922  bool bNewRelCol, bool bNewRelRow, bool bNewRelTab )
923 {
924  aAdr = rAdr;
925  bRelCol = bNewRelCol;
926  bRelRow = bNewRelRow;
927  bRelTab = bNewRelTab;
928 }
929 
930 inline void ScRefAddress::Set( SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
931  bool bNewRelCol, bool bNewRelRow, bool bNewRelTab )
932 {
933  aAdr.Set( nNewCol, nNewRow, nNewTab);
934  bRelCol = bNewRelCol;
935  bRelRow = bNewRelRow;
936  bRelTab = bNewRelTab;
937 }
938 
939 inline bool ScRefAddress::operator==( const ScRefAddress& rRefAddress ) const
940 {
941  return aAdr == rRefAddress.aAdr &&
942  bRelCol == rRefAddress.bRelCol &&
943  bRelRow == rRefAddress.bRelRow &&
944  bRelTab == rRefAddress.bRelTab;
945 }
946 
947 // Global functions
948 
949 // Special values for cells always broadcasting or listening (ScRecalcMode::ALWAYS
950 // and the like).
951 #define BCA_BRDCST_ALWAYS ScAddress( 0, SCROW_MAX, 0 )
952 #define BCA_LISTEN_ALWAYS ScRange( BCA_BRDCST_ALWAYS, BCA_BRDCST_ALWAYS )
953 
954 template< typename T > inline void PutInOrder( T& nStart, T& nEnd )
955 {
956  if (nEnd < nStart)
957  {
958  std::swap(nStart, nEnd);
959  }
960 }
961 
962 bool ConvertSingleRef( const ScDocument* pDocument, const OUString& rRefString,
963  SCTAB nDefTab, ScRefAddress& rRefAddress,
964  const ScAddress::Details& rDetails,
965  ScAddress::ExternalInfo* pExtInfo = nullptr );
966 
967 bool ConvertDoubleRef( const ScDocument* pDocument, const OUString& rRefString,
968  SCTAB nDefTab, ScRefAddress& rStartRefAddress,
969  ScRefAddress& rEndRefAddress,
970  const ScAddress::Details& rDetails,
971  ScAddress::ExternalInfo* pExtInfo = nullptr );
972 
974 SC_DLLPUBLIC void ScColToAlpha( OUStringBuffer& rBuffer, SCCOL nCol);
975 
976 inline void ScColToAlpha( OUString& rStr, SCCOL nCol)
977 {
978  OUStringBuffer aBuf(4);
979  ScColToAlpha( aBuf, nCol);
980  rStr += aBuf;
981 }
982 
983 inline OUString ScColToAlpha( SCCOL nCol )
984 {
985  OUStringBuffer aBuf(4);
986  ScColToAlpha( aBuf, nCol);
987  return aBuf.makeStringAndClear();
988 }
989 
991 bool AlphaToCol(const ScDocument& rDoc, SCCOL& rCol, const OUString& rStr);
992 
993 #endif // INCLUDED_SC_INC_ADDRESS_HXX
994 
995 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool operator==(const XclFontData &rLeft, const XclFontData &rRight)
Definition: xlstyle.cxx:517
Details(formula::FormulaGrammar::AddressConvention eConvP)
Definition: address.hxx:223
ScAddress(const ScAddress &rAddress)
Definition: address.hxx:255
void Set(const ScAddress &rAdr, bool bNewRelCol, bool bNewRelRow, bool bNewRelTab)
Definition: address.hxx:921
bool bRelTab
Definition: address.hxx:841
const SCROW SCROWS32K
Definition: address.hxx:86
void GetVars(SCCOL &nColP, SCROW &nRowP, SCTAB &nTabP) const
Definition: address.hxx:312
bool operator!=(const ScAddress &rAddress) const
Definition: address.hxx:426
size_t hashArea() const
Hash 2D area ignoring table number.
Definition: address.hxx:749
ScAddress aStart
Definition: address.hxx:500
SC_DLLPUBLIC void ScColToAlpha(OUStringBuffer &rBuffer, SCCOL nCol)
append alpha representation of column to buffer
Definition: address.cxx:1921
ScRange(const ScRange &rRange)
Definition: address.hxx:518
const SCROW MAXROW_30
Definition: address.hxx:91
bool operator!=(const XclExpString &rLeft, const XclExpString &rRight)
Definition: xestring.hxx:246
void IncTab(SCTAB nDelta=1)
Definition: address.hxx:308
SCROW Row() const
Definition: address.hxx:262
const SCCOLROW SCCOLROW_MAX
Definition: address.hxx:59
size_t hash() const
Definition: address.hxx:464
ScRangePair & operator=(const ScRangePair &rRange)
Definition: address.hxx:827
size_t hashStartColumn() const
Hash start column and start and end rows.
Definition: address.hxx:774
void SetRelTab(bool bNewRelTab)
Definition: address.hxx:878
const SCCOL SCCOL_MAX
Definition: address.hxx:57
constexpr std::underlying_type_t< T > underlyingEnumValue(T e)
aBuf
void PutInOrder(ScAddress &rAddress)
Definition: address.hxx:384
ScRange(const ScAddress &rRange)
Definition: address.hxx:521
ScAddress aEnd
Definition: address.hxx:501
bool operator<=(const BigInt &rVal1, const BigInt &rVal2)
ScRange(ScAddress::Uninitialized eUninitialized)
Definition: address.hxx:507
const SCCOL MAXCOLCOUNT
Definition: address.hxx:64
bool ConvertDoubleRef(const ScDocument *pDocument, const OUString &rRefString, SCTAB nDefTab, ScRefAddress &rStartRefAddress, ScRefAddress &rEndRefAddress, const ScAddress::Details &rDetails, ScAddress::ExternalInfo *pExtInfo=nullptr)
Definition: address.cxx:1517
bool operator<(const ScRange &rRange) const
Sort on upper left corner tab,col,row, if equal then use lower right too.
Definition: address.hxx:723
bool operator==(const ScRefAddress &r) const
Definition: address.hxx:939
const SCROW SCROW_MAX
Definition: address.hxx:56
ScRefAddress & operator=(const ScRefAddress &)
Definition: address.hxx:912
exports com.sun.star. sheet
ScAddress(InitializeInvalid)
Definition: address.hxx:252
sal_uInt16 sal_Unicode
const SCROW MAXROW_JUMBO
Definition: address.hxx:73
ScRange()
Definition: address.hxx:503
bool ValidColRowTab(SCCOL nCol, SCROW nRow, SCTAB nTab, SCCOL nMaxCol, SCROW nMaxRow)
Definition: address.hxx:121
formula::FormulaGrammar::AddressConvention eConv
Definition: address.hxx:213
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:45
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:24
const SCROW MAXROW
Definition: address.hxx:69
bool ValidRange(const ScRange &rRange, SCCOL nMaxCol=MAXCOL, SCROW nMaxRow=MAXROW)
Definition: address.hxx:793
static SC_DLLPUBLIC const Details detailsOOOa1
Definition: address.hxx:229
SCTAB Tab() const
Definition: address.hxx:271
ScAddress & operator=(const ScAddress &rAddress)
Definition: address.hxx:413
void SetRow(SCROW nRowP)
Definition: address.hxx:275
SCROW SanitizeRow(SCROW nRow, SCROW nMaxRow)
Definition: address.hxx:133
SCCOL nCol
Definition: address.hxx:203
const SCCOLROW MAXCOLROW
Definition: address.hxx:72
void SetCol(SCCOL nColP)
Definition: address.hxx:279
ScRange(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2)
Definition: address.hxx:527
const SCROW MAXROWCOUNT
Definition: address.hxx:63
ScRange & operator=(const ScRange &rRange)
Definition: address.hxx:531
void PutInOrder(T &nStart, T &nEnd)
Definition: address.hxx:954
ScRefAddress(const ScRefAddress &rRef)
Definition: address.hxx:850
bool IsRelTab() const
Definition: address.hxx:865
SCCOL SanitizeCol(SCCOL nCol, SCCOL nMaxCol)
Definition: address.hxx:127
bool IsValid() const
Definition: address.hxx:293
SCROW nRow
Definition: address.hxx:202
ScRange & GetRange(sal_uInt16 n)
Definition: address.hxx:821
bool ValidCol(SCCOL nCol, SCCOL nMaxCol)
Definition: address.hxx:93
void SetTab(SCTAB nTabP)
Definition: address.hxx:283
ScRange & operator=(const ScAddress &rPos)
Definition: address.hxx:537
bool IsEndColSticky() const
If maximum end column should not be adapted during reference update.
Definition: address.hxx:700
const SCTAB SC_TAB_APPEND
Definition: address.hxx:84
void IncCol(SCCOL nDelta=1)
Definition: address.hxx:304
void Set(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: address.hxx:406
sal_Int16 SCCOL
Definition: types.hxx:22
Details(formula::FormulaGrammar::AddressConvention eConvP, SCROW nRowP, SCCOL nColP)
Definition: address.hxx:217
bool operator!=(const ScRange &rRange) const
Definition: address.hxx:717
void applyStartToEndFlags(ScRefFlags &target, const ScRefFlags source)
Definition: address.hxx:184
const SCTAB MININITTAB
Definition: address.hxx:81
const SCCOL MAXCOL
Definition: address.hxx:70
const SCSIZE SCSIZE_MAX
Definition: address.hxx:60
std::array< ScRange, 2 > aRange
Definition: address.hxx:802
bool IsEndRowSticky() const
If maximum end row should not be adapted during reference update.
Definition: address.hxx:706
void IncRow(SCROW nDelta=1)
Definition: address.hxx:300
const ScRange & GetRange(sal_uInt16 n) const
Definition: address.hxx:817
ScRange(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: address.hxx:524
InitializeInvalid
Definition: address.hxx:209
bool operator<=(const ScRange &rRange) const
Definition: address.hxx:728
void GetVars(SCCOL &nCol1, SCROW &nRow1, SCTAB &nTab1, SCCOL &nCol2, SCROW &nRow2, SCTAB &nTab2) const
Definition: address.hxx:693
bool AlphaToCol(const ScDocument &rDoc, SCCOL &rCol, const OUString &rStr)
get column number of A..IV... string
Definition: address.cxx:2538
ScRangePair(const ScRangePair &r)
Definition: address.hxx:805
bool In(const ScAddress &) const
is Address& in Range?
Definition: address.hxx:733
const SCTAB MAXTAB
Definition: address.hxx:71
bool operator<(const ScAddress &rAddress) const
Less than ordered by tab,col,row.
Definition: address.hxx:432
void SetInvalid()
Definition: address.hxx:542
bool IsValid() const
Definition: address.hxx:547
const SCROW SCROW_REPEAT_NONE
Definition: address.hxx:88
const SCTAB TABLEID_DOC
Definition: address.hxx:85
const SCTAB MAXINITTAB
Definition: address.hxx:80
ScAddress aAdr
Definition: address.hxx:838
ScRange(const ScAddress &aInputStart, const ScAddress &aInputEnd)
Definition: address.hxx:513
ScRange(ScAddress::InitializeInvalid eInvalid)
Definition: address.hxx:510
SCCOL Col() const
Definition: address.hxx:267
Details(formula::FormulaGrammar::AddressConvention eConvP, ScAddress const &rAddr)
Definition: address.hxx:220
Reference< XOutputStream > stream
#define SAL_WARN_UNUSED
SCTAB SanitizeTab(SCTAB nTab)
Definition: address.hxx:139
sal_Int32 SCROW
Definition: types.hxx:18
bool operator<(const ScDPCollection::DBType &left, const ScDPCollection::DBType &right)
Definition: dpobject.cxx:3929
const ScAddress & GetAddress() const
Definition: address.hxx:888
size_t operator()(const ScAddress &rAddress) const
Definition: address.hxx:485
bool ConvertSingleRef(const ScDocument *pDocument, const OUString &rRefString, SCTAB nDefTab, ScRefAddress &rRefAddress, const ScAddress::Details &rDetails, ScAddress::ExternalInfo *pExtInfo=nullptr)
Definition: address.cxx:1495
const SCCOL INITIALCOLCOUNT
Definition: address.hxx:65
const SCCOL MAXCOL_JUMBO
Definition: address.hxx:74
bool IsRelCol() const
Definition: address.hxx:857
bool IsRelRow() const
Definition: address.hxx:861
SCROW Row() const
Definition: address.hxx:897
SCCOL Col() const
Definition: address.hxx:893
void SetInvalid()
Definition: address.hxx:287
const SCROW MAXTILEDROW
Definition: address.hxx:76
void SetRelCol(bool bNewRelCol)
Definition: address.hxx:870
ScRefAddress(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: address.hxx:846
bool ValidColRow(SCCOL nCol, SCROW nRow, SCCOL nMaxCol, SCROW nMaxRow)
Definition: address.hxx:115
bool ValidRow(SCROW nRow, SCROW nMaxRow)
Definition: address.hxx:99
bool bRelCol
Definition: address.hxx:839
SCTAB nTab
Definition: address.hxx:204
const SCCOL SC_TABSTART_NONE
Definition: address.hxx:89
ScAddress(Uninitialized)
Yes, it is what it seems to be: Uninitialized.
Definition: address.hxx:250
SCTAB Tab() const
Definition: address.hxx:901
ScAddress(SCCOL nColP, SCROW nRowP, SCTAB nTabP)
Definition: address.hxx:245
bool lessThanByRow(const ScAddress &rAddress) const
Less than ordered by tab,row,col as needed by row-wise import/export.
Definition: address.hxx:451
ScRefFlags
Definition: address.hxx:145
const SCTAB MAXTABCOUNT
limiting to 10000 for now, problem with 32 bit builds for now
Definition: address.hxx:67
const SCTAB SCTAB_MAX
Definition: address.hxx:58
ScRangePair(const ScRange &rRange1, const ScRange &rRange2)
Definition: address.hxx:810
#define SC_DLLPUBLIC
Definition: scdllapi.h:28
bool ValidTab(SCTAB nTab)
Definition: address.hxx:105
const SCCOL SCCOL_REPEAT_NONE
Definition: address.hxx:87
bool operator==(const ScAddress &rAddress) const
Definition: address.hxx:421
bool operator<=(const ScAddress &rAddress) const
Definition: address.hxx:445
sal_Int16 SCTAB
Definition: types.hxx:23
bool bRelRow
Definition: address.hxx:840
void SetRelRow(bool bNewRelRow)
Definition: address.hxx:874
bool ValidAddress(const ScAddress &rAddress, SCCOL nMaxCol=MAXCOL, SCROW nMaxRow=MAXROW)
Definition: address.hxx:491
bool operator==(const ScRange &rRange) const
Definition: address.hxx:712