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 "scmatrix.hxx"
33 #include "calcmacros.hxx"
35 // Matrix token constants.
36 #define MATRIX_TOKEN_HAS_RANGE 1
46 typedef ::std::vector
< ScComplexRefData
> ScRefList
;
48 class SC_DLLPUBLIC ScToken
: public formula::FormulaToken
51 // not implemented, prevent usage
53 ScToken
& operator=( const ScToken
& );
57 ScToken( formula::StackVar eTypeP
,OpCode e
= ocPush
) : formula::FormulaToken(eTypeP
,e
) {}
58 ScToken( const ScToken
& r
): formula::FormulaToken(r
) {}
65 Dummy methods to avoid switches and casts where possible,
66 the real token classes have to overload the appropriate method[s].
67 The only methods valid anytime if not overloaded are:
69 - GetByte() since this represents the count of parameters to a function
70 which of course is 0 on non-functions. formula::FormulaByteToken and ScExternal do
73 - HasForceArray() since also this is only used for operators and
74 functions and is 0 for other tokens.
76 Any other non-overloaded method pops up an assertion.
79 virtual const ScSingleRefData
& GetSingleRef() const;
80 virtual ScSingleRefData
& GetSingleRef();
81 virtual const ScComplexRefData
& GetDoubleRef() const;
82 virtual ScComplexRefData
& GetDoubleRef();
83 virtual const ScSingleRefData
& GetSingleRef2() const;
84 virtual ScSingleRefData
& GetSingleRef2();
85 virtual const ScMatrix
* GetMatrix() const;
86 virtual ScMatrix
* GetMatrix();
87 virtual ScJumpMatrix
* GetJumpMatrix() const;
88 virtual const ScRefList
* GetRefList() const;
89 virtual ScRefList
* GetRefList();
91 virtual bool TextEqual( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
92 virtual bool Is3DRef() const SAL_OVERRIDE
; // reference with 3D flag set
94 #if DEBUG_FORMULA_COMPILER
95 virtual void Dump() const;
98 /** If rTok1 and rTok2 both are SingleRef or DoubleRef tokens, extend/merge
99 ranges as needed for ocRange.
101 The formula's position, used to calculate absolute positions from
103 @param bReuseDoubleRef
104 If true, a DoubleRef token is reused if passed as rTok1 or rTok2,
105 else a new DoubleRef token is created and returned.
107 A reused or new'ed ScDoubleRefToken, or a NULL TokenRef if rTok1 or
108 rTok2 are not of sv(Single|Double)Ref
110 static formula::FormulaTokenRef
ExtendRangeReference( formula::FormulaToken
& rTok1
, formula::FormulaToken
& rTok2
, const ScAddress
& rPos
, bool bReuseDoubleRef
);
113 inline void intrusive_ptr_add_ref(const ScToken
* p
)
118 inline void intrusive_ptr_release(const ScToken
* p
)
123 class ScSingleRefToken
: public ScToken
126 ScSingleRefData aSingleRef
;
128 ScSingleRefToken( const ScSingleRefData
& r
, OpCode e
= ocPush
) :
129 ScToken( formula::svSingleRef
, e
), aSingleRef( r
) {}
130 ScSingleRefToken( const ScSingleRefToken
& r
) :
131 ScToken( r
), aSingleRef( r
.aSingleRef
) {}
132 virtual const ScSingleRefData
& GetSingleRef() const SAL_OVERRIDE
;
133 virtual ScSingleRefData
& GetSingleRef() SAL_OVERRIDE
;
134 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
135 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScSingleRefToken(*this); }
137 #if DEBUG_FORMULA_COMPILER
138 virtual void Dump() const;
140 DECL_FIXEDMEMPOOL_NEWDEL( ScSingleRefToken
);
143 class ScDoubleRefToken
: public ScToken
146 ScComplexRefData aDoubleRef
;
148 ScDoubleRefToken( const ScComplexRefData
& r
, OpCode e
= ocPush
) :
149 ScToken( formula::svDoubleRef
, e
), aDoubleRef( r
) {}
150 ScDoubleRefToken( const ScSingleRefData
& r
, OpCode e
= ocPush
) :
151 ScToken( formula::svDoubleRef
, e
)
156 ScDoubleRefToken( const ScDoubleRefToken
& r
) :
157 ScToken( r
), aDoubleRef( r
.aDoubleRef
) {}
158 virtual const ScSingleRefData
& GetSingleRef() const SAL_OVERRIDE
;
159 virtual ScSingleRefData
& GetSingleRef() SAL_OVERRIDE
;
160 virtual const ScComplexRefData
& GetDoubleRef() const SAL_OVERRIDE
;
161 virtual ScComplexRefData
& GetDoubleRef() SAL_OVERRIDE
;
162 virtual const ScSingleRefData
& GetSingleRef2() const SAL_OVERRIDE
;
163 virtual ScSingleRefData
& GetSingleRef2() SAL_OVERRIDE
;
164 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
165 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScDoubleRefToken(*this); }
167 #if DEBUG_FORMULA_COMPILER
168 virtual void Dump() const;
170 DECL_FIXEDMEMPOOL_NEWDEL( ScDoubleRefToken
);
173 class ScMatrixToken
: public ScToken
178 ScMatrixToken( const ScMatrixRef
& p
);
179 ScMatrixToken( const ScMatrixToken
& r
);
181 virtual const ScMatrix
* GetMatrix() const SAL_OVERRIDE
;
182 virtual ScMatrix
* GetMatrix() SAL_OVERRIDE
;
183 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
184 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScMatrixToken(*this); }
188 * Token storing matrix that represents values in sheet range. It stores
189 * both the values in matrix form, and the range address the matrix
192 class ScMatrixRangeToken
: public ScToken
194 ScMatrixRef mpMatrix
;
195 ScComplexRefData maRef
;
197 ScMatrixRangeToken( const ScMatrixRef
& p
, const ScComplexRefData
& rRef
);
198 ScMatrixRangeToken( const sc::RangeMatrix
& rMat
);
199 ScMatrixRangeToken( const ScMatrixRangeToken
& r
);
201 virtual sal_uInt8
GetByte() const SAL_OVERRIDE
;
202 virtual const ScMatrix
* GetMatrix() const SAL_OVERRIDE
;
203 virtual ScMatrix
* GetMatrix() SAL_OVERRIDE
;
204 virtual const ScComplexRefData
& GetDoubleRef() const SAL_OVERRIDE
;
205 virtual ScComplexRefData
& GetDoubleRef() SAL_OVERRIDE
;
206 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
207 virtual FormulaToken
* Clone() const SAL_OVERRIDE
;
210 class ScExternalSingleRefToken
: public ScToken
213 svl::SharedString maTabName
;
214 ScSingleRefData maSingleRef
;
216 ScExternalSingleRefToken(); // disabled
218 ScExternalSingleRefToken( sal_uInt16 nFileId
, const svl::SharedString
& rTabName
, const ScSingleRefData
& r
);
219 ScExternalSingleRefToken( const ScExternalSingleRefToken
& r
);
220 virtual ~ScExternalSingleRefToken();
222 virtual sal_uInt16
GetIndex() const SAL_OVERRIDE
;
223 virtual svl::SharedString
GetString() const SAL_OVERRIDE
;
224 virtual const ScSingleRefData
& GetSingleRef() const SAL_OVERRIDE
;
225 virtual ScSingleRefData
& GetSingleRef() SAL_OVERRIDE
;
226 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
227 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScExternalSingleRefToken(*this); }
231 class ScExternalDoubleRefToken
: public ScToken
234 svl::SharedString maTabName
; // name of the first sheet
235 ScComplexRefData maDoubleRef
;
237 ScExternalDoubleRefToken(); // disabled
239 ScExternalDoubleRefToken( sal_uInt16 nFileId
, const svl::SharedString
& rTabName
, const ScComplexRefData
& r
);
240 ScExternalDoubleRefToken( const ScExternalDoubleRefToken
& r
);
241 virtual ~ScExternalDoubleRefToken();
243 virtual sal_uInt16
GetIndex() const SAL_OVERRIDE
;
244 virtual svl::SharedString
GetString() const SAL_OVERRIDE
;
245 virtual const ScSingleRefData
& GetSingleRef() const SAL_OVERRIDE
;
246 virtual ScSingleRefData
& GetSingleRef() SAL_OVERRIDE
;
247 virtual const ScSingleRefData
& GetSingleRef2() const SAL_OVERRIDE
;
248 virtual ScSingleRefData
& GetSingleRef2() SAL_OVERRIDE
;
249 virtual const ScComplexRefData
& GetDoubleRef() const SAL_OVERRIDE
;
250 virtual ScComplexRefData
& GetDoubleRef() SAL_OVERRIDE
;
251 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
252 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScExternalDoubleRefToken(*this); }
255 class ScExternalNameToken
: public ScToken
258 svl::SharedString maName
;
260 ScExternalNameToken(); // disabled
262 ScExternalNameToken( sal_uInt16 nFileId
, const svl::SharedString
& rName
);
263 ScExternalNameToken( const ScExternalNameToken
& r
);
264 virtual ~ScExternalNameToken();
266 virtual sal_uInt16
GetIndex() const SAL_OVERRIDE
;
267 virtual svl::SharedString
GetString() const SAL_OVERRIDE
;
268 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
269 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScExternalNameToken(*this); }
273 // Only created from within the interpreter, no conversion from ScRawToken,
274 // never added to ScTokenArray!
275 class ScJumpMatrixToken
: public ScToken
278 ScJumpMatrix
* pJumpMatrix
;
280 ScJumpMatrixToken( ScJumpMatrix
* p
) :
281 ScToken( formula::svJumpMatrix
), pJumpMatrix( p
) {}
282 ScJumpMatrixToken( const ScJumpMatrixToken
& r
) :
283 ScToken( r
), pJumpMatrix( r
.pJumpMatrix
) {}
284 virtual ~ScJumpMatrixToken();
285 virtual ScJumpMatrix
* GetJumpMatrix() const SAL_OVERRIDE
;
286 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
287 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScJumpMatrixToken(*this); }
291 // Only created from within the interpreter, no conversion from ScRawToken,
292 // never added to ScTokenArray!
293 class ScRefListToken
: public ScToken
299 ScToken( formula::svRefList
) {}
300 ScRefListToken( const ScRefListToken
& r
) :
301 ScToken( r
), aRefList( r
.aRefList
) {}
302 virtual const ScRefList
* GetRefList() const SAL_OVERRIDE
;
303 virtual ScRefList
* GetRefList() SAL_OVERRIDE
;
304 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
305 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScRefListToken(*this); }
309 class SC_DLLPUBLIC ScEmptyCellToken
: public ScToken
312 bool bDisplayedAsString
:1;
314 explicit ScEmptyCellToken( bool bInheritedP
, bool bDisplayAsString
) :
315 ScToken( formula::svEmptyCell
),
316 bInherited( bInheritedP
),
317 bDisplayedAsString( bDisplayAsString
) {}
318 ScEmptyCellToken( const ScEmptyCellToken
& r
) :
320 bInherited( r
.bInherited
),
321 bDisplayedAsString( r
.bDisplayedAsString
) {}
322 bool IsInherited() const { return bInherited
; }
323 bool IsDisplayedAsString() const { return bDisplayedAsString
; }
324 virtual double GetDouble() const SAL_OVERRIDE
;
325 virtual svl::SharedString
GetString() const SAL_OVERRIDE
;
326 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
327 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScEmptyCellToken(*this); }
331 /** Transports the result from the interpreter to the formula cell. */
332 class SC_DLLPUBLIC ScMatrixCellResultToken
: public ScToken
334 // No non-const access implemented, silence down unxsols4 complaining about
335 // the public GetMatrix() hiding the one from ScToken.
336 virtual ScMatrix
* GetMatrix() SAL_OVERRIDE
;
339 ScConstMatrixRef xMatrix
;
340 formula::FormulaConstTokenRef xUpperLeft
;
342 ScMatrixCellResultToken( const ScConstMatrixRef
& pMat
, formula::FormulaToken
* pUL
);
343 ScMatrixCellResultToken( const ScMatrixCellResultToken
& r
);
344 virtual double GetDouble() const SAL_OVERRIDE
;
345 virtual svl::SharedString
GetString() const SAL_OVERRIDE
;
346 virtual const ScMatrix
* GetMatrix() const SAL_OVERRIDE
;
347 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
348 virtual FormulaToken
* Clone() const SAL_OVERRIDE
;
349 formula::StackVar
GetUpperLeftType() const
352 xUpperLeft
->GetType() :
353 static_cast<formula::StackVar
>(formula::svUnknown
);
355 inline formula::FormulaConstTokenRef
GetUpperLeftToken() const { return xUpperLeft
; }
356 void Assign( const ScMatrixCellResultToken
& r
);
360 /** Stores the matrix result at the formula cell, additionally the range the
361 matrix formula occupies. */
362 class SC_DLLPUBLIC ScMatrixFormulaCellToken
: public ScMatrixCellResultToken
368 ScMatrixFormulaCellToken( SCCOL nC
, SCROW nR
, const ScConstMatrixRef
& pMat
, formula::FormulaToken
* pUL
);
369 ScMatrixFormulaCellToken( SCCOL nC
, SCROW nR
);
370 ScMatrixFormulaCellToken( const ScMatrixFormulaCellToken
& r
);
372 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
373 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScMatrixFormulaCellToken(*this); }
374 void SetMatColsRows( SCCOL nC
, SCROW nR
)
379 void GetMatColsRows( SCCOL
& nC
, SCROW
& nR
) const
384 SCCOL
GetMatCols() const { return nCols
; }
385 SCROW
GetMatRows() const { return nRows
; }
387 /** Assign matrix result, keep matrix formula
389 void Assign( const ScMatrixCellResultToken
& r
);
391 /** Assign any result, keep matrix formula
392 dimension. If token is of type
393 ScMatrixCellResultToken uses the
394 appropriate Assign() call, other tokens
395 are assigned to xUpperLeft and xMatrix will
397 void Assign( const formula::FormulaToken
& r
);
399 /** Modify xUpperLeft if formula::svDouble, or create
400 new formula::FormulaDoubleToken if not set yet. Does
401 nothing if xUpperLeft is of different type! */
402 void SetUpperLeftDouble( double f
);
404 /** Reset matrix and upper left, keep matrix
405 formula dimension. */
410 class SC_DLLPUBLIC ScHybridCellToken
: public ScToken
414 svl::SharedString maString
;
418 double f
, const svl::SharedString
& rStr
, const OUString
& rFormula
);
420 const OUString
& GetFormula() const { return maFormula
; }
421 virtual double GetDouble() const SAL_OVERRIDE
;
423 virtual svl::SharedString
GetString() const SAL_OVERRIDE
;
424 virtual bool operator==( const formula::FormulaToken
& rToken
) const SAL_OVERRIDE
;
425 virtual FormulaToken
* Clone() const SAL_OVERRIDE
{ return new ScHybridCellToken(*this); }
428 // Simplify argument passing to RefUpdate methods with ScSingleRefToken or
430 class SingleDoubleRefModifier
432 ScComplexRefData aDub
;
434 ScComplexRefData
* pD
;
436 // not implemented, prevent usage
437 SingleDoubleRefModifier( const SingleDoubleRefModifier
& );
438 SingleDoubleRefModifier
& operator=( const SingleDoubleRefModifier
& );
441 SingleDoubleRefModifier( ScToken
& rT
)
443 formula::StackVar eType
= rT
.GetType();
444 if ( eType
== formula::svSingleRef
|| eType
== formula::svExternalSingleRef
)
446 pS
= &rT
.GetSingleRef();
447 aDub
.Ref1
= aDub
.Ref2
= *pS
;
453 pD
= &rT
.GetDoubleRef();
456 SingleDoubleRefModifier( ScSingleRefData
& rS
)
459 aDub
.Ref1
= aDub
.Ref2
= *pS
;
462 ~SingleDoubleRefModifier()
467 inline ScComplexRefData
& Ref() { return *pD
; }
470 class SingleDoubleRefProvider
474 const ScSingleRefData
& Ref1
;
475 const ScSingleRefData
& Ref2
;
477 SingleDoubleRefProvider( const ScToken
& r
)
478 : Ref1( r
.GetSingleRef() ),
479 Ref2( (r
.GetType() == formula::svDoubleRef
||
480 r
.GetType() == formula::svExternalDoubleRef
) ?
481 r
.GetDoubleRef().Ref2
: Ref1
)
483 SingleDoubleRefProvider( const ScSingleRefData
& r
)
484 : Ref1( r
), Ref2( r
)
486 SingleDoubleRefProvider( const ScComplexRefData
& r
)
487 : Ref1( r
.Ref1
), Ref2( r
.Ref2
)
489 ~SingleDoubleRefProvider()
495 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */