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/.
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 #ifndef INCLUDED_SC_INC_TOKEN_HXX
21 #define INCLUDED_SC_INC_TOKEN_HXX
26 #include <formula/opcode.hxx>
27 #include "refdata.hxx"
29 #include <formula/token.hxx>
30 #include "calcmacros.hxx"
33 // Matrix token constants.
34 #define MATRIX_TOKEN_HAS_RANGE 1
39 typedef ::std::vector
< ScComplexRefData
> ScRefList
;
41 #if DEBUG_FORMULA_COMPILER
42 void DumpToken(formula::FormulaToken
const & rToken
);
45 /** If rTok1 and rTok2 both are SingleRef or DoubleRef tokens, extend/merge
46 ranges as needed for ocRange.
48 The formula's position, used to calculate absolute positions from
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.
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( formula::FormulaToken
& rTok1
, formula::FormulaToken
& rTok2
, const ScAddress
& rPos
, bool bReuseDoubleRef
);
59 class ScSingleRefToken final
: public formula::FormulaToken
62 ScSingleRefData aSingleRef
;
64 ScSingleRefToken( const ScSingleRefData
& r
, OpCode e
= ocPush
) :
65 FormulaToken( formula::svSingleRef
, e
), aSingleRef( r
) {}
66 virtual const ScSingleRefData
* GetSingleRef() const override
;
67 virtual ScSingleRefData
* GetSingleRef() override
;
68 virtual bool TextEqual( const formula::FormulaToken
& rToken
) const override
;
69 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
70 virtual FormulaToken
* Clone() const override
{ return new ScSingleRefToken(*this); }
73 class ScDoubleRefToken final
: public formula::FormulaToken
76 ScComplexRefData aDoubleRef
;
78 ScDoubleRefToken( const ScComplexRefData
& r
, OpCode e
= ocPush
) :
79 FormulaToken( formula::svDoubleRef
, e
), aDoubleRef( r
) {}
80 virtual const ScSingleRefData
* GetSingleRef() const override
;
81 virtual ScSingleRefData
* GetSingleRef() override
;
82 virtual const ScComplexRefData
* GetDoubleRef() const override
;
83 virtual ScComplexRefData
* GetDoubleRef() override
;
84 virtual const ScSingleRefData
* GetSingleRef2() const override
;
85 virtual ScSingleRefData
* GetSingleRef2() override
;
86 virtual bool TextEqual( const formula::FormulaToken
& rToken
) const override
;
87 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
88 virtual FormulaToken
* Clone() const override
{ return new ScDoubleRefToken(*this); }
91 class ScMatrixToken final
: public formula::FormulaToken
94 ScMatrixRef
const pMatrix
;
96 ScMatrixToken( const ScMatrixRef
& p
);
97 ScMatrixToken( const ScMatrixToken
& );
99 virtual const ScMatrix
* GetMatrix() const override
;
100 virtual ScMatrix
* GetMatrix() override
;
101 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
102 virtual FormulaToken
* Clone() const override
{ return new ScMatrixToken(*this); }
106 * Token storing matrix that represents values in sheet range. It stores
107 * both the values in matrix form, and the range address the matrix
110 class ScMatrixRangeToken final
: public formula::FormulaToken
112 ScMatrixRef
const mpMatrix
;
113 ScComplexRefData maRef
;
115 ScMatrixRangeToken( const sc::RangeMatrix
& rMat
);
116 ScMatrixRangeToken( const ScMatrixRangeToken
& );
118 virtual sal_uInt8
GetByte() const override
;
119 virtual const ScMatrix
* GetMatrix() const override
;
120 virtual ScMatrix
* GetMatrix() override
;
121 virtual const ScComplexRefData
* GetDoubleRef() const override
;
122 virtual ScComplexRefData
* GetDoubleRef() override
;
123 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
124 virtual FormulaToken
* Clone() const override
;
127 class ScExternalSingleRefToken final
: public formula::FormulaToken
129 sal_uInt16
const mnFileId
;
130 svl::SharedString
const maTabName
;
131 ScSingleRefData maSingleRef
;
134 ScExternalSingleRefToken( sal_uInt16 nFileId
, const svl::SharedString
& rTabName
, const ScSingleRefData
& r
);
135 ScExternalSingleRefToken() = delete;
136 virtual ~ScExternalSingleRefToken() override
;
138 ScExternalSingleRefToken(ScExternalSingleRefToken
const &) = default;
139 ScExternalSingleRefToken(ScExternalSingleRefToken
&&) = default;
140 ScExternalSingleRefToken
& operator =(ScExternalSingleRefToken
const &) = delete; // due to FormulaToken
141 ScExternalSingleRefToken
& operator =(ScExternalSingleRefToken
&&) = delete; // due to FormulaToken
143 virtual sal_uInt16
GetIndex() const override
;
144 virtual svl::SharedString
GetString() const override
;
145 virtual const ScSingleRefData
* GetSingleRef() const override
;
146 virtual ScSingleRefData
* GetSingleRef() override
;
147 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
148 virtual FormulaToken
* Clone() const override
{ return new ScExternalSingleRefToken(*this); }
151 class ScExternalDoubleRefToken final
: public formula::FormulaToken
153 sal_uInt16
const mnFileId
;
154 svl::SharedString
const maTabName
; // name of the first sheet
155 ScComplexRefData maDoubleRef
;
158 ScExternalDoubleRefToken() = delete;
159 ScExternalDoubleRefToken( sal_uInt16 nFileId
, const svl::SharedString
& rTabName
, const ScComplexRefData
& r
);
160 virtual ~ScExternalDoubleRefToken() override
;
162 ScExternalDoubleRefToken(ScExternalDoubleRefToken
const &) = default;
163 ScExternalDoubleRefToken(ScExternalDoubleRefToken
&&) = default;
164 ScExternalDoubleRefToken
& operator =(ScExternalDoubleRefToken
const &) = delete; // due to FormulaToken
165 ScExternalDoubleRefToken
& operator =(ScExternalDoubleRefToken
&&) = delete; // due to FormulaToken
167 virtual sal_uInt16
GetIndex() const override
;
168 virtual svl::SharedString
GetString() const override
;
169 virtual const ScSingleRefData
* GetSingleRef() const override
;
170 virtual ScSingleRefData
* GetSingleRef() override
;
171 virtual const ScSingleRefData
* GetSingleRef2() const override
;
172 virtual ScSingleRefData
* GetSingleRef2() override
;
173 virtual const ScComplexRefData
* GetDoubleRef() const override
;
174 virtual ScComplexRefData
* GetDoubleRef() override
;
175 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
176 virtual FormulaToken
* Clone() const override
{ return new ScExternalDoubleRefToken(*this); }
179 class ScExternalNameToken final
: public formula::FormulaToken
181 sal_uInt16
const mnFileId
;
182 svl::SharedString
const maName
;
185 ScExternalNameToken() = delete;
186 ScExternalNameToken( sal_uInt16 nFileId
, const svl::SharedString
& rName
);
187 virtual ~ScExternalNameToken() override
;
189 ScExternalNameToken(ScExternalNameToken
const &) = default;
190 ScExternalNameToken(ScExternalNameToken
&&) = default;
191 ScExternalNameToken
& operator =(ScExternalNameToken
const &) = delete; // due to FormulaToken
192 ScExternalNameToken
& operator =(ScExternalNameToken
&&) = delete; // due to FormulaToken
194 virtual sal_uInt16
GetIndex() const override
;
195 virtual svl::SharedString
GetString() const override
;
196 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
197 virtual FormulaToken
* Clone() const override
{ return new ScExternalNameToken(*this); }
200 /** Special token to remember details of ocTableRef "structured references". */
201 class ScTableRefToken final
: public formula::FormulaToken
213 HEADERS_DATA
= HEADERS
| DATA
,
214 DATA_TOTALS
= DATA
| TOTALS
217 ScTableRefToken() = delete;
218 ScTableRefToken( sal_uInt16 nIndex
, Item eItem
);
219 ScTableRefToken( const ScTableRefToken
& r
);
220 virtual ~ScTableRefToken() override
;
222 virtual sal_uInt16
GetIndex() const override
;
223 virtual void SetIndex( sal_uInt16 n
) override
;
224 virtual sal_Int16
GetSheet() const override
;
225 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
226 virtual FormulaToken
* Clone() const override
{ return new ScTableRefToken(*this); }
228 Item
GetItem() const;
229 void AddItem( Item
);
230 void SetAreaRefRPN( formula::FormulaToken
* pToken
);
231 formula::FormulaToken
* GetAreaRefRPN() const;
235 formula::FormulaTokenRef mxAreaRefRPN
; ///< resulting RPN area
236 sal_uInt16 mnIndex
; ///< index into table / database range collection
240 // Only created from within the interpreter, no conversion from ScRawToken,
241 // never added to ScTokenArray!
242 class ScJumpMatrixToken final
: public formula::FormulaToken
245 std::shared_ptr
<ScJumpMatrix
> mpJumpMatrix
;
247 ScJumpMatrixToken( std::shared_ptr
<ScJumpMatrix
> p
);
248 ScJumpMatrixToken( const ScJumpMatrixToken
& );
249 virtual ~ScJumpMatrixToken() override
;
250 virtual ScJumpMatrix
* GetJumpMatrix() const override
;
251 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
252 virtual FormulaToken
* Clone() const override
{ return new ScJumpMatrixToken(*this); }
255 // Only created from within the interpreter, no conversion from ScRawToken,
256 // never added to ScTokenArray!
257 class ScRefListToken final
: public formula::FormulaToken
261 bool const mbArrayResult
; // whether RefList is an array result
264 FormulaToken( formula::svRefList
), mbArrayResult(false) {}
265 explicit ScRefListToken( bool bArrayResult
) :
266 FormulaToken( formula::svRefList
), mbArrayResult( bArrayResult
) {}
267 bool IsArrayResult() const;
268 virtual const ScRefList
* GetRefList() const override
;
269 virtual ScRefList
* GetRefList() override
;
270 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
271 virtual FormulaToken
* Clone() const override
{ return new ScRefListToken(*this); }
274 class ScEmptyCellToken final
: public formula::FormulaToken
276 bool const bInherited
:1;
277 bool const bDisplayedAsString
:1;
279 explicit ScEmptyCellToken( bool bInheritedP
, bool bDisplayAsString
) :
280 FormulaToken( formula::svEmptyCell
),
281 bInherited( bInheritedP
),
282 bDisplayedAsString( bDisplayAsString
) {}
283 bool IsInherited() const { return bInherited
; }
284 bool IsDisplayedAsString() const { return bDisplayedAsString
; }
285 virtual double GetDouble() const override
;
286 virtual svl::SharedString
GetString() const override
;
287 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
288 virtual FormulaToken
* Clone() const override
{ return new ScEmptyCellToken(*this); }
291 /** Transports the result from the interpreter to the formula cell. */
292 class ScMatrixCellResultToken
: public formula::FormulaToken
294 // No non-const access implemented, silence down unxsols4 complaining about
295 // the public GetMatrix() hiding the one from FormulaToken.
296 virtual ScMatrix
* GetMatrix() override
;
299 ScConstMatrixRef xMatrix
;
300 formula::FormulaConstTokenRef xUpperLeft
;
302 ScMatrixCellResultToken( const ScConstMatrixRef
& pMat
, const formula::FormulaToken
* pUL
);
303 ScMatrixCellResultToken( const ScMatrixCellResultToken
& );
304 virtual ~ScMatrixCellResultToken() override
;
305 virtual double GetDouble() const override
;
306 virtual svl::SharedString
GetString() const override
;
307 virtual const ScMatrix
* GetMatrix() const override
;
308 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
309 virtual FormulaToken
* Clone() const override
;
310 formula::StackVar
GetUpperLeftType() const
313 xUpperLeft
->GetType() :
316 const formula::FormulaConstTokenRef
& GetUpperLeftToken() const { return xUpperLeft
; }
317 void Assign( const ScMatrixCellResultToken
& r
);
320 /** Stores the matrix result at the formula cell, additionally the range the
321 matrix formula occupies. */
322 class ScMatrixFormulaCellToken final
: public ScMatrixCellResultToken
328 ScMatrixFormulaCellToken( SCCOL nC
, SCROW nR
, const ScConstMatrixRef
& pMat
, const formula::FormulaToken
* pUL
);
329 ScMatrixFormulaCellToken( SCCOL nC
, SCROW nR
);
330 ScMatrixFormulaCellToken( const ScMatrixFormulaCellToken
& r
);
331 virtual ~ScMatrixFormulaCellToken() override
;
333 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
334 virtual FormulaToken
* Clone() const override
{ return new ScMatrixFormulaCellToken(*this); }
335 void SetMatColsRows( SCCOL nC
, SCROW nR
)
340 void GetMatColsRows( SCCOL
& nC
, SCROW
& nR
) const
345 SCCOL
GetMatCols() const { return nCols
; }
346 SCROW
GetMatRows() const { return nRows
; }
348 /** Assign matrix result, keep matrix formula
350 void Assign( const ScMatrixCellResultToken
& r
);
352 /** Assign any result, keep matrix formula
353 dimension. If token is of type
354 ScMatrixCellResultToken uses the
355 appropriate Assign() call, other tokens
356 are assigned to xUpperLeft and xMatrix will
358 void Assign( const formula::FormulaToken
& r
);
360 /** Modify xUpperLeft if formula::svDouble, or create
361 new formula::FormulaDoubleToken if not set yet. Does
362 nothing if xUpperLeft is of different type! */
363 void SetUpperLeftDouble( double f
);
365 /** Reset matrix and upper left, keep matrix
366 formula dimension. */
371 /** xUpperLeft is modifiable through SetUpperLeftDouble(), so clone it
372 whenever an svDouble token is assigned to. */
373 void CloneUpperLeftIfNecessary();
376 class ScHybridCellToken final
: public formula::FormulaToken
379 double const mfDouble
;
380 svl::SharedString
const maString
;
381 OUString
const maFormula
;
382 bool const mbEmptyDisplayedAsString
;
385 double f
, const svl::SharedString
& rStr
, const OUString
& rFormula
, bool bEmptyDisplayedAsString
);
387 const OUString
& GetFormula() const { return maFormula
; }
388 bool IsEmptyDisplayedAsString() const { return mbEmptyDisplayedAsString
; }
389 virtual double GetDouble() const override
;
391 virtual svl::SharedString
GetString() const override
;
392 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
393 virtual FormulaToken
* Clone() const override
{ return new ScHybridCellToken(*this); }
396 // Simplify argument passing to RefUpdate methods with ScSingleRefToken or
398 class SingleDoubleRefModifier
400 ScComplexRefData aDub
;
402 ScComplexRefData
* pD
;
404 SingleDoubleRefModifier( const SingleDoubleRefModifier
& ) = delete;
405 SingleDoubleRefModifier
& operator=( const SingleDoubleRefModifier
& ) = delete;
408 SingleDoubleRefModifier( formula::FormulaToken
& rT
)
410 formula::StackVar eType
= rT
.GetType();
411 if ( eType
== formula::svSingleRef
|| eType
== formula::svExternalSingleRef
)
413 pS
= rT
.GetSingleRef();
414 aDub
.Ref1
= aDub
.Ref2
= *pS
;
420 pD
= rT
.GetDoubleRef();
421 // aDub intentionally not initialized, unnecessary
425 SingleDoubleRefModifier( ScSingleRefData
& rS
)
428 aDub
.Ref1
= aDub
.Ref2
= *pS
;
431 ~SingleDoubleRefModifier()
436 ScComplexRefData
& Ref() { return *pD
; }
439 class SingleDoubleRefProvider
443 const ScSingleRefData
& Ref1
;
444 const ScSingleRefData
& Ref2
;
446 SingleDoubleRefProvider( const formula::FormulaToken
& r
)
447 : Ref1( *r
.GetSingleRef() ),
448 Ref2( (r
.GetType() == formula::svDoubleRef
||
449 r
.GetType() == formula::svExternalDoubleRef
) ?
450 r
.GetDoubleRef()->Ref2
: Ref1
)
456 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */