// Written in the D programming language.

/**
A one-stop shop for converting values from one type to another.

$(SCRIPT inhibitQuickIndex = 1;)
$(DIVC quickindex,
$(BOOKTABLE,
$(TR $(TH Category) $(TH Functions))
$(TR $(TD Generic) $(TD
        $(LREF asOriginalType)
        $(LREF castFrom)
        $(LREF parse)
        $(LREF to)
        $(LREF toChars)
        $(LREF bitCast)
))
$(TR $(TD Strings) $(TD
        $(LREF text)
        $(LREF wtext)
        $(LREF dtext)
        $(LREF writeText)
        $(LREF writeWText)
        $(LREF writeDText)
        $(LREF hexString)
))
$(TR $(TD Numeric) $(TD
        $(LREF octal)
        $(LREF roundTo)
        $(LREF signed)
        $(LREF unsigned)
))
$(TR $(TD Exceptions) $(TD
        $(LREF ConvException)
        $(LREF ConvOverflowException)
))
))

Copyright: Copyright The D Language Foundation 2007-.

License:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).

Authors:   $(HTTP digitalmars.com, Walter Bright),
           $(HTTP erdani.org, Andrei Alexandrescu),
           Shin Fujishiro,
           Adam D. Ruppe,
           Kenji Hara

Source:    $(PHOBOSSRC std/conv.d)

*/
module std.conv;

public import std.ascii : LetterCase;

import std.meta;
import std.range;
import std.traits;
import std.typecons : Flag, Yes, No, tuple, isTuple;

// Same as std.string.format, but "self-importing".
// Helps reduce code and imports, particularly in static asserts.
// Also helps with missing imports errors.
package template convFormat()
{
    import std.format : format;
    alias convFormat = format;
}

/* ************* Exceptions *************** */

/**
 * Thrown on conversion errors.
 */
class ConvException : Exception
{
    import std.exception : basicExceptionCtors;
    ///
    mixin basicExceptionCtors;
}

///
@safe unittest
{
    import std.exception : assertThrown;
    assertThrown!ConvException(to!int("abc"));
}

private auto convError(S, T)(S source, string fn = __FILE__, size_t ln = __LINE__)
{
    string msg;

    if (source.empty)
        msg = "Unexpected end of input when converting from type " ~ S.stringof ~ " to type " ~ T.stringof;
    else
    {
        ElementType!S el = source.front;

        if (el == '\n')
            msg = text("Unexpected '\\n' when converting from type " ~ S.stringof ~ " to type " ~ T.stringof);
        else
            msg =  text("Unexpected '", el,
                 "' when converting from type " ~ S.stringof ~ " to type " ~ T.stringof);
    }

    return new ConvException(msg, fn, ln);
}

@safe pure/* nothrow*/  // lazy parameter bug
private auto parseError(lazy string msg, string fn = __FILE__, size_t ln = __LINE__)
{
    return new ConvException(text("Can't parse string: ", msg), fn, ln);
}

private void parseCheck(alias source)(dchar c, string fn = __FILE__, size_t ln = __LINE__)
{
    if (source.empty)
        throw parseError(text("unexpected end of input when expecting \"", c, "\""));
    if (source.front != c)
        throw parseError(text("\"", c, "\" is missing"), fn, ln);
    source.popFront();
}

private
{
    T toStr(T, S)(S src)
    if (isSomeString!T)
    {
        // workaround for https://issues.dlang.org/show_bug.cgi?id=14198
        static if (is(S == bool) && is(typeof({ T s = "string"; })))
        {
            return src ? "true" : "false";
        }
        else
        {
            import std.array : appender;
            import std.format.spec : FormatSpec;
            import std.format.write : formatValue;

            auto w = appender!T();
            FormatSpec!(ElementEncodingType!T) f;
            formatValue(w, src, f);
            return w.data;
        }
    }

    template isExactSomeString(T)
    {
        enum isExactSomeString = isSomeString!T && !is(T == enum);
    }

    template isEnumStrToStr(S, T)
    {
        enum isEnumStrToStr = is(S : T) &&
                              is(S == enum) && isExactSomeString!T;
    }
    template isNullToStr(S, T)
    {
        enum isNullToStr = is(S : T) &&
                           (is(immutable S == immutable typeof(null))) && isExactSomeString!T;
    }
}

/**
 * Thrown on conversion overflow errors.
 */
class ConvOverflowException : ConvException
{
    @safe pure nothrow
    this(string s, string fn = __FILE__, size_t ln = __LINE__)
    {
        super(s, fn, ln);
    }
}

///
@safe unittest
{
    import std.exception : assertThrown;
    assertThrown!ConvOverflowException(to!ubyte(1_000_000));
}

/**
The `to` template converts a value from one type _to another.
The source type is deduced and the target type must be specified, for example the
expression `to!int(42.0)` converts the number 42 from
`double` _to `int`. The conversion is "safe", i.e.,
it checks for overflow; `to!int(4.2e10)` would throw the
`ConvOverflowException` exception. Overflow checks are only
inserted when necessary, e.g., `to!double(42)` does not do
any checking because any `int` fits in a `double`.

Conversions from string _to numeric types differ from the C equivalents
`atoi()` and `atol()` by checking for overflow and not allowing whitespace.

For conversion of strings _to signed types, the grammar recognized is:
$(PRE $(I Integer):
    $(I Sign UnsignedInteger)
    $(I UnsignedInteger)
$(I Sign):
    $(B +)
    $(B -))

For conversion _to unsigned types, the grammar recognized is:
$(PRE $(I UnsignedInteger):
    $(I DecimalDigit)
    $(I DecimalDigit) $(I UnsignedInteger))
 */
template to(T)
{
    T to(A...)(A args)
    if (A.length > 0)
    {
        return toImpl!T(args);
    }

    // Fix https://issues.dlang.org/show_bug.cgi?id=6175
    T to(S)(ref S arg)
    if (isStaticArray!S)
    {
        return toImpl!T(arg);
    }

    // Fix https://issues.dlang.org/show_bug.cgi?id=16108
    T to(S)(ref S arg)
    if (isAggregateType!S && !isCopyable!S)
    {
        return toImpl!T(arg);
    }
}

/**
 * Converting a value _to its own type (useful mostly for generic code)
 * simply returns its argument.
 */
@safe pure unittest
{
    int a = 42;
    int b = to!int(a);
    double c = to!double(3.14); // c is double with value 3.14
}

/**
 * Converting among numeric types is a safe way _to cast them around.
 *
 * Conversions from floating-point types _to integral types allow loss of
 * precision (the fractional part of a floating-point number). The
 * conversion is truncating towards zero, the same way a cast would
 * truncate. (_To round a floating point value when casting _to an
 * integral, use `roundTo`.)
 */
@safe pure unittest
{
    import std.exception : assertThrown;

    int a = 420;
    assert(to!long(a) == a);
    assertThrown!ConvOverflowException(to!byte(a));

    assert(to!int(4.2e6) == 4200000);
    assertThrown!ConvOverflowException(to!uint(-3.14));
    assert(to!uint(3.14) == 3);
    assert(to!uint(3.99) == 3);
    assert(to!int(-3.99) == -3);
}

/**
 * When converting strings _to numeric types, note that D hexadecimal and binary
 * literals are not handled. Neither the prefixes that indicate the base, nor the
 * horizontal bar used _to separate groups of digits are recognized. This also
 * applies to the suffixes that indicate the type.
 *
 * _To work around this, you can specify a radix for conversions involving numbers.
 */
@safe pure unittest
{
    auto str = to!string(42, 16);
    assert(str == "2A");
    auto i = to!int(str, 16);
    assert(i == 42);
}

/**
 * Conversions from integral types _to floating-point types always
 * succeed, but might lose accuracy. The largest integers with a
 * predecessor representable in floating-point format are `2^24-1` for
 * `float`, `2^53-1` for `double`, and `2^64-1` for `real` (when
 * `real` is 80-bit, e.g. on Intel machines).
 */
@safe pure unittest
{
    // 2^24 - 1, largest proper integer representable as float
    int a = 16_777_215;
    assert(to!int(to!float(a)) == a);
    assert(to!int(to!float(-a)) == -a);
}

/**
   Conversion from string types to char types enforces the input
   to consist of a single code point, and said code point must
   fit in the target type. Otherwise, $(LREF ConvException) is thrown.
 */
@safe pure unittest
{
    import std.exception : assertThrown;

    assert(to!char("a") == 'a');
    assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
    assert(to!wchar("ñ") == 'ñ');
    assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
    assert(to!dchar("😃") == '😃');

    // Using wstring or dstring as source type does not affect the result
    assert(to!char("a"w) == 'a');
    assert(to!char("a"d) == 'a');

    // Two code points cannot be converted to a single one
    assertThrown(to!char("ab"));
}

/**
 * Converting an array _to another array type works by converting each
 * element in turn. Associative arrays can be converted _to associative
 * arrays as long as keys and values can in turn be converted.
 */
@safe pure unittest
{
    import std.string : split;

    int[] a = [1, 2, 3];
    auto b = to!(float[])(a);
    assert(b == [1.0f, 2, 3]);
    string str = "1 2 3 4 5 6";
    auto numbers = to!(double[])(split(str));
    assert(numbers == [1.0, 2, 3, 4, 5, 6]);
    int[string] c;
    c["a"] = 1;
    c["b"] = 2;
    auto d = to!(double[wstring])(c);
    assert(d["a"w] == 1 && d["b"w] == 2);
}

/**
 * Conversions operate transitively, meaning that they work on arrays and
 * associative arrays of any complexity.
 *
 * This conversion works because `to!short` applies _to an `int`, `to!wstring`
 * applies _to a `string`, `to!string` applies _to a `double`, and
 * `to!(double[])` applies _to an `int[]`. The conversion might throw an
 * exception because `to!short` might fail the range check.
 */
@safe unittest
{
    int[string][double[int[]]] a;
    auto b = to!(short[wstring][string[double[]]])(a);
}

/**
 * Object-to-object conversions by dynamic casting throw exception when
 * the source is non-null and the target is null.
 */
@safe pure unittest
{
    import std.exception : assertThrown;
    // Testing object conversions
    class A {}
    class B : A {}
    class C : A {}
    A a1 = new A, a2 = new B, a3 = new C;
    assert(to!B(a2) is a2);
    assert(to!C(a3) is a3);
    assertThrown!ConvException(to!B(a3));
}

/**
 * Stringize conversion from all types is supported.
 * $(UL
 *   $(LI String _to string conversion works for any two string types having
 *        (`char`, `wchar`, `dchar`) character widths and any
 *        combination of qualifiers (mutable, `const`, or `immutable`).)
 *   $(LI Converts array (other than strings) _to string.
 *        Each element is converted by calling `to!T`.)
 *   $(LI Associative array _to string conversion.
 *        Each element is converted by calling `to!T`.)
 *   $(LI Object _to string conversion calls `toString` against the object or
 *        returns `"null"` if the object is null.)
 *   $(LI Struct _to string conversion calls `toString` against the struct if
 *        it is defined.)
 *   $(LI For structs that do not define `toString`, the conversion _to string
 *        produces the list of fields.)
 *   $(LI Enumerated types are converted _to strings as their symbolic names.)
 *   $(LI Boolean values are converted to `"true"` or `"false"`.)
 *   $(LI `char`, `wchar`, `dchar` _to a string type.)
 *   $(LI Unsigned or signed integers _to strings.
 *        $(DL $(DT [special case])
 *             $(DD Convert integral value _to string in $(D_PARAM radix) radix.
 *             radix must be a value from 2 to 36.
 *             value is treated as a signed value only if radix is 10.
 *             The characters A through Z are used to represent values 10 through 36
 *             and their case is determined by the $(D_PARAM letterCase) parameter.)))
 *   $(LI All floating point types _to all string types.)
 *   $(LI Pointer to string conversions convert the pointer to a `size_t` value.
 *        If pointer is `char*`, treat it as C-style strings.
 *        In that case, this function is `@system`.))
 * See $(REF formatValue, std,format) on how `toString` should be defined.
 */
@system pure unittest // @system due to cast and ptr
{
    // Conversion representing dynamic/static array with string
    long[] a = [ 1, 3, 5 ];
    assert(to!string(a) == "[1, 3, 5]");

    // Conversion representing associative array with string
    int[string] associativeArray = ["0":1, "1":2];
    assert(to!string(associativeArray) == `["0":1, "1":2]` ||
           to!string(associativeArray) == `["1":2, "0":1]`);

    // char* to string conversion
    assert(to!string(cast(char*) null) == "");
    assert(to!string("foo\0".ptr) == "foo");

    // Conversion reinterpreting void array to string
    auto w = "abcx"w;
    const(void)[] b = w;
    assert(b.length == 8);

    auto c = to!(wchar[])(b);
    assert(c == "abcx");
}

/**
 * Strings can be converted to enum types. The enum member with the same name as the
 * input string is returned. The comparison is case-sensitive.
 *
 * A $(LREF ConvException) is thrown if the enum does not have the specified member.
 */
@safe pure unittest
{
    import std.exception : assertThrown;

    enum E { a, b, c }
    assert(to!E("a") == E.a);
    assert(to!E("b") == E.b);
    assertThrown!ConvException(to!E("A"));
}

// Tests for https://issues.dlang.org/show_bug.cgi?id=6175
@safe pure nothrow unittest
{
    char[9] sarr = "blablabla";
    auto darr = to!(char[])(sarr);
    assert(sarr.ptr == darr.ptr);
    assert(sarr.length == darr.length);
}

// Tests for https://issues.dlang.org/show_bug.cgi?id=7348
@safe pure /+nothrow+/ unittest
{
    assert(to!string(null) == "null");
    assert(text(null) == "null");
}

// Test `scope` inference of parameters of `text`
@safe unittest
{
    static struct S
    {
        int* x; // make S a type with pointers
        string toString() const scope
        {
            return "S";
        }
    }
    scope S s;
    assert(text("a", s) == "aS");
}

// Tests for https://issues.dlang.org/show_bug.cgi?id=11390
@safe pure /+nothrow+/ unittest
{
    const(typeof(null)) ctn;
    immutable(typeof(null)) itn;
    assert(to!string(ctn) == "null");
    assert(to!string(itn) == "null");
}

// Tests for https://issues.dlang.org/show_bug.cgi?id=8729: do NOT skip leading WS
@safe pure unittest
{
    import std.exception;
    static foreach (T; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))
    {
        assertThrown!ConvException(to!T(" 0"));
        assertThrown!ConvException(to!T(" 0", 8));
    }
    static foreach (T; AliasSeq!(float, double, real))
    {
        assertThrown!ConvException(to!T(" 0"));
    }

    assertThrown!ConvException(to!bool(" true"));

    alias NullType = typeof(null);
    assertThrown!ConvException(to!NullType(" null"));

    alias ARR = int[];
    assertThrown!ConvException(to!ARR(" [1]"));

    alias AA = int[int];
    assertThrown!ConvException(to!AA(" [1:1]"));
}

// https://issues.dlang.org/show_bug.cgi?id=20623
@safe pure nothrow unittest
{
    // static class C
    // {
    //     override string toString() const
    //     {
    //         return "C()";
    //     }
    // }

    static struct S
    {
        bool b;
        int i;
        float f;
        int[] a;
        int[int] aa;
        S* p;
        // C c; // TODO: Fails because of hasToString

        void fun() inout
        {
            static foreach (const idx; 0 .. this.tupleof.length)
            {
                {
                    const _ = this.tupleof[idx].to!string();
                }
            }
        }
    }
}

private T toImpl(T, S)(S)
if (isInputRange!S && isInfinite!S && isExactSomeString!T)
{
    static assert(0, "Cannot convert infinite range to string. " ~
                "Use `std.range.take` or `std.range.takeExactly` to make it finite.");
}

// Test for issue : https://github.com/dlang/phobos/issues/10559
@safe pure nothrow unittest
{
    import std.range : repeat;
    import std.conv : to;

    // Test that converting an infinite range doesn't compile
    static assert(!__traits(compiles, repeat(1).to!string));
}

/**
If the source type is implicitly convertible to the target type, $(D
to) simply performs the implicit conversion.
 */
private T toImpl(T, S)(S value)
if (is(S : T) &&
    !isEnumStrToStr!(S, T) && !isNullToStr!(S, T))
{
    template isSignedInt(T)
    {
        enum isSignedInt = isIntegral!T && isSigned!T;
    }
    alias isUnsignedInt = isUnsigned;

    // Conversion from integer to integer, and changing its sign
    static if (isUnsignedInt!S && isSignedInt!T && S.sizeof == T.sizeof)
    {   // unsigned to signed & same size
        import std.exception : enforce;
        enforce(value <= cast(S) T.max,
                new ConvOverflowException("Conversion positive overflow"));
    }
    else static if (isSignedInt!S && isUnsignedInt!T)
    {   // signed to unsigned
        import std.exception : enforce;
        enforce(0 <= value,
                new ConvOverflowException("Conversion negative overflow"));
    }

    return value;
}

// https://issues.dlang.org/show_bug.cgi?id=9523: Allow identity enum conversion
@safe pure nothrow unittest
{
    enum E { a }
    auto e = to!E(E.a);
    assert(e == E.a);
}

@safe pure nothrow unittest
{
    int a = 42;
    auto b = to!long(a);
    assert(a == b);
}

// https://issues.dlang.org/show_bug.cgi?id=6377
@safe pure unittest
{
    import std.exception;
    // Conversion between same size
    static foreach (S; AliasSeq!(byte, short, int, long))
    {{
        alias U = Unsigned!S;

        static foreach (Sint; AliasSeq!(S, const S, immutable S))
        static foreach (Uint; AliasSeq!(U, const U, immutable U))
        {{
            // positive overflow
            Uint un = Uint.max;
            assertThrown!ConvOverflowException(to!Sint(un),
                text(Sint.stringof, ' ', Uint.stringof, ' ', un));

            // negative overflow
            Sint sn = -1;
            assertThrown!ConvOverflowException(to!Uint(sn),
                text(Sint.stringof, ' ', Uint.stringof, ' ', un));
        }}
    }}

    // Conversion between different size
    static foreach (i, S1; AliasSeq!(byte, short, int, long))
    static foreach (   S2; AliasSeq!(byte, short, int, long)[i+1..$])
    {{
        alias U1 = Unsigned!S1;
        alias U2 = Unsigned!S2;

        static assert(U1.sizeof < S2.sizeof);

        // small unsigned to big signed
        static foreach (Uint; AliasSeq!(U1, const U1, immutable U1))
        static foreach (Sint; AliasSeq!(S2, const S2, immutable S2))
        {{
            Uint un = Uint.max;
            assertNotThrown(to!Sint(un));
            assert(to!Sint(un) == un);
        }}

        // big unsigned to small signed
        static foreach (Uint; AliasSeq!(U2, const U2, immutable U2))
        static foreach (Sint; AliasSeq!(S1, const S1, immutable S1))
        {{
            Uint un = Uint.max;
            assertThrown(to!Sint(un));
        }}

        static assert(S1.sizeof < U2.sizeof);

        // small signed to big unsigned
        static foreach (Sint; AliasSeq!(S1, const S1, immutable S1))
        static foreach (Uint; AliasSeq!(U2, const U2, immutable U2))
        {{
            Sint sn = -1;
            assertThrown!ConvOverflowException(to!Uint(sn));
        }}

        // big signed to small unsigned
        static foreach (Sint; AliasSeq!(S2, const S2, immutable S2))
        static foreach (Uint; AliasSeq!(U1, const U1, immutable U1))
        {{
            Sint sn = -1;
            assertThrown!ConvOverflowException(to!Uint(sn));
        }}
    }}
}

// https://issues.dlang.org/show_bug.cgi?id=13551
private T toImpl(T, S)(S value)
if (isTuple!T)
{
    T t;
    static foreach (i; 0 .. T.length)
    {
        t[i] = value[i].to!(typeof(T[i]));
    }
    return t;
}

@safe unittest
{
    import std.typecons : Tuple;

    auto test = ["10", "20", "30"];
    assert(test.to!(Tuple!(int, int, int)) == Tuple!(int, int, int)(10, 20, 30));

    auto test1 = [1, 2];
    assert(test1.to!(Tuple!(int, int)) == Tuple!(int, int)(1, 2));

    auto test2 = [1.0, 2.0, 3.0];
    assert(test2.to!(Tuple!(int, int, int)) == Tuple!(int, int, int)(1, 2, 3));
}

/*
  Converting static arrays forwards to their dynamic counterparts.
 */
private T toImpl(T, S)(ref S s)
if (isStaticArray!S)
{
    return toImpl!(T, typeof(s[0])[])(s);
}

@safe pure nothrow unittest
{
    char[4] test = ['a', 'b', 'c', 'd'];
    static assert(!isInputRange!(Unqual!(char[4])));
    assert(to!string(test) == test);
}

/**
When source type supports member template function opCast, it is used.
*/
private T toImpl(T, S)(S value)
if (!is(S : T) &&
    is(typeof(S.init.opCast!T()) : T) &&
    !isExactSomeString!T &&
    !is(typeof(T(value))))
{
    return value.opCast!T();
}

@safe pure unittest
{
    static struct Test
    {
        struct T
        {
            this(S s) @safe pure { }
        }
        struct S
        {
            T opCast(U)() @safe pure { assert(false); }
        }
    }
    cast(void) to!(Test.T)(Test.S());

    // make sure std.conv.to is doing the same thing as initialization
    Test.S s;
    Test.T t = s;
}

@safe pure unittest
{
    class B
    {
        T opCast(T)() { return 43; }
    }
    auto b = new B;
    assert(to!int(b) == 43);

    struct S
    {
        T opCast(T)() { return 43; }
    }
    auto s = S();
    assert(to!int(s) == 43);
}

/**
When target type supports 'converting construction', it is used.
$(UL $(LI If target type is struct, `T(value)` is used.)
     $(LI If target type is class, $(D new T(value)) is used.))
*/
private T toImpl(T, S)(S value)
if (!is(S : T) &&
    is(T == struct) && is(typeof(T(value))))
{
    return T(value);
}

// https://issues.dlang.org/show_bug.cgi?id=3961
@safe pure unittest
{
    struct Int
    {
        int x;
    }
    Int i = to!Int(1);

    static struct Int2
    {
        int x;
        this(int x) @safe pure { this.x = x; }
    }
    Int2 i2 = to!Int2(1);

    static struct Int3
    {
        int x;
        static Int3 opCall(int x) @safe pure
        {
            Int3 i;
            i.x = x;
            return i;
        }
    }
    Int3 i3 = to!Int3(1);
}

// https://issues.dlang.org/show_bug.cgi?id=6808
@safe pure unittest
{
    static struct FakeBigInt
    {
        this(string s) @safe pure {}
    }

    string s = "101";
    auto i3 = to!FakeBigInt(s);
}

/// ditto
private T toImpl(T, S)(S value)
if (!is(S : T) &&
    is(T == class) && is(typeof(new T(value))))
{
    return new T(value);
}

@safe pure unittest
{
    static struct S
    {
        int x;
    }
    static class C
    {
        int x;
        this(int x) @safe pure { this.x = x; }
    }

    static class B
    {
        int value;
        this(S src) @safe pure { value = src.x; }
        this(C src) @safe pure { value = src.x; }
    }

    S s = S(1);
    auto b1 = to!B(s);  // == new B(s)
    assert(b1.value == 1);

    C c = new C(2);
    auto b2 = to!B(c);  // == new B(c)
    assert(b2.value == 2);

    auto c2 = to!C(3);   // == new C(3)
    assert(c2.x == 3);
}

