/**
 * A $(LINK2 http://en.wikipedia.org/wiki/Universally_unique_identifier, UUID), or
 * $(LINK2 http://en.wikipedia.org/wiki/Universally_unique_identifier, Universally unique identifier),
 * is intended to uniquely identify information in a distributed environment
 * without significant central coordination. It can be
 * used to tag objects with very short lifetimes, or to reliably identify very
 * persistent objects across a network.
 *
$(SCRIPT inhibitQuickIndex = 1;)

$(DIVC quickindex,
$(BOOKTABLE ,
$(TR $(TH Category) $(TH Functions)
)
$(TR $(TDNW Parsing UUIDs)
     $(TD $(MYREF parseUUID)
          $(MYREF UUID)
          $(MYREF UUIDParsingException)
          $(MYREF uuidRegex)
          )
     )
$(TR $(TDNW Generating UUIDs)
     $(TD $(MYREF sha1UUID)
          $(MYREF randomUUID)
          $(MYREF md5UUID)
          )
     )
$(TR $(TDNW Using UUIDs)
     $(TD $(MYREF2 UUID.uuidVersion, uuidVersion)
          $(MYREF2 UUID.variant, variant)
          $(MYREF2 UUID.toString, toString)
          $(MYREF2 UUID.data, data)
          $(MYREF2 UUID.swap, swap)
          $(MYREF2 UUID.opEquals, opEquals)
          $(MYREF2 UUID.opCmp, opCmp)
          $(MYREF2 UUID.toHash, toHash)
          )
     )
$(TR $(TDNW UUID namespaces)
     $(TD $(MYREF dnsNamespace)
          $(MYREF urlNamespace)
          $(MYREF oidNamespace)
          $(MYREF x500Namespace)
          )
     )
)
)

 * UUIDs have many applications. Some examples follow: Databases may use UUIDs to identify
 * rows or records in order to ensure that they are unique across different
 * databases, or for publication/subscription services. Network messages may be
 * identified with a UUID to ensure that different parts of a message are put back together
 * again. Distributed computing may use UUIDs to identify a remote procedure call.
 * Transactions and classes involved in serialization may be identified by UUIDs.
 * Microsoft's component object model (COM) uses UUIDs to distinguish different software
 * component interfaces. UUIDs are inserted into documents from Microsoft Office programs.
 * UUIDs identify audio or video streams in the Advanced Systems Format (ASF). UUIDs are
 * also a basis for OIDs (object identifiers), and URNs (uniform resource name).
 *
 * An attractive feature of UUIDs when compared to alternatives is their relative small size,
 * of 128 bits, or 16 bytes. Another is that the creation of UUIDs does not require
 * a centralized authority.
 *
 * When UUIDs are generated by one of the defined mechanisms, they are either guaranteed
 * to be unique, different from all other generated UUIDs (that is, it has never been
 * generated before and it will never be generated again), or it is extremely likely
 * to be unique (depending on the mechanism).
 *
 * 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
 * `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
 * changes for a more D-like API.
 *
 * Standards:
 * $(LINK2 http://www.ietf.org/rfc/rfc4122.txt, RFC 4122)
 *
 * See_Also:
 * $(LINK http://en.wikipedia.org/wiki/Universally_unique_identifier)
 *
 * 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)
 *
 * Macros:
 * MYREF2 = <a href="#$2">$(TT $1)</a>&nbsp;
 * MYREF3 = <a href="#$2">`$1`</a>
 */
/*          Copyright Johannes Pfau 2011 - 2012.
 * Distributed under the Boost Software License, Version 1.0.
 *    (See accompanying file LICENSE_1_0.txt or copy at
 *          http://www.boost.org/LICENSE_1_0.txt)
 */
module std.uuid;

///
@safe unittest
{
    import std.uuid;

    UUID[] ids;
    ids ~= randomUUID();
    ids ~= md5UUID("test.name.123");
    ids ~= sha1UUID("test.name.123");

    foreach (entry; ids)
    {
        assert(entry.variant == UUID.Variant.rfc4122);
    }
    assert(ids[0].uuidVersion == UUID.Version.randomNumberBased);
    assert(ids[1].toString() == "22390768-cced-325f-8f0f-cfeaa19d0ccd");
    assert(ids[1].data == [34, 57, 7, 104, 204, 237, 50, 95, 143, 15, 207,
        234, 161, 157, 12, 205]);
    UUID id;
    assert(id.empty);
}

import std.range.primitives;
import std.traits;

/**
 *
 */
public struct UUID
{
    import std.meta : AliasSeq, allSatisfy;

    private:
        alias skipSeq = AliasSeq!(8, 13, 18, 23);
        alias byteSeq = AliasSeq!(0,2,4,6,9,11,14,16,19,21,24,26,28,30,32,34);

        @safe pure nothrow @nogc Char toChar(Char)(size_t i) const
        {
            if (i <= 9)
                return cast(Char)('0' + i);
            else
                return cast(Char)('a' + (i-10));
        }

