diff options
Diffstat (limited to 'libphobos/src/std')
-rw-r--r-- | libphobos/src/std/getopt.d | 73 | ||||
-rw-r--r-- | libphobos/src/std/json.d | 44 |
2 files changed, 56 insertions, 61 deletions
diff --git a/libphobos/src/std/getopt.d b/libphobos/src/std/getopt.d index 1a90722..fc5cdac 100644 --- a/libphobos/src/std/getopt.d +++ b/libphobos/src/std/getopt.d @@ -610,14 +610,14 @@ private template optionValidator(A...) alias optionValidator = message; } -private void handleConversion(R)(string option, string value, R* receiver, +private auto getoptTo(R)(string option, string value, size_t idx, string file = __FILE__, size_t line = __LINE__) { import std.conv : to, ConvException; import std.format : format; try { - *receiver = to!(typeof(*receiver))(value); + return to!R(value); } catch (ConvException e) { @@ -876,12 +876,18 @@ private bool handleOption(R)(string option, R receiver, ref string[] args, // (and potentially args[i + 1] too, but that comes later) args = args[0 .. i] ~ args[i + 1 .. $]; - static if (is(typeof(*receiver) == bool)) + static if (is(typeof(*receiver))) + alias Target = typeof(*receiver); + else + // delegate + alias Target = void; + + static if (is(Target == bool)) { if (val.length) { // parse '--b=true/false' - handleConversion(option, val, receiver, i); + *receiver = getoptTo!(Target)(option, val, i); } else { @@ -894,23 +900,23 @@ private bool handleOption(R)(string option, R receiver, ref string[] args, import std.exception : enforce; // non-boolean option, which might include an argument enum isCallbackWithLessThanTwoParameters = - (is(typeof(receiver) == delegate) || is(typeof(*receiver) == function)) && + (is(R == delegate) || is(Target == function)) && !is(typeof(receiver("", ""))); if (!isCallbackWithLessThanTwoParameters && !(val.length) && !incremental) { // Eat the next argument too. Check to make sure there's one // to be eaten first, though. enforce!GetOptException(i < args.length, - "Missing value for argument " ~ a ~ "."); + "Missing value for argument " ~ a ~ "."); val = args[i]; args = args[0 .. i] ~ args[i + 1 .. $]; } - static if (is(typeof(*receiver) == enum) || - is(typeof(*receiver) == string)) + static if (is(Target == enum) || + is(Target == string)) { - handleConversion(option, val, receiver, i); + *receiver = getoptTo!Target(option, val, i); } - else static if (is(typeof(*receiver) : real)) + else static if (is(Target : real)) { // numeric receiver if (incremental) @@ -919,16 +925,16 @@ private bool handleOption(R)(string option, R receiver, ref string[] args, } else { - handleConversion(option, val, receiver, i); + *receiver = getoptTo!Target(option, val, i); } } - else static if (is(typeof(*receiver) == string)) + else static if (is(Target == string)) { // string receiver - *receiver = to!(typeof(*receiver))(val); + *receiver = getoptTo!(Target)(option, val, i); } - else static if (is(typeof(receiver) == delegate) || - is(typeof(*receiver) == function)) + else static if (is(R == delegate) || + is(Target == function)) { static if (is(typeof(receiver("", "")) : void)) { @@ -952,29 +958,25 @@ private bool handleOption(R)(string option, R receiver, ref string[] args, receiver(); } } - else static if (isArray!(typeof(*receiver))) + else static if (isArray!(Target)) { // array receiver import std.range : ElementEncodingType; - alias E = ElementEncodingType!(typeof(*receiver)); + alias E = ElementEncodingType!(Target); if (arraySep == "") { - E tmp; - handleConversion(option, val, &tmp, i); - *receiver ~= tmp; + *receiver ~= getoptTo!E(option, val, i); } else { foreach (elem; val.splitter(arraySep)) { - E tmp; - handleConversion(option, elem, &tmp, i); - *receiver ~= tmp; + *receiver ~= getoptTo!E(option, elem, i); } } } - else static if (isAssociativeArray!(typeof(*receiver))) + else static if (isAssociativeArray!(Target)) { // hash receiver alias K = typeof(receiver.keys[0]); @@ -991,14 +993,7 @@ private bool handleOption(R)(string option, R receiver, ref string[] args, ~ to!string(assignChar) ~ "' in argument '" ~ input ~ "'."); auto key = input[0 .. j]; auto value = input[j + 1 .. $]; - - K k; - handleConversion("", key, &k, 0); - - V v; - handleConversion("", value, &v, 0); - - return tuple(k,v); + return tuple(getoptTo!K("", key, 0), getoptTo!V("", value, 0)); } static void setHash(Range)(R receiver, Range range) @@ -1013,7 +1008,7 @@ private bool handleOption(R)(string option, R receiver, ref string[] args, setHash(receiver, val.splitter(arraySep)); } else - static assert(false, "getopt does not know how to handle the type " ~ typeof(receiver).stringof); + static assert(false, "getopt does not know how to handle the type " ~ R.stringof); } } @@ -1099,6 +1094,18 @@ private bool handleOption(R)(string option, R receiver, ref string[] args, assert(values == ["foo":0, "bar":1, "baz":2], to!string(values)); } +// https://github.com/dlang/phobos/issues/10680 +@safe unittest +{ + arraySep = ","; + scope(exit) arraySep = ""; + const(string)[] s; + string[] args = ["program.name", "-s", "a", "-s", "b", "-s", "c,d,e"]; + getopt(args, "values|s", &s); + assert(s == ["a", "b", "c", "d", "e"]); +} + + /** The option character (default '-'). diff --git a/libphobos/src/std/json.d b/libphobos/src/std/json.d index 7182f6e..eb08de8 100644 --- a/libphobos/src/std/json.d +++ b/libphobos/src/std/json.d @@ -562,8 +562,7 @@ struct JSONValue else static if (is(T : string)) { type_tag = JSONType.string; - string t = arg; - () @trusted { store.str = t; }(); + store = Store(str: arg); } // https://issues.dlang.org/show_bug.cgi?id=15884 else static if (isSomeString!T) @@ -572,7 +571,7 @@ struct JSONValue // FIXME: std.Array.Array(Range) is not deduced as 'pure' () @trusted { import std.utf : byUTF; - store.str = cast(immutable)(arg.byUTF!char.array); + store = Store(str: cast(immutable)(arg.byUTF!char.array)); }(); } else static if (is(T : bool)) @@ -582,17 +581,17 @@ struct JSONValue else static if (is(T : ulong) && isUnsigned!T) { type_tag = JSONType.uinteger; - store.uinteger = arg; + store = Store(uinteger: arg); } else static if (is(T : long)) { type_tag = JSONType.integer; - store.integer = arg; + store = Store(integer: arg); } else static if (isFloatingPoint!T) { type_tag = JSONType.float_; - store.floating = arg; + store = Store(floating: arg); } else static if (is(T : Value[Key], Key, Value)) { @@ -600,45 +599,34 @@ struct JSONValue type_tag = JSONType.object; static if (is(Value : JSONValue)) { - JSONValue[string] t = arg; - () @trusted { - store.object.isOrdered = false; - store.object.unordered = t; - }(); + store = Store(object: Store.Object(false, unordered: arg)); } else { JSONValue[string] aa; foreach (key, value; arg) aa[key] = JSONValue(value); - () @trusted { - store.object.isOrdered = false; - store.object.unordered = aa; - }(); + store = Store(object: Store.Object(false, unordered: aa)); } } else static if (is(T : OrderedObjectMember[])) { type_tag = JSONType.object; - () @trusted { - store.object.isOrdered = true; - store.object.ordered = arg; - }(); + store = Store(object: Store.Object(true, ordered: arg)); } else static if (isArray!T) { type_tag = JSONType.array; static if (is(ElementEncodingType!T : JSONValue)) { - JSONValue[] t = arg; - () @trusted { store.array = t; }(); + store = Store(array: arg); } else { JSONValue[] new_arg = new JSONValue[arg.length]; foreach (i, e; arg) new_arg[i] = JSONValue(e); - () @trusted { store.array = new_arg; }(); + store = Store(array: new_arg); } } else static if (is(T : JSONValue)) @@ -658,14 +646,14 @@ struct JSONValue type_tag = JSONType.array; static if (is(ElementEncodingType!T : JSONValue)) { - store.array = arg; + store = Store(array: arg); } else { JSONValue[] new_arg = new JSONValue[arg.length]; foreach (i, e; arg) new_arg[i] = JSONValue(e); - store.array = new_arg; + store = Store(array: new_arg); } } @@ -1616,13 +1604,13 @@ if (isSomeFiniteCharInputRange!T) if (isFloat) { value.type_tag = JSONType.float_; - value.store.floating = parse!double(data); + value.store = JSONValue.Store(floating: parse!double(data)); } else { if (isNegative) { - value.store.integer = parse!long(data); + value.store = JSONValue.Store(integer: parse!long(data)); value.type_tag = JSONType.integer; } else @@ -1631,12 +1619,12 @@ if (isSomeFiniteCharInputRange!T) ulong u = parse!ulong(data); if (u & (1UL << 63)) { - value.store.uinteger = u; + value.store = JSONValue.Store(uinteger: u); value.type_tag = JSONType.uinteger; } else { - value.store.integer = u; + value.store = JSONValue.Store(integer: u); value.type_tag = JSONType.integer; } } |