Branch libreoffice-24-8-3
[LibreOffice.git] / sc / inc / token.hxx
blob9969158184454a52437e15793ba7d4cf60445f61
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #pragma once
22 #include <memory>
23 #include <vector>
25 #include <formula/opcode.hxx>
26 #include "refdata.hxx"
27 #include "scdllapi.h"
28 #include <formula/token.hxx>
29 #include "calcmacros.hxx"
30 #include "types.hxx"
32 // Matrix token constants.
33 #define MATRIX_TOKEN_HAS_RANGE 1
35 class ScJumpMatrix;
36 class ScMatrix;
37 struct ScSheetLimits;
39 typedef ::std::vector< ScComplexRefData > ScRefList;
41 #if DEBUG_FORMULA_COMPILER
42 void DumpToken(formula::FormulaToken const & rToken);
43 #endif
45 /** If rTok1 and rTok2 both are SingleRef or DoubleRef tokens, extend/merge
46 ranges as needed for ocRange.
47 @param rPos
48 The formula's position, used to calculate absolute positions from
49 relative references.
50 @param bReuseDoubleRef
51 If true, a DoubleRef token is reused if passed as rTok1 or rTok2,
52 else a new DoubleRef token is created and returned.
53 @return
54 A reused or new'ed ScDoubleRefToken, or a NULL TokenRef if rTok1 or
55 rTok2 are not of sv(Single|Double)Ref
57 formula::FormulaTokenRef extendRangeReference( ScSheetLimits& rLimits, formula::FormulaToken & rTok1, formula::FormulaToken & rTok2, const ScAddress & rPos, bool bReuseDoubleRef );
59 class ScSingleRefToken final : public formula::FormulaToken
61 private:
62 ScSheetLimits& mrSheetLimits; // don't use rtl::Reference to avoid ref-counting traffic
63 ScSingleRefData aSingleRef;
64 public:
65 ScSingleRefToken( ScSheetLimits& rLimits, const ScSingleRefData& r, OpCode e = ocPush ) :
66 FormulaToken( formula::svSingleRef, e ), mrSheetLimits(rLimits), aSingleRef( r ) {}
67 virtual const ScSingleRefData* GetSingleRef() const override;
68 virtual ScSingleRefData* GetSingleRef() override;
69 virtual bool TextEqual( const formula::FormulaToken& rToken ) const override;
70 virtual bool operator==( const formula::FormulaToken& rToken ) const override;
71 virtual FormulaToken* Clone() const override { return new ScSingleRefToken(*this); }
74 class ScDoubleRefToken final : public formula::FormulaToken
76 private:
77 ScSheetLimits& mrSheetLimits; // don't use rtl::Reference to avoid ref-counting traffic
78 ScComplexRefData aDoubleRef;
79 public:
80 ScDoubleRefToken( ScSheetLimits& rLimits, const ScComplexRefData& r, OpCode e = ocPush ) :
81 FormulaToken( formula::svDoubleRef, e ), mrSheetLimits(rLimits), aDoubleRef( r ) {}
82 virtual const ScSingleRefData* GetSingleRef() const override;
83 virtual ScSingleRefData* GetSingleRef() override;
84 virtual const ScComplexRefData* GetDoubleRef() const override;
85 virtual ScComplexRefData* GetDoubleRef() override;
86 virtual const ScSingleRefData* GetSingleRef2() const override;
87 virtual ScSingleRefData* GetSingleRef2() override;
88 virtual bool TextEqual( const formula::FormulaToken& rToken ) const override;
89 virtual bool operator==( const formula::FormulaToken& rToken ) const override;
90 virtual FormulaToken* Clone() const override { return new ScDoubleRefToken(*this); }
93 class ScMatrixToken final : public formula::FormulaToken
95 private:
96 ScMatrixRef pMatrix;
97 public:
98 ScMatrixToken( ScMatrixRef p );
99 ScMatrixToken( const ScMatrixToken& );
101 virtual const ScMatrix* GetMatrix() const override;
102 virtual ScMatrix* GetMatrix() override;
103 virtual bool operator==( const formula::FormulaToken& rToken ) const override;
104 virtual FormulaToken* Clone() const override { return new ScMatrixToken(*this); }
108 * Token storing matrix that represents values in sheet range. It stores
109 * both the values in matrix form, and the range address the matrix
110 * represents.
112 class ScMatrixRangeToken final : public formula::FormulaToken
114 ScMatrixRef mpMatrix;
115 ScComplexRefData maRef;
116 public:
117 ScMatrixRangeToken( const sc::RangeMatrix& rMat );
118 ScMatrixRangeToken( const ScMatrixRangeToken& );
120 virtual sal_uInt8 GetByte() const override;
121 virtual const ScMatrix* GetMatrix() const override;
122 virtual ScMatrix* GetMatrix() override;
123 virtual const ScComplexRefData* GetDoubleRef() const override;
124 virtual ScComplexRefData* GetDoubleRef() override;
125 virtual bool operator==( const formula::FormulaToken& rToken ) const override;
126 virtual FormulaToken* Clone() const override;
129 class ScExternalSingleRefToken final : public formula::FormulaToken
131 sal_uInt16 mnFileId;
132 svl::SharedString maTabName;
133 ScSingleRefData maSingleRef;
135 public:
136 ScExternalSingleRefToken( sal_uInt16 nFileId, svl::SharedString aTabName, const ScSingleRefData& r );
137 ScExternalSingleRefToken() = delete;
138 virtual ~ScExternalSingleRefToken() override;
140 ScExternalSingleRefToken(ScExternalSingleRefToken const &) = default;
141 ScExternalSingleRefToken(ScExternalSingleRefToken &&) = default;
142 ScExternalSingleRefToken & operator =(ScExternalSingleRefToken const &) = delete; // due to FormulaToken
143 ScExternalSingleRefToken & operator =(ScExternalSingleRefToken &&) = delete; // due to FormulaToken
145 virtual sal_uInt16 GetIndex() const override;
146 virtual const svl::SharedString & GetString() const override;
147 virtual const ScSingleRefData* GetSingleRef() const override;
148 virtual ScSingleRefData* GetSingleRef() override;
149 virtual bool operator==( const formula::FormulaToken& rToken ) const override;
150 virtual FormulaToken* Clone() const override { return new ScExternalSingleRefToken(*this); }
153 class ScExternalDoubleRefToken final : public formula::FormulaToken
155 sal_uInt16 mnFileId;
156 svl::SharedString maTabName; // name of the first sheet
157 ScComplexRefData maDoubleRef;
159 public:
160 ScExternalDoubleRefToken() = delete;
161 ScExternalDoubleRefToken( sal_uInt16 nFileId, svl::SharedString aTabName, const ScComplexRefData& r );
162 virtual ~ScExternalDoubleRefToken() override;
164 ScExternalDoubleRefToken(ScExternalDoubleRefToken const &) = default;
165 ScExternalDoubleRefToken(ScExternalDoubleRefToken &&) = default;
166 ScExternalDoubleRefToken & operator =(ScExternalDoubleRefToken const &) = delete; // due to FormulaToken
167 ScExternalDoubleRefToken & operator =(ScExternalDoubleRefToken &&) = delete; // due to FormulaToken
169 virtual sal_uInt16 GetIndex() const override;
170 virtual const svl::SharedString & GetString() const override;
171 virtual const ScSingleRefData* GetSingleRef() const override;
172 virtual ScSingleRefData* GetSingleRef() override;
173 virtual const ScSingleRefData* GetSingleRef2() const override;
174 virtual ScSingleRefData* GetSingleRef2() override;
175 virtual const ScComplexRefData* GetDoubleRef() const override;
176 virtual ScComplexRefData* GetDoubleRef() override;
177 virtual bool operator==( const formula::FormulaToken& rToken ) const override;
178 virtual FormulaToken* Clone() const override { return new ScExternalDoubleRefToken(*this); }
181 class ScExternalNameToken final : public formula::FormulaToken
183 sal_uInt16 mnFileId;
184 svl::SharedString maName;
186 public:
187 ScExternalNameToken() = delete;
188 ScExternalNameToken( sal_uInt16 nFileId, svl::SharedString aName );
189 virtual ~ScExternalNameToken() override;
191 ScExternalNameToken(ScExternalNameToken const &) = default;
192 ScExternalNameToken(ScExternalNameToken &&) = default;
193 ScExternalNameToken & operator =(ScExternalNameToken const &) = delete; // due to FormulaToken
194 ScExternalNameToken & operator =(ScExternalNameToken &&) = delete; // due to FormulaToken
196 virtual sal_uInt16 GetIndex() const override;
197 virtual const svl::SharedString & GetString() const override;
198 virtual bool operator==( const formula::FormulaToken& rToken ) const override;
199 virtual FormulaToken* Clone() const override { return new ScExternalNameToken(*this); }
202 /** Special token to remember details of ocTableRef "structured references". */
203 class ScTableRefToken final : public formula::FormulaToken
205 public:
207 enum Item
209 TABLE = 0,
210 ALL = 1,
211 HEADERS = 2,
212 DATA = 4,
213 TOTALS = 8,
214 THIS_ROW = 16,
215 HEADERS_DATA = HEADERS | DATA,
216 DATA_TOTALS = DATA | TOTALS
219 ScTableRefToken() = delete;
220 ScTableRefToken( sal_uInt16 nIndex, Item eItem );
221 ScTableRefToken( const ScTableRefToken& r );
222 virtual ~ScTableRefToken() override;
224 virtual sal_uInt16 GetIndex() const override;
225 virtual void SetIndex( sal_uInt16 n ) override;
226 virtual sal_Int16 GetSheet() const override;
227 virtual bool operator==( const formula::FormulaToken& rToken ) const override;
228 virtual FormulaToken* Clone() const override { return new ScTableRefToken(*this); }
230 Item GetItem() const;
231 void AddItem( Item );
232 void SetAreaRefRPN( formula::FormulaToken* pToken );
233 formula::FormulaToken* GetAreaRefRPN() const;
235 private:
237 formula::FormulaTokenRef mxAreaRefRPN; ///< resulting RPN area
238 sal_uInt16 mnIndex; ///< index into table / database range collection
239 Item meItem;
242 // Only created from within the interpreter, no conversion from ScRawToken,
243 // never added to ScTokenArray!
244 class ScJumpMatrixToken final : public formula::FormulaToken
246 private:
247 std::shared_ptr<ScJumpMatrix> mpJumpMatrix;
248 public:
249 ScJumpMatrixToken( std::shared_ptr<ScJumpMatrix> p );
250 ScJumpMatrixToken( const ScJumpMatrixToken & );
251 virtual ~ScJumpMatrixToken() override;
252 virtual ScJumpMatrix* GetJumpMatrix() const override;
253 virtual bool operator==( const formula::FormulaToken& rToken ) const override;
254 virtual FormulaToken* Clone() const override { return new ScJumpMatrixToken(*this); }
257 // Only created from within the interpreter, no conversion from ScRawToken,
258 // never added to ScTokenArray!
259 class ScRefListToken final : public formula::FormulaToken
261 private:
262 ScRefList aRefList;
263 bool mbArrayResult; // whether RefList is an array result
264 public:
265 ScRefListToken() :
266 FormulaToken( formula::svRefList ), mbArrayResult(false) {}
267 explicit ScRefListToken( bool bArrayResult ) :
268 FormulaToken( formula::svRefList ), mbArrayResult( bArrayResult ) {}
269 bool IsArrayResult() const;
270 virtual const ScRefList* GetRefList() const override;
271 virtual ScRefList* GetRefList() override;
272 virtual bool operator==( const formula::FormulaToken& rToken ) const override;
273 virtual FormulaToken* Clone() const override { return new ScRefListToken(*this); }
276 class ScEmptyCellToken final : public formula::FormulaToken
278 bool bInherited :1;
279 bool bDisplayedAsString :1;
280 public:
281 explicit ScEmptyCellToken( bool bInheritedP, bool bDisplayAsString ) :
282 FormulaToken( formula::svEmptyCell ),
283 bInherited( bInheritedP ),
284 bDisplayedAsString( bDisplayAsString ) {}
285 bool IsInherited() const { return bInherited; }
286 bool IsDisplayedAsString() const { return bDisplayedAsString; }
287 virtual double GetDouble() const override;
288 virtual const svl::SharedString & GetString() const override;
289 virtual bool operator==( const formula::FormulaToken& rToken ) const override;
290 virtual FormulaToken* Clone() const override { return new ScEmptyCellToken(*this); }
293 /** Transports the result from the interpreter to the formula cell. */
294 class ScMatrixCellResultToken : public formula::FormulaToken
296 // No non-const access implemented, silence down unxsols4 complaining about
297 // the public GetMatrix() hiding the one from FormulaToken.
298 virtual ScMatrix* GetMatrix() override;
300 protected:
301 ScConstMatrixRef xMatrix;
302 formula::FormulaConstTokenRef xUpperLeft;
303 public:
304 ScMatrixCellResultToken( ScConstMatrixRef pMat, const formula::FormulaToken* pUL );
305 ScMatrixCellResultToken( const ScMatrixCellResultToken& );
306 virtual ~ScMatrixCellResultToken() override;
307 virtual double GetDouble() const override;
308 virtual const svl::SharedString & GetString() const override;
309 virtual const ScMatrix* GetMatrix() const override;
310 virtual bool operator==( const formula::FormulaToken& rToken ) const override;
311 virtual FormulaToken* Clone() const override;
312 formula::StackVar GetUpperLeftType() const
314 return xUpperLeft ?
315 xUpperLeft->GetType() :
316 formula::svUnknown;
318 const formula::FormulaConstTokenRef& GetUpperLeftToken() const { return xUpperLeft; }
319 void Assign( const ScMatrixCellResultToken & r );
322 /** Stores the matrix result at the formula cell, additionally the range the
323 matrix formula occupies. */
324 class ScMatrixFormulaCellToken final : public ScMatrixCellResultToken
326 private:
327 SCROW nRows;
328 SCCOL nCols;
329 public:
330 ScMatrixFormulaCellToken( SCCOL nC, SCROW nR, const ScConstMatrixRef& pMat, const formula::FormulaToken* pUL );
331 ScMatrixFormulaCellToken( SCCOL nC, SCROW nR );
332 ScMatrixFormulaCellToken( const ScMatrixFormulaCellToken& r );
333 virtual ~ScMatrixFormulaCellToken() override;
335 virtual bool operator==( const formula::FormulaToken& rToken ) const override;
336 virtual FormulaToken* Clone() const override { return new ScMatrixFormulaCellToken(*this); }
337 void SetMatColsRows( SCCOL nC, SCROW nR )
339 nRows = nR;
340 nCols = nC;
342 void GetMatColsRows( SCCOL & nC, SCROW & nR ) const
344 nR = nRows;
345 nC = nCols;
347 SCCOL GetMatCols() const { return nCols; }
348 SCROW GetMatRows() const { return nRows; }
350 /** Assign matrix result, keep matrix formula
351 dimension. */
352 void Assign( const ScMatrixCellResultToken & r );
354 /** Assign any result, keep matrix formula
355 dimension. If token is of type
356 ScMatrixCellResultToken uses the
357 appropriate Assign() call, other tokens
358 are assigned to xUpperLeft and xMatrix will
359 be assigned NULL. */
360 void Assign( const formula::FormulaToken & r );
362 /** Modify xUpperLeft if formula::svDouble, or create
363 new formula::FormulaDoubleToken if not set yet. Does
364 nothing if xUpperLeft is of different type! */
365 void SetUpperLeftDouble( double f);
367 /** Reset matrix and upper left, keep matrix
368 formula dimension. */
369 void ResetResult();
371 private:
373 /** xUpperLeft is modifiable through SetUpperLeftDouble(), so clone it
374 whenever an svDouble token is assigned to. */
375 void CloneUpperLeftIfNecessary();
378 class ScHybridCellToken final : public formula::FormulaToken
380 private:
381 double mfDouble;
382 svl::SharedString maString;
383 OUString maFormula;
384 bool mbEmptyDisplayedAsString;
385 public:
386 ScHybridCellToken(
387 double f, const svl::SharedString & rStr, OUString aFormula, bool bEmptyDisplayedAsString );
389 const OUString& GetFormula() const { return maFormula; }
390 bool IsEmptyDisplayedAsString() const { return mbEmptyDisplayedAsString; }
391 virtual double GetDouble() const override;
393 virtual const svl::SharedString & GetString() const override;
394 virtual bool operator==( const formula::FormulaToken& rToken ) const override;
395 virtual FormulaToken* Clone() const override { return new ScHybridCellToken(*this); }
398 // Simplify argument passing to RefUpdate methods with ScSingleRefToken or
399 // ScDoubleRefToken
400 class SingleDoubleRefModifier
402 ScComplexRefData aDub;
403 ScSingleRefData* pS;
404 ScComplexRefData* pD;
406 SingleDoubleRefModifier( const SingleDoubleRefModifier& ) = delete;
407 SingleDoubleRefModifier& operator=( const SingleDoubleRefModifier& ) = delete;
409 public:
410 SingleDoubleRefModifier( formula::FormulaToken& rT )
412 formula::StackVar eType = rT.GetType();
413 if ( eType == formula::svSingleRef || eType == formula::svExternalSingleRef )
415 pS = rT.GetSingleRef();
416 aDub.Ref1 = aDub.Ref2 = *pS;
417 pD = &aDub;
419 else
421 pS = nullptr;
422 pD = rT.GetDoubleRef();
423 // coverity[uninit_member] - aDub intentionally not initialized, unnecessary because unused.
426 SingleDoubleRefModifier( ScSingleRefData& rS )
428 pS = &rS;
429 aDub.Ref1 = aDub.Ref2 = *pS;
430 pD = &aDub;
432 ~SingleDoubleRefModifier()
434 if ( pS )
435 *pS = (*pD).Ref1;
437 ScComplexRefData& Ref() { return *pD; }
440 class SingleDoubleRefProvider
442 public:
444 const ScSingleRefData& Ref1;
445 const ScSingleRefData& Ref2;
447 SingleDoubleRefProvider( const formula::FormulaToken& r )
448 : Ref1( *r.GetSingleRef() ),
449 Ref2( (r.GetType() == formula::svDoubleRef ||
450 r.GetType() == formula::svExternalDoubleRef) ?
451 r.GetDoubleRef()->Ref2 : Ref1 )
455 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */