Expressions

- DOM::get now returns the input name by default, rather than "", which
  was the cause of many filter elements not working.
- Modified Variant to have no private data, which means fewer copies of
  Variants and less code.
- Eliminated Variant::operator^ - not needed.
This commit is contained in:
Paul Beckingham 2011-06-19 18:15:09 -04:00
parent 7762ee2f9e
commit 1bf6c8a9fa
4 changed files with 201 additions and 260 deletions

View file

@ -156,7 +156,7 @@ const std::string DOM::get (const std::string& name)
throw format (STRING_DOM_UNREC, name);
}
return "";
return name;
}
////////////////////////////////////////////////////////////////////////////////
@ -300,7 +300,6 @@ void DOM::set (const std::string& name, const std::string& value)
}
////////////////////////////////////////////////////////////////////////////////
// TODO This should return a Variant.
bool DOM::is_primitive (const std::string& input)
{
std::string s;

View file

@ -93,18 +93,18 @@ bool Expression::eval (Task& task)
throw std::string ("Error: Insufficient operands for '!' operator.");
Variant right (value_stack.back ());
if (right.raw_type () == "lvalue")
if (right._raw_type == "lvalue")
{
right = Variant (context.dom.get (right.raw (), task));
right.raw (value_stack.back ().raw ());
right.raw_type (value_stack.back ().raw_type ());
right = Variant (context.dom.get (right._raw, task));
right._raw = value_stack.back ()._raw;
right._raw_type = value_stack.back ()._raw_type;
}
value_stack.pop_back ();
std::cout << "# " << " ! " << right.dump () << "\n";
bool result = !right;
right = Variant (result);
right.raw_type ("bool");
right._raw_type = "bool";
std::cout << "# --> " << right.dump () << "\n";
value_stack.push_back (right);
@ -120,21 +120,21 @@ bool Expression::eval (Task& task)
// rvalue (string, rx, int, number, dom ...).
Variant right (value_stack.back ());
if (right.raw_type () == "lvalue")
if (right._raw_type == "lvalue")
{
right = Variant (context.dom.get (right.raw (), task));
right.raw (value_stack.back ().raw ());
right.raw_type (value_stack.back ().raw_type ());
right = Variant (context.dom.get (right._raw, task));
right._raw = value_stack.back ()._raw;
right._raw_type = value_stack.back ()._raw_type;
}
value_stack.pop_back ();
// lvalue (dom).
Variant left (value_stack.back ());
if (left.raw_type () == "lvalue")
if (left._raw_type == "lvalue")
{
left = Variant (context.dom.get (left.raw (), task));
left.raw (value_stack.back ().raw ());
left.raw_type (value_stack.back ().raw_type ());
left = Variant (context.dom.get (left._raw, task));
left._raw = value_stack.back ()._raw;
left._raw_type = value_stack.back ()._raw_type;
}
value_stack.pop_back ();
@ -144,7 +144,7 @@ bool Expression::eval (Task& task)
std::cout << "# " << left.dump () << " and " << right.dump () << "\n";
bool result = (left && right);
left = Variant (result);
left.raw_type ("bool");
left._raw_type = "bool";
std::cout << "# --> " << left.dump () << "\n";
value_stack.push_back (left);
@ -157,7 +157,7 @@ bool Expression::eval (Task& task)
bool right_bool = right.boolean ();
bool result = (left_bool && !right_bool) || (!left_bool && right_bool);
left = Variant (result);
left.raw_type ("bool");
left._raw_type = "bool";
std::cout << "# --> " << left.dump () << "\n";
value_stack.push_back (left);
@ -168,7 +168,7 @@ bool Expression::eval (Task& task)
std::cout << "# " << left.dump () << " or " << right.dump () << "\n";
bool result = (left || right);
left = Variant (result);
left.raw_type ("bool");
left._raw_type = "bool";
std::cout << "# --> " << left.dump () << "\n";
value_stack.push_back (left);
@ -179,7 +179,7 @@ bool Expression::eval (Task& task)
std::cout << "# " << left.dump () << " <= " << right.dump () << "\n";
bool result = (left <= right);
left = Variant (result);
left.raw_type ("bool");
left._raw_type = "bool";
std::cout << "# --> " << left.dump () << "\n";
value_stack.push_back (left);
@ -190,7 +190,7 @@ bool Expression::eval (Task& task)
std::cout << "# " << left.dump () << " >= " << right.dump () << "\n";
bool result = (left >= right);
left = Variant (result);
left.raw_type ("bool");
left._raw_type = "bool";
std::cout << "# --> " << left.dump () << "\n";
value_stack.push_back (left);
@ -206,7 +206,7 @@ bool Expression::eval (Task& task)
std::cout << "# " << left.dump () << " != " << right.dump () << "\n";
bool result = (left != right);
left = Variant (result);
left.raw_type ("bool");
left._raw_type = "bool";
std::cout << "# --> " << left.dump () << "\n";
value_stack.push_back (left);
@ -217,7 +217,7 @@ bool Expression::eval (Task& task)
std::cout << "# " << left.dump () << " = " << right.dump () << "\n";
bool result = (left == right);
left = Variant (result);
left.raw_type ("bool");
left._raw_type = "bool";
std::cout << "# --> " << left.dump () << "\n";
value_stack.push_back (left);
@ -228,7 +228,7 @@ bool Expression::eval (Task& task)
std::cout << "# " << left.dump () << " > " << right.dump () << "\n";
bool result = (left > right);
left = Variant (result);
left.raw_type ("bool");
left._raw_type = "bool";
std::cout << "# --> " << left.dump () << "\n";
value_stack.push_back (left);
@ -236,30 +236,47 @@ bool Expression::eval (Task& task)
else if (arg->first == "~")
{
std::cout << "# " << left.dump () << " ~ " << right.dump () << "\n";
bool result = false;
// Matches against description are really against either description,
// annotations or project.
if (left.raw () == "description")
if (left._raw == "description")
{
if (right.raw_type () == "rx")
if (right._raw_type == "rx")
{
throw std::string ("rx not supported");
}
else
{
left.cast (Variant::v_string);
right.cast (Variant::v_string);
if (left._string.find (right._string) != std::string::npos)
result = true;
}
}
// Matches against non-description fields are treated as-is.
else
{
if (right.raw_type () == "rx")
if (right._raw_type == "rx")
{
throw std::string ("rx not supported");
}
else
{
left.cast (Variant::v_string);
right.cast (Variant::v_string);
if (left._string.find (right._string) != std::string::npos)
result = true;
}
}
left = Variant (result);
left._raw_type = "bool";
std::cout << "# --> " << left.dump () << "\n";
value_stack.push_back (left);
}
else if (arg->first == "*")
@ -296,7 +313,7 @@ bool Expression::eval (Task& task)
std::cout << "# " << left.dump () << " < " << right.dump () << "\n";
bool result = (left < right);
left = Variant (result);
left.raw_type ("bool");
left._raw_type = "bool";
std::cout << "# --> " << left.dump () << "\n";
value_stack.push_back (left);
@ -355,8 +372,8 @@ void Expression::create_variant (
else
throw std::string ("Unrecognized operand '") + + "'.";
variant.raw (value);
variant.raw_type (type);
variant._raw = value;
variant._raw_type = type;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -33,28 +33,28 @@
////////////////////////////////////////////////////////////////////////////////
Variant::Variant ()
: mType (v_unknown)
, mRaw ("")
, mRawType ("")
: _type (v_unknown)
, _raw ("")
, _raw_type ("")
{
}
////////////////////////////////////////////////////////////////////////////////
Variant::Variant (const Variant& other)
{
mType = other.mType;
mRaw = other.mRaw;
mRawType = other.mRawType;
_type = other._type;
_raw = other._raw;
_raw_type = other._raw_type;
// Explicitly copy only the relevant type. This saves memory.
switch (mType)
switch (_type)
{
case v_boolean: mBool = other.mBool; break;
case v_integer: mInteger = other.mInteger; break;
case v_double: mDouble = other.mDouble; break;
case v_string: mString = other.mString; break;
case v_date: mDate = other.mDate; break;
case v_duration: mDuration = other.mDuration; break;
case v_boolean: _bool = other._bool; break;
case v_integer: _integer = other._integer; break;
case v_double: _double = other._double; break;
case v_string: _string = other._string; break;
case v_date: _date = other._date; break;
case v_duration: _duration = other._duration; break;
case v_unknown: break;
}
}
@ -62,43 +62,43 @@ Variant::Variant (const Variant& other)
////////////////////////////////////////////////////////////////////////////////
Variant::Variant (const bool input)
{
mType = v_boolean;
mBool = input;
_type = v_boolean;
_bool = input;
}
////////////////////////////////////////////////////////////////////////////////
Variant::Variant (const int input)
{
mType = v_integer;
mInteger = input;
_type = v_integer;
_integer = input;
}
////////////////////////////////////////////////////////////////////////////////
Variant::Variant (const double& input)
{
mType = v_double;
mDouble = input;
_type = v_double;
_double = input;
}
////////////////////////////////////////////////////////////////////////////////
Variant::Variant (const std::string& input)
{
mType = v_string;
mString = input;
_type = v_string;
_string = input;
}
////////////////////////////////////////////////////////////////////////////////
Variant::Variant (const Date& input)
{
mType = v_date;
mDate = input;
_type = v_date;
_date = input;
}
////////////////////////////////////////////////////////////////////////////////
Variant::Variant (const Duration& input)
{
mType = v_duration;
mDuration = input;
_type = v_duration;
_duration = input;
}
////////////////////////////////////////////////////////////////////////////////
@ -107,15 +107,15 @@ Variant& Variant::operator= (const Variant& other)
{
if (this != &other)
{
mType = other.mType;
mBool = other.mBool;
mInteger = other.mInteger;
mDouble = other.mDouble;
mString = other.mString;
mDate = other.mDate;
mDuration = other.mDuration;
mRaw = other.mRaw;
mRawType = other.mRawType;
_type = other._type;
_bool = other._bool;
_integer = other._integer;
_double = other._double;
_string = other._string;
_date = other._date;
_duration = other._duration;
_raw = other._raw;
_raw_type = other._raw_type;
}
return *this;
@ -126,7 +126,7 @@ bool Variant::operator&& (Variant& other)
{
cast (v_boolean);
other.cast (v_boolean);
return mBool && other.mBool;
return _bool && other._bool;
}
////////////////////////////////////////////////////////////////////////////////
@ -134,7 +134,7 @@ bool Variant::operator|| (Variant& other)
{
cast (v_boolean);
other.cast (v_boolean);
return mBool || other.mBool;
return _bool || other._bool;
}
////////////////////////////////////////////////////////////////////////////////
@ -143,33 +143,33 @@ bool Variant::operator<= (Variant& other)
promote (*this, other);
bool result;
switch (mType)
switch (_type)
{
case v_boolean:
throw std::string ("Cannot perform relative comparison on bool types");
break;
case v_integer:
result = mInteger <= other.mInteger ? true : false;
result = _integer <= other._integer ? true : false;
break;
case v_double:
result = mDouble <= other.mDouble ? true : false;
result = _double <= other._double ? true : false;
break;
case v_string:
{
int collating = strcmp (mString.c_str (), other.mString.c_str ());
int collating = strcmp (_string.c_str (), other._string.c_str ());
result = collating <= 0 ? true : false;
}
break;
case v_date:
result = mDate <= other.mDate ? true : false;
result = _date <= other._date ? true : false;
break;
case v_duration:
result = (time_t)mDuration <= (time_t)other.mDuration ? true : false;
result = (time_t)_duration <= (time_t)other._duration ? true : false;
break;
case v_unknown:
@ -186,33 +186,33 @@ bool Variant::operator>= (Variant& other)
promote (*this, other);
bool result;
switch (mType)
switch (_type)
{
case v_boolean:
throw std::string ("Cannot perform relative comparison on bool types");
break;
case v_integer:
result = mInteger >= other.mInteger ? true : false;
result = _integer >= other._integer ? true : false;
break;
case v_double:
result = mDouble >= other.mDouble ? true : false;
result = _double >= other._double ? true : false;
break;
case v_string:
{
int collating = strcmp (mString.c_str (), other.mString.c_str ());
int collating = strcmp (_string.c_str (), other._string.c_str ());
result = collating >= 0 ? true : false;
}
break;
case v_date:
result = mDate >= other.mDate ? true : false;
result = _date >= other._date ? true : false;
break;
case v_duration:
result = (time_t)mDuration >= (time_t)other.mDuration ? true : false;
result = (time_t)_duration >= (time_t)other._duration ? true : false;
break;
case v_unknown:
@ -229,33 +229,33 @@ bool Variant::operator== (Variant& other)
promote (*this, other);
bool result;
switch (mType)
switch (_type)
{
case v_boolean:
result = mBool == other.mBool ? true : false;
result = _bool == other._bool ? true : false;
break;
case v_integer:
result = mInteger == other.mInteger ? true : false;
result = _integer == other._integer ? true : false;
break;
case v_double:
result = mDouble == other.mDouble ? true : false;
result = _double == other._double ? true : false;
break;
case v_string:
{
int collating = strcmp (mString.c_str (), other.mString.c_str ());
int collating = strcmp (_string.c_str (), other._string.c_str ());
result = collating == 0 ? true : false;
}
break;
case v_date:
result = mDate == other.mDate ? true : false;
result = _date == other._date ? true : false;
break;
case v_duration:
result = mDuration == other.mDuration ? true : false;
result = _duration == other._duration ? true : false;
break;
case v_unknown:
@ -272,33 +272,33 @@ bool Variant::operator!= (Variant& other)
promote (*this, other);
bool result;
switch (mType)
switch (_type)
{
case v_boolean:
result = mBool != other.mBool ? true : false;
result = _bool != other._bool ? true : false;
break;
case v_integer:
result = mInteger != other.mInteger ? true : false;
result = _integer != other._integer ? true : false;
break;
case v_double:
result = mDouble != other.mDouble ? true : false;
result = _double != other._double ? true : false;
break;
case v_string:
{
int collating = strcmp (mString.c_str (), other.mString.c_str ());
int collating = strcmp (_string.c_str (), other._string.c_str ());
result = collating != 0 ? true : false;
}
break;
case v_date:
result = mDate != other.mDate ? true : false;
result = _date != other._date ? true : false;
break;
case v_duration:
result = mDuration != other.mDuration ? true : false;
result = _duration != other._duration ? true : false;
break;
case v_unknown:
@ -309,50 +309,12 @@ bool Variant::operator!= (Variant& other)
return result;
}
////////////////////////////////////////////////////////////////////////////////
Variant& Variant::operator^ (Variant& other)
{
// TODO This is all wrong!
switch (mType)
{
case v_boolean:
throw std::string ("Cannot perform exponentiation on Boolean types");
break;
case v_integer:
mInteger = (int) pow ((double) mInteger, (double) other.mInteger);
break;
case v_double:
mDouble = pow (mDouble, other.mDouble);
break;
case v_string:
throw std::string ("Cannot perform exponentiation on string types");
break;
case v_date:
throw std::string ("Cannot perform exponentiation on date types");
break;
case v_duration:
throw std::string ("Cannot perform exponentiation on duration types");
break;
case v_unknown:
throw std::string ("Cannot perform exponentiation on unknown types");
break;
}
return *this;
}
////////////////////////////////////////////////////////////////////////////////
bool Variant::operator! ()
{
cast (v_boolean);
mBool = ! mBool;
return mBool;
_bool = ! _bool;
return _bool;
}
////////////////////////////////////////////////////////////////////////////////
@ -360,18 +322,18 @@ Variant& Variant::operator- (Variant& other)
{
promote (*this, other);
switch (mType)
switch (_type)
{
case v_boolean:
throw std::string ("Cannot perform subtraction on Boolean types");
break;
case v_integer:
mInteger -= other.mInteger;
_integer -= other._integer;
break;
case v_double:
mDouble -= other.mDouble;
_double -= other._double;
break;
case v_string:
@ -379,12 +341,12 @@ Variant& Variant::operator- (Variant& other)
break;
case v_date:
mDuration = Duration (mDate - other.mDate);
mType = v_duration;
_duration = Duration (_date - other._date);
_type = v_duration;
break;
case v_duration:
mDuration = mDuration - other.mDuration;
_duration = _duration - other._duration;
break;
case v_unknown:
@ -400,32 +362,32 @@ Variant& Variant::operator+ (Variant& other)
{
promote (*this, other);
switch (mType)
switch (_type)
{
case v_boolean:
throw std::string ("Cannot perform addition on Boolean types");
break;
case v_integer:
mInteger += other.mInteger;
_integer += other._integer;
break;
case v_double:
mDouble += other.mDouble;
_double += other._double;
break;
case v_string:
mString += other.mString;
_string += other._string;
break;
case v_date:
// TODO operator+ only works for int
//mDate += other.mDate;
//_date += other._date;
break;
case v_duration:
// TODO operator+ missing
//mDuration += other.mDuration;
//_duration += other._duration;
break;
case v_unknown:
@ -441,18 +403,18 @@ Variant& Variant::operator* (Variant& other)
{
promote (*this, other);
switch (mType)
switch (_type)
{
case v_boolean:
throw std::string ("Cannot perform multiplication on Boolean types");
break;
case v_integer:
mInteger *= other.mInteger;
_integer *= other._integer;
break;
case v_double:
mDouble *= other.mDouble;
_double *= other._double;
break;
case v_string:
@ -480,18 +442,18 @@ Variant& Variant::operator/ (Variant& other)
{
promote (*this, other);
switch (mType)
switch (_type)
{
case v_boolean:
throw std::string ("Cannot perform division on Boolean types");
break;
case v_integer:
mInteger /= other.mInteger;
_integer /= other._integer;
break;
case v_double:
mDouble /= other.mDouble;
_double /= other._double;
break;
case v_string:
@ -520,33 +482,33 @@ bool Variant::operator< (Variant& other)
promote (*this, other);
bool result;
switch (mType)
switch (_type)
{
case v_boolean:
throw std::string ("Cannot perform relational compare Boolean types");
break;
case v_integer:
result = mInteger < other.mInteger ? true : false;
result = _integer < other._integer ? true : false;
break;
case v_double:
result = mDouble < other.mDouble ? true : false;
result = _double < other._double ? true : false;
break;
case v_string:
{
int collating = strcmp (mString.c_str (), other.mString.c_str ());
int collating = strcmp (_string.c_str (), other._string.c_str ());
result = collating < 0 ? true : false;
}
break;
case v_date:
result = mDate < other.mDate ? true : false;
result = _date < other._date ? true : false;
break;
case v_duration:
result = mDuration < other.mDuration ? true : false;
result = _duration < other._duration ? true : false;
break;
case v_unknown:
@ -563,33 +525,33 @@ bool Variant::operator> (Variant& other)
promote (*this, other);
bool result;
switch (mType)
switch (_type)
{
case v_boolean:
throw std::string ("Cannot perform relational compare Boolean types");
break;
case v_integer:
result = mInteger > other.mInteger ? true : false;
result = _integer > other._integer ? true : false;
break;
case v_double:
result = mDouble > other.mDouble ? true : false;
result = _double > other._double ? true : false;
break;
case v_string:
{
int collating = strcmp (mString.c_str (), other.mString.c_str ());
int collating = strcmp (_string.c_str (), other._string.c_str ());
result = collating > 0 ? true : false;
}
break;
case v_date:
result = mDate > other.mDate ? true : false;
result = _date > other._date ? true : false;
break;
case v_duration:
result = mDuration > other.mDuration ? true : false;
result = _duration > other._duration ? true : false;
break;
case v_unknown:
@ -608,8 +570,8 @@ void Variant::input (const std::string& input)
! compare (input, "yes", false) ||
! compare (input, "on", false))
{
mType = v_boolean;
mBool = true;
_type = v_boolean;
_bool = true;
return;
}
@ -618,8 +580,8 @@ void Variant::input (const std::string& input)
! compare (input, "no", false) ||
! compare (input, "off", false))
{
mType = v_boolean;
mBool = false;
_type = v_boolean;
_bool = false;
return;
}
@ -638,20 +600,20 @@ void Variant::input (const std::string& input)
{
if (period)
{
mType = v_double;
mDouble = atof (input.c_str ());
_type = v_double;
_double = atof (input.c_str ());
}
else
{
mType = v_integer;
mInteger = atoi (input.c_str ());
_type = v_integer;
_integer = atoi (input.c_str ());
}
return;
}
mType = v_string;
mString = input;
_type = v_string;
_string = input;
}
////////////////////////////////////////////////////////////////////////////////
@ -659,16 +621,16 @@ std::string Variant::format ()
{
std::string output;
switch (mType)
switch (_type)
{
case v_boolean:
output = mBool ? "true" : "false";
output = _bool ? "true" : "false";
break;
case v_integer:
{
char temp [24];
sprintf (temp, "%d", mInteger);
sprintf (temp, "%d", _integer);
output = temp;
}
break;
@ -676,21 +638,21 @@ std::string Variant::format ()
case v_double:
{
char temp [24];
sprintf (temp, "%g", mDouble);
sprintf (temp, "%g", _double);
output = temp;
}
break;
case v_string:
output = mString;
output = _string;
break;
case v_date:
// TODO Format mDate.
// TODO Format _date.
break;
case v_duration:
// TODO Format mDuration.
// TODO Format _duration.
break;
case v_unknown:
@ -705,62 +667,62 @@ std::string Variant::format ()
////////////////////////////////////////////////////////////////////////////////
void Variant::cast (const variant_type type)
{
if (mType == v_unknown || type == v_unknown)
if (_type == v_unknown || type == v_unknown)
throw std::string ("Cannot coerce data either to or from an unknown type");
// Short circuit.
if (mType == type)
if (_type == type)
return;
// From v_boolean
if (mType == v_boolean && type == v_integer)
mInteger = mBool ? 1 : 0;
if (_type == v_boolean && type == v_integer)
_integer = _bool ? 1 : 0;
else if (mType == v_boolean && type == v_double)
mDouble = mBool ? 1.0 : 0.0;
else if (_type == v_boolean && type == v_double)
_double = _bool ? 1.0 : 0.0;
else if (mType == v_boolean && type == v_string)
mString = mBool ? "true" : "false";
else if (_type == v_boolean && type == v_string)
_string = _bool ? "true" : "false";
// From v_integer
else if (mType == v_integer && type == v_boolean)
mBool = mInteger == 0 ? false : true;
else if (_type == v_integer && type == v_boolean)
_bool = _integer == 0 ? false : true;
else if (mType == v_integer && type == v_double)
mDouble = (double)mInteger;
else if (_type == v_integer && type == v_double)
_double = (double)_integer;
else if (mType == v_integer && type == v_string)
else if (_type == v_integer && type == v_string)
{
char temp [24];
sprintf (temp, "%d", mInteger);
mString = temp;
sprintf (temp, "%d", _integer);
_string = temp;
}
// From v_double
else if (mType == v_double && type == v_boolean)
mBool = mDouble == 0.0 ? false : true;
else if (_type == v_double && type == v_boolean)
_bool = _double == 0.0 ? false : true;
else if (mType == v_double && type == v_integer)
mInteger = (int)mDouble;
else if (_type == v_double && type == v_integer)
_integer = (int)_double;
else if (mType == v_double && type == v_string)
else if (_type == v_double && type == v_string)
{
char temp [24];
sprintf (temp, "%g", mDouble);
mString = temp;
sprintf (temp, "%g", _double);
_string = temp;
}
// From v_string
else if (mType == v_string && type == v_boolean)
mBool = (mString.length () == 0 ||
mString == "0" ||
mString == "0.0") ? false : true;
else if (_type == v_string && type == v_boolean)
_bool = (_string.length () == 0 ||
_string == "0" ||
_string == "0.0") ? false : true;
else if (mType == v_string && type == v_integer)
mInteger = atol (mString.c_str ());
else if (_type == v_string && type == v_integer)
_integer = atol (_string.c_str ());
else if (mType == v_string && type == v_double)
mDouble = atol (mString.c_str ());
else if (_type == v_string && type == v_double)
_double = atol (_string.c_str ());
// TODO From v_date
@ -768,48 +730,18 @@ void Variant::cast (const variant_type type)
// TODO From v_duration
mType = type;
}
////////////////////////////////////////////////////////////////////////////////
Variant::variant_type Variant::type ()
{
return mType;
}
////////////////////////////////////////////////////////////////////////////////
void Variant::raw (const std::string& input)
{
mRaw = input;
}
////////////////////////////////////////////////////////////////////////////////
std::string Variant::raw ()
{
return mRaw;
}
////////////////////////////////////////////////////////////////////////////////
void Variant::raw_type (const std::string& input)
{
mRawType = input;
}
////////////////////////////////////////////////////////////////////////////////
std::string Variant::raw_type ()
{
return mRawType;
_type = type;
}
////////////////////////////////////////////////////////////////////////////////
void Variant::promote (Variant& lhs, Variant& rhs)
{
// Short circuit.
if (lhs.type () == rhs.type ())
if (lhs._type == rhs._type)
return;
variant_type newType;
switch (lhs.type () | rhs.type ())
switch (lhs._type | rhs._type)
{
case v_boolean | v_integer: newType = v_integer; break;
case v_boolean | v_double: newType = v_double; break;
@ -838,13 +770,13 @@ void Variant::promote (Variant& lhs, Variant& rhs)
bool Variant::boolean ()
{
cast (v_boolean);
return mBool;
return _bool;
}
////////////////////////////////////////////////////////////////////////////////
std::string Variant::dump ()
{
return format () + "/" + raw () + "/" + raw_type ();
return format () + "/" + _raw + "/" + _raw_type;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -68,7 +68,6 @@ public:
bool operator!= (Variant& other);
bool operator! ();
Variant& operator^ (Variant& other);
Variant& operator- (Variant& other);
Variant& operator+ (Variant& other);
Variant& operator* (Variant& other);
@ -77,27 +76,21 @@ public:
void input (const std::string&);
std::string format ();
void cast (const variant_type);
variant_type type ();
void raw (const std::string&);
std::string raw ();
void raw_type (const std::string&);
std::string raw_type ();
void promote (Variant&, Variant&);
bool boolean ();
std::string dump ();
private:
variant_type mType;
public:
variant_type _type;
std::string _raw;
std::string _raw_type;
bool mBool;
int mInteger;
double mDouble;
std::string mString;
Date mDate;
Duration mDuration;
std::string mRaw;
std::string mRawType;
bool _bool;
int _integer;
double _double;
std::string _string;
Date _date;
Duration _duration;
};
#endif