// 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)
))
$(TR $(TD Strings) $(TD
        $(LREF text)
        $(LREF wtext)
        $(LREF dtext)
        $(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);
}

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

    if (source.empty)
        msg = text("Unexpected end of input when converting from type " ~ S.stringof ~ " base ", radix,
                " to type " ~ T.stringof);
    else
        msg = text("Unexpected '", source.front,
            "' when converting from type " ~ S.stringof ~ " base ", radix,
            " 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 = isImplicitlyConvertible!(S, T) &&
                              is(S == enum) && isExactSomeString!T;
    }
    template isNullToStr(S, T)
    {
        enum isNullToStr = isImplicitlyConvertible!(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 issue 6175
    T to(S)(ref S arg)
        if (isStaticArray!S)
    {
        return toImpl!T(arg);
    }

    // Fix issue 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 the 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");
}

// Tests for issue 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 issue 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 issue 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 issue 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();
                }
            }
        }
    }
}

/**
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 (isImplicitlyConvertible!(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 (!isImplicitlyConvertible!(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 (!isImplicitlyConvertible!(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 (!isImplicitlyConvertible!(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 (!isImplicitlyConvertible!(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)
    {
        throw new ConvException("Cannot convert object of static type "
                ~S.classinfo.name~" and dynamic type "~value.classinfo.name
                ~" to type "~T.classinfo.name);
    }
    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 (isImplicitlyConvertible!(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 (!(isImplicitlyConvertible!(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
        return toImpl!(T, S)(value, 10);
    }
    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 (!(isImplicitlyConvertible!(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 issue 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 (!isImplicitlyConvertible!(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 (!isImplicitlyConvertible!(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 (!isImplicitlyConvertible!(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 : 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.0 + 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.0 + 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.0 + 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
    {
        // AllInts[0 .. $ - 1] should be AllInts
        // @@@ BUG IN COMPILER @@@
        foreach (Integral; AllInts[0 .. $ - 1])
        {
            foreach (Floating; AllFloats)
            {
                testFloatingToIntegral!(Floating, Integral)();
            }
        }
    }
    // test conversion integral => floating
    {
        foreach (Integral; AllInts[0 .. $ - 1])
        {
            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))) &&
    // issue 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);
}

/**
The `parse` family of functions works quite like the `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 converts a character input range to a `bool`.

Params:
    Target = the 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 (isInputRange!Source &&
    isSomeChar!(ElementType!Source) &&
    is(immutable Target == immutable bool))
{
    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 a character $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
to an integral value.

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 (isSomeChar!(ElementType!Source) &&
    isIntegral!Target && !is(Target == enum))
{
    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;
        }

        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 '+':
                    ++count;
                    source.popFront();

                    if (source.empty)
                        goto Lerr;

                    c = source.front;

                    break;

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

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

    // parse only accepts lvalues
    static assert(!__traits(compiles, parse!int("123")));
}

///
@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 (isSomeChar!(ElementType!Source) &&
    isIntegral!Target && !is(Target == enum))
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;
    }

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

/**
 * Takes a string representing an `enum` type and returns that type.
 *
 * 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 (isSomeString!Source && !is(Source == enum) &&
    is(Target == 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 character range to a floating point number.
 *
 * 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 (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum) &&
    isFloatingPoint!Target && !is(Target == 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;
        ++count;
        p.popFront();
        enforce(!p.empty, bailOut());
        if (toLower(p.front) == 'i')
            goto case 'i';
        break;
    case '+':
        ++count;
        p.popFront();
        enforce(!p.empty, bailOut());
        break;
    case 'i': case 'I':
        // inf
        ++count;
        p.popFront();
        enforce(!p.empty && toUpper(p.front) == 'N',
               bailOut("error converting input to floating point"));
        ++count;
        p.popFront();
        enforce(!p.empty && toUpper(p.front) == 'F',
               bailOut("error converting input to floating point"));
        // skip past the last 'f'
        ++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)
    {
        ++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)
        {
            ++count;
            p.popFront();
        }
    }
    else if (toLower(p.front) == 'n')
    {
        // nan
        ++count;
        p.popFront();
        enforce(!p.empty && toUpper(p.front) == 'A',
               bailOut("error converting input to floating point"));
        ++count;
        p.popFront();
        enforce(!p.empty && toUpper(p.front) == 'N',
               bailOut("error converting input to floating point"));
        // skip past the last 'n'
        ++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;
                ++count;
                p.popFront();
                if (p.empty)
                    break;
                i = p.front;
                if (i == '_')
                {
                    ++count;
                    p.popFront();
                    if (p.empty)
                        break;
                    i = p.front;
                }
            }
            if (i == '.' && !dot)
            {
                ++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;

        ++count;
        p.popFront();
        enforce(!p.empty, new ConvException("Unexpected end of input"));
        switch (p.front)
        {
            case '-':    sexp++;
                         goto case;
            case '+':    ++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';
            }
            ++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 : 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 : 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 : 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));
}

/**
Parsing one character off a range returns the first element and calls `popFront`.

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 (isSomeString!Source && !is(Source == enum) &&
    staticIndexOf!(immutable Target, immutable dchar, immutable ElementEncodingType!Source) >= 0)
{
    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 (!isSomeString!Source && isInputRange!Source && isSomeChar!(ElementType!Source) &&
    isSomeChar!Target && Target.sizeof >= ElementType!Source.sizeof && !is(Target == enum))
{
    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);
}

/**
Parsing a character range to `typeof(null)` returns `null` 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 (isInputRange!Source &&
    isSomeChar!(ElementType!Source) &&
    is(immutable Target == immutable typeof(null)))
{
    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 (isSomeString!Source && !is(Source == enum) &&
    isDynamicArray!Target && !is(Target == enum))
{
    import std.array : appender;

    auto result = appender!Target();

    parseCheck!s(lbracket);
    size_t count = 1 + skipWS!(Source, Yes.doCount)(s);
    if (s.empty)
        throw convError!(Source, Target)(s);
    if (s.front == rbracket)
    {
        s.popFront();
        static if (doCount)
        {
            return tuple!("data", "count")(result.data, ++count);
        }
        else
        {
            return result.data;
        }
    }
    for (;; s.popFront(), count += 1 + skipWS!(Source, Yes.doCount)(s))
    {
        if (!s.empty && s.front == rbracket)
            break;
        auto r = parseElement!(WideElementType!Target, Source, Yes.doCount)(s);
        result ~= r.data;
        count += r.count + skipWS!(Source, Yes.doCount)(s);
        if (s.empty)
            throw convError!(Source, Target)(s);
        if (s.front != comma)
            break;
    }
    parseCheck!s(rbracket);
    static if (doCount)
    {
        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 (isExactSomeString!Source &&
    isStaticArray!Target && !is(Target == enum))
{
    static if (hasIndirections!Target)
        Target result = Target.init[0].init;
    else
        Target result = void;

    parseCheck!s(lbracket);
    size_t count = 1 + skipWS!(Source, Yes.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)
            {
                return tuple!("data", "count")(result, ++count);
            }
            else
            {
                return result;
            }
        }
    }
    for (size_t i = 0; ; s.popFront(), count += 1 + skipWS!(Source, Yes.doCount)(s))
    {
        if (i == result.length)
            goto Lmanyerr;
        auto r = parseElement!(ElementType!Target, Source, Yes.doCount)(s);
        result[i++] = r.data;
        count += r.count + skipWS!(Source, Yes.doCount)(s);
        if (s.empty)
            throw convError!(Source, Target)(s);
        if (s.front != comma)
        {
            if (i != result.length)
                goto Lfewerr;
            break;
        }
    }
    parseCheck!s(rbracket);
    static if (doCount)
    {
        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 (isSomeString!Source && !is(Source == enum) &&
    isAssociativeArray!Target && !is(Target == enum))
{
    alias KeyType = typeof(Target.init.keys[0]);
    alias ValType = typeof(Target.init.values[0]);

    Target result;

    parseCheck!s(lbracket);
    size_t count = 1 + skipWS!(Source, Yes.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);
        }
        else
        {
            return result;
        }
    }
    for (;; s.popFront(), count += 1 + skipWS!(Source, Yes.doCount)(s))
    {
        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;
        if (s.empty)
            throw convError!(Source, Target)(s);
        if (s.front != comma)
            break;
    }
    parseCheck!s(rbracket);
    static if (doCount)
    {
        return tuple!("data", "count")(result, ++count);
    }
    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 = 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;
        ++count;
        s.popFront();
        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');
            }
        }
        ++count;
        s.popFront();
        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'));
            }
        }
        ++count;
        s.popFront();
        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();
            count += 2;
            break;
        case 'u':
            result  = getHexDigit() << 12;
            result |= getHexDigit() << 8;
            result |= getHexDigit() << 4;
            result |= getHexDigit();
            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();
            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 = 1;
    if (s.empty)
        throw convError!(Source, Target)(s);
    if (s.front == '\"')
    {
        s.popFront();
        static if (doCount)
        {
            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)
                {
                    return tuple!("data", "count")(result.data, ++count);
                }
                else
                {
                    return result.data;
                }
            case '\\':
                auto r = parseEscape!(typeof(s), Yes.doCount)(s);
                result.put(r[0]);
                count += r[1];
                break;
            default:
                result.put(s.front);
                ++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 = 1;
    if (s.empty)
        throw convError!(Source, Target)(s);
    ++count; // for the following if-else sequence
    if (s.front != '\\')
    {
        c = s.front;
        s.popFront();
    }
    else
        c = parseEscape(s);
    parseCheck!s('\'');
    static if (doCount)
    {
        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);
}

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);
        // 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))) )
            )
                app.put(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
                app.put(textImpl!(S)(arg));
            else
                app.put(to!S(arg));
        }

        return app.data;
    }
}


/***************************************************************
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 = octal!(typeof(decimalInteger))(to!string(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";
}

/*
    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(Unqual!(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(Unqual!T) 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(Unqual!(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 issue 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.
 */
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 uint or ulong. If radix is 10, can also be
 *              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) &&
    (is(immutable T == immutable uint) || is(immutable T == immutable ulong) ||
    radix == 10 && (is(immutable T == immutable int) || is(immutable T == immutable long))))
{
    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)
            {
                bool neg = false;
                if (value < 10)
                {
                    if (value >= 0)
                    {
                        lwr = 0;
                        upr = 1;
                        buf[0] = cast(char)(cast(uint) value + '0');
                        return;
                    }
                    value = -value;
                    neg = true;
                }
                auto i = cast(uint) buf.length - 1;
                while (cast(Unsigned!UT) value >= 10)
                {
                    buf[i] = cast(ubyte)('0' + cast(Unsigned!UT) value % 10);
                    value = unsigned(value) / 10;
                    --i;
                }
                buf[i] = cast(char)(cast(uint) value + '0');
                if (neg)
                {
                    buf[i - 1] = '-';
                    --i;
                }
                lwr = i;
                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(0u).array == "0");
        assert(toChars!2(0Lu).array == "0");
        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(0u).array == "0");
        assert(toChars!8(0Lu).array == "0");
        assert(toChars!8(1u).array == "1");
        assert(toChars!8(1234567Lu).array == "4553207");

        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(0u).array == "0");
        assert(toChars!10(0Lu).array == "0");
        assert(toChars!10(1u).array == "1");
        assert(toChars!10(1234567Lu).array == "1234567");
        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(int.max).array == "2147483647");
        assert(toChars!10(long.max).array == "9223372036854775807");
        assert(toChars!10(-int.max).array == "-2147483647");
        assert(toChars!10(-long.max).array == "-9223372036854775807");
        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");

        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 (issue 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 issue 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");
}
