1 /* 2 <pre> 3 __________ ____ ___ 4 _____ __ _\______ \_____ _______ ______ __________\ \/ / 5 / \| | \ ___/\__ \\_ __ \/ ___// __ \_ __ \ / 6 | Y Y \ | / | / __ \| | \/\___ \\ ___/| | \/ \ 7 |__|_| /____/|____| (____ /__| /____ >\___ >__| /___/\ \ 8 \/ \/ \/ \/ \_/ 9 Copyright (C) 2016 Ingo Berg 10 All rights reserved. 11 12 muParserX - A C++ math parser library with array and string support 13 Copyright (c) 2016, Ingo Berg 14 All rights reserved. 15 16 Redistribution and use in source and binary forms, with or without 17 modification, are permitted provided that the following conditions are met: 18 19 * Redistributions of source code must retain the above copyright notice, 20 this list of conditions and the following disclaimer. 21 * Redistributions in binary form must reproduce the above copyright notice, 22 this list of conditions and the following disclaimer in the documentation 23 and/or other materials provided with the distribution. 24 25 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 29 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 30 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 32 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 POSSIBILITY OF SUCH DAMAGE. 35 </pre> 36 */ 37 #ifndef MUP_ITOKEN_H 38 #define MUP_ITOKEN_H 39 40 #include <list> 41 #include "mpTypes.h" 42 #include "mpFwdDecl.h" 43 44 MUP_NAMESPACE_START 45 46 //------------------------------------------------------------------------------ 47 /** \brief Generic token interface for expression tokens. 48 \author (C) 2010 Ingo Berg 49 50 Tokens can either be Functions, operators, values, variables or necessary 51 base tokens like brackets. ´The IToken baseclass implements reference 52 counting. Only TokenPtr<...> templates may be used as pointers to tokens. 53 */ 54 class IToken 55 { 56 friend std::ostream& operator<<(std::ostream &a_Stream, const IToken &a_Val); 57 friend std::wostream& operator<<(std::wostream &a_Stream, const IToken &a_Val); 58 59 friend class TokenPtr<IToken>; 60 friend class TokenPtr<IValue>; 61 friend class TokenPtr<IOprtBin>; 62 friend class TokenPtr<IOprtInfix>; 63 friend class TokenPtr<IOprtPostfix>; 64 friend class TokenPtr<IFunction>; 65 friend class TokenPtr<Value>; 66 friend class TokenPtr<Variable>; 67 friend class TokenPtr<ICallback>; 68 friend class TokenPtr<IOprtBinShortcut>; 69 70 public: 71 72 enum EFlags 73 { 74 flNONE = 0, 75 flVOLATILE = 1 76 }; 77 78 virtual IToken* Clone() const = 0; 79 virtual string_type ToString() const; 80 virtual string_type AsciiDump() const; 81 82 virtual ICallback* AsICallback(); 83 virtual IValue* AsIValue(); 84 virtual IPrecedence* AsIPrecedence(); 85 86 virtual void Compile(const string_type &sArg); 87 88 ECmdCode GetCode() const; 89 int GetExprPos() const; 90 91 const string_type& GetIdent() const; 92 long GetRef() const; 93 void SetIdent(const string_type &a_sIdent); 94 void SetExprPos(int nPos); 95 96 void AddFlags(int flags); 97 bool IsFlagSet(int flags) const; 98 99 protected: 100 101 explicit IToken(ECmdCode a_iCode); 102 virtual ~IToken(); 103 IToken(ECmdCode a_iCode, string_type a_sIdent); 104 IToken(const IToken &ref); 105 106 void ResetRef(); 107 108 private: 109 110 /** \brief Release the token. 111 112 This Function either deletes the token or releases it to 113 the value cache for reuse without deletion. 114 */ 115 virtual void Release(); 116 117 void IncRef() const; 118 long DecRef() const; 119 120 ECmdCode m_eCode; 121 string_type m_sIdent; 122 int m_nPosExpr; ///< Original position of the token in the expression 123 mutable long m_nRefCount; ///< Reference counter. 124 int m_flags; 125 126 #ifdef MUP_LEAKAGE_REPORT 127 static std::list<IToken*> s_Tokens; 128 129 public: 130 static void LeakageReport(); 131 #endif 132 }; 133 134 135 //--------------------------------------------------------------------------- 136 /** \brief Default token implentation. 137 */ 138 class GenericToken : public IToken 139 { 140 public: 141 GenericToken(ECmdCode a_iCode, string_type a_sIdent); 142 explicit GenericToken(ECmdCode a_iCode); 143 GenericToken(const GenericToken &a_Tok); 144 virtual ~GenericToken(); 145 virtual IToken* Clone() const; 146 virtual string_type AsciiDump() const; 147 }; 148 149 //------------------------------------------------------------------------------ 150 template<typename T> 151 class TokenPtr 152 { 153 public: 154 155 typedef T* token_type; 156 157 //--------------------------------------------------------------------------- 158 TokenPtr(token_type p = 0) m_pTok(p)159 :m_pTok(p) 160 { 161 if (m_pTok) 162 m_pTok->IncRef(); 163 } 164 165 //--------------------------------------------------------------------------- TokenPtr(const TokenPtr & p)166 TokenPtr(const TokenPtr &p) 167 :m_pTok(p.m_pTok) 168 { 169 if (m_pTok) 170 m_pTok->IncRef(); 171 } 172 173 //--------------------------------------------------------------------------- ~TokenPtr()174 ~TokenPtr() 175 { 176 if (m_pTok && m_pTok->DecRef()==0) 177 m_pTok->Release(); 178 } 179 180 //--------------------------------------------------------------------------- 181 token_type operator->() const 182 { 183 return static_cast<token_type>(m_pTok); 184 } 185 186 //--------------------------------------------------------------------------- 187 T& operator*() const 188 { 189 assert(m_pTok); 190 return *(static_cast<token_type>(m_pTok)); 191 } 192 193 //--------------------------------------------------------------------------- Get()194 token_type Get() const 195 { 196 return static_cast<token_type>(m_pTok); 197 } 198 199 //--------------------------------------------------------------------------- 200 /** \brief Release the managed pointer and assign a new pointer. */ Reset(token_type tok)201 void Reset(token_type tok) 202 { 203 if (m_pTok && m_pTok->DecRef()==0) 204 { 205 m_pTok->Release(); 206 //delete m_pTok; 207 } 208 209 tok->IncRef(); 210 m_pTok = tok; 211 } 212 213 //--------------------------------------------------------------------------- 214 TokenPtr& operator=(const TokenPtr &p) 215 { 216 if (p.m_pTok) 217 p.m_pTok->IncRef(); 218 219 if (m_pTok && m_pTok->DecRef()==0) 220 { 221 m_pTok->Release(); 222 //delete m_pTok; 223 } 224 225 m_pTok = p.m_pTok; 226 227 return *this; 228 } 229 230 private: 231 IToken *m_pTok; 232 }; 233 234 MUP_NAMESPACE_END 235 236 #endif // include guard 237