aboutsummaryrefslogtreecommitdiff
path: root/libphobos/src/std
diff options
context:
space:
mode:
Diffstat (limited to 'libphobos/src/std')
-rw-r--r--libphobos/src/std/getopt.d73
-rw-r--r--libphobos/src/std/json.d44
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;
}
}