muParser API -  1.35
Public Member Functions | List of all members
mu::ParserByteCode Class Referencefinal

Bytecode implementation of the Math Parser. More...

#include <muParserBytecode.h>

Public Member Functions

 ParserByteCode ()
 Bytecode default constructor.
 
 ParserByteCode (const ParserByteCode &a_ByteCode)
 Copy constructor. More...
 
ParserByteCodeoperator= (const ParserByteCode &a_ByteCode)
 Assignment operator. More...
 
void Assign (const ParserByteCode &a_ByteCode)
 Copy state of another object to this. More...
 
void AddVar (value_type *a_pVar)
 Add a Variable pointer to bytecode. More...
 
void AddVal (value_type a_fVal)
 Add a Variable pointer to bytecode. More...
 
void AddOp (ECmdCode a_Oprt)
 Add an operator identifier to bytecode. More...
 
void AddIfElse (ECmdCode a_Oprt)
 
void AddAssignOp (value_type *a_pVar)
 Add an assignment operator. More...
 
void AddFun (generic_fun_type a_pFun, int a_iArgc)
 Add function to bytecode. More...
 
void AddBulkFun (generic_fun_type a_pFun, int a_iArgc)
 Add a bulk function to bytecode. More...
 
void AddStrFun (generic_fun_type a_pFun, int a_iArgc, int a_iIdx)
 Add Strung function entry to the parser bytecode. More...
 
void EnableOptimizer (bool bStat)
 
void Finalize ()
 Add end marker to bytecode. More...
 
void clear ()
 Delete the bytecode. More...
 
std::size_t GetMaxStackSize () const
 
std::size_t GetSize () const
 
const STokenGetBase () const
 
void AsciiDump ()
 Dump bytecode (for debugging only!).
 

Detailed Description

Bytecode implementation of the Math Parser.

The bytecode contains the formula converted to revers polish notation stored in a continious memory area. Associated with this data are operator codes, variable pointers, constant values and function pointers. Those are necessary in order to calculate the result. All those data items will be casted to the underlying datatype of the bytecode.

Definition at line 87 of file muParserBytecode.h.

Constructor & Destructor Documentation

mu::ParserByteCode::ParserByteCode ( const ParserByteCode a_ByteCode)

Copy constructor.

Implemented in Terms of Assign(const ParserByteCode &a_ByteCode)

Definition at line 60 of file muParserBytecode.cpp.

61  {
62  Assign(a_ByteCode);
63  }
void Assign(const ParserByteCode &a_ByteCode)
Copy state of another object to this.

Member Function Documentation

void mu::ParserByteCode::AddAssignOp ( value_type a_pVar)

Add an assignment operator.

Operator entries in byte code consist of:

  • cmASSIGN code
  • the pointer of the destination variable
See also
ParserToken::ECmdCode

Definition at line 353 of file muParserBytecode.cpp.

354  {
355  --m_iStackPos;
356 
357  SToken tok;
358  tok.Cmd = cmASSIGN;
359  tok.Oprt.ptr = a_pVar;
360  m_vRPN.push_back(tok);
361  }
Operator item: Assignment operator.
Definition: muParserDef.h:153
void mu::ParserByteCode::AddBulkFun ( generic_fun_type  a_pFun,
int  a_iArgc 
)

Add a bulk function to bytecode.

Parameters
a_iArgcNumber of arguments, negative numbers indicate multiarg functions.
a_pFunPointer to function callback.

Definition at line 443 of file muParserBytecode.cpp.

444  {
445  m_iStackPos = m_iStackPos - a_iArgc + 1;
446  m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
447 
448  SToken tok;
449  tok.Cmd = cmFUNC_BULK;
450  tok.Fun.argc = a_iArgc;
451  tok.Fun.ptr = a_pFun;
452  m_vRPN.push_back(tok);
453  }
Special callbacks for Bulk mode with an additional parameter for the bulk index.
Definition: muParserDef.h:172
void mu::ParserByteCode::AddFun ( generic_fun_type  a_pFun,
int  a_iArgc 
)

Add function to bytecode.

Parameters
a_iArgcNumber of arguments, negative numbers indicate multiarg functions.
a_pFunPointer to function callback.

Definition at line 369 of file muParserBytecode.cpp.