@safe pure unittest
{
    struct S
    {
        class A
        {
            this(B b) @safe pure {}
        }
        class B : A
        {
            this() @safe pure { super(this); }
        }
    }

    S.B b = new S.B();
    S.A a = to!(S.A)(b);      // == cast(S.A) b
                              // (do not run construction conversion like new S.A(b))
    assert(b is a);

    static class C : Object
    {
        this() @safe pure {}
        this(Object o) @safe pure {}
    }

    Object oc = new C();
    C a2 = to!C(oc);    // == new C(a)
                        // Construction conversion overrides down-casting conversion
    assert(a2 !is a);   //
}

/**
Object-to-object conversions by dynamic casting throw exception when the source is
non-null and the target is null.
 */
private T toImpl(T, S)(S value)
if (!is(S : T) &&
    (is(S == class) || is(S == interface)) && !is(typeof(value.opCast!T()) : T) &&
    (is(T == class) || is(T == interface)) && !is(typeof(new T(value))))
{
    static if (is(T == immutable))
    {
            // immutable <- immutable
            enum isModConvertible = is(S == immutable);
    }
    else static if (is(T == const))
    {
        static if (is(T == shared))
        {
            // shared const <- shared
            // shared const <- shared const
            // shared const <- immutable
            enum isModConvertible = is(S == shared) || is(S == immutable);
        }
        else
        {
            // const <- mutable
            // const <- immutable
            enum isModConvertible = !is(S == shared);
        }
    }
    else
    {
        static if (is(T == shared))
        {
            // shared <- shared mutable
            enum isModConvertible = is(S == shared) && !is(S == const);
        }
        else
        {
            // (mutable) <- (mutable)
            enum isModConvertible = is(Unqual!S == S);
        }
    }
    static assert(isModConvertible, "Bad modifier conversion: "~S.stringof~" to "~T.stringof);

    auto result = ()@trusted{ return cast(T) value; }();
    if (!result && value)
    {
        string name(TypeInfo ti) @trusted
        {
            while (auto tc = (cast(TypeInfo_Const) ti))
            {
                ti = tc.base;
            }
            if (auto tinf = cast(TypeInfo_Interface) ti)
            {
                ti = tinf.info;
            }
            TypeInfo_Class tc = cast(TypeInfo_Class) ti;
            assert(tc);
            return tc.name;
        }
        throw new ConvException("Cannot convert object of static type " ~
                name(typeid(S)) ~ " and dynamic type " ~ name(typeid(value)) ~ " to type " ~ name(typeid(T)));
    }
    return result;
}

// Unittest for 6288
@safe pure unittest
{
    import std.exception;

    alias Identity(T)      =              T;
    alias toConst(T)       =        const T;
    alias toShared(T)      =       shared T;
    alias toSharedConst(T) = shared const T;
    alias toImmutable(T)   =    immutable T;
    template AddModifier(int n)
    if (0 <= n && n < 5)
    {
             static if (n == 0) alias AddModifier = Identity;
        else static if (n == 1) alias AddModifier = toConst;
        else static if (n == 2) alias AddModifier = toShared;
        else static if (n == 3) alias AddModifier = toSharedConst;
        else static if (n == 4) alias AddModifier = toImmutable;
    }

    interface I {}
    interface J {}

    class A {}
    class B : A {}
    class C : B, I, J {}
    class D : I {}

    static foreach (m1; 0 .. 5) // enumerate modifiers
    static foreach (m2; 0 .. 5) // ditto
    {{
        alias srcmod = AddModifier!m1;
        alias tgtmod = AddModifier!m2;

        // Compile time convertible equals to modifier convertible.
        static if (is(srcmod!Object : tgtmod!Object))
        {
            // Test runtime conversions: class to class, class to interface,
            // interface to class, and interface to interface

            // Check that the runtime conversion to succeed
            srcmod!A ac = new srcmod!C();
            srcmod!I ic = new srcmod!C();
            assert(to!(tgtmod!C)(ac) !is null); // A(c) to C
            assert(to!(tgtmod!I)(ac) !is null); // A(c) to I
            assert(to!(tgtmod!C)(ic) !is null); // I(c) to C
            assert(to!(tgtmod!J)(ic) !is null); // I(c) to J

            // Check that the runtime conversion fails
            srcmod!A ab = new srcmod!B();
            srcmod!I id = new srcmod!D();
            assertThrown(to!(tgtmod!C)(ab));    // A(b) to C
            assertThrown(to!(tgtmod!I)(ab));    // A(b) to I
            assertThrown(to!(tgtmod!C)(id));    // I(d) to C
            assertThrown(to!(tgtmod!J)(id));    // I(d) to J
        }
        else
        {
            // Check that the conversion is rejected statically
            static assert(!is(typeof(to!(tgtmod!C)(srcmod!A.init))));   // A to C
            static assert(!is(typeof(to!(tgtmod!I)(srcmod!A.init))));   // A to I
            static assert(!is(typeof(to!(tgtmod!C)(srcmod!I.init))));   // I to C
            static assert(!is(typeof(to!(tgtmod!J)(srcmod!I.init))));   // I to J
        }
    }}
}

/**
Handles type _to string conversions
*/
private T toImpl(T, S)(S value)
if (!(is(S : T) &&
    !isEnumStrToStr!(S, T) && !isNullToStr!(S, T)) &&
    !isInfinite!S && isExactSomeString!T)
{
    static if (isExactSomeString!S && value[0].sizeof == ElementEncodingType!T.sizeof)
    {
        // string-to-string with incompatible qualifier conversion
        static if (is(ElementEncodingType!T == immutable))
        {
            // conversion (mutable|const) -> immutable
            return value.idup;
        }
        else
        {
            // conversion (immutable|const) -> mutable
            return value.dup;
        }
    }
    else static if (isExactSomeString!S)
    {
        import std.array : appender;
        // other string-to-string
        //Use Appender directly instead of toStr, which also uses a formatedWrite
        auto w = appender!T();
        w.put(value);
        return w.data;
    }
    else static if (isIntegral!S && !is(S == enum))
    {
        // other integral-to-string conversions with default radix

        import core.internal.string : signedToTempString, unsignedToTempString;

        alias EEType = Unqual!(ElementEncodingType!T);
        EEType[long.sizeof * 3 + 1] buf = void;
        EEType[] t = isSigned!S
            ?   signedToTempString!(10, false, EEType)(value, buf)
            : unsignedToTempString!(10, false, EEType)(value, buf);
        return t.dup;
    }
    else static if (is(S == void[]) || is(S == const(void)[]) || is(S == immutable(void)[]))
    {
        import core.stdc.string : memcpy;
        import std.exception : enforce;
        // Converting void array to string
        alias Char = Unqual!(ElementEncodingType!T);
        auto raw = cast(const(ubyte)[]) value;
        enforce(raw.length % Char.sizeof == 0,
                new ConvException("Alignment mismatch in converting a "
                        ~ S.stringof ~ " to a "
                        ~ T.stringof));
        auto result = new Char[raw.length / Char.sizeof];
        ()@trusted{ memcpy(result.ptr, value.ptr, value.length); }();
        return cast(T) result;
    }
    else static if (isPointer!S && isSomeChar!(PointerTarget!S))
    {
        // This is unsafe because we cannot guarantee that the pointer is null terminated.
        return () @system {
            static if (is(S : const(char)*))
                import core.stdc.string : strlen;
            else
                size_t strlen(S s) nothrow
                {
                    S p = s;
                    while (*p++) {}
                    return p-s-1;
                }
            return toImpl!T(value ? value[0 .. strlen(value)].dup : null);
        }();
    }
    else static if (isSomeString!T && is(S == enum))
    {
        static if (isSwitchable!(OriginalType!S) && EnumMembers!S.length <= 50)
        {
            switch (value)
            {
                foreach (member; NoDuplicates!(EnumMembers!S))
                {
                    case member:
                        return to!T(enumRep!(immutable(T), S, member));
                }
                default:
            }
        }
        else
        {
            foreach (member; EnumMembers!S)
            {
                if (value == member)
                    return to!T(enumRep!(immutable(T), S, member));
            }
        }

        import std.array : appender;
        import std.format.spec : FormatSpec;
        import std.format.write : formatValue;

        //Default case, delegate to format
        //Note: we don't call toStr directly, to avoid duplicate work.
        auto app = appender!T();
        app.put("cast(" ~ S.stringof ~ ")");
        FormatSpec!char f;
        formatValue(app, cast(OriginalType!S) value, f);
        return app.data;
    }
    else
    {
        // other non-string values runs formatting
        return toStr!T(value);
    }
}

// https://issues.dlang.org/show_bug.cgi?id=14042
@system unittest
{
    immutable(char)* ptr = "hello".ptr;
    auto result = ptr.to!(char[]);
}
// https://issues.dlang.org/show_bug.cgi?id=8384
@system unittest
{
    void test1(T)(T lp, string cmp)
    {
        static foreach (e; AliasSeq!(char, wchar, dchar))
        {
            test2!(e[])(lp, cmp);
            test2!(const(e)[])(lp, cmp);
            test2!(immutable(e)[])(lp, cmp);
        }
    }

    void test2(D, S)(S lp, string cmp)
    {
        assert(to!string(to!D(lp)) == cmp);
    }

    static foreach (e; AliasSeq!("Hello, world!", "Hello, world!"w, "Hello, world!"d))
    {
        test1(e, "Hello, world!");
        test1(e.ptr, "Hello, world!");
    }
    static foreach (e; AliasSeq!("", ""w, ""d))
    {
        test1(e, "");
        test1(e.ptr, "");
    }
}

/*
    To string conversion for non copy-able structs
 */
private T toImpl(T, S)(ref S value)
if (!(is(S : T) &&
    !isEnumStrToStr!(S, T) && !isNullToStr!(S, T)) &&
    !isInfinite!S && isExactSomeString!T && !isCopyable!S && !isStaticArray!S)
{
    import std.array : appender;
    import std.format.spec : FormatSpec;
    import std.format.write : formatValue;

    auto w = appender!T();
    FormatSpec!(ElementEncodingType!T) f;
    formatValue(w, value, f);
    return w.data;
}

// https://issues.dlang.org/show_bug.cgi?id=16108
@safe unittest
{
    static struct A
    {
        int val;
        bool flag;

        string toString() { return text(val, ":", flag); }

        @disable this(this);
    }

    auto a = A();
    assert(to!string(a) == "0:false");

    static struct B
    {
        int val;
        bool flag;

        @disable this(this);
    }

    auto b = B();
    assert(to!string(b) == "B(0, false)");
}

// https://issues.dlang.org/show_bug.cgi?id=20070
@safe unittest
{
    void writeThem(T)(ref inout(T) them)
    {
        assert(them.to!string == "[1, 2, 3, 4]");
    }

    const(uint)[4] vals = [ 1, 2, 3, 4 ];
    writeThem(vals);
}

/*
    Check whether type `T` can be used in a switch statement.
    This is useful for compile-time generation of switch case statements.
*/
private template isSwitchable(E)
{
    enum bool isSwitchable = is(typeof({
        switch (E.init) { default: }
    }));
}

//
@safe unittest
{
    static assert(isSwitchable!int);
    static assert(!isSwitchable!double);
    static assert(!isSwitchable!real);
}

//Static representation of the index I of the enum S,
//In representation T.
//T must be an immutable string (avoids un-necessary initializations).
private template enumRep(T, S, S value)
if (is (T == immutable) && isExactSomeString!T && is(S == enum))
{
    static T enumRep = toStr!T(value);
}

@safe pure unittest
{
    import std.exception;
    void dg()
    {
        // string to string conversion
        alias Chars = AliasSeq!(char, wchar, dchar);
        foreach (LhsC; Chars)
        {
            alias LhStrings = AliasSeq!(LhsC[], const(LhsC)[], immutable(LhsC)[]);
            foreach (Lhs; LhStrings)
            {
                foreach (RhsC; Chars)
                {
                    alias RhStrings = AliasSeq!(RhsC[], const(RhsC)[], immutable(RhsC)[]);
                    foreach (Rhs; RhStrings)
                    {
                        Lhs s1 = to!Lhs("wyda");
                        Rhs s2 = to!Rhs(s1);
                        //writeln(Lhs.stringof, " -> ", Rhs.stringof);
                        assert(s1 == to!Lhs(s2));
                    }
                }
            }
        }

        foreach (T; Chars)
        {
            foreach (U; Chars)
            {
                T[] s1 = to!(T[])("Hello, world!");
                auto s2 = to!(U[])(s1);
                assert(s1 == to!(T[])(s2));
                auto s3 = to!(const(U)[])(s1);
                assert(s1 == to!(T[])(s3));
                auto s4 = to!(immutable(U)[])(s1);
                assert(s1 == to!(T[])(s4));
            }
        }
    }
    dg();
    assertCTFEable!dg;
}

@safe pure unittest
{
    // Conversion representing bool value with string
    bool b;
    assert(to!string(b) == "false");
    b = true;
    assert(to!string(b) == "true");
}

@safe pure unittest
{
    // Conversion representing character value with string
    alias AllChars =
        AliasSeq!( char, const( char), immutable( char),
                  wchar, const(wchar), immutable(wchar),
                  dchar, const(dchar), immutable(dchar));
    foreach (Char1; AllChars)
    {
        foreach (Char2; AllChars)
        {
            Char1 c = 'a';
            assert(to!(Char2[])(c)[0] == c);
        }
        uint x = 4;
        assert(to!(Char1[])(x) == "4");
    }

    string s = "foo";
    string s2;
    foreach (char c; s)
    {
        s2 ~= to!string(c);
    }
    assert(s2 == "foo");
}

@safe pure nothrow unittest
{
    import std.exception;
    // Conversion representing integer values with string

    static foreach (Int; AliasSeq!(ubyte, ushort, uint, ulong))
    {
        assert(to!string(Int(0)) == "0");
        assert(to!string(Int(9)) == "9");
        assert(to!string(Int(123)) == "123");
    }

    static foreach (Int; AliasSeq!(byte, short, int, long))
    {
        assert(to!string(Int(0)) == "0");
        assert(to!string(Int(9)) == "9");
        assert(to!string(Int(123)) == "123");
        assert(to!string(Int(-0)) == "0");
        assert(to!string(Int(-9)) == "-9");
        assert(to!string(Int(-123)) == "-123");
        assert(to!string(const(Int)(6)) == "6");
    }

    assert(wtext(int.max) == "2147483647"w);
    assert(wtext(int.min) == "-2147483648"w);
    assert(to!string(0L) == "0");

    assertCTFEable!(
    {
        assert(to!string(1uL << 62) == "4611686018427387904");
        assert(to!string(0x100000000) == "4294967296");
        assert(to!string(-138L) == "-138");
    });
}

@safe unittest // sprintf issue
{
    double[2] a = [ 1.5, 2.5 ];
    assert(to!string(a) == "[1.5, 2.5]");
}

@safe unittest
{
    // Conversion representing class object with string
    class A
    {
        override string toString() @safe const { return "an A"; }
    }
    A a;
    assert(to!string(a) == "null");
    a = new A;
    assert(to!string(a) == "an A");

    // https://issues.dlang.org/show_bug.cgi?id=7660
    class C { override string toString() @safe const { return "C"; } }
    struct S { C c; alias c this; }
    S s; s.c = new C();
    assert(to!string(s) == "C");
}

@safe unittest
{
    // Conversion representing struct object with string
    struct S1
    {
        string toString() { return "wyda"; }
    }
    assert(to!string(S1()) == "wyda");

    struct S2
    {
        int a = 42;
        float b = 43.5;
    }
    S2 s2;
    assert(to!string(s2) == "S2(42, 43.5)");

    // Test for https://issues.dlang.org/show_bug.cgi?id=8080
    struct S8080
    {
        short[4] data;
        alias data this;
        string toString() { return "<S>"; }
    }
    S8080 s8080;
    assert(to!string(s8080) == "<S>");
}

@safe unittest
{
    // Conversion representing enum value with string
    enum EB : bool { a = true }
    enum EU : uint { a = 0, b = 1, c = 2 }  // base type is unsigned
    // base type is signed (https://issues.dlang.org/show_bug.cgi?id=7909)
    enum EI : int { a = -1, b = 0, c = 1 }
    enum EF : real { a = 1.414, b = 1.732, c = 2.236 }
    enum EC : char { a = 'x', b = 'y' }
    enum ES : string { a = "aaa", b = "bbb" }

    static foreach (E; AliasSeq!(EB, EU, EI, EF, EC, ES))
    {
        assert(to! string(E.a) == "a"c);
        assert(to!wstring(E.a) == "a"w);
        assert(to!dstring(E.a) == "a"d);
    }

    // Test an value not corresponding to an enum member.
    auto o = cast(EU) 5;
    assert(to! string(o) == "cast(EU)5"c);
    assert(to!wstring(o) == "cast(EU)5"w);
    assert(to!dstring(o) == "cast(EU)5"d);
}

@safe unittest
{
    enum E
    {
        foo,
        doo = foo, // check duplicate switch statements
        bar,
    }

    //Test regression 12494
    assert(to!string(E.foo) == "foo");
    assert(to!string(E.doo) == "foo");
    assert(to!string(E.bar) == "bar");

    static foreach (S; AliasSeq!(string, wstring, dstring, const(char[]), const(wchar[]), const(dchar[])))
    {{
        auto s1 = to!S(E.foo);
        auto s2 = to!S(E.foo);
        assert(s1 == s2);
        // ensure we don't allocate when it's unnecessary
        assert(s1 is s2);
    }}

    static foreach (S; AliasSeq!(char[], wchar[], dchar[]))
    {{
        auto s1 = to!S(E.foo);
        auto s2 = to!S(E.foo);
        assert(s1 == s2);
        // ensure each mutable array is unique
        assert(s1 !is s2);
    }}
}

// ditto
@trusted pure private T toImpl(T, S)(S value, uint radix, LetterCase letterCase = LetterCase.upper)
if (isIntegral!S &&
    isExactSomeString!T)
in
{
    assert(radix >= 2 && radix <= 36, "radix must be in range [2,36]");
}
do
{
    alias EEType = Unqual!(ElementEncodingType!T);

    T toStringRadixConvert(size_t bufLen)(uint runtimeRadix = 0)
    {
        Unsigned!(Unqual!S) div = void, mValue = unsigned(value);

        size_t index = bufLen;
        EEType[bufLen] buffer = void;
        char baseChar = letterCase == LetterCase.lower ? 'a' : 'A';
        char mod = void;

        do
        {
            div = cast(S)(mValue / runtimeRadix );
            mod = cast(ubyte)(mValue % runtimeRadix);
            mod += mod < 10 ? '0' : baseChar - 10;
            buffer[--index] = cast(char) mod;
            mValue = div;
        } while (mValue);

        return cast(T) buffer[index .. $].dup;
    }

    import std.array : array;
    switch (radix)
    {
        case 10:
            // The (value+0) is so integral promotions happen to the type
            return toChars!(10, EEType)(value + 0).array;
        case 16:
            // The unsigned(unsigned(value)+0) is so unsigned integral promotions happen to the type
            if (letterCase == letterCase.upper)
                return toChars!(16, EEType, LetterCase.upper)(unsigned(unsigned(value) + 0)).array;
            else
                return toChars!(16, EEType, LetterCase.lower)(unsigned(unsigned(value) + 0)).array;
        case 2:
            return toChars!(2, EEType)(unsigned(unsigned(value) + 0)).array;
        case 8:
            return toChars!(8, EEType)(unsigned(unsigned(value) + 0)).array;

        default:
            return toStringRadixConvert!(S.sizeof * 6)(radix);
    }
}

@safe pure nothrow unittest
{
    static foreach (Int; AliasSeq!(uint, ulong))
    {
        assert(to!string(Int(16), 16) == "10");
        assert(to!string(Int(15), 2u) == "1111");
        assert(to!string(Int(1), 2u) == "1");
        assert(to!string(Int(0x1234AF), 16u) == "1234AF");
        assert(to!string(Int(0x1234BCD), 16u, LetterCase.upper) == "1234BCD");
        assert(to!string(Int(0x1234AF), 16u, LetterCase.lower) == "1234af");
    }

    static foreach (Int; AliasSeq!(int, long))
    {
        assert(to!string(Int(-10), 10u) == "-10");
    }

    assert(to!string(byte(-10), 16) == "F6");
    assert(to!string(long.min) == "-9223372036854775808");
    assert(to!string(long.max) == "9223372036854775807");
}

/**
Narrowing numeric-numeric conversions throw when the value does not
fit in the narrower type.
 */
private T toImpl(T, S)(S value)
if (!is(S : T) &&
    (isNumeric!S || isSomeChar!S || isBoolean!S) &&
    (isNumeric!T || isSomeChar!T || isBoolean!T) && !is(T == enum))
{
    static if (isFloatingPoint!S && isIntegral!T)
    {
        import std.math.traits : isNaN;
        if (value.isNaN) throw new ConvException("Input was NaN");
    }

    enum sSmallest = mostNegative!S;
    enum tSmallest = mostNegative!T;
    static if (sSmallest < 0)
    {
        // possible underflow converting from a signed
        static if (tSmallest == 0)
        {
            immutable good = value >= 0;
        }
        else
        {
            static assert(tSmallest < 0,
                "minimum value of T must be smaller than 0");
            immutable good = value >= tSmallest;
        }
        if (!good)
            throw new ConvOverflowException("Conversion negative overflow");
    }
    static if (S.max > T.max)
    {
        // possible overflow
        if (value > T.max)
            throw new ConvOverflowException("Conversion positive overflow");
    }
    return (ref value)@trusted{ return cast(T) value; }(value);
}

@safe pure unittest
{
    import std.exception;

    dchar a = ' ';
    assert(to!char(a) == ' ');
    a = 300;
    assert(collectException(to!char(a)));

    dchar from0 = 'A';
    char to0 = to!char(from0);

    wchar from1 = 'A';
    char to1 = to!char(from1);

    char from2 = 'A';
    char to2 = to!char(from2);

    char from3 = 'A';
    wchar to3 = to!wchar(from3);

    char from4 = 'A';
    dchar to4 = to!dchar(from4);
}

@safe unittest
{
    import std.exception;

    // Narrowing conversions from enum -> integral should be allowed, but they
    // should throw at runtime if the enum value doesn't fit in the target
    // type.
    enum E1 : ulong { A = 1, B = 1UL << 48, C = 0 }
    assert(to!int(E1.A) == 1);
    assert(to!bool(E1.A) == true);
    assertThrown!ConvOverflowException(to!int(E1.B)); // E1.B overflows int
    assertThrown!ConvOverflowException(to!bool(E1.B)); // E1.B overflows bool
    assert(to!bool(E1.C) == false);

    enum E2 : long { A = -1L << 48, B = -1 << 31, C = 1 << 31 }
    assertThrown!ConvOverflowException(to!int(E2.A)); // E2.A overflows int
    assertThrown!ConvOverflowException(to!uint(E2.B)); // E2.B overflows uint
    assert(to!int(E2.B) == -1 << 31); // but does not overflow int
    assert(to!int(E2.C) == 1 << 31);  // E2.C does not overflow int

    enum E3 : int { A = -1, B = 1, C = 255, D = 0 }
    assertThrown!ConvOverflowException(to!ubyte(E3.A));
    assertThrown!ConvOverflowException(to!bool(E3.A));
    assert(to!byte(E3.A) == -1);
    assert(to!byte(E3.B) == 1);
    assert(to!ubyte(E3.C) == 255);
    assert(to!bool(E3.B) == true);
    assertThrown!ConvOverflowException(to!byte(E3.C));
    assertThrown!ConvOverflowException(to!bool(E3.C));
    assert(to!bool(E3.D) == false);

}

