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); 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) bool DOM::is_primitive (const std::string& input)
{ {
std::string s; std::string s;

View file

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

View file

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