370  {
371  std::size_t sz = m_vRPN.size();
372  bool optimize = false;
373 
374  // only optimize functions with fixed number of more than a single arguments
375  if (m_bEnableOptimizer && a_iArgc > 0)
376  {
377  // <ibg 2020-06-10/> Unary Plus is a no-op
378  if ((void*)a_pFun == (void*)&MathImpl<value_type>::UnaryPlus)
379  return;
380 
381  optimize = true;
382 
383  for (int i = 0; i < std::abs(a_iArgc); ++i)
384  {
385  if (m_vRPN[sz - i - 1].Cmd != cmVAL)
386  {
387  optimize = false;
388  break;
389  }
390  }
391  }
392 
393  if (optimize)
394  {
395  value_type val = 0;
396  switch (a_iArgc)
397  {
398  case 1: val = (*reinterpret_cast<fun_type1>(a_pFun))(m_vRPN[sz - 1].Val.data2); break;
399  case 2: val = (*reinterpret_cast<fun_type2>(a_pFun))(m_vRPN[sz - 2].Val.data2, m_vRPN[sz - 1].Val.data2); break;
400  case 3: val = (*reinterpret_cast<fun_type3>(a_pFun))(m_vRPN[sz - 3].Val.data2, m_vRPN[sz - 2].Val.data2, m_vRPN[sz - 1].Val.data2); break;
401  case 4: val = (*reinterpret_cast<fun_type4>(a_pFun))(m_vRPN[sz - 4].Val.data2, m_vRPN[sz - 3].Val.data2, m_vRPN[sz - 2].Val.data2, m_vRPN[sz - 1].Val.data2); break;
402  case 5: val = (*reinterpret_cast<fun_type5>(a_pFun))(m_vRPN[sz - 5].Val.data2, m_vRPN[sz - 4].Val.data2, m_vRPN[sz - 3].Val.data2, m_vRPN[sz - 2].Val.data2, m_vRPN[sz - 1].Val.data2); break;
403  case 6: val = (*reinterpret_cast<fun_type6>(a_pFun))(m_vRPN[sz - 6].Val.data2, m_vRPN[sz - 5].Val.data2, m_vRPN[sz - 4].Val.data2, m_vRPN[sz - 3].Val.data2, m_vRPN[sz - 2].Val.data2, m_vRPN[sz - 1].Val.data2); break;
404  case 7: val = (*reinterpret_cast<fun_type7>(a_pFun))(m_vRPN[sz - 7].Val.data2, m_vRPN[sz - 6].Val.data2, m_vRPN[sz - 5].Val.data2, m_vRPN[sz - 4].Val.data2, m_vRPN[sz - 3].Val.data2, m_vRPN[sz - 2].Val.data2, m_vRPN[sz - 1].Val.data2); break;
405  case 8: val = (*reinterpret_cast<fun_type8>(a_pFun))(m_vRPN[sz - 8].Val.data2, m_vRPN[sz - 7].Val.data2, m_vRPN[sz - 6].Val.data2, m_vRPN[sz - 5].Val.data2, m_vRPN[sz - 4].Val.data2, m_vRPN[sz - 3].Val.data2, m_vRPN[sz - 2].Val.data2, m_vRPN[sz - 1].Val.data2); break;
406  case 9: val = (*reinterpret_cast<fun_type9>(a_pFun))(m_vRPN[sz - 9].Val.data2, m_vRPN[sz - 8].Val.data2, m_vRPN[sz - 7].Val.data2, m_vRPN[sz - 6].Val.data2, m_vRPN[sz - 5].Val.data2, m_vRPN[sz - 4].Val.data2, m_vRPN[sz - 3].Val.data2, m_vRPN[sz - 2].Val.data2, m_vRPN[sz - 1].Val.data2); break;
407  case 10: val = (*reinterpret_cast<fun_type10>(a_pFun))(m_vRPN[sz - 10].Val.data2, m_vRPN[sz - 9].Val.data2, m_vRPN[sz - 8].Val.data2, m_vRPN[sz - 7].Val.data2, m_vRPN[sz - 6].Val.data2, m_vRPN[sz - 5].Val.data2, m_vRPN[sz - 4].Val.data2, m_vRPN[sz - 3].Val.data2, m_vRPN[sz - 2].Val.data2, m_vRPN[sz - 1].Val.data2); break;
408  default:
409  // For now functions with unlimited number of arguments are not optimized
410  throw ParserError(ecINTERNAL_ERROR);
411  }
412 
413  // remove the folded values
414  m_vRPN.erase(m_vRPN.end() - a_iArgc, m_vRPN.end());
415 
416  SToken tok;
417  tok.Cmd = cmVAL;
418  tok.Val.data = 0;
419  tok.Val.data2 = val;
420  tok.Val.ptr = nullptr;
421  m_vRPN.push_back(tok);
422  }
423  else
424  {
425  SToken tok;
426  tok.Cmd = cmFUNC;
427  tok.Fun.argc = a_iArgc;
428  tok.Fun.ptr = a_pFun;
429  m_vRPN.push_back(tok);
430  }
431 
432  m_iStackPos = m_iStackPos - std::abs(a_iArgc) + 1;
433  m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
434 
435  }
Internal error of any kind.
Definition: muParserDef.h:279
value_type(* fun_type5)(value_type, value_type, value_type, value_type, value_type)
Callback type used for functions with five arguments.
Definition: muParserDef.h:343
value_type(* fun_type1)(value_type)
Callback type used for functions with a single arguments.
Definition: muParserDef.h:331
Code for a generic function item.
Definition: muParserDef.h:170
value_type(* fun_type8)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type)
Callback type used for functions with eight arguments.
Definition: muParserDef.h:352
value_type(* fun_type10)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type)
Callback type used for functions with ten arguments.
Definition: muParserDef.h:358
value_type(* fun_type9)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type)
Callback type used for functions with nine arguments.
Definition: muParserDef.h:355
value_type(* fun_type2)(value_type, value_type)
Callback type used for functions with two arguments.
Definition: muParserDef.h:334
MUP_BASETYPE value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:294
value item
Definition: muParserDef.h:161
value_type(* fun_type3)(value_type, value_type, value_type)
Callback type used for functions with three arguments.
Definition: muParserDef.h:337
value_type(* fun_type4)(value_type, value_type, value_type, value_type)
Callback type used for functions with four arguments.
Definition: muParserDef.h:340
value_type(* fun_type7)(value_type, value_type, value_type, value_type, value_type, value_type, value_type)
Callback type used for functions with seven arguments.
Definition: muParserDef.h:349
value_type(* fun_type6)(value_type, value_type, value_type, value_type, value_type, value_type)
Callback type used for functions with six arguments.
Definition: muParserDef.h:346
void mu::ParserByteCode::AddOp ( ECmdCode  a_Oprt)