@safe unittest
{
    import std.exception;
    import std.math.traits : isNaN;

    double d = double.nan;
    float f = to!float(d);
    assert(f.isNaN);
    assert(to!double(f).isNaN);
    assertThrown!ConvException(to!int(d));
    assertThrown!ConvException(to!int(f));
    auto ex = collectException(d.to!int);
    assert(ex.msg == "Input was NaN");
}

/**
Array-to-array conversion (except when target is a string type)
converts each element in turn by using `to`.
 */
private T toImpl(T, S)(scope S value)
if (!is(S : T) &&
    !isSomeString!S && isDynamicArray!S &&
    !isExactSomeString!T && isArray!T)
{
    alias E = typeof(T.init[0]);

    static if (isStaticArray!T)
    {
        import std.exception : enforce;
        auto res = to!(E[])(value);
        enforce!ConvException(T.length == res.length,
            convFormat("Length mismatch when converting to static array: %s vs %s", T.length, res.length));
        return res[0 .. T.length];
    }
    else
    {
        import std.array : appender;
        auto w = appender!(E[])();
        w.reserve(value.length);
        foreach (ref e; value)
        {
            w.put(to!E(e));
        }
        return w.data;
    }
}

@safe pure unittest
{
    import std.exception;

    // array to array conversions
    uint[] a = [ 1u, 2, 3 ];
    auto b = to!(float[])(a);
    assert(b == [ 1.0f, 2, 3 ]);

    immutable(int)[3] d = [ 1, 2, 3 ];
    b = to!(float[])(d);
    assert(b == [ 1.0f, 2, 3 ]);

    uint[][] e = [ a, a ];
    auto f = to!(float[][])(e);
    assert(f[0] == b && f[1] == b);

    // Test for https://issues.dlang.org/show_bug.cgi?id=8264
    struct Wrap
    {
        string wrap;
        alias wrap this;
    }
    Wrap[] warr = to!(Wrap[])(["foo", "bar"]);  // should work

    // https://issues.dlang.org/show_bug.cgi?id=12633
    import std.conv : to;
    const s2 = ["10", "20"];

    immutable int[2] a3 = s2.to!(int[2]);
    assert(a3 == [10, 20]);

    // verify length mismatches are caught
    immutable s4 = [1, 2, 3, 4];
    foreach (i; [1, 4])
    {
        auto ex = collectException(s4[0 .. i].to!(int[2]));
            assert(ex && ex.msg == "Length mismatch when converting to static array: 2 vs " ~ [cast(char)(i + '0')],
                ex ? ex.msg : "Exception was not thrown!");
    }
}

@safe unittest
{
    auto b = [ 1.0f, 2, 3 ];

    auto c = to!(string[])(b);
    assert(c[0] == "1" && c[1] == "2" && c[2] == "3");
}

/**
Associative array to associative array conversion converts each key
and each value in turn.
 */
private T toImpl(T, S)(S value)
if (!is(S : T) && isAssociativeArray!S &&
    isAssociativeArray!T && !is(T == enum))
{
    /* This code is potentially unsafe.
     */
    alias K2 = KeyType!T;
    alias V2 = ValueType!T;

    // While we are "building" the AA, we need to unqualify its values, and only re-qualify at the end
    Unqual!V2[K2] result;

    foreach (k1, v1; value)
    {
        // Cast values temporarily to Unqual!V2 to store them to result variable
        result[to!K2(k1)] = to!(Unqual!V2)(v1);
    }
    // Cast back to original type
    return () @trusted { return cast(T) result; }();
}

@safe unittest
{
    // hash to hash conversions
    int[string] a;
    a["0"] = 1;
    a["1"] = 2;
    auto b = to!(double[dstring])(a);
    assert(b["0"d] == 1 && b["1"d] == 2);
}

// https://issues.dlang.org/show_bug.cgi?id=8705, from doc
@safe unittest
{
    import std.exception;
    int[string][double[int[]]] a;
    auto b = to!(short[wstring][string[double[]]])(a);
    a = [null:["hello":int.max]];
    assertThrown!ConvOverflowException(to!(short[wstring][string[double[]]])(a));
}
@system unittest // Extra cases for AA with qualifiers conversion
{
    int[][int[]] a;// = [[], []];
    auto b = to!(immutable(short[])[immutable short[]])(a);

    double[dstring][int[long[]]] c;
    auto d = to!(immutable(short[immutable wstring])[immutable string[double[]]])(c);
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.array : byPair;

    int[int] a;
    assert(a.to!(int[int]) == a);
    assert(a.to!(const(int)[int]).byPair.equal(a.byPair));
}

@safe pure unittest
{
    static void testIntegralToFloating(Integral, Floating)()
    {
        Integral a = 42;
        auto b = to!Floating(a);
        assert(a == b);
        assert(a == to!Integral(b));
    }
    static void testFloatingToIntegral(Floating, Integral)()
    {
        import std.math.traits : floatTraits, RealFormat;

        bool convFails(Source, Target, E)(Source src)
        {
            try
                cast(void) to!Target(src);
            catch (E)
                return true;
            return false;
        }

        // convert some value
        Floating a = 4.2e1;
        auto b = to!Integral(a);
        assert(is(typeof(b) == Integral) && b == 42);
        // convert some negative value (if applicable)
        a = -4.2e1;
        static if (Integral.min < 0)
        {
            b = to!Integral(a);
            assert(is(typeof(b) == Integral) && b == -42);
        }
        else
        {
            // no go for unsigned types
            assert(convFails!(Floating, Integral, ConvOverflowException)(a));
        }
        // convert to the smallest integral value
        a = 0.0L + Integral.min;
        static if (Integral.min < 0)
        {
            a = -a; // -Integral.min not representable as an Integral
            assert(convFails!(Floating, Integral, ConvOverflowException)(a)
                    || Floating.sizeof <= Integral.sizeof
                    || floatTraits!Floating.realFormat == RealFormat.ieeeExtended53);
        }
        a = 0.0L + Integral.min;
        assert(to!Integral(a) == Integral.min);
        --a; // no more representable as an Integral
        assert(convFails!(Floating, Integral, ConvOverflowException)(a)
                || Floating.sizeof <= Integral.sizeof
                || floatTraits!Floating.realFormat == RealFormat.ieeeExtended53);
        a = 0.0L + Integral.max;
        assert(to!Integral(a) == Integral.max
                || Floating.sizeof <= Integral.sizeof
                || floatTraits!Floating.realFormat == RealFormat.ieeeExtended53);
        ++a; // no more representable as an Integral
        assert(convFails!(Floating, Integral, ConvOverflowException)(a)
                || Floating.sizeof <= Integral.sizeof
                || floatTraits!Floating.realFormat == RealFormat.ieeeExtended53);
        // convert a value with a fractional part
        a = 3.14;
        assert(to!Integral(a) == 3);
        a = 3.99;
        assert(to!Integral(a) == 3);
        static if (Integral.min < 0)
        {
            a = -3.14;
            assert(to!Integral(a) == -3);
            a = -3.99;
            assert(to!Integral(a) == -3);
        }
    }

    alias AllInts = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong);
    alias AllFloats = AliasSeq!(float, double, real);
    alias AllNumerics = AliasSeq!(AllInts, AllFloats);
    // test with same type
    {
        foreach (T; AllNumerics)
        {
            T a = 42;
            auto b = to!T(a);
            assert(is(typeof(a) == typeof(b)) && a == b);
        }
    }
    // test that floating-point numbers convert properly to largest ints
    // see http://oregonstate.edu/~peterseb/mth351/docs/351s2001_fp80x87.html
    // look for "largest fp integer with a predecessor"
    {
        // float
        int a = 16_777_215; // 2^24 - 1
        assert(to!int(to!float(a)) == a);
        assert(to!int(to!float(-a)) == -a);
        // double
        long b = 9_007_199_254_740_991; // 2^53 - 1
        assert(to!long(to!double(b)) == b);
        assert(to!long(to!double(-b)) == -b);
        // real
        static if (real.mant_dig >= 64)
        {
            ulong c = 18_446_744_073_709_551_615UL; // 2^64 - 1
            assert(to!ulong(to!real(c)) == c);
        }
    }
    // test conversions floating => integral
    {
        foreach (Integral; AllInts)
        {
            foreach (Floating; AllFloats)
            {
                testFloatingToIntegral!(Floating, Integral)();
            }
        }
    }
    // test conversion integral => floating
    {
        foreach (Integral; AllInts)
        {
            foreach (Floating; AllFloats)
            {
                testIntegralToFloating!(Integral, Floating)();
            }
        }
    }
    // test parsing
    {
        foreach (T; AllNumerics)
        {
            // from type immutable(char)[2]
            auto a = to!T("42");
            assert(a == 42);
            // from type char[]
            char[] s1 = "42".dup;
            a = to!T(s1);
            assert(a == 42);
            // from type char[2]
            char[2] s2;
            s2[] = "42";
            a = to!T(s2);
            assert(a == 42);
            // from type immutable(wchar)[2]
            a = to!T("42"w);
            assert(a == 42);
        }
    }
}

@safe unittest
{
    alias AllInts = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong);
    alias AllFloats = AliasSeq!(float, double, real);
    alias AllNumerics = AliasSeq!(AllInts, AllFloats);
    // test conversions to string
    {
        foreach (T; AllNumerics)
        {
            T a = 42;
            string s = to!string(a);
            assert(s == "42", s);
            wstring ws = to!wstring(a);
            assert(ws == "42"w, to!string(ws));
            dstring ds = to!dstring(a);
            assert(ds == "42"d, to!string(ds));
            // array test
            T[] b = new T[2];
            b[0] = 42;
            b[1] = 33;
            assert(to!string(b) == "[42, 33]");
        }
    }
    // test array to string conversion
    foreach (T ; AllNumerics)
    {
        auto a = [to!T(1), 2, 3];
        assert(to!string(a) == "[1, 2, 3]");
    }
    // test enum to int conversion
    enum Testing { Test1, Test2 }
    Testing t;
    auto a = to!string(t);
    assert(a == "Test1");
}


/**
String, or string-like input range, to non-string conversion runs parsing.
$(UL
  $(LI When the source is a wide string, it is first converted to a narrow
       string and then parsed.)
  $(LI When the source is a narrow string, normal text parsing occurs.))
*/
private T toImpl(T, S)(S value)
if (isInputRange!S && isSomeChar!(ElementEncodingType!S) &&
    !isExactSomeString!T && is(typeof(parse!T(value))) &&
    // https://issues.dlang.org/show_bug.cgi?id=20539
    !(is(T == enum) && is(typeof(value == OriginalType!T.init)) && !isSomeString!(OriginalType!T)))
{
    scope(success)
    {
        if (!value.empty)
        {
            throw convError!(S, T)(value);
        }
    }
    return parse!T(value);
}

/// ditto
private T toImpl(T, S)(S value, uint radix)
if (isSomeFiniteCharInputRange!S &&
    isIntegral!T && is(typeof(parse!T(value, radix))))
{
    scope(success)
    {
        if (!value.empty)
        {
            throw convError!(S, T)(value);
        }
    }
    return parse!T(value, radix);
}

@safe pure unittest
{
    // https://issues.dlang.org/show_bug.cgi?id=6668
    // ensure no collaterals thrown
    try { to!uint("-1"); }
    catch (ConvException e) { assert(e.next is null); }
}

@safe pure unittest
{
    static foreach (Str; AliasSeq!(string, wstring, dstring))
    {{
        Str a = "123";
        assert(to!int(a) == 123);
        assert(to!double(a) == 123);
    }}

    // https://issues.dlang.org/show_bug.cgi?id=6255
    auto n = to!int("FF", 16);
    assert(n == 255);
}

// https://issues.dlang.org/show_bug.cgi?id=15800
@safe unittest
{
    import std.utf : byCodeUnit, byChar, byWchar, byDchar;

    assert(to!int(byCodeUnit("10")) == 10);
    assert(to!int(byCodeUnit("10"), 10) == 10);
    assert(to!int(byCodeUnit("10"w)) == 10);
    assert(to!int(byCodeUnit("10"w), 10) == 10);

    assert(to!int(byChar("10")) == 10);
    assert(to!int(byChar("10"), 10) == 10);
    assert(to!int(byWchar("10")) == 10);
    assert(to!int(byWchar("10"), 10) == 10);
    assert(to!int(byDchar("10")) == 10);
    assert(to!int(byDchar("10"), 10) == 10);
}

/**
String, or string-like input range, to char type not directly
supported by parse parses the first dchar of the source.

Returns: the first code point of the input range, converted
         to type T.

Throws: ConvException if the input range contains more than
        a single code point, or if the code point does not
        fit into a code unit of type T.
*/
private T toImpl(T, S)(S value)
if (isSomeChar!T && !is(typeof(parse!T(value))) &&
    is(typeof(parse!dchar(value))))
{
    import std.utf : encode;

    immutable dchar codepoint = parse!dchar(value);
    if (!value.empty)
        throw new ConvException(convFormat("Cannot convert \"%s\" to %s because it " ~
                                           "contains more than a single code point.",
                                           value, T.stringof));
    T[dchar.sizeof / T.sizeof] decodedCodepoint;
    if (encode(decodedCodepoint, codepoint) != 1)
        throw new ConvException(convFormat("First code point '%s' of \"%s\" does not fit into a " ~
                                           "single %s code unit", codepoint, value, T.stringof));
    return decodedCodepoint[0];
}

@safe pure unittest
{
    import std.exception : assertThrown;

    assert(toImpl!wchar("a") == 'a');

    assert(toImpl!char("a"d) == 'a');
    assert(toImpl!char("a"w) == 'a');
    assert(toImpl!wchar("a"d) == 'a');

    assertThrown!ConvException(toImpl!wchar("ab"));
    assertThrown!ConvException(toImpl!char("😃"d));
}

/**
Convert a value that is implicitly convertible to the enum base type
into an Enum value. If the value does not match any enum member values
a ConvException is thrown.
Enums with floating-point or string base types are not supported.
*/
private T toImpl(T, S)(S value)
if (is(T == enum) && !is(S == enum)
    && is(typeof(value == OriginalType!T.init))
    && !isFloatingPoint!(OriginalType!T) && !isSomeString!(OriginalType!T))
{
    foreach (Member; EnumMembers!T)
    {
        if (Member == value)
            return Member;
    }
    throw new ConvException(convFormat("Value (%s) does not match any member value of enum '%s'", value, T.stringof));
}

@safe pure unittest
{
    import std.exception;
    enum En8143 : int { A = 10, B = 20, C = 30, D = 20 }
    enum En8143[][] m3 = to!(En8143[][])([[10, 30], [30, 10]]);
    static assert(m3 == [[En8143.A, En8143.C], [En8143.C, En8143.A]]);

    En8143 en1 = to!En8143(10);
    assert(en1 == En8143.A);
    assertThrown!ConvException(to!En8143(5));   // matches none
    En8143[][] m1 = to!(En8143[][])([[10, 30], [30, 10]]);
    assert(m1 == [[En8143.A, En8143.C], [En8143.C, En8143.A]]);
}

// https://issues.dlang.org/show_bug.cgi?id=20539
@safe pure unittest
{
    import std.exception : assertNotThrown;

    // To test that the bug is fixed it is required that the struct is static,
    // otherwise, the frame pointer makes the test pass even if the bug is not
    // fixed.

    static struct A
    {
        auto opEquals(U)(U)
        {
            return true;
        }
    }

    enum ColorA
    {
        red = A()
    }

    assertNotThrown("xxx".to!ColorA);

    // This is a guard for the future.

    struct B
    {
        auto opEquals(U)(U)
        {
            return true;
        }
    }

    enum ColorB
    {
        red = B()
    }

    assertNotThrown("xxx".to!ColorB);
}

/***************************************************************
 Rounded conversion from floating point to integral.

Rounded conversions do not work with non-integral target types.
 */

template roundTo(Target)
{
    Target roundTo(Source)(Source value)
    {
        import core.math : abs = fabs;
        import std.math.exponential : log2;
        import std.math.rounding : trunc;

        static assert(isFloatingPoint!Source);
        static assert(isIntegral!Target);

        // If value >= 2 ^^ (real.mant_dig - 1), the number is an integer
        // and adding 0.5 won't work, but we allready know, that we do
        // not have to round anything.
        if (log2(abs(value)) >= real.mant_dig - 1)
            return to!Target(value);

        return to!Target(trunc(value + (value < 0 ? -0.5L : 0.5L)));
    }
}

///
@safe unittest
{
    assert(roundTo!int(3.14) == 3);
    assert(roundTo!int(3.49) == 3);
    assert(roundTo!int(3.5) == 4);
    assert(roundTo!int(3.999) == 4);
    assert(roundTo!int(-3.14) == -3);
    assert(roundTo!int(-3.49) == -3);
    assert(roundTo!int(-3.5) == -4);
    assert(roundTo!int(-3.999) == -4);
    assert(roundTo!(const int)(to!(const double)(-3.999)) == -4);
}

@safe unittest
{
    import std.exception;
    // boundary values
    static foreach (Int; AliasSeq!(byte, ubyte, short, ushort, int, uint))
    {
        assert(roundTo!Int(Int.min - 0.4L) == Int.min);
        assert(roundTo!Int(Int.max + 0.4L) == Int.max);
        assertThrown!ConvOverflowException(roundTo!Int(Int.min - 0.5L));
        assertThrown!ConvOverflowException(roundTo!Int(Int.max + 0.5L));
    }
}

@safe unittest
{
    import std.exception;
    assertThrown!ConvException(roundTo!int(float.init));
    auto ex = collectException(roundTo!int(float.init));
    assert(ex.msg == "Input was NaN");
}

// https://issues.dlang.org/show_bug.cgi?id=5232
@safe pure unittest
{
    static if (real.mant_dig >= 64)
        ulong maxOdd = ulong.max;
    else
        ulong maxOdd = (1UL << real.mant_dig) - 1;

    real r1 = maxOdd;
    assert(roundTo!ulong(r1) == maxOdd);

    real r2 = maxOdd - 1;
    assert(roundTo!ulong(r2) == maxOdd - 1);

    real r3 = maxOdd / 2;
    assert(roundTo!ulong(r3) == maxOdd / 2);

    real r4 = maxOdd / 2 + 1;
    assert(roundTo!ulong(r4) == maxOdd / 2 + 1);

    // this is only an issue on computers where real == double
    long l = -((1L << double.mant_dig) - 1);
    double r5 = l;
    assert(roundTo!long(r5) == l);
}

/**
$(PANEL
The `parse` family of functions works quite like the $(LREF to)
family, except that:
$(OL
    $(LI It only works with character ranges as input.)
    $(LI It takes the input by reference. This means that rvalues (such
    as string literals) are not accepted: use `to` instead.)
    $(LI It advances the input to the position following the conversion.)
    $(LI It does not throw if it could not convert the entire input.))
)

This overload parses a `bool` from a character input range.

Params:
    Target = the boolean type to convert to
    source = the lvalue of an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
    doCount = the flag for deciding to report the number of consumed characters

Returns:
$(UL
    $(LI A `bool` if `doCount` is set to `No.doCount`)
    $(LI A `tuple` containing a `bool` and a `size_t` if `doCount` is set to `Yes.doCount`))

Throws:
    A $(LREF ConvException) if the range does not represent a `bool`.

Note:
    All character input range conversions using $(LREF to) are forwarded
    to `parse` and do not require lvalues.
*/
auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source source)
if (is(immutable Target == immutable bool) &&
    isInputRange!Source &&
    isSomeChar!(ElementType!Source))
{
    import std.ascii : toLower;

    static if (isNarrowString!Source)
    {
        import std.string : representation;
        auto s = source.representation;
    }
    else
    {
        alias s = source;
    }

    if (!s.empty)
    {
        auto c1 = toLower(s.front);
        bool result = c1 == 't';
        if (result || c1 == 'f')
        {
            s.popFront();
            foreach (c; result ? "rue" : "alse")
            {
                if (s.empty || toLower(s.front) != c)
                    goto Lerr;
                s.popFront();
            }

            static if (isNarrowString!Source)
                source = cast(Source) s;

            static if (doCount)
            {
                if (result)
                    return tuple!("data", "count")(result, 4);
                return tuple!("data", "count")(result, 5);
            }
            else
            {
                return result;
            }
        }
    }
Lerr:
    throw parseError("bool should be case-insensitive 'true' or 'false'");
}

///
@safe unittest
{
    import std.typecons : Flag, Yes, No;
    auto s = "true";
    bool b = parse!bool(s);
    assert(b);
    auto s2 = "true";
    bool b2 = parse!(bool, string, No.doCount)(s2);
    assert(b2);
    auto s3 = "true";
    auto b3 = parse!(bool, string, Yes.doCount)(s3);
    assert(b3.data && b3.count == 4);
    auto s4 = "falSE";
    auto b4 = parse!(bool, string, Yes.doCount)(s4);
    assert(!b4.data && b4.count == 5);
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.exception;
    struct InputString
    {
        string _s;
        @property auto front() { return _s.front; }
        @property bool empty() { return _s.empty; }
        void popFront() { _s.popFront(); }
    }

    auto s = InputString("trueFALSETrueFalsetRUEfALSE");
    assert(parse!bool(s) == true);
    assert(s.equal("FALSETrueFalsetRUEfALSE"));
    assert(parse!bool(s) == false);
    assert(s.equal("TrueFalsetRUEfALSE"));
    assert(parse!bool(s) == true);
    assert(s.equal("FalsetRUEfALSE"));
    assert(parse!bool(s) == false);
    assert(s.equal("tRUEfALSE"));
    assert(parse!bool(s) == true);
    assert(s.equal("fALSE"));
    assert(parse!bool(s) == false);
    assert(s.empty);

    foreach (ss; ["tfalse", "ftrue", "t", "f", "tru", "fals", ""])
    {
        s = InputString(ss);
        assertThrown!ConvException(parse!bool(s));
    }
}

