[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:
ridiculousfish 2017-11-22 13:27:09 -08:00
parent 65f4963542
commit 9443a4bf2d
6 changed files with 13 additions and 218 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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:
//---------------------------------------------------------------------------

View File

@ -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.

View File

@ -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.

View File

@ -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) {