        @safe pure nothrow unittest
        {
            assert(UUID(cast(ubyte[16])[138, 179, 6, 14, 44, 186, 79, 35, 183, 76, 181, 45,
                179, 189, 251, 70]).toString() == "8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
        }

        // Reinterpret the UUID as an array of some other primitive.
        @trusted ref T[16 / T.sizeof] asArrayOf(T)() return
        if (isIntegral!T)
        {
            return *cast(typeof(return)*)&data;
        }

    public:
        /**
         * RFC 4122 defines different internal data layouts for UUIDs. These are
         * the UUID formats supported by this module. It's
         * possible to read, compare and use all these Variants, but
         * UUIDs generated by this module will always be in rfc4122 format.
         *
         * Note: Do not confuse this with $(REF _Variant, std,_variant).
         */
        enum Variant
        {
            ncs, /// NCS backward compatibility
            rfc4122, /// Defined in RFC 4122 document
            microsoft, /// Microsoft Corporation backward compatibility
            future ///Reserved for future use
        }

        /**
         * RFC 4122 defines different UUID versions. The version shows
         * how a UUID was generated, e.g. a version 4 UUID was generated
         * from a random number, a version 3 UUID from an MD5 hash of a name.
         *
         * Note:
         * All of these UUID versions can be read and processed by
         * `std.uuid`, but only version 3, 4 and 5 UUIDs can be generated.
         */
        enum Version
        {
            ///Unknown version
            unknown = -1,
            ///Version 1
            timeBased = 1,
            ///Version 2
            dceSecurity = 2,
            ///Version 3 (Name based + MD5)
            nameBasedMD5 = 3,
            ///Version 4 (Random)
            randomNumberBased = 4,
            ///Version 5 (Name based + SHA-1)
            nameBasedSHA1 = 5
        }

        union
        {
            /**
             * It is sometimes useful to get or set the 16 bytes of a UUID
             * directly.
             *
             * Note:
             * UUID uses a 16-ubyte representation for the UUID data.
             * RFC 4122 defines a UUID as a special structure in big-endian
             * format. These 16-ubytes always equal the big-endian structure
             * defined in RFC 4122.
             *
             * Example:
             * -----------------------------------------------
             * auto rawData = uuid.data; //get data
             * rawData[0] = 1; //modify
             * uuid.data = rawData; //set data
             * uuid.data[1] = 2; //modify directly
             * -----------------------------------------------
             */
            ubyte[16] data;
            private ulong[2] ulongs;
            static if (size_t.sizeof == 4)
                private uint[4] uints;
        }

        /*
         * We could use a union here to also provide access to the
         * fields specified in RFC 4122, but as we never have to access
         * those (only necessary for version 1 (and maybe 2) UUIDs),
         * that is not needed right now.
         */

        @safe pure unittest
        {
            UUID tmp;
            tmp.data = cast(ubyte[16])[0,1,2,3,4,5,6,7,8,9,10,11,12,
                13,14,15];
            assert(tmp.data == cast(ubyte[16])[0,1,2,3,4,5,6,7,8,9,10,11,
                12,13,14,15]);
            tmp.data[2] = 3;
            assert(tmp.data == cast(ubyte[16])[0,1,3,3,4,5,6,7,8,9,10,11,
                12,13,14,15]);

            auto tmp2 = cast(immutable UUID) tmp;
            assert(tmp2.data == cast(ubyte[16])[0,1,3,3,4,5,6,7,8,9,10,11,
                12,13,14,15]);
        }

        /**
         * Construct a UUID struct from the 16 byte representation
         * of a UUID.
         */
        @safe pure nothrow @nogc this(ref const scope ubyte[16] uuidData)
        {
            data = uuidData;
        }
        /// ditto
        @safe pure nothrow @nogc this(const ubyte[16] uuidData)
        {
            data = uuidData;
        }

        ///
        @safe pure unittest
        {
            enum ubyte[16] data = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
            auto uuid = UUID(data);
            enum ctfe = UUID(data);
            assert(uuid.data == data);
            assert(ctfe.data == data);
        }

        /**
         * Construct a UUID struct from the 16 byte representation
         * of a UUID. Variadic constructor to allow a simpler syntax, see examples.
         * You need to pass exactly 16 ubytes.
         */
        @safe pure this(T...)(T uuidData)
            if (uuidData.length == 16 && allSatisfy!(isIntegral, T))
        {
            import std.conv : to;

            foreach (idx, it; uuidData)
            {
                this.data[idx] = to!ubyte(it);
            }
        }

        ///
        @safe unittest
        {
            auto tmp = UUID(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
            assert(tmp.data == cast(ubyte[16])[0,1,2,3,4,5,6,7,8,9,10,11,
                12,13,14,15]);
        }

        @safe unittest
        {
            UUID tmp = UUID(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
            assert(tmp.data == cast(ubyte[16])[0,1,2,3,4,5,6,7,8,9,10,11,
                12,13,14,15]);

            enum UUID ctfeID = UUID(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
            assert(ctfeID == tmp);

            //Too few arguments
            assert(!__traits(compiles, typeof(UUID(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14))));

            //Too many arguments
            assert(!__traits(compiles, typeof(UUID(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1))));
        }

        /**
         * <a name="UUID(string)"></a>
         * Parse a UUID from its canonical string form. An UUID in its
         * canonical form looks like this: 8ab3060e-2cba-4f23-b74c-b52db3bdfb46
         *
         * Throws:
         * $(LREF UUIDParsingException) if the input is invalid
         *
         * CTFE:
         * This function is supported in CTFE code. Note that error messages
         * caused by a malformed UUID parsed at compile time can be cryptic,
         * but errors are detected and reported at
         * compile time.
         *
         * Note:
         * This is a strict parser. It only accepts the pattern above.
         * It doesn't support any leading or trailing characters. It only
         * accepts characters used for hex numbers and the string must have
         * hyphens exactly like above.
         *
         * For a less strict parser, see $(LREF parseUUID)
         */
        this(T)(in T[] uuid) if (isSomeChar!T)
        {
            import std.conv : to, parse;
            if (uuid.length < 36)
            {
                throw new UUIDParsingException(to!string(uuid), 0,
                    UUIDParsingException.Reason.tooLittle, "Insufficient Input");
            }
            if (uuid.length > 36)
            {
                throw new UUIDParsingException(to!string(uuid), 35, UUIDParsingException.Reason.tooMuch,
                    "Input is too long, need exactly 36 characters");
            }
            static immutable skipInd = [skipSeq];
            foreach (pos; skipInd)
                if (uuid[pos] != '-')
                    throw new UUIDParsingException(to!string(uuid), pos,
                        UUIDParsingException.Reason.invalidChar, "Expected '-'");

            ubyte[16] data2; //ctfe bug
            uint pos = void;

            foreach (i, p; byteSeq)
            {
                enum uint s = 'a'-10-'0';
                uint h = uuid[p];
                uint l = uuid[p+1];
                pos = p;
                if (h < '0') goto Lerr;
                if (l < '0') goto Lerr;
                if (h > '9')
                {
                    h |= 0x20; //poorman's tolower
                    if (h < 'a') goto Lerr;
                    if (h > 'f') goto Lerr;
                    h -= s;
                }
                if (l > '9')
                {
                    l |= 0x20; //poorman's tolower
                    if (l < 'a') goto Lerr;
                    if (l > 'f') goto Lerr;
                    l -= s;
                }
                h -= '0';
                l -= '0';

                data2[i] = cast(ubyte)((h << 4) ^ l);
            }
            this.data = data2;
            return;

        Lerr: throw new UUIDParsingException(to!string(uuid), pos,
                UUIDParsingException.Reason.invalidChar, "Couldn't parse ubyte");
        }

        ///
        @safe pure unittest
        {
            auto id = UUID("8AB3060E-2cba-4f23-b74c-b52db3bdfb46");
            assert(id.data == [138, 179, 6, 14, 44, 186, 79, 35, 183, 76,
               181, 45, 179, 189, 251, 70]);
            assert(id.toString() == "8ab3060e-2cba-4f23-b74c-b52db3bdfb46");

            //Can also be used in CTFE, for example as UUID literals:
            enum ctfeID = UUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
            //here parsing is done at compile time, no runtime overhead!
        }

        @safe pure unittest
        {
            import std.conv : to;
            import std.exception;
            import std.meta : AliasSeq;

            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);

                auto id = UUID(to!S("8AB3060E-2cba-4f23-b74c-b52db3bdfb46"));
                assert(id.data == [138, 179, 6, 14, 44, 186, 79, 35, 183, 76,
                    181, 45, 179, 189, 251, 70]);
                assert(id.toString() == "8ab3060e-2cba-4f23-b74c-b52db3bdfb46");

                enum UUID ctfe = UUID(to!S("8ab3060e-2cba-4f23-b74c-b52db3bdfb46"));
                assert(ctfe == id);

                assert(UUID(to!S("5668122d-9df0-49a4-ad0b-b9b0a57f886a")).data
                    == [86, 104, 18, 45, 157, 240, 73, 164, 173, 11, 185, 176, 165, 127, 136, 106]);

                //Test too short UUIDS
                auto except = collectException!UUIDParsingException(
                    UUID(to!S("5668122d-9df0-49a4-ad0b-b9b0a57f886")));
                assert(except && except.reason == UUIDParsingException.Reason.tooLittle);

                //Test too long UUIDS
                except = collectException!UUIDParsingException(
                    UUID(to!S("5668122d-9df0-49a4-ad0b-b9b0a57f886aa")));
                assert(except && except.reason == UUIDParsingException.Reason.tooMuch);

                //Test dashes
                except = collectException!UUIDParsingException(
                    UUID(to!S("8ab3060e2cba-4f23-b74c-b52db3bdfb-46")));
                assert(except && except.reason == UUIDParsingException.Reason.invalidChar);

                //Test dashes 2
                except = collectException!UUIDParsingException(
                    UUID(to!S("8ab3-060e2cba-4f23-b74c-b52db3bdfb46")));
                assert(except && except.reason == UUIDParsingException.Reason.invalidChar);

                //Test invalid characters
                //make sure 36 characters in total or we'll get a 'tooMuch' reason
                except = collectException!UUIDParsingException(
                    UUID(to!S("{8ab3060e-2cba-4f23-b74c-b52db3bdf6}")));
                assert(except && except.reason == UUIDParsingException.Reason.invalidChar);

                //Boost test
                assert(UUID(to!S("01234567-89ab-cdef-0123-456789ABCDEF"))
                    == 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
         * to {00000000-0000-0000-0000-000000000000}
         */
        @trusted pure nothrow @nogc @property bool empty() const
        {
            if (__ctfe)
                return data == (ubyte[16]).init;

            auto p = cast(const(size_t*))data.ptr;
            static if (size_t.sizeof == 4)
                return p[0] == 0 && p[1] == 0 && p[2] == 0 && p[3] == 0;
            else static if (size_t.sizeof == 8)
                return p[0] == 0 && p[1] == 0;
            else
                static assert(false, "nonsense, it's not 32 or 64 bit");
        }

        ///
        @safe pure unittest
        {
            UUID id;
            assert(id.empty);
            id = UUID("00000000-0000-0000-0000-000000000001");
            assert(!id.empty);
        }

        @safe pure unittest
        {
            ubyte[16] getData(size_t i)
            {
                ubyte[16] data;
                data[i] = 1;
                return data;
            }

            for (size_t i = 0; i < 16; i++)
            {
                assert(!UUID(getData(i)).empty);
            }

            enum ctfeEmpty = UUID.init.empty;
            assert(ctfeEmpty);

            bool ctfeTest()
            {
                for (size_t i = 0; i < 16; i++)
                {
                    auto ctfeEmpty2 = UUID(getData(i)).empty;
                    assert(!ctfeEmpty2);
                }
                return true;
            }
            enum res = ctfeTest();
        }

        /**
         * RFC 4122 defines different internal data layouts for UUIDs.
         * Returns the format used by this UUID.
         *
         * Note: Do not confuse this with $(REF _Variant, std,_variant).
         * The type of this property is $(MYREF3 std.uuid.UUID.Variant, _Variant).
         *
         * See_Also:
         * $(MYREF3 UUID.Variant, Variant)
         */
        @safe pure nothrow @nogc @property Variant variant() const
        {
            //variant is stored in octet 7
            //which is index 8, since indexes count backwards
            immutable octet7 = data[8]; //octet 7 is array index 8

            if ((octet7 & 0x80) == 0x00) //0b0xxxxxxx
                return Variant.ncs;
            else if ((octet7 & 0xC0) == 0x80) //0b10xxxxxx
                return Variant.rfc4122;
            else if ((octet7 & 0xE0) == 0xC0) //0b110xxxxx
                return Variant.microsoft;
            else
            {
                //assert((octet7 & 0xE0) == 0xE0, "Unknown UUID variant!") //0b111xxxx
                return Variant.future;
            }
        }

        ///
        @safe pure unittest
        {
            assert(UUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46").variant
               == UUID.Variant.rfc4122);
        }
        @system pure unittest
        {
            // @system due to Variant
            Variant[ubyte] tests = cast(Variant[ubyte])[0x00 : Variant.ncs,
                                    0x10 : Variant.ncs,
                                    0x20 : Variant.ncs,
                                    0x30 : Variant.ncs,
                                    0x40 : Variant.ncs,
                                    0x50 : Variant.ncs,
                                    0x60 : Variant.ncs,
                                    0x70 : Variant.ncs,
                                    0x80 : Variant.rfc4122,
                                    0x90 : Variant.rfc4122,
                                    0xa0 : Variant.rfc4122,
                                    0xb0 : Variant.rfc4122,
                                    0xc0 : Variant.microsoft,
                                    0xd0 : Variant.microsoft,
                                    0xe0 : Variant.future,
                                    0xf0 : Variant.future];
            foreach (key, value; tests)
            {
                UUID u;
                u.data[8] = key;
                assert(u.variant == value);
            }
        }

        /**
         * RFC 4122 defines different UUID versions. The version shows
         * how a UUID was generated, e.g. a version 4 UUID was generated
         * from a random number, a version 3 UUID from an MD5 hash of a name.
         * Returns the version used by this UUID.
         *
         * See_Also:
         * $(MYREF3 UUID.Version, Version)
         */
        @safe pure nothrow @nogc @property Version uuidVersion() const
        {
            //version is stored in octet 9
            //which is index 6, since indexes count backwards
            immutable octet9 = data[6];
            if ((octet9 & 0xF0) == 0x10)
                return Version.timeBased;
            else if ((octet9 & 0xF0) == 0x20)
                return Version.dceSecurity;
            else if ((octet9 & 0xF0) == 0x30)
                return Version.nameBasedMD5;
            else if ((octet9 & 0xF0) == 0x40)
                return Version.randomNumberBased;
            else if ((octet9 & 0xF0) == 0x50)
                return Version.nameBasedSHA1;
            else
                return Version.unknown;
        }

        ///
        @safe unittest
        {
            assert(UUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46").uuidVersion
                == UUID.Version.randomNumberBased);
        }
        @system unittest
        {
            // @system due to cast
            Version[ubyte] tests = cast(Version[ubyte]) [
                0x00 : UUID.Version.unknown,
                0x10 : UUID.Version.timeBased,
                0x20 : UUID.Version.dceSecurity,
                0x30 : UUID.Version.nameBasedMD5,
                0x40 : UUID.Version.randomNumberBased,
                0x50 : UUID.Version.nameBasedSHA1,
                0x60 : UUID.Version.unknown,
                0x70 : UUID.Version.unknown,
                0x80 : UUID.Version.unknown,
                0x90 : UUID.Version.unknown,
                0xa0 : UUID.Version.unknown,
                0xb0 : UUID.Version.unknown,
                0xc0 : UUID.Version.unknown,
                0xd0 : UUID.Version.unknown,
                0xe0 : UUID.Version.unknown,
                0xf0 : UUID.Version.unknown];
            foreach (key, value; tests)
            {
                UUID u;
                u.data[6] = key;
                assert(u.uuidVersion == value);
            }
        }

        /**
         * Swap the data of this UUID with the data of rhs.
         */
        @safe pure nothrow @nogc void swap(ref UUID rhs)
        {
            immutable bck = data;
            data = rhs.data;
            rhs.data = bck;
        }

        ///
        @safe unittest
        {
            immutable ubyte[16] data = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
            UUID u1;
            UUID u2 = UUID(data);
            u1.swap(u2);

            assert(u1 == UUID(data));
            assert(u2 == UUID.init);
        }

        /**
         * All of the standard numeric operators are defined for
         * the UUID struct.
         */
        @safe pure nothrow @nogc bool opEquals(const UUID s) const
        {
            return ulongs[0] == s.ulongs[0] && ulongs[1] == s.ulongs[1];
        }

        ///
        @safe pure unittest
        {
            //compare UUIDs
            assert(UUID("00000000-0000-0000-0000-000000000000") == UUID.init);

            //UUIDs in associative arrays:
            int[UUID] test = [UUID("8a94f585-d180-44f7-8929-6fca0189c7d0") : 1,
                UUID("7c351fd4-b860-4ee3-bbdc-7f79f3dfb00a") : 2,
                UUID("9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1") : 3];

            assert(test[UUID("9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1")] == 3);

            //UUIDS can be sorted:
            import std.algorithm;
            UUID[] ids = [UUID("8a94f585-d180-44f7-8929-6fca0189c7d0"),
                          UUID("7c351fd4-b860-4ee3-bbdc-7f79f3dfb00a"),
                          UUID("9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1")];
            sort(ids);
        }

        /**
         * ditto
         */
        @safe pure nothrow @nogc bool opEquals(ref const scope UUID s) const
        {
            return ulongs[0] == s.ulongs[0] && ulongs[1] == s.ulongs[1];
        }

        /**
         * ditto
         */
        @safe pure nothrow @nogc int opCmp(const UUID s) const
        {
            import std.algorithm.comparison : cmp;
            return cmp(this.data[], s.data[]);
        }

        /**
         * ditto
         */
        @safe pure nothrow @nogc int opCmp(ref const scope UUID s) const
        {
            import std.algorithm.comparison : cmp;
            return cmp(this.data[], s.data[]);
        }

        /**
         * ditto
         */
       @safe pure nothrow @nogc UUID opAssign(const UUID s)
        {
            ulongs[0] = s.ulongs[0];
            ulongs[1] = s.ulongs[1];
            return this;
        }

        /**
         * ditto
         */
        @safe pure nothrow @nogc UUID opAssign(ref const scope UUID s)
        {
            ulongs[0] = s.ulongs[0];
            ulongs[1] = s.ulongs[1];
            return this;
        }

        /**
         * ditto
         */
        //MurmurHash2
        @safe pure nothrow @nogc size_t toHash() const
        {
            static if (size_t.sizeof == 4)
            {
                enum uint m = 0x5bd1e995;
                enum uint n = 16;
                enum uint r = 24;

                uint h = n;

                uint k = uints[0];
                k *= m;
                k ^= k >> r;
                k *= m;

                h ^= k;
                h *= m;

                k = uints[1];
                k *= m;
                k ^= k >> r;
                k *= m;

                h ^= k;
                h *= m;

                k = uints[2];
                k *= m;
                k ^= k >> r;
                k *= m;

                h ^= k;
                h *= m;

                k = uints[3];
                k *= m;
                k ^= k >> r;
                k *= m;

                h ^= k;
                h *= m;
            }
            else
            {
                enum ulong m = 0xc6a4a7935bd1e995UL;
                enum ulong n = m * 16;
                enum uint r = 47;

                ulong h = n;

                ulong k = ulongs[0];
                k *= m;
                k ^= k >> r;
                k *= m;

                h ^= k;
                h *= m;

                k = ulongs[1];
                k *= m;
                k ^= k >> r;
                k *= m;

                h ^= k;
                h *= m;
            }
            return h;
        }
        @safe unittest
        {
            assert(UUID("00000000-0000-0000-0000-000000000000") == UUID.init);
            int[UUID] test = [UUID("8a94f585-d180-44f7-8929-6fca0189c7d0") : 1,
                UUID("7c351fd4-b860-4ee3-bbdc-7f79f3dfb00a") : 2,
                UUID("9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1") : 3];

            assert(test[UUID("9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1")] == 3);

            import std.algorithm;
            UUID[] ids = [UUID("8a94f585-d180-44f7-8929-6fca0189c7d0"),
                          UUID("7c351fd4-b860-4ee3-bbdc-7f79f3dfb00a"),
                          UUID("9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1")];
            sort(ids);
            auto id2 = ids.dup;

            ids = [UUID("7c351fd4-b860-4ee3-bbdc-7f79f3dfb00a"),
                   UUID("8a94f585-d180-44f7-8929-6fca0189c7d0"),
                   UUID("9ac0a4e5-10ee-493a-86fc-d29eeb82ecc1")];
            sort(ids);
            assert(ids == id2);

            //test comparsion
            UUID u1;
            UUID u2 = UUID(cast(ubyte[16])[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
            UUID u3 = UUID(cast(ubyte[16])[255,255,255,255,255,255,255,255,255,
                255,255,255,255,255,255,255]);

            assert(u1 == u1);

            assert(u1 != u2);

            assert(u1 < u2);
            assert(u2 < u3);

            assert(u1 <= u1);
            assert(u1 <= u2);
            assert(u2 <= u3);

            assert(u2 >= u2);
            assert(u3 >= u2);

            assert(u3 >= u3);
            assert(u2 >= u1);
            assert(u3 >= u1);

            // test hash
            assert(u1.toHash() != u2.toHash());
            assert(u2.toHash() != u3.toHash());
            assert(u3.toHash() != u1.toHash());
        }


        /**
         * Write the UUID into `sink` as an ASCII string in the canonical form,
         * which is 36 characters in the form "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
         * Params:
         *      sink = OutputRange or writeable array at least 36 entries long
         */
        void toString(Writer)(scope Writer sink) const
        {
            char[36] result = void;
            foreach (pos; skipSeq)
                result[pos] = '-';
            foreach (i, pos; byteSeq)
            {
                const uint entry = this.data[i];
                const uint hi = entry >> 4;
                result[pos  ] = toChar!char(hi);
                const uint lo = (entry) & 0x0F;
                result[pos+1] = toChar!char(lo);
            }
            static if (!__traits(compiles, put(sink, result[])) || isSomeString!Writer)
            {
                foreach (i, c; result)
                    sink[i] = cast(typeof(sink[i]))c;
            }
            else
            {
                put(sink, result[]);
            }
        }

        /**
         * Return the UUID as a string in the canonical form.
         */
        @trusted pure nothrow string toString() const
        {
            import std.exception : assumeUnique;
            auto result = new char[36];
            toString(result);
            return result.assumeUnique;
        }

        ///
        @safe pure unittest
        {
            immutable str = "8ab3060e-2cba-4f23-b74c-b52db3bdfb46";
            auto id = UUID(str);
            assert(id.toString() == str);
        }

        @safe pure nothrow @nogc unittest
        {
            import std.meta : AliasSeq;
            static foreach (Char; AliasSeq!(char, wchar, dchar))
            {{
                alias String = immutable(Char)[];
                //CTFE
                enum String s = "8ab3060e-2cba-4f23-b74c-b52db3bdfb46";
                enum id = UUID(s);
                static if (is(Char == char))
                {
                    enum p = id.toString();
                    static assert(s == p);
                }
                //nogc
                Char[36] str;
                id.toString(str[]);
                assert(str == s);
            }}
        }

        @system pure nothrow @nogc unittest
        {
            // @system due to cast
            import std.encoding : Char = AsciiChar;
            enum  utfstr = "8ab3060e-2cba-4f23-b74c-b52db3bdfb46";
            alias String = immutable(Char)[];
            enum String s = cast(String) utfstr;
            enum id = UUID(utfstr);
            //nogc
            Char[36] str;
            id.toString(str[]);
            assert(str == s);
        }

        @safe unittest
        {
            auto u1 = UUID(cast(ubyte[16])[138, 179, 6, 14, 44, 186, 79,
                35, 183, 76, 181, 45, 179, 189, 251, 70]);
            assert(u1.toString() == "8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
            u1 = UUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
            assert(u1.toString() == "8ab3060e-2cba-4f23-b74c-b52db3bdfb46");

            char[] buf;
            void sink(scope const(char)[] data)
            {
                buf ~= data;
            }
            u1.toString(&sink);
            assert(buf == "8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
        }
}

///
@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 `UUID.init` is used.
 *
 * Note:
 * The default namespaces ($(LREF dnsNamespace), ...) defined by
 * this module should be used when appropriate.
 *
 * RFC 4122 recommends to use Version 5 UUIDs (SHA-1) instead of Version 3
 * UUIDs (MD5) for new applications.
 *
 * CTFE:
 * CTFE is not supported.
 *
 * Note:
 * 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 `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).
 *
 * Note:
 * This function does not provide overloads for wstring and dstring, as
 * there's no clear answer on how that should be implemented. It could be
 * argued, that string, wstring and dstring input should have the same output,
 * but that wouldn't be compatible with Boost, which generates different output
 * 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 md5UUID(const(char[]) name, const UUID namespace = UUID.init)
{
    return md5UUID(cast(const(ubyte[]))name, namespace);
}

/// ditto
@safe pure nothrow @nogc UUID md5UUID(const(ubyte[]) data, const UUID namespace = UUID.init)
{
    import std.digest.md : MD5;

    MD5 hash;
    hash.start();

    /*
     * NOTE: RFC 4122 says namespace should be converted to big-endian.
     * We always keep the UUID data in big-endian representation, so
     * that's fine
     */
    hash.put(namespace.data[]);
    hash.put(data[]);

    UUID u;
    u.data = hash.finish();

    //set variant
    //must be 0b10xxxxxx
    u.data[8] &= 0b10111111;
    u.data[8] |= 0b10000000;

    //set version
    //must be 0b0011xxxx
    u.data[6] &= 0b00111111;
    u.data[6] |= 0b00110000;

    return u;
}

///
@safe unittest
{
    //Use default UUID.init namespace
    auto simpleID = md5UUID("test.uuid.any.string");

    //use a name-based id as namespace
    auto namespace = md5UUID("my.app");
    auto id = md5UUID("some-description", namespace);
}

@safe pure unittest
{
    auto simpleID = md5UUID("test.uuid.any.string");
    assert(simpleID.data == cast(ubyte[16])[126, 206, 86, 72, 29, 233, 62, 213, 178, 139, 198, 136,
        188, 135, 153, 123]);
    auto namespace = md5UUID("my.app");
    auto id = md5UUID("some-description", namespace);
    assert(id.data == cast(ubyte[16])[166, 138, 167, 79, 48, 219, 55, 166, 170, 103, 39, 73, 216,
        150, 144, 164]);

    auto constTest = md5UUID(cast(const(char)[])"test");
    constTest = md5UUID(cast(const(char[]))"test");

    char[] mutable = "test".dup;
    id = md5UUID(mutable, namespace);

    const(ubyte)[] data = cast(ubyte[])[0,1,2,244,165,222];
    id = md5UUID(data);
    assert(id.data == cast(ubyte[16])[16, 50, 29, 247, 243, 185, 61, 178, 157, 100, 253, 236, 73,
        76, 51, 47]);

    assert(id.variant == UUID.Variant.rfc4122);
    assert(id.uuidVersion == UUID.Version.nameBasedMD5);

    auto correct = UUID("3d813cbb-47fb-32ba-91df-831e1593ac29");

    auto u = md5UUID("www.widgets.com", dnsNamespace);
    //enum ctfeId = md5UUID("www.widgets.com", dnsNamespace);
    //assert(ctfeId == u);
    assert(u == correct);
    assert(u.variant == UUID.Variant.rfc4122);
    assert(u.uuidVersion == UUID.Version.nameBasedMD5);
}

 /**
 * 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 `UUID.init` is used.
 *
 * Note:
 * The default namespaces ($(LREF dnsNamespace), ...) defined by
 * this module should be used when appropriate.
 *
 * CTFE:
 * CTFE is not supported.
 *
 * Note:
 * 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 `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).
 *
 * Note:
 * This function does not provide overloads for wstring and dstring, as
 * there's no clear answer on how that should be implemented. It could be
 * argued, that string, wstring and dstring input should have the same output,
 * but that wouldn't be compatible with Boost, which generates different output
 * 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(scope const(char)[] name, scope const UUID namespace = UUID.init)
{
    return sha1UUID(cast(const(ubyte[]))name, namespace);
}

/// ditto
@safe pure nothrow @nogc UUID sha1UUID(scope const(ubyte)[] data, scope const UUID namespace = UUID.init)
{
    import std.digest.sha : SHA1;

    SHA1 sha;
    sha.start();

    /*
     * NOTE: RFC 4122 says namespace should be converted to big-endian.
     * We always keep the UUID data in big-endian representation, so
     * that's fine
     */
    sha.put(namespace.data[]);
    sha.put(data[]);

    auto hash = sha.finish();
    auto u = UUID();
    u.data[] = hash[0 .. 16];

    //set variant
    //must be 0b10xxxxxx
    u.data[8] &= 0b10111111;
    u.data[8] |= 0b10000000;

    //set version
    //must be 0b0101xxxx
    u.data[6] &= 0b01011111;
    u.data[6] |= 0b01010000;

    return u;
}

///
@safe unittest
{
    //Use default UUID.init namespace
    auto simpleID = sha1UUID("test.uuid.any.string");

    //use a name-based id as namespace
    auto namespace = sha1UUID("my.app");
    auto id = sha1UUID("some-description", namespace);
}

@safe pure unittest
{
    auto simpleID = sha1UUID("test.uuid.any.string");
    assert(simpleID.data == cast(ubyte[16])[16, 209, 239, 61, 99, 12, 94, 70, 159, 79, 255, 250,
        131, 79, 14, 147]);
    auto namespace = sha1UUID("my.app");
    auto id = sha1UUID("some-description", namespace);
    assert(id.data == cast(ubyte[16])[225, 94, 195, 219, 126, 75, 83, 71, 157, 52, 247, 43, 238, 248,
        148, 46]);

    auto constTest = sha1UUID(cast(const(char)[])"test");
    constTest = sha1UUID(cast(const(char[]))"test");

    char[] mutable = "test".dup;
    id = sha1UUID(mutable, namespace);

    const(ubyte)[] data = cast(ubyte[])[0,1,2,244,165,222];
    id = sha1UUID(data);
    assert(id.data == cast(ubyte[16])[60, 65, 92, 240, 96, 46, 95, 238, 149, 100, 12, 64, 199, 194,
        243, 12]);

    auto correct = UUID("21f7f8de-8051-5b89-8680-0195ef798b6a");

    auto u = sha1UUID("www.widgets.com", dnsNamespace);
    assert(u == correct);
    assert(u.variant == UUID.Variant.rfc4122);
    assert(u.uuidVersion == UUID.Version.nameBasedSHA1);
}

/**
 * This function generates a random number based UUID from a random
 * number generator.
 *
 * This function is not supported at compile time.
 *
 * Params:
 *      randomGen = uniform RNG
 * See_Also: $(REF isUniformRNG, std,random)
 */
@safe UUID randomUUID()
{
    import std.random : 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
UUID randomUUID(RNG)(ref RNG randomGen)
if (isInputRange!RNG && isIntegral!(ElementType!RNG))
{
    import std.random : isUniformRNG;
    static assert(isUniformRNG!RNG, "randomGen must be a uniform RNG");

    alias E = ElementEncodingType!RNG;
    enum size_t elemSize = E.sizeof;
    static assert(elemSize <= 16);
    static assert(16 % elemSize == 0);

    UUID u;
    foreach (ref E e ; u.asArrayOf!E())
    {
        e = randomGen.front;
        randomGen.popFront();
    }

    //set variant
    //must be 0b10xxxxxx
    u.data[8] &= 0b10111111;
    u.data[8] |= 0b10000000;

    //set version
    //must be 0b0100xxxx
    u.data[6] &= 0b01001111;
    u.data[6] |= 0b01000000;

    return u;
}

///
@safe unittest
{
    import std.random : Xorshift192, unpredictableSeed;

    //simple call
    auto uuid = randomUUID();

    //provide a custom RNG. Must be seeded manually.
    Xorshift192 gen;

    gen.seed(unpredictableSeed);
    auto uuid3 = randomUUID(gen);
}

@safe unittest
{
    import std.random : Xorshift192, unpredictableSeed;
    //simple call
    auto uuid = randomUUID();

    //provide a custom RNG. Must be seeded manually.
    Xorshift192 gen;
    gen.seed(unpredictableSeed);
    auto uuid3 = randomUUID(gen);

    auto u1 = randomUUID();
    auto u2 = randomUUID();
    assert(u1 != u2);
    assert(u1.variant == UUID.Variant.rfc4122);
    assert(u1.uuidVersion == UUID.Version.randomNumberBased);
}

/**
 * This is a less strict parser compared to the parser used in the
 * UUID constructor. It enforces the following rules:
 *
 * $(UL
 *   $(LI hex numbers are always two hexdigits([0-9a-fA-F]))
 *   $(LI there must be exactly 16 such pairs in the input, not less, not more)
 *   $(LI there can be exactly one dash between two hex-pairs, but not more)
 *   $(LI there can be multiple characters enclosing the 16 hex pairs,
 *     as long as these characters do not contain [0-9a-fA-F])
 * )
 *
 * Note:
 * Like most parsers, it consumes its argument. This means:
 * -------------------------
 * string s = "8AB3060E-2CBA-4F23-b74c-B52Db3BDFB46";
 * parseUUID(s);
 * assert(s == "");
 * -------------------------
 *
 * Throws:
 * $(LREF UUIDParsingException) if the input is invalid
 *
 * CTFE:
 * This function is supported in CTFE code. Note that error messages
 * caused by a malformed UUID parsed at compile time can be cryptic,
 * but errors are detected and reported at compile time.
 */
UUID parseUUID(T)(T uuidString)
if (isSomeString!T)
{
    return parseUUID(uuidString);
}

///ditto
UUID parseUUID(Range)(ref Range uuidRange)
if (isInputRange!Range && isSomeChar!(ElementType!Range))
{
    import std.ascii : isHexDigit;
    import std.conv : ConvException, parse;

    static if (isForwardRange!Range)
        auto errorCopy = uuidRange.save;

    void parserError()(size_t pos, UUIDParsingException.Reason reason, string message, Throwable next = null,
        string file = __FILE__, size_t line = __LINE__)
    {
        static if (isForwardRange!Range)
        {
            import std.conv : to;
            static if (isInfinite!Range)
            {
                throw new UUIDParsingException(to!string(take(errorCopy, pos)), pos, reason, message,
                    next, file, line);
            }
            else
            {
                throw new UUIDParsingException(to!string(errorCopy), pos, reason, message, next, file,
                    line);
            }
        }
        else
        {
            throw new UUIDParsingException("", pos, reason, message, next, file, line);
        }
    }

    static if (hasLength!Range)
    {
        import std.conv : to;
        if (uuidRange.length < 32)
        {
            throw new UUIDParsingException(to!string(uuidRange), 0, UUIDParsingException.Reason.tooLittle,
                "Insufficient Input");
        }
    }

    UUID result;
    size_t consumed;
    size_t element = 0;

    //skip garbage
    size_t skip()()
    {
        size_t skipped;
        while (!uuidRange.empty && !isHexDigit(uuidRange.front))
        {
            skipped++;
            uuidRange.popFront();
        }
        return skipped;
    }

    consumed += skip();

    if (uuidRange.empty)
        parserError(consumed, UUIDParsingException.Reason.tooLittle, "Insufficient Input");

    bool dashAllowed = false;

    parseLoop: while (!uuidRange.empty)
    {
        immutable character = uuidRange.front;

        if (character == '-')
        {
            if (!dashAllowed)
                parserError(consumed, UUIDParsingException.Reason.invalidChar, "Unexpected '-'");
            else
                dashAllowed = false;

            consumed++;
        }
        else if (!isHexDigit(character))
        {
            parserError(consumed, UUIDParsingException.Reason.invalidChar,
                "Unexpected character (wanted a hexDigit)");
        }
        else
        {
            try
            {
                consumed += 2;
                static if (isSomeString!Range)
                {
                    if (uuidRange.length < 2)
                    {
                        parserError(consumed, UUIDParsingException.Reason.tooLittle,
                            "Insufficient Input");
                    }
                    auto part = uuidRange[0 .. 2];
                    result.data[element++] = parse!ubyte(part, 16);
                    uuidRange.popFront();
                }
                else
                {
                    dchar[2] copyBuf;
                    copyBuf[0] = character;
                    uuidRange.popFront();
                    if (uuidRange.empty)
                    {
                        parserError(consumed, UUIDParsingException.Reason.tooLittle,
                            "Insufficient Input");
                    }
                    copyBuf[1] = uuidRange.front;
                    auto part = copyBuf[];
                    result.data[element++] = parse!ubyte(part, 16);
                }

                if (element == 16)
                {
                    uuidRange.popFront();
                    break parseLoop;
                }

                dashAllowed = true;
            }
            catch (ConvException e)
            {
                parserError(consumed, UUIDParsingException.Reason.invalidChar,
                    "Couldn't parse ubyte", e);
            }
        }
        uuidRange.popFront();
    }
    assert(element <= 16);

    if (element < 16)
        parserError(consumed, UUIDParsingException.Reason.tooLittle, "Insufficient Input");

    consumed += skip();
    if (!uuidRange.empty)
        parserError(consumed, UUIDParsingException.Reason.invalidChar, "Unexpected character");

    return result;
}

///
@safe unittest
{
    auto id = parseUUID("8AB3060E-2CBA-4F23-b74c-B52Db3BDFB46");
    //no dashes
    id = parseUUID("8ab3060e2cba4f23b74cb52db3bdfb46");
    //dashes at different positions
    id = parseUUID("8a-b3-06-0e2cba4f23b74c-b52db3bdfb-46");
    //leading / trailing characters
    id = parseUUID("{8ab3060e-2cba-4f23-b74c-b52db3bdfb46}");
    //unicode
    id = parseUUID("ü8ab3060e2cba4f23b74cb52db3bdfb46ü");
    //multiple trailing/leading characters
    id = parseUUID("///8ab3060e2cba4f23b74cb52db3bdfb46||");

    //Can also be used in CTFE, for example as UUID literals:
    enum ctfeID = parseUUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
    //here parsing is done at compile time, no runtime overhead!
}

@safe pure unittest
{
    import std.conv : to;
    import std.exception;
    import std.meta;

    struct TestRange(bool forward)
    {
        dstring input;

        @property dchar front()
        {
            return input.front;
        }

        void popFront()
        {
            input.popFront();
        }

        @property bool empty()
        {
            return input.empty;
        }

        static if (forward)
        {
            @property TestRange!true save()
            {
                return this;
            }
        }
    }
    alias TestInputRange = TestRange!false;
    alias TestForwardRange = TestRange!true;

    assert(isInputRange!TestInputRange);
    assert(is(ElementType!TestInputRange == dchar));
    assert(isInputRange!TestForwardRange);
    assert(isForwardRange!TestForwardRange);
    assert(is(ElementType!TestForwardRange == dchar));

    //Helper function for unittests - Need to pass ranges by ref
    UUID parseHelper(T)(string input)
    {
        static if (is(T == TestInputRange) || is(T == TestForwardRange))
        {
            T range = T(to!dstring(input));
            return parseUUID(range);
        }
        else
            return parseUUID(to!T(input));
    }

    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
        id = parseHelper!S("8ab3060e2cba4f23b74cb52db3bdfb46");
        //dashes at different positions
        id = parseHelper!S("8a-b3-06-0e2cba4f23b74c-b52db3bdfb-46");
        //leading / trailing characters
        id = parseHelper!S("{8ab3060e-2cba-4f23-b74c-b52db3bdfb46}");
        //unicode
        id = parseHelper!S("ü8ab3060e2cba4f23b74cb52db3bdfb46ü");
        //multiple trailing/leading characters
        id = parseHelper!S("///8ab3060e2cba4f23b74cb52db3bdfb46||");
        enum ctfeId = parseHelper!S("8ab3060e-2cba-4f23-b74c-b52db3bdfb46");
        assert(parseHelper!S("8AB3060E-2cba-4f23-b74c-b52db3bdfb46") == ctfeId);

        //Test valid, working cases
        assert(parseHelper!S("00000000-0000-0000-0000-000000000000").empty);
        assert(parseHelper!S("8AB3060E-2CBA-4F23-b74c-B52Db3BDFB46").data
            == [138, 179, 6, 14, 44, 186, 79, 35, 183, 76, 181, 45, 179, 189, 251, 70]);

        assert(parseHelper!S("5668122d-9df0-49a4-ad0b-b9b0a57f886a").data
            == [86, 104, 18, 45, 157, 240, 73, 164, 173, 11, 185, 176, 165, 127, 136, 106]);

        //wstring / dstring
        assert(parseHelper!S("5668122d-9df0-49a4-ad0b-b9b0a57f886a").data
            == [86, 104, 18, 45, 157, 240, 73, 164, 173, 11, 185, 176, 165, 127, 136, 106]);
        assert(parseHelper!S("5668122d-9df0-49a4-ad0b-b9b0a57f886a").data
            == [86, 104, 18, 45, 157, 240, 73, 164, 173, 11, 185, 176, 165, 127, 136, 106]);

        //Test too short UUIDS
        auto except = collectException!UUIDParsingException(
            parseHelper!S("5668122d-9df0-49a4-ad0b-b9b0a57f886"));
        assert(except && except.reason == UUIDParsingException.Reason.tooLittle);

        //Test too long UUIDS
        except = collectException!UUIDParsingException(
            parseHelper!S("5668122d-9df0-49a4-ad0b-b9b0a57f886aa"));
        assert(except && except.reason == UUIDParsingException.Reason.invalidChar);

        //Test too long UUIDS 2
        except = collectException!UUIDParsingException(
            parseHelper!S("5668122d-9df0-49a4-ad0b-b9b0a57f886a-aa"));
        assert(except && except.reason == UUIDParsingException.Reason.invalidChar);

        //Test dashes
        assert(parseHelper!S("8ab3060e2cba-4f23-b74c-b52db3bdfb46")
            == parseUUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46"));
        assert(parseHelper!S("8ab3-060e2cba-4f23-b74c-b52db3bdfb46")
            == parseUUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46"));
        assert(parseHelper!S("8ab3060e2cba4f23b74cb52db3bdfb46")
            == parseUUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46"));

        except = collectException!UUIDParsingException(
            parseHelper!S("8-ab3060e2cba-4f23-b74c-b52db3bdfb46"));
        assert(except && except.reason == UUIDParsingException.Reason.invalidChar);

        //Test leading/trailing characters
        assert(parseHelper!S("{8ab3060e-2cba-4f23-b74c-b52db3bdfb46}")
            == parseUUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46"));
        assert(parseHelper!S("{8ab3060e2cba4f23b74cb52db3bdfb46}")
            == parseUUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46"));

        //Boost test
        auto u_increasing = UUID(cast(ubyte[16])[0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
            0xcd, 0xef,0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
        assert(parseHelper!S("0123456789abcdef0123456789ABCDEF") == UUID(cast(ubyte[16])[0x01,
            0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]));

        //unicode
        assert(parseHelper!S("ü8ab3060e2cba4f23b74cb52db3bdfb46ü")
            == parseUUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46"));

        //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]);
    }
}

/**
 * Default namespace from RFC 4122
 *
 * Name string is a fully-qualified domain name
 */
enum dnsNamespace = UUID("6ba7b810-9dad-11d1-80b4-00c04fd430c8");

/**
 * Default namespace from RFC 4122
 *
 * Name string is a URL
 */
enum urlNamespace = UUID("6ba7b811-9dad-11d1-80b4-00c04fd430c8");

/**
 * Default namespace from RFC 4122
 *
 * Name string is an ISO OID
 */
enum oidNamespace = UUID("6ba7b812-9dad-11d1-80b4-00c04fd430c8");

/**
 * Default namespace from RFC 4122
 *
 * Name string is an X.500 DN (in DER or a text output format)
 */
enum x500Namespace = UUID("6ba7b814-9dad-11d1-80b4-00c04fd430c8");

/**
 * Regex string to extract UUIDs from text.
 */
enum uuidRegex = "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}"~
    "-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}";

///
@safe unittest
{
    import std.algorithm;
    import std.regex;

    string test = "Lorem ipsum dolor sit amet, consetetur "~
    "6ba7b814-9dad-11d1-80b4-00c04fd430c8 sadipscing \n"~
    "elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore \r\n"~
    "magna aliquyam erat, sed diam voluptua. "~
    "8ab3060e-2cba-4f23-b74c-b52db3bdfb46 At vero eos et accusam et "~
    "justo duo dolores et ea rebum.";

    auto r = regex(uuidRegex, "g");
    UUID[] found;
    foreach (c; match(test, r))
    {
        found ~= UUID(c.hit);
    }
    assert(found == [
        UUID("6ba7b814-9dad-11d1-80b4-00c04fd430c8"),
        UUID("8ab3060e-2cba-4f23-b74c-b52db3bdfb46"),
    ]);
}

/**
 * This exception is thrown if an error occurs when parsing a UUID
 * from a string.
 */
public class UUIDParsingException : Exception
{
    /**
     * The reason why parsing the UUID string failed (if known)
     */
    enum Reason
    {
        unknown, ///
        tooLittle, ///The passed in input was correct, but more input was expected.
        tooMuch, ///The input data is too long (There's no guarantee the first part of the data is valid)
        invalidChar, ///Encountered an invalid character

    }
    ///ditto
    Reason reason;
    ///The original input string which should have been parsed.
    string input;
    ///The position in the input string where the error occurred.
    size_t position;

    private this(string input, size_t pos, Reason why = Reason.unknown, string msg = "",
        Throwable next = null, string file = __FILE__, size_t line = __LINE__) pure @trusted
    {
        import std.array : replace;
        import std.format : format;
        this.input = input;
        this.position = pos;
        this.reason = why;
        string message = format("An error occured in the UUID parser: %s\n" ~
          " * Input:\t'%s'\n * Position:\t%s", msg, replace(replace(input,
          "\r", "\\r"), "\n", "\\n"), pos);
        super(message, file, line, next);
    }
}

///
@safe unittest
{
    import std.exception : collectException;

    const inputUUID = "this-is-an-invalid-uuid";
    auto ex = collectException!UUIDParsingException(UUID(inputUUID));
    assert(ex !is null); // check that exception was thrown
    assert(ex.input == inputUUID);
    assert(ex.position == 0);
    assert(ex.reason == UUIDParsingException.Reason.tooLittle);
}

@safe unittest
{
    auto ex = new UUIDParsingException("foo", 10, UUIDParsingException.Reason.tooMuch);
    assert(ex.input == "foo");
    assert(ex.position == 10);
    assert(ex.reason == UUIDParsingException.Reason.tooMuch);
}