Add an operator identifier to bytecode.

Operator entries in byte code consist of:

  • value array position of the result
  • the operator code according to ParserToken::ECmdCode
See also
ParserToken::ECmdCode

Definition at line 189 of file muParserBytecode.cpp.

190  {
191  bool bOptimized = false;
192 
193  if (m_bEnableOptimizer)
194  {
195  std::size_t sz = m_vRPN.size();
196 
197  // Check for foldable constants like:
198  // cmVAL cmVAL cmADD
199  // where cmADD can stand fopr any binary operator applied to
200  // two constant values.
201  if (sz >= 2 && m_vRPN[sz - 2].Cmd == cmVAL && m_vRPN[sz - 1].Cmd == cmVAL)
202  {
203  ConstantFolding(a_Oprt);
204  bOptimized = true;
205  }
206  else
207  {
208  switch (a_Oprt)
209  {
210  case cmPOW:
211  // Optimization for polynomials of low order
212  if (m_vRPN[sz - 2].Cmd == cmVAR && m_vRPN[sz - 1].Cmd == cmVAL)
213  {
214  if (m_vRPN[sz - 1].Val.data2 == 0)
215  {
216  m_vRPN[sz - 2].Cmd = cmVAL;
217  m_vRPN[sz - 2].Val.ptr = nullptr;
218  m_vRPN[sz - 2].Val.data = 0;
219  m_vRPN[sz - 2].Val.data2 = 1;
220  }
221  else if (m_vRPN[sz - 1].Val.data2 == 1)
222  m_vRPN[sz - 2].Cmd = cmVAR;
223  else if (m_vRPN[sz - 1].Val.data2 == 2)
224  m_vRPN[sz - 2].Cmd = cmVARPOW2;
225  else if (m_vRPN[sz - 1].Val.data2 == 3)
226  m_vRPN[sz - 2].Cmd = cmVARPOW3;
227  else if (m_vRPN[sz - 1].Val.data2 == 4)
228  m_vRPN[sz - 2].Cmd = cmVARPOW4;
229  else
230  break;
231 
232  m_vRPN.pop_back();
233  bOptimized = true;
234  }
235  break;
236 
237  case cmSUB:
238  case cmADD:
239  // Simple optimization based on pattern recognition for a shitload of different
240  // bytecode combinations of addition/subtraction
241  if ((m_vRPN[sz - 1].Cmd == cmVAR && m_vRPN[sz - 2].Cmd == cmVAL) ||
242  (m_vRPN[sz - 1].Cmd == cmVAL && m_vRPN[sz - 2].Cmd == cmVAR) ||
243  (m_vRPN[sz - 1].Cmd == cmVAL && m_vRPN[sz - 2].Cmd == cmVARMUL) ||
244  (m_vRPN[sz - 1].Cmd == cmVARMUL && m_vRPN[sz - 2].Cmd == cmVAL) ||
245  (m_vRPN[sz - 1].Cmd == cmVAR && m_vRPN[sz - 2].Cmd == cmVAR && m_vRPN[sz - 2].Val.ptr == m_vRPN[sz - 1].Val.ptr) ||
246  (m_vRPN[sz - 1].Cmd == cmVAR && m_vRPN[sz - 2].Cmd == cmVARMUL && m_vRPN[sz - 2].Val.ptr == m_vRPN[sz - 1].Val.ptr) ||
247  (m_vRPN[sz - 1].Cmd == cmVARMUL && m_vRPN[sz - 2].Cmd == cmVAR && m_vRPN[sz - 2].Val.ptr == m_vRPN[sz - 1].Val.ptr) ||
248  (m_vRPN[sz - 1].Cmd == cmVARMUL && m_vRPN[sz - 2].Cmd == cmVARMUL && m_vRPN[sz - 2].Val.ptr == m_vRPN[sz - 1].Val.ptr))
249  {
250  MUP_ASSERT(
251  (m_vRPN[sz - 2].Val.ptr == nullptr && m_vRPN[sz - 1].Val.ptr != nullptr) ||
252  (m_vRPN[sz - 2].Val.ptr != nullptr && m_vRPN[sz - 1].Val.ptr == nullptr) ||
253  (m_vRPN[sz - 2].Val.ptr == m_vRPN[sz - 1].Val.ptr));
254 
255  m_vRPN[sz - 2].Cmd = cmVARMUL;
256  m_vRPN[sz - 2].Val.ptr = (value_type*)((long long)(m_vRPN[sz - 2].Val.ptr) | (long long)(m_vRPN[sz - 1].Val.ptr)); // variable
257  m_vRPN[sz - 2].Val.data2 += ((a_Oprt == cmSUB) ? -1 : 1) * m_vRPN[sz - 1].Val.data2; // offset
258  m_vRPN[sz - 2].Val.data += ((a_Oprt == cmSUB) ? -1 : 1) * m_vRPN[sz - 1].Val.data; // multiplicand
259  m_vRPN.pop_back();
260  bOptimized = true;
261  }
262  break;
263 
264  case cmMUL:
265  if ((m_vRPN[sz - 1].Cmd == cmVAR && m_vRPN[sz - 2].Cmd == cmVAL) ||
266  (m_vRPN[sz - 1].Cmd == cmVAL && m_vRPN[sz - 2].Cmd == cmVAR))
267  {
268  m_vRPN[sz - 2].Cmd = cmVARMUL;
269  m_vRPN[sz - 2].Val.ptr = (value_type*)((long long)(m_vRPN[sz - 2].Val.ptr) | (long long)(m_vRPN[sz - 1].Val.ptr));
270  m_vRPN[sz - 2].Val.data = m_vRPN[sz - 2].Val.data2 + m_vRPN[sz - 1].Val.data2;
271  m_vRPN[sz - 2].Val.data2 = 0;
272  m_vRPN.pop_back();
273  bOptimized = true;
274  }
275  else if (
276  (m_vRPN[sz - 1].Cmd == cmVAL && m_vRPN[sz - 2].Cmd == cmVARMUL) ||
277  (m_vRPN[sz - 1].Cmd == cmVARMUL && m_vRPN[sz - 2].Cmd == cmVAL))
278  {
279  // Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2
280  m_vRPN[sz - 2].Cmd = cmVARMUL;
281  m_vRPN[sz - 2].Val.ptr = (value_type*)((long long)(m_vRPN[sz - 2].Val.ptr) | (long long)(m_vRPN[sz - 1].Val.ptr));
282  if (m_vRPN[sz - 1].Cmd == cmVAL)
283  {
284  m_vRPN[sz - 2].Val.data *= m_vRPN[sz - 1].Val.data2;
285  m_vRPN[sz - 2].Val.data2 *= m_vRPN[sz - 1].Val.data2;
286  }
287  else
288  {
289  m_vRPN[sz - 2].Val.data = m_vRPN[sz - 1].Val.data * m_vRPN[sz - 2].Val.data2;
290  m_vRPN[sz - 2].Val.data2 = m_vRPN[sz - 1].Val.data2 * m_vRPN[sz - 2].Val.data2;
291  }
292  m_vRPN.pop_back();
293  bOptimized = true;
294  }
295  else if (
296  m_vRPN[sz - 1].Cmd == cmVAR && m_vRPN[sz - 2].Cmd == cmVAR &&
297  m_vRPN[sz - 1].Val.ptr == m_vRPN[sz - 2].Val.ptr)
298  {
299  // Optimization: a*a -> a^2
300  m_vRPN[sz - 2].Cmd = cmVARPOW2;
301  m_vRPN.pop_back();
302  bOptimized = true;
303  }
304  break;
305 
306  case cmDIV:
307  if (m_vRPN[sz - 1].Cmd == cmVAL && m_vRPN[sz - 2].Cmd == cmVARMUL && m_vRPN[sz - 1].Val.data2 != 0)
308  {
309  // Optimization: 4*a/2 -> 2*a
310  m_vRPN[sz - 2].Val.data /= m_vRPN[sz - 1].Val.data2;
311  m_vRPN[sz - 2].Val.data2 /= m_vRPN[sz - 1].Val.data2;
312  m_vRPN.pop_back();
313  bOptimized = true;
314  }
315  break;
316 
317  // no optimization for other opcodes
318  default:
319  break;
320  } // switch a_Oprt
321  }
322  }
323 
324  // If optimization can't be applied just write the value
325  if (!bOptimized)
326  {
327  --m_iStackPos;
328  SToken tok;
329  tok.Cmd = a_Oprt;
330  m_vRPN.push_back(tok);
331  }
332  }
Operator item: y to the power of ...
Definition: muParserDef.h:150
Operator item: subtract.
Definition: muParserDef.h:147
Operator item: multiply.
Definition: muParserDef.h:148
#define MUP_ASSERT(COND)
An assertion that does not kill the program.
Definition: muParserDef.h:77
MUP_BASETYPE value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:294
Operator item: division.
Definition: muParserDef.h:149
Operator item: add.
Definition: muParserDef.h:146
value item
Definition: muParserDef.h:161
variable item
Definition: muParserDef.h:160
void mu::ParserByteCode::AddStrFun ( generic_fun_type  a_pFun,
int  a_iArgc,
int  a_iIdx 
)

