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
24 #include <boost/intrusive_ptr.hpp>
26 #include <formula/opcode.hxx>
27 #include "refdata.hxx"
28 #include <tools/mempool.hxx>
30 #include <formula/IFunctionDescription.hxx>
31 #include <formula/token.hxx>
32 #include "calcmacros.hxx"
35 // Matrix token constants.
36 #define MATRIX_TOKEN_HAS_RANGE 1
47 typedef ::std::vector
< ScComplexRefData
> ScRefList
;
49 #if DEBUG_FORMULA_COMPILER
50 void DumpToken(formula::FormulaToken
const & rToken
);
53 /** If rTok1 and rTok2 both are SingleRef or DoubleRef tokens, extend/merge
54 ranges as needed for ocRange.
56 The formula's position, used to calculate absolute positions from
58 @param bReuseDoubleRef
59 If true, a DoubleRef token is reused if passed as rTok1 or rTok2,
60 else a new DoubleRef token is created and returned.
62 A reused or new'ed ScDoubleRefToken, or a NULL TokenRef if rTok1 or
63 rTok2 are not of sv(Single|Double)Ref
65 formula::FormulaTokenRef
extendRangeReference( formula::FormulaToken
& rTok1
, formula::FormulaToken
& rTok2
, const ScAddress
& rPos
, bool bReuseDoubleRef
);
67 class ScSingleRefToken
: public formula::FormulaToken
70 ScSingleRefData aSingleRef
;
72 ScSingleRefToken( const ScSingleRefData
& r
, OpCode e
= ocPush
) :
73 FormulaToken( formula::svSingleRef
, e
), aSingleRef( r
) {}
74 ScSingleRefToken( const ScSingleRefToken
& r
) :
75 FormulaToken( r
), aSingleRef( r
.aSingleRef
) {}
76 virtual const ScSingleRefData
* GetSingleRef() const SAL_OVERRIDE
;
77 virtual ScSingleRefData
* GetSingleRef() SAL_OVERRIDE
;
78 virtual bool TextEqual( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
79 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
80 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScSingleRefToken(*this); }
82 DECL_FIXEDMEMPOOL_NEWDEL( ScSingleRefToken
);
85 class ScDoubleRefToken
: public formula::FormulaToken
88 ScComplexRefData aDoubleRef
;
90 ScDoubleRefToken( const ScComplexRefData
& r
, OpCode e
= ocPush
) :
91 FormulaToken( formula::svDoubleRef
, e
), aDoubleRef( r
) {}
92 ScDoubleRefToken( const ScSingleRefData
& r
, OpCode e
= ocPush
) :
93 FormulaToken( formula::svDoubleRef
, e
)
98 ScDoubleRefToken( const ScDoubleRefToken
& r
) :
99 FormulaToken( r
), aDoubleRef( r
.aDoubleRef
) {}
100 virtual const ScSingleRefData
* GetSingleRef() const SAL_OVERRIDE
;
101 virtual ScSingleRefData
* GetSingleRef() SAL_OVERRIDE
;
102 virtual const ScComplexRefData
* GetDoubleRef() const SAL_OVERRIDE
;
103 virtual ScComplexRefData
* GetDoubleRef() SAL_OVERRIDE
;
104 virtual const ScSingleRefData
* GetSingleRef2() const SAL_OVERRIDE
;
105 virtual ScSingleRefData
* GetSingleRef2() SAL_OVERRIDE
;
106 virtual bool TextEqual( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
107 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
108 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScDoubleRefToken(*this); }
110 DECL_FIXEDMEMPOOL_NEWDEL( ScDoubleRefToken
);
113 class ScMatrixToken
: public formula::FormulaToken
118 ScMatrixToken( const ScMatrixRef
& p
);
119 ScMatrixToken( const ScMatrixToken
& r
);
121 virtual const ScMatrix
* GetMatrix() const SAL_OVERRIDE
;
122 virtual ScMatrix
* GetMatrix() SAL_OVERRIDE
;
123 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
124 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScMatrixToken(*this); }
128 * Token storing matrix that represents values in sheet range. It stores
129 * both the values in matrix form, and the range address the matrix
132 class ScMatrixRangeToken
: public formula::FormulaToken
134 ScMatrixRef mpMatrix
;
135 ScComplexRefData maRef
;
137 ScMatrixRangeToken( const ScMatrixRef
& p
, const ScComplexRefData
& rRef
);
138 ScMatrixRangeToken( const sc::RangeMatrix
& rMat
);
139 ScMatrixRangeToken( const ScMatrixRangeToken
& r
);
141 virtual sal_uInt8
GetByte() const SAL_OVERRIDE
;
142 virtual const ScMatrix
* GetMatrix() const SAL_OVERRIDE
;
143 virtual ScMatrix
* GetMatrix() SAL_OVERRIDE
;
144 virtual const ScComplexRefData
* GetDoubleRef() const SAL_OVERRIDE
;
145 virtual ScComplexRefData
* GetDoubleRef() SAL_OVERRIDE
;
146 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
147 virtual FormulaToken
* Clone() const SAL_OVERRIDE
;
150 class ScExternalSingleRefToken
: public formula::FormulaToken
153 svl::SharedString maTabName
;
154 ScSingleRefData maSingleRef
;
156 ScExternalSingleRefToken(); // disabled
158 ScExternalSingleRefToken( sal_uInt16 nFileId
, const svl::SharedString
& rTabName
, const ScSingleRefData
& r
);
159 ScExternalSingleRefToken( const ScExternalSingleRefToken
& r
);
160 virtual ~ScExternalSingleRefToken();
162 virtual sal_uInt16
GetIndex() const SAL_OVERRIDE
;
163 virtual svl::SharedString
GetString() const SAL_OVERRIDE
;
164 virtual const ScSingleRefData
* GetSingleRef() const SAL_OVERRIDE
;
165 virtual ScSingleRefData
* GetSingleRef() SAL_OVERRIDE
;
166 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
167 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScExternalSingleRefToken(*this); }
170 class ScExternalDoubleRefToken
: public formula::FormulaToken
173 svl::SharedString maTabName
; // name of the first sheet
174 ScComplexRefData maDoubleRef
;
176 ScExternalDoubleRefToken(); // disabled
178 ScExternalDoubleRefToken( sal_uInt16 nFileId
, const svl::SharedString
& rTabName
, const ScComplexRefData
& r
);
179 ScExternalDoubleRefToken( const ScExternalDoubleRefToken
& r
);
180 virtual ~ScExternalDoubleRefToken();
182 virtual sal_uInt16
GetIndex() const SAL_OVERRIDE
;
183 virtual svl::SharedString
GetString() const SAL_OVERRIDE
;
184 virtual const ScSingleRefData
* GetSingleRef() const SAL_OVERRIDE
;
185 virtual ScSingleRefData
* GetSingleRef() SAL_OVERRIDE
;
186 virtual const ScSingleRefData
* GetSingleRef2() const SAL_OVERRIDE
;
187 virtual ScSingleRefData
* GetSingleRef2() SAL_OVERRIDE
;
188 virtual const ScComplexRefData
* GetDoubleRef() const SAL_OVERRIDE
;
189 virtual ScComplexRefData
* GetDoubleRef() SAL_OVERRIDE
;
190 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
191 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScExternalDoubleRefToken(*this); }
194 class ScExternalNameToken
: public formula::FormulaToken
197 svl::SharedString maName
;
199 ScExternalNameToken(); // disabled
201 ScExternalNameToken( sal_uInt16 nFileId
, const svl::SharedString
& rName
);
202 ScExternalNameToken( const ScExternalNameToken
& r
);
203 virtual ~ScExternalNameToken();
205 virtual sal_uInt16
GetIndex() const SAL_OVERRIDE
;
206 virtual svl::SharedString
GetString() const SAL_OVERRIDE
;
207 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
208 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScExternalNameToken(*this); }
211 /** Special token to remember details of ocTableRef "structured references". */
212 class ScTableRefToken
: public formula::FormulaToken
224 HEADERS_DATA
= HEADERS
| DATA
,
225 DATA_TOTALS
= DATA
| TOTALS
228 ScTableRefToken( sal_uInt16 nIndex
, Item eItem
);
229 ScTableRefToken( const ScTableRefToken
& r
);
230 virtual ~ScTableRefToken();
232 virtual sal_uInt16
GetIndex() const SAL_OVERRIDE
;
233 virtual void SetIndex( sal_uInt16 n
) SAL_OVERRIDE
;
234 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
235 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScTableRefToken(*this); }
237 Item
GetItem() const;
238 void AddItem( Item
);
239 void SetAreaRefRPN( formula::FormulaToken
* pToken
);
240 formula::FormulaToken
* GetAreaRefRPN() const;
244 formula::FormulaTokenRef mxAreaRefRPN
; ///< resulting RPN area
245 sal_uInt16 mnIndex
; ///< index into table / database range collection
248 ScTableRefToken(); // disabled
252 // Only created from within the interpreter, no conversion from ScRawToken,
253 // never added to ScTokenArray!
254 class ScJumpMatrixToken
: public formula::FormulaToken
257 ScJumpMatrix
* pJumpMatrix
;
259 ScJumpMatrixToken( ScJumpMatrix
* p
) :
260 FormulaToken( formula::svJumpMatrix
), pJumpMatrix( p
) {}
261 ScJumpMatrixToken( const ScJumpMatrixToken
& r
) :
262 FormulaToken( r
), pJumpMatrix( r
.pJumpMatrix
) {}
263 virtual ~ScJumpMatrixToken();
264 virtual ScJumpMatrix
* GetJumpMatrix() const SAL_OVERRIDE
;
265 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
266 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScJumpMatrixToken(*this); }
269 // Only created from within the interpreter, no conversion from ScRawToken,
270 // never added to ScTokenArray!
271 class ScRefListToken
: public formula::FormulaToken
277 FormulaToken( formula::svRefList
) {}
278 ScRefListToken( const ScRefListToken
& r
) :
279 FormulaToken( r
), aRefList( r
.aRefList
) {}
280 virtual const ScRefList
* GetRefList() const SAL_OVERRIDE
;
281 virtual ScRefList
* GetRefList() SAL_OVERRIDE
;
282 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
283 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScRefListToken(*this); }
286 class SC_DLLPUBLIC ScEmptyCellToken
: public formula::FormulaToken
289 bool bDisplayedAsString
:1;
291 explicit ScEmptyCellToken( bool bInheritedP
, bool bDisplayAsString
) :
292 FormulaToken( formula::svEmptyCell
),
293 bInherited( bInheritedP
),
294 bDisplayedAsString( bDisplayAsString
) {}
295 ScEmptyCellToken( const ScEmptyCellToken
& r
) :
297 bInherited( r
.bInherited
),
298 bDisplayedAsString( r
.bDisplayedAsString
) {}
299 bool IsInherited() const { return bInherited
; }
300 bool IsDisplayedAsString() const { return bDisplayedAsString
; }
301 virtual double GetDouble() const SAL_OVERRIDE
;
302 virtual svl::SharedString
GetString() const SAL_OVERRIDE
;
303 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
304 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScEmptyCellToken(*this); }
307 /** Transports the result from the interpreter to the formula cell. */
308 class SC_DLLPUBLIC ScMatrixCellResultToken
: public formula::FormulaToken
310 // No non-const access implemented, silence down unxsols4 complaining about
311 // the public GetMatrix() hiding the one from FormulaToken.
312 virtual ScMatrix
* GetMatrix() SAL_OVERRIDE
;
315 ScConstMatrixRef xMatrix
;
316 formula::FormulaConstTokenRef xUpperLeft
;
318 ScMatrixCellResultToken( const ScConstMatrixRef
& pMat
, formula::FormulaToken
* pUL
);
319 ScMatrixCellResultToken( const ScMatrixCellResultToken
& r
);
320 virtual ~ScMatrixCellResultToken();
321 virtual double GetDouble() const SAL_OVERRIDE
;
322 virtual svl::SharedString
GetString() const SAL_OVERRIDE
;
323 virtual const ScMatrix
* GetMatrix() const SAL_OVERRIDE
;
324 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
325 virtual FormulaToken
* Clone() const SAL_OVERRIDE
;
326 formula::StackVar
GetUpperLeftType() const
329 xUpperLeft
->GetType() :
330 static_cast<formula::StackVar
>(formula::svUnknown
);
332 inline formula::FormulaConstTokenRef
GetUpperLeftToken() const { return xUpperLeft
; }
333 void Assign( const ScMatrixCellResultToken
& r
);
336 /** Stores the matrix result at the formula cell, additionally the range the
337 matrix formula occupies. */
338 class SC_DLLPUBLIC ScMatrixFormulaCellToken
: public ScMatrixCellResultToken
344 ScMatrixFormulaCellToken( SCCOL nC
, SCROW nR
, const ScConstMatrixRef
& pMat
, formula::FormulaToken
* pUL
);
345 ScMatrixFormulaCellToken( SCCOL nC
, SCROW nR
);
346 ScMatrixFormulaCellToken( const ScMatrixFormulaCellToken
& r
);
347 virtual ~ScMatrixFormulaCellToken();
349 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
350 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScMatrixFormulaCellToken(*this); }
351 void SetMatColsRows( SCCOL nC
, SCROW nR
)
356 void GetMatColsRows( SCCOL
& nC
, SCROW
& nR
) const
361 SCCOL
GetMatCols() const { return nCols
; }
362 SCROW
GetMatRows() const { return nRows
; }
364 /** Assign matrix result, keep matrix formula
366 void Assign( const ScMatrixCellResultToken
& r
);
368 /** Assign any result, keep matrix formula
369 dimension. If token is of type
370 ScMatrixCellResultToken uses the
371 appropriate Assign() call, other tokens
372 are assigned to xUpperLeft and xMatrix will
374 void Assign( const formula::FormulaToken
& r
);
376 /** Modify xUpperLeft if formula::svDouble, or create
377 new formula::FormulaDoubleToken if not set yet. Does
378 nothing if xUpperLeft is of different type! */
379 void SetUpperLeftDouble( double f
);
381 /** Reset matrix and upper left, keep matrix
382 formula dimension. */
387 /** xUpperLeft is modifiable through SetUpperLeftDouble(), so clone it
388 whenever an svDouble token is assigned to. */
389 void CloneUpperLeftIfNecessary();
392 class SC_DLLPUBLIC ScHybridCellToken
: public formula::FormulaToken
396 svl::SharedString maString
;
400 double f
, const svl::SharedString
& rStr
, const OUString
& rFormula
);
402 const OUString
& GetFormula() const { return maFormula
; }
403 virtual double GetDouble() const SAL_OVERRIDE
;
405 virtual svl::SharedString
GetString() const SAL_OVERRIDE
;
406 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
407 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScHybridCellToken(*this); }
410 // Simplify argument passing to RefUpdate methods with ScSingleRefToken or
412 class SingleDoubleRefModifier
414 ScComplexRefData aDub
;
416 ScComplexRefData
* pD
;
418 SingleDoubleRefModifier( const SingleDoubleRefModifier
& ) SAL_DELETED_FUNCTION
;
419 SingleDoubleRefModifier
& operator=( const SingleDoubleRefModifier
& ) SAL_DELETED_FUNCTION
;
422 SingleDoubleRefModifier( formula::FormulaToken
& rT
)
424 formula::StackVar eType
= rT
.GetType();
425 if ( eType
== formula::svSingleRef
|| eType
== formula::svExternalSingleRef
)
427 pS
= rT
.GetSingleRef();
428 aDub
.Ref1
= aDub
.Ref2
= *pS
;
434 pD
= rT
.GetDoubleRef();
435 // aDub intentionally not initialized, unnecessary
439 SingleDoubleRefModifier( ScSingleRefData
& rS
)
442 aDub
.Ref1
= aDub
.Ref2
= *pS
;
445 ~SingleDoubleRefModifier()
450 inline ScComplexRefData
& Ref() { return *pD
; }
453 class SingleDoubleRefProvider
457 const ScSingleRefData
& Ref1
;
458 const ScSingleRefData
& Ref2
;
460 SingleDoubleRefProvider( const formula::FormulaToken
& r
)
461 : Ref1( *r
.GetSingleRef() ),
462 Ref2( (r
.GetType() == formula::svDoubleRef
||
463 r
.GetType() == formula::svExternalDoubleRef
) ?
464 r
.GetDoubleRef()->Ref2
: Ref1
)
466 SingleDoubleRefProvider( const ScSingleRefData
& r
)
467 : Ref1( r
), Ref2( r
)
469 SingleDoubleRefProvider( const ScComplexRefData
& r
)
470 : Ref1( r
.Ref1
), Ref2( r
.Ref2
)
472 ~SingleDoubleRefProvider()
478 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */