Coverage Report

Created: 2026-02-14 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/muparser/include/muParserToken.h
Line
Count
Source
1
/*
2
3
   _____  __ _____________ _______  ______ ___________
4
  /     \|  |  \____ \__  \\_  __ \/  ___// __ \_  __ \
5
   |  Y Y  \  |  /  |_> > __ \|  | \/\___ \\  ___/|  | \/
6
   |__|_|  /____/|   __(____  /__|  /____  >\___  >__|
7
     \/      |__|       \/           \/     \/
8
   Copyright (C) 2004 - 2022 Ingo Berg
9
10
  Redistribution and use in source and binary forms, with or without modification, are permitted
11
  provided that the following conditions are met:
12
13
    * Redistributions of source code must retain the above copyright notice, this list of
14
    conditions and the following disclaimer.
15
    * Redistributions in binary form must reproduce the above copyright notice, this list of
16
    conditions and the following disclaimer in the documentation and/or other materials provided
17
    with the distribution.
18
19
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20
  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21
  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22
  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25
  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26
  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
*/
28
29
#ifndef MU_PARSER_TOKEN_H
30
#define MU_PARSER_TOKEN_H
31
32
#include <string>
33
#include <stack>
34
#include <vector>
35
#include <memory>
36
#include <utility>
37
#include <type_traits>
38
#include <cstddef>
39
40
#if defined(_MSC_VER)
41
  #pragma warning(push)
42
  #pragma warning(disable : 26812) 
43
#endif
44
45
#include "muParserError.h"
46
#include "muParserCallback.h"
47
48
/** \file
49
  \brief This file contains the parser token definition.
50
*/
51
52
namespace mu
53
{
54
  template <std::size_t NbParams> struct TplCallType;
55
  template <> struct TplCallType<0> { using fun_type = fun_type0; using fun_userdata_type = fun_userdata_type0; using bulkfun_type = bulkfun_type0; using bulkfun_userdata_type = bulkfun_userdata_type0; };
56
  template <> struct TplCallType<1> { using fun_type = fun_type1; using fun_userdata_type = fun_userdata_type1; using bulkfun_type = bulkfun_type1; using bulkfun_userdata_type = bulkfun_userdata_type1; using strfun_type = strfun_type1; using strfun_userdata_type = strfun_userdata_type1; };
57
  template <> struct TplCallType<2> { using fun_type = fun_type2; using fun_userdata_type = fun_userdata_type2; using bulkfun_type = bulkfun_type2; using bulkfun_userdata_type = bulkfun_userdata_type2; using strfun_type = strfun_type2; using strfun_userdata_type = strfun_userdata_type2; };
58
  template <> struct TplCallType<3> { using fun_type = fun_type3; using fun_userdata_type = fun_userdata_type3; using bulkfun_type = bulkfun_type3; using bulkfun_userdata_type = bulkfun_userdata_type3; using strfun_type = strfun_type3; using strfun_userdata_type = strfun_userdata_type3; };
59
  template <> struct TplCallType<4> { using fun_type = fun_type4; using fun_userdata_type = fun_userdata_type4; using bulkfun_type = bulkfun_type4; using bulkfun_userdata_type = bulkfun_userdata_type4; using strfun_type = strfun_type4; using strfun_userdata_type = strfun_userdata_type4; };
60
  template <> struct TplCallType<5> { using fun_type = fun_type5; using fun_userdata_type = fun_userdata_type5; using bulkfun_type = bulkfun_type5; using bulkfun_userdata_type = bulkfun_userdata_type5; using strfun_type = strfun_type5; using strfun_userdata_type = strfun_userdata_type5; };
61
  template <> struct TplCallType<6> { using fun_type = fun_type6; using fun_userdata_type = fun_userdata_type6; using bulkfun_type = bulkfun_type6; using bulkfun_userdata_type = bulkfun_userdata_type6; using strfun_type = strfun_type6; using strfun_userdata_type = strfun_userdata_type6; };
62
  template <> struct TplCallType<7> { using fun_type = fun_type7; using fun_userdata_type = fun_userdata_type7; using bulkfun_type = bulkfun_type7; using bulkfun_userdata_type = bulkfun_userdata_type7; };
63
  template <> struct TplCallType<8> { using fun_type = fun_type8; using fun_userdata_type = fun_userdata_type8; using bulkfun_type = bulkfun_type8; using bulkfun_userdata_type = bulkfun_userdata_type8; };
64
  template <> struct TplCallType<9> { using fun_type = fun_type9; using fun_userdata_type = fun_userdata_type9; using bulkfun_type = bulkfun_type9; using bulkfun_userdata_type = bulkfun_userdata_type9; };
65
  template <> struct TplCallType<10> { using fun_type = fun_type10; using fun_userdata_type = fun_userdata_type10; using bulkfun_type = bulkfun_type10; using bulkfun_userdata_type = bulkfun_userdata_type10; };
66
67
  struct generic_callable_type
68
  {
69
    // Note: we keep generic_callable_type a pod for the purpose of layout
70
71
    erased_fun_type _pRawFun;
72
    void*           _pUserData;
73
74
    template <std::size_t NbParams, typename... Args>
75
    value_type call_fun(Args&&... args) const
76
10.3k
    {
77
10.3k
      static_assert(NbParams == sizeof...(Args), "mismatch between NbParams and Args");
78
10.3k
      if (_pUserData == nullptr) 
79
10.3k
      {
80
10.3k
        auto fun_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::fun_type>(_pRawFun);
81
10.3k
        return (*fun_typed_ptr)(std::forward<Args>(args)...);
82
10.3k
      } 
83
0
      else 
84
0
      {
85
0
        auto fun_userdata_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::fun_userdata_type>(_pRawFun);
86
0
        return (*fun_userdata_typed_ptr)(_pUserData, std::forward<Args>(args)...);
87
0
      }
88
10.3k
    }
double mu::generic_callable_type::call_fun<0ul>() const
Line
Count
Source
76
741
    {
77
741
      static_assert(NbParams == sizeof...(Args), "mismatch between NbParams and Args");
78
741
      if (_pUserData == nullptr) 
79
741
      {
80
741
        auto fun_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::fun_type>(_pRawFun);
81
741
        return (*fun_typed_ptr)(std::forward<Args>(args)...);
82
741
      } 
83
0
      else 
84
0
      {
85
0
        auto fun_userdata_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::fun_userdata_type>(_pRawFun);
86
0
        return (*fun_userdata_typed_ptr)(_pUserData, std::forward<Args>(args)...);
87
0
      }
88
741
    }
double mu::generic_callable_type::call_fun<1ul, double&>(double&) const
Line
Count
Source
76
9.16k
    {
77
9.16k
      static_assert(NbParams == sizeof...(Args), "mismatch between NbParams and Args");
78
9.16k
      if (_pUserData == nullptr) 
79
9.16k
      {
80
9.16k
        auto fun_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::fun_type>(_pRawFun);
81
9.16k
        return (*fun_typed_ptr)(std::forward<Args>(args)...);
82
9.16k
      } 
83
0
      else 
84
0
      {
85
0
        auto fun_userdata_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::fun_userdata_type>(_pRawFun);
86
0
        return (*fun_userdata_typed_ptr)(_pUserData, std::forward<Args>(args)...);
87
0
      }
88
9.16k
    }
double mu::generic_callable_type::call_fun<2ul, double&, double&>(double&, double&) const
Line
Count
Source
76
412
    {
77
412
      static_assert(NbParams == sizeof...(Args), "mismatch between NbParams and Args");
78
412
      if (_pUserData == nullptr) 
79
412
      {
80
412
        auto fun_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::fun_type>(_pRawFun);
81
412
        return (*fun_typed_ptr)(std::forward<Args>(args)...);
82
412
      } 
83
0
      else 
84
0
      {
85
0
        auto fun_userdata_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::fun_userdata_type>(_pRawFun);
86
0
        return (*fun_userdata_typed_ptr)(_pUserData, std::forward<Args>(args)...);
87
0
      }
88
412
    }
Unexecuted instantiation: double mu::generic_callable_type::call_fun<3ul, double&, double&, double&>(double&, double&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_fun<4ul, double&, double&, double&, double&>(double&, double&, double&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_fun<5ul, double&, double&, double&, double&, double&>(double&, double&, double&, double&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_fun<6ul, double&, double&, double&, double&, double&, double&>(double&, double&, double&, double&, double&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_fun<7ul, double&, double&, double&, double&, double&, double&, double&>(double&, double&, double&, double&, double&, double&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_fun<8ul, double&, double&, double&, double&, double&, double&, double&, double&>(double&, double&, double&, double&, double&, double&, double&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_fun<9ul, double&, double&, double&, double&, double&, double&, double&, double&, double&>(double&, double&, double&, double&, double&, double&, double&, double&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_fun<10ul, double&, double&, double&, double&, double&, double&, double&, double&, double&, double&>(double&, double&, double&, double&, double&, double&, double&, double&, double&, double&) const
89
90
    template <std::size_t NbParams, typename... Args>
91
    value_type call_bulkfun(Args&&... args) const
92
0
    {
93
0
      static_assert(NbParams == sizeof...(Args) - 2, "mismatch between NbParams and Args");
94
0
      if (_pUserData == nullptr) {
95
0
        auto bulkfun_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::bulkfun_type>(_pRawFun);
96
0
        return (*bulkfun_typed_ptr)(std::forward<Args>(args)...);
97
0
      } else {
98
0
        auto bulkfun_userdata_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::bulkfun_userdata_type>(_pRawFun);
99
0
        return (*bulkfun_userdata_typed_ptr)(_pUserData, std::forward<Args>(args)...);
100
0
      }
101
0
    }
Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<0ul, int&, int&>(int&, int&) const
Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<1ul, int&, int&, double&>(int&, int&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<2ul, int&, int&, double&, double&>(int&, int&, double&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<3ul, int&, int&, double&, double&, double&>(int&, int&, double&, double&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<4ul, int&, int&, double&, double&, double&, double&>(int&, int&, double&, double&, double&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<5ul, int&, int&, double&, double&, double&, double&, double&>(int&, int&, double&, double&, double&, double&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<6ul, int&, int&, double&, double&, double&, double&, double&, double&>(int&, int&, double&, double&, double&, double&, double&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<7ul, int&, int&, double&, double&, double&, double&, double&, double&, double&>(int&, int&, double&, double&, double&, double&, double&, double&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<8ul, int&, int&, double&, double&, double&, double&, double&, double&, double&, double&>(int&, int&, double&, double&, double&, double&, double&, double&, double&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<9ul, int&, int&, double&, double&, double&, double&, double&, double&, double&, double&, double&>(int&, int&, double&, double&, double&, double&, double&, double&, double&, double&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_bulkfun<10ul, int&, int&, double&, double&, double&, double&, double&, double&, double&, double&, double&, double&>(int&, int&, double&, double&, double&, double&, double&, double&, double&, double&, double&, double&) const
102
103
    value_type call_multfun(const value_type* a_afArg, int a_iArgc) const
104
3.79k
    {
105
3.79k
      if (_pUserData == nullptr) {
106
3.79k
        auto multfun_typed_ptr = reinterpret_cast<multfun_type>(_pRawFun);
107
3.79k
        return (*multfun_typed_ptr)(a_afArg, a_iArgc);
108
3.79k
      } else {
109
0
        auto multfun_userdata_typed_ptr = reinterpret_cast<multfun_userdata_type>(_pRawFun);
110
0
        return (*multfun_userdata_typed_ptr)(_pUserData, a_afArg, a_iArgc);
111
0
      }
112
3.79k
    }
113
114
    template <std::size_t NbParams, typename... Args>
115
    value_type call_strfun(Args&&... args) const
116
0
    {
117
0
      static_assert(NbParams == sizeof...(Args), "mismatch between NbParams and Args");
118
0
      if (_pUserData == nullptr) 
119
0
      {
120
0
        auto strfun_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::strfun_type>(_pRawFun);
121
0
        return (*strfun_typed_ptr)(std::forward<Args>(args)...);
122
0
      } 
123
0
      else 
124
0
      {
125
0
        auto strfun_userdata_typed_ptr = reinterpret_cast<typename TplCallType<NbParams>::strfun_userdata_type>(_pRawFun);
126
0
        return (*strfun_userdata_typed_ptr)(_pUserData, std::forward<Args>(args)...);
127
0
      }
128
0
    }
Unexecuted instantiation: double mu::generic_callable_type::call_strfun<1ul, char const*>(char const*&&) const
Unexecuted instantiation: double mu::generic_callable_type::call_strfun<2ul, char const*, double&>(char const*&&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_strfun<3ul, char const*, double&, double&>(char const*&&, double&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_strfun<4ul, char const*, double&, double&, double&>(char const*&&, double&, double&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_strfun<5ul, char const*, double&, double&, double&, double&>(char const*&&, double&, double&, double&, double&) const
Unexecuted instantiation: double mu::generic_callable_type::call_strfun<6ul, char const*, double&, double&, double&, double&, double&>(char const*&&, double&, double&, double&, double&, double&) const
129
130
    bool operator==(generic_callable_type other) const 
131
42.7k
    {
132
42.7k
      return _pRawFun == other._pRawFun && _pUserData == other._pUserData; 
133
42.7k
    }
134
135
    explicit operator bool() const 
136
0
    {
137
0
      return _pRawFun != nullptr; 
138
0
    }
139
140
    bool operator==(std::nullptr_t) const 
141
48.5k
    {
142
48.5k
      return _pRawFun == nullptr; 
143
48.5k
    }
144
    
145
    bool operator!=(std::nullptr_t) const 
146
91.6k
    {
147
91.6k
      return _pRawFun != nullptr; 
148
91.6k
    }
149
  };
150
151
  static_assert(std::is_trivial<generic_callable_type>::value, "generic_callable_type shall be trivial");
152
  static_assert(std::is_standard_layout<generic_callable_type>::value, "generic_callable_type shall have standard layout");
153
  // C++17: static_assert(std::is_aggregate<generic_callable_type>::value, "generic_callable_type shall be an aggregate");
154
155
  /** \brief Encapsulation of the data for a single formula token.
156
157
    Formula token implementation. Part of the Math Parser Package.
158
    Formula tokens can be either one of the following:
159
    <ul>
160
      <li>value</li>
161
      <li>variable</li>
162
      <li>function with numerical arguments</li>
163
      <li>functions with a string as argument</li>
164
      <li>prefix operators</li>
165
      <li>infix operators</li>
166
      <li>binary operator</li>
167
    </ul>
168
  */
169
  template<typename TBase, typename TString>
170
  class ParserToken final
171
  {
172
  private:
173
174
    ECmdCode  m_iCode;  ///< Type of the token; The token type is a constant of type #ECmdCode.
175
    ETypeCode m_iType;
176
    void* m_pTok;   ///< Stores Token pointer; not applicable for all tokens
177
    int  m_iIdx;    ///< An otional index to an external buffer storing the token data
178
    TString m_strTok;   ///< Token string
179
    TString m_strVal;   ///< Value for string variables
180
    value_type m_fVal;  ///< the value 
181
    std::unique_ptr<ParserCallback> m_pCallback;
182
183
  public:
184
185
    /** \brief Constructor (default).
186
187
      Sets token to an neutral state of type cmUNKNOWN.
188
      \throw nothrow
189
      \sa ECmdCode
190
    */
191
    ParserToken()
192
2.52M
      :m_iCode(cmUNKNOWN)
193
2.52M
      , m_iType(tpVOID)
194
2.52M
      , m_pTok(0)
195
2.52M
      , m_iIdx(-1)
196
2.52M
      , m_strTok()
197
2.52M
      , m_strVal()
198
2.52M
      , m_fVal(0)
199
2.52M
      , m_pCallback()
200
2.52M
    {}
201
202
    //------------------------------------------------------------------------------
203
    /** \brief Create token from another one.
204
205
      Implemented by calling Assign(...)
206
      \throw nothrow
207
      \post m_iType==cmUNKNOWN
208
      \sa #Assign
209
    */
210
    ParserToken(const ParserToken& a_Tok)
211
5.24M
    {
212
5.24M
      Assign(a_Tok);
213
5.24M
    }
214
215
    
216
    /** \brief Assignment operator.
217
218
      Copy token state from another token and return this.
219
      Implemented by calling Assign(...).
220
      \throw nothrow
221
    */
222
    ParserToken& operator=(const ParserToken& a_Tok)
223
6.89M
    {
224
6.89M
      Assign(a_Tok);
225
6.89M
      return *this;
226
6.89M
    }
227
228
229
    /** \brief Copy token information from argument.
230
231
      \throw nothrow
232
    */
233
    void Assign(const ParserToken& a_Tok)
234
12.1M
    {
235
12.1M
      m_iCode = a_Tok.m_iCode;
236
12.1M
      m_pTok = a_Tok.m_pTok;
237
12.1M
      m_strTok = a_Tok.m_strTok;
238
12.1M
      m_iIdx = a_Tok.m_iIdx;
239
12.1M
      m_strVal = a_Tok.m_strVal;
240
12.1M
      m_iType = a_Tok.m_iType;
241
12.1M
      m_fVal = a_Tok.m_fVal;
242
      // create new callback object if a_Tok has one 
243
12.1M
      m_pCallback.reset(a_Tok.m_pCallback.get() ? a_Tok.m_pCallback->Clone() : 0);
244
12.1M
    }
245
246
    //------------------------------------------------------------------------------
247
    /** \brief Assign a token type.
248
249
      Token may not be of type value, variable or function. Those have separate set functions.
250
251
      \pre [assert] a_iType!=cmVAR
252
      \pre [assert] a_iType!=cmVAL
253
      \pre [assert] a_iType!=cmFUNC
254
      \post m_fVal = 0
255
      \post m_pTok = 0
256
    */
257
    ParserToken& Set(ECmdCode a_iType, const TString& a_strTok = TString())
258
1.61M
    {
259
      // The following types can't be set this way, they have special Set functions
260
1.61M
      MUP_ASSERT(a_iType != cmVAR);
261
1.61M
      MUP_ASSERT(a_iType != cmVAL);
262
1.61M
      MUP_ASSERT(a_iType != cmFUNC);
263
264
1.61M
      m_iCode = a_iType;
265
1.61M
      m_iType = tpVOID;
266
1.61M
      m_pTok = 0;
267
1.61M
      m_strTok = a_strTok;
268
1.61M
      m_iIdx = -1;
269
270
1.61M
      return *this;
271
1.61M
    }
272
273
    //------------------------------------------------------------------------------
274
    /** \brief Set Callback type. */
275
    ParserToken& Set(const ParserCallback& a_pCallback, const TString& a_sTok)
276
52.9k
    {
277
52.9k
      MUP_ASSERT(a_pCallback.IsValid());
278
279
52.9k
      m_iCode = a_pCallback.GetCode();
280
52.9k
      m_iType = tpVOID;
281
52.9k
      m_strTok = a_sTok;
282
52.9k
      m_pCallback.reset(new ParserCallback(a_pCallback));
283
284
52.9k
      m_pTok = 0;
285
52.9k
      m_iIdx = -1;
286
287
52.9k
      return *this;
288
52.9k
    }
289
290
    //------------------------------------------------------------------------------
291
    /** \brief Make this token a value token.
292
293
      Member variables not necessary for value tokens will be invalidated.
294
      \throw nothrow
295
    */
296
    ParserToken& SetVal(TBase a_fVal, const TString& a_strTok = TString())
297
684k
    {
298
684k
      m_iCode = cmVAL;
299
684k
      m_iType = tpDBL;
300
684k
      m_fVal = a_fVal;
301
684k
      m_strTok = a_strTok;
302
684k
      m_iIdx = -1;
303
304
684k
      m_pTok = 0;
305
684k
      m_pCallback.reset(0);
306
307
684k
      return *this;
308
684k
    }
309
310
    //------------------------------------------------------------------------------
311
    /** \brief make this token a variable token.
312
313
      Member variables not necessary for variable tokens will be invalidated.
314
      \throw nothrow
315
    */
316
    ParserToken& SetVar(TBase* a_pVar, const TString& a_strTok)
317
0
    {
318
0
      m_iCode = cmVAR;
319
0
      m_iType = tpDBL;
320
0
      m_strTok = a_strTok;
321
0
      m_iIdx = -1;
322
0
      m_pTok = (void*)a_pVar;
323
0
      m_pCallback.reset(0);
324
0
      return *this;
325
0
    }
326
327
    //------------------------------------------------------------------------------
328
    /** \brief Make this token a variable token.
329
330
      Member variables not necessary for variable tokens will be invalidated.
331
      \throw nothrow
332
    */
333
    ParserToken& SetString(const TString& a_strTok, std::size_t a_iSize)
334
15.4k
    {
335
15.4k
      m_iCode = cmSTRING;
336
15.4k
      m_iType = tpSTR;
337
15.4k
      m_strTok = a_strTok;
338
15.4k
      m_iIdx = static_cast<int>(a_iSize);
339
340
15.4k
      m_pTok = 0;
341
15.4k
      m_pCallback.reset(0);
342
15.4k
      return *this;
343
15.4k
    }
344
345
    //------------------------------------------------------------------------------
346
    /** \brief Set an index associated with the token related data.
347
348
      In cmSTRFUNC - This is the index to a string table in the main parser.
349
      \param a_iIdx The index the string function result will take in the bytecode parser.
350
      \throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING
351
    */
352
    void SetIdx(int a_iIdx)
353
15.3k
    {
354
15.3k
      if (m_iCode != cmSTRING || a_iIdx < 0)
355
0
        throw ParserError(ecINTERNAL_ERROR);
356
357
15.3k
      m_iIdx = a_iIdx;
358
15.3k
    }
359
360
    //------------------------------------------------------------------------------
361
    /** \brief Return Index associated with the token related data.
362
363
      In cmSTRFUNC - This is the index to a string table in the main parser.
364
365
      \throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING
366
      \return The index the result will take in the Bytecode calculatin array (#m_iIdx).
367
    */
368
    int GetIdx() const
369
0
    {
370
0
      if (m_iIdx < 0 || m_iCode != cmSTRING)
371
0
        throw ParserError(ecINTERNAL_ERROR);
372
373
0
      return m_iIdx;
374
0
    }
375
376
    //------------------------------------------------------------------------------
377
    /** \brief Return the token type.
378
379
      \return #m_iType
380
      \throw nothrow
381
    */
382
    ECmdCode GetCode() const
383
9.02M
    {
384
9.02M
      if (m_pCallback.get())
385
609k
      {
386
609k
        return m_pCallback->GetCode();
387
609k
      }
388
8.41M
      else
389
8.41M
      {
390
8.41M
        return m_iCode;
391
8.41M
      }
392
9.02M
    }
393
394
    //------------------------------------------------------------------------------
395
    ETypeCode GetType() const
396
649k
    {
397
649k
      if (m_pCallback.get())
398
97.1k
      {
399
97.1k
        return m_pCallback->GetType();
400
97.1k
      }
401
552k
      else
402
552k
      {
403
552k
        return m_iType;
404
552k
      }
405
649k
    }
406
407
    //------------------------------------------------------------------------------
408
    int GetPri() const
409
33.3k
    {
410
33.3k
      if (!m_pCallback.get())
411
0
        throw ParserError(ecINTERNAL_ERROR);
412
413
33.3k
      if (m_pCallback->GetCode() != cmOPRT_BIN && m_pCallback->GetCode() != cmOPRT_INFIX)
414
0
        throw ParserError(ecINTERNAL_ERROR);
415
416
33.3k
      return m_pCallback->GetPri();
417
33.3k
    }
418
419
    //------------------------------------------------------------------------------
420
    EOprtAssociativity GetAssociativity() const
421
0
    {
422
0
      if (m_pCallback.get() == nullptr || m_pCallback->GetCode() != cmOPRT_BIN)
423
0
        throw ParserError(ecINTERNAL_ERROR);
424
425
0
      return m_pCallback->GetAssociativity();
426
0
    }
427
428
    //------------------------------------------------------------------------------
429
    /** \brief Return the address of the callback function assoziated with
430
           function and operator tokens.
431
432
      \return The pointer stored in #m_pTok.
433
      \throw exception_type if token type is non of:
434
           <ul>
435
           <li>cmFUNC</li>
436
           <li>cmSTRFUNC</li>
437
           <li>cmPOSTOP</li>
438
           <li>cmINFIXOP</li>
439
           <li>cmOPRT_BIN</li>
440
           </ul>
441
      \sa ECmdCode
442
    */
443
    generic_callable_type GetFuncAddr() const
444
188k
    {
445
188k
      return (m_pCallback.get())
446
188k
        ? generic_callable_type{(erased_fun_type)m_pCallback->GetAddr(),
447
158k
                                m_pCallback->GetUserData()}
448
188k
        : generic_callable_type{};
449
188k
    }
450
451
    //------------------------------------------------------------------------------
452
    /** \biref Get value of the token.
453
454
      Only applicable to variable and value tokens.
455
      \throw exception_type if token is no value/variable token.
456
    */
457
    TBase GetVal() const
458
599k
    {
459
599k
      switch (m_iCode)
460
599k
      {
461
599k
      case cmVAL:  return m_fVal;
462
0
      case cmVAR:  return *((TBase*)m_pTok);
463
1
      default:     throw ParserError(ecVAL_EXPECTED);
464
599k
      }
465
599k
    }
466
467
    //------------------------------------------------------------------------------
468
    /** \brief Get address of a variable token.
469
470
      Valid only if m_iType==CmdVar.
471
      \throw exception_type if token is no variable token.
472
    */
473
    TBase* GetVar() const
474
0
    {
475
0
      if (m_iCode != cmVAR)
476
0
        throw ParserError(ecINTERNAL_ERROR);
477
478
0
      return (TBase*)m_pTok;
479
0
    }
480
481
    //------------------------------------------------------------------------------
482
    /** \brief Return the number of function arguments.
483
484
      Valid only if m_iType==CmdFUNC.
485
    */
486
    int GetArgCount() const
487
194k
    {
488
194k
      MUP_ASSERT(m_pCallback.get());
489
490
194k
      if (!m_pCallback->IsValid())
491
0
        throw ParserError(ecINTERNAL_ERROR);
492
493
194k
      return m_pCallback->GetArgc();
494
194k
    }
495
496
    //------------------------------------------------------------------------------
497
    /** \brief Return true if the token is a function token that can be optimized.
498
    */
499
    bool IsOptimizable() const
500
48.5k
    {
501
48.5k
      return m_pCallback->IsValid() && m_pCallback->IsOptimizable();
502
48.5k
    }
503
504
    //------------------------------------------------------------------------------
505
    /** \brief Return the token identifier.
506
507
      If #m_iType is cmSTRING the token identifier is the value of the string argument
508
      for a string function.
509
      \return #m_strTok
510
      \throw nothrow
511
      \sa m_strTok
512
    */
513
    const TString& GetAsString() const
514
15.5k
    {
515
15.5k
      return m_strTok;
516
15.5k
    }
517
  };
518
} // namespace mu
519
520
#if defined(_MSC_VER)
521
  #pragma warning(pop)
522
#endif
523
524
#endif