Add Strung function entry to the parser bytecode.

Exceptions
nothrowA string function entry consists of the stack position of the return value, followed by a cmSTRFUNC code, the function pointer and an index into the string buffer maintained by the parser.

Definition at line 463 of file muParserBytecode.cpp.

464  {
465  m_iStackPos = m_iStackPos - a_iArgc + 1;
466 
467  SToken tok;
468  tok.Cmd = cmFUNC_STR;
469  tok.Fun.argc = a_iArgc;
470  tok.Fun.idx = a_iIdx;
471  tok.Fun.ptr = a_pFun;
472  m_vRPN.push_back(tok);
473 
474  m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
475  }
Code for a function with a string parameter.
Definition: muParserDef.h:171
void mu::ParserByteCode::AddVal ( value_type  a_fVal)

Add a Variable pointer to bytecode.

Value entries in byte code consist of:

  • value array position of the value
  • the operator code according to ParserToken::cmVAL
  • the value stored in #mc_iSizeVal number of bytecode entries.
Parameters
a_pValValue to be added.
Exceptions
nothrow

Definition at line 130 of file muParserBytecode.cpp.

131  {
132  ++m_iStackPos;
133  m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
134 
135  // If optimization does not apply
136  SToken tok;
137  tok.Cmd = cmVAL;
138  tok.Val.ptr = nullptr;
139  tok.Val.data = 0;
140  tok.Val.data2 = a_fVal;
141  m_vRPN.push_back(tok);
142  }
value item
Definition: muParserDef.h:161
void mu::ParserByteCode::AddVar ( value_type a_pVar)

