/**
 * 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)
 */
@nogc nothrow @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);
}