/**
Parses an integer from a character $(REF_ALTTEXT input range, isInputRange, std,range,primitives).

Params:
    Target = the integral type to convert to
    s = the lvalue of an input range
    doCount = the flag for deciding to report the number of consumed characters

Returns:
$(UL
    $(LI A number of type `Target` if `doCount` is set to `No.doCount`)
    $(LI A `tuple` containing a number of type `Target` and a `size_t` if `doCount` is set to `Yes.doCount`))

Throws:
    A $(LREF ConvException) If an overflow occurred during conversion or
    if no character of the input was meaningfully converted.
*/
auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref scope Source s)
if (isIntegral!Target && !is(Target == enum) &&
    isSomeChar!(ElementType!Source))
{
    static if (Target.sizeof < int.sizeof)
    {
        // smaller types are handled like integers
        auto v = .parse!(Select!(Target.min < 0, int, uint), Source, Yes.doCount)(s);
        auto result = (() @trusted => cast (Target) v.data)();
        if (result == v.data)
        {
            static if (doCount)
            {
                return tuple!("data", "count")(result, v.count);
            }
            else
            {
                return result;
            }
        }
        throw new ConvOverflowException("Overflow in integral conversion");
    }
    else
    {
        // int or larger types

        static if (Target.min < 0)
            bool sign = false;
        else
            enum bool sign = false;

        enum char maxLastDigit = Target.min < 0 ? 7 : 5;
        uint c;

        static if (isNarrowString!Source)
        {
            import std.string : representation;
            auto source = s.representation;
        }
        else
        {
            alias source = s;
        }

        static if (doCount)
            size_t count = 0;

        if (source.empty)
            goto Lerr;

        c = source.front;

        static if (Target.min < 0)
        {
            switch (c)
            {
                case '-':
                    sign = true;
                    goto case '+';
                case '+':
                    static if (doCount)
                        ++count;
                    source.popFront();

                    if (source.empty)
                        goto Lerr;

                    c = source.front;

                    break;

                default:
                    break;
            }
        }
        c -= '0';
        if (c <= 9)
        {
            Target v = cast(Target) c;

            static if (doCount)
                ++count;
            source.popFront();

            while (!source.empty)
            {
                c = cast(typeof(c)) (source.front - '0');

                if (c > 9)
                    break;

                if (v >= 0 && (v < Target.max/10 ||
                    (v == Target.max/10 && c <= maxLastDigit + sign)))
                {
                    // Note: `v` can become negative here in case of parsing
                    // the most negative value:
                    v = cast(Target) (v * 10 + c);
                    static if (doCount)
                        ++count;
                    source.popFront();
                }
                else
                    throw new ConvOverflowException("Overflow in integral conversion");
            }

            if (sign)
                v = -v;

            static if (isNarrowString!Source)
                s = s[$-source.length..$];

            static if (doCount)
            {
                return tuple!("data", "count")(v, count);
            }
            else
            {
                return v;
            }
        }
Lerr:
        static if (isNarrowString!Source)
            throw convError!(Source, Target)(cast(Source) source);
        else
            throw convError!(Source, Target)(source);
    }
}

///
@safe pure unittest
{
    import std.typecons : Flag, Yes, No;
    string s = "123";
    auto a = parse!int(s);
    assert(a == 123);

    string s1 = "123";
    auto a1 = parse!(int, string, Yes.doCount)(s1);
    assert(a1.data == 123 && a1.count == 3);
}

///
@safe pure unittest
{
    import std.string : tr;
    import std.typecons : Flag, Yes, No;
    string test = "123 \t  76.14";
    auto a = parse!uint(test);
    assert(a == 123);
    assert(test == " \t  76.14"); // parse bumps string
    test = tr(test, " \t\n\r", "", "d"); // skip ws
    assert(test == "76.14");
    auto b = parse!double(test);
    assert(b == 76.14);
    assert(test == "");

    string test2 = "123 \t  76.14";
    auto a2 = parse!(uint, string, Yes.doCount)(test2);
    assert(a2.data == 123 && a2.count == 3);
    assert(test2 == " \t  76.14");// parse bumps string
    test2 = tr(test2, " \t\n\r", "", "d"); // skip ws
    assert(test2 == "76.14");
    auto b2 = parse!(double, string, Yes.doCount)(test2);
    assert(b2.data == 76.14 && b2.count == 5);
    assert(test2 == "");

}

@safe pure unittest
{
    static foreach (Int; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))
    {
        {
            assert(to!Int("0") == 0);

            static if (isSigned!Int)
            {
                assert(to!Int("+0") == 0);
                assert(to!Int("-0") == 0);
            }
        }

        static if (Int.sizeof >= byte.sizeof)
        {
                assert(to!Int("6") == 6);
                assert(to!Int("23") == 23);
                assert(to!Int("68") == 68);
                assert(to!Int("127") == 0x7F);

            static if (isUnsigned!Int)
            {
                assert(to!Int("255") == 0xFF);
            }
            static if (isSigned!Int)
            {
                assert(to!Int("+6") == 6);
                assert(to!Int("+23") == 23);
                assert(to!Int("+68") == 68);
                assert(to!Int("+127") == 0x7F);

                assert(to!Int("-6") == -6);
                assert(to!Int("-23") == -23);
                assert(to!Int("-68") == -68);
                assert(to!Int("-128") == -128);
            }
        }

        static if (Int.sizeof >= short.sizeof)
        {
                assert(to!Int("468") == 468);
                assert(to!Int("32767") == 0x7FFF);

            static if (isUnsigned!Int)
            {
                assert(to!Int("65535") == 0xFFFF);
            }
            static if (isSigned!Int)
            {
                assert(to!Int("+468") == 468);
                assert(to!Int("+32767") == 0x7FFF);

                assert(to!Int("-468") == -468);
                assert(to!Int("-32768") == -32768);
            }
        }

        static if (Int.sizeof >= int.sizeof)
        {
                assert(to!Int("2147483647") == 0x7FFFFFFF);

            static if (isUnsigned!Int)
            {
                assert(to!Int("4294967295") == 0xFFFFFFFF);
            }

            static if (isSigned!Int)
            {
                assert(to!Int("+2147483647") == 0x7FFFFFFF);

                assert(to!Int("-2147483648") == -2147483648);
            }
        }

        static if (Int.sizeof >= long.sizeof)
        {
                assert(to!Int("9223372036854775807") == 0x7FFFFFFFFFFFFFFF);

            static if (isUnsigned!Int)
            {
                assert(to!Int("18446744073709551615") == 0xFFFFFFFFFFFFFFFF);
            }

            static if (isSigned!Int)
            {
                assert(to!Int("+9223372036854775807") == 0x7FFFFFFFFFFFFFFF);

                assert(to!Int("-9223372036854775808") == 0x8000000000000000);
            }
        }
    }
}

@safe pure unittest
{
    import std.exception;

    immutable string[] errors =
    [
        "",
        "-",
        "+",
        "-+",
        " ",
        " 0",
        "0 ",
        "- 0",
        "1-",
        "xx",
        "123h",
        "-+1",
        "--1",
        "+-1",
        "++1",
    ];

    immutable string[] unsignedErrors =
    [
        "+5",
        "-78",
    ];

    // parsing error check
    static foreach (Int; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))
    {
        foreach (j, s; errors)
            assertThrown!ConvException(to!Int(s));

        // parse!SomeUnsigned cannot parse head sign.
        static if (isUnsigned!Int)
        {
            foreach (j, s; unsignedErrors)
                assertThrown!ConvException(to!Int(s));
        }
    }

    immutable string[] positiveOverflowErrors =
    [
        "128",                  // > byte.max
        "256",                  // > ubyte.max
        "32768",                // > short.max
        "65536",                // > ushort.max
        "2147483648",           // > int.max
        "4294967296",           // > uint.max
        "9223372036854775808",  // > long.max
        "18446744073709551616", // > ulong.max
    ];
    // positive overflow check
    static foreach (i, Int; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))
    {
        foreach (j, s; positiveOverflowErrors[i..$])
            assertThrown!ConvOverflowException(to!Int(s));
    }

    immutable string[] negativeOverflowErrors =
    [
        "-129",                 // < byte.min
        "-32769",               // < short.min
        "-2147483649",          // < int.min
        "-9223372036854775809", // < long.min
    ];
    // negative overflow check
    static foreach (i, Int; AliasSeq!(byte, short, int, long))
    {
        foreach (j, s; negativeOverflowErrors[i..$])
            assertThrown!ConvOverflowException(to!Int(s));
    }
}

@safe pure unittest
{
    void checkErrMsg(string input, dchar charInMsg, dchar charNotInMsg)
    {
        try
        {
            int x = input.to!int();
            assert(false, "Invalid conversion did not throw");
        }
        catch (ConvException e)
        {
            // Ensure error message contains failing character, not the character
            // beyond.
            import std.algorithm.searching : canFind;
            assert( e.msg.canFind(charInMsg) &&
                   !e.msg.canFind(charNotInMsg));
        }
        catch (Exception e)
        {
            assert(false, "Did not throw ConvException");
        }
    }
    checkErrMsg("@$", '@', '$');
    checkErrMsg("@$123", '@', '$');
    checkErrMsg("1@$23", '@', '$');
    checkErrMsg("1@$", '@', '$');
    checkErrMsg("1@$2", '@', '$');
    checkErrMsg("12@$", '@', '$');
}

@safe pure unittest
{
    import std.exception;
    assertCTFEable!({ string s =  "1234abc"; assert(parse! int(s) ==  1234 && s == "abc"); });
    assertCTFEable!({ string s = "-1234abc"; assert(parse! int(s) == -1234 && s == "abc"); });
    assertCTFEable!({ string s =  "1234abc"; assert(parse!uint(s) ==  1234 && s == "abc"); });

    assertCTFEable!({ string s =  "1234abc"; assert(parse!( int, string, Yes.doCount)(s) ==
        tuple( 1234, 4) && s == "abc"); });
    assertCTFEable!({ string s = "-1234abc"; assert(parse!( int, string, Yes.doCount)(s) ==
        tuple(-1234, 5) && s == "abc"); });
    assertCTFEable!({ string s =  "1234abc"; assert(parse!(uint, string, Yes.doCount)(s) ==
        tuple( 1234 ,4) && s == "abc"); });
}

// https://issues.dlang.org/show_bug.cgi?id=13931
@safe pure unittest
{
    import std.exception;

    assertThrown!ConvOverflowException("-21474836480".to!int());
    assertThrown!ConvOverflowException("-92233720368547758080".to!long());
}

// https://issues.dlang.org/show_bug.cgi?id=14396
@safe pure unittest
{
    struct StrInputRange
    {
        this (string s) { str = s; }
        char front() const @property { return str[front_index]; }
        char popFront() { return str[front_index++]; }
        bool empty() const @property { return str.length <= front_index; }
        string str;
        size_t front_index = 0;
    }
    auto input = StrInputRange("777");
    assert(parse!int(input) == 777);

    auto input2 = StrInputRange("777");
    assert(parse!(int, StrInputRange, Yes.doCount)(input2) == tuple(777, 3));
}

// https://issues.dlang.org/show_bug.cgi?id=9621
@safe pure unittest
{
    string s1 = "[ \"\\141\", \"\\0\", \"\\41\", \"\\418\" ]";
    assert(parse!(string[])(s1) == ["a", "\0", "!", "!8"]);

    s1 = "[ \"\\141\", \"\\0\", \"\\41\", \"\\418\" ]";
    auto len = s1.length;
    assert(parse!(string[], string, Yes.doCount)(s1) == tuple(["a", "\0", "!", "!8"], len));
}

/// ditto
auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source source, uint radix)
if (isIntegral!Target && !is(Target == enum) &&
    isSomeChar!(ElementType!Source))
in
{
    assert(radix >= 2 && radix <= 36, "radix must be in range [2,36]");
}
do
{
    import core.checkedint : mulu, addu;
    import std.exception : enforce;

    if (radix == 10)
    {
        return parse!(Target, Source, doCount)(source);
    }

    enforce!ConvException(!source.empty, "s must not be empty in integral parse");

    immutable uint beyond = (radix < 10 ? '0' : 'a'-10) + radix;
    Target v = 0;

    static if (isNarrowString!Source)
    {
        import std.string : representation;
        scope s = source.representation;
    }
    else
    {
        alias s = source;
    }

    static if (doCount)
        size_t count = 0;
    auto found = false;
    do
    {
        uint c = s.front;
        if (c < '0')
            break;
        if (radix < 10)
        {
            if (c >= beyond)
                break;
        }
        else
        {
            if (c > '9')
            {
                c |= 0x20;//poorman's tolower
                if (c < 'a' || c >= beyond)
                    break;
                c -= 'a'-10-'0';
            }
        }

        bool overflow = false;
        auto nextv = v.mulu(radix, overflow).addu(c - '0', overflow);
        enforce!ConvOverflowException(!overflow && nextv <= Target.max, "Overflow in integral conversion");
        v = cast(Target) nextv;
        static if (doCount)
            ++count;
        s.popFront();
        found = true;
    } while (!s.empty);

    if (!found)
    {
        static if (isNarrowString!Source)
            throw convError!(Source, Target)(cast(Source) source);
        else
            throw convError!(Source, Target)(source);
    }

    static if (isNarrowString!Source)
        source = source[$ - s.length .. $];

    static if (doCount)
    {
        return tuple!("data", "count")(v, count);
    }
    else
    {
        return v;
    }
}

@safe pure unittest
{
    string s; // parse doesn't accept rvalues
    foreach (i; 2 .. 37)
    {
        assert(parse!int(s = "0", i) == 0);
        assert(parse!int(s = "1", i) == 1);
        assert(parse!byte(s = "10", i) == i);
        assert(parse!(int, string, Yes.doCount)(s = "0", i) == tuple(0, 1));
        assert(parse!(int, string, Yes.doCount)(s = "1", i) == tuple(1, 1));
        assert(parse!(byte, string, Yes.doCount)(s = "10", i) == tuple(i, 2));
    }

    assert(parse!int(s = "0011001101101", 2) == 0b0011001101101);
    assert(parse!int(s = "765", 8) == octal!765);
    assert(parse!int(s = "000135", 8) == octal!"135");
    assert(parse!int(s = "fCDe", 16) == 0xfcde);

    // https://issues.dlang.org/show_bug.cgi?id=6609
    assert(parse!int(s = "-42", 10) == -42);

    assert(parse!ubyte(s = "ff", 16) == 0xFF);
}

// https://issues.dlang.org/show_bug.cgi?id=7302
@safe pure unittest
{
    import std.range : cycle;
    auto r = cycle("2A!");
    auto u = parse!uint(r, 16);
    assert(u == 42);
    assert(r.front == '!');

    auto r2 = cycle("2A!");
    auto u2 = parse!(uint, typeof(r2), Yes.doCount)(r2, 16);
    assert(u2.data == 42 && u2.count == 2);
    assert(r2.front == '!');
}

// https://issues.dlang.org/show_bug.cgi?id=13163
@safe pure unittest
{
    import std.exception;
    foreach (s; ["fff", "123"])
        assertThrown!ConvOverflowException(s.parse!ubyte(16));
}

// https://issues.dlang.org/show_bug.cgi?id=17282
@safe pure unittest
{
    auto str = "0=\x00\x02\x55\x40&\xff\xf0\n\x00\x04\x55\x40\xff\xf0~4+10\n";
    assert(parse!uint(str) == 0);

    str = "0=\x00\x02\x55\x40&\xff\xf0\n\x00\x04\x55\x40\xff\xf0~4+10\n";
    assert(parse!(uint, string, Yes.doCount)(str) == tuple(0, 1));
}

// https://issues.dlang.org/show_bug.cgi?id=18248
@safe pure unittest
{
    import std.exception : assertThrown;

    auto str = ";";
    assertThrown(str.parse!uint(16));
    assertThrown(str.parse!(uint, string, Yes.doCount)(16));
}

/**
 * Parses an `enum` type from a string representing an enum member name.
 *
 * Params:
 *     Target = the `enum` type to convert to
 *     s = the lvalue of the range to _parse
 *     doCount = the flag for deciding to report the number of consumed characters
 *
 * Returns:
 $(UL
 *     $(LI An `enum` of type `Target` if `doCount` is set to `No.doCount`)
 *     $(LI A `tuple` containing an `enum` of type `Target` and a `size_t` if `doCount` is set to `Yes.doCount`))
 *
 * Throws:
 *     A $(LREF ConvException) if type `Target` does not have a member
 *     represented by `s`.
 */
auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s)
if (is(Target == enum) && isSomeString!Source && !is(Source == enum))
{
    import std.algorithm.searching : startsWith;
    import std.traits : Unqual, EnumMembers;

    Unqual!Target result;
    size_t longest_match = 0;

    foreach (i, e; EnumMembers!Target)
    {
        auto ident = __traits(allMembers, Target)[i];
        if (longest_match < ident.length && s.startsWith(ident))
        {
            result = e;
            longest_match = ident.length ;
        }
    }

    if (longest_match > 0)
    {
        s = s[longest_match .. $];
        static if (doCount)
        {
            return tuple!("data", "count")(result, longest_match);
        }
        else
        {
            return result;
        }
    }

    throw new ConvException(
        Target.stringof ~ " does not have a member named '"
        ~ to!string(s) ~ "'");
}

///
@safe unittest
{
    import std.typecons : Flag, Yes, No, tuple;
    enum EnumType : bool { a = true, b = false, c = a }

    auto str = "a";
    assert(parse!EnumType(str) == EnumType.a);
    auto str2 = "a";
    assert(parse!(EnumType, string, No.doCount)(str2) == EnumType.a);
    auto str3 = "a";
    assert(parse!(EnumType, string, Yes.doCount)(str3) == tuple(EnumType.a, 1));

}

@safe unittest
{
    import std.exception;

    enum EB : bool { a = true, b = false, c = a }
    enum EU { a, b, c }
    enum EI { a = -1, b = 0, c = 1 }
    enum EF : real { a = 1.414, b = 1.732, c = 2.236 }
    enum EC : char { a = 'a', b = 'b', c = 'c' }
    enum ES : string { a = "aaa", b = "bbb", c = "ccc" }

    static foreach (E; AliasSeq!(EB, EU, EI, EF, EC, ES))
    {
        assert(to!E("a"c) == E.a);
        assert(to!E("b"w) == E.b);
        assert(to!E("c"d) == E.c);

        assert(to!(const E)("a") == E.a);
        assert(to!(immutable E)("a") == E.a);
        assert(to!(shared E)("a") == E.a);

        assertThrown!ConvException(to!E("d"));
    }
}

// https://issues.dlang.org/show_bug.cgi?id=4744
@safe pure unittest
{
    enum A { member1, member11, member111 }
    assert(to!A("member1"  ) == A.member1  );
    assert(to!A("member11" ) == A.member11 );
    assert(to!A("member111") == A.member111);
    auto s = "member1111";
    assert(parse!A(s) == A.member111 && s == "1");
    auto s2 = "member1111";
    assert(parse!(A, string, No.doCount)(s2) == A.member111 && s2 == "1");
    auto s3 = "member1111";
    assert(parse!(A, string, Yes.doCount)(s3) == tuple(A.member111, 9) && s3 == "1");
}

/**
 * Parses a floating point number from a character range.
 *
 * Params:
 *     Target = a floating point type
 *     source = the lvalue of the range to _parse
 *     doCount = the flag for deciding to report the number of consumed characters
 *
 * Returns:
 $(UL
 *     $(LI A floating point number of type `Target` if `doCount` is set to `No.doCount`)
 *     $(LI A `tuple` containing a floating point number of·type `Target` and a `size_t`
 *     if `doCount` is set to `Yes.doCount`))
 *
 * Throws:
 *     A $(LREF ConvException) if `source` is empty, if no number could be
 *     parsed, or if an overflow occurred.
 */
auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source source)
if (isFloatingPoint!Target && !is(Target == enum) &&
    isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum))
{
    import std.ascii : isDigit, isAlpha, toLower, toUpper, isHexDigit;
    import std.exception : enforce;

    static if (isNarrowString!Source)
    {
        import std.string : representation;
        scope p = source.representation;
    }
    else
    {
        alias p = source;
    }

    void advanceSource()
    {
        static if (isNarrowString!Source)
            source = source[$ - p.length .. $];
    }

    static immutable real[14] negtab =
        [ 1e-4096L,1e-2048L,1e-1024L,1e-512L,1e-256L,1e-128L,1e-64L,1e-32L,
                1e-16L,1e-8L,1e-4L,1e-2L,1e-1L,1.0L ];
    static immutable real[13] postab =
        [ 1e+4096L,1e+2048L,1e+1024L,1e+512L,1e+256L,1e+128L,1e+64L,1e+32L,
                1e+16L,1e+8L,1e+4L,1e+2L,1e+1L ];

    ConvException bailOut()(string msg = null, string fn = __FILE__, size_t ln = __LINE__)
    {
        if (msg == null)
            msg = "Floating point conversion error";
        return new ConvException(text(msg, " for input \"", source, "\"."), fn, ln);
    }

    enforce(!p.empty, bailOut());

    size_t count = 0;
    bool sign = false;
    switch (p.front)
    {
    case '-':
        sign = true;
        static if (doCount) ++count;
        p.popFront();
        enforce(!p.empty, bailOut());
        if (toLower(p.front) == 'i')
            goto case 'i';
        break;
    case '+':
        static if (doCount) ++count;
        p.popFront();
        enforce(!p.empty, bailOut());
        break;
    case 'i': case 'I':
        // inf
        static if (doCount) ++count;
        p.popFront();
        enforce(!p.empty && toUpper(p.front) == 'N',
               bailOut("error converting input to floating point"));
        static if (doCount) ++count;
        p.popFront();
        enforce(!p.empty && toUpper(p.front) == 'F',
               bailOut("error converting input to floating point"));
        // skip past the last 'f'
        static if (doCount) ++count;
        p.popFront();
        advanceSource();
        static if (doCount)
        {
            return tuple!("data", "count")(sign ? -Target.infinity : Target.infinity, count);
        }
        else
        {
            return sign ? -Target.infinity : Target.infinity;
        }
    default: {}
    }

    bool isHex = false;
    bool startsWithZero = p.front == '0';
    if (startsWithZero)
    {
        static if (doCount) ++count;
        p.popFront();
        if (p.empty)
        {
            advanceSource();
            static if (doCount)
            {
                return tuple!("data", "count")(cast (Target) (sign ? -0.0 : 0.0), count);
            }
            else
            {
                return sign ? -0.0 : 0.0;
            }
        }

        isHex = p.front == 'x' || p.front == 'X';
        if (isHex)
        {
            static if (doCount) ++count;
            p.popFront();
        }
    }
    else if (toLower(p.front) == 'n')
    {
        // nan
        static if (doCount) ++count;
        p.popFront();
        enforce(!p.empty && toUpper(p.front) == 'A',
               bailOut("error converting input to floating point"));
        static if (doCount) ++count;
        p.popFront();
        enforce(!p.empty && toUpper(p.front) == 'N',
               bailOut("error converting input to floating point"));
        // skip past the last 'n'
        static if (doCount) ++count;
        p.popFront();
        advanceSource();
        static if (doCount)
        {
            return tuple!("data", "count")(Target.nan, count);
        }
        else
        {
            return typeof(return).nan;
        }
    }

    /*
     * The following algorithm consists of 2 steps:
     * 1) parseDigits processes the textual input into msdec and possibly
     *    lsdec/msscale variables, followed by the exponent parser which sets
     *    exp below.
     *    Hex: input is 0xaaaaa...p+000... where aaaa is the mantissa in hex
     *    and 000 is the exponent in decimal format with base 2.
     *    Decimal: input is 0.00333...p+000... where 0.0033 is the mantissa
     *    in decimal and 000 is the exponent in decimal format with base 10.
     * 2) Convert msdec/lsdec and exp into native real format
     */

    real ldval = 0.0;
    char dot = 0;                        /* if decimal point has been seen */
    int exp = 0;
    ulong msdec = 0, lsdec = 0;
    ulong msscale = 1;
    bool sawDigits;

    enum { hex, decimal }

    // sets msdec, lsdec/msscale, and sawDigits by parsing the mantissa digits
    void parseDigits(alias FloatFormat)()
    {
        static if (FloatFormat == hex)
        {
            enum uint base = 16;
            enum ulong msscaleMax = 0x1000_0000_0000_0000UL; // largest power of 16 a ulong holds
            enum ubyte expIter = 4; // iterate the base-2 exponent by 4 for every hex digit
            alias checkDigit = isHexDigit;
            /*
             * convert letter to binary representation: First clear bit
             * to convert lower space chars to upperspace, then -('A'-10)
             * converts letter A to 10, letter B to 11, ...
             */
            alias convertDigit = (int x) => isAlpha(x) ? ((x & ~0x20) - ('A' - 10)) : x - '0';
            sawDigits = false;
        }
        else static if (FloatFormat == decimal)
        {
            enum uint base = 10;
            enum ulong msscaleMax = 10_000_000_000_000_000_000UL; // largest power of 10 a ulong holds
            enum ubyte expIter = 1; // iterate the base-10 exponent once for every decimal digit
            alias checkDigit = isDigit;
            alias convertDigit = (int x) => x - '0';
            // Used to enforce that any mantissa digits are present
            sawDigits = startsWithZero;
        }
        else
            static assert(false, "Unrecognized floating-point format used.");

        while (!p.empty)
        {
            int i = p.front;
            while (checkDigit(i))
            {
                sawDigits = true;        /* must have at least 1 digit   */

                i = convertDigit(i);

                if (msdec < (ulong.max - base)/base)
                {
                    // For base 16: Y = ... + y3*16^3 + y2*16^2 + y1*16^1 + y0*16^0
                    msdec = msdec * base + i;
                }
                else if (msscale < msscaleMax)
                {
                    lsdec = lsdec * base + i;
                    msscale *= base;
                }
                else
                {
                    exp += expIter;
                }
                exp -= dot;
                static if (doCount) ++count;
                p.popFront();
                if (p.empty)
                    break;
                i = p.front;
                if (i == '_')
                {
                    static if (doCount) ++count;
                    p.popFront();
                    if (p.empty)
                        break;
                    i = p.front;
                }
            }
            if (i == '.' && !dot)
            {
                static if (doCount) ++count;
                p.popFront();
                dot += expIter;
            }
            else
                break;
        }

        // Have we seen any mantissa digits so far?
        enforce(sawDigits, bailOut("no digits seen"));
        static if (FloatFormat == hex)
            enforce(!p.empty && (p.front == 'p' || p.front == 'P'),
                    bailOut("Floating point parsing: exponent is required"));
    }

    if (isHex)
        parseDigits!hex;
    else
        parseDigits!decimal;

    if (isHex || (!p.empty && (p.front == 'e' || p.front == 'E')))
    {
        char sexp = 0;
        int e = 0;

        static if (doCount) ++count;
        p.popFront();
        enforce(!p.empty, new ConvException("Unexpected end of input"));
        switch (p.front)
        {
            case '-':    sexp++;
                         goto case;
            case '+':    static if (doCount) ++count;
                         p.popFront();
                         break;
            default: {}
        }
        sawDigits = false;
        while (!p.empty && isDigit(p.front))
        {
            if (e < 0x7FFFFFFF / 10 - 10)   // prevent integer overflow
            {
                e = e * 10 + p.front - '0';
            }
            static if (doCount) ++count;
            p.popFront();
            sawDigits = true;
        }
        exp += (sexp) ? -e : e;
        enforce(sawDigits, new ConvException("No digits seen."));
    }

    ldval = msdec;
    if (msscale != 1)               /* if stuff was accumulated in lsdec */
        ldval = ldval * msscale + lsdec;
    if (isHex)
    {
        import core.math : ldexp;

        // Exponent is power of 2, not power of 10
        ldval = ldexp(ldval,exp);
    }
    else if (ldval)
    {
        uint u = 0;
        int pow = 4096;

        while (exp > 0)
        {
            while (exp >= pow)
            {
                ldval *= postab[u];
                exp -= pow;
            }
            pow >>= 1;
            u++;
        }
        while (exp < 0)
        {
            while (exp <= -pow)
            {
                ldval *= negtab[u];
                enforce(ldval != 0, new ConvException("Range error"));
                exp += pow;
            }
            pow >>= 1;
            u++;
        }
    }

    Target result = cast(Target) (sign ? -ldval : ldval);

    // if overflow occurred
    import std.math.traits : isFinite;
    enforce(isFinite(result), new ConvException("Range error"));

    advanceSource();
    static if (doCount)
    {
        return tuple!("data", "count")(result, count);
    }
    else
    {
        return result;
    }
}


///
@safe unittest
{
    import std.math.operations : isClose;
    import std.math.traits : isNaN, isInfinity;
    import std.typecons : Flag, Yes, No;
    auto str = "123.456";
    assert(parse!double(str).isClose(123.456));
    auto str2 = "123.456";
    assert(parse!(double, string, No.doCount)(str2).isClose(123.456));
    auto str3 = "123.456";
    auto r = parse!(double, string, Yes.doCount)(str3);
    assert(r.data.isClose(123.456));
    assert(r.count == 7);
    auto str4 = "-123.456";
    r = parse!(double, string, Yes.doCount)(str4);
    assert(r.data.isClose(-123.456));
    assert(r.count == 8);
    auto str5 = "+123.456";
    r = parse!(double, string, Yes.doCount)(str5);
    assert(r.data.isClose(123.456));
    assert(r.count == 8);
    auto str6 = "inf0";
    r = parse!(double, string, Yes.doCount)(str6);
    assert(isInfinity(r.data) && r.count == 3 && str6 == "0");
    auto str7 = "-0";
    auto r2 = parse!(float, string, Yes.doCount)(str7);
    assert(r2.data.isClose(0.0) && r2.count == 2);
    auto str8 = "nan";
    auto r3 = parse!(real, string, Yes.doCount)(str8);
    assert(isNaN(r3.data) && r3.count == 3);
}

@safe unittest
{
    import std.exception;
    import std.math.traits : isNaN, isInfinity;
    import std.math.algebraic : fabs;

    // Compare reals with given precision
    bool feq(in real rx, in real ry, in real precision = 0.000001L)
    {
        if (rx == ry)
            return 1;

        if (isNaN(rx))
            return cast(bool) isNaN(ry);

        if (isNaN(ry))
            return 0;

        return cast(bool)(fabs(rx - ry) <= precision);
    }

    // Make given typed literal
    F Literal(F)(F f)
    {
        return f;
    }

    static foreach (Float; AliasSeq!(float, double, real))
    {
        assert(to!Float("123") == Literal!Float(123));
        assert(to!Float("+123") == Literal!Float(+123));
        assert(to!Float("-123") == Literal!Float(-123));
        assert(to!Float("123e2") == Literal!Float(123e2));
        assert(to!Float("123e+2") == Literal!Float(123e+2));
        assert(to!Float("123e-2") == Literal!Float(123e-2L));
        assert(to!Float("123.") == Literal!Float(123.0));
        assert(to!Float(".375") == Literal!Float(.375));

        assert(to!Float("1.23375E+2") == Literal!Float(1.23375E+2));

        assert(to!Float("0") is 0.0);
        assert(to!Float("-0") is -0.0);

        assert(isNaN(to!Float("nan")));

        assertThrown!ConvException(to!Float("\x00"));
    }

    // min and max
    float f = to!float("1.17549e-38");
    assert(feq(cast(real) f, cast(real) 1.17549e-38));
    assert(feq(cast(real) f, cast(real) float.min_normal));
    f = to!float("3.40282e+38");
    assert(to!string(f) == to!string(3.40282e+38));

    // min and max
    double d = to!double("2.22508e-308");
    assert(feq(cast(real) d, cast(real) 2.22508e-308));
    assert(feq(cast(real) d, cast(real) double.min_normal));
    d = to!double("1.79769e+308");
    assert(to!string(d) == to!string(1.79769e+308));
    assert(to!string(d) == to!string(double.max));

    auto z = real.max / 2L;
    static assert(is(typeof(z) == real));
    assert(!isNaN(z));
    assert(!isInfinity(z));
    string a = to!string(z);
    real b = to!real(a);
    string c = to!string(b);

    assert(c == a, "\n" ~ c ~ "\n" ~ a);

    assert(to!string(to!real(to!string(real.max / 2L))) == to!string(real.max / 2L));

    // min and max
    real r = to!real(to!string(real.min_normal));
    version (NetBSD)
    {
        // NetBSD notice
        // to!string returns 3.3621e-4932L. It is less than real.min_normal and it is subnormal value
        // Simple C code
        //     long double rd = 3.3621e-4932L;
        //     printf("%Le\n", rd);
        // has unexpected result: 1.681050e-4932
        //
        // Bug report: http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=50937
    }
    else
    {
        assert(to!string(r) == to!string(real.min_normal));
    }
    r = to!real(to!string(real.max));
    assert(to!string(r) == to!string(real.max));

    real pi = 3.1415926535897932384626433832795028841971693993751L;
    string fullPrecision = "3.1415926535897932384626433832795028841971693993751";
    assert(feq(parse!real(fullPrecision), pi, 2*real.epsilon));
    string fullPrecision2 = "3.1415926535897932384626433832795028841971693993751";
    assert(feq(parse!(real, string, No.doCount)(fullPrecision2), pi, 2*real.epsilon));
    string fullPrecision3= "3.1415926535897932384626433832795028841971693993751";
    auto len = fullPrecision3.length;
    auto res = parse!(real, string, Yes.doCount)(fullPrecision3);
    assert(feq(res.data, pi, 2*real.epsilon));
    assert(res.count == len);

    real x = 0x1.FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAAFAAFAFAFAFAFAFAFAP-252L;
    string full = "0x1.FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAAFAAFAFAFAFAFAFAFAP-252";
    assert(parse!real(full) == x);
    string full2 = "0x1.FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAAFAAFAFAFAFAFAFAFAP-252";
    assert(parse!(real, string, No.doCount)(full2) == x);
    string full3 = "0x1.FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAAFAAFAFAFAFAFAFAFAP-252";
    auto len2 = full3.length;
    assert(parse!(real, string, Yes.doCount)(full3) == tuple(x, len2));
}

// Tests for the double implementation
@system unittest
{
    // @system because strtod is not @safe.
    import std.math.traits : floatTraits, RealFormat;

    static if (floatTraits!real.realFormat == RealFormat.ieeeDouble)
    {
        import core.stdc.stdlib, std.exception, std.math;

        //Should be parsed exactly: 53 bit mantissa
        string s = "0x1A_BCDE_F012_3456p10";
        auto x = parse!real(s);
        assert(x == 0x1A_BCDE_F012_3456p10L);
        //1 bit is implicit
        assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0xA_BCDE_F012_3456);
        assert(strtod("0x1ABCDEF0123456p10", null) == x);

        s = "0x1A_BCDE_F012_3456p10";
        auto len = s.length;
        assert(parse!(real, string, Yes.doCount)(s) == tuple(x, len));

        //Should be parsed exactly: 10 bit mantissa
        s = "0x3FFp10";
        x = parse!real(s);
        assert(x == 0x03FFp10);
        //1 bit is implicit
        assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x000F_F800_0000_0000);
        assert(strtod("0x3FFp10", null) == x);

        //60 bit mantissa, round up
        s = "0xFFF_FFFF_FFFF_FFFFp10";
        x = parse!real(s);
        assert(isClose(x, 0xFFF_FFFF_FFFF_FFFFp10));
        //1 bit is implicit
        assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x0000_0000_0000_0000);
        assert(strtod("0xFFFFFFFFFFFFFFFp10", null) == x);

        //60 bit mantissa, round down
        s = "0xFFF_FFFF_FFFF_FF90p10";
        x = parse!real(s);
        assert(isClose(x, 0xFFF_FFFF_FFFF_FF90p10));
        //1 bit is implicit
        assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x000F_FFFF_FFFF_FFFF);
        assert(strtod("0xFFFFFFFFFFFFF90p10", null) == x);

        //61 bit mantissa, round up 2
        s = "0x1F0F_FFFF_FFFF_FFFFp10";
        x = parse!real(s);
        assert(isClose(x, 0x1F0F_FFFF_FFFF_FFFFp10));
        //1 bit is implicit
        assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x000F_1000_0000_0000);
        assert(strtod("0x1F0FFFFFFFFFFFFFp10", null) == x);

        //61 bit mantissa, round down 2
        s = "0x1F0F_FFFF_FFFF_FF10p10";
        x = parse!real(s);
        assert(isClose(x, 0x1F0F_FFFF_FFFF_FF10p10));
        //1 bit is implicit
        assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x000F_0FFF_FFFF_FFFF);
        assert(strtod("0x1F0FFFFFFFFFFF10p10", null) == x);

        //Huge exponent
        s = "0x1F_FFFF_FFFF_FFFFp900";
        x = parse!real(s);
        assert(strtod("0x1FFFFFFFFFFFFFp900", null) == x);

        //exponent too big -> converror
        s = "";
        assertThrown!ConvException(x = parse!real(s));
        assert(strtod("0x1FFFFFFFFFFFFFp1024", null) == real.infinity);

        //-exponent too big -> 0
        s = "0x1FFFFFFFFFFFFFp-2000";
        x = parse!real(s);
        assert(x == 0);
        assert(strtod("0x1FFFFFFFFFFFFFp-2000", null) == x);

        s = "0x1FFFFFFFFFFFFFp-2000";
        len = s.length;
        assert(parse!(real, string, Yes.doCount)(s) == tuple(x, len));
    }
}

@system unittest
{
    import core.stdc.errno;
    import core.stdc.stdlib;
    import std.math.traits : floatTraits, RealFormat;

    errno = 0;  // In case it was set by another unittest in a different module.
    struct longdouble
    {
        static if (floatTraits!real.realFormat == RealFormat.ieeeQuadruple)
        {
            ushort[8] value;
        }
        else static if (floatTraits!real.realFormat == RealFormat.ieeeExtended ||
                        floatTraits!real.realFormat == RealFormat.ieeeExtended53)
        {
            ushort[5] value;
        }
        else static if (floatTraits!real.realFormat == RealFormat.ieeeDouble)
        {
            ushort[4] value;
        }
        else
            static assert(false, "Not implemented");
    }

    real ld;
    longdouble x;
    real ld1;
    longdouble x1;
    int i;

    static if (floatTraits!real.realFormat == RealFormat.ieeeQuadruple)
        enum s = "0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp-16382";
    else static if (floatTraits!real.realFormat == RealFormat.ieeeExtended)
        enum s = "0x1.FFFFFFFFFFFFFFFEp-16382";
    else static if (floatTraits!real.realFormat == RealFormat.ieeeExtended53)
        enum s = "0x1.FFFFFFFFFFFFFFFEp-16382";
    else static if (floatTraits!real.realFormat == RealFormat.ieeeDouble)
        enum s = "0x1.FFFFFFFFFFFFFFFEp-1000";
    else
        static assert(false, "Floating point format for real not supported");

    auto s2 = s.idup;
    ld = parse!real(s2);
    assert(s2.empty);
    x = *cast(longdouble *)&ld;

    static if (floatTraits!real.realFormat == RealFormat.ieeeExtended)
    {
        version (CRuntime_Microsoft)
            ld1 = 0x1.FFFFFFFFFFFFFFFEp-16382L; // strtold currently mapped to strtod
        else
            ld1 = strtold(s.ptr, null);
    }
    else static if (floatTraits!real.realFormat == RealFormat.ieeeExtended53)
        ld1 = 0x1.FFFFFFFFFFFFFFFEp-16382L; // strtold rounds to 53 bits.
    else
        ld1 = strtold(s.ptr, null);

    x1 = *cast(longdouble *)&ld1;
    assert(x1 == x && ld1 == ld);

    assert(!errno);

    s2 = "1.0e5";
    ld = parse!real(s2);
    assert(s2.empty);
    x = *cast(longdouble *)&ld;
    ld1 = strtold("1.0e5", null);
    x1 = *cast(longdouble *)&ld1;
}

@safe pure unittest
{
    import std.exception;

    // https://issues.dlang.org/show_bug.cgi?id=4959
    {
        auto s = "0 ";
        auto x = parse!double(s);
        assert(s == " ");
        assert(x == 0.0);
    }
    {
        auto s = "0 ";
        auto x = parse!(double, string, Yes.doCount)(s);
        assert(s == " ");
        assert(x == tuple(0.0, 1));
    }

    // https://issues.dlang.org/show_bug.cgi?id=3369
    assert(to!float("inf") == float.infinity);
    assert(to!float("-inf") == -float.infinity);

    // https://issues.dlang.org/show_bug.cgi?id=6160
    assert(6_5.536e3L == to!real("6_5.536e3"));                     // 2^16
    assert(0x1000_000_000_p10 == to!real("0x1000_000_000_p10"));    // 7.03687e+13

    // https://issues.dlang.org/show_bug.cgi?id=6258
    assertThrown!ConvException(to!real("-"));
    assertThrown!ConvException(to!real("in"));

    // https://issues.dlang.org/show_bug.cgi?id=7055
    assertThrown!ConvException(to!float("INF2"));

    //extra stress testing
    auto ssOK    = ["1.", "1.1.1", "1.e5", "2e1e", "2a", "2e1_1", "3.4_",
                    "inf", "-inf", "infa", "-infa", "inf2e2", "-inf2e2",
                    "nan", "-NAN", "+NaN", "-nAna", "NAn2e2", "-naN2e2"];
    auto ssKO    = ["", " ", "2e", "2e+", "2e-", "2ee", "2e++1", "2e--1", "2e_1",
                    "+inf", "-in", "I", "+N", "-NaD", "0x3.F"];
    foreach (s; ssOK)
        parse!double(s);
    foreach (s; ssKO)
        assertThrown!ConvException(parse!double(s));
}

@safe unittest // https://issues.dlang.org/show_bug.cgi?id=22637
{
    import std.exception : assertThrown, assertNotThrown;
    auto src = "9991232549867999698999493543521458974414359998784641646846435132132543645435456345634541999999999999999"
    ~ "9999999943321231321311999231345312413646846354354354399999934153465464654646464654134135354199999999996515734999"
    ~ "9999999320135273486741354354731567431324134999999999999999999999999999999999999999999999135411.9";
    assertThrown!ConvException(parse!double(src));
    static if (real.max_10_exp > 310) assertNotThrown!ConvException(parse!real(src));
}

/**
Parses one character from a character range.

Params:
    Target = the type to convert to
    s = the lvalue of an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
    doCount = the flag for deciding to report the number of consumed characters

Returns:
$(UL
    $(LI A character of type `Target` if `doCount` is set to `No.doCount`)
    $(LI A `tuple` containing a character of type `Target` and a `size_t` if `doCount` is set to `Yes.doCount`))

Throws:
    A $(LREF ConvException) if the range is empty.
 */
auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s)
if (staticIndexOf!(immutable Target, immutable dchar, immutable ElementEncodingType!Source) >= 0 &&
    isSomeString!Source && !is(Source == enum))
{
    if (s.empty)
        throw convError!(Source, Target)(s);
    static if (is(immutable Target == immutable dchar))
    {
        Target result = s.front;
        s.popFront();
        static if (doCount)
        {
            return tuple!("data", "count")(result, 1);
        }
        else
        {
            return result;
        }

    }
    else
    {
        // Special case: okay so parse a Char off a Char[]
        Target result = s[0];
        s = s[1 .. $];
        static if (doCount)
        {
            return tuple!("data", "count")(result, 1);
        }
        else
        {
            return result;
        }
    }
}

@safe pure unittest
{
    static foreach (Str; AliasSeq!(string, wstring, dstring))
    {
        static foreach (Char; AliasSeq!(char, wchar, dchar))
        {{
            static if (is(immutable Char == immutable dchar) ||
                       Char.sizeof == ElementEncodingType!Str.sizeof)
            {
                Str s = "aaa";
                assert(parse!Char(s) == 'a');
                assert(s == "aa");
                assert(parse!(Char, typeof(s), No.doCount)(s) == 'a');
                assert(s == "a");
                assert(parse!(Char, typeof(s), Yes.doCount)(s) == tuple('a', 1) && s == "");
            }
        }}
    }
}

/// ditto
auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s)
if (isSomeChar!Target && Target.sizeof >= ElementType!Source.sizeof && !is(Target == enum) &&
    !isSomeString!Source && isInputRange!Source && isSomeChar!(ElementType!Source))
{
    if (s.empty)
        throw convError!(Source, Target)(s);
    Target result = s.front;
    s.popFront();
    static if (doCount)
    {
        return tuple!("data", "count")(result, 1);
    }
    else
    {
        return result;
    }
}

///
@safe pure unittest
{
    import std.typecons : Flag, Yes, No;
    auto s = "Hello, World!";
    char first = parse!char(s);
    assert(first == 'H');
    assert(s == "ello, World!");
    char second = parse!(char, string, No.doCount)(s);
    assert(second == 'e');
    assert(s == "llo, World!");
    auto third = parse!(char, string, Yes.doCount)(s);
    assert(third.data == 'l' && third.count == 1);
    assert(s == "lo, World!");
}


/*
    Tests for to!bool and parse!bool
*/
@safe pure unittest
{
    import std.exception;

    assert(to!bool("TruE") == true);
    assert(to!bool("faLse"d) == false);
    assertThrown!ConvException(to!bool("maybe"));

    auto t = "TrueType";
    assert(parse!bool(t) == true);
    assert(t == "Type");

    auto f = "False killer whale"d;
    assert(parse!bool(f) == false);
    assert(f == " killer whale"d);

    f = "False killer whale"d;
    assert(parse!(bool, dstring, Yes.doCount)(f) == tuple(false, 5));
    assert(f == " killer whale"d);

    auto m = "maybe";
    assertThrown!ConvException(parse!bool(m));
    assertThrown!ConvException(parse!(bool, string, Yes.doCount)(m));
    assert(m == "maybe");  // m shouldn't change on failure

    auto s = "true";
    auto b = parse!(const(bool))(s);
    assert(b == true);
}

/**
Parses `typeof(null)` from a character range if the range
spells `"null"`. This function is case insensitive.

Params:
    Target = the type to convert to
    s = the lvalue of an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
    doCount = the flag for deciding to report the number of consumed characters

Returns:
$(UL
    $(LI `null` if `doCount` is set to `No.doCount`)
    $(LI A `tuple` containing `null` and a `size_t` if `doCount` is set to `Yes.doCount`))

Throws:
    A $(LREF ConvException) if the range doesn't represent `null`.
 */
auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s)
if (is(immutable Target == immutable typeof(null)) &&
    isInputRange!Source &&
    isSomeChar!(ElementType!Source))
{
    import std.ascii : toLower;
    foreach (c; "null")
    {
        if (s.empty || toLower(s.front) != c)
            throw parseError("null should be case-insensitive 'null'");
        s.popFront();
    }
    static if (doCount)
    {
        return tuple!("data", "count")(null, 4);
    }
    else
    {
        return null;
    }
}

///
@safe pure unittest
{
    import std.exception : assertThrown;
    import std.typecons : Flag, Yes, No;

    alias NullType = typeof(null);
    auto s1 = "null";
    assert(parse!NullType(s1) is null);
    assert(s1 == "");

    auto s2 = "NUll"d;
    assert(parse!NullType(s2) is null);
    assert(s2 == "");

    auto s3 = "nuLlNULl";
    assert(parse!(NullType, string, No.doCount)(s3) is null);
    auto r = parse!(NullType, string, Yes.doCount)(s3);
    assert(r.data is null && r.count == 4);

    auto m = "maybe";
    assertThrown!ConvException(parse!NullType(m));
    assertThrown!ConvException(parse!(NullType, string, Yes.doCount)(m));
    assert(m == "maybe");  // m shouldn't change on failure

    auto s = "NULL";
    assert(parse!(const NullType)(s) is null);
}

//Used internally by parse Array/AA, to remove ascii whites
package auto skipWS(R, Flag!"doCount" doCount = No.doCount)(ref R r)
{
    import std.ascii : isWhite;
    static if (isSomeString!R)
    {
        //Implementation inspired from stripLeft.
        foreach (i, c; r)
        {
            if (!isWhite(c))
            {
                r = r[i .. $];
                static if (doCount)
                {
                    return i;
                }
                else
                {
                    return;
                }
            }
        }
        auto len = r.length;
        r = r[0 .. 0]; //Empty string with correct type.
        static if (doCount)
        {
            return len;
        }
        else
        {
            return;
        }
    }
    else
    {
        size_t i = 0;
        for (; !r.empty && isWhite(r.front); r.popFront(), ++i)
        { }
        static if (doCount)
        {
            return i;
        }
    }
}

/**
 * Parses an array from a string given the left bracket (default $(D
 * '[')), right bracket (default `']'`), and element separator (by
 * default `','`). A trailing separator is allowed.
 *
 * Params:
 *     s = The string to parse
 *     lbracket = the character that starts the array
 *     rbracket = the character that ends the array
 *     comma = the character that separates the elements of the array
 *     doCount = the flag for deciding to report the number of consumed characters
 *
 * Returns:
 $(UL
 *     $(LI An array of type `Target` if `doCount` is set to `No.doCount`)
 *     $(LI A `tuple` containing an array of type `Target` and a `size_t` if `doCount` is set to `Yes.doCount`))
 */
auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s, dchar lbracket = '[',
    dchar rbracket = ']', dchar comma = ',')
if (isDynamicArray!Target && !is(Target == enum) &&
    isSomeString!Source && !is(Source == enum))
{
    import std.array : appender;

    auto result = appender!Target();

    parseCheck!s(lbracket);
    static if (doCount)
        size_t count = 1;
    static if (doCount)
        count += skipWS!(Source, Yes.doCount)(s);
    else
        skipWS!(Source, No.doCount)(s);
    if (s.empty)
        throw convError!(Source, Target)(s);
    if (s.front == rbracket)
    {
        s.popFront();
        static if (doCount)
        {
            ++count;
            return tuple!("data", "count")(result.data, count);
        }
        else
        {
            return result.data;
        }
    }
    for (;;)
    {
        if (!s.empty && s.front == rbracket)
            break;
        static if (doCount)
        {
            auto r = parseElement!(WideElementType!Target, Source, Yes.doCount)(s);
            result ~= r.data;
            count += r.count;
            count += skipWS!(Source, Yes.doCount)(s);
        }
        else
        {
            auto r = parseElement!(WideElementType!Target, Source, No.doCount)(s);
            result ~= r;
            skipWS!(Source, No.doCount)(s);
        }
        if (s.empty)
            throw convError!(Source, Target)(s);
        if (s.front != comma)
            break;
        s.popFront();
        static if (doCount)
            ++count;
        static if (doCount)
            count += skipWS!(Source, Yes.doCount)(s);
        else
            skipWS!(Source, No.doCount)(s);
    }
    parseCheck!s(rbracket);
    static if (doCount)
    {
        ++count;
        return tuple!("data", "count")(result.data, count);
    }
    else
    {
        return result.data;
    }
}
///
@safe pure unittest
{
    import std.typecons : Flag, Yes, No;
    auto s1 = `[['h', 'e', 'l', 'l', 'o'], "world"]`;
    auto a1 = parse!(string[])(s1);
    assert(a1 == ["hello", "world"]);

    auto s2 = `["aaa", "bbb", "ccc"]`;
    auto a2 = parse!(string[])(s2);
    assert(a2 == ["aaa", "bbb", "ccc"]);

    auto s3 = `[['h', 'e', 'l', 'l', 'o'], "world"]`;
    auto len3 = s3.length;
    auto a3 = parse!(string[], string, Yes.doCount)(s3);
    assert(a3.data == ["hello", "world"]);
    assert(a3.count == len3);
}

// https://issues.dlang.org/show_bug.cgi?id=9615
@safe unittest
{
    import std.typecons : Flag, Yes, No, tuple;
    string s0 = "[1,2, ]";
    string s1 = "[1,2, \t\v\r\n]";
    string s2 = "[1,2]";
    assert(s0.parse!(int[]) == [1,2]);
    assert(s1.parse!(int[]) == [1,2]);
    assert(s2.parse!(int[]) == [1,2]);

    s0 = "[1,2, ]";
    auto len0 = s0.length;
    s1 = "[1,2, \t\v\r\n]";
    auto len1 = s1.length;
    s2 = "[1,2]";
    auto len2 = s2.length;
    assert(s0.parse!(int[], string, Yes.doCount) == tuple([1,2], len0));
    assert(s1.parse!(int[], string, Yes.doCount) == tuple([1,2], len1));
    assert(s2.parse!(int[], string, Yes.doCount) == tuple([1,2], len2));

    string s3 = `["a","b",]`;
    string s4 = `["a","b"]`;
    assert(s3.parse!(string[]) == ["a","b"]);
    assert(s4.parse!(string[]) == ["a","b"]);

    s3 = `["a","b",]`;
    auto len3 = s3.length;
    assert(s3.parse!(string[], string, Yes.doCount) == tuple(["a","b"], len3));

    s3 = `[    ]`;
    assert(tuple([], s3.length) == s3.parse!(string[], string, Yes.doCount));

    import std.exception : assertThrown;
    string s5 = "[,]";
    string s6 = "[, \t,]";
    assertThrown!ConvException(parse!(string[])(s5));
    assertThrown!ConvException(parse!(int[])(s6));

    s5 = "[,]";
    s6 = "[,·\t,]";
    assertThrown!ConvException(parse!(string[], string, Yes.doCount)(s5));
    assertThrown!ConvException(parse!(string[], string, Yes.doCount)(s6));
}

@safe unittest
{
    int[] a = [1, 2, 3, 4, 5];
    auto s = to!string(a);
    assert(to!(int[])(s) == a);
}

@safe unittest
{
    int[][] a = [ [1, 2] , [3], [4, 5] ];
    auto s = to!string(a);
    assert(to!(int[][])(s) == a);
}

@safe unittest
{
    int[][][] ia = [ [[1,2],[3,4],[5]] , [[6],[],[7,8,9]] , [[]] ];

    char[] s = to!(char[])(ia);
    int[][][] ia2;

    ia2 = to!(typeof(ia2))(s);
    assert( ia == ia2);
}

@safe pure unittest
{
    import std.exception;
    import std.typecons : Flag, Yes, No;

    //Check proper failure
    auto s = "[ 1 , 2 , 3 ]";
    auto s2 = s.save;
    foreach (i ; 0 .. s.length-1)
    {
        auto ss = s[0 .. i];
        assertThrown!ConvException(parse!(int[])(ss));
        assertThrown!ConvException(parse!(int[], string, Yes.doCount)(ss));
    }
    int[] arr = parse!(int[])(s);
    auto arr2 = parse!(int[], string, Yes.doCount)(s2);
    arr = arr2.data;
}

@safe pure unittest
{
    //Checks parsing of strings with escaped characters
    string s1 = `[
        "Contains a\0null!",
        "tab\there",
        "line\nbreak",
        "backslash \\ slash / question \?",
        "number \x35 five",
        "unicode \u65E5 sun",
        "very long \U000065E5 sun"
    ]`;

    //Note: escaped characters purposefully replaced and isolated to guarantee
    //there are no typos in the escape syntax
    string[] s2 = [
        "Contains a" ~ '\0' ~ "null!",
        "tab" ~ '\t' ~ "here",
        "line" ~ '\n' ~ "break",
        "backslash " ~ '\\' ~ " slash / question ?",
        "number 5 five",
        "unicode 日 sun",
        "very long 日 sun"
    ];
    string s3 = s1.save;
    assert(s2 == parse!(string[])(s1));
    assert(s1.empty);
    assert(tuple(s2, s3.length) == parse!(string[], string, Yes.doCount)(s3));
}

/// ditto
auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s, dchar lbracket = '[',
    dchar rbracket = ']', dchar comma = ',')
if (isStaticArray!Target && !is(Target == enum) &&
    isExactSomeString!Source)
{
    static if (hasIndirections!Target)
        Target result = Target.init[0].init;
    else
        Target result = void;

    parseCheck!s(lbracket);
    static if (doCount)
        size_t count = 1;
    static if (doCount)
        count += skipWS!(Source, Yes.doCount)(s);
    else
        skipWS!(Source, No.doCount)(s);
    if (s.empty)
        throw convError!(Source, Target)(s);
    if (s.front == rbracket)
    {
        static if (result.length != 0)
            goto Lmanyerr;
        else
        {
            s.popFront();
            static if (doCount)
            {
                ++count;
                return tuple!("data", "count")(result, count);
            }
            else
            {
                return result;
            }
        }
    }
    for (size_t i = 0; ; )
    {
        if (i == result.length)
            goto Lmanyerr;
        static if (doCount)
        {
            auto r = parseElement!(ElementType!Target, Source, Yes.doCount)(s);
            result[i++] = r.data;
            count += r.count;
            count += skipWS!(Source, Yes.doCount)(s);
        }
        else
        {
            auto r = parseElement!(ElementType!Target, Source, No.doCount)(s);
            result[i++] = r;
            skipWS!(Source, No.doCount)(s);
        }
        if (s.empty)
            throw convError!(Source, Target)(s);
        if (s.front != comma)
        {
            if (i != result.length)
                goto Lfewerr;
            break;
        }
        s.popFront();
        static if (doCount)
            ++count;
        static if (doCount)
            count += skipWS!(Source, Yes.doCount)(s);
        else
            skipWS!(Source, No.doCount)(s);
    }
    parseCheck!s(rbracket);
    static if (doCount)
    {
        ++count;
        return tuple!("data", "count")(result, count);
    }
    else
    {
        return result;
    }

Lmanyerr:
    throw parseError(text("Too many elements in input, ", result.length, " elements expected."));
Lfewerr:
    throw parseError(text("Too few elements in input, ", result.length, " elements expected."));
}

@safe pure unittest
{
    import std.exception;

    auto s1 = "[1,2,3,4]";
    auto sa1 = parse!(int[4])(s1);
    assert(sa1 == [1,2,3,4]);
    s1 = "[1,2,3,4]";
    assert(tuple([1,2,3,4], s1.length) == parse!(int[4], string, Yes.doCount)(s1));

    auto s2 = "[[1],[2,3],[4]]";
    auto sa2 = parse!(int[][3])(s2);
    assert(sa2 == [[1],[2,3],[4]]);
    s2 = "[[1],[2,3],[4]]";
    assert(tuple([[1],[2,3],[4]], s2.length) == parse!(int[][3], string, Yes.doCount)(s2));

    auto s3 = "[1,2,3]";
    assertThrown!ConvException(parse!(int[4])(s3));
    assertThrown!ConvException(parse!(int[4], string, Yes.doCount)(s3));

    auto s4 = "[1,2,3,4,5]";
    assertThrown!ConvException(parse!(int[4])(s4));
    assertThrown!ConvException(parse!(int[4], string, Yes.doCount)(s4));
}

/**
 * Parses an associative array from a string given the left bracket (default $(D
 * '[')), right bracket (default `']'`), key-value separator (default $(D
 * ':')), and element seprator (by default `','`).
 *
 * Params:
 *     s = the string to parse
 *     lbracket = the character that starts the associative array
 *     rbracket = the character that ends the associative array
 *     keyval = the character that associates the key with the value
 *     comma = the character that separates the elements of the associative array
 *     doCount = the flag for deciding to report the number of consumed characters
 *
 * Returns:
 $(UL
 *     $(LI An associative array of type `Target` if `doCount` is set to `No.doCount`)
 *     $(LI A `tuple` containing an associative array of type `Target` and a `size_t`
 *     if `doCount` is set to `Yes.doCount`))
 */
auto parse(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s, dchar lbracket = '[',
                             dchar rbracket = ']', dchar keyval = ':', dchar comma = ',')
if (isAssociativeArray!Target && !is(Target == enum) &&
    isSomeString!Source && !is(Source == enum))
{
    alias KeyType = typeof(Target.init.keys[0]);
    alias ValType = typeof(Target.init.values[0]);

    Target result;
    static if (doCount) size_t count;

    parseCheck!s(lbracket);
    static if (doCount)
        count = 1 + skipWS!(Source, Yes.doCount)(s);
    else
        skipWS!(Source, No.doCount)(s);
    if (s.empty)
        throw convError!(Source, Target)(s);
    if (s.front == rbracket)
    {
        s.popFront();
        static if (doCount)
            return tuple!("data", "count")(result, count + 1);
        else
            return result;
    }
    for (;;)
    {
        static if (doCount)
        {
            auto key = parseElement!(KeyType, Source, Yes.doCount)(s);
            count += key.count + skipWS!(Source, Yes.doCount)(s);
            parseCheck!s(keyval);
            count += 1 + skipWS!(Source, Yes.doCount)(s);
            auto val = parseElement!(ValType, Source, Yes.doCount)(s);
            count += val.count + skipWS!(Source, Yes.doCount)(s);
            result[key.data] = val.data;
        }
        else
        {
            auto key = parseElement!(KeyType, Source, No.doCount)(s);
            skipWS!(Source, No.doCount)(s);
            parseCheck!s(keyval);
            skipWS!(Source, No.doCount)(s);
            auto val = parseElement!(ValType, Source, No.doCount)(s);
            skipWS!(Source, No.doCount)(s);
            result[key] = val;
        }
        if (s.empty)
            throw convError!(Source, Target)(s);
        if (s.front != comma)
            break;
        s.popFront();
        static if (doCount)
            count += 1 + skipWS!(Source, Yes.doCount)(s);
        else
            skipWS!(Source, No.doCount)(s);
    }
    parseCheck!s(rbracket);
    static if (doCount)
        return tuple!("data", "count")(result, count + 1);
    else
        return result;
}

///
@safe pure unittest
{
    import std.typecons : Flag, Yes, No, tuple;
    import std.range.primitives : save;
    import std.array : assocArray;
    auto s1 = "[1:10, 2:20, 3:30]";
    auto copyS1 = s1.save;
    auto aa1 = parse!(int[int])(s1);
    assert(aa1 == [1:10, 2:20, 3:30]);
    assert(tuple([1:10, 2:20, 3:30], copyS1.length) == parse!(int[int], string, Yes.doCount)(copyS1));

    auto s2 = `["aaa":10, "bbb":20, "ccc":30]`;
    auto copyS2 = s2.save;
    auto aa2 = parse!(int[string])(s2);
    assert(aa2 == ["aaa":10, "bbb":20, "ccc":30]);
    assert(tuple(["aaa":10, "bbb":20, "ccc":30], copyS2.length) ==
        parse!(int[string], string, Yes.doCount)(copyS2));

    auto s3 = `["aaa":[1], "bbb":[2,3], "ccc":[4,5,6]]`;
    auto copyS3 = s3.save;
    auto aa3 = parse!(int[][string])(s3);
    assert(aa3 == ["aaa":[1], "bbb":[2,3], "ccc":[4,5,6]]);
    assert(tuple(["aaa":[1], "bbb":[2,3], "ccc":[4,5,6]], copyS3.length) ==
        parse!(int[][string], string, Yes.doCount)(copyS3));

    auto s4 = `[]`;
    int[int] emptyAA;
    assert(tuple(emptyAA, s4.length) == parse!(int[int], string, Yes.doCount)(s4));
}

@safe pure unittest
{
    import std.exception;

    //Check proper failure
    auto s = "[1:10, 2:20, 3:30]";
    auto s2 = s.save;
    foreach (i ; 0 .. s.length-1)
    {
        auto ss = s[0 .. i];
        assertThrown!ConvException(parse!(int[int])(ss));
        assertThrown!ConvException(parse!(int[int], string, Yes.doCount)(ss));
    }
    int[int] aa = parse!(int[int])(s);
    auto aa2 = parse!(int[int], string, Yes.doCount)(s2);
    aa  = aa2[0];

}

private auto parseEscape(Source, Flag!"doCount" doCount = No.doCount)(ref Source s)
if (isInputRange!Source && isSomeChar!(ElementType!Source))
{
    parseCheck!s('\\');
    size_t count;
    static if (doCount)
        count = 1;
    if (s.empty)
        throw parseError("Unterminated escape sequence");

    // consumes 1 element from Source
    dchar getHexDigit()(ref Source s_ = s)  // workaround
    {
        import std.ascii : isAlpha, isHexDigit;
        if (s_.empty)
            throw parseError("Unterminated escape sequence");
        s_.popFront();
        if (s_.empty)
            throw parseError("Unterminated escape sequence");
        dchar c = s_.front;
        if (!isHexDigit(c))
            throw parseError("Hex digit is missing");
        return isAlpha(c) ? ((c & ~0x20) - ('A' - 10)) : c - '0';
    }
    // We need to do octals separate, because they need a lookahead to find out,
    // where the escape sequence ends.
    auto first = s.front;
    if (first >= '0' && first <= '7')
    {
        dchar c1 = s.front;
        s.popFront();
        static if (doCount)
            ++count;
        if (s.empty)
        {
            static if (doCount)
            {
                return tuple!("data", "count")(cast (dchar) (c1 - '0'), count);
            }
            else
            {
                return cast (dchar) (c1 - '0');
            }
        }
        dchar c2 = s.front;
        if (c2 < '0' || c2 > '7')
        {
            static if (doCount)
            {
                return tuple!("data", "count")(cast (dchar)(c1 - '0'), count);
            }
            else
            {
                return cast (dchar)(c1 - '0');
            }
        }
        s.popFront();
        static if (doCount)
            ++count;
        dchar c3 = s.front;
        if (c3 < '0' || c3 > '7')
        {
            static if (doCount)
            {
                return tuple!("data", "count")(cast (dchar) (8 * (c1 - '0') + (c2 - '0')), count);
            }
            else
            {
                return cast (dchar) (8 * (c1 - '0') + (c2 - '0'));
            }
        }
        s.popFront();
        static if (doCount)
            ++count;
        if (c1 > '3')
            throw parseError("Octal sequence is larger than \\377");
        static if (doCount)
        {
            return tuple!("data", "count")(cast (dchar) (64 * (c1 - '0') + 8 * (c2 - '0') + (c3 - '0')), count);
        }
        else
        {
            return cast (dchar) (64 * (c1 - '0') + 8 * (c2 - '0') + (c3 - '0'));
        }
    }

    dchar result;

    switch (first)
    {
        case '"':   result = '\"';  break;
        case '\'':  result = '\'';  break;
        case '?':   result = '\?';  break;
        case '\\':  result = '\\';  break;
        case 'a':   result = '\a';  break;
        case 'b':   result = '\b';  break;
        case 'f':   result = '\f';  break;
        case 'n':   result = '\n';  break;
        case 'r':   result = '\r';  break;
        case 't':   result = '\t';  break;
        case 'v':   result = '\v';  break;
        case 'x':
            result  = getHexDigit() << 4;
            result |= getHexDigit();
            static if (doCount)
                count += 2;
            break;
        case 'u':
            result  = getHexDigit() << 12;
            result |= getHexDigit() << 8;
            result |= getHexDigit() << 4;
            result |= getHexDigit();
            static if (doCount)
                count += 4;
            break;
        case 'U':
            result  = getHexDigit() << 28;
            result |= getHexDigit() << 24;
            result |= getHexDigit() << 20;
            result |= getHexDigit() << 16;
            result |= getHexDigit() << 12;
            result |= getHexDigit() << 8;
            result |= getHexDigit() << 4;
            result |= getHexDigit();
            static if (doCount)
                count += 8;
            break;
        default:
            throw parseError("Unknown escape character " ~ to!string(s.front));
    }
    if (s.empty)
        throw parseError("Unterminated escape sequence");

    s.popFront();

    static if (doCount)
    {
        return tuple!("data", "count")(cast (dchar) result, ++count);
    }
    else
    {
        return cast (dchar) result;
    }
}

@safe pure unittest
{
    string[] s1 = [
        `\"`, `\'`, `\?`, `\\`, `\a`, `\b`, `\f`, `\n`, `\r`, `\t`, `\v`, //Normal escapes
        `\141`,
        `\x61`,
        `\u65E5`, `\U00012456`,
         // https://issues.dlang.org/show_bug.cgi?id=9621 (Named Character Entities)
        //`\&amp;`, `\&quot;`,
    ];
    string[] copyS1 = s1 ~ s1[0 .. 0];

    const(dchar)[] s2 = [
        '\"', '\'', '\?', '\\', '\a', '\b', '\f', '\n', '\r', '\t', '\v', //Normal escapes
        '\141',
        '\x61',
        '\u65E5', '\U00012456',
        // https://issues.dlang.org/show_bug.cgi?id=9621 (Named Character Entities)
        //'\&amp;', '\&quot;',
    ];
    foreach (i ; 0 .. s1.length)
    {
        assert(s2[i] == parseEscape(s1[i]));
        assert(s1[i].empty);

        assert(tuple(s2[i], copyS1[i].length) == parseEscape!(string, Yes.doCount)(copyS1[i]));
        assert(copyS1[i].empty);
    }
}

@safe pure unittest
{
    import std.exception;

    string[] ss = [
        `hello!`,  //Not an escape
        `\`,       //Premature termination
        `\/`,      //Not an escape
        `\gggg`,   //Not an escape
        `\xzz`,    //Not an hex
        `\x0`,     //Premature hex end
        `\XB9`,    //Not legal hex syntax
        `\u!!`,    //Not a unicode hex
        `\777`,    //Octal is larger than a byte
        `\80`,     //Wrong digit at beginning of octal
        `\u123`,   //Premature hex end
        `\U123123` //Premature hex end
    ];
    foreach (s ; ss)
    {
        assertThrown!ConvException(parseEscape(s));
        assertThrown!ConvException(parseEscape!(string, Yes.doCount)(s));
    }
}

// Undocumented
auto parseElement(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s)
if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum) &&
    isExactSomeString!Target)
{
    import std.array : appender;
    auto result = appender!Target();

    // parse array of chars
    if (s.empty)
        throw convError!(Source, Target)(s);
    if (s.front == '[')
    {
        return parse!(Target, Source, doCount)(s);
    }

    parseCheck!s('\"');
    size_t count;
    static if (doCount)
        count = 1;
    if (s.empty)
        throw convError!(Source, Target)(s);
    if (s.front == '\"')
    {
        s.popFront();
        static if (doCount)
        {
            count++;
            return tuple!("data", "count")(result.data, count);
        }
        else
        {
            return result.data;
        }
    }
    while (true)
    {
        if (s.empty)
            throw parseError("Unterminated quoted string");
        switch (s.front)
        {
            case '\"':
                s.popFront();
                static if (doCount)
                {
                    count++;
                    return tuple!("data", "count")(result.data, count);
                }
                else
                {
                    return result.data;
                }
            case '\\':
                static if (doCount)
                {
                    auto r = parseEscape!(typeof(s), Yes.doCount)(s);
                    result.put(r[0]);
                    count += r[1];
                }
                else
                {
                    auto r = parseEscape!(typeof(s), No.doCount)(s);
                    result.put(r);
                }
                break;
            default:
                result.put(s.front);
                static if (doCount)
                    count++;
                s.popFront();
                break;
        }
    }
    assert(false, "Unexpected fallthrough");
}

// ditto
auto parseElement(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s)
if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum) &&
    is(CharTypeOf!Target == dchar) && !is(Target == enum))
{
    Unqual!Target c;

    parseCheck!s('\'');
    size_t count;
    static if (doCount)
        count = 1;
    if (s.empty)
        throw convError!(Source, Target)(s);
    static if (doCount)
        count++;
    if (s.front != '\\')
    {
        c = s.front;
        s.popFront();
    }
    else
    {
        static if (doCount)
            c = parseEscape!(typeof(s), Yes.doCount)(s).data;
        else
            c = parseEscape!(typeof(s), No.doCount)(s);
    }
    parseCheck!s('\'');
    static if (doCount)
    {
        count++;
        return tuple!("data", "count")(c, count);
    }
    else
    {
        return c;
    }
}

// ditto
auto parseElement(Target, Source, Flag!"doCount" doCount = No.doCount)(ref Source s)
if (isInputRange!Source && isSomeChar!(ElementType!Source) &&
    !isSomeString!Target && !isSomeChar!Target)
{
    return parse!(Target, Source, doCount)(s);
}

// Use this when parsing a type that will ultimately be appended to a
// string.
package template WideElementType(T)
{
    alias E = ElementType!T;
    static if (isSomeChar!E)
        alias WideElementType = dchar;
    else
        alias WideElementType = E;
}


/***************************************************************
 * Convenience functions for converting one or more arguments
 * of any type into _text (the three character widths).
 */
string text(T...)(T args)
if (T.length > 0) { return textImpl!string(args); }

///ditto
wstring wtext(T...)(T args)
if (T.length > 0) { return textImpl!wstring(args); }

///ditto
dstring dtext(T...)(T args)
if (T.length > 0) { return textImpl!dstring(args); }

///
@safe unittest
{
    assert( text(42, ' ', 1.5, ": xyz") == "42 1.5: xyz"c);
    assert(wtext(42, ' ', 1.5, ": xyz") == "42 1.5: xyz"w);
    assert(dtext(42, ' ', 1.5, ": xyz") == "42 1.5: xyz"d);
}

@safe unittest
{
    char  c = 'h';
    wchar w = '你';
    dchar d = 'እ';

    assert( text(c, "ello", ' ', w, "好 ", d, "ው ሰላም ነው") == "hello 你好 እው ሰላም ነው"c);
    assert(wtext(c, "ello", ' ', w, "好 ", d, "ው ሰላም ነው") == "hello 你好 እው ሰላም ነው"w);
    assert(dtext(c, "ello", ' ', w, "好 ", d, "ው ሰላም ነው") == "hello 你好 እው ሰላም ነው"d);

    string  cs = "今日は";
    wstring ws = "여보세요";
    dstring ds = "Здравствуйте";

    assert( text(cs, ' ', ws, " ", ds) == "今日は 여보세요 Здравствуйте"c);
    assert(wtext(cs, ' ', ws, " ", ds) == "今日は 여보세요 Здравствуйте"w);
    assert(dtext(cs, ' ', ws, " ", ds) == "今日は 여보세요 Здравствуйте"d);
}

// Ensure that ranges are being printed as expected.
@safe unittest
{
    static struct Range
    {
        int counter = 0;

    @safe pure nothrow @nogc:
        bool empty() const => (counter <= 0);
        int front() const => counter;
        void popFront() { --counter; }
    }

    auto m = Range(2);
    assert(text(m) == "[2, 1]");

    const c = Range(3);
    assert(text(c) == "const(Range)(3)");
}

// Ensure that a usage pattern seen in libraries like "unit-threaded" works.
@safe unittest
{
    static final class Foo
    {
        override string toString() const @safe
        {
            return ":-)";
        }
    }

    const c = new Foo();
    assert(text(c) == ":-)");
    assert(text(c, " ") == ":-) ");
}

// Ensure that classes are printed as expected.
@system unittest
{
    import std.string : endsWith, startsWith;

    static final class Bar {}

    // CTFE:                                                         `Bar`
    // Runtime:                         `std.conv.__unittest_L4875_C9.Bar`
    static assert(text(     new       Bar ()     )  ==               "Bar"   );
           assert(text(     new       Bar ()     ).endsWith  (      ".Bar"  ));
    static assert(text("=", new       Bar (), ".")  ==              "=Bar."  );
           assert(text("=", new       Bar (), ".").endsWith  (      ".Bar." ));
    static assert(text(     new const(Bar)()     )  ==         "const(Bar)"  );
           assert(text(     new const(Bar)()     ).startsWith( "const("     ));
           assert(text(     new const(Bar)()     ).endsWith  (      ".Bar)" ));
    static assert(text("=", new const(Bar)(), ".")  ==        "=const(Bar)." );
           assert(text("=", new const(Bar)(), ".").startsWith("=const("     ));
           assert(text("=", new const(Bar)(), ".").endsWith  (      ".Bar)."));
}

// Ensure that various types are printed as expected.
@safe unittest
{
    import std.string : endsWith;

    int dummy;

    static struct Foo {}
    struct Bar { int i() @safe => dummy; }

    static struct Point
    {
        int x;
        int y;
    }

    struct Range
    {
        bool empty()    =>              dummy > 9;
        int  front()    =>              dummy;
        void popFront() => cast(void) ++dummy;
    }

    assert(text(null         ) == "null"     );
    assert(text(null, null   ) == "nullnull" );
    assert(text(0, null, '\0') == "0null\x00");

    assert(text('\r','\n','\t','\x00') == "\r\n\t\0");
    assert(text("\r\n\t\0"           ) == "\r\n\t\0");

    assert(text(       3141,     ) ==    "3141"  );
    assert(text(": ",  3141, '\0') ==  ": 3141\0");
    assert(text(      -3141,     ) ==   "-3141"  );
    assert(text(": ", -3141, '\0') == ": -3141\0");

    () @trusted
    {
        int* pointer = cast(int*) 3141;
        assert(text(       pointer,     ) ==    "C45"  );
        assert(text(": ",  pointer, '\0') ==  ": C45\0");
    }();

    assert(text(      3.1415923,      ) ==   "3.14159"  );
    assert(text(": ", 3.1415923,  '\0') == ": 3.14159\0");
    assert(text(      3.1415923f,     ) ==   "3.14159"  );
    assert(text(": ", 3.1415923f, '\0') == ": 3.14159\0");

    assert(text(       !3141,     ) ==   "false"  );
    assert(text(": ",  !3141, '\0') == ": false\0");
    assert(text(      !!3141,     ) ==   "true"   );
    assert(text(": ", !!3141, '\0') == ": true\0" );

    assert(text(             Foo(),      ) ==         "Foo()"  );
    assert(text(": ",        Foo(),  '\0') ==       ": Foo()\0");
    assert(text(      const(Foo)(),     ) ==   "const(Foo)()"  );
    assert(text(": ", const(Foo)(), '\0') == ": const(Foo)()\0");

    assert(text(             Bar(),      ) ==         "Bar()"  );
    assert(text(": ",        Bar(),  '\0') ==       ": Bar()\0");
    assert(text(      const(Bar)(),     ) ==   "const(Bar)()"  );
    assert(text(": ", const(Bar)(), '\0') == ": const(Bar)()\0");

    assert(text(                 Point(3, 141),     ) ==              "Point(3, 141)"  );
    assert(text(": ",            Point(3, 141), '\0') ==            ": Point(3, 141)\0");
    assert(text(          const(Point)(3, 141),     ) ==       "const(Point)(3, 141)"  );
    assert(text(": ",     const(Point)(3, 141), '\0') ==     ": const(Point)(3, 141)\0");
    assert(text(         shared(Point)(3, 141),     ) ==      "shared(Point)(3, 141)"  );
    assert(text(": ",    shared(Point)(3, 141), '\0') ==    ": shared(Point)(3, 141)\0");
    assert(text(      immutable(Point)(3, 141),     ) ==   "immutable(Point)(3, 141)"  );
    assert(text(": ", immutable(Point)(3, 141), '\0') == ": immutable(Point)(3, 141)\0");

    dummy = 0;
    assert(text(            Range(),      ) ==   "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"  );
    dummy = 0;
    assert(text(": ",       Range(),  '\0') == ": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\0");
    assert(text(      const(Range)(),     ) ==   "const(Range)()"                  );
    assert(text(": ", const(Range)(), '\0') == ": const(Range)()\0"                );

    void function() @safe fn1;
    void delegate() @safe dg1;
    assert(text(fn1) == "null");
    assert(text(dg1) == "void delegate() @safe");

    bool function(bool, int) @safe    fn2;
    bool delegate(bool, int) @safe    dg2;
    bool delegate(bool, int) @system  dg3;
    bool delegate(bool, int) @trusted dg4;
    assert(text(fn2) == "null");
    assert(text(dg2) == "bool delegate(bool, int) @safe");
    assert(text(dg3) == "bool delegate(bool, int) @system");
    assert(text(dg4) == "bool delegate(bool, int) @trusted");
}

/// Convenience functions for writing arguments to an output range as text.
void writeText(Sink, T...)(ref Sink sink, T args)
if (isOutputRange!(Sink, char) && T.length > 0)
{
    sink.writeTextImpl!string(args);
}

/// ditto
void writeWText(Sink, T...)(ref Sink sink, T args)
if (isOutputRange!(Sink, wchar) && T.length > 0)
{
    sink.writeTextImpl!wstring(args);
}

/// ditto
void writeDText(Sink, T...)(ref Sink sink, T args)
if (isOutputRange!(Sink, dchar) && T.length > 0)
{
    sink.writeTextImpl!dstring(args);
}

///
@safe unittest
{
    import std.array : appender;

    auto output = appender!string();
    output.writeText("The answer is ", 42);

    assert(output.data == "The answer is 42");
}

///
@safe unittest
{
    import std.array : appender;

    const color = "red";
    auto output = appender!string();
    output.writeText(i"My favorite color is $(color)");

    assert(output.data == "My favorite color is red");
}

@safe unittest
{
    auto capp = appender!string();
    auto wapp = appender!wstring();
    auto dapp = appender!dstring();

    capp.writeText(42, ' ', 1.5, ": xyz");
    wapp.writeWText(42, ' ', 1.5, ": xyz");
    dapp.writeDText(42, ' ', 1.5, ": xyz");

    assert(capp.data == "42 1.5: xyz"c);
    assert(wapp.data == "42 1.5: xyz"w);
    assert(dapp.data == "42 1.5: xyz"d);
}

// Check range API compliance using OutputRange interface
@system unittest
{
    import std.range.interfaces : OutputRange, outputRangeObject;
    import std.range : nullSink;

    OutputRange!char testOutput = outputRangeObject!char(nullSink);
    testOutput.writeText(42, ' ', 1.5, ": xyz");
}

private S textImpl(S, U...)(U args)
{
    static if (U.length == 0)
    {
        return null;
    }
    else static if (U.length == 1)
    {
        return to!S(args[0]);
    }
    else
    {
        import std.array : appender;
        import std.traits : isSomeChar, isSomeString;

        auto app = appender!S();

        // assume that on average, parameters will have less
        // than 20 elements
        app.reserve(U.length * 20);
        app.writeTextImpl!S(args);
        return app.data;
    }
}

private void writeTextImpl(S, Sink, U...)(ref Sink sink, U args)
if (isSomeString!S && isOutputRange!(Sink, ElementEncodingType!S))
{
    // Must be static foreach because of https://issues.dlang.org/show_bug.cgi?id=21209
    static foreach (arg; args)
    {
        static if (
            isSomeChar!(typeof(arg))
            || isSomeString!(typeof(arg))
            || ( isInputRange!(typeof(arg)) && isSomeChar!(ElementType!(typeof(arg))) )
        )
            put(sink, arg);
        else static if (

            is(immutable typeof(arg) == immutable uint) || is(immutable typeof(arg) == immutable ulong) ||
            is(immutable typeof(arg) == immutable int) || is(immutable typeof(arg) == immutable long)
        )
            // https://issues.dlang.org/show_bug.cgi?id=17712#c15
            put(sink, textImpl!(S)(arg));
        else
            put(sink, to!S(arg));
    }
}


/***************************************************************
The `octal` facility provides a means to declare a number in base 8.
Using `octal!177` or `octal!"177"` for 127 represented in octal
(same as 0177 in C).

The rules for strings are the usual for literals: If it can fit in an
`int`, it is an `int`. Otherwise, it is a `long`. But, if the
user specifically asks for a `long` with the `L` suffix, always
give the `long`. Give an unsigned iff it is asked for with the $(D
U) or `u` suffix. _Octals created from integers preserve the type
of the passed-in integral.

See_Also:
    $(LREF parse) for parsing octal strings at runtime.
 */
template octal(string num)
if (isOctalLiteral(num))
{
    static if ((octalFitsInInt!num && !literalIsLong!num) && !literalIsUnsigned!num)
        enum octal = octal!int(num);
    else static if ((!octalFitsInInt!num || literalIsLong!num) && !literalIsUnsigned!num)
        enum octal = octal!long(num);
    else static if ((octalFitsInInt!num && !literalIsLong!num) && literalIsUnsigned!num)
        enum octal = octal!uint(num);
    else static if ((!octalFitsInInt!(num) || literalIsLong!(num)) && literalIsUnsigned!(num))
        enum octal = octal!ulong(num);
    else
        static assert(false, "Unusable input " ~ num);
}

/// Ditto
template octal(alias decimalInteger)
if (is(typeof(decimalInteger)) && isIntegral!(typeof(decimalInteger)))
{
    enum octal = convertToOctal(decimalInteger);
}

///
@safe unittest
{
    // Same as 0177
    auto a = octal!177;
    // octal is a compile-time device
    enum b = octal!160;
    // Create an unsigned octal
    auto c = octal!"1_000_000u";
    // Leading zeros are allowed when converting from a string
    auto d = octal!"0001_200_000";
}

/*************************************
 * Convert a decimal integer to an octal integer with the same digits.
 * Params:
 *    i = integer to convert
 * Returns:
 *    octal integer with the same type and same digits
 */
private T convertToOctal(T)(T i)
{
    assert((i % 10) < 8);
    return i ? convertToOctal(i / 10) * 8 + i % 10 : 0;
}

/*
    Takes a string, num, which is an octal literal, and returns its
    value, in the type T specified.
*/
private T octal(T)(const string num)
{
    assert(isOctalLiteral(num), num ~ " is not an octal literal");

    T value = 0;

    foreach (const char s; num)
    {
        if (s < '0' || s > '7') // we only care about digits; skip the rest
        // safe to skip - this is checked out in the assert so these
        // are just suffixes
            continue;

        value *= 8;
        value += s - '0';
    }

    return value;
}

@safe unittest
{
    int a = octal!int("10");
    assert(a == 8);

    int b = octal!int("000137");
    assert(b == 95);
}

/*
Take a look at int.max and int.max+1 in octal and the logic for this
function follows directly.
 */
private template octalFitsInInt(string octalNum)
{
    // note it is important to strip the literal of all
    // non-numbers. kill the suffix and underscores lest they mess up
    // the number of digits here that we depend on.
    enum bool octalFitsInInt = strippedOctalLiteral(octalNum).length < 11 ||
        strippedOctalLiteral(octalNum).length == 11 &&
        strippedOctalLiteral(octalNum)[0] == '1';
}

private string strippedOctalLiteral(string original)
{
    string stripped = "";
    bool leading_zeros = true;
    foreach (c; original)
    {
        if (!('0' <= c && c <= '7'))
            continue;
        if (c == '0')
        {
            if (leading_zeros)
                continue;
        }
        else
        {
            leading_zeros = false;
        }
        stripped ~= c;
    }
    if (stripped.length == 0)
    {
        assert(leading_zeros);
        return "0";
    }
    return stripped;
}

@safe unittest
{
    static assert(strippedOctalLiteral("7") == "7");
    static assert(strippedOctalLiteral("123") == "123");
    static assert(strippedOctalLiteral("00123") == "123");
    static assert(strippedOctalLiteral("01230") == "1230");
    static assert(strippedOctalLiteral("0") == "0");
    static assert(strippedOctalLiteral("00_000") == "0");
    static assert(strippedOctalLiteral("000_000_12_300") == "12300");
}

private template literalIsLong(string num)
{
    static if (num.length > 1)
    // can be xxL or xxLu according to spec
        enum literalIsLong = (num[$-1] == 'L' || num[$-2] == 'L');
    else
        enum literalIsLong = false;
}

private template literalIsUnsigned(string num)
{
    static if (num.length > 1)
    // can be xxU or xxUL according to spec
        enum literalIsUnsigned = (num[$-1] == 'u' || num[$-2] == 'u')
            // both cases are allowed too
            || (num[$-1] == 'U' || num[$-2] == 'U');
    else
        enum literalIsUnsigned = false;
}

/*
Returns if the given string is a correctly formatted octal literal.

The format is specified in spec/lex.html. The leading zeros are allowed,
but not required.
 */
@safe pure nothrow @nogc
private bool isOctalLiteral(const string num)
{
    if (num.length == 0)
        return false;

    // Must start with a digit.
    if (num[0] < '0' || num[0] > '7')
        return false;

    foreach (i, c; num)
    {
        if (('0' <= c && c <= '7') || c == '_')  // a legal character
            continue;

        if (i < num.length - 2)
            return false;

        // gotta check for those suffixes
        if (c != 'U' && c != 'u' && c != 'L')
            return false;
        if (i != num.length - 1)
        {
            // if we're not the last one, the next one must
            // also be a suffix to be valid
            char c2 = num[$-1];
            if (c2 != 'U' && c2 != 'u' && c2 != 'L')
                return false; // spam at the end of the string
            if (c2 == c)
                return false; // repeats are disallowed
        }
    }

    return true;
}

@safe unittest
{
    // ensure that you get the right types, even with embedded underscores
    auto w = octal!"100_000_000_000";
    static assert(!is(typeof(w) == int));
    auto w2 = octal!"1_000_000_000";
    static assert(is(typeof(w2) == int));

    static assert(octal!"45" == 37);
    static assert(octal!"0" == 0);
    static assert(octal!"7" == 7);
    static assert(octal!"10" == 8);
    static assert(octal!"666" == 438);
    static assert(octal!"0004001" == 2049);
    static assert(octal!"00" == 0);
    static assert(octal!"0_0" == 0);

    static assert(octal!45 == 37);
    static assert(octal!0 == 0);
    static assert(octal!7 == 7);
    static assert(octal!10 == 8);
    static assert(octal!666 == 438);

    static assert(octal!"66_6" == 438);
    static assert(octal!"0_0_66_6" == 438);

    static assert(octal!2520046213 == 356535435);
    static assert(octal!"2520046213" == 356535435);

    static assert(octal!17777777777 == int.max);

    static assert(!__traits(compiles, octal!823));

    static assert(!__traits(compiles, octal!"823"));

    static assert(!__traits(compiles, octal!"_823"));
    static assert(!__traits(compiles, octal!"spam"));
    static assert(!__traits(compiles, octal!"77%"));

    static assert(is(typeof(octal!"17777777777") == int));
    static assert(octal!"17777777777" == int.max);

    static assert(is(typeof(octal!"20000000000U") == ulong)); // Shouldn't this be uint?
    static assert(octal!"20000000000" == uint(int.max) + 1);

    static assert(is(typeof(octal!"777777777777777777777") == long));
    static assert(octal!"777777777777777777777" == long.max);

    static assert(is(typeof(octal!"1000000000000000000000U") == ulong));
    static assert(octal!"1000000000000000000000" == ulong(long.max) + 1);

    int a;
    long b;

    // biggest value that should fit in an it
    a = octal!"17777777777";
    assert(a == int.max);
    // should not fit in the int
    static assert(!__traits(compiles, a = octal!"20000000000"));
    // ... but should fit in a long
    b = octal!"20000000000";
    assert(b == 1L + int.max);

    b = octal!"1L";
    assert(b == 1);
    b = octal!1L;
    assert(b == 1);
}

// emplace() used to be here but was moved to druntime
public import core.lifetime : emplace;

// https://issues.dlang.org/show_bug.cgi?id=9559
@safe unittest
{
    import std.algorithm.iteration : map;
    import std.array : array;
    import std.typecons : Nullable;
    alias I = Nullable!int;
    auto ints = [0, 1, 2].map!(i => i & 1 ? I.init : I(i))();
    auto asArray = array(ints);
}

@system unittest //http://forum.dlang.org/post/nxbdgtdlmwscocbiypjs@forum.dlang.org
{
    import std.array : array;
    import std.datetime : SysTime, UTC;
    import std.math.traits : isNaN;

    static struct A
    {
        double i;
    }

    static struct B
    {
        invariant()
        {
            if (j == 0)
                assert(a.i.isNaN(), "why is 'j' zero?? and i is not NaN?");
            else
                assert(!a.i.isNaN());
        }
        SysTime when; // comment this line avoid the breakage
        int j;
        A a;
    }

    B b1 = B.init;
    assert(&b1); // verify that default eyes invariants are ok;

    auto b2 = B(SysTime(0, UTC()), 1, A(1));
    assert(&b2);
    auto b3 = B(SysTime(0, UTC()), 1, A(1));
    assert(&b3);

    auto arr = [b2, b3];

    assert(arr[0].j == 1);
    assert(arr[1].j == 1);
    auto a2 = arr.array(); // << bang, invariant is raised, also if b2 and b3 are good
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : map;
    // Check fix for https://issues.dlang.org/show_bug.cgi?id=2971
    assert(equal(map!(to!int)(["42", "34", "345"]), [42, 34, 345]));
}

// Undocumented for the time being
void toTextRange(T, W)(T value, W writer)
if (isIntegral!T && isOutputRange!(W, char))
{
    import core.internal.string : SignedStringBuf, signedToTempString,
                                  UnsignedStringBuf, unsignedToTempString;

    if (value < 0)
    {
        SignedStringBuf buf = void;
        put(writer, signedToTempString(value, buf));
    }
    else
    {
        UnsignedStringBuf buf = void;
        put(writer, unsignedToTempString(value, buf));
    }
}

@safe unittest
{
    import std.array : appender;
    auto result = appender!(char[])();
    toTextRange(-1, result);
    assert(result.data == "-1");
}


/**
    Returns the corresponding _unsigned value for `x` (e.g. if `x` has type
    `int`, it returns $(D cast(uint) x)). The advantage compared to the cast
    is that you do not need to rewrite the cast if `x` later changes type
    (e.g from `int` to `long`).

    Note that the result is always mutable even if the original type was const
    or immutable. In order to retain the constness, use $(REF Unsigned, std,traits).
 */
auto unsigned(T)(T x)
if (isIntegral!T)
{
    return cast() cast(Unsigned!T) x;
}

///
@safe unittest
{
    import std.traits : Unsigned;
    immutable int s = 42;
    auto u1 = unsigned(s); //not qualified
    static assert(is(typeof(u1) == uint));
    Unsigned!(typeof(s)) u2 = unsigned(s); //same qualification
    static assert(is(typeof(u2) == immutable uint));
    immutable u3 = unsigned(s); //explicitly qualified
}

/// Ditto
auto unsigned(T)(T x)
if (isSomeChar!T)
{
    // All characters are unsigned
    static assert(T.min == 0, T.stringof ~ ".min must be zero");
    return cast() x;
}

@safe unittest
{
    static foreach (T; AliasSeq!(byte, ubyte))
    {
        static assert(is(typeof(unsigned(cast(T) 1)) == ubyte));
        static assert(is(typeof(unsigned(cast(const T) 1)) == ubyte));
        static assert(is(typeof(unsigned(cast(immutable T) 1)) == ubyte));
    }

    static foreach (T; AliasSeq!(short, ushort))
    {
        static assert(is(typeof(unsigned(cast(T) 1)) == ushort));
        static assert(is(typeof(unsigned(cast(const T) 1)) == ushort));
        static assert(is(typeof(unsigned(cast(immutable T) 1)) == ushort));
    }

    static foreach (T; AliasSeq!(int, uint))
    {
        static assert(is(typeof(unsigned(cast(T) 1)) == uint));
        static assert(is(typeof(unsigned(cast(const T) 1)) == uint));
        static assert(is(typeof(unsigned(cast(immutable T) 1)) == uint));
    }

    static foreach (T; AliasSeq!(long, ulong))
    {
        static assert(is(typeof(unsigned(cast(T) 1)) == ulong));
        static assert(is(typeof(unsigned(cast(const T) 1)) == ulong));
        static assert(is(typeof(unsigned(cast(immutable T) 1)) == ulong));
    }
}

@safe unittest
{
    static foreach (T; AliasSeq!(char, wchar, dchar))
    {
        static assert(is(typeof(unsigned(cast(T)'A')) == T));
        static assert(is(typeof(unsigned(cast(const T)'A')) == T));
        static assert(is(typeof(unsigned(cast(immutable T)'A')) == T));
    }
}


/**
    Returns the corresponding _signed value for `x` (e.g. if `x` has type
    `uint`, it returns $(D cast(int) x)). The advantage compared to the cast
    is that you do not need to rewrite the cast if `x` later changes type
    (e.g from `uint` to `ulong`).

    Note that the result is always mutable even if the original type was const
    or immutable. In order to retain the constness, use $(REF Signed, std,traits).
 */
auto signed(T)(T x)
if (isIntegral!T)
{
    return cast() cast(Signed!T) x;
}

///
@safe unittest
{
    import std.traits : Signed;

    immutable uint u = 42;
    auto s1 = signed(u); //not qualified
    static assert(is(typeof(s1) == int));
    Signed!(typeof(u)) s2 = signed(u); //same qualification
    static assert(is(typeof(s2) == immutable int));
    immutable s3 = signed(u); //explicitly qualified
}

@system unittest
{
    static foreach (T; AliasSeq!(byte, ubyte))
    {
        static assert(is(typeof(signed(cast(T) 1)) == byte));
        static assert(is(typeof(signed(cast(const T) 1)) == byte));
        static assert(is(typeof(signed(cast(immutable T) 1)) == byte));
    }

    static foreach (T; AliasSeq!(short, ushort))
    {
        static assert(is(typeof(signed(cast(T) 1)) == short));
        static assert(is(typeof(signed(cast(const T) 1)) == short));
        static assert(is(typeof(signed(cast(immutable T) 1)) == short));
    }

    static foreach (T; AliasSeq!(int, uint))
    {
        static assert(is(typeof(signed(cast(T) 1)) == int));
        static assert(is(typeof(signed(cast(const T) 1)) == int));
        static assert(is(typeof(signed(cast(immutable T) 1)) == int));
    }

    static foreach (T; AliasSeq!(long, ulong))
    {
        static assert(is(typeof(signed(cast(T) 1)) == long));
        static assert(is(typeof(signed(cast(const T) 1)) == long));
        static assert(is(typeof(signed(cast(immutable T) 1)) == long));
    }
}

// https://issues.dlang.org/show_bug.cgi?id=10874
@safe unittest
{
    enum Test { a = 0 }
    ulong l = 0;
    auto t = l.to!Test;
}

// asOriginalType
/**
Returns the representation of an enumerated value, i.e. the value converted to
the base type of the enumeration.
*/
OriginalType!E asOriginalType(E)(E value)
if (is(E == enum))
{
    return value;
}

///
@safe unittest
{
    enum A { a = 42 }
    static assert(is(typeof(A.a.asOriginalType) == int));
    assert(A.a.asOriginalType == 42);
    enum B : double { a = 43 }
    static assert(is(typeof(B.a.asOriginalType) == double));
    assert(B.a.asOriginalType == 43);
}

/**
    A wrapper on top of the built-in cast operator that allows one to restrict
    casting of the original type of the value.

    A common issue with using a raw cast is that it may silently continue to
    compile even if the value's type has changed during refactoring,
    which breaks the initial assumption about the cast.

    Params:
        From  = The type to cast from. The programmer must ensure it is legal
                to make this cast.
 */
template castFrom(From)
{
    /**
        Params:
            To    = The type _to cast _to.
            value = The value _to cast. It must be of type `From`,
                    otherwise a compile-time error is emitted.

        Returns:
            the value after the cast, returned by reference if possible.
     */
    auto ref to(To, T)(auto ref T value) @system
    {
        static assert(
            is(From == T),
            "the value to cast is not of specified type '" ~ From.stringof ~
                 "', it is of type '" ~ T.stringof ~ "'"
        );

        static assert(
            is(typeof(cast(To) value)),
            "can't cast from '" ~ From.stringof ~ "' to '" ~ To.stringof ~ "'"
        );

        return cast(To) value;
    }
}

///
@system unittest
{
    // Regular cast, which has been verified to be legal by the programmer:
    {
        long x;
        auto y = cast(int) x;
    }

    // However this will still compile if 'x' is changed to be a pointer:
    {
        long* x;
        auto y = cast(int) x;
    }

    // castFrom provides a more reliable alternative to casting:
    {
        long x;
        auto y = castFrom!long.to!int(x);
    }

    // Changing the type of 'x' will now issue a compiler error,
    // allowing bad casts to be caught before it's too late:
    {
        long* x;
        static assert(
            !__traits(compiles, castFrom!long.to!int(x))
        );

        // if cast is still needed, must be changed to:
        auto y = castFrom!(long*).to!int(x);
    }
}

// https://issues.dlang.org/show_bug.cgi?id=16667
@system unittest
{
    ubyte[] a = ['a', 'b', 'c'];
    assert(castFrom!(ubyte[]).to!(string)(a) == "abc");
}

/**
Check the correctness of a string for `hexString`.
The result is true if and only if the input string is composed of whitespace
characters (\f\n\r\t\v lineSep paraSep nelSep) and
an even number of hexadecimal digits (regardless of the case).
*/
@safe pure @nogc
private bool isHexLiteral(String)(scope const String hexData)
{
    import std.ascii : isHexDigit;
    import std.uni : lineSep, paraSep, nelSep;
    size_t i;
    foreach (const dchar c; hexData)
    {
        switch (c)
        {
            case ' ':
            case '\t':
            case '\v':
            case '\f':
            case '\r':
            case '\n':
            case lineSep:
            case paraSep:
            case nelSep:
                continue;

            default:
                break;
        }
        if (c.isHexDigit)
            ++i;
        else
            return false;
    }
    return !(i & 1);
}

@safe unittest
{
    // test all the hex digits
    static assert( ("0123456789abcdefABCDEF").isHexLiteral);
    // empty or white strings are not valid
    static assert( "\r\n\t".isHexLiteral);
    // but are accepted if the count of hex digits is even
    static assert( "A\r\n\tB".isHexLiteral);
}

@safe unittest
{
    import std.ascii;
    // empty/whites
    static assert( "".isHexLiteral);
    static assert( " \r".isHexLiteral);
    static assert( whitespace.isHexLiteral);
    static assert( ""w.isHexLiteral);
    static assert( " \r"w.isHexLiteral);
    static assert( ""d.isHexLiteral);
    static assert( " \r"d.isHexLiteral);
    static assert( "\u2028\u2029\u0085"d.isHexLiteral);
    // odd x strings
    static assert( !("5" ~ whitespace).isHexLiteral);
    static assert( !"123".isHexLiteral);
    static assert( !"1A3".isHexLiteral);
    static assert( !"1 23".isHexLiteral);
    static assert( !"\r\n\tC".isHexLiteral);
    static assert( !"123"w.isHexLiteral);
    static assert( !"1A3"w.isHexLiteral);
    static assert( !"1 23"w.isHexLiteral);
    static assert( !"\r\n\tC"w.isHexLiteral);
    static assert( !"123"d.isHexLiteral);
    static assert( !"1A3"d.isHexLiteral);
    static assert( !"1 23"d.isHexLiteral);
    static assert( !"\r\n\tC"d.isHexLiteral);
    // even x strings with invalid charset
    static assert( !"12gG".isHexLiteral);
    static assert( !"2A  3q".isHexLiteral);
    static assert( !"12gG"w.isHexLiteral);
    static assert( !"2A  3q"w.isHexLiteral);
    static assert( !"12gG"d.isHexLiteral);
    static assert( !"2A  3q"d.isHexLiteral);
    // valid x strings
    static assert( ("5A" ~ whitespace).isHexLiteral);
    static assert( ("5A 01A C FF de 1b").isHexLiteral);
    static assert( ("0123456789abcdefABCDEF").isHexLiteral);
    static assert( (" 012 34 5 6789 abcd ef\rAB\nCDEF").isHexLiteral);
    static assert( ("5A 01A C FF de 1b"w).isHexLiteral);
    static assert( ("0123456789abcdefABCDEF"w).isHexLiteral);
    static assert( (" 012 34 5 6789 abcd ef\rAB\nCDEF"w).isHexLiteral);
    static assert( ("5A 01A C FF de 1b"d).isHexLiteral);
    static assert( ("0123456789abcdefABCDEF"d).isHexLiteral);
    static assert( (" 012 34 5 6789 abcd ef\rAB\nCDEF"d).isHexLiteral);
    // library version allows what's pointed by https://issues.dlang.org/show_bug.cgi?id=10454
    static assert( ("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF").isHexLiteral);
}

/**
Converts a hex literal to a string at compile time.

Takes a string made of hexadecimal digits and returns
the matching string by converting each pair of digits to a character.
The input string can also include white characters, which can be used
to keep the literal string readable in the source code.

The function is intended to replace the hexadecimal literal strings
starting with `'x'`, which could be removed to simplify the core language.

Params:
    hexData = string to be converted.

Returns:
    a `string`, a `wstring` or a `dstring`, according to the type of hexData.

See_Also:
    Use $(REF fromHexString, std, digest) for run time conversions.
    Note, these functions are not drop-in replacements and have different
    input requirements.
    This template inherits its data syntax from builtin
    $(LINK2 $(ROOT_DIR)spec/lex.html#hex_string, hex strings).
    See $(REF fromHexString, std, digest) for its own respective requirements.
 */
template hexString(string hexData)
if (hexData.isHexLiteral)
{
    enum hexString = mixin(hexToString(hexData));
}

/// ditto
template hexString(wstring hexData)
if (hexData.isHexLiteral)
{
    enum wstring hexString = mixin(hexToString(hexData));
}

/// ditto
template hexString(dstring hexData)
if (hexData.isHexLiteral)
{
    enum dstring hexString = mixin(hexToString(hexData));
}

///
@safe unittest
{
    // conversion at compile time
    auto string1 = hexString!"304A314B";
    assert(string1 == "0J1K");
    auto string2 = hexString!"304A314B"w;
    assert(string2 == "0J1K"w);
    auto string3 = hexString!"304A314B"d;
    assert(string3 == "0J1K"d);
}

@safe nothrow pure private
{
    /* These are meant to be used with CTFE.
     * They cause the instantiations of hexStrLiteral()
     * to be in Phobos, not user code.
     */
    string hexToString(string s)
    {
        return hexStrLiteral(s);
    }

    wstring hexToString(wstring s)
    {
        return hexStrLiteral(s);
    }

    dstring hexToString(dstring s)
    {
        return hexStrLiteral(s);
    }
}

/*
    Turn a hexadecimal string into a regular string literal.
    I.e. "dead beef" is transformed into "\xde\xad\xbe\xef"
    suitable for use in a mixin.
    Params:
        hexData is string, wstring, or dstring and validated by isHexLiteral()
 */
@trusted nothrow pure
private auto hexStrLiteral(String)(scope String hexData)
{
    import std.ascii : isHexDigit;
    alias C = Unqual!(ElementEncodingType!String);    // char, wchar or dchar
    C[] result;
    result.length = 1 + hexData.length * 2 + 1;       // don't forget the " "
    /* Use a pointer because we know it won't overrun,
     * and this will reduce the size of the function substantially
     * by not doing the array bounds checks.
     * This is why this function is @trusted.
     */
    auto r = result.ptr;
    r[0] = '"';
    size_t cnt = 0;
    foreach (c; hexData)
    {
        if (c.isHexDigit)
        {
            if ((cnt & 1) == 0)
            {
                r[1 + cnt]     = '\\';
                r[1 + cnt + 1] = 'x';
                cnt += 2;
            }
            r[1 + cnt] = c;
            ++cnt;
        }
    }
    r[1 + cnt] = '"';
    result.length = 1 + cnt + 1;        // trim off any excess length
    return result;
}


@safe unittest
{
    // compile time
    assert(hexString!"46 47 48 49 4A 4B" == "FGHIJK");
    assert(hexString!"30\r\n\t\f\v31 32 33 32 31 30" == "0123210");
    assert(hexString!"ab cd" == hexString!"ABCD");
}


/**
 * Convert integer to a range of characters.
 * Intended to be lightweight and fast.
 *
 * Params:
 *      radix = 2, 8, 10, 16
 *      Char = character type for output
 *      letterCase = lower for deadbeef, upper for DEADBEEF
 *      value = integer to convert. Can be ubyte, ushort, uint or ulong. If radix
 *              is 10, can also be byte, short, int or long.
 * Returns:
 *      Random access range with slicing and everything
 */

auto toChars(ubyte radix = 10, Char = char, LetterCase letterCase = LetterCase.lower, T)(T value)
    pure nothrow @nogc @safe
if ((radix == 2 || radix == 8 || radix == 10 || radix == 16) &&
        isIntegral!T && (radix == 10 || isUnsigned!T))
{
    alias UT = Unqual!T;

    static if (radix == 10)
    {
        /* uint.max  is 42_9496_7295
         *  int.max  is 21_4748_3647
         * ulong.max is 1844_6744_0737_0955_1615
         *  long.max is  922_3372_0368_5477_5807
         */
        static struct Result
        {
            void initialize(UT value)
            {
                import core.internal.string : signedToTempString, unsignedToTempString;

                char[] t = value < 0
                    ?   signedToTempString!(10, false, char)(value, buf)
                    : unsignedToTempString!(10, false, char)(value, buf);

                lwr = cast(uint) (buf.length - t.length);
                upr = cast(uint) buf.length;
            }

            @property size_t length() { return upr - lwr; }

            alias opDollar = length;

            @property bool empty() { return upr == lwr; }

            @property Char front() { return buf[lwr]; }

            void popFront() { ++lwr; }

            @property Char back() { return buf[upr - 1]; }

            void popBack() { --upr; }

            @property Result save() { return this; }

            Char opIndex(size_t i) { return buf[lwr + i]; }

            Result opSlice(size_t lwr, size_t upr)
            {
                Result result = void;
                result.buf = buf;
                result.lwr = cast(uint)(this.lwr + lwr);
                result.upr = cast(uint)(this.lwr + upr);
                return result;
            }

          private:
            uint lwr = void, upr = void;
            char[(UT.sizeof == 4) ? 10 + isSigned!T : 20] buf = void;
        }

        Result result;
        result.initialize(value);
        return result;
    }
    else
    {
        static if (radix == 2)
            enum SHIFT = 1;
        else static if (radix == 8)
            enum SHIFT = 3;
        else static if (radix == 16)
            enum SHIFT = 4;
        else
            static assert(false, "radix must be 2, 8, 10, or 16");
        static struct Result
        {
            this(UT value)
            {
                this.value = value;

                ubyte len = 1;
                while (value >>>= SHIFT)
                   ++len;
                this.len = len;
            }

            @property size_t length() { return len; }

            @property bool empty() { return len == 0; }

            @property Char front() { return opIndex(0); }

            void popFront() { --len; }

            @property Char back() { return opIndex(len - 1); }

            void popBack()
            {
                value >>>= SHIFT;
                --len;
            }

            @property Result save() { return this; }

            Char opIndex(size_t i)
            {
                Char c = (value >>> ((len - i - 1) * SHIFT)) & ((1 << SHIFT) - 1);
                return cast(Char)((radix < 10 || c < 10) ? c + '0'
                                                         : (letterCase == LetterCase.upper ? c + 'A' - 10
                                                                                           : c + 'a' - 10));
            }

            Result opSlice(size_t lwr, size_t upr)
            {
                Result result = void;
                result.value = value >>> ((len - upr) * SHIFT);
                result.len = cast(ubyte)(upr - lwr);
                return result;
            }

          private:
            UT value;
            ubyte len;
        }

        return Result(value);
    }
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;

    assert(toChars(1).equal("1"));
    assert(toChars(1_000_000).equal("1000000"));

    assert(toChars!(2)(2U).equal("10"));
    assert(toChars!(16)(255U).equal("ff"));
    assert(toChars!(16, char, LetterCase.upper)(255U).equal("FF"));
}


@safe unittest
{
    import std.array;
    import std.range;

    assert(toChars(123) == toChars(123));

    {
        assert(toChars!2(ubyte(0)).array == "0");
        assert(toChars!2(ushort(0)).array == "0");
        assert(toChars!2(0u).array == "0");
        assert(toChars!2(0Lu).array == "0");
        assert(toChars!2(ubyte(1)).array == "1");
        assert(toChars!2(ushort(1)).array == "1");
        assert(toChars!2(1u).array == "1");
        assert(toChars!2(1Lu).array == "1");

        auto r = toChars!2(2u);
        assert(r.length == 2);
        assert(r[0] == '1');
        assert(r[1 .. 2].array == "0");
        auto s = r.save;
        assert(r.array == "10");
        assert(s.retro.array == "01");
    }
    {
        assert(toChars!8(ubyte(0)).array == "0");
        assert(toChars!8(ushort(0)).array == "0");
        assert(toChars!8(0u).array == "0");
        assert(toChars!8(0Lu).array == "0");
        assert(toChars!8(1u).array == "1");
        assert(toChars!8(1234567Lu).array == "4553207");
        assert(toChars!8(ubyte.max).array == "377");
        assert(toChars!8(ushort.max).array == "177777");

        auto r = toChars!8(8u);
        assert(r.length == 2);
        assert(r[0] == '1');
        assert(r[1 .. 2].array == "0");
        auto s = r.save;
        assert(r.array == "10");
        assert(s.retro.array == "01");
    }
    {
        assert(toChars!10(ubyte(0)).array == "0");
        assert(toChars!10(ushort(0)).array == "0");
        assert(toChars!10(0u).array == "0");
        assert(toChars!10(0Lu).array == "0");
        assert(toChars!10(1u).array == "1");
        assert(toChars!10(1234567Lu).array == "1234567");
        assert(toChars!10(ubyte.max).array == "255");
        assert(toChars!10(ushort.max).array == "65535");
        assert(toChars!10(uint.max).array == "4294967295");
        assert(toChars!10(ulong.max).array == "18446744073709551615");

        auto r = toChars(10u);
        assert(r.length == 2);
        assert(r[0] == '1');
        assert(r[1 .. 2].array == "0");
        auto s = r.save;
        assert(r.array == "10");
        assert(s.retro.array == "01");
    }
    {
        assert(toChars!10(0).array == "0");
        assert(toChars!10(0L).array == "0");
        assert(toChars!10(1).array == "1");
        assert(toChars!10(1234567L).array == "1234567");
        assert(toChars!10(byte.max).array == "127");
        assert(toChars!10(short.max).array == "32767");
        assert(toChars!10(int.max).array == "2147483647");
        assert(toChars!10(long.max).array == "9223372036854775807");
        assert(toChars!10(-byte.max).array == "-127");
        assert(toChars!10(-short.max).array == "-32767");
        assert(toChars!10(-int.max).array == "-2147483647");
        assert(toChars!10(-long.max).array == "-9223372036854775807");
        assert(toChars!10(byte.min).array == "-128");
        assert(toChars!10(short.min).array == "-32768");
        assert(toChars!10(int.min).array == "-2147483648");
        assert(toChars!10(long.min).array == "-9223372036854775808");

        auto r = toChars!10(10);
        assert(r.length == 2);
        assert(r[0] == '1');
        assert(r[1 .. 2].array == "0");
        auto s = r.save;
        assert(r.array == "10");
        assert(s.retro.array == "01");
    }
    {
        assert(toChars!(16)(0u).array == "0");
        assert(toChars!(16)(0Lu).array == "0");
        assert(toChars!(16)(10u).array == "a");
        assert(toChars!(16, char, LetterCase.upper)(0x12AF34567Lu).array == "12AF34567");
        assert(toChars!(16)(ubyte(0)).array == "0");
        assert(toChars!(16)(ushort(0)).array == "0");
        assert(toChars!(16)(ubyte.max).array == "ff");
        assert(toChars!(16)(ushort.max).array == "ffff");

        auto r = toChars!(16)(16u);
        assert(r.length == 2);
        assert(r[0] == '1');
        assert(r[1 .. 2].array == "0");
        auto s = r.save;
        assert(r.array == "10");
        assert(s.retro.array == "01");
    }
}

@safe unittest // opSlice (https://issues.dlang.org/show_bug.cgi?id=16192)
{
    import std.meta : AliasSeq;

    static struct Test { ubyte radix; uint number; }

    alias tests = AliasSeq!(
        Test(2, 0b1_0110_0111u),
        Test(2, 0b10_1100_1110u),
        Test(8, octal!123456701u),
        Test(8, octal!1234567012u),
        Test(10, 123456789u),
        Test(10, 1234567890u),
        Test(16, 0x789ABCDu),
        Test(16, 0x789ABCDEu),
    );

    foreach (test; tests)
    {
        enum ubyte radix = test.radix;
        auto original = toChars!radix(test.number);

        // opSlice vs popFront
        auto r = original.save;
        size_t i = 0;
        for (; !r.empty; r.popFront(), ++i)
        {
            assert(original[i .. original.length].tupleof == r.tupleof);
                // tupleof is used to work around https://issues.dlang.org/show_bug.cgi?id=16216.
        }

        // opSlice vs popBack
        r = original.save;
        i = 0;
        for (; !r.empty; r.popBack(), ++i)
        {
            assert(original[0 .. original.length - i].tupleof == r.tupleof);
        }

        // opSlice vs both popFront and popBack
        r = original.save;
        i = 0;
        for (; r.length >= 2; r.popFront(), r.popBack(), ++i)
        {
            assert(original[i .. original.length - i].tupleof == r.tupleof);
        }
    }
}

// Converts an unsigned integer to a compile-time string constant.
package enum toCtString(ulong n) = n.stringof[0 .. $ - "LU".length];

// Check that .stringof does what we expect, since it's not guaranteed by the
// language spec.
@safe /*@betterC*/ unittest
{
    assert(toCtString!0 == "0");
    assert(toCtString!123456 == "123456");
}

/**
 * Takes the raw bits of a value and reinterprets them as a different type.
 *
 * Params:
 *   T = the new type.
 *   value = the value to reinterpret.
 *
 * Returns: a reference to the reinterpreted value.
 */
pragma(inline, true)
ref T bitCast(T, S)(ref S value)
if (T.sizeof <= S.sizeof)
{
    return *cast(T*) &value;
}

///
@safe unittest
{
    uint n = 0xDEADBEEF;

    version (LittleEndian)
        assert(n.bitCast!(ubyte[4]) == [0xEF, 0xBE, 0xAD, 0xDE]);
    version (BigEndian)
        assert(n.bitCast!(ubyte[4]) == [0xDE, 0xAD, 0xBE, 0xEF]);
}

// Sizes must be compatible
@safe unittest
{
    uint n;

    assert(!__traits(compiles, n.bitCast!ulong));
}