Add a Variable pointer to bytecode.

Parameters
a_pVarPointer to be added.
Exceptions
nothrow

Definition at line 103 of file muParserBytecode.cpp.

104  {
105  ++m_iStackPos;
106  m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
107 
108  // optimization does not apply
109  SToken tok;
110  tok.Cmd = cmVAR;
111  tok.Val.ptr = a_pVar;
112  tok.Val.data = 1;
113  tok.Val.data2 = 0;
114  m_vRPN.push_back(tok);
115  }
variable item
Definition: muParserDef.h:160
void mu::ParserByteCode::Assign ( const ParserByteCode a_ByteCode)

Copy state of another object to this.

Exceptions
nowthrow

Definition at line 87 of file muParserBytecode.cpp.

Referenced by operator=(), and ParserByteCode().

88  {
89  if (this == &a_ByteCode)
90  return;
91 
92  m_iStackPos = a_ByteCode.m_iStackPos;
93  m_vRPN = a_ByteCode.m_vRPN;
94  m_iMaxStackSize = a_ByteCode.m_iMaxStackSize;
95  m_bEnableOptimizer = a_ByteCode.m_bEnableOptimizer;
96  }
void mu::ParserByteCode::clear ( )

Delete the bytecode.

Exceptions
nothrowThe name of this function is a violation of my own coding guidelines but this way it's more in line with the STL functions thus more intuitive.

