Merge pull request #74 from dlang-community/issue-73

fix issue #73 - Failure to compile when assigning a `const(bool)` to a node
This commit is contained in:
Basile Burg 2017-08-01 01:40:34 +02:00 committed by GitHub
commit 860eab9be5
2 changed files with 40 additions and 9 deletions

View file

@ -200,6 +200,7 @@ struct Node
enum allowed = isIntegral!T || enum allowed = isIntegral!T ||
isFloatingPoint!T || isFloatingPoint!T ||
isSomeString!T || isSomeString!T ||
is(Unqual!T == bool) ||
Value.allowed!T; Value.allowed!T;
} }
@ -226,7 +227,7 @@ struct Node
// Eventually we should simplify this and make all Node constructors except from // Eventually we should simplify this and make all Node constructors except from
// user values nothrow (and think even about those user values). 2014-08-28 // user values nothrow (and think even about those user values). 2014-08-28
enum scalarCtorNothrow(T) = enum scalarCtorNothrow(T) =
(is(Unqual!T == string) || isIntegral!T || isFloatingPoint!T) || (is(Unqual!T == string) || isIntegral!T || isFloatingPoint!T) || is(Unqual!T == bool) ||
(Value.allowed!T && (!is(Unqual!T == Value) && !isSomeString!T && !isArray!T && !isAssociativeArray!T)); (Value.allowed!T && (!is(Unqual!T == Value) && !isSomeString!T && !isArray!T && !isAssociativeArray!T));
public: public:
/** Construct a Node from a value. /** Construct a Node from a value.
@ -272,9 +273,10 @@ struct Node
tag_ = Tag(tag); tag_ = Tag(tag);
// We can easily store ints, floats, strings. // We can easily store ints, floats, strings.
static if(isIntegral!T) { value_ = Value(cast(long)value); } static if(isIntegral!T) { value_ = Value(cast(long)value); }
else static if(is(Unqual!T==bool)){ value_ = Value(cast(bool)value); }
else static if(isFloatingPoint!T) { value_ = Value(cast(real)value); } else static if(isFloatingPoint!T) { value_ = Value(cast(real)value); }
// User defined type or plain string. // User defined type or plain string.
else { value_ = Value(value); } else { value_ = Value(value);}
} }
unittest unittest
{ {
@ -648,15 +650,25 @@ struct Node
if(isInt()) {return to!T(value_.get!(const long));} if(isInt()) {return to!T(value_.get!(const long));}
else if(isFloat()){return to!T(value_.get!(const real));} else if(isFloat()){return to!T(value_.get!(const real));}
} }
else static if(isIntegral!T) if(isInt()) else static if(is(Unqual!T == bool))
{ {
const temp = value_.get!(const long); const temp = value_.get!(const bool);
enforce(temp >= T.min && temp <= T.max, return to!bool(temp);
}
else static if(isIntegral!T)
{
if(isInt())
{
const temp = value_.get!(const long);
enforce(temp >= T.min && temp <= T.max,
new Error("Integer value of type " ~ typeid(T).toString() ~ new Error("Integer value of type " ~ typeid(T).toString() ~
" out of range. Value: " ~ to!string(temp), startMark_)); " out of range. Value: " ~ to!string(temp), startMark_));
return to!T(temp); return to!T(temp);
}
throw new Error("Node stores unexpected type: " ~ type.toString() ~
". Expected: " ~ typeid(T).toString(), startMark_);
} }
throw new Error("Node stores unexpected type: " ~ type.toString() ~ else throw new Error("Node stores unexpected type: " ~ type.toString() ~
". Expected: " ~ typeid(T).toString(), startMark_); ". Expected: " ~ typeid(T).toString(), startMark_);
} }
assert(false, "This code should never be reached"); assert(false, "This code should never be reached");
@ -719,6 +731,11 @@ struct Node
if(isInt()) {return to!T(value_.get!(const long));} if(isInt()) {return to!T(value_.get!(const long));}
else if(isFloat()){return to!T(value_.get!(const real));} else if(isFloat()){return to!T(value_.get!(const real));}
} }
else static if(is(Unqual!T == bool))
{
const temp = value_.get!(const bool);
return to!bool(temp);
}
else static if(isIntegral!T) if(isInt()) else static if(isIntegral!T) if(isInt())
{ {
const temp = value_.get!(const long); const temp = value_.get!(const long);
@ -772,7 +789,7 @@ struct Node
if(isSequence) if(isSequence)
{ {
checkSequenceIndex(index); checkSequenceIndex(index);
static if(isIntegral!T) static if(isIntegral!T || is(Unqual!T == bool))
{ {
return cast(Node)value_.get!(Node[])[index]; return cast(Node)value_.get!(Node[])[index];
} }
@ -966,7 +983,7 @@ struct Node
{ {
// This ensures K is integral. // This ensures K is integral.
checkSequenceIndex(index); checkSequenceIndex(index);
static if(isIntegral!K) static if(isIntegral!K || is(Unqual!K == bool))
{ {
auto nodes = value_.get!(Node[]); auto nodes = value_.get!(Node[]);
static if(is(Unqual!V == Node)){nodes[index] = value;} static if(is(Unqual!V == Node)){nodes[index] = value;}
@ -1434,6 +1451,10 @@ struct Node
{ {
return Value(cast(long)(value)); return Value(cast(long)(value));
} }
else static if (is(Unqual!T == bool))
{
return Value(cast(bool)(value));
}
else static if(isFloatingPoint!T) else static if(isFloatingPoint!T)
{ {
return Value(cast(real)(value)); return Value(cast(real)(value));
@ -1682,6 +1703,7 @@ struct Node
static if(isSomeString!T) {return true;} static if(isSomeString!T) {return true;}
else static if(isFloatingPoint!T){return isInt() || isFloat();} else static if(isFloatingPoint!T){return isInt() || isFloat();}
else static if(isIntegral!T) {return isInt();} else static if(isIntegral!T) {return isInt();}
else static if(is(Unqual!T==bool)){return isBool();}
else {return false;} else {return false;}
} }
@ -1764,6 +1786,7 @@ struct Node
bool typeMatch = (isFloatingPoint!T && (node.isInt || node.isFloat)) || bool typeMatch = (isFloatingPoint!T && (node.isInt || node.isFloat)) ||
(isIntegral!T && node.isInt) || (isIntegral!T && node.isInt) ||
(is(Unqual!T==bool) && node.isBool) ||
(isSomeString!T && node.isString) || (isSomeString!T && node.isString) ||
(node.isType!T); (node.isType!T);
if(typeMatch && *node == index) if(typeMatch && *node == index)

View file

@ -83,10 +83,18 @@ Node[] constructBinary()
Node[] constructBool() Node[] constructBool()
{ {
const(bool) a = true;
immutable(bool) b = true;
const bool aa = true;
immutable bool bb = true;
return [Node([pair("canonical", true), return [Node([pair("canonical", true),
pair("answer", false), pair("answer", false),
pair("logical", true), pair("logical", true),
pair("option", true), pair("option", true),
pair("constbool", a),
pair("imutbool", b),
pair("const_bool", aa),
pair("imut_bool", bb),
pair("but", [pair("y", "is a string"), pair("n", "is a string")])])]; pair("but", [pair("y", "is a string"), pair("n", "is a string")])])];
} }