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 "scmatrix.hxx"
30 #include <tools/mempool.hxx>
32 #include "formula/IFunctionDescription.hxx"
33 #include "formula/token.hxx"
38 typedef ::std::vector
< ScComplexRefData
> ScRefList
;
40 class SC_DLLPUBLIC ScToken
: public formula::FormulaToken
43 // not implemented, prevent usage
45 ScToken
& operator=( const ScToken
& );
49 ScToken( formula::StackVar eTypeP
,OpCode e
= ocPush
) : formula::FormulaToken(eTypeP
,e
) {}
50 ScToken( const ScToken
& r
): formula::FormulaToken(r
) {}
57 Dummy methods to avoid switches and casts where possible,
58 the real token classes have to overload the appropriate method[s].
59 The only methods valid anytime if not overloaded are:
61 - GetByte() since this represents the count of parameters to a function
62 which of course is 0 on non-functions. formula::FormulaByteToken and ScExternal do
65 - HasForceArray() since also this is only used for operators and
66 functions and is 0 for other tokens.
68 Any other non-overloaded method pops up an assertion.
71 virtual const ScSingleRefData
& GetSingleRef() const;
72 virtual ScSingleRefData
& GetSingleRef();
73 virtual const ScComplexRefData
& GetDoubleRef() const;
74 virtual ScComplexRefData
& GetDoubleRef();
75 virtual const ScSingleRefData
& GetSingleRef2() const;
76 virtual ScSingleRefData
& GetSingleRef2();
77 virtual void CalcAbsIfRel( const ScAddress
& );
78 virtual void CalcRelFromAbs( const ScAddress
& );
79 virtual const ScMatrix
* GetMatrix() const;
80 virtual ScMatrix
* GetMatrix();
81 virtual ScJumpMatrix
* GetJumpMatrix() const;
82 virtual const ScRefList
* GetRefList() const;
83 virtual ScRefList
* GetRefList();
85 virtual bool TextEqual( const formula::FormulaToken
& rToken
) const;
86 virtual bool Is3DRef() const; // reference with 3D flag set
88 /** If rTok1 and rTok2 both are SingleRef or DoubleRef tokens, extend/merge
89 ranges as needed for ocRange.
91 The formula's position, used to calculate absolute positions from
93 @param bReuseDoubleRef
94 If true, a DoubleRef token is reused if passed as rTok1 or rTok2,
95 else a new DoubleRef token is created and returned.
97 A reused or new'ed ScDoubleRefToken, or a NULL TokenRef if rTok1 or
98 rTok2 are not of sv(Single|Double)Ref
100 static formula::FormulaTokenRef
ExtendRangeReference( formula::FormulaToken
& rTok1
, formula::FormulaToken
& rTok2
, const ScAddress
& rPos
, bool bReuseDoubleRef
);
103 inline void intrusive_ptr_add_ref(const ScToken
* p
)
108 inline void intrusive_ptr_release(const ScToken
* p
)
113 class ScSingleRefToken
: public ScToken
116 ScSingleRefData aSingleRef
;
118 ScSingleRefToken( const ScSingleRefData
& r
, OpCode e
= ocPush
) :
119 ScToken( formula::svSingleRef
, e
), aSingleRef( r
) {}
120 ScSingleRefToken( const ScSingleRefToken
& r
) :
121 ScToken( r
), aSingleRef( r
.aSingleRef
) {}
122 virtual const ScSingleRefData
& GetSingleRef() const;
123 virtual ScSingleRefData
& GetSingleRef();
124 virtual void CalcAbsIfRel( const ScAddress
& );
125 virtual void CalcRelFromAbs( const ScAddress
& );
126 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
127 virtual FormulaToken
* Clone() const { return new ScSingleRefToken(*this); }
129 DECL_FIXEDMEMPOOL_NEWDEL( ScSingleRefToken
);
132 class ScDoubleRefToken
: public ScToken
135 ScComplexRefData aDoubleRef
;
137 ScDoubleRefToken( const ScComplexRefData
& r
, OpCode e
= ocPush
) :
138 ScToken( formula::svDoubleRef
, e
), aDoubleRef( r
) {}
139 ScDoubleRefToken( const ScSingleRefData
& r
, OpCode e
= ocPush
) :
140 ScToken( formula::svDoubleRef
, e
)
145 ScDoubleRefToken( const ScDoubleRefToken
& r
) :
146 ScToken( r
), aDoubleRef( r
.aDoubleRef
) {}
147 virtual const ScSingleRefData
& GetSingleRef() const;
148 virtual ScSingleRefData
& GetSingleRef();
149 virtual const ScComplexRefData
& GetDoubleRef() const;
150 virtual ScComplexRefData
& GetDoubleRef();
151 virtual const ScSingleRefData
& GetSingleRef2() const;
152 virtual ScSingleRefData
& GetSingleRef2();
153 virtual void CalcAbsIfRel( const ScAddress
& );
154 virtual void CalcRelFromAbs( const ScAddress
& );
155 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
156 virtual FormulaToken
* Clone() const { return new ScDoubleRefToken(*this); }
158 DECL_FIXEDMEMPOOL_NEWDEL( ScDoubleRefToken
);
161 class ScMatrixToken
: public ScToken
166 ScMatrixToken( ScMatrixRef p
) :
167 ScToken( formula::svMatrix
), pMatrix( p
) {}
168 ScMatrixToken( const ScMatrixToken
& r
) :
169 ScToken( r
), pMatrix( r
.pMatrix
) {}
170 virtual const ScMatrix
* GetMatrix() const;
171 virtual ScMatrix
* GetMatrix();
172 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
173 virtual FormulaToken
* Clone() const { return new ScMatrixToken(*this); }
177 class ScExternalSingleRefToken
: public ScToken
182 ScSingleRefData maSingleRef
;
184 ScExternalSingleRefToken(); // disabled
186 ScExternalSingleRefToken( sal_uInt16 nFileId
, const String
& rTabName
, const ScSingleRefData
& r
);
187 ScExternalSingleRefToken( const ScExternalSingleRefToken
& r
);
188 virtual ~ScExternalSingleRefToken();
190 virtual sal_uInt16
GetIndex() const;
191 virtual const String
& GetString() const;
192 virtual const ScSingleRefData
& GetSingleRef() const;
193 virtual ScSingleRefData
& GetSingleRef();
194 virtual void CalcAbsIfRel( const ScAddress
& );
195 virtual void CalcRelFromAbs( const ScAddress
& );
196 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
197 virtual FormulaToken
* Clone() const { return new ScExternalSingleRefToken(*this); }
201 class ScExternalDoubleRefToken
: public ScToken
205 String maTabName
; // name of the first sheet
206 ScComplexRefData maDoubleRef
;
208 ScExternalDoubleRefToken(); // disabled
210 ScExternalDoubleRefToken( sal_uInt16 nFileId
, const String
& rTabName
, const ScComplexRefData
& r
);
211 ScExternalDoubleRefToken( const ScExternalDoubleRefToken
& r
);
212 virtual ~ScExternalDoubleRefToken();
214 virtual sal_uInt16
GetIndex() const;
215 virtual const String
& GetString() const;
216 virtual const ScSingleRefData
& GetSingleRef() const;
217 virtual ScSingleRefData
& GetSingleRef();
218 virtual const ScSingleRefData
& GetSingleRef2() const;
219 virtual ScSingleRefData
& GetSingleRef2();
220 virtual const ScComplexRefData
& GetDoubleRef() const;
221 virtual ScComplexRefData
& GetDoubleRef();
222 virtual void CalcAbsIfRel( const ScAddress
& );
223 virtual void CalcRelFromAbs( const ScAddress
& );
224 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
225 virtual FormulaToken
* Clone() const { return new ScExternalDoubleRefToken(*this); }
228 class ScExternalNameToken
: public ScToken
234 ScExternalNameToken(); // disabled
236 ScExternalNameToken( sal_uInt16 nFileId
, const String
& rName
);
237 ScExternalNameToken( const ScExternalNameToken
& r
);
238 virtual ~ScExternalNameToken();
239 virtual sal_uInt16
GetIndex() const;
240 virtual const String
& GetString() const;
241 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
242 virtual FormulaToken
* Clone() const { return new ScExternalNameToken(*this); }
246 // Only created from within the interpreter, no conversion from ScRawToken,
247 // never added to ScTokenArray!
248 class ScJumpMatrixToken
: public ScToken
251 ScJumpMatrix
* pJumpMatrix
;
253 ScJumpMatrixToken( ScJumpMatrix
* p
) :
254 ScToken( formula::svJumpMatrix
), pJumpMatrix( p
) {}
255 ScJumpMatrixToken( const ScJumpMatrixToken
& r
) :
256 ScToken( r
), pJumpMatrix( r
.pJumpMatrix
) {}
257 virtual ~ScJumpMatrixToken();
258 virtual ScJumpMatrix
* GetJumpMatrix() const;
259 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
260 virtual FormulaToken
* Clone() const { return new ScJumpMatrixToken(*this); }
264 // Only created from within the interpreter, no conversion from ScRawToken,
265 // never added to ScTokenArray!
266 class ScRefListToken
: public ScToken
272 ScToken( formula::svRefList
) {}
273 ScRefListToken( const ScRefListToken
& r
) :
274 ScToken( r
), aRefList( r
.aRefList
) {}
275 virtual void CalcAbsIfRel( const ScAddress
& );
276 virtual void CalcRelFromAbs( const ScAddress
& );
277 virtual const ScRefList
* GetRefList() const;
278 virtual ScRefList
* GetRefList();
279 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
280 virtual FormulaToken
* Clone() const { return new ScRefListToken(*this); }
284 class SC_DLLPUBLIC ScEmptyCellToken
: public ScToken
287 bool bDisplayedAsString
:1;
289 explicit ScEmptyCellToken( bool bInheritedP
, bool bDisplayAsString
) :
290 ScToken( formula::svEmptyCell
),
291 bInherited( bInheritedP
),
292 bDisplayedAsString( bDisplayAsString
) {}
293 ScEmptyCellToken( const ScEmptyCellToken
& r
) :
295 bInherited( r
.bInherited
),
296 bDisplayedAsString( r
.bDisplayedAsString
) {}
297 bool IsInherited() const { return bInherited
; }
298 bool IsDisplayedAsString() const { return bDisplayedAsString
; }
299 virtual double GetDouble() const;
300 virtual const String
& GetString() const;
301 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
302 virtual FormulaToken
* Clone() const { return new ScEmptyCellToken(*this); }
306 /** Transports the result from the interpreter to the formula cell. */
307 class SC_DLLPUBLIC ScMatrixCellResultToken
: public ScToken
309 // No non-const access implemented, silence down unxsols4 complaining about
310 // the public GetMatrix() hiding the one from ScToken.
311 virtual ScMatrix
* GetMatrix();
314 ScConstMatrixRef xMatrix
;
315 formula::FormulaConstTokenRef xUpperLeft
;
317 ScMatrixCellResultToken( const ScConstMatrixRef
& pMat
, formula::FormulaToken
* pUL
) :
318 ScToken( formula::svMatrixCell
),
319 xMatrix( pMat
), xUpperLeft( pUL
) {}
320 ScMatrixCellResultToken( const ScMatrixCellResultToken
& r
) :
321 ScToken( r
), xMatrix( r
.xMatrix
),
322 xUpperLeft( r
.xUpperLeft
) {}
323 virtual double GetDouble() const;
324 virtual const String
& GetString() const;
325 virtual const ScMatrix
* GetMatrix() const;
326 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
327 virtual FormulaToken
* Clone() const { return new ScMatrixCellResultToken(*this); }
328 formula::StackVar
GetUpperLeftType() const
331 xUpperLeft
->GetType() :
332 static_cast<formula::StackVar
>(formula::svUnknown
);
334 inline formula::FormulaConstTokenRef
GetUpperLeftToken() const { return xUpperLeft
; }
335 void Assign( const ScMatrixCellResultToken
& r
)
338 xUpperLeft
= r
.xUpperLeft
;
343 /** Stores the matrix result at the formula cell, additionally the range the
344 matrix formula occupies. */
345 class SC_DLLPUBLIC ScMatrixFormulaCellToken
: public ScMatrixCellResultToken
351 ScMatrixFormulaCellToken( SCCOL nC
, SCROW nR
, const ScConstMatrixRef
& pMat
, formula::FormulaToken
* pUL
) :
352 ScMatrixCellResultToken(pMat
, pUL
),
353 nRows(nR
), nCols(nC
) {}
355 ScMatrixFormulaCellToken( SCCOL nC
, SCROW nR
) :
356 ScMatrixCellResultToken( NULL
, NULL
),
357 nRows( nR
), nCols( nC
) {}
358 ScMatrixFormulaCellToken( const ScMatrixFormulaCellToken
& r
) :
359 ScMatrixCellResultToken( r
),
360 nRows( r
.nRows
), nCols( r
.nCols
)
362 // xUpperLeft is modifiable through
363 // SetUpperLeftDouble(), so clone it.
365 xUpperLeft
= xUpperLeft
->Clone();
367 virtual bool operator==( const formula::FormulaToken
& rToken
) const;
368 virtual FormulaToken
* Clone() const { return new ScMatrixFormulaCellToken(*this); }
369 void SetMatColsRows( SCCOL nC
, SCROW nR
)
374 void GetMatColsRows( SCCOL
& nC
, SCROW
& nR
) const
379 SCCOL
GetMatCols() const { return nCols
; }
380 SCROW
GetMatRows() const { return nRows
; }
382 /** Assign matrix result, keep matrix formula
384 void Assign( const ScMatrixCellResultToken
& r
)
386 ScMatrixCellResultToken::Assign( r
);
389 /** Assign any result, keep matrix formula
390 dimension. If token is of type
391 ScMatrixCellResultToken uses the
392 appropriate Assign() call, other tokens
393 are assigned to xUpperLeft and xMatrix will
395 void Assign( const formula::FormulaToken
& r
);
397 /** Modify xUpperLeft if formula::svDouble, or create
398 new formula::FormulaDoubleToken if not set yet. Does
399 nothing if xUpperLeft is of different type! */
400 void SetUpperLeftDouble( double f
);
402 /** Reset matrix and upper left, keep matrix
403 formula dimension. */
412 class SC_DLLPUBLIC ScHybridCellToken
: public ScToken
419 ScHybridCellToken( double f
,
420 const OUString
& rStr
,
421 const OUString
& rFormula
) :
422 ScToken( formula::svHybridCell
),
423 mfDouble( f
), maString( rStr
),
424 maFormula( rFormula
) {}
426 const OUString
& GetFormula() const { return maFormula
; }
427 virtual double GetDouble() const;
428 virtual const String
& 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: */