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 <vector>
24 : #include <boost/intrusive_ptr.hpp>
25 :
26 : #include "formula/opcode.hxx"
27 : #include "refdata.hxx"
28 : #include <tools/mempool.hxx>
29 : #include "scdllapi.h"
30 : #include "formula/IFunctionDescription.hxx"
31 : #include "formula/token.hxx"
32 : #include "scmatrix.hxx"
33 : #include "calcmacros.hxx"
34 :
35 : // Matrix token constants.
36 : #define MATRIX_TOKEN_HAS_RANGE 1
37 :
38 : namespace sc {
39 :
40 : struct RangeMatrix;
41 :
42 : }
43 :
44 : class ScJumpMatrix;
45 :
46 : typedef ::std::vector< ScComplexRefData > ScRefList;
47 :
48 : class SC_DLLPUBLIC ScToken : public formula::FormulaToken
49 : {
50 : private:
51 : // not implemented, prevent usage
52 : ScToken();
53 : ScToken& operator=( const ScToken& );
54 :
55 : protected:
56 :
57 0 : ScToken( formula::StackVar eTypeP,OpCode e = ocPush ) : formula::FormulaToken(eTypeP,e) {}
58 0 : ScToken( const ScToken& r ): formula::FormulaToken(r) {}
59 :
60 : public:
61 :
62 : virtual ~ScToken();
63 :
64 : /**
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:
68 :
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
71 : overload it.
72 :
73 : - HasForceArray() since also this is only used for operators and
74 : functions and is 0 for other tokens.
75 :
76 : Any other non-overloaded method pops up an assertion.
77 : */
78 :
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();
90 :
91 : virtual bool TextEqual( const formula::FormulaToken& rToken ) const SAL_OVERRIDE;
92 : virtual bool Is3DRef() const SAL_OVERRIDE; // reference with 3D flag set
93 :
94 : #if DEBUG_FORMULA_COMPILER
95 : virtual void Dump() const;
96 : #endif
97 :
98 : /** If rTok1 and rTok2 both are SingleRef or DoubleRef tokens, extend/merge
99 : ranges as needed for ocRange.
100 : @param rPos
101 : The formula's position, used to calculate absolute positions from
102 : relative references.
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.
106 : @return
107 : A reused or new'ed ScDoubleRefToken, or a NULL TokenRef if rTok1 or
108 : rTok2 are not of sv(Single|Double)Ref
109 : */
110 : static formula::FormulaTokenRef ExtendRangeReference( formula::FormulaToken & rTok1, formula::FormulaToken & rTok2, const ScAddress & rPos, bool bReuseDoubleRef );
111 : };
112 :
113 0 : inline void intrusive_ptr_add_ref(const ScToken* p)
114 : {
115 0 : p->IncRef();
116 0 : }
117 :
118 0 : inline void intrusive_ptr_release(const ScToken* p)
119 : {
120 0 : p->DecRef();
121 0 : }
122 :
123 0 : class ScSingleRefToken : public ScToken
124 : {
125 : private:
126 : ScSingleRefData aSingleRef;
127 : public:
128 0 : ScSingleRefToken( const ScSingleRefData& r, OpCode e = ocPush ) :
129 0 : ScToken( formula::svSingleRef, e ), aSingleRef( r ) {}
130 0 : ScSingleRefToken( const ScSingleRefToken& r ) :
131 0 : 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 0 : virtual FormulaToken* Clone() const SAL_OVERRIDE { return new ScSingleRefToken(*this); }
136 :
137 : #if DEBUG_FORMULA_COMPILER
138 : virtual void Dump() const;
139 : #endif
140 0 : DECL_FIXEDMEMPOOL_NEWDEL( ScSingleRefToken );
141 : };
142 :
143 0 : class ScDoubleRefToken : public ScToken
144 : {
145 : private:
146 : ScComplexRefData aDoubleRef;
147 : public:
148 0 : ScDoubleRefToken( const ScComplexRefData& r, OpCode e = ocPush ) :
149 0 : ScToken( formula::svDoubleRef, e ), aDoubleRef( r ) {}
150 : ScDoubleRefToken( const ScSingleRefData& r, OpCode e = ocPush ) :
151 : ScToken( formula::svDoubleRef, e )
152 : {
153 : aDoubleRef.Ref1 = r;
154 : aDoubleRef.Ref2 = r;
155 : }
156 0 : ScDoubleRefToken( const ScDoubleRefToken& r ) :
157 0 : 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 0 : virtual FormulaToken* Clone() const SAL_OVERRIDE { return new ScDoubleRefToken(*this); }
166 :
167 : #if DEBUG_FORMULA_COMPILER
168 : virtual void Dump() const;
169 : #endif
170 0 : DECL_FIXEDMEMPOOL_NEWDEL( ScDoubleRefToken );
171 : };
172 :
173 0 : class ScMatrixToken : public ScToken
174 : {
175 : private:
176 : ScMatrixRef pMatrix;
177 : public:
178 : ScMatrixToken( const ScMatrixRef& p );
179 : ScMatrixToken( const ScMatrixToken& r );
180 :
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 0 : virtual FormulaToken* Clone() const SAL_OVERRIDE { return new ScMatrixToken(*this); }
185 : };
186 :
187 : /**
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
190 : * represents.
191 : */
192 0 : class ScMatrixRangeToken : public ScToken
193 : {
194 : ScMatrixRef mpMatrix;
195 : ScComplexRefData maRef;
196 : public:
197 : ScMatrixRangeToken( const ScMatrixRef& p, const ScComplexRefData& rRef );
198 : ScMatrixRangeToken( const sc::RangeMatrix& rMat );
199 : ScMatrixRangeToken( const ScMatrixRangeToken& r );
200 :
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;
208 : };
209 :
210 : class ScExternalSingleRefToken : public ScToken
211 : {
212 : sal_uInt16 mnFileId;
213 : svl::SharedString maTabName;
214 : ScSingleRefData maSingleRef;
215 :
216 : ScExternalSingleRefToken(); // disabled
217 : public:
218 : ScExternalSingleRefToken( sal_uInt16 nFileId, const svl::SharedString& rTabName, const ScSingleRefData& r );
219 : ScExternalSingleRefToken( const ScExternalSingleRefToken& r );
220 : virtual ~ScExternalSingleRefToken();
221 :
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 0 : virtual FormulaToken* Clone() const SAL_OVERRIDE { return new ScExternalSingleRefToken(*this); }
228 : };
229 :
230 :
231 : class ScExternalDoubleRefToken : public ScToken
232 : {
233 : sal_uInt16 mnFileId;
234 : svl::SharedString maTabName; // name of the first sheet
235 : ScComplexRefData maDoubleRef;
236 :
237 : ScExternalDoubleRefToken(); // disabled
238 : public:
239 : ScExternalDoubleRefToken( sal_uInt16 nFileId, const svl::SharedString& rTabName, const ScComplexRefData& r );
240 : ScExternalDoubleRefToken( const ScExternalDoubleRefToken& r );
241 : virtual ~ScExternalDoubleRefToken();
242 :
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 0 : virtual FormulaToken* Clone() const SAL_OVERRIDE { return new ScExternalDoubleRefToken(*this); }
253 : };
254 :
255 : class ScExternalNameToken : public ScToken
256 : {
257 : sal_uInt16 mnFileId;
258 : svl::SharedString maName;
259 :
260 : ScExternalNameToken(); // disabled
261 : public:
262 : ScExternalNameToken( sal_uInt16 nFileId, const svl::SharedString& rName );
263 : ScExternalNameToken( const ScExternalNameToken& r );
264 : virtual ~ScExternalNameToken();
265 :
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 0 : virtual FormulaToken* Clone() const SAL_OVERRIDE { return new ScExternalNameToken(*this); }
270 : };
271 :
272 :
273 : // Only created from within the interpreter, no conversion from ScRawToken,
274 : // never added to ScTokenArray!
275 : class ScJumpMatrixToken : public ScToken
276 : {
277 : private:
278 : ScJumpMatrix* pJumpMatrix;
279 : public:
280 0 : ScJumpMatrixToken( ScJumpMatrix* p ) :
281 0 : ScToken( formula::svJumpMatrix ), pJumpMatrix( p ) {}
282 0 : ScJumpMatrixToken( const ScJumpMatrixToken& r ) :
283 0 : 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 0 : virtual FormulaToken* Clone() const SAL_OVERRIDE { return new ScJumpMatrixToken(*this); }
288 : };
289 :
290 :
291 : // Only created from within the interpreter, no conversion from ScRawToken,
292 : // never added to ScTokenArray!
293 0 : class ScRefListToken : public ScToken
294 : {
295 : private:
296 : ScRefList aRefList;
297 : public:
298 0 : ScRefListToken() :
299 0 : ScToken( formula::svRefList ) {}
300 0 : ScRefListToken( const ScRefListToken & r ) :
301 0 : 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 0 : virtual FormulaToken* Clone() const SAL_OVERRIDE { return new ScRefListToken(*this); }
306 : };
307 :
308 :
309 0 : class SC_DLLPUBLIC ScEmptyCellToken : public ScToken
310 : {
311 : bool bInherited :1;
312 : bool bDisplayedAsString :1;
313 : public:
314 0 : explicit ScEmptyCellToken( bool bInheritedP, bool bDisplayAsString ) :
315 : ScToken( formula::svEmptyCell ),
316 : bInherited( bInheritedP ),
317 0 : bDisplayedAsString( bDisplayAsString ) {}
318 0 : ScEmptyCellToken( const ScEmptyCellToken& r ) :
319 : ScToken( r ),
320 : bInherited( r.bInherited ),
321 0 : bDisplayedAsString( r.bDisplayedAsString ) {}
322 0 : bool IsInherited() const { return bInherited; }
323 0 : 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 0 : virtual FormulaToken* Clone() const SAL_OVERRIDE { return new ScEmptyCellToken(*this); }
328 : };
329 :
330 :
331 : /** Transports the result from the interpreter to the formula cell. */
332 0 : class SC_DLLPUBLIC ScMatrixCellResultToken : public ScToken
333 : {
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;
337 :
338 : protected:
339 : ScConstMatrixRef xMatrix;
340 : formula::FormulaConstTokenRef xUpperLeft;
341 : public:
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 0 : formula::StackVar GetUpperLeftType() const
350 : {
351 : return xUpperLeft ?
352 0 : xUpperLeft->GetType() :
353 0 : static_cast<formula::StackVar>(formula::svUnknown);
354 : }
355 0 : inline formula::FormulaConstTokenRef GetUpperLeftToken() const { return xUpperLeft; }
356 : void Assign( const ScMatrixCellResultToken & r );
357 : };
358 :
359 :
360 : /** Stores the matrix result at the formula cell, additionally the range the
361 : matrix formula occupies. */
362 0 : class SC_DLLPUBLIC ScMatrixFormulaCellToken : public ScMatrixCellResultToken
363 : {
364 : private:
365 : SCROW nRows;
366 : SCCOL nCols;
367 : public:
368 : ScMatrixFormulaCellToken( SCCOL nC, SCROW nR, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL );
369 : ScMatrixFormulaCellToken( SCCOL nC, SCROW nR );
370 : ScMatrixFormulaCellToken( const ScMatrixFormulaCellToken& r );
371 :
372 : virtual bool operator==( const formula::FormulaToken& rToken ) const SAL_OVERRIDE;
373 0 : virtual FormulaToken* Clone() const SAL_OVERRIDE { return new ScMatrixFormulaCellToken(*this); }
374 0 : void SetMatColsRows( SCCOL nC, SCROW nR )
375 : {
376 0 : nRows = nR;
377 0 : nCols = nC;
378 0 : }
379 0 : void GetMatColsRows( SCCOL & nC, SCROW & nR ) const
380 : {
381 0 : nR = nRows;
382 0 : nC = nCols;
383 0 : }
384 0 : SCCOL GetMatCols() const { return nCols; }
385 0 : SCROW GetMatRows() const { return nRows; }
386 :
387 : /** Assign matrix result, keep matrix formula
388 : dimension. */
389 : void Assign( const ScMatrixCellResultToken & r );
390 :
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
396 : be assigned NULL. */
397 : void Assign( const formula::FormulaToken & r );
398 :
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);
403 :
404 : /** Reset matrix and upper left, keep matrix
405 : formula dimension. */
406 : void ResetResult();
407 : };
408 :
409 :
410 0 : class SC_DLLPUBLIC ScHybridCellToken : public ScToken
411 : {
412 : private:
413 : double mfDouble;
414 : svl::SharedString maString;
415 : OUString maFormula;
416 : public:
417 0 : ScHybridCellToken( double f,
418 : const svl::SharedString & rStr,
419 : const OUString & rFormula ) :
420 : ScToken( formula::svHybridCell ),
421 : mfDouble( f ), maString( rStr ),
422 0 : maFormula( rFormula ) {}
423 :
424 0 : const OUString& GetFormula() const { return maFormula; }
425 : virtual double GetDouble() const SAL_OVERRIDE;
426 :
427 : virtual svl::SharedString GetString() const SAL_OVERRIDE;
428 : virtual bool operator==( const formula::FormulaToken& rToken ) const SAL_OVERRIDE;
429 0 : virtual FormulaToken* Clone() const SAL_OVERRIDE { return new ScHybridCellToken(*this); }
430 : };
431 :
432 : // Simplify argument passing to RefUpdate methods with ScSingleRefToken or
433 : // ScDoubleRefToken
434 : class SingleDoubleRefModifier
435 : {
436 : ScComplexRefData aDub;
437 : ScSingleRefData* pS;
438 : ScComplexRefData* pD;
439 :
440 : // not implemented, prevent usage
441 : SingleDoubleRefModifier( const SingleDoubleRefModifier& );
442 : SingleDoubleRefModifier& operator=( const SingleDoubleRefModifier& );
443 :
444 : public:
445 0 : SingleDoubleRefModifier( ScToken& rT )
446 : {
447 0 : formula::StackVar eType = rT.GetType();
448 0 : if ( eType == formula::svSingleRef || eType == formula::svExternalSingleRef )
449 : {
450 0 : pS = &rT.GetSingleRef();
451 0 : aDub.Ref1 = aDub.Ref2 = *pS;
452 0 : pD = &aDub;
453 : }
454 : else
455 : {
456 0 : pS = 0;
457 0 : pD = &rT.GetDoubleRef();
458 : }
459 0 : }
460 0 : SingleDoubleRefModifier( ScSingleRefData& rS )
461 : {
462 0 : pS = &rS;
463 0 : aDub.Ref1 = aDub.Ref2 = *pS;
464 0 : pD = &aDub;
465 0 : }
466 0 : ~SingleDoubleRefModifier()
467 : {
468 0 : if ( pS )
469 0 : *pS = (*pD).Ref1;
470 0 : }
471 0 : inline ScComplexRefData& Ref() { return *pD; }
472 : };
473 :
474 : class SingleDoubleRefProvider
475 : {
476 : public:
477 :
478 : const ScSingleRefData& Ref1;
479 : const ScSingleRefData& Ref2;
480 :
481 0 : SingleDoubleRefProvider( const ScToken& r )
482 0 : : Ref1( r.GetSingleRef() ),
483 0 : Ref2( (r.GetType() == formula::svDoubleRef ||
484 0 : r.GetType() == formula::svExternalDoubleRef) ?
485 0 : r.GetDoubleRef().Ref2 : Ref1 )
486 0 : {}
487 : SingleDoubleRefProvider( const ScSingleRefData& r )
488 : : Ref1( r ), Ref2( r )
489 : {}
490 : SingleDoubleRefProvider( const ScComplexRefData& r )
491 : : Ref1( r.Ref1 ), Ref2( r.Ref2 )
492 : {}
493 0 : ~SingleDoubleRefProvider()
494 0 : {}
495 : };
496 :
497 : #endif
498 :
499 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|