Merge pull request #10732 from dlang/stable

Merge stable
This commit is contained in:
Dennis 2025-04-02 13:43:44 +02:00 committed by GitHub
commit ff612b867c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 119 additions and 261 deletions

View file

@ -1,14 +0,0 @@
Added `std.conv.bitCast`
This convenience function allows reinterpreting casts to be written in a more
readable way.
---
uint n = 0xDEADBEEF;
// Before
writeln("Bytes of n are: ", *cast(const ubyte[4]*) &n);
// After
writeln("Bytes of n are: ", n.bitCast!(const ubyte[4]));
---

View file

@ -1,30 +0,0 @@
Extend the functionality of formattedRead to permit a std.file.slurp like execution.
Template argument types can now be passed to formattedRead along with a
format string to parse and read the input range as a Tuple of those arguments.
All arguments must be read successfully, otherwise, and unlike std.file.slurp
which has non exhaustive option for partial reads, it'll throw a std.format.FormatException.
---
import std.exception : assertThrown;
import std.format : FormatException;
import std.typecons : tuple;
@safe pure unittest
{
auto complete = "hello!34.5:124".formattedRead!(string, double, int)("%s!%s:%s");
assert(complete == tuple("hello", 34.5, 124));
assertThrown!FormatException("hello!34.5:".formattedRead!(string, double, int)("%s!%s:%s"));
}
/// The format string can be checked at compile-time:
@safe pure unittest
{
auto expected = tuple("hello", 124, 34.5);
auto result = "hello!124:34.5".formattedRead!("%s!%s:%s", string, int, double);
assert(result == expected);
assertThrown!FormatException("hello!34.5:".formattedRead!("%s!%s:%s", string, double, int));
}
---

View file

@ -1,15 +0,0 @@
Added fromHexString and fromHexStringAsRange functions to std.digest.
This new function enables the converion of a hex string to a range of bytes.
Unlike the template $(REF hexString, std, conv) that was designed to supersede
a language feature, this function is usable with runtime input.
The `std.conv` module lacks facilities to conveniently transform the input
to a series of bytes directly. Both $(REF parse, std, conv) and $(REF to, std,
conv) can only handle the conversion for a single value of the requested target
integer type. Furthermore, said functions would allocate a new buffer for the
result, while `fromHexStringAsRange` operates lazily by implementing a forward
range.
For further convenience, a validation function $(REF isHexString, std, digest)
was added as well.

View file

@ -1,11 +0,0 @@
ODBC Bindings in `etc.c.odbc` have been updated to ODBC 4.0.
ODBC 4.0, via these new bindings, adds the following functionality:
1. Support for semi-structured data, such as JSON.
2. Collection valued columns.
3. Web-based Authorization flows.
A full list of new features can be found here: https://github.com/Microsoft/ODBC-Specification/blob/master/ODBC%204.0.md
Additionally these modules add support for 64-bit ODBC interfaces.

View file

@ -1,38 +0,0 @@
Added popGrapheme function to std.uni.
The new function is a cross between the existing $(REF graphemeStride, std,
uni) and $(REF decodeGrapheme, std, uni) functions. The new function both
supports `@safe pure nothrow @nogc` like `graphemeStride` does as long as you
don't rely on autodecoding (side node: `@nogc` support for `graphemeStride`
added in this release), and works with any non-array ranges just like
`decodeGrapheme` does.
Example:
-------
import std.uni;
// Two Union Jacks of the Great Britain in each
string s = "\U0001F1EC\U0001F1E7\U0001F1EC\U0001F1E7";
wstring ws = "\U0001F1EC\U0001F1E7\U0001F1EC\U0001F1E7";
dstring ds = "\U0001F1EC\U0001F1E7\U0001F1EC\U0001F1E7";
// String pop length in code units, not points.
assert(s.popGrapheme() == 8);
assert(ws.popGrapheme() == 4);
assert(ds.popGrapheme() == 2);
assert(s == "\U0001F1EC\U0001F1E7");
assert(ws == "\U0001F1EC\U0001F1E7");
assert(ds == "\U0001F1EC\U0001F1E7");
import std.algorithm.comparison : equal;
import std.algorithm.iteration : filter;
// Also works for non-random access ranges as long as the
// character type is 32-bit.
auto testPiece = "\r\nhello!"d.filter!(x => !x.isAlpha);
// Windows-style line ending is two code point in a single grapheme.
assert(testPiece.popGrapheme() == 2);
assert(testPiece.equal("!"d));
-------

View file

@ -1,6 +0,0 @@
Added `readfln` and `File.readfln` to `std.stdio`
These functions read a single line of input and parse it using a format string.
Unlike `readf`, they will not accidentally read multiple lines if the user
forgets to include a line terminator in the format string—a common mistake for
beginners.

View file

@ -1,13 +0,0 @@
Added the `SharedAllocatorList`, as the thread-safe version of the regular `AllocatorList`.
The new $(REF SharedAllocatorList, std,experimental,allocator,building_blocks,allocator_list) has the same semantics as the regular `AllocatorList`.
Just as the regular `AllocatorList`, if the `BookkeepingAllocator` is `NullAllocator`, the `SharedAllocatorList` will switch to `ouroboros` mode,
allocationg memory for its own metadata.
---
SharedAllocatorList!((n) => SharedAscendingPageAllocator(max(n, numPages * pageSize)), NullAllocator) a;
auto b = a.allocate(100);
assert(b.length == 100);
assert(a.deallocate(b));
---

View file

@ -1,39 +0,0 @@
New procedural API for `std.sumtype`
`std.sumtype` has three new convenience functions for querying and retrieving
the value of a `SumType` object.
* `has!T` returns `true` if the `SumType` object has a value of type `T`.
* `get!T` returns the value if its type is `T`, or asserts if it is not.
* `tryGet!T` returns the value if its type is `T`, or throws an exception if it
is not.
These functions make it easier to write code using `SumType` in a procedural
style, as opposed to the functional style encouraged by `match`.
Example:
---
import std.sumtype;
import std.stdio;
SumType!(string, double) example = "hello";
if (example.has!string)
{
writeln("string: ", example.get!string);
}
else if (example.has!double)
{
writeln("double: ", example.get!double);
}
try
{
writeln("double: ", example.tryGet!double);
}
catch (MatchException e)
{
writeln("Couldn't get a double.");
}
---

View file

@ -1,16 +0,0 @@
std.uni has been upgraded from Unicode 15.1.0 to 16.0.0
This Unicode update was released September 10, 2024, and adds new blocks with characters.
See: https://www.unicode.org/versions/Unicode16.0.0/
```
import std;
void main()
{
const alphaCount = iota(0, dchar.max).filter!(std.uni.isAlpha).walkLength;
writeln(alphaCount);
// formerly: 138387
// now: 142759
}
```

View file

