Implement a boolean sub-type for the Value class

fixes #8043
This commit is contained in:
Gunnar Beutner 2014-12-10 09:04:49 +01:00
parent 9e01f6d8b9
commit 89a0fc006e
10 changed files with 49 additions and 9 deletions

View File

@ -74,6 +74,10 @@ static void Encode(yajl_gen handle, const Value& value)
if (yajl_gen_double(handle, static_cast<double>(value)) == yajl_gen_invalid_number)
yajl_gen_double(handle, 0);
break;
case ValueBoolean:
yajl_gen_bool(handle, value.ToBool());
break;
case ValueString:
str = value;
@ -220,7 +224,7 @@ static int DecodeBoolean(void *ctx, int value)
JsonContext *context = static_cast<JsonContext *>(ctx);
try {
context->AddValue(value);
context->AddValue(static_cast<bool>(value));
} catch (...) {
context->SaveException();
return 0;

View File

@ -22,6 +22,7 @@
using namespace icinga;
REGISTER_BUILTIN_TYPE(Number);
REGISTER_BUILTIN_TYPE(Boolean);
PrimitiveType::PrimitiveType(const String& name)
: m_Name(name)

View File

@ -218,6 +218,8 @@ Type::Ptr ScriptUtils::TypeOf(const Value& value)
return Type::GetByName("Object");
case ValueNumber:
return Type::GetByName("Number");
case ValueBoolean:
return Type::GetByName("Boolean");
case ValueString:
return Type::GetByName("String");
case ValueObject:

View File

@ -55,6 +55,11 @@ Value::operator String(void) const
return boost::lexical_cast<std::string>(m_Value);
else
return boost::lexical_cast<std::string>((long)integral);
case ValueBoolean:
if (boost::get<bool>(m_Value))
return "true";
else
return "false";
case ValueString:
return boost::get<String>(m_Value);
case ValueObject:
@ -133,7 +138,7 @@ bool Value::operator==(const Value& rhs) const
{
if (IsNumber() && rhs.IsNumber())
return Get<double>() == rhs.Get<double>();
else if ((IsNumber() || IsEmpty()) && (rhs.IsNumber() || rhs.IsEmpty()) && !(IsEmpty() && rhs.IsEmpty()))
else if ((IsBoolean() || IsNumber() || IsEmpty()) && (rhs.IsBoolean() || rhs.IsNumber() || rhs.IsEmpty()) && !(IsEmpty() && rhs.IsEmpty()))
return static_cast<double>(*this) == static_cast<double>(rhs);
if (IsString() && rhs.IsString())

View File

@ -32,6 +32,9 @@ bool Value::ToBool(void) const
case ValueNumber:
return static_cast<bool>(boost::get<double>(m_Value));
case ValueBoolean:
return boost::get<bool>(m_Value);
case ValueString:
return !boost::get<String>(m_Value).IsEmpty();
@ -63,6 +66,8 @@ String Value::GetTypeName(void) const
return "Empty";
case ValueNumber:
return "Number";
case ValueBoolean:
return "Boolean";
case ValueString:
return "String";
case ValueObject:

View File

@ -37,8 +37,9 @@ enum ValueType
{
ValueEmpty = 0,
ValueNumber = 1,
ValueString = 2,
ValueObject = 3
ValueBoolean = 2,
ValueString = 3,
ValueObject = 4
};
/**
@ -73,6 +74,10 @@ public:
: m_Value(value)
{ }
inline Value(bool value)
: m_Value(value)
{ }
inline Value(const String& value)
: m_Value(value)
{ }
@ -178,6 +183,16 @@ public:
return (GetType() == ValueNumber);
}
/**
* Checks whether the variant is a boolean.
*
* @returns true if the variant is a boolean.
*/
inline bool IsBoolean(void) const
{
return (GetType() == ValueBoolean);
}
/**
* Checks whether the variant is a string.
*
@ -220,7 +235,7 @@ public:
String GetTypeName(void) const;
private:
boost::variant<boost::blank, double, String, Object::Ptr> m_Value;
boost::variant<boost::blank, double, bool, String, Object::Ptr> m_Value;
template<typename T>
const T& Get(void) const

View File

@ -175,8 +175,8 @@ include return T_INCLUDE;
include_recursive return T_INCLUDE_RECURSIVE;
library return T_LIBRARY;
null return T_NULL;
true { yylval->num = 1; return T_NUMBER; }
false { yylval->num = 0; return T_NUMBER; }
true { yylval->boolean = 1; return T_BOOLEAN; }
false { yylval->boolean = 0; return T_BOOLEAN; }
const return T_CONST;
local return T_LOCAL;
use return T_USE;

View File

@ -90,6 +90,7 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig
%union {
char *text;
double num;
bool boolean;
icinga::Expression *expr;
icinga::Value *variant;
CombinedSetOp csop;
@ -104,6 +105,7 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig
%token <text> T_STRING
%token <text> T_STRING_ANGLE
%token <num> T_NUMBER
%token <boolean> T_BOOLEAN
%token T_NULL
%token <text> T_IDENTIFIER
@ -739,6 +741,10 @@ rterm_without_indexer: T_STRING
{
$$ = MakeLiteral($1);
}
| T_BOOLEAN
{
$$ = MakeLiteral($1);
}
| T_NULL
{
$$ = MakeLiteral();

View File

@ -57,7 +57,7 @@ bool AttributeFilter::Apply(const Table::Ptr& table, const Value& row)
}
} else {
if (m_Operator == "=") {
if (value.GetType() == ValueNumber)
if (value.GetType() == ValueNumber || value.GetType() == ValueBoolean)
return (static_cast<double>(value) == Convert::ToDouble(m_Operand));
else
return (static_cast<String>(value) == m_Operand);

View File

@ -299,8 +299,10 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
for (it = klass.Fields.begin(); it != klass.Fields.end(); it++) {
std::string ftype = it->Type;
if (ftype == "bool" || ftype == "int" || ftype == "double")
if (ftype == "int" || ftype == "double")
ftype = "Number";
else if (ftype == "bool")
ftype = "Boolean";
if (ftype.find("::Ptr") != std::string::npos)
ftype = ftype.substr(0, ftype.size() - strlen("::Ptr"));