Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #ifndef SC_TOKEN_HXX
21 : #define SC_TOKEN_HXX
22 :
23 : #include <memory>
24 : #include <vector>
25 : #include <boost/intrusive_ptr.hpp>
26 :
27 : #include "formula/opcode.hxx"
28 : #include "refdata.hxx"
29 : #include <tools/mempool.hxx>
30 : #include "scdllapi.h"
31 : #include "formula/IFunctionDescription.hxx"
32 : #include "formula/token.hxx"
33 : #include "scmatrix.hxx"
34 :
35 : class ScJumpMatrix;
36 :
37 : typedef ::std::vector< ScComplexRefData > ScRefList;
38 :
39 : class SC_DLLPUBLIC ScToken : public formula::FormulaToken
40 : {
41 : private:
42 : // not implemented, prevent usage
43 : ScToken();
44 : ScToken& operator=( const ScToken& );
45 :
46 : protected:
47 :
48 21077 : ScToken( formula::StackVar eTypeP,OpCode e = ocPush ) : formula::FormulaToken(eTypeP,e) {}
49 9362 : ScToken( const ScToken& r ): formula::FormulaToken(r) {}
50 :
51 : public:
52 :
53 : virtual ~ScToken();
54 :
55 : /**
56 : Dummy methods to avoid switches and casts where possible,
57 : the real token classes have to overload the appropriate method[s].
58 : The only methods valid anytime if not overloaded are:
59 :
60 : - GetByte() since this represents the count of parameters to a function
61 : which of course is 0 on non-functions. formula::FormulaByteToken and ScExternal do
62 : overload it.
63 :
64 : - HasForceArray() since also this is only used for operators and
65 : functions and is 0 for other tokens.
66 :
67 : Any other non-overloaded method pops up an assertion.
68 : */
69 :
70 : virtual const ScSingleRefData& GetSingleRef() const;
71 : virtual ScSingleRefData& GetSingleRef();
72 : virtual const ScComplexRefData& GetDoubleRef() const;
73 : virtual ScComplexRefData& GetDoubleRef();
74 : virtual const ScSingleRefData& GetSingleRef2() const;
75 : virtual ScSingleRefData& GetSingleRef2();
76 : virtual void CalcAbsIfRel( const ScAddress& );
77 : virtual void CalcRelFromAbs( const ScAddress& );
78 : virtual const ScMatrix* GetMatrix() const;
79 : virtual ScMatrix* GetMatrix();
80 : virtual ScJumpMatrix* GetJumpMatrix() const;
81 : virtual const ScRefList* GetRefList() const;
82 : virtual ScRefList* GetRefList();
83 :
84 : virtual bool TextEqual( const formula::FormulaToken& rToken ) const;
85 : virtual bool Is3DRef() const; // reference with 3D flag set
86 :
87 : /** If rTok1 and rTok2 both are SingleRef or DoubleRef tokens, extend/merge
88 : ranges as needed for ocRange.
89 : @param rPos
90 : The formula's position, used to calculate absolute positions from
91 : relative references.
92 : @param bReuseDoubleRef
93 : If true, a DoubleRef token is reused if passed as rTok1 or rTok2,
94 : else a new DoubleRef token is created and returned.
95 : @return
96 : A reused or new'ed ScDoubleRefToken, or a NULL TokenRef if rTok1 or
97 : rTok2 are not of sv(Single|Double)Ref
98 : */
99 : static formula::FormulaTokenRef ExtendRangeReference( formula::FormulaToken & rTok1, formula::FormulaToken & rTok2, const ScAddress & rPos, bool bReuseDoubleRef );
100 : };
101 :
102 19194 : inline void intrusive_ptr_add_ref(const ScToken* p)
103 : {
104 19194 : p->IncRef();
105 19194 : }
106 :
107 19194 : inline void intrusive_ptr_release(const ScToken* p)
108 : {
109 19194 : p->DecRef();
110 19194 : }
111 :
112 38504 : class ScSingleRefToken : public ScToken
113 : {
114 : private:
115 : ScSingleRefData aSingleRef;
116 : public:
117 11764 : ScSingleRefToken( const ScSingleRefData& r, OpCode e = ocPush ) :
118 11764 : ScToken( formula::svSingleRef, e ), aSingleRef( r ) {}
119 7842 : ScSingleRefToken( const ScSingleRefToken& r ) :
120 7842 : ScToken( r ), aSingleRef( r.aSingleRef ) {}
121 : virtual const ScSingleRefData& GetSingleRef() const;
122 : virtual ScSingleRefData& GetSingleRef();
123 : virtual void CalcAbsIfRel( const ScAddress& );
124 : virtual void CalcRelFromAbs( const ScAddress& );
125 : virtual bool operator==( const formula::FormulaToken& rToken ) const;
126 7842 : virtual FormulaToken* Clone() const { return new ScSingleRefToken(*this); }
127 :
128 38858 : DECL_FIXEDMEMPOOL_NEWDEL( ScSingleRefToken );
129 : };
130 :
131 19540 : class ScDoubleRefToken : public ScToken
132 : {
133 : private:
134 : ScComplexRefData aDoubleRef;
135 : public:
136 8332 : ScDoubleRefToken( const ScComplexRefData& r, OpCode e = ocPush ) :
137 8332 : ScToken( formula::svDoubleRef, e ), aDoubleRef( r ) {}
138 : ScDoubleRefToken( const ScSingleRefData& r, OpCode e = ocPush ) :
139 : ScToken( formula::svDoubleRef, e )
140 : {
141 : aDoubleRef.Ref1 = r;
142 : aDoubleRef.Ref2 = r;
143 : }
144 1507 : ScDoubleRefToken( const ScDoubleRefToken& r ) :
145 1507 : ScToken( r ), aDoubleRef( r.aDoubleRef ) {}
146 : virtual const ScSingleRefData& GetSingleRef() const;
147 : virtual ScSingleRefData& GetSingleRef();
148 : virtual const ScComplexRefData& GetDoubleRef() const;
149 : virtual ScComplexRefData& GetDoubleRef();
150 : virtual const ScSingleRefData& GetSingleRef2() const;
151 : virtual ScSingleRefData& GetSingleRef2();
152 : virtual void CalcAbsIfRel( const ScAddress& );
153 : virtual void CalcRelFromAbs( const ScAddress& );
154 : virtual bool operator==( const formula::FormulaToken& rToken ) const;
155 1507 : virtual FormulaToken* Clone() const { return new ScDoubleRefToken(*this); }
156 :
157 19609 : DECL_FIXEDMEMPOOL_NEWDEL( ScDoubleRefToken );
158 : };
159 :
160 192 : class ScMatrixToken : public ScToken
161 : {
162 : private:
163 : ScMatrixRef pMatrix;
164 : public:
165 : ScMatrixToken( const ScMatrixRef& p );
166 : ScMatrixToken( const ScMatrixToken& r );
167 :
168 : virtual const ScMatrix* GetMatrix() const;
169 : virtual ScMatrix* GetMatrix();
170 : virtual bool operator==( const formula::FormulaToken& rToken ) const;
171 9 : virtual FormulaToken* Clone() const { return new ScMatrixToken(*this); }
172 : };
173 :
174 :
175 : class ScExternalSingleRefToken : public ScToken
176 : {
177 : private:
178 : sal_uInt16 mnFileId;
179 : String maTabName;
180 : ScSingleRefData maSingleRef;
181 :
182 : ScExternalSingleRefToken(); // disabled
183 : public:
184 : ScExternalSingleRefToken( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& r );
185 : ScExternalSingleRefToken( const ScExternalSingleRefToken& r );
186 : virtual ~ScExternalSingleRefToken();
187 :
188 : virtual sal_uInt16 GetIndex() const;
189 : virtual const String& GetString() const;
190 : virtual const ScSingleRefData& GetSingleRef() const;
191 : virtual ScSingleRefData& GetSingleRef();
192 : virtual void CalcAbsIfRel( const ScAddress& );
193 : virtual void CalcRelFromAbs( const ScAddress& );
194 : virtual bool operator==( const formula::FormulaToken& rToken ) const;
195 2 : virtual FormulaToken* Clone() const { return new ScExternalSingleRefToken(*this); }
196 : };
197 :
198 :
199 : class ScExternalDoubleRefToken : public ScToken
200 : {
201 : private:
202 : sal_uInt16 mnFileId;
203 : String maTabName; // name of the first sheet
204 : ScComplexRefData maDoubleRef;
205 :
206 : ScExternalDoubleRefToken(); // disabled
207 : public:
208 : ScExternalDoubleRefToken( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& r );
209 : ScExternalDoubleRefToken( const ScExternalDoubleRefToken& r );
210 : virtual ~ScExternalDoubleRefToken();
211 :
212 : virtual sal_uInt16 GetIndex() const;
213 : virtual const String& GetString() const;
214 : virtual const ScSingleRefData& GetSingleRef() const;
215 : virtual ScSingleRefData& GetSingleRef();
216 : virtual const ScSingleRefData& GetSingleRef2() const;
217 : virtual ScSingleRefData& GetSingleRef2();
218 : virtual const ScComplexRefData& GetDoubleRef() const;
219 : virtual ScComplexRefData& GetDoubleRef();
220 : virtual void CalcAbsIfRel( const ScAddress& );
221 : virtual void CalcRelFromAbs( const ScAddress& );
222 : virtual bool operator==( const formula::FormulaToken& rToken ) const;
223 0 : virtual FormulaToken* Clone() const { return new ScExternalDoubleRefToken(*this); }
224 : };
225 :
226 : class ScExternalNameToken : public ScToken
227 : {
228 : private:
229 : sal_uInt16 mnFileId;
230 : String maName;
231 : private:
232 : ScExternalNameToken(); // disabled
233 : public:
234 : ScExternalNameToken( sal_uInt16 nFileId, const String& rName );
235 : ScExternalNameToken( const ScExternalNameToken& r );
236 : virtual ~ScExternalNameToken();
237 : virtual sal_uInt16 GetIndex() const;
238 : virtual const String& GetString() const;
239 : virtual bool operator==( const formula::FormulaToken& rToken ) const;
240 0 : virtual FormulaToken* Clone() const { return new ScExternalNameToken(*this); }
241 : };
242 :
243 :
244 : // Only created from within the interpreter, no conversion from ScRawToken,
245 : // never added to ScTokenArray!
246 : class ScJumpMatrixToken : public ScToken
247 : {
248 : private:
249 : ScJumpMatrix* pJumpMatrix;
250 : public:
251 1 : ScJumpMatrixToken( ScJumpMatrix* p ) :
252 1 : ScToken( formula::svJumpMatrix ), pJumpMatrix( p ) {}
253 0 : ScJumpMatrixToken( const ScJumpMatrixToken& r ) :
254 0 : ScToken( r ), pJumpMatrix( r.pJumpMatrix ) {}
255 : virtual ~ScJumpMatrixToken();
256 : virtual ScJumpMatrix* GetJumpMatrix() const;
257 : virtual bool operator==( const formula::FormulaToken& rToken ) const;
258 0 : virtual FormulaToken* Clone() const { return new ScJumpMatrixToken(*this); }
259 : };
260 :
261 :
262 : // Only created from within the interpreter, no conversion from ScRawToken,
263 : // never added to ScTokenArray!
264 0 : class ScRefListToken : public ScToken
265 : {
266 : private:
267 : ScRefList aRefList;
268 : public:
269 0 : ScRefListToken() :
270 0 : ScToken( formula::svRefList ) {}
271 0 : ScRefListToken( const ScRefListToken & r ) :
272 0 : ScToken( r ), aRefList( r.aRefList ) {}
273 : virtual void CalcAbsIfRel( const ScAddress& );
274 : virtual void CalcRelFromAbs( const ScAddress& );
275 : virtual const ScRefList* GetRefList() const;
276 : virtual ScRefList* GetRefList();
277 : virtual bool operator==( const formula::FormulaToken& rToken ) const;
278 0 : virtual FormulaToken* Clone() const { return new ScRefListToken(*this); }
279 : };
280 :
281 :
282 1458 : class SC_DLLPUBLIC ScEmptyCellToken : public ScToken
283 : {
284 : bool bInherited :1;
285 : bool bDisplayedAsString :1;
286 : public:
287 727 : explicit ScEmptyCellToken( bool bInheritedP, bool bDisplayAsString ) :
288 : ScToken( formula::svEmptyCell ),
289 : bInherited( bInheritedP ),
290 727 : bDisplayedAsString( bDisplayAsString ) {}
291 2 : ScEmptyCellToken( const ScEmptyCellToken& r ) :
292 : ScToken( r ),
293 : bInherited( r.bInherited ),
294 2 : bDisplayedAsString( r.bDisplayedAsString ) {}
295 0 : bool IsInherited() const { return bInherited; }
296 726 : bool IsDisplayedAsString() const { return bDisplayedAsString; }
297 : virtual double GetDouble() const;
298 : virtual const String & GetString() const;
299 : virtual bool operator==( const formula::FormulaToken& rToken ) const;
300 2 : virtual FormulaToken* Clone() const { return new ScEmptyCellToken(*this); }
301 : };
302 :
303 :
304 : /** Transports the result from the interpreter to the formula cell. */
305 143 : class SC_DLLPUBLIC ScMatrixCellResultToken : public ScToken
306 : {
307 : // No non-const access implemented, silence down unxsols4 complaining about
308 : // the public GetMatrix() hiding the one from ScToken.
309 : virtual ScMatrix* GetMatrix();
310 :
311 : protected:
312 : ScConstMatrixRef xMatrix;
313 : formula::FormulaConstTokenRef xUpperLeft;
314 : public:
315 : ScMatrixCellResultToken( const ScConstMatrixRef& pMat, formula::FormulaToken* pUL );
316 : ScMatrixCellResultToken( const ScMatrixCellResultToken& r );
317 : virtual double GetDouble() const;
318 : virtual const String & GetString() const;
319 : virtual const ScMatrix* GetMatrix() const;
320 : virtual bool operator==( const formula::FormulaToken& rToken ) const;
321 : virtual FormulaToken* Clone() const;
322 518 : formula::StackVar GetUpperLeftType() const
323 : {
324 : return xUpperLeft ?
325 486 : xUpperLeft->GetType() :
326 1004 : static_cast<formula::StackVar>(formula::svUnknown);
327 : }
328 171 : inline formula::FormulaConstTokenRef GetUpperLeftToken() const { return xUpperLeft; }
329 : void Assign( const ScMatrixCellResultToken & r );
330 : };
331 :
332 :
333 : /** Stores the matrix result at the formula cell, additionally the range the
334 : matrix formula occupies. */
335 118 : class SC_DLLPUBLIC ScMatrixFormulaCellToken : public ScMatrixCellResultToken
336 : {
337 : private:
338 : SCROW nRows;
339 : SCCOL nCols;
340 : public:
341 : ScMatrixFormulaCellToken( SCCOL nC, SCROW nR, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL );
342 : ScMatrixFormulaCellToken( SCCOL nC, SCROW nR );
343 : ScMatrixFormulaCellToken( const ScMatrixFormulaCellToken& r );
344 :
345 : virtual bool operator==( const formula::FormulaToken& rToken ) const;
346 0 : virtual FormulaToken* Clone() const { return new ScMatrixFormulaCellToken(*this); }
347 0 : void SetMatColsRows( SCCOL nC, SCROW nR )
348 : {
349 0 : nRows = nR;
350 0 : nCols = nC;
351 0 : }
352 4 : void GetMatColsRows( SCCOL & nC, SCROW & nR ) const
353 : {
354 4 : nR = nRows;
355 4 : nC = nCols;
356 4 : }
357 0 : SCCOL GetMatCols() const { return nCols; }
358 0 : SCROW GetMatRows() const { return nRows; }
359 :
360 : /** Assign matrix result, keep matrix formula
361 : dimension. */
362 : void Assign( const ScMatrixCellResultToken & r );
363 :
364 : /** Assign any result, keep matrix formula
365 : dimension. If token is of type
366 : ScMatrixCellResultToken uses the
367 : appropriate Assign() call, other tokens
368 : are assigned to xUpperLeft and xMatrix will
369 : be assigned NULL. */
370 : void Assign( const formula::FormulaToken & r );
371 :
372 : /** Modify xUpperLeft if formula::svDouble, or create
373 : new formula::FormulaDoubleToken if not set yet. Does
374 : nothing if xUpperLeft is of different type! */
375 : void SetUpperLeftDouble( double f);
376 :
377 : /** Reset matrix and upper left, keep matrix
378 : formula dimension. */
379 : void ResetResult();
380 : };
381 :
382 :
383 52 : class SC_DLLPUBLIC ScHybridCellToken : public ScToken
384 : {
385 : private:
386 : double mfDouble;
387 : String maString;
388 : OUString maFormula;
389 : public:
390 26 : ScHybridCellToken( double f,
391 : const OUString & rStr,
392 : const OUString & rFormula ) :
393 : ScToken( formula::svHybridCell ),
394 : mfDouble( f ), maString( rStr ),
395 26 : maFormula( rFormula ) {}
396 :
397 0 : const OUString& GetFormula() const { return maFormula; }
398 : virtual double GetDouble() const;
399 : virtual const String& GetString() const;
400 : virtual bool operator==( const formula::FormulaToken& rToken ) const;
401 0 : virtual FormulaToken* Clone() const { return new ScHybridCellToken(*this); }
402 : };
403 :
404 : // Simplify argument passing to RefUpdate methods with ScSingleRefToken or
405 : // ScDoubleRefToken
406 : class SingleDoubleRefModifier
407 : {
408 : ScComplexRefData aDub;
409 : ScSingleRefData* pS;
410 : ScComplexRefData* pD;
411 :
412 : // not implemented, prevent usage
413 : SingleDoubleRefModifier( const SingleDoubleRefModifier& );
414 : SingleDoubleRefModifier& operator=( const SingleDoubleRefModifier& );
415 :
416 : public:
417 17 : SingleDoubleRefModifier( ScToken& rT )
418 : {
419 17 : formula::StackVar eType = rT.GetType();
420 17 : if ( eType == formula::svSingleRef || eType == formula::svExternalSingleRef )
421 : {
422 1 : pS = &rT.GetSingleRef();
423 1 : aDub.Ref1 = aDub.Ref2 = *pS;
424 1 : pD = &aDub;
425 : }
426 : else
427 : {
428 16 : pS = 0;
429 16 : pD = &rT.GetDoubleRef();
430 : }
431 17 : }
432 322 : SingleDoubleRefModifier( ScSingleRefData& rS )
433 : {
434 322 : pS = &rS;
435 322 : aDub.Ref1 = aDub.Ref2 = *pS;
436 322 : pD = &aDub;
437 322 : }
438 339 : ~SingleDoubleRefModifier()
439 : {
440 339 : if ( pS )
441 323 : *pS = (*pD).Ref1;
442 339 : }
443 339 : inline ScComplexRefData& Ref() { return *pD; }
444 : };
445 :
446 : class SingleDoubleRefProvider
447 : {
448 : public:
449 :
450 : const ScSingleRefData& Ref1;
451 : const ScSingleRefData& Ref2;
452 :
453 176 : SingleDoubleRefProvider( const ScToken& r )
454 176 : : Ref1( r.GetSingleRef() ),
455 339 : Ref2( (r.GetType() == formula::svDoubleRef ||
456 163 : r.GetType() == formula::svExternalDoubleRef) ?
457 365 : r.GetDoubleRef().Ref2 : Ref1 )
458 176 : {}
459 : SingleDoubleRefProvider( const ScSingleRefData& r )
460 : : Ref1( r ), Ref2( r )
461 : {}
462 : SingleDoubleRefProvider( const ScComplexRefData& r )
463 : : Ref1( r.Ref1 ), Ref2( r.Ref2 )
464 : {}
465 176 : ~SingleDoubleRefProvider()
466 176 : {}
467 : };
468 :
469 : #endif
470 :
471 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|