Definition at line 534 of file muParserBytecode.cpp.

535  {
536  m_vRPN.clear();
537  m_iStackPos = 0;
538  m_iMaxStackSize = 0;
539  }
void mu::ParserByteCode::Finalize ( )

Add end marker to bytecode.

Exceptions
nothrow

Definition at line 482 of file muParserBytecode.cpp.

483  {
484  SToken tok;
485  tok.Cmd = cmEND;
486  m_vRPN.push_back(tok);
487  rpn_type(m_vRPN).swap(m_vRPN); // shrink bytecode vector to fit
488 
489  // Determine the if-then-else jump offsets
490  std::stack<int> stIf, stElse;
491  int idx;
492  for (int i = 0; i < (int)m_vRPN.size(); ++i)
493  {
494  switch (m_vRPN[i].Cmd)
495  {
496  case cmIF:
497  stIf.push(i);
498  break;
499 
500  case cmELSE:
501  stElse.push(i);
502  idx = stIf.top();
503  stIf.pop();
504  m_vRPN[idx].Oprt.offset = i - idx;
505  break;
506 
507  case cmENDIF:
508  idx = stElse.top();
509  stElse.pop();
510  m_vRPN[idx].Oprt.offset = i - idx;
511  break;
512 
513  default:
514  break;
515  }
516  }
517  }
For use in the ternary if-then-else operator.
Definition: muParserDef.h:156
end of formula
Definition: muParserDef.h:177
For use in the ternary if-then-else operator.
Definition: muParserDef.h:157
For use in the ternary if-then-else operator.
Definition: muParserDef.h:158
ParserByteCode & mu::ParserByteCode::operator= ( const ParserByteCode a_ByteCode)

Assignment operator.

Implemented in Terms of Assign(const ParserByteCode &a_ByteCode)

Definition at line 70 of file muParserBytecode.cpp.

71  {
72  Assign(a_ByteCode);
73  return *this;
74  }
void Assign(const ParserByteCode &a_ByteCode)
Copy state of another object to this.

The documentation for this class was generated from the following files: