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 .
25 #include <boost/intrusive_ptr.hpp>
27 #include "formula/opcode.hxx"
28 #include "refdata.hxx"
29 #include <tools/mempool.hxx>
31 #include "formula/IFunctionDescription.hxx"
32 #include "formula/token.hxx"
33 #include "scmatrix.hxx"
34 #include "calcmacros.hxx"
36 // Matrix token constants.
37 #define MATRIX_TOKEN_HAS_RANGE 1
47 typedef ::std::vector
< ScComplexRefData
> ScRefList
;
49 class SC_DLLPUBLIC ScToken
: public formula::FormulaToken
52 // not implemented, prevent usage
54 ScToken
& operator=( const ScToken
& );
58 ScToken( formula::StackVar eTypeP
,OpCode e
= ocPush
) : formula::FormulaToken(eTypeP
,e
) {}
59 ScToken( const ScToken
& r
): formula::FormulaToken(r
) {}
66 Dummy methods to avoid switches and casts where possible,
67 the real token classes have to overload the appropriate method[s].
68 The only methods valid anytime if not overloaded are:
70 - GetByte() since this represents the count of parameters to a function
71 which of course is 0 on non-functions. formula::FormulaByteToken and ScExternal do
74 - HasForceArray() since also this is only used for operators and
75 functions and is 0 for other tokens.
77 Any other non-overloaded method pops up an assertion.
80 virtual const ScSingleRefData
& GetSingleRef() const;
81 virtual ScSingleRefData
& GetSingleRef();
82 virtual const ScComplexRefData
& GetDoubleRef() const;
83 virtual ScComplexRefData
& GetDoubleRef();
84 virtual const ScSingleRefData
& GetSingleRef2() const;
85 virtual ScSingleRefData
& GetSingleRef2();
86 virtual const ScMatrix
* GetMatrix() const;
87 virtual ScMatrix
* GetMatrix();
88 virtual ScJumpMatrix
* GetJumpMatrix() const;
89 virtual const ScRefList
* GetRefList() const;
90 virtual ScRefList
* GetRefList();
92 virtual bool TextEqual( const formula::FormulaToken
& rToken
) const;
93 virtual bool Is3DRef() const; // reference with 3D flag set
95 #if DEBUG_FORMULA_COMPILER
96 virtual void Dump() const;
99 /** If rTok1 and rTok2 both are SingleRef or DoubleRef tokens, extend/merge
100 ranges as needed for ocRange.
102 The formula's position, used to calculate absolute positions from
104 @param bReuseDoubleRef
105 If true, a DoubleRef token is reused if passed as rTok1 or rTok2,
106 else a new DoubleRef token is created and returned.
108 A reused or new'ed ScDoubleRefToken, or a NULL TokenRef if rTok1 or
109 rTok2 are not of sv(Single|Double)Ref
111 static formula::FormulaTokenRef
ExtendRangeReference( formula::FormulaToken
& rTok1
, formula::FormulaToken
& rTok2
, const ScAddress
& rPos
, bool bReuseDoubleRef
);
114 inline void intrusive_ptr_add_ref(const ScToken
* p
)
119 inline void intrusive_ptr_release(const ScToken
* p
)
124 class ScSingleRefToken
: public ScToken
127 ScSingleRefData aSingleRef
;
129 ScSingleRefToken( const ScSingleRefData
& r
, OpCode e
= ocPush
) :
130 ScToken( formula::svSingleRef
, e
), aSingleRef( r
) {}
131 ScSingleRefToken( const ScSingleRefToken
& r
) :
132 ScToken( r
), aSingleRef( r
.aSingleRef
) {}
133 virtual const ScSingleRefData
& GetSingleRef() const;
134 virtual ScSingleRefData
& GetSingleRef();
135 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
136 virtual FormulaToken
* Clone() const { return new ScSingleRefToken(*this); }
138 #if DEBUG_FORMULA_COMPILER
139 virtual void Dump() const;
141 DECL_FIXEDMEMPOOL_NEWDEL( ScSingleRefToken
);
144 class ScDoubleRefToken
: public ScToken
147 ScComplexRefData aDoubleRef
;
149 ScDoubleRefToken( const ScComplexRefData
& r
, OpCode e
= ocPush
) :
150 ScToken( formula::svDoubleRef
, e
), aDoubleRef( r
) {}
151 ScDoubleRefToken( const ScSingleRefData
& r
, OpCode e
= ocPush
) :
152 ScToken( formula::svDoubleRef
, e
)
157 ScDoubleRefToken( const ScDoubleRefToken
& r
) :
158 ScToken( r
), aDoubleRef( r
.aDoubleRef
) {}
159 virtual const ScSingleRefData
& GetSingleRef() const;
160 virtual ScSingleRefData
& GetSingleRef();
161 virtual const ScComplexRefData
& GetDoubleRef() const;
162 virtual ScComplexRefData
& GetDoubleRef();
163 virtual const ScSingleRefData
& GetSingleRef2() const;
164 virtual ScSingleRefData
& GetSingleRef2();
165 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
166 virtual FormulaToken
* Clone() const { return new ScDoubleRefToken(*this); }
168 #if DEBUG_FORMULA_COMPILER
169 virtual void Dump() const;
171 DECL_FIXEDMEMPOOL_NEWDEL( ScDoubleRefToken
);
174 class ScMatrixToken
: public ScToken
179 ScMatrixToken( const ScMatrixRef
& p
);
180 ScMatrixToken( const ScMatrixToken
& r
);
182 virtual const ScMatrix
* GetMatrix() const;
183 virtual ScMatrix
* GetMatrix();
184 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
185 virtual FormulaToken
* Clone() const { return new ScMatrixToken(*this); }
189 * Token storing matrix that represents values in sheet range. It stores
190 * both the values in matrix form, and the range address the matrix
193 class ScMatrixRangeToken
: public ScToken
195 ScMatrixRef mpMatrix
;
196 ScComplexRefData maRef
;
198 ScMatrixRangeToken( const ScMatrixRef
& p
, const ScComplexRefData
& rRef
);
199 ScMatrixRangeToken( const sc::RangeMatrix
& rMat
);
200 ScMatrixRangeToken( const ScMatrixRangeToken
& r
);
202 virtual sal_uInt8
GetByte() const;
203 virtual const ScMatrix
* GetMatrix() const;
204 virtual ScMatrix
* GetMatrix();
205 virtual const ScComplexRefData
& GetDoubleRef() const;
206 virtual ScComplexRefData
& GetDoubleRef();
207 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
208 virtual FormulaToken
* Clone() const;
211 class ScExternalSingleRefToken
: public ScToken
214 svl::SharedString maTabName
;
215 ScSingleRefData maSingleRef
;
217 ScExternalSingleRefToken(); // disabled
219 ScExternalSingleRefToken( sal_uInt16 nFileId
, const svl::SharedString
& rTabName
, const ScSingleRefData
& r
);
220 ScExternalSingleRefToken( const ScExternalSingleRefToken
& r
);
221 virtual ~ScExternalSingleRefToken();
223 virtual sal_uInt16
GetIndex() const;
224 virtual svl::SharedString
GetString() const;
225 virtual const ScSingleRefData
& GetSingleRef() const;
226 virtual ScSingleRefData
& GetSingleRef();
227 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
228 virtual FormulaToken
* Clone() const { return new ScExternalSingleRefToken(*this); }
232 class ScExternalDoubleRefToken
: public ScToken
235 svl::SharedString maTabName
; // name of the first sheet
236 ScComplexRefData maDoubleRef
;
238 ScExternalDoubleRefToken(); // disabled
240 ScExternalDoubleRefToken( sal_uInt16 nFileId
, const svl::SharedString
& rTabName
, const ScComplexRefData
& r
);
241 ScExternalDoubleRefToken( const ScExternalDoubleRefToken
& r
);
242 virtual ~ScExternalDoubleRefToken();
244 virtual sal_uInt16
GetIndex() const;
245 virtual svl::SharedString
GetString() const;
246 virtual const ScSingleRefData
& GetSingleRef() const;
247 virtual ScSingleRefData
& GetSingleRef();
248 virtual const ScSingleRefData
& GetSingleRef2() const;
249 virtual ScSingleRefData
& GetSingleRef2();
250 virtual const ScComplexRefData
& GetDoubleRef() const;
251 virtual ScComplexRefData
& GetDoubleRef();
252 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
253 virtual FormulaToken
* Clone() const { return new ScExternalDoubleRefToken(*this); }
256 class ScExternalNameToken
: public ScToken
259 svl::SharedString maName
;
261 ScExternalNameToken(); // disabled
263 ScExternalNameToken( sal_uInt16 nFileId
, const svl::SharedString
& rName
);
264 ScExternalNameToken( const ScExternalNameToken
& r
);
265 virtual ~ScExternalNameToken();
267 virtual sal_uInt16
GetIndex() const;
268 virtual svl::SharedString
GetString() const;
269 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
270 virtual FormulaToken
* Clone() const { return new ScExternalNameToken(*this); }
274 // Only created from within the interpreter, no conversion from ScRawToken,
275 // never added to ScTokenArray!
276 class ScJumpMatrixToken
: public ScToken
279 ScJumpMatrix
* pJumpMatrix
;
281 ScJumpMatrixToken( ScJumpMatrix
* p
) :
282 ScToken( formula::svJumpMatrix
), pJumpMatrix( p
) {}
283 ScJumpMatrixToken( const ScJumpMatrixToken
& r
) :
284 ScToken( r
), pJumpMatrix( r
.pJumpMatrix
) {}
285 virtual ~ScJumpMatrixToken();
286 virtual ScJumpMatrix
* GetJumpMatrix() const;
287 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
288 virtual FormulaToken
* Clone() const { return new ScJumpMatrixToken(*this); }
292 // Only created from within the interpreter, no conversion from ScRawToken,
293 // never added to ScTokenArray!
294 class ScRefListToken
: public ScToken
300 ScToken( formula::svRefList
) {}
301 ScRefListToken( const ScRefListToken
& r
) :
302 ScToken( r
), aRefList( r
.aRefList
) {}
303 virtual const ScRefList
* GetRefList() const;
304 virtual ScRefList
* GetRefList();
305 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
306 virtual FormulaToken
* Clone() const { return new ScRefListToken(*this); }
310 class SC_DLLPUBLIC ScEmptyCellToken
: public ScToken
313 bool bDisplayedAsString
:1;
315 explicit ScEmptyCellToken( bool bInheritedP
, bool bDisplayAsString
) :
316 ScToken( formula::svEmptyCell
),
317 bInherited( bInheritedP
),
318 bDisplayedAsString( bDisplayAsString
) {}
319 ScEmptyCellToken( const ScEmptyCellToken
& r
) :
321 bInherited( r
.bInherited
),
322 bDisplayedAsString( r
.bDisplayedAsString
) {}
323 bool IsInherited() const { return bInherited
; }
324 bool IsDisplayedAsString() const { return bDisplayedAsString
; }
325 virtual double GetDouble() const;
326 virtual svl::SharedString
GetString() const;
327 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
328 virtual FormulaToken
* Clone() const { return new ScEmptyCellToken(*this); }
332 /** Transports the result from the interpreter to the formula cell. */
333 class SC_DLLPUBLIC ScMatrixCellResultToken
: public ScToken
335 // No non-const access implemented, silence down unxsols4 complaining about
336 // the public GetMatrix() hiding the one from ScToken.
337 virtual ScMatrix
* GetMatrix();
340 ScConstMatrixRef xMatrix
;
341 formula::FormulaConstTokenRef xUpperLeft
;
343 ScMatrixCellResultToken( const ScConstMatrixRef
& pMat
, formula::FormulaToken
* pUL
);
344 ScMatrixCellResultToken( const ScMatrixCellResultToken
& r
);
345 virtual double GetDouble() const;
346 virtual svl::SharedString
GetString() const;
347 virtual const ScMatrix
* GetMatrix() const;
348 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
349 virtual FormulaToken
* Clone() const;
350 formula::StackVar
GetUpperLeftType() const
353 xUpperLeft
->GetType() :
354 static_cast<formula::StackVar
>(formula::svUnknown
);
356 inline formula::FormulaConstTokenRef
GetUpperLeftToken() const { return xUpperLeft
; }
357 void Assign( const ScMatrixCellResultToken
& r
);
361 /** Stores the matrix result at the formula cell, additionally the range the
362 matrix formula occupies. */
363 class SC_DLLPUBLIC ScMatrixFormulaCellToken
: public ScMatrixCellResultToken
369 ScMatrixFormulaCellToken( SCCOL nC
, SCROW nR
, const ScConstMatrixRef
& pMat
, formula::FormulaToken
* pUL
);
370 ScMatrixFormulaCellToken( SCCOL nC
, SCROW nR
);
371 ScMatrixFormulaCellToken( const ScMatrixFormulaCellToken
& r
);
373 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
374 virtual FormulaToken
* Clone() const { return new ScMatrixFormulaCellToken(*this); }
375 void SetMatColsRows( SCCOL nC
, SCROW nR
)
380 void GetMatColsRows( SCCOL
& nC
, SCROW
& nR
) const
385 SCCOL
GetMatCols() const { return nCols
; }
386 SCROW
GetMatRows() const { return nRows
; }
388 /** Assign matrix result, keep matrix formula
390 void Assign( const ScMatrixCellResultToken
& r
);
392 /** Assign any result, keep matrix formula
393 dimension. If token is of type
394 ScMatrixCellResultToken uses the
395 appropriate Assign() call, other tokens
396 are assigned to xUpperLeft and xMatrix will
398 void Assign( const formula::FormulaToken
& r
);
400 /** Modify xUpperLeft if formula::svDouble, or create
401 new formula::FormulaDoubleToken if not set yet. Does
402 nothing if xUpperLeft is of different type! */
403 void SetUpperLeftDouble( double f
);
405 /** Reset matrix and upper left, keep matrix
406 formula dimension. */
411 class SC_DLLPUBLIC ScHybridCellToken
: public ScToken
415 svl::SharedString maString
;
418 ScHybridCellToken( double f
,
419 const svl::SharedString
& rStr
,
420 const OUString
& rFormula
) :
421 ScToken( formula::svHybridCell
),
422 mfDouble( f
), maString( rStr
),
423 maFormula( rFormula
) {}
425 const OUString
& GetFormula() const { return maFormula
; }
426 virtual double GetDouble() const;
428 virtual svl::SharedString
GetString() const;
429 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
430 virtual FormulaToken
* Clone() const { return new ScHybridCellToken(*this); }
433 // Simplify argument passing to RefUpdate methods with ScSingleRefToken or
435 class SingleDoubleRefModifier
437 ScComplexRefData aDub
;
439 ScComplexRefData
* pD
;
441 // not implemented, prevent usage
442 SingleDoubleRefModifier( const SingleDoubleRefModifier
& );
443 SingleDoubleRefModifier
& operator=( const SingleDoubleRefModifier
& );
446 SingleDoubleRefModifier( ScToken
& rT
)
448 formula::StackVar eType
= rT
.GetType();
449 if ( eType
== formula::svSingleRef
|| eType
== formula::svExternalSingleRef
)
451 pS
= &rT
.GetSingleRef();
452 aDub
.Ref1
= aDub
.Ref2
= *pS
;
458 pD
= &rT
.GetDoubleRef();
461 SingleDoubleRefModifier( ScSingleRefData
& rS
)
464 aDub
.Ref1
= aDub
.Ref2
= *pS
;
467 ~SingleDoubleRefModifier()
472 inline ScComplexRefData
& Ref() { return *pD
; }
475 class SingleDoubleRefProvider
479 const ScSingleRefData
& Ref1
;
480 const ScSingleRefData
& Ref2
;
482 SingleDoubleRefProvider( const ScToken
& r
)
483 : Ref1( r
.GetSingleRef() ),
484 Ref2( (r
.GetType() == formula::svDoubleRef
||
485 r
.GetType() == formula::svExternalDoubleRef
) ?
486 r
.GetDoubleRef().Ref2
: Ref1
)
488 SingleDoubleRefProvider( const ScSingleRefData
& r
)
489 : Ref1( r
), Ref2( r
)
491 SingleDoubleRefProvider( const ScComplexRefData
& r
)
492 : Ref1( r
.Ref1
), Ref2( r
.Ref2
)
494 ~SingleDoubleRefProvider()
500 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */