mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-28 12:13:55 +08:00
[muparser] Remove copy and assignment
There is no reason for muParsers to be copyable or assignable. Also remove some dead code and switch an auto_ptr to unique_ptr.
This commit is contained in:
parent
65f4963542
commit
9443a4bf2d
|
@ -92,8 +92,8 @@ class ParserBase {
|
|||
static void EnableDebugDump(bool bDumpCmd, bool bDumpStack);
|
||||
|
||||
ParserBase();
|
||||
ParserBase(const ParserBase &a_Parser);
|
||||
ParserBase &operator=(const ParserBase &a_Parser);
|
||||
ParserBase(const ParserBase &a_Parser) = delete;
|
||||
ParserBase &operator=(const ParserBase &a_Parser) = delete;
|
||||
|
||||
virtual ~ParserBase();
|
||||
|
||||
|
@ -212,7 +212,6 @@ class ParserBase {
|
|||
};
|
||||
|
||||
private:
|
||||
void Assign(const ParserBase &a_Parser);
|
||||
void InitTokenReader();
|
||||
void ReInit() const;
|
||||
|
||||
|
|
|
@ -95,13 +95,10 @@ class ParserByteCode {
|
|||
/** \brief The actual rpn storage. */
|
||||
rpn_type m_vRPN;
|
||||
|
||||
void ConstantFolding(ECmdCode a_Oprt);
|
||||
|
||||
public:
|
||||
ParserByteCode();
|
||||
ParserByteCode(const ParserByteCode &a_ByteCode);
|
||||
ParserByteCode &operator=(const ParserByteCode &a_ByteCode);
|
||||
void Assign(const ParserByteCode &a_ByteCode);
|
||||
ParserByteCode(const ParserByteCode &a_ByteCode) = default;
|
||||
ParserByteCode &operator=(const ParserByteCode &a_ByteCode) = default;
|
||||
|
||||
void AddVar(value_type *a_pVar);
|
||||
void AddVal(value_type a_fVal);
|
||||
|
|
|
@ -65,7 +65,7 @@ class ParserToken {
|
|||
TString m_strTok; ///< Token string
|
||||
TString m_strVal; ///< Value for string variables
|
||||
value_type m_fVal; ///< the value
|
||||
std::auto_ptr<ParserCallback> m_pCallback;
|
||||
std::unique_ptr<ParserCallback> m_pCallback;
|
||||
|
||||
public:
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -87,84 +87,7 @@ ParserBase::ParserBase()
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Copy constructor.
|
||||
|
||||
The parser can be safely copy constructed but the bytecode is reset during
|
||||
copy construction.
|
||||
*/
|
||||
ParserBase::ParserBase(const ParserBase &a_Parser)
|
||||
: m_pParseFormula(&ParserBase::ParseString),
|
||||
m_vRPN(),
|
||||
m_vStringBuf(),
|
||||
m_pTokenReader(),
|
||||
m_FunDef(),
|
||||
m_PostOprtDef(),
|
||||
m_InfixOprtDef(),
|
||||
m_OprtDef(),
|
||||
m_ConstDef(),
|
||||
m_StrVarDef(),
|
||||
m_VarDef(),
|
||||
m_bBuiltInOp(true),
|
||||
m_sNameChars(),
|
||||
m_sOprtChars(),
|
||||
m_sInfixOprtChars(),
|
||||
m_nIfElseCounter(0) {
|
||||
m_pTokenReader.reset(new token_reader_type(this));
|
||||
Assign(a_Parser);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
ParserBase::~ParserBase() {}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Assignment operator.
|
||||
|
||||
Implemented by calling Assign(a_Parser). Self assignment is suppressed.
|
||||
\param a_Parser Object to copy to this.
|
||||
\return *this
|
||||
*/
|
||||
ParserBase &ParserBase::operator=(const ParserBase &a_Parser) {
|
||||
Assign(a_Parser);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Copy state of a parser object to this.
|
||||
|
||||
Clears Variables and Functions of this parser.
|
||||
Copies the states of all internal variables.
|
||||
Resets parse function to string parse mode.
|
||||
|
||||
\param a_Parser the source object.
|
||||
*/
|
||||
void ParserBase::Assign(const ParserBase &a_Parser) {
|
||||
if (&a_Parser == this) return;
|
||||
|
||||
// Don't copy bytecode instead cause the parser to create new bytecode
|
||||
// by resetting the parse function.
|
||||
ReInit();
|
||||
|
||||
m_ConstDef = a_Parser.m_ConstDef; // Copy user define constants
|
||||
m_VarDef = a_Parser.m_VarDef; // Copy user defined variables
|
||||
m_bBuiltInOp = a_Parser.m_bBuiltInOp;
|
||||
m_vStringBuf = a_Parser.m_vStringBuf;
|
||||
m_vStackBuffer = a_Parser.m_vStackBuffer;
|
||||
m_nFinalResultIdx = a_Parser.m_nFinalResultIdx;
|
||||
m_StrVarDef = a_Parser.m_StrVarDef;
|
||||
m_vStringVarBuf = a_Parser.m_vStringVarBuf;
|
||||
m_nIfElseCounter = a_Parser.m_nIfElseCounter;
|
||||
m_pTokenReader.reset(a_Parser.m_pTokenReader->Clone(this));
|
||||
|
||||
// Copy function and operator callbacks
|
||||
m_FunDef = a_Parser.m_FunDef; // Copy function definitions
|
||||
m_PostOprtDef = a_Parser.m_PostOprtDef; // post value unary operators
|
||||
m_InfixOprtDef = a_Parser.m_InfixOprtDef; // unary operators for infix notation
|
||||
m_OprtDef = a_Parser.m_OprtDef; // binary operators
|
||||
|
||||
m_sNameChars = a_Parser.m_sNameChars;
|
||||
m_sOprtChars = a_Parser.m_sOprtChars;
|
||||
m_sInfixOprtChars = a_Parser.m_sInfixOprtChars;
|
||||
}
|
||||
ParserBase::~ParserBase() = default;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Set the decimal separator.
|
||||
|
|
|
@ -43,36 +43,6 @@ ParserByteCode::ParserByteCode() : m_iStackPos(0), m_iMaxStackSize(0), m_vRPN()
|
|||
m_vRPN.reserve(50);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Copy constructor.
|
||||
|
||||
Implemented in Terms of Assign(const ParserByteCode &a_ByteCode)
|
||||
*/
|
||||
ParserByteCode::ParserByteCode(const ParserByteCode &a_ByteCode) { Assign(a_ByteCode); }
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Assignment operator.
|
||||
|
||||
Implemented in Terms of Assign(const ParserByteCode &a_ByteCode)
|
||||
*/
|
||||
ParserByteCode &ParserByteCode::operator=(const ParserByteCode &a_ByteCode) {
|
||||
Assign(a_ByteCode);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Copy state of another object to this.
|
||||
|
||||
\throw nowthrow
|
||||
*/
|
||||
void ParserByteCode::Assign(const ParserByteCode &a_ByteCode) {
|
||||
if (this == &a_ByteCode) return;
|
||||
|
||||
m_iStackPos = a_ByteCode.m_iStackPos;
|
||||
m_vRPN = a_ByteCode.m_vRPN;
|
||||
m_iMaxStackSize = a_ByteCode.m_iMaxStackSize;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Add a Variable pointer to bytecode.
|
||||
\param a_pVar Pointer to be added.
|
||||
|
@ -115,75 +85,6 @@ void ParserByteCode::AddVal(value_type a_fVal) {
|
|||
m_vRPN.push_back(tok);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void ParserByteCode::ConstantFolding(ECmdCode a_Oprt) {
|
||||
std::size_t sz = m_vRPN.size();
|
||||
value_type &x = m_vRPN[sz - 2].Val.data2, &y = m_vRPN[sz - 1].Val.data2;
|
||||
switch (a_Oprt) {
|
||||
case cmLAND:
|
||||
x = (int)x && (int)y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmLOR:
|
||||
x = (int)x || (int)y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmLT:
|
||||
x = x < y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmGT:
|
||||
x = x > y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmLE:
|
||||
x = x <= y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmGE:
|
||||
x = x >= y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmNEQ:
|
||||
x = x != y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmEQ:
|
||||
x = x == y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmADD:
|
||||
x = x + y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmSUB:
|
||||
x = x - y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmMUL:
|
||||
x = x * y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
case cmDIV:
|
||||
|
||||
#if defined(MUP_MATH_EXCEPTIONS)
|
||||
if (y == 0) throw ParserError(ecDIV_BY_ZERO, _T("0"));
|
||||
#endif
|
||||
|
||||
x = x / y;
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
|
||||
case cmPOW:
|
||||
x = MathImpl<value_type>::Pow(x, y);
|
||||
m_vRPN.pop_back();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
} // switch opcode
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
/** \brief Add an operator identifier to bytecode.
|
||||
|
||||
|
|
|
@ -1151,7 +1151,7 @@ int ParserTester::EqnTestWithVarChange(const string_type &a_str, double a_fVar1,
|
|||
int ParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass) {
|
||||
ParserTester::c_iCount++;
|
||||
int iRet(0);
|
||||
value_type fVal[5] = {-999, -998, -997, -996, -995}; // initially should be different
|
||||
value_type fVal[] = {-999, -998, -997}; // initially should be different
|
||||
|
||||
try {
|
||||
std::auto_ptr<Parser> p1;
|
||||
|
@ -1239,31 +1239,10 @@ int ParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass)
|
|||
if (fVal[0] != fVal[1])
|
||||
throw Parser::exception_type(_T("Bytecode / string parsing mismatch."));
|
||||
|
||||
// Test copy and assignment operators
|
||||
try {
|
||||
// Test copy constructor
|
||||
std::vector<mu::Parser> vParser;
|
||||
vParser.push_back(*(p1.get()));
|
||||
mu::Parser p2 = vParser[0]; // take parser from vector
|
||||
|
||||
// destroy the originals from p2
|
||||
vParser.clear(); // delete the vector
|
||||
p1.reset(0);
|
||||
|
||||
fVal[2] = *p2.Eval();
|
||||
|
||||
// Test assignment operator
|
||||
mu::Parser p3;
|
||||
p3 = p2;
|
||||
fVal[3] = *p3.Eval();
|
||||
|
||||
// Test Eval function for multiple return values
|
||||
std::vector<ValueOrError> v;
|
||||
p2.Eval(&v);
|
||||
fVal[4] = *v.back();
|
||||
} catch (std::exception &e) {
|
||||
mu::console() << _T("\n ") << e.what() << _T("\n");
|
||||
}
|
||||
// Test Eval function for multiple return values.
|
||||
std::vector<ValueOrError> v;
|
||||
p1->Eval(&v);
|
||||
fVal[2] = *v.back();
|
||||
|
||||
// limited floating point accuracy requires the following test
|
||||
bool bCloseEnough(true);
|
||||
|
@ -1288,15 +1267,11 @@ int ParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass)
|
|||
mu::console() << _T("\n fail: ") << a_str.c_str()
|
||||
<< _T(" (incorrect result; expected: ") << a_fRes << _T(" ;calculated: ")
|
||||
<< fVal[0] << _T(",") << fVal[1] << _T(",") << fVal[2] << _T(",")
|
||||
<< fVal[3] << _T(",") << fVal[4] << _T(").");
|
||||
<< _T(").");
|
||||
}
|
||||
} catch (Parser::exception_type &e) {
|
||||
if (a_fPass) {
|
||||
if (fVal[0] != fVal[2] && fVal[0] != -999 && fVal[1] != -998)
|
||||
mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (copy construction)");
|
||||
else
|
||||
mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (") << e.GetMsg()
|
||||
<< _T(")");
|
||||
mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (") << e.GetMsg() << _T(")");
|
||||
return 1;
|
||||
}
|
||||
} catch (std::exception &e) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user