make ValueTransfer easier to understand
[LibreOffice.git] / include / formula / token.hxx
blobebb08e6d7c17a40da37b0399e1fd777b8f695854
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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_FORMULA_TOKEN_HXX
21 #define INCLUDED_FORMULA_TOKEN_HXX
23 #include <sal/config.h>
25 #include <cstring>
26 #include <memory>
27 #include <vector>
29 #include <formula/formuladllapi.h>
30 #include <formula/opcode.hxx>
31 #include <formula/types.hxx>
32 #include <formula/paramclass.hxx>
33 #include <osl/interlck.h>
34 #include <rtl/ustring.hxx>
35 #include <sal/types.h>
36 #include <svl/sharedstring.hxx>
38 class ScJumpMatrix;
39 class ScMatrix;
40 struct ScComplexRefData;
41 struct ScSingleRefData;
42 enum class FormulaError : sal_uInt16;
44 namespace formula
47 enum StackVar : sal_uInt8
49 svByte,
50 svDouble,
51 svString,
52 svSingleRef,
53 svDoubleRef,
54 svMatrix,
55 svIndex,
56 svJump,
57 svExternal, // Byte + String
58 svFAP, // FormulaAutoPilot only, ever exported
59 svJumpMatrix,
60 svRefList, // ocUnion result
61 svEmptyCell, // Result is an empty cell, e.g. in LOOKUP()
63 svMatrixCell, // Result is a matrix with bells and
64 // whistles as needed for _the_ matrix
65 // formula result.
67 svHybridCell, // A temporary condition of a formula
68 // cell during import, having a double
69 // and/or string result and a formula
70 // string to be compiled.
72 svExternalSingleRef,
73 svExternalDoubleRef,
74 svExternalName,
75 svSingleVectorRef,
76 svDoubleVectorRef,
77 svError, // error token
78 svMissing, // 0 or ""
79 svSep, // separator, ocSep, ocOpen, ocClose
80 svUnknown // unknown StackType
83 // Only to be used for debugging output. No guarantee of stability of the
84 // return value.
86 // Turn this into an operator<< when StackVar becomes a scoped enum
88 inline std::string StackVarEnumToString(StackVar const e)
90 switch (e)
92 case svByte: return "Byte";
93 case svDouble: return "Double";
94 case svString: return "String";
95 case svSingleRef: return "SingleRef";
96 case svDoubleRef: return "DoubleRef";
97 case svMatrix: return "Matrix";
98 case svIndex: return "Index";
99 case svJump: return "Jump";
100 case svExternal: return "External";
101 case svFAP: return "FAP";
102 case svJumpMatrix: return "JumpMatrix";
103 case svRefList: return "RefList";
104 case svEmptyCell: return "EmptyCell";
105 case svMatrixCell: return "MatrixCell";
106 case svHybridCell: return "HybridCell";
107 case svExternalSingleRef: return "ExternalSingleRef";
108 case svExternalDoubleRef: return "ExternalDoubleRef";
109 case svExternalName: return "ExternalName";
110 case svSingleVectorRef: return "SingleVectorRef";
111 case svDoubleVectorRef: return "DoubleVectorRef";
112 case svError: return "Error";
113 case svMissing: return "Missing";
114 case svSep: return "Sep";
115 case svUnknown: return "Unknown";
117 std::ostringstream os;
118 os << static_cast<int>(e);
119 return os.str();
122 class FORMULA_DLLPUBLIC FormulaToken
124 OpCode eOp;
125 const StackVar eType; // type of data
126 mutable oslInterlockedCount mnRefCnt; // reference count
128 FormulaToken& operator=( const FormulaToken& ) = delete;
129 public:
130 FormulaToken( StackVar eTypeP,OpCode e = ocPush );
131 FormulaToken( const FormulaToken& r );
133 virtual ~FormulaToken();
135 void Delete() { delete this; }
136 void DeleteIfZeroRef() { if (mnRefCnt == 0) delete this; }
137 StackVar GetType() const { return eType; }
138 bool IsFunction() const; // pure functions, no operators
140 bool IsExternalRef() const;
141 bool IsRef() const;
143 sal_uInt8 GetParamCount() const;
145 void IncRef() const
147 osl_atomic_increment(&mnRefCnt);
150 void DecRef() const
152 if (!osl_atomic_decrement(&mnRefCnt))
153 const_cast<FormulaToken*>(this)->Delete();
156 oslInterlockedCount GetRef() const { return mnRefCnt; }
157 OpCode GetOpCode() const { return eOp; }
159 bool IsInForceArray() const;
162 Dummy methods to avoid switches and casts where possible,
163 the real token classes have to override the appropriate method[s].
164 The only methods valid anytime if not overridden are:
166 - GetByte() since this represents the count of parameters to a function
167 which of course is 0 on non-functions. FormulaByteToken and ScExternal do
168 override it.
170 - GetInForceArray() since also this is only used for operators and
171 functions and is ParamClass::Unknown for other tokens.
173 Any other non-overridden method pops up an assertion.
176 virtual sal_uInt8 GetByte() const;
177 virtual void SetByte( sal_uInt8 n );
178 virtual ParamClass GetInForceArray() const;
179 virtual void SetInForceArray( ParamClass c );
180 virtual double GetDouble() const;
181 virtual double& GetDoubleAsReference();
182 virtual sal_Int16 GetDoubleType() const;
183 virtual void SetDoubleType( sal_Int16 nType );
184 virtual const svl::SharedString & GetString() const;
185 virtual void SetString( const svl::SharedString& rStr );
186 virtual sal_uInt16 GetIndex() const;
187 virtual void SetIndex( sal_uInt16 n );
188 virtual sal_Int16 GetSheet() const;
189 virtual void SetSheet( sal_Int16 n );
190 virtual sal_Unicode GetChar() const;
191 virtual short* GetJump() const;
192 virtual const OUString& GetExternal() const;
193 virtual FormulaToken* GetFAPOrigToken() const;
194 virtual FormulaError GetError() const;
195 virtual void SetError( FormulaError );
197 virtual const ScSingleRefData* GetSingleRef() const;
198 virtual ScSingleRefData* GetSingleRef();
199 virtual const ScComplexRefData* GetDoubleRef() const;
200 virtual ScComplexRefData* GetDoubleRef();
201 virtual const ScSingleRefData* GetSingleRef2() const;
202 virtual ScSingleRefData* GetSingleRef2();
203 virtual const ScMatrix* GetMatrix() const;
204 virtual ScMatrix* GetMatrix();
205 virtual ScJumpMatrix* GetJumpMatrix() const;
206 virtual const std::vector<ScComplexRefData>* GetRefList() const;
207 virtual std::vector<ScComplexRefData>* GetRefList();
209 virtual FormulaToken* Clone() const { return new FormulaToken(*this); }
211 virtual bool TextEqual( const formula::FormulaToken& rToken ) const;
212 virtual bool operator==( const FormulaToken& rToken ) const;
214 /** This is dirty and only the compiler should use it! */
215 struct PrivateAccess { friend class FormulaCompiler; private: PrivateAccess() { } };
216 void NewOpCode( OpCode e, const PrivateAccess& ) { eOp = e; }
219 inline void intrusive_ptr_add_ref(const FormulaToken* p)
221 p->IncRef();
224 inline void intrusive_ptr_release(const FormulaToken* p)
226 p->DecRef();
229 class FORMULA_DLLPUBLIC FormulaSpaceToken final : public FormulaToken
231 private:
232 sal_uInt8 nByte;
233 sal_Unicode cChar;
234 public:
235 FormulaSpaceToken( sal_uInt8 n, sal_Unicode c ) :
236 FormulaToken( svByte, ocWhitespace ),
237 nByte( n ), cChar( c ) {}
238 FormulaSpaceToken( const FormulaSpaceToken& r ) :
239 FormulaToken( r ),
240 nByte( r.nByte ), cChar( r.cChar ) {}
242 virtual FormulaToken* Clone() const override { return new FormulaSpaceToken(*this); }
243 virtual sal_uInt8 GetByte() const override;
244 virtual sal_Unicode GetChar() const override;
245 virtual bool operator==( const FormulaToken& rToken ) const override;
248 class FORMULA_DLLPUBLIC FormulaByteToken : public FormulaToken
250 private:
251 sal_uInt8 nByte;
252 ParamClass eInForceArray;
253 protected:
254 FormulaByteToken( OpCode e, sal_uInt8 n, StackVar v, ParamClass c ) :
255 FormulaToken( v,e ), nByte( n ),
256 eInForceArray( c ) {}
257 public:
258 FormulaByteToken( OpCode e, sal_uInt8 n, ParamClass c ) :
259 FormulaToken( svByte,e ), nByte( n ),
260 eInForceArray( c ) {}
261 FormulaByteToken( OpCode e, sal_uInt8 n ) :
262 FormulaToken( svByte,e ), nByte( n ),
263 eInForceArray( ParamClass::Unknown ) {}
264 FormulaByteToken( OpCode e ) :
265 FormulaToken( svByte,e ), nByte( 0 ),
266 eInForceArray( ParamClass::Unknown ) {}
267 FormulaByteToken( const FormulaByteToken& r ) :
268 FormulaToken( r ), nByte( r.nByte ),
269 eInForceArray( r.eInForceArray ) {}
271 virtual FormulaToken* Clone() const override { return new FormulaByteToken(*this); }
272 virtual sal_uInt8 GetByte() const override;
273 virtual void SetByte( sal_uInt8 n ) override;
274 virtual ParamClass GetInForceArray() const override;
275 virtual void SetInForceArray( ParamClass c ) override;
276 virtual bool operator==( const FormulaToken& rToken ) const override;
280 // A special token for the FormulaAutoPilot only. Keeps a reference pointer of
281 // the token of which it was created for comparison.
282 class FORMULA_DLLPUBLIC FormulaFAPToken final : public FormulaByteToken
284 private:
285 FormulaTokenRef pOrigToken;
286 public:
287 FormulaFAPToken( OpCode e, sal_uInt8 n, FormulaToken* p ) :
288 FormulaByteToken( e, n, svFAP, ParamClass::Unknown ),
289 pOrigToken( p ) {}
290 FormulaFAPToken( const FormulaFAPToken& r ) :
291 FormulaByteToken( r ), pOrigToken( r.pOrigToken ) {}
293 virtual FormulaToken* Clone() const override { return new FormulaFAPToken(*this); }
294 virtual FormulaToken* GetFAPOrigToken() const override;
295 virtual bool operator==( const FormulaToken& rToken ) const override;
298 class FORMULA_DLLPUBLIC FormulaDoubleToken : public FormulaToken
300 private:
301 double fDouble;
302 public:
303 FormulaDoubleToken( double f ) :
304 FormulaToken( svDouble ), fDouble( f ) {}
305 FormulaDoubleToken( const FormulaDoubleToken& r ) :
306 FormulaToken( r ), fDouble( r.fDouble ) {}
308 virtual FormulaToken* Clone() const override { return new FormulaDoubleToken(*this); }
309 virtual double GetDouble() const override;
310 virtual double& GetDoubleAsReference() override;
311 virtual sal_Int16 GetDoubleType() const override; ///< always returns 0 for "not typed"
312 virtual bool operator==( const FormulaToken& rToken ) const override;
315 class FORMULA_DLLPUBLIC FormulaTypedDoubleToken final : public FormulaDoubleToken
317 private:
318 sal_Int16 mnType; /**< Can hold, for example, a value
319 of SvNumFormatType, or by
320 contract any other
321 classification. */
322 public:
323 FormulaTypedDoubleToken( double f, sal_Int16 nType ) :
324 FormulaDoubleToken( f ), mnType( nType ) {}
325 FormulaTypedDoubleToken( const FormulaTypedDoubleToken& r ) :
326 FormulaDoubleToken( r ), mnType( r.mnType ) {}
328 virtual FormulaToken* Clone() const override { return new FormulaTypedDoubleToken(*this); }
329 virtual sal_Int16 GetDoubleType() const override;
330 virtual void SetDoubleType( sal_Int16 nType ) override;
331 virtual bool operator==( const FormulaToken& rToken ) const override;
335 class FORMULA_DLLPUBLIC FormulaStringToken final : public FormulaToken
337 svl::SharedString maString;
338 public:
339 FormulaStringToken( const svl::SharedString& r );
340 FormulaStringToken( const FormulaStringToken& r );
342 virtual FormulaToken* Clone() const override;
343 virtual const svl::SharedString & GetString() const override;
344 virtual void SetString( const svl::SharedString& rStr ) override;
345 virtual bool operator==( const FormulaToken& rToken ) const override;
349 /** Identical to FormulaStringToken, but with explicit OpCode instead of implicit
350 ocPush, and an optional sal_uInt8 for ocBad tokens. */
351 class FORMULA_DLLPUBLIC FormulaStringOpToken final : public FormulaByteToken
353 svl::SharedString maString;
354 public:
355 FormulaStringOpToken( OpCode e, const svl::SharedString& r );
356 FormulaStringOpToken( const FormulaStringOpToken& r );
358 virtual FormulaToken* Clone() const override;
359 virtual const svl::SharedString & GetString() const override;
360 virtual void SetString( const svl::SharedString& rStr ) override;
361 virtual bool operator==( const FormulaToken& rToken ) const override;
364 class FORMULA_DLLPUBLIC FormulaIndexToken final : public FormulaToken
366 private:
367 sal_uInt16 nIndex;
368 sal_Int16 mnSheet;
369 public:
370 FormulaIndexToken( OpCode e, sal_uInt16 n, sal_Int16 nSheet = -1 ) :
371 FormulaToken( svIndex, e ), nIndex( n ), mnSheet( nSheet ) {}
372 FormulaIndexToken( const FormulaIndexToken& r ) :
373 FormulaToken( r ), nIndex( r.nIndex ), mnSheet( r.mnSheet ) {}
375 virtual FormulaToken* Clone() const override { return new FormulaIndexToken(*this); }
376 virtual sal_uInt16 GetIndex() const override;
377 virtual void SetIndex( sal_uInt16 n ) override;
378 virtual sal_Int16 GetSheet() const override;
379 virtual void SetSheet( sal_Int16 n ) override;
380 virtual bool operator==( const FormulaToken& rToken ) const override;
384 class FORMULA_DLLPUBLIC FormulaExternalToken final : public FormulaByteToken
386 private:
387 OUString aExternal;
388 public:
389 FormulaExternalToken( OpCode e, sal_uInt8 n, const OUString& r ) :
390 FormulaByteToken( e, n, svExternal, ParamClass::Unknown ),
391 aExternal( r ) {}
392 FormulaExternalToken( OpCode e, const OUString& r ) :
393 FormulaByteToken( e, 0, svExternal, ParamClass::Unknown ),
394 aExternal( r ) {}
395 FormulaExternalToken( const FormulaExternalToken& r ) :
396 FormulaByteToken( r ), aExternal( r.aExternal ) {}
398 virtual FormulaToken* Clone() const override { return new FormulaExternalToken(*this); }
399 virtual const OUString& GetExternal() const override;
400 virtual bool operator==( const FormulaToken& rToken ) const override;
404 class FORMULA_DLLPUBLIC FormulaMissingToken final : public FormulaToken
406 public:
407 FormulaMissingToken() :
408 FormulaToken( svMissing,ocMissing ) {}
409 FormulaMissingToken( const FormulaMissingToken& r ) :
410 FormulaToken( r ) {}
412 virtual FormulaToken* Clone() const override { return new FormulaMissingToken(*this); }
413 virtual double GetDouble() const override;
414 virtual const svl::SharedString & GetString() const override;
415 virtual bool operator==( const FormulaToken& rToken ) const override;
418 class FORMULA_DLLPUBLIC FormulaJumpToken final : public FormulaToken
420 private:
421 std::unique_ptr<short[]>
422 pJump;
423 ParamClass eInForceArray;
424 public:
425 FormulaJumpToken( OpCode e, short const * p ) :
426 FormulaToken( formula::svJump , e),
427 eInForceArray( ParamClass::Unknown)
429 pJump.reset( new short[ p[0] + 1 ] );
430 memcpy( pJump.get(), p, (p[0] + 1) * sizeof(short) );
432 FormulaJumpToken( const FormulaJumpToken& r ) :
433 FormulaToken( r ),
434 eInForceArray( r.eInForceArray)
436 pJump.reset( new short[ r.pJump[0] + 1 ] );
437 memcpy( pJump.get(), r.pJump.get(), (r.pJump[0] + 1) * sizeof(short) );
439 virtual ~FormulaJumpToken() override;
440 virtual short* GetJump() const override;
441 virtual bool operator==( const formula::FormulaToken& rToken ) const override;
442 virtual FormulaToken* Clone() const override { return new FormulaJumpToken(*this); }
443 virtual ParamClass GetInForceArray() const override;
444 virtual void SetInForceArray( ParamClass c ) override;
448 class FORMULA_DLLPUBLIC FormulaUnknownToken final : public FormulaToken
450 public:
451 FormulaUnknownToken( OpCode e ) :
452 FormulaToken( svUnknown, e ) {}
453 FormulaUnknownToken( const FormulaUnknownToken& r ) :
454 FormulaToken( r ) {}
456 virtual FormulaToken* Clone() const override { return new FormulaUnknownToken(*this); }
457 virtual bool operator==( const FormulaToken& rToken ) const override;
461 class FORMULA_DLLPUBLIC FormulaErrorToken final : public FormulaToken
463 FormulaError nError;
464 public:
465 FormulaErrorToken( FormulaError nErr ) :
466 FormulaToken( svError ), nError( nErr) {}
467 FormulaErrorToken( const FormulaErrorToken& r ) :
468 FormulaToken( r ), nError( r.nError) {}
470 virtual FormulaToken* Clone() const override { return new FormulaErrorToken(*this); }
471 virtual FormulaError GetError() const override;
472 virtual void SetError( FormulaError nErr ) override;
473 virtual bool operator==( const FormulaToken& rToken ) const override;
477 } // formula
480 #endif
482 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */