summaryrefslogtreecommitdiff
path: root/libphobos/src/std/uuid.d
diff options
context:
space:
mode:
Diffstat (limited to 'libphobos/src/std/uuid.d')
-rw-r--r--libphobos/src/std/uuid.d129
1 files changed, 78 insertions, 51 deletions
diff --git a/libphobos/src/std/uuid.d b/libphobos/src/std/uuid.d
index c804e8eb7e8..dec2a1c276d 100644
--- a/libphobos/src/std/uuid.d
+++ b/libphobos/src/std/uuid.d
@@ -68,11 +68,11 @@ $(TR $(TDNW UUID namespaces)
*
* For efficiency, UUID is implemented as a struct. UUIDs are therefore empty if not explicitly
* initialized. An UUID is empty if $(MYREF3 UUID.empty, empty) is true. Empty UUIDs are equal to
- * $(D UUID.init), which is a UUID with all 16 bytes set to 0.
+ * `UUID.init`, which is a UUID with all 16 bytes set to 0.
* Use UUID's constructors or the UUID generator functions to get an initialized UUID.
*
* This is a port of $(LINK2 http://www.boost.org/doc/libs/1_42_0/libs/uuid/uuid.html,
- * boost._uuid) from the Boost project with some minor additions and API
+ * boost.uuid) from the Boost project with some minor additions and API
* changes for a more D-like API.
*
* Standards:
@@ -84,11 +84,11 @@ $(TR $(TDNW UUID namespaces)
* Copyright: Copyright Johannes Pfau 2011 - .
* License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
* Authors: Johannes Pfau
- * Source: $(PHOBOSSRC std/_uuid.d)
+ * Source: $(PHOBOSSRC std/uuid.d)
*
* Macros:
* MYREF2 = <a href="#$2">$(TT $1)</a>&nbsp;
- * MYREF3 = <a href="#$2">$(D $1)</a>
+ * MYREF3 = <a href="#$2">`$1`</a>
*/
/* Copyright Johannes Pfau 2011 - 2012.
* Distributed under the Boost Software License, Version 1.0.
@@ -178,7 +178,7 @@ public struct UUID
*
* Note:
* All of these UUID versions can be read and processed by
- * $(D std.uuid), but only version 3, 4 and 5 UUIDs can be generated.
+ * `std.uuid`, but only version 3, 4 and 5 UUIDs can be generated.
*/
enum Version
{
@@ -249,12 +249,12 @@ public struct UUID
* Construct a UUID struct from the 16 byte representation
* of a UUID.
*/
- @safe pure nothrow @nogc this(ref in ubyte[16] uuidData)
+ @safe pure nothrow @nogc this(ref const scope ubyte[16] uuidData)
{
data = uuidData;
}
/// ditto
- @safe pure nothrow @nogc this(in ubyte[16] uuidData)
+ @safe pure nothrow @nogc this(const ubyte[16] uuidData)
{
data = uuidData;
}
@@ -331,7 +331,7 @@ public struct UUID
*
* For a less strict parser, see $(LREF parseUUID)
*/
- this(T)(in T[] uuid) if (isSomeChar!(Unqual!T))
+ this(T)(in T[] uuid) if (isSomeChar!T)
{
import std.conv : to, parse;
if (uuid.length < 36)
@@ -404,13 +404,13 @@ public struct UUID
{
import std.conv : to;
import std.exception;
- import std.meta;
+ import std.meta : AliasSeq;
- foreach (S; AliasSeq!(char[], const(char)[], immutable(char)[],
+ static foreach (S; AliasSeq!(char[], const(char)[], immutable(char)[],
wchar[], const(wchar)[], immutable(wchar)[],
dchar[], const(dchar)[], immutable(dchar)[],
immutable(char[]), immutable(wchar[]), immutable(dchar[])))
- {
+ {{
//Test valid, working cases
assert(UUID(to!S("00000000-0000-0000-0000-000000000000")).empty);
@@ -456,7 +456,7 @@ public struct UUID
== UUID(cast(ubyte[16])[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,0x01,
0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]));
}
- }
+ }}
/**
* Returns true if and only if the UUID is equal
@@ -664,7 +664,7 @@ public struct UUID
* All of the standard numeric operators are defined for
* the UUID struct.
*/
- @safe pure nothrow @nogc bool opEquals(in UUID s) const
+ @safe pure nothrow @nogc bool opEquals(const UUID s) const
{
return ulongs[0] == s.ulongs[0] && ulongs[1] == s.ulongs[1];
}
@@ -693,7 +693,7 @@ public struct UUID
/**
* ditto
*/
- @safe pure nothrow @nogc bool opEquals(ref in UUID s) const
+ @safe pure nothrow @nogc bool opEquals(ref const scope UUID s) const
{
return ulongs[0] == s.ulongs[0] && ulongs[1] == s.ulongs[1];
}
@@ -701,7 +701,7 @@ public struct UUID
/**
* ditto
*/
- @safe pure nothrow @nogc int opCmp(in UUID s) const
+ @safe pure nothrow @nogc int opCmp(const UUID s) const
{
import std.algorithm.comparison : cmp;
return cmp(this.data[], s.data[]);
@@ -710,7 +710,7 @@ public struct UUID
/**
* ditto
*/
- @safe pure nothrow @nogc int opCmp(ref in UUID s) const
+ @safe pure nothrow @nogc int opCmp(ref const scope UUID s) const
{
import std.algorithm.comparison : cmp;
return cmp(this.data[], s.data[]);
@@ -719,7 +719,7 @@ public struct UUID
/**
* ditto
*/
- @safe pure nothrow @nogc UUID opAssign(in UUID s)
+ @safe pure nothrow @nogc UUID opAssign(const UUID s)
{
ulongs[0] = s.ulongs[0];
ulongs[1] = s.ulongs[1];
@@ -729,7 +729,7 @@ public struct UUID
/**
* ditto
*/
- @safe pure nothrow @nogc UUID opAssign(ref in UUID s)
+ @safe pure nothrow @nogc UUID opAssign(ref const scope UUID s)
{
ulongs[0] = s.ulongs[0];
ulongs[1] = s.ulongs[1];
@@ -880,13 +880,15 @@ public struct UUID
const uint lo = (entry) & 0x0F;
result[pos+1] = toChar!char(lo);
}
- foreach (i, c; result)
+ static if (!__traits(compiles, put(sink, result[])) || isSomeString!Writer)
{
- static if (__traits(compiles, put(sink, c)))
- put(sink, c);
- else
+ foreach (i, c; result)
sink[i] = cast(typeof(sink[i]))c;
}
+ else
+ {
+ put(sink, result[]);
+ }
}
/**
@@ -911,8 +913,8 @@ public struct UUID
@safe pure nothrow @nogc unittest
{
import std.meta : AliasSeq;
- foreach (Char; AliasSeq!(char, wchar, dchar))
- {
+ static foreach (Char; AliasSeq!(char, wchar, dchar))
+ {{
alias String = immutable(Char)[];
//CTFE
enum String s = "8ab3060e-2cba-4f23-b74c-b52db3bdfb46";
@@ -926,7 +928,7 @@ public struct UUID
Char[36] str;
id.toString(str[]);
assert(str == s);
- }
+ }}
}
@system pure nothrow @nogc unittest
@@ -952,7 +954,7 @@ public struct UUID
assert(u1.toString() == "8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
char[] buf;
- void sink(const(char)[] data)
+ void sink(scope const(char)[] data)
{
buf ~= data;
}
@@ -961,10 +963,23 @@ public struct UUID
}
}
+///
+@safe unittest
+{
+ UUID id;
+ assert(id.empty);
+
+ id = randomUUID;
+ assert(!id.empty);
+
+ id = UUID(cast(ubyte[16]) [138, 179, 6, 14, 44, 186, 79,
+ 35, 183, 76, 181, 45, 179, 189, 251, 70]);
+ assert(id.toString() == "8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
+}
/**
* This function generates a name based (Version 3) UUID from a namespace UUID and a name.
- * If no namespace UUID was passed, the empty UUID $(D UUID.init) is used.
+ * If no namespace UUID was passed, the empty UUID `UUID.init` is used.
*
* Note:
* The default namespaces ($(LREF dnsNamespace), ...) defined by
@@ -980,8 +995,8 @@ public struct UUID
* RFC 4122 isn't very clear on how UUIDs should be generated from names.
* It is possible that different implementations return different UUIDs
* for the same input, so be warned. The implementation for UTF-8 strings
- * and byte arrays used by $(D std.uuid) is compatible with Boost's implementation.
- * $(D std.uuid) guarantees that the same input to this function will generate
+ * and byte arrays used by `std.uuid` is compatible with Boost's implementation.
+ * `std.uuid` guarantees that the same input to this function will generate
* the same output at any time, on any system (this especially means endianness
* doesn't matter).
*
@@ -1078,7 +1093,7 @@ public struct UUID
/**
* This function generates a name based (Version 5) UUID from a namespace
* UUID and a name.
- * If no namespace UUID was passed, the empty UUID $(D UUID.init) is used.
+ * If no namespace UUID was passed, the empty UUID `UUID.init` is used.
*
* Note:
* The default namespaces ($(LREF dnsNamespace), ...) defined by
@@ -1091,8 +1106,8 @@ public struct UUID
* RFC 4122 isn't very clear on how UUIDs should be generated from names.
* It is possible that different implementations return different UUIDs
* for the same input, so be warned. The implementation for UTF-8 strings
- * and byte arrays used by $(D std.uuid) is compatible with Boost's implementation.
- * $(D std.uuid) guarantees that the same input to this function will generate
+ * and byte arrays used by `std.uuid` is compatible with Boost's implementation.
+ * `std.uuid` guarantees that the same input to this function will generate
* the same output at any time, on any system (this especially means endianness
* doesn't matter).
*
@@ -1104,13 +1119,13 @@ public struct UUID
* for strings and wstrings. It's always possible to pass wstrings and dstrings
* by using the ubyte[] function overload (but be aware of endianness issues!).
*/
-@safe pure nothrow @nogc UUID sha1UUID(in char[] name, const UUID namespace = UUID.init)
+@safe pure nothrow @nogc UUID sha1UUID(scope const(char)[] name, scope const UUID namespace = UUID.init)
{
return sha1UUID(cast(const(ubyte[]))name, namespace);
}
/// ditto
-@safe pure nothrow @nogc UUID sha1UUID(in ubyte[] data, const UUID namespace = UUID.init)
+@safe pure nothrow @nogc UUID sha1UUID(scope const(ubyte)[] data, scope const UUID namespace = UUID.init)
{
import std.digest.sha : SHA1;
@@ -1195,7 +1210,25 @@ public struct UUID
@safe UUID randomUUID()
{
import std.random : rndGen;
- return randomUUID(rndGen);
+ // A PRNG with fewer than `n` bytes of state cannot produce
+ // every distinct `n` byte sequence.
+ static if (typeof(rndGen).sizeof >= UUID.sizeof)
+ {
+ return randomUUID(rndGen);
+ }
+ else
+ {
+ import std.random : unpredictableSeed, Xorshift192;
+ static assert(Xorshift192.sizeof >= UUID.sizeof);
+ static Xorshift192 rng;
+ static bool initialized;
+ if (!initialized)
+ {
+ rng.seed(unpredictableSeed);
+ initialized = true;
+ }
+ return randomUUID(rng);
+ }
}
/// ditto
@@ -1245,18 +1278,6 @@ if (isInputRange!RNG && isIntegral!(ElementType!RNG))
auto uuid3 = randomUUID(gen);
}
-/*
- * Original boost.uuid used Mt19937, we don't want
- * to use anything worse than that. If Random is changed
- * to something else, this assert and the randomUUID function
- * have to be updated.
- */
-@safe unittest
-{
- import std.random : rndGen, Mt19937;
- static assert(is(typeof(rndGen) == Mt19937));
-}
-
@safe unittest
{
import std.random : Xorshift192, unpredictableSeed;
@@ -1311,8 +1332,7 @@ if (isSomeString!T)
///ditto
UUID parseUUID(Range)(ref Range uuidRange)
-if (isInputRange!Range
- && is(Unqual!(ElementType!Range) == dchar))
+if (isInputRange!Range && isSomeChar!(ElementType!Range))
{
import std.ascii : isHexDigit;
import std.conv : ConvException, parse;
@@ -1527,12 +1547,12 @@ if (isInputRange!Range
return parseUUID(to!T(input));
}
- foreach (S; AliasSeq!(char[], const(char)[], immutable(char)[],
+ static foreach (S; AliasSeq!(char[], const(char)[], immutable(char)[],
wchar[], const(wchar)[], immutable(wchar)[],
dchar[], const(dchar)[], immutable(dchar)[],
immutable(char[]), immutable(wchar[]), immutable(dchar[]),
TestForwardRange, TestInputRange))
- {
+ {{
//Verify examples.
auto id = parseHelper!S("8AB3060E-2CBA-4F23-b74c-B52Db3BDFB46");
//no dashes
@@ -1608,6 +1628,13 @@ if (isInputRange!Range
//multiple trailing/leading characters
assert(parseHelper!S("///8ab3060e2cba4f23b74cb52db3bdfb46||")
== parseUUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46"));
+ }}
+
+ // Test input range with non-dchar element type.
+ {
+ import std.utf : byCodeUnit;
+ auto range = "8AB3060E-2CBA-4F23-b74c-B52Db3BDFB46".byCodeUnit;
+ assert(parseUUID(range).data == [138, 179, 6, 14, 44, 186, 79, 35, 183, 76, 181, 45, 179, 189, 251, 70]);
}
}