@ -1140,7 +1140,6 @@ template SharedAllocatorList(alias factoryFunction,
import std.algorithm.comparison : max; import std.algorithm.comparison : max;
import std.typecons : Ternary; import std.typecons : Ternary;
enum pageSize = 4096;
enum numPages = 2; enum numPages = 2;
static void testrw(void[] b) static void testrw(void[] b)
@ -1269,8 +1268,6 @@ template SharedAllocatorList(alias factoryFunction,
import std.algorithm.comparison : max; import std.algorithm.comparison : max;
import std.typecons : Ternary; import std.typecons : Ternary;
enum pageSize = 4096;
static void testrw(void[] b) static void testrw(void[] b)
{ {
ubyte* buf = cast(ubyte*) b.ptr; ubyte* buf = cast(ubyte*) b.ptr;
@ -1283,17 +1280,17 @@ template SharedAllocatorList(alias factoryFunction,
enum numPages = 5; enum numPages = 5;
AllocatorList!((n) => AscendingPageAllocator(max(n, numPages * pageSize)), NullAllocator) a; AllocatorList!((n) => AscendingPageAllocator(max(n, numPages * pageSize)), NullAllocator) a;
auto b = a.alignedAllocate(1, pageSize * 2); auto b = a.alignedAllocate(1, cast(uint) (pageSize * 2));
assert(b.length == 1); assert(b.length == 1);
assert(a.expand(b, 4095)); assert(a.expand(b, pageSize - 1));
assert(b.ptr.alignedAt(2 * 4096)); assert(b.ptr.alignedAt(cast(uint) (pageSize * 2)));
assert(b.length == 4096); assert(b.length == pageSize);
b = a.allocate(4096); b = a.allocate(pageSize);
assert(b.length == 4096); assert(b.length == pageSize);
assert(a.allocators.length == 1); assert(a.allocators.length == 1);
assert(a.allocate(4096 * 5).length == 4096 * 5); assert(a.allocate(pageSize * 5).length == pageSize * 5);
assert(a.allocators.length == 2); assert(a.allocators.length == 2);
assert(a.deallocateAll()); assert(a.deallocateAll());
@ -1339,7 +1336,6 @@ template SharedAllocatorList(alias factoryFunction,
import std.algorithm.comparison : max; import std.algorithm.comparison : max;
enum numThreads = 100; enum numThreads = 100;
enum pageSize = 4096;
enum numPages = 10; enum numPages = 10;
SharedAllocatorList!((n) => SharedAscendingPageAllocator(max(n, pageSize * numPages)), Mallocator) a; SharedAllocatorList!((n) => SharedAscendingPageAllocator(max(n, pageSize * numPages)), Mallocator) a;

View file

@ -63,7 +63,8 @@ unittest
class C2 { char c; } class C2 { char c; }
static assert(stateSize!C2 == 4 * size_t.sizeof); static assert(stateSize!C2 == 4 * size_t.sizeof);
static class C3 { char c; } static class C3 { char c; }
static assert(stateSize!C3 == 2 * size_t.sizeof + char.sizeof); // Uncomment test after dmd issue closed https://github.com/dlang/dmd/issues/21065
//static assert(stateSize!C3 == 3 * size_t.sizeof);
} }
/** /**

View file

@ -127,14 +127,16 @@ if (is(Unqual!Char == Char))
Counting starts with `1`. Set to `0` if not used. Default: `0`. Counting starts with `1`. Set to `0` if not used. Default: `0`.
*/ */
ubyte indexStart; ushort indexStart;
/** /**
Index of the last argument for positional parameter ranges. Index of the last argument for positional parameter ranges.
Counting starts with `1`. Set to `0` if not used. Default: `0`. Counting starts with `1`. Set to `0` if not used. Default: `0`.
The maximum value of this field is used as a sentinel to indicate the arguments' length.
*/ */
ubyte indexEnd; ushort indexEnd;
version (StdDdoc) version (StdDdoc)
{ {
@ -296,6 +298,8 @@ if (is(Unqual!Char == Char))
} }
width = 0; width = 0;
indexStart = 0;
indexEnd = 0;
precision = UNSPECIFIED; precision = UNSPECIFIED;
nested = null; nested = null;
// Parse the spec (we assume we're past '%' already) // Parse the spec (we assume we're past '%' already)
@ -834,6 +838,33 @@ if (is(Unqual!Char == Char))
== "$ expected after '*10' in format string"); == "$ expected after '*10' in format string");
} }
// https://github.com/dlang/phobos/issues/10713
@safe pure unittest
{
import std.array : appender;
auto f = FormatSpec!char("%3$d%d");
auto w = appender!(char[])();
f.writeUpToNextSpec(w);
assert(f.indexStart == 3);
f.writeUpToNextSpec(w);
assert(w.data.length == 0);
assert(f.indexStart == 0);
}
// https://github.com/dlang/phobos/issues/10699
@safe pure unittest
{
import std.array : appender;
auto f = FormatSpec!char("%1:$d");
auto w = appender!(char[])();
f.writeUpToNextSpec(w);
assert(f.indexStart == 1);
assert(f.indexEnd == ushort.max);
}
/** /**
Helper function that returns a `FormatSpec` for a single format specifier. Helper function that returns a `FormatSpec` for a single format specifier.

View file

@ -648,9 +648,16 @@ uint formattedWrite(Writer, Char, Args...)(auto ref Writer w, const scope Char[]
break SWITCH; break SWITCH;
} }
default: default:
throw new FormatException( if (spec.indexEnd == spec.indexEnd.max)
text("Positional specifier %", spec.indexStart, '$', spec.spec, break;
" index exceeds ", Args.length)); else if (spec.indexEnd == spec.indexStart)
throw new FormatException(
text("Positional specifier %", spec.indexStart, '$', spec.spec,
" index exceeds ", Args.length));
else
throw new FormatException(
text("Positional specifier %", spec.indexStart, ":", spec.indexEnd, '$', spec.spec,
" index exceeds ", Args.length));
} }
} }
return currentArg; return currentArg;
@ -1199,6 +1206,16 @@ if (isSomeString!(typeof(fmt)))
formattedWrite(stream, "%s", aa); formattedWrite(stream, "%s", aa);
} }
// https://github.com/dlang/phobos/issues/10699
@safe pure unittest
{
import std.array : appender;
auto w = appender!(char[])();
formattedWrite(w, "%1:$d", 1, 2, 3);
assert(w.data == "123");
}
/** /**
Formats a value of any type according to a format specifier and Formats a value of any type according to a format specifier and
writes the result to an output range. writes the result to an output range.

View file

@ -610,14 +610,14 @@ private template optionValidator(A...)
alias optionValidator = message; 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__) size_t idx, string file = __FILE__, size_t line = __LINE__)
{ {
import std.conv : to, ConvException; import std.conv : to, ConvException;
import std.format : format; import std.format : format;
try try
{ {
*receiver = to!(typeof(*receiver))(value); return to!R(value);
} }
catch (ConvException e) 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) // (and potentially args[i + 1] too, but that comes later)
args = args[0 .. i] ~ args[i + 1 .. $]; 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) if (val.length)
{ {
// parse '--b=true/false' // parse '--b=true/false'
handleConversion(option, val, receiver, i); *receiver = getoptTo!(Target)(option, val, i);
} }
else else
{ {
@ -894,23 +900,23 @@ private bool handleOption(R)(string option, R receiver, ref string[] args,
import std.exception : enforce; import std.exception : enforce;
// non-boolean option, which might include an argument // non-boolean option, which might include an argument
enum isCallbackWithLessThanTwoParameters = enum isCallbackWithLessThanTwoParameters =
(is(typeof(receiver) == delegate) || is(typeof(*receiver) == function)) && (is(R == delegate) || is(Target == function)) &&
!is(typeof(receiver("", ""))); !is(typeof(receiver("", "")));
if (!isCallbackWithLessThanTwoParameters && !(val.length) && !incremental) if (!isCallbackWithLessThanTwoParameters && !(val.length) && !incremental)
{ {
// Eat the next argument too. Check to make sure there's one // Eat the next argument too. Check to make sure there's one
// to be eaten first, though. // to be eaten first, though.
enforce!GetOptException(i < args.length, enforce!GetOptException(i < args.length,
"Missing value for argument " ~ a ~ "."); "Missing value for argument " ~ a ~ ".");
val = args[i]; val = args[i];
args = args[0 .. i] ~ args[i + 1 .. $]; args = args[0 .. i] ~ args[i + 1 .. $];
} }
static if (is(typeof(*receiver) == enum) || static if (is(Target == enum) ||
is(typeof(*receiver) == string)) 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 // numeric receiver
if (incremental) if (incremental)
@ -919,16 +925,16 @@ private bool handleOption(R)(string option, R receiver, ref string[] args,
} }
else 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 // string receiver
*receiver = to!(typeof(*receiver))(val); *receiver = getoptTo!(Target)(option, val, i);
} }
else static if (is(typeof(receiver) == delegate) || else static if (is(R == delegate) ||
is(typeof(*receiver) == function)) is(Target == function))
{ {
static if (is(typeof(receiver("", "")) : void)) static if (is(typeof(receiver("", "")) : void))
{ {
@ -952,29 +958,25 @@ private bool handleOption(R)(string option, R receiver, ref string[] args,
receiver(); receiver();
} }
} }
else static if (isArray!(typeof(*receiver))) else static if (isArray!(Target))
{ {
// array receiver // array receiver
import std.range : ElementEncodingType; import std.range : ElementEncodingType;
alias E = ElementEncodingType!(typeof(*receiver)); alias E = ElementEncodingType!(Target);
if (arraySep == "") if (arraySep == "")
{ {
E tmp; *receiver ~= getoptTo!E(option, val, i);
handleConversion(option, val, &tmp, i);
*receiver ~= tmp;
} }
else else
{ {
foreach (elem; val.splitter(arraySep)) foreach (elem; val.splitter(arraySep))
{ {
E tmp; *receiver ~= getoptTo!E(option, elem, i);
handleConversion(option, elem, &tmp, i);
*receiver ~= tmp;
} }
} }
} }
else static if (isAssociativeArray!(typeof(*receiver))) else static if (isAssociativeArray!(Target))
{ {
// hash receiver // hash receiver
alias K = typeof(receiver.keys[0]); 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 ~ "'."); ~ to!string(assignChar) ~ "' in argument '" ~ input ~ "'.");
auto key = input[0 .. j]; auto key = input[0 .. j];
auto value = input[j + 1 .. $]; auto value = input[j + 1 .. $];
return tuple(getoptTo!K("", key, 0), getoptTo!V("", value, 0));
K k;
handleConversion("", key, &k, 0);
V v;
handleConversion("", value, &v, 0);
return tuple(k,v);
} }
static void setHash(Range)(R receiver, Range range) 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)); setHash(receiver, val.splitter(arraySep));
} }
else 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)); 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 '-'). The option character (default '-').

View file

@ -562,8 +562,7 @@ struct JSONValue
else static if (is(T : string)) else static if (is(T : string))
{ {
type_tag = JSONType.string; type_tag = JSONType.string;
string t = arg; store = Store(str: arg);
() @trusted { store.str = t; }();
} }
// https://issues.dlang.org/show_bug.cgi?id=15884 // https://issues.dlang.org/show_bug.cgi?id=15884
else static if (isSomeString!T) else static if (isSomeString!T)
@ -572,7 +571,7 @@ struct JSONValue
// FIXME: std.Array.Array(Range) is not deduced as 'pure' // FIXME: std.Array.Array(Range) is not deduced as 'pure'
() @trusted { () @trusted {
import std.utf : byUTF; 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)) else static if (is(T : bool))
@ -582,17 +581,17 @@ struct JSONValue
else static if (is(T : ulong) && isUnsigned!T) else static if (is(T : ulong) && isUnsigned!T)
{ {
type_tag = JSONType.uinteger; type_tag = JSONType.uinteger;
store.uinteger = arg; store = Store(uinteger: arg);
} }
else static if (is(T : long)) else static if (is(T : long))
{ {
type_tag = JSONType.integer; type_tag = JSONType.integer;
store.integer = arg; store = Store(integer: arg);
} }
else static if (isFloatingPoint!T) else static if (isFloatingPoint!T)
{ {
type_tag = JSONType.float_; type_tag = JSONType.float_;
store.floating = arg; store = Store(floating: arg);
} }
else static if (is(T : Value[Key], Key, Value)) else static if (is(T : Value[Key], Key, Value))
{ {
@ -600,45 +599,34 @@ struct JSONValue
type_tag = JSONType.object; type_tag = JSONType.object;
static if (is(Value : JSONValue)) static if (is(Value : JSONValue))
{ {
JSONValue[string] t = arg; store = Store(object: Store.Object(false, unordered: arg));
() @trusted {
store.object.isOrdered = false;
store.object.unordered = t;
}();
} }
else else
{ {
JSONValue[string] aa; JSONValue[string] aa;
foreach (key, value; arg) foreach (key, value; arg)
aa[key] = JSONValue(value); aa[key] = JSONValue(value);
() @trusted { store = Store(object: Store.Object(false, unordered: aa));
store.object.isOrdered = false;
store.object.unordered = aa;
}();
} }
} }
else static if (is(T : OrderedObjectMember[])) else static if (is(T : OrderedObjectMember[]))
{ {
type_tag = JSONType.object; type_tag = JSONType.object;
() @trusted { store = Store(object: Store.Object(true, ordered: arg));
store.object.isOrdered = true;
store.object.ordered = arg;
}();
} }
else static if (isArray!T) else static if (isArray!T)
{ {
type_tag = JSONType.array; type_tag = JSONType.array;
static if (is(ElementEncodingType!T : JSONValue)) static if (is(ElementEncodingType!T : JSONValue))
{ {
JSONValue[] t = arg; store = Store(array: arg);
() @trusted { store.array = t; }();
} }
else else
{ {
JSONValue[] new_arg = new JSONValue[arg.length]; JSONValue[] new_arg = new JSONValue[arg.length];
foreach (i, e; arg) foreach (i, e; arg)
new_arg[i] = JSONValue(e); new_arg[i] = JSONValue(e);
() @trusted { store.array = new_arg; }(); store = Store(array: new_arg);
} }
} }
else static if (is(T : JSONValue)) else static if (is(T : JSONValue))
@ -658,14 +646,14 @@ struct JSONValue
type_tag = JSONType.array; type_tag = JSONType.array;
static if (is(ElementEncodingType!T : JSONValue)) static if (is(ElementEncodingType!T : JSONValue))
{ {
store.array = arg; store = Store(array: arg);
} }
else else
{ {
JSONValue[] new_arg = new JSONValue[arg.length]; JSONValue[] new_arg = new JSONValue[arg.length];
foreach (i, e; arg) foreach (i, e; arg)
new_arg[i] = JSONValue(e); new_arg[i] = JSONValue(e);
store.array = new_arg; store = Store(array: new_arg);
} }
} }
@ -1651,13 +1639,13 @@ if (isSomeFiniteCharInputRange!T)
if (isFloat) if (isFloat)
{ {
value.type_tag = JSONType.float_; value.type_tag = JSONType.float_;
value.store.floating = parse!double(data); value.store = JSONValue.Store(floating: parse!double(data));
} }
else else
{ {
if (isNegative) if (isNegative)
{ {
value.store.integer = parse!long(data); value.store = JSONValue.Store(integer: parse!long(data));
value.type_tag = JSONType.integer; value.type_tag = JSONType.integer;
} }
else else
@ -1666,12 +1654,12 @@ if (isSomeFiniteCharInputRange!T)
ulong u = parse!ulong(data); ulong u = parse!ulong(data);
if (u & (1UL << 63)) if (u & (1UL << 63))
{ {
value.store.uinteger = u; value.store = JSONValue.Store(uinteger: u);
value.type_tag = JSONType.uinteger; value.type_tag = JSONType.uinteger;
} }
else else
{ {
value.store.integer = u; value.store = JSONValue.Store(integer: u);
value.type_tag = JSONType.integer; value.type_tag = JSONType.integer;
} }
} }

View file

@ -37,7 +37,7 @@ public enum CustomFloatFlags
* Store values in normalized form by default. The actual precision of the * Store values in normalized form by default. The actual precision of the
* significand is extended by 1 bit by assuming an implicit leading bit of 1 * significand is extended by 1 bit by assuming an implicit leading bit of 1
* instead of 0. i.e. `1.nnnn` instead of `0.nnnn`. * instead of 0. i.e. `1.nnnn` instead of `0.nnnn`.
* True for all $(LINK2 https://en.wikipedia.org/wiki/IEEE_floating_point, IEE754) types * True for all $(LINK2 https://en.wikipedia.org/wiki/IEEE_floating_point, IEEE754) types
*/ */
storeNormalized = 2, storeNormalized = 2,