PageRenderTime 423ms CodeModel.GetById 35ms app.highlight 354ms RepoModel.GetById 1ms app.codeStats 1ms

/std/conv.d

http://github.com/jcd/phobos
D | 4888 lines | 3813 code | 448 blank | 627 comment | 824 complexity | 9f8975efc579f42aff691130644fc5ba MD5 | raw file
   1// Written in the D programming language.
   2
   3/**
   4A one-stop shop for converting values from one type to another.
   5
   6Copyright: Copyright Digital Mars 2007-.
   7
   8License:   $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
   9
  10Authors:   $(WEB digitalmars.com, Walter Bright),
  11           $(WEB erdani.org, Andrei Alexandrescu),
  12           Shin Fujishiro,
  13           Adam D. Ruppe,
  14           Kenji Hara
  15
  16Source:    $(PHOBOSSRC std/_conv.d)
  17
  18Macros:
  19WIKI = Phobos/StdConv
  20
  21*/
  22module std.conv;
  23
  24import core.stdc.string;
  25import std.algorithm, std.array, std.ascii, std.exception, std.range,
  26    std.string, std.traits, std.typecons, std.typetuple, std.uni,
  27    std.utf;
  28import std.format;
  29
  30//debug=conv;           // uncomment to turn on debugging printf's
  31
  32/* ************* Exceptions *************** */
  33
  34/**
  35 * Thrown on conversion errors.
  36 */
  37class ConvException : Exception
  38{
  39    @safe pure nothrow
  40    this(string s, string fn = __FILE__, size_t ln = __LINE__)
  41    {
  42        super(s, fn, ln);
  43    }
  44}
  45
  46private string convError_unexpected(S)(S source)
  47{
  48    return source.empty ? "end of input" : text("'", source.front, "'");
  49}
  50
  51private auto convError(S, T)(S source, string fn = __FILE__, size_t ln = __LINE__)
  52{
  53    return new ConvException(
  54        text("Unexpected ", convError_unexpected(source),
  55             " when converting from type "~S.stringof~" to type "~T.stringof),
  56        fn, ln);
  57}
  58
  59private auto convError(S, T)(S source, int radix, string fn = __FILE__, size_t ln = __LINE__)
  60{
  61    return new ConvException(
  62        text("Unexpected ", convError_unexpected(source),
  63             " when converting from type "~S.stringof~" base ", radix,
  64             " to type "~T.stringof),
  65        fn, ln);
  66}
  67
  68@safe pure/* nothrow*/  // lazy parameter bug
  69private auto parseError(lazy string msg, string fn = __FILE__, size_t ln = __LINE__)
  70{
  71    return new ConvException(text("Can't parse string: ", msg), fn, ln);
  72}
  73
  74private void parseCheck(alias source)(dchar c, string fn = __FILE__, size_t ln = __LINE__)
  75{
  76    if (source.empty)
  77        throw parseError(text("unexpected end of input when expecting", "\"", c, "\""));
  78    if (source.front != c)
  79        throw parseError(text("\"", c, "\" is missing"), fn, ln);
  80    source.popFront();
  81}
  82
  83private
  84{
  85    template isImaginary(T)
  86    {
  87        enum bool isImaginary = staticIndexOf!(Unqual!T,
  88                ifloat, idouble, ireal) >= 0;
  89    }
  90    template isComplex(T)
  91    {
  92        enum bool isComplex = staticIndexOf!(Unqual!T,
  93                cfloat, cdouble, creal) >= 0;
  94    }
  95    template isNarrowInteger(T)
  96    {
  97        enum bool isNarrowInteger = staticIndexOf!(Unqual!T,
  98                byte, ubyte, short, ushort) >= 0;
  99    }
 100
 101    T toStr(T, S)(S src)
 102        if (isSomeString!T)
 103    {
 104        import std.format : FormatSpec, formatValue;
 105
 106        auto w = appender!T();
 107        FormatSpec!(ElementEncodingType!T) f;
 108        formatValue(w, src, f);
 109        return w.data;
 110    }
 111
 112    template isExactSomeString(T)
 113    {
 114        enum isExactSomeString = isSomeString!T && !is(T == enum);
 115    }
 116
 117    template isEnumStrToStr(S, T)
 118    {
 119        enum isEnumStrToStr = isImplicitlyConvertible!(S, T) &&
 120                              is(S == enum) && isExactSomeString!T;
 121    }
 122    template isNullToStr(S, T)
 123    {
 124        enum isNullToStr = isImplicitlyConvertible!(S, T) &&
 125                           (is(Unqual!S == typeof(null))) && isExactSomeString!T;
 126    }
 127
 128    template isRawStaticArray(T, A...)
 129    {
 130        enum isRawStaticArray =
 131            A.length == 0 &&
 132            isStaticArray!T &&
 133            !is(T == class) &&
 134            !is(T == interface) &&
 135            !is(T == struct) &&
 136            !is(T == union);
 137    }
 138}
 139
 140/**
 141 * Thrown on conversion overflow errors.
 142 */
 143class ConvOverflowException : ConvException
 144{
 145    @safe pure nothrow
 146    this(string s, string fn = __FILE__, size_t ln = __LINE__)
 147    {
 148        super(s, fn, ln);
 149    }
 150}
 151
 152/**
 153
 154The $(D_PARAM to) family of functions converts a value from type
 155$(D_PARAM Source) to type $(D_PARAM Target). The source type is
 156deduced and the target type must be specified, for example the
 157expression $(D_PARAM to!int(42.0)) converts the number 42 from
 158$(D_PARAM double) to $(D_PARAM int). The conversion is "safe", i.e.,
 159it checks for overflow; $(D_PARAM to!int(4.2e10)) would throw the
 160$(D_PARAM ConvOverflowException) exception. Overflow checks are only
 161inserted when necessary, e.g., $(D_PARAM to!double(42)) does not do
 162any checking because any int fits in a double.
 163
 164Converting a value to its own type (useful mostly for generic code)
 165simply returns its argument.
 166
 167Example:
 168-------------------------
 169int a = 42;
 170auto b = to!int(a); // b is int with value 42
 171auto c = to!double(3.14); // c is double with value 3.14
 172-------------------------
 173
 174Converting among numeric types is a safe way to cast them around.
 175
 176Conversions from floating-point types to integral types allow loss of
 177precision (the fractional part of a floating-point number). The
 178conversion is truncating towards zero, the same way a cast would
 179truncate. (To round a floating point value when casting to an
 180integral, use $(D_PARAM roundTo).)
 181
 182Examples:
 183-------------------------
 184int a = 420;
 185auto b = to!long(a); // same as long b = a;
 186auto c = to!byte(a / 10); // fine, c = 42
 187auto d = to!byte(a); // throw ConvOverflowException
 188double e = 4.2e6;
 189auto f = to!int(e); // f == 4200000
 190e = -3.14;
 191auto g = to!uint(e); // fails: floating-to-integral negative overflow
 192e = 3.14;
 193auto h = to!uint(e); // h = 3
 194e = 3.99;
 195h = to!uint(a); // h = 3
 196e = -3.99;
 197f = to!int(a); // f = -3
 198-------------------------
 199
 200Conversions from integral types to floating-point types always
 201succeed, but might lose accuracy. The largest integers with a
 202predecessor representable in floating-point format are 2^24-1 for
 203float, 2^53-1 for double, and 2^64-1 for $(D_PARAM real) (when
 204$(D_PARAM real) is 80-bit, e.g. on Intel machines).
 205
 206Example:
 207-------------------------
 208int a = 16_777_215; // 2^24 - 1, largest proper integer representable as float
 209assert(to!int(to!float(a)) == a);
 210assert(to!int(to!float(-a)) == -a);
 211a += 2;
 212assert(to!int(to!float(a)) == a); // fails!
 213-------------------------
 214
 215Conversions from string to numeric types differ from the C equivalents
 216$(D_PARAM atoi()) and $(D_PARAM atol()) by checking for overflow and
 217not allowing whitespace.
 218
 219For conversion of strings to signed types, the grammar recognized is:
 220<pre>
 221$(I Integer): $(I Sign UnsignedInteger)
 222$(I UnsignedInteger)
 223$(I Sign):
 224    $(B +)
 225    $(B -)
 226</pre>
 227
 228For conversion to unsigned types, the grammar recognized is:
 229<pre>
 230$(I UnsignedInteger):
 231    $(I DecimalDigit)
 232    $(I DecimalDigit) $(I UnsignedInteger)
 233</pre>
 234
 235Converting an array to another array type works by converting each
 236element in turn. Associative arrays can be converted to associative
 237arrays as long as keys and values can in turn be converted.
 238
 239Example:
 240-------------------------
 241int[] a = ([1, 2, 3]).dup;
 242auto b = to!(float[])(a);
 243assert(b == [1.0f, 2, 3]);
 244string str = "1 2 3 4 5 6";
 245auto numbers = to!(double[])(split(str));
 246assert(numbers == [1.0, 2, 3, 4, 5, 6]);
 247int[string] c;
 248c["a"] = 1;
 249c["b"] = 2;
 250auto d = to!(double[wstring])(c);
 251assert(d["a"w] == 1 && d["b"w] == 2);
 252-------------------------
 253
 254Conversions operate transitively, meaning that they work on arrays and
 255associative arrays of any complexity:
 256
 257-------------------------
 258int[string][double[int[]]] a;
 259...
 260auto b = to!(short[wstring][string[double[]]])(a);
 261-------------------------
 262
 263This conversion works because $(D_PARAM to!short) applies to an
 264$(D_PARAM int), $(D_PARAM to!wstring) applies to a $(D_PARAM
 265string), $(D_PARAM to!string) applies to a $(D_PARAM double), and
 266$(D_PARAM to!(double[])) applies to an $(D_PARAM int[]). The
 267conversion might throw an exception because $(D_PARAM to!short)
 268might fail the range check.
 269
 270 */
 271
 272/**
 273   Entry point that dispatches to the appropriate conversion
 274   primitive. Client code normally calls $(D _to!TargetType(value))
 275   (and not some variant of $(D toImpl)).
 276 */
 277template to(T)
 278{
 279    T to(A...)(A args)
 280        if (!isRawStaticArray!A)
 281    {
 282        return toImpl!T(args);
 283    }
 284
 285    // Fix issue 6175
 286    T to(S)(ref S arg)
 287        if (isRawStaticArray!S)
 288    {
 289        return toImpl!T(arg);
 290    }
 291}
 292
 293// Tests for issue 6175
 294@safe pure unittest
 295{
 296    char[9] sarr = "blablabla";
 297    auto darr = to!(char[])(sarr);
 298    assert(sarr.ptr == darr.ptr);
 299    assert(sarr.length == darr.length);
 300}
 301
 302// Tests for issue 7348
 303@safe pure unittest
 304{
 305    assert(to!string(null) == "null");
 306    assert(text(null) == "null");
 307}
 308
 309// Tests for issue 11390
 310@safe pure unittest
 311{
 312    const(typeof(null)) ctn;
 313    immutable(typeof(null)) itn;
 314    assert(to!string(ctn) == "null");
 315    assert(to!string(itn) == "null");
 316}
 317
 318// Tests for issue 8729: do NOT skip leading WS
 319@safe pure unittest
 320{
 321    foreach (T; TypeTuple!(byte, ubyte, short, ushort, int, uint, long, ulong))
 322    {
 323        assertThrown!ConvException(to!T(" 0"));
 324        assertThrown!ConvException(to!T(" 0", 8));
 325    }
 326    foreach (T; TypeTuple!(float, double, real))
 327    {
 328        assertThrown!ConvException(to!T(" 0"));
 329    }
 330
 331    assertThrown!ConvException(to!bool(" true"));
 332
 333    alias NullType = typeof(null);
 334    assertThrown!ConvException(to!NullType(" null"));
 335
 336    alias ARR = int[];
 337    assertThrown!ConvException(to!ARR(" [1]"));
 338
 339    alias AA = int[int];
 340    assertThrown!ConvException(to!AA(" [1:1]"));
 341}
 342
 343/**
 344If the source type is implicitly convertible to the target type, $(D
 345to) simply performs the implicit conversion.
 346 */
 347T toImpl(T, S)(S value)
 348    if (isImplicitlyConvertible!(S, T) &&
 349        !isEnumStrToStr!(S, T) && !isNullToStr!(S, T))
 350{
 351    template isSignedInt(T)
 352    {
 353        enum isSignedInt = isIntegral!T && isSigned!T;
 354    }
 355    alias isUnsignedInt = isUnsigned;
 356
 357    // Conversion from integer to integer, and changing its sign
 358    static if (isUnsignedInt!S && isSignedInt!T && S.sizeof == T.sizeof)
 359    {   // unsigned to signed & same size
 360        enforce(value <= cast(S)T.max,
 361                new ConvOverflowException("Conversion positive overflow"));
 362    }
 363    else static if (isSignedInt!S && isUnsignedInt!T)
 364    {   // signed to unsigned
 365        enforce(0 <= value,
 366                new ConvOverflowException("Conversion negative overflow"));
 367    }
 368
 369    return value;
 370}
 371
 372@safe pure unittest
 373{
 374    enum E { a }  // Issue 9523 - Allow identity enum conversion
 375    auto e = to!E(E.a);
 376    assert(e == E.a);
 377}
 378
 379@safe pure unittest
 380{
 381    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
 382    int a = 42;
 383    auto b = to!long(a);
 384    assert(a == b);
 385}
 386
 387// Tests for issue 6377
 388@safe pure unittest
 389{
 390    // Conversion between same size
 391    foreach (S; TypeTuple!(byte, short, int, long))
 392    {
 393        alias Unsigned!S U;
 394
 395        foreach (Sint; TypeTuple!(S, const S, immutable S))
 396        foreach (Uint; TypeTuple!(U, const U, immutable U))
 397        {
 398            // positive overflow
 399            Uint un = Uint.max;
 400            assertThrown!ConvOverflowException(to!Sint(un),
 401                text(Sint.stringof, ' ', Uint.stringof, ' ', un));
 402
 403            // negative overflow
 404            Sint sn = -1;
 405            assertThrown!ConvOverflowException(to!Uint(sn),
 406                text(Sint.stringof, ' ', Uint.stringof, ' ', un));
 407        }
 408    }
 409
 410    // Conversion between different size
 411    foreach (i, S1; TypeTuple!(byte, short, int, long))
 412    foreach (   S2; TypeTuple!(byte, short, int, long)[i+1..$])
 413    {
 414        alias Unsigned!S1 U1;
 415        alias Unsigned!S2 U2;
 416
 417        static assert(U1.sizeof < S2.sizeof);
 418
 419        // small unsigned to big signed
 420        foreach (Uint; TypeTuple!(U1, const U1, immutable U1))
 421        foreach (Sint; TypeTuple!(S2, const S2, immutable S2))
 422        {
 423            Uint un = Uint.max;
 424            assertNotThrown(to!Sint(un));
 425            assert(to!Sint(un) == un);
 426        }
 427
 428        // big unsigned to small signed
 429        foreach (Uint; TypeTuple!(U2, const U2, immutable U2))
 430        foreach (Sint; TypeTuple!(S1, const S1, immutable S1))
 431        {
 432            Uint un = Uint.max;
 433            assertThrown(to!Sint(un));
 434        }
 435
 436        static assert(S1.sizeof < U2.sizeof);
 437
 438        // small signed to big unsigned
 439        foreach (Sint; TypeTuple!(S1, const S1, immutable S1))
 440        foreach (Uint; TypeTuple!(U2, const U2, immutable U2))
 441        {
 442            Sint sn = -1;
 443            assertThrown!ConvOverflowException(to!Uint(sn));
 444        }
 445
 446        // big signed to small unsigned
 447        foreach (Sint; TypeTuple!(S2, const S2, immutable S2))
 448        foreach (Uint; TypeTuple!(U1, const U1, immutable U1))
 449        {
 450            Sint sn = -1;
 451            assertThrown!ConvOverflowException(to!Uint(sn));
 452        }
 453    }
 454}
 455
 456/*
 457  Converting static arrays forwards to their dynamic counterparts.
 458 */
 459T toImpl(T, S)(ref S s)
 460    if (isRawStaticArray!S)
 461{
 462    return toImpl!(T, typeof(s[0])[])(s);
 463}
 464
 465@safe pure unittest
 466{
 467    char[4] test = ['a', 'b', 'c', 'd'];
 468    static assert(!isInputRange!(Unqual!(char[4])));
 469    assert(to!string(test) == test);
 470}
 471
 472/**
 473When source type supports member template function opCast, is is used.
 474*/
 475T toImpl(T, S)(S value)
 476    if (!isImplicitlyConvertible!(S, T) &&
 477        is(typeof(S.init.opCast!T()) : T) &&
 478        !isExactSomeString!T)
 479{
 480    return value.opCast!T();
 481}
 482
 483@safe pure unittest
 484{
 485    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
 486    class B
 487    {
 488        T opCast(T)() { return 43; }
 489    }
 490    auto b = new B;
 491    assert(to!int(b) == 43);
 492
 493    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
 494    struct S
 495    {
 496        T opCast(T)() { return 43; }
 497    }
 498    auto s = S();
 499    assert(to!int(s) == 43);
 500}
 501
 502/**
 503When target type supports 'converting construction', it is used.
 504$(UL $(LI If target type is struct, $(D T(value)) is used.)
 505     $(LI If target type is class, $(D new T(value)) is used.))
 506*/
 507T toImpl(T, S)(S value)
 508    if (!isImplicitlyConvertible!(S, T) &&
 509        is(T == struct) && is(typeof(T(value))))
 510{
 511    return T(value);
 512}
 513
 514// Bugzilla 3961
 515@safe pure unittest
 516{
 517    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
 518    struct Int
 519    {
 520        int x;
 521    }
 522    Int i = to!Int(1);
 523
 524    static struct Int2
 525    {
 526        int x;
 527        this(int x) @safe pure { this.x = x; }
 528    }
 529    Int2 i2 = to!Int2(1);
 530
 531    static struct Int3
 532    {
 533        int x;
 534        static Int3 opCall(int x) @safe pure
 535        {
 536            Int3 i;
 537            i.x = x;
 538            return i;
 539        }
 540    }
 541    Int3 i3 = to!Int3(1);
 542}
 543
 544// Bugzilla 6808
 545@safe pure unittest
 546{
 547    static struct FakeBigInt
 548    {
 549        this(string s) @safe pure {}
 550    }
 551
 552    string s = "101";
 553    auto i3 = to!FakeBigInt(s);
 554}
 555
 556/// ditto
 557T toImpl(T, S)(S value)
 558    if (!isImplicitlyConvertible!(S, T) &&
 559        is(T == class) && is(typeof(new T(value))))
 560{
 561    return new T(value);
 562}
 563
 564@safe pure unittest
 565{
 566    static struct S
 567    {
 568        int x;
 569    }
 570    static class C
 571    {
 572        int x;
 573        this(int x) @safe pure { this.x = x; }
 574    }
 575
 576    static class B
 577    {
 578        int value;
 579        this(S src) @safe pure { value = src.x; }
 580        this(C src) @safe pure { value = src.x; }
 581    }
 582
 583    S s = S(1);
 584    auto b1 = to!B(s);  // == new B(s)
 585    assert(b1.value == 1);
 586
 587    C c = new C(2);
 588    auto b2 = to!B(c);  // == new B(c)
 589    assert(b2.value == 2);
 590
 591    auto c2 = to!C(3);   // == new C(3)
 592    assert(c2.x == 3);
 593}
 594
 595@safe pure unittest
 596{
 597    struct S
 598    {
 599        class A
 600        {
 601            this(B b) @safe pure {}
 602        }
 603        class B : A
 604        {
 605            this() @safe pure { super(this); }
 606        }
 607    }
 608
 609    S.B b = new S.B();
 610    S.A a = to!(S.A)(b);      // == cast(S.A)b
 611                              // (do not run construction conversion like new S.A(b))
 612    assert(b is a);
 613
 614    static class C : Object
 615    {
 616        this() @safe pure {}
 617        this(Object o) @safe pure {}
 618    }
 619
 620    Object oc = new C();
 621    C a2 = to!C(oc);    // == new C(a)
 622                        // Construction conversion overrides down-casting conversion
 623    assert(a2 !is a);   //
 624}
 625
 626/**
 627Object-to-object conversions by dynamic casting throw exception when the source is
 628non-null and the target is null.
 629 */
 630T toImpl(T, S)(S value)
 631    if (!isImplicitlyConvertible!(S, T) &&
 632        (is(S == class) || is(S == interface)) && !is(typeof(value.opCast!T()) : T) &&
 633        (is(T == class) || is(T == interface)) && !is(typeof(new T(value))))
 634{
 635    static if (is(T == immutable))
 636    {
 637            // immutable <- immutable
 638            enum isModConvertible = is(S == immutable);
 639    }
 640    else static if (is(T == const))
 641    {
 642        static if (is(T == shared))
 643        {
 644            // shared const <- shared
 645            // shared const <- shared const
 646            // shared const <- immutable
 647            enum isModConvertible = is(S == shared) || is(S == immutable);
 648        }
 649        else
 650        {
 651            // const <- mutable
 652            // const <- immutable
 653            enum isModConvertible = !is(S == shared);
 654        }
 655    }
 656    else
 657    {
 658        static if (is(T == shared))
 659        {
 660            // shared <- shared mutable
 661            enum isModConvertible = is(S == shared) && !is(S == const);
 662        }
 663        else
 664        {
 665            // (mutable) <- (mutable)
 666            enum isModConvertible = is(Unqual!S == S);
 667        }
 668    }
 669    static assert(isModConvertible, "Bad modifier conversion: "~S.stringof~" to "~T.stringof);
 670
 671    auto result = ()@trusted{ return cast(T) value; }();
 672    if (!result && value)
 673    {
 674        throw new ConvException("Cannot convert object of static type "
 675                ~S.classinfo.name~" and dynamic type "~value.classinfo.name
 676                ~" to type "~T.classinfo.name);
 677    }
 678    return result;
 679}
 680
 681@safe pure unittest
 682{
 683    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
 684    // Testing object conversions
 685    class A {}
 686    class B : A {}
 687    class C : A {}
 688    A a1 = new A, a2 = new B, a3 = new C;
 689    assert(to!B(a2) is a2);
 690    assert(to!C(a3) is a3);
 691    assertThrown!ConvException(to!B(a3));
 692}
 693
 694// Unittest for 6288
 695@safe pure unittest
 696{
 697    template Identity(T)        { alias              T   Identity; }
 698    template toConst(T)         { alias        const(T)  toConst; }
 699    template toShared(T)        { alias       shared(T)  toShared; }
 700    template toSharedConst(T)   { alias shared(const(T)) toSharedConst; }
 701    template toImmutable(T)     { alias    immutable(T)  toImmutable; }
 702    template AddModifier(int n) if (0 <= n && n < 5)
 703    {
 704             static if (n == 0) alias Identity       AddModifier;
 705        else static if (n == 1) alias toConst        AddModifier;
 706        else static if (n == 2) alias toShared       AddModifier;
 707        else static if (n == 3) alias toSharedConst  AddModifier;
 708        else static if (n == 4) alias toImmutable    AddModifier;
 709    }
 710
 711    interface I {}
 712    interface J {}
 713
 714    class A {}
 715    class B : A {}
 716    class C : B, I, J {}
 717    class D : I {}
 718
 719    foreach (m1; TypeTuple!(0,1,2,3,4)) // enumerate modifiers
 720    foreach (m2; TypeTuple!(0,1,2,3,4)) // ditto
 721    {
 722        alias AddModifier!m1 srcmod;
 723        alias AddModifier!m2 tgtmod;
 724        //pragma(msg, srcmod!Object, " -> ", tgtmod!Object, ", convertible = ",
 725        //            isImplicitlyConvertible!(srcmod!Object, tgtmod!Object));
 726
 727        // Compile time convertible equals to modifier convertible.
 728        static if (isImplicitlyConvertible!(srcmod!Object, tgtmod!Object))
 729        {
 730            // Test runtime conversions: class to class, class to interface,
 731            // interface to class, and interface to interface
 732
 733            // Check that the runtime conversion to succeed
 734            srcmod!A ac = new srcmod!C();
 735            srcmod!I ic = new srcmod!C();
 736            assert(to!(tgtmod!C)(ac) !is null); // A(c) to C
 737            assert(to!(tgtmod!I)(ac) !is null); // A(c) to I
 738            assert(to!(tgtmod!C)(ic) !is null); // I(c) to C
 739            assert(to!(tgtmod!J)(ic) !is null); // I(c) to J
 740
 741            // Check that the runtime conversion fails
 742            srcmod!A ab = new srcmod!B();
 743            srcmod!I id = new srcmod!D();
 744            assertThrown(to!(tgtmod!C)(ab));    // A(b) to C
 745            assertThrown(to!(tgtmod!I)(ab));    // A(b) to I
 746            assertThrown(to!(tgtmod!C)(id));    // I(d) to C
 747            assertThrown(to!(tgtmod!J)(id));    // I(d) to J
 748        }
 749        else
 750        {
 751            // Check that the conversion is rejected statically
 752            static assert(!is(typeof(to!(tgtmod!C)(srcmod!A.init))));   // A to C
 753            static assert(!is(typeof(to!(tgtmod!I)(srcmod!A.init))));   // A to I
 754            static assert(!is(typeof(to!(tgtmod!C)(srcmod!I.init))));   // I to C
 755            static assert(!is(typeof(to!(tgtmod!J)(srcmod!I.init))));   // I to J
 756        }
 757    }
 758}
 759
 760/**
 761Stringize conversion from all types is supported.
 762$(UL
 763  $(LI String _to string conversion works for any two string types having
 764       ($(D char), $(D wchar), $(D dchar)) character widths and any
 765       combination of qualifiers (mutable, $(D const), or $(D immutable)).)
 766  $(LI Converts array (other than strings) to string.
 767       Each element is converted by calling $(D to!T).)
 768  $(LI Associative array to string conversion.
 769       Each element is printed by calling $(D to!T).)
 770  $(LI Object to string conversion calls $(D toString) against the object or
 771       returns $(D "null") if the object is null.)
 772  $(LI Struct to string conversion calls $(D toString) against the struct if
 773       it is defined.)
 774  $(LI For structs that do not define $(D toString), the conversion to string
 775       produces the list of fields.)
 776  $(LI Enumerated types are converted to strings as their symbolic names.)
 777  $(LI Boolean values are printed as $(D "true") or $(D "false").)
 778  $(LI $(D char), $(D wchar), $(D dchar) to a string type.)
 779  $(LI Unsigned or signed integers to strings.
 780       $(DL $(DT [special case])
 781            $(DD Convert integral value to string in $(D_PARAM radix) radix.
 782            radix must be a value from 2 to 36.
 783            value is treated as a signed value only if radix is 10.
 784            The characters A through Z are used to represent values 10 through 36
 785            and their case is determined by the $(D_PARAM letterCase) parameter.)))
 786  $(LI All floating point types to all string types.)
 787  $(LI Pointer to string conversions prints the pointer as a $(D size_t) value.
 788       If pointer is $(D char*), treat it as C-style strings.
 789       In that case, this function is $(D @system).))
 790*/
 791T toImpl(T, S)(S value)
 792    if (!(isImplicitlyConvertible!(S, T) &&
 793          !isEnumStrToStr!(S, T) && !isNullToStr!(S, T)) &&
 794        isExactSomeString!T)
 795{
 796    static if (isExactSomeString!S && value[0].sizeof == ElementEncodingType!T.sizeof)
 797    {
 798        // string-to-string with incompatible qualifier conversion
 799        static if (is(ElementEncodingType!T == immutable))
 800        {
 801            // conversion (mutable|const) -> immutable
 802            return value.idup;
 803        }
 804        else
 805        {
 806            // conversion (immutable|const) -> mutable
 807            return value.dup;
 808        }
 809    }
 810    else static if (isExactSomeString!S)
 811    {
 812        // other string-to-string
 813        //Use Appender directly instead of toStr, which also uses a formatedWrite
 814        auto w = appender!T();
 815        w.put(value);
 816        return w.data;
 817    }
 818    else static if (isIntegral!S && !is(S == enum))
 819    {
 820        // other integral-to-string conversions with default radix
 821        return toImpl!(T, S)(value, 10);
 822    }
 823    else static if (is(S == void[]) || is(S == const(void)[]) || is(S == immutable(void)[]))
 824    {
 825        // Converting void array to string
 826        alias Unqual!(ElementEncodingType!T) Char;
 827        auto raw = cast(const(ubyte)[]) value;
 828        enforce(raw.length % Char.sizeof == 0,
 829                new ConvException("Alignment mismatch in converting a "
 830                        ~ S.stringof ~ " to a "
 831                        ~ T.stringof));
 832        auto result = new Char[raw.length / Char.sizeof];
 833        ()@trusted{ memcpy(result.ptr, value.ptr, value.length); }();
 834        return cast(T) result;
 835    }
 836    else static if (isPointer!S && is(S : const(char)*))
 837    {
 838        // It is unsafe because we cannot guarantee that the pointer is null terminated.
 839        return value ? cast(T) value[0 .. strlen(value)].dup : cast(string)null;
 840    }
 841    else static if (isSomeString!T && is(S == enum))
 842    {
 843        static if (isSwitchable!(OriginalType!S) && EnumMembers!S.length <= 50)
 844        {
 845            switch(value)
 846            {
 847                foreach (I, member; NoDuplicates!(EnumMembers!S))
 848                {
 849                    case member:
 850                        return to!T(enumRep!(immutable(T), S, I));
 851                }
 852                default:
 853            }
 854        }
 855        else
 856        {
 857            foreach (I, member; EnumMembers!S)
 858            {
 859                if (value == member)
 860                    return to!T(enumRep!(immutable(T), S, I));
 861            }
 862        }
 863
 864        import std.format : FormatSpec, formatValue;
 865
 866        //Default case, delegate to format
 867        //Note: we don't call toStr directly, to avoid duplicate work.
 868        auto app = appender!T();
 869        app.put("cast(");
 870        app.put(S.stringof);
 871        app.put(')');
 872        FormatSpec!char f;
 873        formatValue(app, cast(OriginalType!S)value, f);
 874        return app.data;
 875    }
 876    else
 877    {
 878        // other non-string values runs formatting
 879        return toStr!T(value);
 880    }
 881}
 882
 883/*
 884    Check whether type $(D T) can be used in a switch statement.
 885    This is useful for compile-time generation of switch case statements.
 886*/
 887private template isSwitchable(E)
 888{
 889    enum bool isSwitchable = is(typeof({
 890        switch (E.init) { default: }
 891    }));
 892}
 893
 894//
 895unittest
 896{
 897    static assert(isSwitchable!int);
 898    static assert(!isSwitchable!double);
 899    static assert(!isSwitchable!real);
 900}
 901
 902//Static representation of the index I of the enum S,
 903//In representation T.
 904//T must be an immutable string (avoids un-necessary initializations).
 905private template enumRep(T, S, size_t I)
 906if (is (T == immutable) && isExactSomeString!T && is(S == enum))
 907{
 908    static T enumRep = to!T(__traits(allMembers, S)[I]);
 909}
 910
 911@safe pure unittest
 912{
 913    void dg()
 914    {
 915        // string to string conversion
 916        debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
 917
 918        alias TypeTuple!(char, wchar, dchar) Chars;
 919        foreach (LhsC; Chars)
 920        {
 921            alias TypeTuple!(LhsC[], const(LhsC)[], immutable(LhsC)[]) LhStrings;
 922            foreach (Lhs; LhStrings)
 923            {
 924                foreach (RhsC; Chars)
 925                {
 926                    alias TypeTuple!(RhsC[], const(RhsC)[], immutable(RhsC)[])
 927                        RhStrings;
 928                    foreach (Rhs; RhStrings)
 929                    {
 930                        Lhs s1 = to!Lhs("wyda");
 931                        Rhs s2 = to!Rhs(s1);
 932                        //writeln(Lhs.stringof, " -> ", Rhs.stringof);
 933                        assert(s1 == to!Lhs(s2));
 934                    }
 935                }
 936            }
 937        }
 938
 939        foreach (T; Chars)
 940        {
 941            foreach (U; Chars)
 942            {
 943                T[] s1 = to!(T[])("Hello, world!");
 944                auto s2 = to!(U[])(s1);
 945                assert(s1 == to!(T[])(s2));
 946                auto s3 = to!(const(U)[])(s1);
 947                assert(s1 == to!(T[])(s3));
 948                auto s4 = to!(immutable(U)[])(s1);
 949                assert(s1 == to!(T[])(s4));
 950            }
 951        }
 952    }
 953    dg();
 954    assertCTFEable!dg;
 955}
 956
 957@safe pure unittest
 958{
 959    // Conversion reinterpreting void array to string
 960    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
 961
 962    auto a = "abcx"w;
 963    const(void)[] b = a;
 964    assert(b.length == 8);
 965
 966    auto c = to!(wchar[])(b);
 967    assert(c == "abcx");
 968}
 969
 970@system pure unittest
 971{
 972    // char* to string conversion
 973    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
 974    debug(conv) printf("string.to!string(char*).unittest\n");
 975
 976    assert(to!string(cast(char*) null) == "");
 977    assert(to!string("foo\0".ptr) == "foo");
 978}
 979
 980@safe pure unittest
 981{
 982    // Conversion representing bool value with string
 983    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
 984
 985    bool b;
 986    assert(to!string(b) == "false");
 987    b = true;
 988    assert(to!string(b) == "true");
 989}
 990
 991@safe pure unittest
 992{
 993    // Conversion representing character value with string
 994    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
 995
 996    alias TypeTuple!(
 997         char, const( char), immutable( char),
 998        wchar, const(wchar), immutable(wchar),
 999        dchar, const(dchar), immutable(dchar)) AllChars;
1000    foreach (Char1; AllChars)
1001    {
1002        foreach (Char2; AllChars)
1003        {
1004            Char1 c = 'a';
1005            assert(to!(Char2[])(c)[0] == c);
1006        }
1007        uint x = 4;
1008        assert(to!(Char1[])(x) == "4");
1009    }
1010
1011    string s = "foo";
1012    string s2;
1013    foreach (char c; s)
1014    {
1015        s2 ~= to!string(c);
1016    }
1017    //printf("%.*s", s2);
1018    assert(s2 == "foo");
1019}
1020
1021@safe pure unittest
1022{
1023    // Conversion representing integer values with string
1024
1025    foreach (Int; TypeTuple!(ubyte, ushort, uint, ulong))
1026    {
1027        debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
1028        debug(conv) printf("string.to!string(%.*s).unittest\n", Int.stringof.length, Int.stringof.ptr);
1029
1030        assert(to!string(to!Int(0)) == "0");
1031        assert(to!string(to!Int(9)) == "9");
1032        assert(to!string(to!Int(123)) == "123");
1033    }
1034
1035    foreach (Int; TypeTuple!(byte, short, int, long))
1036    {
1037        debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
1038        debug(conv) printf("string.to!string(%.*s).unittest\n", Int.stringof.length, Int.stringof.ptr);
1039
1040        assert(to!string(to!Int(0)) == "0");
1041        assert(to!string(to!Int(9)) == "9");
1042        assert(to!string(to!Int(123)) == "123");
1043        assert(to!string(to!Int(-0)) == "0");
1044        assert(to!string(to!Int(-9)) == "-9");
1045        assert(to!string(to!Int(-123)) == "-123");
1046        assert(to!string(to!(const Int)(6)) == "6");
1047    }
1048
1049    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
1050    assert(wtext(int.max) == "2147483647"w);
1051    assert(wtext(int.min) == "-2147483648"w);
1052    assert(to!string(0L) == "0");
1053
1054    assertCTFEable!(
1055    {
1056        assert(to!string(1uL << 62) == "4611686018427387904");
1057        assert(to!string(0x100000000) == "4294967296");
1058        assert(to!string(-138L) == "-138");
1059    });
1060}
1061
1062@safe pure unittest
1063{
1064    // Conversion representing dynamic/static array with string
1065    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
1066
1067    long[] b = [ 1, 3, 5 ];
1068    auto s = to!string(b);
1069    assert(to!string(b) == "[1, 3, 5]", s);
1070}
1071/*@safe pure */unittest // sprintf issue
1072{
1073    double[2] a = [ 1.5, 2.5 ];
1074    assert(to!string(a) == "[1.5, 2.5]");
1075}
1076
1077/*@safe pure */unittest
1078{
1079    // Conversion representing associative array with string
1080    int[string] a = ["0":1, "1":2];
1081    assert(to!string(a) == `["0":1, "1":2]`);
1082}
1083
1084unittest
1085{
1086    // Conversion representing class object with string
1087    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
1088
1089    class A
1090    {
1091        override string toString() const { return "an A"; }
1092    }
1093    A a;
1094    assert(to!string(a) == "null");
1095    a = new A;
1096    assert(to!string(a) == "an A");
1097
1098    // Bug 7660
1099    class C { override string toString() const { return "C"; } }
1100    struct S { C c; alias c this; }
1101    S s; s.c = new C();
1102    assert(to!string(s) == "C");
1103}
1104
1105unittest
1106{
1107    // Conversion representing struct object with string
1108    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
1109
1110    struct S1
1111    {
1112        string toString() { return "wyda"; }
1113    }
1114    assert(to!string(S1()) == "wyda");
1115
1116    struct S2
1117    {
1118        int a = 42;
1119        float b = 43.5;
1120    }
1121    S2 s2;
1122    assert(to!string(s2) == "S2(42, 43.5)");
1123
1124    // Test for issue 8080
1125    struct S8080
1126    {
1127        short[4] data;
1128        alias data this;
1129        string toString() { return "<S>"; }
1130    }
1131    S8080 s8080;
1132    assert(to!string(s8080) == "<S>");
1133}
1134
1135unittest
1136{
1137    // Conversion representing enum value with string
1138    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
1139
1140    enum EB : bool { a = true }
1141    enum EU : uint { a = 0, b = 1, c = 2 }  // base type is unsigned
1142    enum EI : int { a = -1, b = 0, c = 1 }  // base type is signed (bug 7909)
1143    enum EF : real { a = 1.414, b = 1.732, c = 2.236 }
1144    enum EC : char { a = 'x', b = 'y' }
1145    enum ES : string { a = "aaa", b = "bbb" }
1146
1147    foreach (E; TypeTuple!(EB, EU, EI, EF, EC, ES))
1148    {
1149        assert(to! string(E.a) == "a"c);
1150        assert(to!wstring(E.a) == "a"w);
1151        assert(to!dstring(E.a) == "a"d);
1152    }
1153
1154    // Test an value not corresponding to an enum member.
1155    auto o = cast(EU)5;
1156    assert(to! string(o) == "cast(EU)5"c);
1157    assert(to!wstring(o) == "cast(EU)5"w);
1158    assert(to!dstring(o) == "cast(EU)5"d);
1159}
1160
1161unittest
1162{
1163    enum E
1164    {
1165        foo,
1166        bar,
1167        doo = foo, // check duplicate switch statements
1168    }
1169
1170    foreach (S; TypeTuple!(string, wstring, dstring, const(char[]), const(wchar[]), const(dchar[])))
1171    {
1172        auto s1 = to!S(E.foo);
1173        auto s2 = to!S(E.foo);
1174        assert(s1 == s2);
1175        // ensure we don't allocate when it's unnecessary
1176        assert(s1 is s2);
1177    }
1178
1179    foreach (S; TypeTuple!(char[], wchar[], dchar[]))
1180    {
1181        auto s1 = to!S(E.foo);
1182        auto s2 = to!S(E.foo);
1183        assert(s1 == s2);
1184        // ensure each mutable array is unique
1185        assert(s1 !is s2);
1186    }
1187}
1188
1189/// ditto
1190@trusted pure T toImpl(T, S)(S value, uint radix, LetterCase letterCase = LetterCase.upper)
1191    if (isIntegral!S &&
1192        isExactSomeString!T)
1193in
1194{
1195    assert(radix >= 2 && radix <= 36);
1196}
1197body
1198{
1199    alias EEType = Unqual!(ElementEncodingType!T);
1200
1201    T toStringRadixConvert(size_t bufLen, uint radix = 0, bool neg = false)(uint runtimeRadix = 0)
1202    {
1203        static if (neg)
1204            ulong div = void, mValue = unsigned(-value);
1205        else
1206            Unsigned!(Unqual!S) div = void, mValue = unsigned(value);
1207
1208        size_t index = bufLen;
1209        EEType[bufLen] buffer = void;
1210        char baseChar = letterCase == LetterCase.lower ? 'a' : 'A';
1211        char mod = void;
1212
1213        do
1214        {
1215            static if (radix == 0)
1216            {
1217                div = cast(S)(mValue / runtimeRadix );
1218                mod = cast(ubyte)(mValue % runtimeRadix);
1219                mod += mod < 10 ? '0' : baseChar - 10;
1220            }
1221            else static if (radix > 10)
1222            {
1223                div = cast(S)(mValue / radix );
1224                mod = cast(ubyte)(mValue % radix);
1225                mod += mod < 10 ? '0' : baseChar - 10;
1226            }
1227            else
1228            {
1229                div = cast(S)(mValue / radix);
1230                mod = mValue % radix + '0';
1231            }
1232            buffer[--index] = cast(char)mod;
1233            mValue = div;
1234        } while (mValue);
1235
1236        static if (neg)
1237        {
1238            buffer[--index] = '-';
1239        }
1240        return cast(T)buffer[index .. $].dup;
1241    }
1242
1243    enforce(radix >= 2 && radix <= 36, new ConvException("Radix error"));
1244
1245    switch(radix)
1246    {
1247        case 10:
1248            if (value < 0)
1249                return toStringRadixConvert!(S.sizeof * 3 + 1, 10, true)();
1250            else
1251                return toStringRadixConvert!(S.sizeof * 3, 10)();
1252        case 16:
1253            return toStringRadixConvert!(S.sizeof * 2, 16)();
1254        case 2:
1255            return toStringRadixConvert!(S.sizeof * 8, 2)();
1256        case 8:
1257            return toStringRadixConvert!(S.sizeof * 3, 8)();
1258        default:
1259           return toStringRadixConvert!(S.sizeof * 6)(radix);
1260    }
1261}
1262
1263@safe pure unittest
1264{
1265    foreach (Int; TypeTuple!(uint, ulong))
1266    {
1267        debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
1268        debug(conv) printf("string.to!string(%.*s, uint).unittest\n", Int.stringof.length, Int.stringof.ptr);
1269
1270        assert(to!string(to!Int(16), 16) == "10");
1271        assert(to!string(to!Int(15), 2u) == "1111");
1272        assert(to!string(to!Int(1), 2u) == "1");
1273        assert(to!string(to!Int(0x1234AF), 16u) == "1234AF");
1274        assert(to!string(to!Int(0x1234BCD), 16u, LetterCase.upper) == "1234BCD");
1275        assert(to!string(to!Int(0x1234AF), 16u, LetterCase.lower) == "1234af");
1276    }
1277
1278    foreach (Int; TypeTuple!(int, long))
1279    {
1280        debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
1281        debug(conv) printf("string.to!string(%.*s, uint).unittest\n", Int.stringof.length, Int.stringof.ptr);
1282
1283        assert(to!string(to!Int(-10), 10u) == "-10");
1284    }
1285
1286    assert(to!string(cast(byte)-10, 16) == "F6");
1287    assert(to!string(long.min) == "-9223372036854775808");
1288    assert(to!string(long.max) == "9223372036854775807");
1289}
1290
1291
1292/**
1293Narrowing numeric-numeric conversions throw when the value does not
1294fit in the narrower type.
1295 */
1296T toImpl(T, S)(S value)
1297    if (!isImplicitlyConvertible!(S, T) &&
1298        (isNumeric!S || isSomeChar!S || isBoolean!S) &&
1299        (isNumeric!T || isSomeChar!T || isBoolean!T) && !is(T == enum))
1300{
1301    enum sSmallest = mostNegative!S;
1302    enum tSmallest = mostNegative!T;
1303    static if (sSmallest < 0)
1304    {
1305        // possible underflow converting from a signed
1306        static if (tSmallest == 0)
1307        {
1308            immutable good = value >= 0;
1309        }
1310        else
1311        {
1312            static assert(tSmallest < 0);
1313            immutable good = value >= tSmallest;
1314        }
1315        if (!good)
1316            throw new ConvOverflowException("Conversion negative overflow");
1317    }
1318    static if (S.max > T.max)
1319    {
1320        // possible overflow
1321        if (value > T.max)
1322            throw new ConvOverflowException("Conversion positive overflow");
1323    }
1324    return (ref value)@trusted{ return cast(T) value; }(value);
1325}
1326
1327@safe pure unittest
1328{
1329    dchar a = ' ';
1330    assert(to!char(a) == ' ');
1331    a = 300;
1332    assert(collectException(to!char(a)));
1333
1334    dchar from0 = 'A';
1335    char to0 = to!char(from0);
1336
1337    wchar from1 = 'A';
1338    char to1 = to!char(from1);
1339
1340    char from2 = 'A';
1341    char to2 = to!char(from2);
1342
1343    char from3 = 'A';
1344    wchar to3 = to!wchar(from3);
1345
1346    char from4 = 'A';
1347    dchar to4 = to!dchar(from4);
1348}
1349
1350unittest
1351{
1352    // Narrowing conversions from enum -> integral should be allowed, but they
1353    // should throw at runtime if the enum value doesn't fit in the target
1354    // type.
1355    enum E1 : ulong { A = 1, B = 1UL<<48, C = 0 }
1356    assert(to!int(E1.A) == 1);
1357    assert(to!bool(E1.A) == true);
1358    assertThrown!ConvOverflowException(to!int(E1.B)); // E1.B overflows int
1359    assertThrown!ConvOverflowException(to!bool(E1.B)); // E1.B overflows bool
1360    assert(to!bool(E1.C) == false);
1361
1362    enum E2 : long { A = -1L<<48, B = -1<<31, C = 1<<31 }
1363    assertThrown!ConvOverflowException(to!int(E2.A)); // E2.A overflows int
1364    assertThrown!ConvOverflowException(to!uint(E2.B)); // E2.B overflows uint
1365    assert(to!int(E2.B) == -1<<31); // but does not overflow int
1366    assert(to!int(E2.C) == 1<<31);  // E2.C does not overflow int
1367
1368    enum E3 : int { A = -1, B = 1, C = 255, D = 0 }
1369    assertThrown!ConvOverflowException(to!ubyte(E3.A));
1370    assertThrown!ConvOverflowException(to!bool(E3.A));
1371    assert(to!byte(E3.A) == -1);
1372    assert(to!byte(E3.B) == 1);
1373    assert(to!ubyte(E3.C) == 255);
1374    assert(to!bool(E3.B) == true);
1375    assertThrown!ConvOverflowException(to!byte(E3.C));
1376    assertThrown!ConvOverflowException(to!bool(E3.C));
1377    assert(to!bool(E3.D) == false);
1378
1379}
1380
1381/**
1382Array-to-array conversion (except when target is a string type)
1383converts each element in turn by using $(D to).
1384 */
1385T toImpl(T, S)(S value)
1386    if (!isImplicitlyConvertible!(S, T) &&
1387        !isSomeString!S && isDynamicArray!S &&
1388        !isExactSomeString!T && isArray!T)
1389{
1390    alias E = typeof(T.init[0]);
1391
1392    auto w = appender!(E[])();
1393    w.reserve(value.length);
1394    foreach (i, ref e; value)
1395    {
1396        w.put(to!E(e));
1397    }
1398    return w.data;
1399}
1400
1401@safe pure unittest
1402{
1403    // array to array conversions
1404    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
1405
1406    uint[] a = ([ 1u, 2, 3 ]).dup;
1407    auto b = to!(float[])(a);
1408    assert(b == [ 1.0f, 2, 3 ]);
1409
1410    //auto c = to!(string[])(b);
1411    //assert(c[0] == "1" && c[1] == "2" && c[2] == "3");
1412
1413    immutable(int)[3] d = [ 1, 2, 3 ];
1414    b = to!(float[])(d);
1415    assert(b == [ 1.0f, 2, 3 ]);
1416
1417    uint[][] e = [ a, a ];
1418    auto f = to!(float[][])(e);
1419    assert(f[0] == b && f[1] == b);
1420
1421    // Test for bug 8264
1422    struct Wrap
1423    {
1424        string wrap;
1425        alias wrap this;
1426    }
1427    Wrap[] warr = to!(Wrap[])(["foo", "bar"]);  // should work
1428}
1429/*@safe pure */unittest
1430{
1431    auto b = [ 1.0f, 2, 3 ];
1432
1433    auto c = to!(string[])(b);
1434    assert(c[0] == "1" && c[1] == "2" && c[2] == "3");
1435}
1436
1437/**
1438Associative array to associative array conversion converts each key
1439and each value in turn.
1440 */
1441T toImpl(T, S)(S value)
1442    if (isAssociativeArray!S &&
1443        isAssociativeArray!T && !is(T == enum))
1444{
1445    /* This code is potentially unsafe.
1446     */
1447    alias KeyType!T   K2;
1448    alias ValueType!T V2;
1449
1450    // While we are "building" the AA, we need to unqualify its values, and only re-qualify at the end
1451    Unqual!V2[K2] result;
1452
1453    foreach (k1, v1; value)
1454    {
1455        // Cast values temporarily to Unqual!V2 to store them to result variable
1456        result[to!K2(k1)] = cast(Unqual!V2) to!V2(v1);
1457    }
1458    // Cast back to original type
1459    return cast(T)result;
1460}
1461
1462@safe /*pure */unittest
1463{
1464    // hash to hash conversions
1465    int[string] a;
1466    a["0"] = 1;
1467    a["1"] = 2;
1468    auto b = to!(double[dstring])(a);
1469    assert(b["0"d] == 1 && b["1"d] == 2);
1470}
1471@safe /*pure */unittest // Bugzilla 8705, from doc
1472{
1473    int[string][double[int[]]] a;
1474    auto b = to!(short[wstring][string[double[]]])(a);
1475    a = [null:["hello":int.max]];
1476    assertThrown!ConvOverflowException(to!(short[wstring][string[double[]]])(a));
1477}
1478version(none) // masked by unexpected linker error in posix platforms
1479unittest // Extra cases for AA with qualifiers conversion
1480{
1481    int[][int[]] a;// = [[], []];
1482    auto b = to!(immutable(short[])[immutable short[]])(a);
1483
1484    double[dstring][int[long[]]] c;
1485    auto d = to!(immutable(short[immutable wstring])[immutable string[double[]]])(c);
1486}
1487
1488private void testIntegralToFloating(Integral, Floating)()
1489{
1490    Integral a = 42;
1491    auto b = to!Floating(a);
1492    assert(a == b);
1493    assert(a == to!Integral(b));
1494}
1495
1496private void testFloatingToIntegral(Floating, Integral)()
1497{
1498    bool convFails(Source, Target, E)(Source src)
1499    {
1500        try
1501            auto t = to!Target(src);
1502        catch (E)
1503            return true;
1504        return false;
1505    }
1506
1507    // convert some value
1508    Floating a = 4.2e1;
1509    auto b = to!Integral(a);
1510    assert(is(typeof(b) == Integral) && b == 42);
1511    // convert some negative value (if applicable)
1512    a = -4.2e1;
1513    static if (Integral.min < 0)
1514    {
1515        b = to!Integral(a);
1516        assert(is(typeof(b) == Integral) && b == -42);
1517    }
1518    else
1519    {
1520        // no go for unsigned types
1521        assert(convFails!(Floating, Integral, ConvOverflowException)(a));
1522    }
1523    // convert to the smallest integral value
1524    a = 0.0 + Integral.min;
1525    static if (Integral.min < 0)
1526    {
1527        a = -a; // -Integral.min not representable as an Integral
1528        assert(convFails!(Floating, Integral, ConvOverflowException)(a)
1529                || Floating.sizeof <= Integral.sizeof);
1530    }
1531    a = 0.0 + Integral.min;
1532    assert(to!Integral(a) == Integral.min);
1533    --a; // no more representable as an Integral
1534    assert(convFails!(Floating, Integral, ConvOverflowException)(a)
1535            || Floating.sizeof <= Integral.sizeof);
1536    a = 0.0 + Integral.max;
1537//   fwritefln(stderr, "%s a=%g, %s conv=%s", Floating.stringof, a,
1538//             Integral.stringof, to!Integral(a));
1539    assert(to!Integral(a) == Integral.max || Floating.sizeof <= Integral.sizeof);
1540    ++a; // no more representable as an Integral
1541    assert(convFails!(Floating, Integral, ConvOverflowException)(a)
1542            || Floating.sizeof <= Integral.sizeof);
1543    // convert a value with a fractional part
1544    a = 3.14;
1545    assert(to!Integral(a) == 3);
1546    a = 3.99;
1547    assert(to!Integral(a) == 3);
1548    static if (Integral.min < 0)
1549    {
1550        a = -3.14;
1551        assert(to!Integral(a) == -3);
1552        a = -3.99;
1553        assert(to!Integral(a) == -3);
1554    }
1555}
1556
1557@safe pure unittest
1558{
1559    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
1560
1561    alias AllInts = TypeTuple!(byte, ubyte, short, ushort, int, uint, long, ulong);
1562    alias AllFloats = TypeTuple!(float, double, real);
1563    alias AllNumerics = TypeTuple!(AllInts, AllFloats);
1564    // test with same type
1565    {
1566        foreach (T; AllNumerics)
1567        {
1568            T a = 42;
1569            auto b = to!T(a);
1570            assert(is(typeof(a) == typeof(b)) && a == b);
1571        }
1572    }
1573    // test that floating-point numbers convert properly to largest ints
1574    // see http://oregonstate.edu/~peterseb/mth351/docs/351s2001_fp80x87.html
1575    // look for "largest fp integer with a predecessor"
1576    {
1577        // float
1578        int a = 16_777_215; // 2^24 - 1
1579        assert(to!int(to!float(a)) == a);
1580        assert(to!int(to!float(-a)) == -a);
1581        // double
1582        long b = 9_007_199_254_740_991; // 2^53 - 1
1583        assert(to!long(to!double(b)) == b);
1584        assert(to!long(to!double(-b)) == -b);
1585        // real
1586        // @@@ BUG IN COMPILER @@@
1587//     ulong c = 18_446_744_073_709_551_615UL; // 2^64 - 1
1588//     assert(to!ulong(to!real(c)) == c);
1589//     assert(to!ulong(-to!real(c)) == c);
1590    }
1591    // test conversions floating => integral
1592    {
1593        // AllInts[0 .. $ - 1] should be AllInts
1594        // @@@ BUG IN COMPILER @@@
1595        foreach (Integral; AllInts[0 .. $ - 1])
1596        {
1597            foreach (Floating; AllFloats)
1598            {
1599                testFloatingToIntegral!(Floating, Integral)();
1600            }
1601        }
1602    }
1603    // test conversion integral => floating
1604    {
1605        foreach (Integral; AllInts[0 .. $ - 1])
1606        {
1607            foreach (Floating; AllFloats)
1608            {
1609                testIntegralToFloating!(Integral, Floating)();
1610            }
1611        }
1612    }
1613    // test parsing
1614    {
1615        foreach (T; AllNumerics)
1616        {
1617            // from type immutable(char)[2]
1618            auto a = to!T("42");
1619            assert(a == 42);
1620            // from type char[]
1621            char[] s1 = "42".dup;
1622            a = to!T(s1);
1623            assert(a == 42);
1624            // from type char[2]
1625            char[2] s2;
1626            s2[] = "42";
1627            a = to!T(s2);
1628            assert(a == 42);
1629            // from type immutable(wchar)[2]
1630            a = to!T("42"w);
1631            assert(a == 42);
1632        }
1633    }
1634}
1635/*@safe pure */unittest
1636{
1637    alias AllInts = TypeTuple!(byte, ubyte, short, ushort, int, uint, long, ulong);
1638    alias AllFloats = TypeTuple!(float, double, real);
1639    alias AllNumerics = TypeTuple!(AllInts, AllFloats);
1640    // test conversions to string
1641    {
1642        foreach (T; AllNumerics)
1643        {
1644            T a = 42;
1645            assert(to!string(a) == "42");
1646            //assert(to!wstring(a) == "42"w);
1647            //assert(to!dstring(a) == "42"d);
1648            // array test
1649//       T[] b = new T[2];
1650//       b[0] = 42;
1651//       b[1] = 33;
1652//       assert(to!string(b) == "[42,33]");
1653        }
1654    }
1655    // test array to string conversion
1656    foreach (T ; AllNumerics)
1657    {
1658        auto a = [to!T(1), 2, 3];
1659        assert(to!string(a) == "[1, 2, 3]");
1660    }
1661    // test enum to int conversion
1662    // enum Testing { Test1, Test2 };
1663    // Testing t;
1664    // auto a = to!string(t);
1665    // assert(a == "0");
1666}
1667
1668
1669/**
1670String to non-string conversion runs parsing.
1671$(UL
1672  $(LI When the source is a wide string, it is first converted to a narrow
1673       string and then parsed.)
1674  $(LI When the source is a narrow string, normal text parsing occurs.))
1675*/
1676T toImpl(T, S)(S value)
1677    if ( isExactSomeString!S && isDynamicArray!S &&
1678        !isExactSomeString!T && is(typeof(parse!T(value))))
1679{
1680    scope(success)
1681    {
1682        if (value.length)
1683        {
1684            throw convError!(S, T)(value);
1685        }
1686    }
1687    return parse!T(value);
1688}
1689
1690/// ditto
1691T toImpl(T, S)(S value, uint radix)
1692    if ( isExactSomeString!S && isDynamicArray!S &&
1693        !isExactSomeString!T && is(typeof(parse!T(value, radix))))
1694{
1695    scope(success)
1696    {
1697        if (value.length)
1698        {
1699            throw convError!(S, T)(value);
1700        }
1701    }
1702    return parse!T(value, radix);
1703}
1704
1705@safe pure unittest
1706{
1707    // Issue 6668 - ensure no collaterals thrown
1708    try { to!uint("-1"); }
1709    catch (ConvException e) { assert(e.next is null); }
1710}
1711
1712@safe pure unittest
1713{
1714    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
1715    foreach (Str; TypeTuple!(string, wstring, dstring))
1716    {
1717        Str a = "123";
1718        assert(to!int(a) == 123);
1719        assert(to!double(a) == 123);
1720    }
1721
1722    // 6255
1723    auto n = to!int("FF", 16);
1724    assert(n == 255);
1725}
1726
1727/**
1728Convert a value that is implicitly convertible to the enum base type
1729into an Enum value. If the value does not match any enum member values
1730a ConvException is thrown.
1731Enums with floating-point or string base types are not supported.
1732*/
1733T toImpl(T, S)(S value)
1734    if (is(T == enum) && !is(S == enum)
1735        && is(typeof(value == OriginalType!T.init))
1736        && !isFloatingPoint!(OriginalType!T) && !isSomeString!(OriginalType!T))
1737{
1738    foreach (Member; EnumMembers!T)
1739    {
1740        if (Member == value)
1741            return Member;
1742    }
1743
1744    throw new ConvException(format("Value (%s) does not match any member value of enum '%s'", value, T.stringof));
1745}
1746
1747@safe pure unittest
1748{
1749    enum En8143 : int { A = 10, B = 20, C = 30, D = 20 }
1750    enum En8143[][] m3 = to!(En8143[][])([[10, 30], [30, 10]]);
1751    static assert(m3 == [[En8143.A, En8143.C], [En8143.C, En8143.A]]);
1752
1753    En8143 en1 = to!En8143(10);
1754    assert(en1 == En8143.A);
1755    assertThrown!ConvException(to!En8143(5));   // matches none
1756    En8143[][] m1 = to!(En8143[][])([[10, 30], [30, 10]]);
1757    assert(m1 == [[En8143.A, En8143.C], [En8143.C, En8143.A]]);
1758}
1759
1760/***************************************************************
1761 Rounded conversion from floating point to integral.
1762
1763Example:
1764---------------
1765assert(roundTo!int(3.14) == 3);
1766assert(roundTo!int(3.49) == 3);
1767assert(roundTo!int(3.5) == 4);
1768assert(roundTo!int(3.999) == 4);
1769assert(roundTo!int(-3.14) == -3);
1770assert(roundTo!int(-3.49) == -3);
1771assert(roundTo!int(-3.5) == -4);
1772assert(roundTo!int(-3.999) == -4);
1773---------------
1774Rounded conversions do not work with non-integral target types.
1775 */
1776
1777template roundTo(Target)
1778{
1779    Target roundTo(Source)(Source value)
1780    {
1781        import std.math : trunc;
1782
1783        static assert(isFloatingPoint!Source);
1784        static assert(isIntegral!Target);
1785        return to!Target(trunc(value + (value < 0 ? -0.5L : 0.5L)));
1786    }
1787}
1788
1789unittest
1790{
1791    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
1792    assert(roundTo!int(3.14) == 3);
1793    assert(roundTo!int(3.49) == 3);
1794    assert(roundTo!int(3.5) == 4);
1795    assert(roundTo!int(3.999) == 4);
1796    assert(roundTo!int(-3.14) == -3);
1797    assert(roundTo!int(-3.49) == -3);
1798    assert(roundTo!int(-3.5) == -4);
1799    assert(roundTo!int(-3.999) == -4);
1800    assert(roundTo!(const int)(to!(const double)(-3.999)) == -4);
1801
1802    // boundary values
1803    foreach (Int; TypeTuple!(byte, ubyte, short, ushort, int, uint))
1804    {
1805        assert(roundTo!Int(Int.min - 0.4L) == Int.min);
1806        assert(roundTo!Int(Int.max + 0.4L) == Int.max);
1807        assertThrown!ConvOverflowException(roundTo!Int(Int.min - 0.5L));
1808        assertThrown!ConvOverflowException(roundTo!Int(Int.max + 0.5L));
1809    }
1810}
1811
1812/***************************************************************
1813 * The $(D_PARAM parse) family of functions works quite like the
1814 * $(D_PARAM to) family, except that (1) it only works with character ranges
1815 * as input, (2) takes the input by reference and advances it to
1816 * the position following the conversion, and (3) does not throw if it
1817 * could not convert the entire input. It still throws if an overflow
1818 * occurred during conversion or if no character of the input
1819 * was meaningfully converted.
1820 *
1821 * Example:
1822 * --------------
1823 * string test = "123 \t  76.14";
1824 * auto a = parse!uint(test);
1825 * assert(a == 123);
1826 * assert(test == " \t  76.14"); // parse bumps string
1827 * munch(test, " \t\n\r"); // skip ws
1828 * assert(test == "76.14");
1829 * auto b = parse!double(test);
1830 * assert(b == 76.14);
1831 * assert(test == "");
1832 * --------------
1833 */
1834
1835Target parse(Target, Source)(ref Source s)
1836    if (isSomeChar!(ElementType!Source) &&
1837        isIntegral!Target && !is(Target == enum))
1838{
1839    static if (Target.sizeof < int.sizeof)
1840    {
1841        // smaller types are handled like integers
1842        auto v = .parse!(Select!(Target.min < 0, int, uint))(s);
1843        auto result = ()@trusted{ return cast(Target) v; }();
1844        if (result != v)
1845            goto Loverflow;
1846        return result;
1847    }
1848    else
1849    {
1850        // Larger than int types
1851
1852        static if (Target.min < 0)
1853            int sign = 0;
1854        else
1855            enum int sign = 0;
1856        Target v = 0;
1857        bool atStart = true;
1858        enum char maxLastDigit = Target.min < 0 ? '7' : '5';
1859        while (!s.empty)
1860        {
1861            immutable c = s.front;
1862            if (c >= '0' && c <= '9')
1863            {
1864                if (v >= Target.max/10 &&
1865                        (v != Target.max/10 || c + sign > maxLastDigit))
1866                    goto Loverflow;
1867                v = cast(Target) (v * 10 + (c - '0'));
1868                s.popFront();
1869                atStart = false;
1870            }
1871            else static if (Target.min < 0)
1872            {
1873                if (c == '-' && atStart)
1874                {
1875                    s.popFront();
1876                    sign = -1;
1877                }
1878                else if (c == '+' && atStart)
1879                    s.popFront();
1880                else
1881                    break;
1882            }
1883            else
1884                break;
1885        }
1886        if (atStart)
1887            goto Lerr;
1888        static if (Target.min < 0)
1889        {
1890            if (sign == -1)
1891            {
1892                v = -v;
1893            }
1894        }
1895        return v;
1896    }
1897
1898Loverflow:
1899    throw new ConvOverflowException("Overflow in integral conversion");
1900Lerr:
1901    throw convError!(Source, Target)(s);
1902}
1903
1904@safe pure unittest
1905{
1906    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
1907    string s = "123";
1908    auto a = parse!int(s);
1909}
1910
1911@safe pure unittest
1912{
1913    foreach (Int; TypeTuple!(byte, ubyte, short, ushort, int, uint, long, ulong))
1914    {
1915        debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
1916        debug(conv) printf("conv.to!%.*s.unittest\n", Int.stringof.length, Int.stringof.ptr);
1917
1918        {
1919                assert(to!Int("0") == 0);
1920
1921            static if (isSigned!Int)
1922            {
1923                assert(to!Int("+0") == 0);
1924                assert(to!Int("-0") == 0);
1925            }
1926        }
1927
1928        static if (Int.sizeof >= byte.sizeof)
1929        {
1930                assert(to!Int("6") == 6);
1931                assert(to!Int("23") == 23);
1932                assert(to!Int("68") == 68);
1933                assert(to!Int("127") == 0x7F);
1934
1935            static if (isUnsigned!Int)
1936            {
1937                assert(to!Int("255") == 0xFF);
1938            }
1939            static if (isSigned!Int)
1940            {
1941                assert(to!Int("+6") == 6);
1942                assert(to!Int("+23") == 23);
1943                assert(to!Int("+68") == 68);
1944                assert(to!Int("+127") == 0x7F);
1945
1946                assert(to!Int("-6") == -6);
1947                assert(to!Int("-23") == -23);
1948                assert(to!Int("-68") == -68);
1949                assert(to!Int("-128") == -128);
1950            }
1951        }
1952
1953        static if (Int.sizeof >= short.sizeof)
1954        {
1955                assert(to!Int("468") == 468);
1956                assert(to!Int("32767") == 0x7FFF);
1957
1958            static if (isUnsigned!Int)
1959            {
1960                assert(to!Int("65535") == 0xFFFF);
1961            }
1962            static if (isSigned!Int)
1963            {
1964                assert(to!Int("+468") == 468);
1965                assert(to!Int("+32767") == 0x7FFF);
1966
1967                assert(to!Int("-468") == -468);
1968                assert(to!Int("-32768") == -32768);
1969            }
1970        }
1971
1972        static if (Int.sizeof >= int.sizeof)
1973        {
1974                assert(to!Int("2147483647") == 0x7FFFFFFF);
1975
1976            static if (isUnsigned!Int)
1977            {
1978                assert(to!Int("4294967295") == 0xFFFFFFFF);
1979            }
1980
1981            static if (isSigned!Int)
1982            {
1983                assert(to!Int("+2147483647") == 0x7FFFFFFF);
1984
1985                assert(to!Int("-2147483648") == -2147483648);
1986            }
1987        }
1988
1989        static if (Int.sizeof >= long.sizeof)
1990        {
1991                assert(to!Int("9223372036854775807") == 0x7FFFFFFFFFFFFFFF);
1992
1993            static if (isUnsigned!Int)
1994            {
1995                assert(to!Int("18446744073709551615") == 0xFFFFFFFFFFFFFFFF);
1996            }
1997
1998            static if (isSigned!Int)
1999            {
2000                assert(to!Int("+9223372036854775807") == 0x7FFFFFFFFFFFFFFF);
2001
2002                assert(to!Int("-9223372036854775808") == 0x8000000000000000);
2003            }
2004        }
2005    }
2006}
2007
2008@safe pure unittest
2009{
2010    // parsing error check
2011    foreach (Int; TypeTuple!(byte, ubyte, short, ushort, int, uint, long, ulong))
2012    {
2013        debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
2014        debug(conv) printf("conv.to!%.*s.unittest (error)\n", Int.stringof.length, Int.stringof.ptr);
2015
2016        {
2017            immutable string[] errors1 =
2018            [
2019                "",
2020                "-",
2021                "+",
2022                "-+",
2023                " ",
2024                " 0",
2025                "0 ",
2026                "- 0",
2027                "1-",
2028                "xx",
2029                "123h",
2030            ];
2031            foreach (j, s; errors1)
2032                assertThrown!ConvException(to!Int(s));
2033        }
2034
2035        // parse!SomeUnsigned cannot parse head sign.
2036        static if (isUnsigned!Int)
2037        {
2038            immutable string[] errors2 =
2039            [
2040                "+5",
2041                "-78",
2042            ];
2043            foreach (j, s; errors2)
2044                assertThrown!ConvException(to!Int(s));
2045        }
2046    }
2047
2048    // positive overflow check
2049    foreach (i, Int; TypeTuple!(byte, ubyte, short, ushort, int, uint, long, ulong))
2050    {
2051        debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
2052        debug(conv) printf("conv.to!%.*s.unittest (pos overflow)\n", Int.stringof.length, Int.stringof.ptr);
2053
2054        immutable string[] errors =
2055        [
2056            "128",                  // > byte.max
2057            "256",                  // > ubyte.max
2058            "32768",                // > short.max
2059            "65536",                // > ushort.max
2060            "2147483648",           // > int.max
2061            "4294967296",           // > uint.max
2062            "9223372036854775808",  // > long.max
2063            "18446744073709551616", // > ulong.max
2064        ];
2065        foreach (j, s; errors[i..$])
2066            assertThrown!ConvOverflowException(to!Int(s));
2067    }
2068
2069    // negative overflow check
2070    foreach (i, Int; TypeTuple!(byte, short, int, long))
2071    {
2072        debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
2073        debug(conv) printf("conv.to!%.*s.unittest (neg overflow)\n", Int.stringof.length, Int.stringof.ptr);
2074
2075        immutable string[] errors =
2076        [
2077            "-129",                 // < byte.min
2078            "-32769",               // < short.min
2079            "-2147483649",          // < int.min
2080            "-9223372036854775809", // < long.min
2081        ];
2082        foreach (j, s; errors[i..$])
2083            assertThrown!ConvOverflowException(to!Int(s));
2084    }
2085}
2086
2087@safe pure unittest
2088{
2089    assertCTFEable!({ string s =  "1234abc"; assert(parse! int(s) ==  1234 && s == "abc"); });
2090    assertCTFEable!({ string s = "-1234abc"; assert(parse! int(s) == -1234 && s == "abc"); });
2091    assertCTFEable!({ string s =  "1234abc"; assert(parse!uint(s) ==  1234 && s == "abc"); });
2092}
2093
2094/// ditto
2095Target parse(Target, Source)(ref Source s, uint radix)
2096    if (isSomeChar!(ElementType!Source) &&
2097        isIntegral!Target && !is(Target == enum))
2098in
2099{
2100    assert(radix >= 2 && radix <= 36);
2101}
2102body
2103{
2104    if (radix == 10)
2105        return parse!Target(s);
2106
2107    immutable uint beyond = (radix < 10 ? '0' : 'a'-10) + radix;
2108
2109    Target v = 0;
2110    size_t atStart = true;
2111
2112    for (; !s.empty; s.popFront())
2113    {
2114        uint c = s.front;
2115        if (c < '0')
2116            break;
2117        if (radix < 10)
2118        {
2119            if (c >= beyond)
2120                break;
2121        }
2122        else
2123        {
2124            if (c > '9')
2125            {
2126                c |= 0x20;//poorman's tolower
2127                if (c < 'a' || c >= beyond)
2128                    break;
2129                c -= 'a'-10-'0';
2130            }
2131        }
2132        auto blah = cast(Target) (v * radix + c - '0');
2133        if (blah < v)
2134            goto Loverflow;
2135        v = blah;
2136        atStart = false;
2137    }
2138    if (atStart)
2139        goto Lerr;
2140    return v;
2141
2142Loverflow:
2143    throw new ConvOverflowException("Overflow in integral conversion");
2144Lerr:
2145    throw convError!(Source, Target)(s, radix);
2146}
2147
2148@safe pure unittest
2149{
2150    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
2151    // @@@BUG@@@ the size of China
2152        // foreach (i; 2..37)
2153        // {
2154        //      assert(parse!int("0",i) == 0);
2155        //      assert(parse!int("1",i) == 1);
2156        //      assert(parse!byte("10",i) == i);
2157        // }
2158        foreach (i; 2..37)
2159        {
2160            string s = "0";
2161                assert(parse!int(s,i) == 0);
2162            s = "1";
2163                assert(parse!int(s,i) == 1);
2164            s = "10";
2165                assert(parse!byte(s,i) == i);
2166        }
2167    // Same @@@BUG@@@ as above
2168        //assert(parse!int("0011001101101", 2) == 0b0011001101101);
2169        // assert(parse!int("765",8) == 0765);
2170        // assert(parse!int("fCDe",16) == 0xfcde);
2171    auto s = "0011001101101";
2172        assert(parse!int(s, 2) == 0b0011001101101);
2173    s = "765";
2174        assert(parse!int(s, 8) == octal!765);
2175    s = "fCDe";
2176        assert(parse!int(s, 16) == 0xfcde);
2177
2178    // 6609
2179    s = "-42";
2180    assert(parse!int(s, 10) == -42);
2181}
2182
2183@safe pure unittest // bugzilla 7302
2184{
2185    auto r = cycle("2A!");
2186    auto u = parse!uint(r, 16);
2187    assert(u == 42);
2188    assert(r.front == '!');
2189}
2190
2191Target parse(Target, Source)(ref Source s)
2192    if (isExactSomeString!Source &&
2193        is(Target == enum))
2194{
2195    Target result;
2196    size_t longest_match = 0;
2197
2198    foreach (i, e; EnumMembers!Target)
2199    {
2200        auto ident = __traits(allMembers, Target)[i];
2201        if (longest_match < ident.length && s.startsWith(ident))
2202        {
2203            result = e;
2204            longest_match = ident.length ;
2205        }
2206    }
2207
2208    if (longest_match > 0)
2209    {
2210        s = s[longest_match .. $];
2211        return result ;
2212    }
2213
2214    throw new ConvException(
2215        Target.stringof ~ " does not have a member named '"
2216        ~ to!string(s) ~ "'");
2217}
2218
2219unittest
2220{
2221    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
2222
2223    enum EB : bool { a = true, b = false, c = a }
2224    enum EU { a, b, c }
2225    enum EI { a = -1, b = 0, c = 1 }
2226    enum EF : real { a = 1.414, b = 1.732, c = 2.236 }
2227    enum EC : char { a = 'a', b = 'b', c = 'c' }
2228    enum ES : string { a = "aaa", b = "bbb", c = "ccc" }
2229
2230    foreach (E; TypeTuple!(EB, EU, EI, EF, EC, ES))
2231    {
2232        assert(to!E("a"c) == E.a);
2233        assert(to!E("b"w) == E.b);
2234        assert(to!E("c"d) == E.c);
2235
2236        assertThrown!ConvException(to!E("d"));
2237    }
2238}
2239
2240@safe pure unittest // bugzilla 4744
2241{
2242    enum A { member1, member11, member111 }
2243    assert(to!A("member1"  ) == A.member1  );
2244    assert(to!A("member11" ) == A.member11 );
2245    assert(to!A("member111") == A.member111);
2246    auto s = "member1111";
2247    assert(parse!A(s) == A.member111 && s == "1");
2248}
2249
2250Target parse(Target, Source)(ref Source p)
2251    if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum) &&
2252        isFloatingPoint!Target && !is(Target == enum))
2253{
2254    static import core.stdc.math/* : HUGE_VAL*/;
2255
2256    static immutable real[14] negtab =
2257        [ 1e-4096L,1e-2048L,1e-1024L,1e-512L,1e-256L,1e-128L,1e-64L,1e-32L,
2258                1e-16L,1e-8L,1e-4L,1e-2L,1e-1L,1.0L ];
2259    static immutable real[13] postab =
2260        [ 1e+4096L,1e+2048L,1e+1024L,1e+512L,1e+256L,1e+128L,1e+64L,1e+32L,
2261                1e+16L,1e+8L,1e+4L,1e+2L,1e+1L ];
2262    // static immutable string infinity = "infinity";
2263    // static immutable string nans = "nans";
2264
2265    ConvException bailOut()(string msg = null, string fn = __FILE__, size_t ln = __LINE__)
2266    {
2267        if (!msg)
2268            msg = "Floating point conversion error";
2269        return new ConvException(text(msg, " for input \"", p, "\"."), fn, ln);
2270    }
2271
2272    enforce(!p.empty, bailOut());
2273
2274    char sign = 0;                       /* indicating +                 */
2275    switch (p.front)
2276    {
2277    case '-':
2278        sign++;
2279        p.popFront();
2280        enforce(!p.empty, bailOut());
2281        if (std.ascii.toLower(p.front) == 'i')
2282            goto case 'i';
2283        enforce(!p.empty, bailOut());
2284        break;
2285    case '+':
2286        p.popFront();
2287        enforce(!p.empty, bailOut());
2288        break;
2289    case 'i': case 'I':
2290        p.popFront();
2291        enforce(!p.empty, bailOut());
2292        if (std.ascii.toLower(p.front) == 'n' &&
2293                (p.popFront(), enforce(!p.empty, bailOut()), std.ascii.toLower(p.front) == 'f'))
2294        {
2295            // 'inf'
2296            p.popFront();
2297            return sign ? -Target.infinity : Target.infinity;
2298        }
2299        goto default;
2300    default: {}
2301    }
2302
2303    bool isHex = false;
2304    bool startsWithZero = p.front == '0';
2305    if(startsWithZero)
2306    {
2307        p.popFront();
2308        if(p.empty)
2309        {
2310            return (sign) ? -0.0 : 0.0;
2311        }
2312
2313        isHex = p.front == 'x' || p.front == 'X';
2314    }
2315
2316    real ldval = 0.0;
2317    char dot = 0;                        /* if decimal point has been seen */
2318    int exp = 0;
2319    long msdec = 0, lsdec = 0;
2320    ulong msscale = 1;
2321
2322    if (isHex)
2323    {
2324        int guard = 0;
2325        int anydigits = 0;
2326        uint ndigits = 0;
2327
2328        p.popFront();
2329        while (!p.empty)
2330        {
2331            int i = p.front;
2332            while (isHexDigit(i))
2333            {
2334                anydigits = 1;
2335                i = std.ascii.isAlpha(i) ? ((i & ~0x20) - ('A' - 10)) : i - '0';
2336                if (ndigits < 16)
2337                {
2338                    msdec = msdec * 16 + i;
2339                    if (msdec)
2340                        ndigits++;
2341                }
2342                else if (ndigits == 16)
2343                {
2344                    while (msdec >= 0)
2345                    {
2346                        exp--;
2347                        msdec <<= 1;
2348                        i <<= 1;
2349                        if (i & 0x10)
2350                            msdec |= 1;
2351                    }
2352                    guard = i << 4;
2353                    ndigits++;
2354                    exp += 4;
2355                }
2356                else
2357                {
2358                    guard |= i;
2359                    exp += 4;
2360                }
2361                exp -= dot;
2362                p.popFront();
2363                if (p.empty)
2364                    break;
2365                i = p.front;
2366                if (i == '_')
2367                {
2368                    p.popFront();
2369                    if (p.empty)
2370                        break;
2371                    i = p.front;
2372                }
2373            }
2374            if (i == '.' && !dot)
2375            {       p.popFront();
2376                dot = 4;
2377            }
2378            else
2379                break;
2380        }
2381
2382        // Round up if (guard && (sticky || odd))
2383        if (guard & 0x80 && (guard & 0x7F || msdec & 1))
2384        {
2385            msdec++;
2386            if (msdec == 0)                 // overflow
2387            {   msdec = 0x8000000000000000L;
2388                exp++;
2389            }
2390        }
2391
2392        enforce(anydigits, bailOut());
2393        enforce(!p.empty && (p.front == 'p' || p.front == 'P'),
2394                bailOut("Floating point parsing: exponent is required"));
2395        char sexp;
2396        int e;
2397
2398        sexp = 0;
2399        p.popFront();
2400        if (!p.empty)
2401        {
2402            switch (p.front)
2403            {   case '-':    sexp++;
2404                             goto case;
2405                case '+':    p.popFront(); enforce(!p.empty,
2406                                new ConvException("Error converting input"
2407                                " to floating point"));
2408                             break;
2409                default: {}
2410            }
2411        }
2412        ndigits = 0;
2413        e = 0;
2414        while (!p.empty && isDigit(p.front))
2415        {
2416            if (e < 0x7FFFFFFF / 10 - 10) // prevent integer overflow
2417            {
2418                e = e * 10 + p.front - '0';
2419            }
2420            p.popFront();
2421            ndigits = 1;
2422        }
2423        exp += (sexp) ? -e : e;
2424        enforce(ndigits, new ConvException("Error converting input"
2425                        " to floating point"));
2426
2427        if (msdec)
2428        {
2429            int e2 = 0x3FFF + 63;
2430
2431            // left justify mantissa
2432            while (msdec >= 0)
2433            {   msdec <<= 1;
2434                e2--;
2435            }
2436
2437            // Stuff mantissa directly into real
2438            ()@trusted{ *cast(long*)&ldval = msdec; }();
2439            ()@trusted{ (cast(ushort*)&ldval)[4] = cast(ushort) e2; }();
2440
2441            import std.math : ldexp;
2442
2443            // Exponent is power of 2, not power of 10
2444            ldval = ldexp(ldval, exp);
2445        }
2446        goto L6;
2447    }
2448    else // not hex
2449    {
2450        if (std.ascii.toUpper(p.front) == 'N' && !startsWithZero)
2451        {
2452            // nan
2453            enforce((p.popFront(), !p.empty && std.ascii.toUpper(p.front) == 'A')
2454                    && (p.popFront(), !p.empty && std.ascii.toUpper(p.front) == 'N'),
2455                   new ConvException("error converting input to floating point"));
2456            // skip past the last 'n'
2457            p.popFront();
2458            return typeof(return).nan;
2459        }
2460
2461        bool sawDigits = startsWithZero;
2462
2463        while (!p.empty)
2464        {
2465            int i = p.front;
2466            while (isDigit(i))
2467            {
2468                sawDigits = true;        /* must have at least 1 digit   */
2469                if (msdec < (0x7FFFFFFFFFFFL-10)/10)
2470                    msdec = msdec * 10 + (i - '0');
2471                else if (msscale < (0xFFFFFFFF-10)/10)
2472                {   lsdec = lsdec * 10 + (i - '0');
2473                    msscale *= 10;
2474                }
2475                else
2476                {
2477                    exp++;
2478                }
2479                exp -= dot;
2480                p.popFront();
2481                if (p.empty)
2482                    break;
2483                i = p.front;
2484                if (i == '_')
2485                {
2486                    p.popFront();
2487                    if (p.empty)
2488                        break;
2489                    i = p.front;
2490                }
2491            }
2492            if (i == '.' && !dot)
2493            {
2494                p.popFront();
2495                dot++;
2496            }
2497            else
2498            {
2499                break;
2500            }
2501        }
2502        enforce(sawDigits, new ConvException("no digits seen"));
2503    }
2504    if (!p.empty && (p.front == 'e' || p.front == 'E'))
2505    {
2506        char sexp;
2507        int e;
2508
2509        sexp = 0;
2510        p.popFront();
2511        enforce(!p.empty, new ConvException("Unexpected end of input"));
2512        switch (p.front)
2513        {   case '-':    sexp++;
2514                         goto case;
2515            case '+':    p.popFront();
2516                         break;
2517            default: {}
2518        }
2519        bool sawDigits = 0;
2520        e = 0;
2521        while (!p.empty && isDigit(p.front))
2522        {
2523            if (e < 0x7FFFFFFF / 10 - 10)   // prevent integer overflow
2524            {
2525                e = e * 10 + p.front - '0';
2526            }
2527            p.popFront();
2528            sawDigits = 1;
2529        }
2530        exp += (sexp) ? -e : e;
2531        enforce(sawDigits, new ConvException("No digits seen."));
2532    }
2533
2534    ldval = msdec;
2535    if (msscale != 1)               /* if stuff was accumulated in lsdec */
2536        ldval = ldval * msscale + lsdec;
2537    if (ldval)
2538    {
2539        uint u = 0;
2540        int pow = 4096;
2541
2542        while (exp > 0)
2543        {
2544            while (exp >= pow)
2545            {
2546                ldval *= postab[u];
2547                exp -= pow;
2548            }
2549            pow >>= 1;
2550            u++;
2551        }
2552        while (exp < 0)
2553        {
2554            while (exp <= -pow)
2555            {
2556                ldval *= negtab[u];
2557                enforce(ldval != 0, new ConvException("Range error"));
2558                exp += pow;
2559            }
2560            pow >>= 1;
2561            u++;
2562        }
2563    }
2564  L6: // if overflow occurred
2565    enforce(ldval != core.stdc.math.HUGE_VAL, new ConvException("Range error"));
2566
2567  L1:
2568    return (sign) ? -ldval : ldval;
2569}
2570
2571unittest
2572{
2573    import std.math : isnan, fabs;
2574
2575    // Compare reals with given precision
2576    bool feq(in real rx, in real ry, in real precision = 0.000001L)
2577    {
2578        if (rx == ry)
2579            return 1;
2580
2581        if (isnan(rx))
2582            return cast(bool)isnan(ry);
2583
2584        if (isnan(ry))
2585            return 0;
2586
2587        return cast(bool)(fabs(rx - ry) <= precision);
2588    }
2589
2590    // Make given typed literal
2591    F Literal(F)(F f)
2592    {
2593        return f;
2594    }
2595
2596    foreach (Float; TypeTuple!(float, double, real))
2597    {
2598        debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
2599        debug(conv) printf("conv.to!%.*s.unittest\n", Float.stringof.length, Float.stringof.ptr);
2600
2601        assert(to!Float("123") == Literal!Float(123));
2602        assert(to!Float("+123") == Literal!Float(+123));
2603        assert(to!Float("-123") == Literal!Float(-123));
2604        assert(to!Float("123e2") == Literal!Float(123e2));
2605        assert(to!Float("123e+2") == Literal!Float(123e+2));
2606        assert(to!Float("123e-2") == Literal!Float(123e-2));
2607        assert(to!Float("123.") == Literal!Float(123.0));
2608        assert(to!Float(".375") == Literal!Float(.375));
2609
2610        assert(to!Float("1.23375E+2") == Literal!Float(1.23375E+2));
2611
2612        assert(to!Float("0") is 0.0);
2613        assert(to!Float("-0") is -0.0);
2614
2615        assert(isnan(to!Float("nan")));
2616
2617        assertThrown!ConvException(to!Float("\x00"));
2618    }
2619
2620    // min and max
2621    float f = to!float("1.17549e-38");
2622    assert(feq(cast(real)f, cast(real)1.17549e-38));
2623    assert(feq(cast(real)f, cast(real)float.min_normal));
2624    f = to!float("3.40282e+38");
2625    assert(to!string(f) == to!string(3.40282e+38));
2626
2627    // min and max
2628    double d = to!double("2.22508e-308");
2629    assert(feq(cast(real)d, cast(real)2.22508e-308));
2630    assert(feq(cast(real)d, cast(real)double.min_normal));
2631    d = to!double("1.79769e+308");
2632    assert(to!string(d) == to!string(1.79769e+308));
2633    assert(to!string(d) == to!string(double.max));
2634
2635    assert(to!string(to!real(to!string(real.max / 2L))) == to!string(real.max / 2L));
2636
2637    // min and max
2638    real r = to!real(to!string(real.min_normal));
2639    assert(to!string(r) == to!string(real.min_normal));
2640    r = to!real(to!string(real.max));
2641    assert(to!string(r) == to!string(real.max));
2642}
2643
2644unittest
2645{
2646    import core.stdc.errno;
2647    import core.stdc.stdlib;
2648
2649    errno = 0;  // In case it was set by another unittest in a different module.
2650    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
2651    struct longdouble
2652    {
2653        ushort[5] value;
2654    }
2655
2656    real ld;
2657    longdouble x;
2658    real ld1;
2659    longdouble x1;
2660    int i;
2661
2662    string s = "0x1.FFFFFFFFFFFFFFFEp-16382";
2663    ld = parse!real(s);
2664    assert(s.empty);
2665    x = *cast(longdouble *)&ld;
2666    ld1 = strtold("0x1.FFFFFFFFFFFFFFFEp-16382", null);
2667    x1 = *cast(longdouble *)&ld1;
2668    assert(x1 == x && ld1 == ld);
2669
2670    // for (i = 4; i >= 0; i--)
2671    // {
2672    //     printf("%04x ", x.value[i]);
2673    // }
2674    // printf("\n");
2675    assert(!errno);
2676
2677    s = "1.0e5";
2678    ld = parse!real(s);
2679    assert(s.empty);
2680    x = *cast(longdouble *)&ld;
2681    ld1 = strtold("1.0e5", null);
2682    x1 = *cast(longdouble *)&ld1;
2683
2684    // for (i = 4; i >= 0; i--)
2685    // {
2686    //     printf("%04x ", x.value[i]);
2687    // }
2688    // printf("\n");
2689}
2690
2691@safe pure unittest
2692{
2693    // Bugzilla 4959
2694    {
2695        auto s = "0 ";
2696        auto x = parse!double(s);
2697        assert(s == " ");
2698        assert(x == 0.0);
2699    }
2700
2701    // Bugzilla 3369
2702    assert(to!float("inf") == float.infinity);
2703    assert(to!float("-inf") == -float.infinity);
2704
2705    // Bugzilla 6160
2706    assert(6_5.536e3L == to!real("6_5.536e3"));                     // 2^16
2707    assert(0x1000_000_000_p10 == to!real("0x1000_000_000_p10"));    // 7.03687e+13
2708
2709    // Bugzilla 6258
2710    assertThrown!ConvException(to!real("-"));
2711    assertThrown!ConvException(to!real("in"));
2712
2713    // Bugzilla 7055
2714    assertThrown!ConvException(to!float("INF2"));
2715
2716    //extra stress testing
2717    auto ssOK    = ["1.", "1.1.1", "1.e5", "2e1e", "2a", "2e1_1",
2718                    "inf", "-inf", "infa", "-infa", "inf2e2", "-inf2e2"];
2719    auto ssKO    = ["", " ", "2e", "2e+", "2e-", "2ee", "2e++1", "2e--1", "2e_1", "+inf"];
2720    foreach (s; ssOK)
2721        parse!double(s);
2722    foreach (s; ssKO)
2723        assertThrown!ConvException(parse!double(s));
2724}
2725
2726/**
2727Parsing one character off a string returns the character and bumps the
2728string up one position.
2729 */
2730Target parse(Target, Source)(ref Source s)
2731    if (isExactSomeString!Source &&
2732        staticIndexOf!(Unqual!Target, dchar, Unqual!(ElementEncodingType!Source)) >= 0)
2733{
2734    if (s.empty)
2735        throw convError!(Source, Target)(s);
2736    static if (is(Unqual!Target == dchar))
2737    {
2738        Target result = s.front;
2739        s.popFront();
2740        return result;
2741    }
2742    else
2743    {
2744        // Special case: okay so parse a Char off a Char[]
2745        Target result = s[0];
2746        s = s[1 .. $];
2747        return result;
2748    }
2749}
2750
2751@safe pure unittest
2752{
2753    foreach (Str; TypeTuple!(string, wstring, dstring))
2754    {
2755        foreach (Char; TypeTuple!(char, wchar, dchar))
2756        {
2757            static if (is(Unqual!Char == dchar) ||
2758                       Char.sizeof == ElementEncodingType!Str.sizeof)
2759            {
2760                Str s = "aaa";
2761                assert(parse!Char(s) == 'a');
2762                assert(s == "aa");
2763            }
2764        }
2765    }
2766}
2767
2768Target parse(Target, Source)(ref Source s)
2769    if (!isSomeString!Source && isInputRange!Source && isSomeChar!(ElementType!Source) &&
2770        isSomeChar!Target && Target.sizeof >= ElementType!Source.sizeof && !is(Target == enum))
2771{
2772    if (s.empty)
2773        throw convError!(Source, Target)(s);
2774    Target result = s.front;
2775    s.popFront();
2776    return result;
2777}
2778
2779// string to bool conversions
2780Target parse(Target, Source)(ref Source s)
2781    if (isExactSomeString!Source &&
2782        is(Unqual!Target == bool))
2783{
2784    if (s.length >= 4 && icmp(s[0 .. 4], "true") == 0)
2785    {
2786        s = s[4 .. $];
2787        return true;
2788    }
2789    if (s.length >= 5 && icmp(s[0 .. 5], "false") == 0)
2790    {
2791        s = s[5 .. $];
2792        return false;
2793    }
2794    throw parseError("bool should be case-insensitive 'true' or 'false'");
2795}
2796
2797/*
2798    Tests for to!bool and parse!bool
2799*/
2800@safe pure unittest
2801{
2802    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
2803    debug(conv) printf("conv.to!bool.unittest\n");
2804
2805    assert (to!bool("TruE") == true);
2806    assert (to!bool("faLse"d) == false);
2807    assertThrown!ConvException(to!bool("maybe"));
2808
2809    auto t = "TrueType";
2810    assert (parse!bool(t) == true);
2811    assert (t == "Type");
2812
2813    auto f = "False killer whale"d;
2814    assert (parse!bool(f) == false);
2815    assert (f == " killer whale"d);
2816
2817    auto m = "maybe";
2818    assertThrown!ConvException(parse!bool(m));
2819    assert (m == "maybe");  // m shouldn't change on failure
2820
2821    auto s = "true";
2822    auto b = parse!(const(bool))(s);
2823    assert(b == true);
2824}
2825
2826// string to null literal conversions
2827Target parse(Target, Source)(ref Source s)
2828    if (isExactSomeString!Source &&
2829        is(Unqual!Target == typeof(null)))
2830{
2831    if (s.length >= 4 && icmp(s[0 .. 4], "null") == 0)
2832    {
2833        s = s[4 .. $];
2834        return null;
2835    }
2836    throw parseError("null should be case-insensitive 'null'");
2837}
2838
2839@safe pure unittest
2840{
2841    alias typeof(null) NullType;
2842    auto s1 = "null";
2843    assert(parse!NullType(s1) is null);
2844    assert(s1 == "");
2845
2846    auto s2 = "NUll"d;
2847    assert(parse!NullType(s2) is null);
2848    assert(s2 == "");
2849
2850    auto m = "maybe";
2851    assertThrown!ConvException(parse!NullType(m));
2852    assert(m == "maybe");  // m shouldn't change on failure
2853
2854    auto s = "NULL";
2855    assert(parse!(const NullType)(s) is null);
2856}
2857
2858//Used internally by parse Array/AA, to remove ascii whites
2859package void skipWS(R)(ref R r)
2860{
2861    static if (isSomeString!R)
2862    {
2863        //Implementation inspired from stripLeft.
2864        foreach (i, dchar c; r)
2865        {
2866            if (!std.ascii.isWhite(c))
2867            {
2868                r = r[i .. $];
2869                return;
2870            }
2871        }
2872        r = r[0 .. 0]; //Empty string with correct type.
2873        return;
2874    }
2875    else
2876    {
2877        for (; !r.empty && std.ascii.isWhite(r.front); r.popFront())
2878        {}
2879    }
2880}
2881
2882/**
2883 * Parses an array from a string given the left bracket (default $(D
2884 * '[')), right bracket (default $(D ']')), and element separator (by
2885 * default $(D ',')).
2886 */
2887Target parse(Target, Source)(ref Source s, dchar lbracket = '[', dchar rbracket = ']', dchar comma = ',')
2888    if (isExactSomeString!Source &&
2889        isDynamicArray!Target && !is(Target == enum))
2890{
2891    Target result;
2892
2893    parseCheck!s(lbracket);
2894    skipWS(s);
2895    if (s.empty)
2896        throw convError!(Source, Target)(s);
2897    if (s.front == rbracket)
2898    {
2899        s.popFront();
2900        return result;
2901    }
2902    for (;; s.popFront(), skipWS(s))
2903    {
2904        result ~= parseElement!(ElementType!Target)(s);
2905        skipWS(s);
2906        if (s.empty)
2907            throw convError!(Source, Target)(s);
2908        if (s.front != comma)
2909            break;
2910    }
2911    parseCheck!s(rbracket);
2912
2913    return result;
2914}
2915
2916unittest
2917{
2918    int[] a = [1, 2, 3, 4, 5];
2919    auto s = to!string(a);
2920    assert(to!(int[])(s) == a);
2921}
2922
2923unittest
2924{
2925    int[][] a = [ [1, 2] , [3], [4, 5] ];
2926    auto s = to!string(a);
2927    assert(to!(int[][])(s) == a);
2928}
2929
2930unittest
2931{
2932    int[][][] ia = [ [[1,2],[3,4],[5]] , [[6],[],[7,8,9]] , [[]] ];
2933
2934    char[] s = to!(char[])(ia);
2935    int[][][] ia2;
2936
2937    ia2 = to!(typeof(ia2))(s);
2938    assert( ia == ia2);
2939}
2940
2941@safe pure unittest
2942{
2943    auto s1 = `[['h', 'e', 'l', 'l', 'o'], "world"]`;
2944    auto a1 = parse!(string[])(s1);
2945    assert(a1 == ["hello", "world"]);
2946
2947    auto s2 = `["aaa", "bbb", "ccc"]`;
2948    auto a2 = parse!(string[])(s2);
2949    assert(a2 == ["aaa", "bbb", "ccc"]);
2950}
2951
2952@safe pure unittest
2953{
2954    //Check proper failure
2955    auto s = "[ 1 , 2 , 3 ]";
2956    foreach (i ; 0..s.length-1)
2957    {
2958        auto ss = s[0 .. i];
2959        assertThrown!ConvException(parse!(int[])(ss));
2960    }
2961    int[] arr = parse!(int[])(s);
2962}
2963
2964@safe pure unittest
2965{
2966    //Checks parsing of strings with escaped characters
2967    string s1 = `[
2968        "Contains a\0null!",
2969        "tab\there",
2970        "line\nbreak",
2971        "backslash \\ slash / question \?",
2972        "number \x35 five",
2973        "unicode \u65E5 sun",
2974        "very long \U000065E5 sun"
2975    ]`;
2976
2977    //Note: escaped characters purposefully replaced and isolated to guarantee
2978    //there are no typos in the escape syntax
2979    string[] s2 = [
2980        "Contains a" ~ '\0' ~ "null!",
2981        "tab" ~ '\t' ~ "here",
2982        "line" ~ '\n' ~ "break",
2983        "backslash " ~ '\\' ~ " slash / question ?",
2984        "number 5 five",
2985        "unicode 日 sun",
2986        "very long 日 sun"
2987    ];
2988    assert(s2 == parse!(string[])(s1));
2989    assert(s1.empty);
2990}
2991
2992/// ditto
2993Target parse(Target, Source)(ref Source s, dchar lbracket = '[', dchar rbracket = ']', dchar comma = ',')
2994    if (isExactSomeString!Source &&
2995        isStaticArray!Target && !is(Target == enum))
2996{
2997    static if (hasIndirections!Target)
2998        Target result = Target.init[0].init;
2999    else
3000        Target result = void;
3001
3002    parseCheck!s(lbracket);
3003    skipWS(s);
3004    if (s.empty)
3005        throw convError!(Source, Target)(s);
3006    if (s.front == rbracket)
3007    {
3008        static if (result.length != 0)
3009            goto Lmanyerr;
3010        else
3011        {
3012            s.popFront();
3013            return result;
3014        }
3015    }
3016    for (size_t i = 0; ; s.popFront(), skipWS(s))
3017    {
3018        if (i == result.length)
3019            goto Lmanyerr;
3020        result[i++] = parseElement!(ElementType!Target)(s);
3021        skipWS(s);
3022        if (s.empty)
3023            throw convError!(Source, Target)(s);
3024        if (s.front != comma)
3025        {
3026            if (i != result.length)
3027                goto Lfewerr;
3028            break;
3029        }
3030    }
3031    parseCheck!s(rbracket);
3032
3033    return result;
3034
3035Lmanyerr:
3036    throw parseError(text("Too many elements in input, ", result.length, " elements expected."));
3037
3038Lfewerr:
3039    throw parseError(text("Too few elements in input, ", result.length, " elements expected."));
3040}
3041
3042@safe pure unittest
3043{
3044    auto s1 = "[1,2,3,4]";
3045    auto sa1 = parse!(int[4])(s1);
3046    assert(sa1 == [1,2,3,4]);
3047
3048    auto s2 = "[[1],[2,3],[4]]";
3049    auto sa2 = parse!(int[][3])(s2);
3050    assert(sa2 == [[1],[2,3],[4]]);
3051
3052    auto s3 = "[1,2,3]";
3053    assertThrown!ConvException(parse!(int[4])(s3));
3054
3055    auto s4 = "[1,2,3,4,5]";
3056    assertThrown!ConvException(parse!(int[4])(s4));
3057}
3058
3059/**
3060 * Parses an associative array from a string given the left bracket (default $(D
3061 * '[')), right bracket (default $(D ']')), key-value separator (default $(D
3062 * ':')), and element seprator (by default $(D ',')).
3063 */
3064Target parse(Target, Source)(ref Source s, dchar lbracket = '[', dchar rbracket = ']', dchar keyval = ':', dchar comma = ',')
3065    if (isExactSomeString!Source &&
3066        isAssociativeArray!Target && !is(Target == enum))
3067{
3068    alias KeyType = typeof(Target.init.keys[0]);
3069    alias ValType = typeof(Target.init.values[0]);
3070
3071    Target result;
3072
3073    parseCheck!s(lbracket);
3074    skipWS(s);
3075    if (s.empty)
3076        throw convError!(Source, Target)(s);
3077    if (s.front == rbracket)
3078    {
3079        s.popFront();
3080        return result;
3081    }
3082    for (;; s.popFront(), skipWS(s))
3083    {
3084        auto key = parseElement!KeyType(s);
3085        skipWS(s);
3086        parseCheck!s(keyval);
3087        skipWS(s);
3088        auto val = parseElement!ValType(s);
3089        skipWS(s);
3090        result[key] = val;
3091        if (s.empty)
3092            throw convError!(Source, Target)(s);
3093        if (s.front != comma)
3094            break;
3095    }
3096    parseCheck!s(rbracket);
3097
3098    return result;
3099}
3100
3101@safe pure unittest
3102{
3103    auto s1 = "[1:10, 2:20, 3:30]";
3104    auto aa1 = parse!(int[int])(s1);
3105    assert(aa1 == [1:10, 2:20, 3:30]);
3106
3107    auto s2 = `["aaa":10, "bbb":20, "ccc":30]`;
3108    auto aa2 = parse!(int[string])(s2);
3109    assert(aa2 == ["aaa":10, "bbb":20, "ccc":30]);
3110
3111    auto s3 = `["aaa":[1], "bbb":[2,3], "ccc":[4,5,6]]`;
3112    auto aa3 = parse!(int[][string])(s3);
3113    assert(aa3 == ["aaa":[1], "bbb":[2,3], "ccc":[4,5,6]]);
3114}
3115
3116@safe pure unittest
3117{
3118    //Check proper failure
3119    auto s = "[1:10, 2:20, 3:30]";
3120    foreach (i ; 0 .. s.length-1)
3121    {
3122        auto ss = s[0 .. i];
3123        assertThrown!ConvException(parse!(int[int])(ss));
3124    }
3125    int[int] aa = parse!(int[int])(s);
3126}
3127
3128private dchar parseEscape(Source)(ref Source s)
3129    if (isInputRange!Source && isSomeChar!(ElementType!Source))
3130{
3131    parseCheck!s('\\');
3132    if (s.empty)
3133        throw parseError("Unterminated escape sequence");
3134
3135    dchar getHexDigit()(ref Source s_ = s)  // workaround
3136    {
3137        if (s_.empty)
3138            throw parseError("Unterminated escape sequence");
3139        s_.popFront();
3140        if (s_.empty)
3141            throw parseError("Unterminated escape sequence");
3142        dchar c = s_.front;
3143        if (!isHexDigit(c))
3144            throw parseError("Hex digit is missing");
3145        return std.ascii.isAlpha(c) ? ((c & ~0x20) - ('A' - 10)) : c - '0';
3146    }
3147
3148    dchar result;
3149
3150    switch (s.front)
3151    {
3152        case '"':   result = '\"';  break;
3153        case '\'':  result = '\'';  break;
3154        case '0':   result = '\0';  break;
3155        case '?':   result = '\?';  break;
3156        case '\\':  result = '\\';  break;
3157        case 'a':   result = '\a';  break;
3158        case 'b':   result = '\b';  break;
3159        case 'f':   result = '\f';  break;
3160        case 'n':   result = '\n';  break;
3161        case 'r':   result = '\r';  break;
3162        case 't':   result = '\t';  break;
3163        case 'v':   result = '\v';  break;
3164        case 'x':
3165            result  = getHexDigit() << 4;
3166            result |= getHexDigit();
3167            break;
3168        case 'u':
3169            result  = getHexDigit() << 12;
3170            result |= getHexDigit() << 8;
3171            result |= getHexDigit() << 4;
3172            result |= getHexDigit();
3173            break;
3174        case 'U':
3175            result  = getHexDigit() << 28;
3176            result |= getHexDigit() << 24;
3177            result |= getHexDigit() << 20;
3178            result |= getHexDigit() << 16;
3179            result |= getHexDigit() << 12;
3180            result |= getHexDigit() << 8;
3181            result |= getHexDigit() << 4;
3182            result |= getHexDigit();
3183            break;
3184        default:
3185            throw parseError("Unknown escape character " ~ to!string(s.front));
3186    }
3187    if (s.empty)
3188        throw parseError("Unterminated escape sequence");
3189
3190    s.popFront();
3191
3192    return result;
3193}
3194
3195@safe pure unittest
3196{
3197    string[] s1 = [
3198        `\"`, `\'`, `\?`, `\\`, `\a`, `\b`, `\f`, `\n`, `\r`, `\t`, `\v`, //Normal escapes
3199        //`\141`, //@@@9621@@@ Octal escapes.
3200        `\x61`,
3201        `\u65E5`, `\U00012456`
3202        //`\&amp;`, `\&quot;`, //@@@9621@@@ Named Character Entities.
3203    ];
3204
3205    const(dchar)[] s2 = [
3206        '\"', '\'', '\?', '\\', '\a', '\b', '\f', '\n', '\r', '\t', '\v', //Normal escapes
3207        //'\141', //@@@9621@@@ Octal escapes.
3208        '\x61',
3209        '\u65E5', '\U00012456'
3210        //'\&amp;', '\&quot;', //@@@9621@@@ Named Character Entities.
3211    ];
3212
3213    foreach (i ; 0 .. s1.length)
3214    {
3215        assert(s2[i] == parseEscape(s1[i]));
3216        assert(s1[i].empty);
3217    }
3218}
3219
3220@safe pure unittest
3221{
3222    string[] ss = [
3223        `hello!`,  //Not an escape
3224        `\`,       //Premature termination
3225        `\/`,      //Not an escape
3226        `\gggg`,   //Not an escape
3227        `\xzz`,    //Not an hex
3228        `\x0`,     //Premature hex end
3229        `\XB9`,    //Not legal hex syntax
3230        `\u!!`,    //Not a unicode hex
3231        `\777`,    //Octal is larger than a byte //Note: Throws, but simply because octals are unsupported
3232        `\u123`,   //Premature hex end
3233        `\U123123` //Premature hex end
3234    ];
3235    foreach (s ; ss)
3236        assertThrown!ConvException(parseEscape(s));
3237}
3238
3239// Undocumented
3240Target parseElement(Target, Source)(ref Source s)
3241    if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum) &&
3242        isExactSomeString!Target)
3243{
3244    auto result = appender!Target();
3245
3246    // parse array of chars
3247    if (s.empty)
3248        throw convError!(Source, Target)(s);
3249    if (s.front == '[')
3250        return parse!Target(s);
3251
3252    parseCheck!s('\"');
3253    if (s.empty)
3254        throw convError!(Source, Target)(s);
3255    if (s.front == '\"')
3256    {
3257        s.popFront();
3258        return result.data;
3259    }
3260    while (true)
3261    {
3262        if (s.empty)
3263            throw parseError("Unterminated quoted string");
3264        switch (s.front)
3265        {
3266            case '\"':
3267                s.popFront();
3268                return result.data;
3269            case '\\':
3270                result.put(parseEscape(s));
3271                break;
3272            default:
3273                result.put(s.front);
3274                s.popFront();
3275                break;
3276        }
3277    }
3278    assert(0);
3279}
3280
3281// ditto
3282Target parseElement(Target, Source)(ref Source s)
3283    if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum) &&
3284        isSomeChar!Target && !is(Target == enum))
3285{
3286    Target c;
3287
3288    parseCheck!s('\'');
3289    if (s.empty)
3290        throw convError!(Source, Target)(s);
3291    if (s.front != '\\')
3292    {
3293        c = s.front;
3294        s.popFront();
3295    }
3296    else
3297        c = parseEscape(s);
3298    parseCheck!s('\'');
3299
3300    return c;
3301}
3302
3303// ditto
3304Target parseElement(Target, Source)(ref Source s)
3305    if (isInputRange!Source && isSomeChar!(ElementType!Source) &&
3306        !isSomeString!Target && !isSomeChar!Target)
3307{
3308    return parse!Target(s);
3309}
3310
3311
3312/***************************************************************
3313 * Convenience functions for converting any number and types of
3314 * arguments into _text (the three character widths).
3315 */
3316string text(T...)(T args) { return textImpl!string(args); }
3317///ditto
3318wstring wtext(T...)(T args) { return textImpl!wstring(args); }
3319///ditto
3320dstring dtext(T...)(T args) { return textImpl!dstring(args); }
3321
3322private S textImpl(S, U...)(U args)
3323{
3324    static if (U.length == 0)
3325    {
3326        return null;
3327    }
3328    else
3329    {
3330        auto result = to!S(args[0]);
3331        foreach (arg; args[1 .. $])
3332            result ~= to!S(arg);
3333        return result;
3334    }
3335}
3336///
3337unittest
3338{
3339    assert( text(42, ' ', 1.5, ": xyz") == "42 1.5: xyz"c);
3340    assert(wtext(42, ' ', 1.5, ": xyz") == "42 1.5: xyz"w);
3341    assert(dtext(42, ' ', 1.5, ": xyz") == "42 1.5: xyz"d);
3342}
3343unittest
3344{
3345    assert(text() is null);
3346    assert(wtext() is null);
3347    assert(dtext() is null);
3348}
3349
3350
3351/***************************************************************
3352The $(D octal) facility is intended as an experimental facility to
3353replace _octal literals starting with $(D '0'), which many find
3354confusing. Using $(D octal!177) or $(D octal!"177") instead of $(D
33550177) as an _octal literal makes code clearer and the intent more
3356visible. If use of this facility becomes preponderent, a future
3357version of the language may deem old-style _octal literals deprecated.
3358
3359The rules for strings are the usual for literals: If it can fit in an
3360$(D int), it is an $(D int). Otherwise, it is a $(D long). But, if the
3361user specifically asks for a $(D long) with the $(D L) suffix, always
3362give the $(D long). Give an unsigned iff it is asked for with the $(D
3363U) or $(D u) suffix. _Octals created from integers preserve the type
3364of the passed-in integral.
3365
3366Example:
3367----
3368// same as 0177
3369auto x = octal!177;
3370// octal is a compile-time device
3371enum y = octal!160;
3372// Create an unsigned octal
3373auto z = octal!"1_000_000u";
3374----
3375 */
3376@property int octal(string num)()
3377    if((octalFitsInInt!(num) && !literalIsLong!(num)) && !literalIsUnsigned!(num))
3378{
3379    return octal!(int, num);
3380}
3381
3382/// Ditto
3383@property long octal(string num)()
3384    if((!octalFitsInInt!(num) || literalIsLong!(num)) && !literalIsUnsigned!(num))
3385{
3386    return octal!(long, num);
3387}
3388
3389/// Ditto
3390@property uint octal(string num)()
3391    if((octalFitsInInt!(num) && !literalIsLong!(num)) && literalIsUnsigned!(num))
3392{
3393    return octal!(int, num);
3394}
3395
3396/// Ditto
3397@property ulong octal(string num)()
3398    if((!octalFitsInInt!(num) || literalIsLong!(num)) && literalIsUnsigned!(num))
3399{
3400    return octal!(long, num);
3401}
3402
3403/// Ditto
3404template octal(alias s)
3405    if (isIntegral!(typeof(s)))
3406{
3407    enum auto octal = octal!(typeof(s), to!string(s));
3408}
3409
3410/*
3411    Takes a string, num, which is an octal literal, and returns its
3412    value, in the type T specified.
3413
3414    So:
3415
3416    int a = octal!(int, "10");
3417
3418    assert(a == 8);
3419*/
3420@property T octal(T, string num)()
3421    if (isOctalLiteral!num)
3422{
3423    ulong pow = 1;
3424    T value = 0;
3425
3426    for (int pos = num.length - 1; pos >= 0; pos--)
3427    {
3428        char s = num[pos];
3429        if (s < '0' || s > '7') // we only care about digits; skip the rest
3430        // safe to skip - this is checked out in the assert so these
3431        // are just suffixes
3432            continue;
3433
3434        value += pow * (s - '0');
3435        pow *= 8;
3436    }
3437
3438    return value;
3439}
3440
3441/*
3442Take a look at int.max and int.max+1 in octal and the logic for this
3443function follows directly.
3444 */
3445template octalFitsInInt(string octalNum)
3446{
3447    // note it is important to strip the literal of all
3448    // non-numbers. kill the suffix and underscores lest they mess up
3449    // the number of digits here that we depend on.
3450    enum bool octalFitsInInt = strippedOctalLiteral(octalNum).length < 11 ||
3451        strippedOctalLiteral(octalNum).length == 11 &&
3452        strippedOctalLiteral(octalNum)[0] == '1';
3453}
3454
3455string strippedOctalLiteral(string original)
3456{
3457    string stripped = "";
3458    foreach (c; original)
3459        if (c >= '0' && c <= '7')
3460            stripped ~= c;
3461    return stripped;
3462}
3463
3464template literalIsLong(string num)
3465{
3466    static if (num.length > 1)
3467    // can be xxL or xxLu according to spec
3468        enum literalIsLong = (num[$-1] == 'L' || num[$-2] == 'L');
3469    else
3470        enum literalIsLong = false;
3471}
3472
3473template literalIsUnsigned(string num)
3474{
3475    static if (num.length > 1)
3476    // can be xxU or xxUL according to spec
3477        enum literalIsUnsigned = (num[$-1] == 'u' || num[$-2] == 'u')
3478            // both cases are allowed too
3479            || (num[$-1] == 'U' || num[$-2] == 'U');
3480    else
3481        enum literalIsUnsigned = false;
3482}
3483
3484/*
3485Returns if the given string is a correctly formatted octal literal.
3486
3487The format is specified in lex.html. The leading zero is allowed, but
3488not required.
3489 */
3490bool isOctalLiteralString(string num)
3491{
3492    if (num.length == 0)
3493        return false;
3494
3495    // Must start with a number. To avoid confusion, literals that
3496    // start with a '0' are not allowed
3497    if (num[0] == '0' && num.length > 1)
3498        return false;
3499    if (num[0] < '0' || num[0] > '7')
3500        return false;
3501
3502    foreach (i, c; num)
3503    {
3504        if ((c < '0' || c > '7') && c != '_') // not a legal character
3505        {
3506            if (i < num.length - 2)
3507                    return false;
3508            else   // gotta check for those suffixes
3509            {
3510                if (c != 'U' && c != 'u' && c != 'L')
3511                        return false;
3512                if (i != num.length - 1)
3513                {
3514                    // if we're not the last one, the next one must
3515                    // also be a suffix to be valid
3516                    char c2 = num[$-1];
3517                    if (c2 != 'U' && c2 != 'u' && c2 != 'L')
3518                        return false; // spam at the end of the string
3519                    if (c2 == c)
3520                        return false; // repeats are disallowed
3521                }
3522            }
3523        }
3524    }
3525
3526    return true;
3527}
3528
3529/*
3530    Returns true if the given compile time string is an octal literal.
3531*/
3532template isOctalLiteral(string num)
3533{
3534    enum bool isOctalLiteral = isOctalLiteralString(num);
3535}
3536
3537unittest
3538{
3539    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
3540    // ensure that you get the right types, even with embedded underscores
3541    auto w = octal!"100_000_000_000";
3542    static assert(!is(typeof(w) == int));
3543    auto w2 = octal!"1_000_000_000";
3544    static assert(is(typeof(w2) == int));
3545
3546    static assert(octal!"45" == 37);
3547    static assert(octal!"0" == 0);
3548    static assert(octal!"7" == 7);
3549    static assert(octal!"10" == 8);
3550    static assert(octal!"666" == 438);
3551
3552    static assert(octal!45 == 37);
3553    static assert(octal!0 == 0);
3554    static assert(octal!7 == 7);
3555    static assert(octal!10 == 8);
3556    static assert(octal!666 == 438);
3557
3558    static assert(octal!"66_6" == 438);
3559
3560    static assert(octal!2520046213 == 356535435);
3561    static assert(octal!"2520046213" == 356535435);
3562
3563    static assert(octal!17777777777 == int.max);
3564
3565    static assert(!__traits(compiles, octal!823));
3566
3567    static assert(!__traits(compiles, octal!"823"));
3568
3569    static assert(!__traits(compiles, octal!"_823"));
3570    static assert(!__traits(compiles, octal!"spam"));
3571    static assert(!__traits(compiles, octal!"77%"));
3572
3573    int a;
3574    long b;
3575
3576    // biggest value that should fit in an it
3577    static assert(__traits(compiles,  a = octal!"17777777777"));
3578    // should not fit in the int
3579    static assert(!__traits(compiles, a = octal!"20000000000"));
3580    // ... but should fit in a long
3581    static assert(__traits(compiles, b = octal!"20000000000"));
3582
3583    static assert(!__traits(compiles, a = octal!"1L"));
3584
3585    // this should pass, but it doesn't, since the int converter
3586    // doesn't pass along its suffix to helper templates
3587
3588    //static assert(!__traits(compiles, a = octal!1L));
3589
3590    static assert(__traits(compiles, b = octal!"1L"));
3591    static assert(__traits(compiles, b = octal!1L));
3592}
3593
3594// emplace
3595/**
3596Given a pointer $(D chunk) to uninitialized memory (but already typed
3597as $(D T)), constructs an object of non-$(D class) type $(D T) at that
3598address.
3599
3600Returns: A pointer to the newly constructed object (which is the same
3601as $(D chunk)).
3602 */
3603T* emplace(T)(T* chunk) @safe nothrow pure
3604{
3605    static assert (is(T* : void*),
3606        format("Cannot emplace a %s because it is qualified.", T.stringof));
3607
3608    static assert (is(typeof({static T i;})),
3609        format("Cannot emplace a %1$s because %1$s.this() is annotated with @disable.", T.stringof));
3610
3611    return emplaceInitializer(chunk);
3612}
3613
3614version(unittest) private struct __conv_EmplaceTest
3615{
3616    int i = 3;
3617    this(int i)
3618    {
3619        assert(this.i == 3 && i == 5);
3620        this.i = i;
3621    }
3622    this(int i, ref int j)
3623    {
3624        assert(i == 5 && j == 6);
3625        this.i = i;
3626        ++j;
3627    }
3628
3629@disable:
3630    this();
3631    this(this);
3632    void opAssign();
3633}
3634
3635version(unittest) private class __conv_EmplaceTestClass
3636{
3637    int i = 3;
3638    this(int i)
3639    {
3640        assert(this.i == 3 && i == 5);
3641        this.i = i;
3642    }
3643    this(int i, ref int j)
3644    {
3645        assert(i == 5 && j == 6);
3646        this.i = i;
3647        ++j;
3648    }
3649}
3650
3651unittest
3652{
3653    struct S { @disable this(); }
3654    S s = void;
3655    static assert(!__traits(compiles, emplace(&s)));
3656    static assert( __traits(compiles, emplace(&s, S.init)));
3657}
3658
3659unittest
3660{
3661    interface I {}
3662    class K : I {}
3663
3664    K k = void;
3665    emplace(&k);
3666    assert(k is null);
3667
3668    I i = void;
3669    emplace(&i);
3670    assert(i is null);
3671}
3672
3673unittest
3674{
3675    static struct S {int i = 5;}
3676    S[2] s2 = void;
3677    emplace(&s2);
3678    assert(s2[0].i == 5 && s2[1].i == 5);
3679}
3680
3681unittest
3682{
3683    struct S1
3684    {}
3685
3686    struct S2
3687    {
3688        void opAssign(S2);
3689    }
3690
3691    S1 s1 = void;
3692    S2 s2 = void;
3693    S1[2] as1 = void;
3694    S2[2] as2 = void;
3695    emplace(&s1);
3696    emplace(&s2);
3697    emplace(&as1);
3698    emplace(&as2);
3699}
3700
3701unittest
3702{
3703    static struct S1
3704    {
3705        this(this) @disable;
3706    }
3707    static struct S2
3708    {
3709        this() @disable;
3710    }
3711    S1[2] ss1 = void;
3712    S2[2] ss2 = void;
3713    static assert( __traits(compiles, emplace(&ss1)));
3714    static assert(!__traits(compiles, emplace(&ss2)));
3715    S1 s1 = S1.init;
3716    S2 s2 = S2.init;
3717    static assert(!__traits(compiles, emplace(&ss1, s1)));
3718    static assert( __traits(compiles, emplace(&ss2, s2)));
3719}
3720
3721unittest
3722{
3723    struct S
3724    {
3725        immutable int i;
3726    }
3727    S s = void;
3728    S[2] ss1 = void;
3729    S[2] ss2 = void;
3730    emplace(&s, 5);
3731    emplace(&ss1, s);
3732    emplace(&ss2, ss1);
3733}
3734
3735/**
3736Given a pointer $(D chunk) to uninitialized memory (but already typed
3737as a non-class type $(D T)), constructs an object of type $(D T) at
3738that address from arguments $(D args).
3739
3740This function can be $(D @trusted) if the corresponding constructor of
3741$(D T) is $(D @safe).
3742
3743Returns: A pointer to the newly constructed object (which is the same
3744as $(D chunk)).
3745 */
3746T* emplace(T, Args...)(T* chunk, auto ref Args args)
3747    if (!is(T == struct) && Args.length == 1)
3748{
3749    alias Arg = Args[0];
3750    alias arg = args[0];
3751
3752    static assert (is(T* : void*),
3753        format("Cannot emplace a %s because it is qualified.", T.stringof));
3754
3755    static assert(is(typeof({T t = args[0];})),
3756        format("%s cannot be emplaced from a %s.", T.stringof, Arg.stringof));
3757
3758    static if (isStaticArray!T)
3759    {
3760        alias UArg = Unqual!Arg;
3761        alias E = typeof(chunk.ptr[0]);
3762        enum N = T.length;
3763
3764        static if (is(Arg : T))
3765        {
3766            //Matching static array
3767            static if (isAssignable!(T, Arg) && !hasElaborateAssign!T)
3768                *chunk = arg;
3769            else static if (is(UArg == T))
3770            {
3771                memcpy(chunk, &arg, T.sizeof);
3772                static if (hasElaborateCopyConstructor!T)
3773                    typeid(T).postblit(cast(void*)&chunk);
3774            }
3775            else
3776                emplace(chunk, cast(T)arg);
3777        }
3778        else static if (is(Arg : E[]))
3779        {
3780            //Matching dynamic array
3781            static if (is(typeof((*chunk)[] = arg[])) && !hasElaborateAssign!T)
3782                (*chunk)[] = arg[];
3783            else static if (is(UArg == E[]))
3784            {
3785                assert(N == chunk.length, "Array length missmatch in emplace");
3786                memcpy(cast(void*)chunk, arg.ptr, T.sizeof);
3787                static if (hasElaborateCopyConstructor!T)
3788                    typeid(T).postblit(cast(void*)&chunk);
3789            }
3790            else
3791                emplace(chunk, cast(E[])arg);
3792        }
3793        else static if (is(Arg : E))
3794        {
3795            //Case matching single element to array.
3796            static if (is(typeof((*chunk)[] = arg)) && !hasElaborateAssign!T)
3797                (*chunk)[] = arg;
3798            else static if (is(UArg == E))
3799            {
3800                //Note: We copy everything, and then postblit just once.
3801                //This is as exception safe as what druntime can provide us.
3802                foreach(i; 0 .. N)
3803                    memcpy(cast(void*)(chunk.ptr + i), &arg, E.sizeof);
3804                static if (hasElaborateCopyConstructor!T)
3805                    typeid(T).postblit(chunk);
3806            }
3807            else
3808                //Alias this. Coerce.
3809                emplace(chunk, cast(E)arg);
3810        }
3811        else static if (is(typeof(emplace(chunk.ptr, arg))))
3812        {
3813            //Final case for everything else:
3814            //Types that don't match (int to uint[2])
3815            //Recursion for multidimensions
3816            static if (is(typeof((*chunk)[] = arg)) && !hasElaborateAssign!T)
3817                (*chunk)[] = arg;
3818
3819            foreach(i; 0 .. N)
3820                emplace(chunk.ptr + i, arg);
3821        }
3822        else
3823            static assert(0, format("Sorry, this implementation doesn't know how to emplace a %s with a %s", T.stringof, Arg.stringof));
3824
3825        return chunk;
3826    }
3827    else
3828    {
3829        *chunk = arg;
3830        return chunk;
3831    }
3832}
3833
3834unittest
3835{
3836    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
3837    int a;
3838    int b = 42;
3839    assert(*emplace!int(&a, b) == 42);
3840}
3841
3842unittest
3843{
3844    interface I {}
3845    class K : I {}
3846
3847    K k = null, k2 = new K;
3848    assert(k !is k2);
3849    emplace!K(&k, k2);
3850    assert(k is k2);
3851
3852    I i = null;
3853    assert(i !is k);
3854    emplace!I(&i, k);
3855    assert(i is k);
3856}
3857
3858unittest
3859{
3860    static struct S
3861    {
3862        int i = 5;
3863        void opAssign(S){assert(0);}
3864    }
3865    S[2] sa = void;
3866    S[2] sb;
3867    emplace(&sa, sb);
3868    assert(sa[0].i == 5 && sa[1].i == 5);
3869}
3870
3871/// ditto
3872T* emplace(T, Args...)(T* chunk, auto ref Args args)
3873    if (is(T == struct))
3874{
3875    static assert (is(T* : void*),
3876        format("Cannot emplace a %s because it is qualified.", T.stringof));
3877
3878    static if (Args.length == 1 && is(Args[0] : T) &&
3879        is (typeof({T t = args[0];})) //Check for legal postblit
3880        )
3881    {
3882        static if (is(T == Unqual!(Args[0])))
3883        {
3884            //Types match exactly: we postblit
3885            static if (isAssignable!T && !hasElaborateAssign!T)
3886                *chunk = args[0];
3887            else
3888            {
3889                memcpy(chunk, &args[0], T.sizeof);
3890                static if (hasElaborateCopyConstructor!T)
3891                    typeid(T).postblit(chunk);
3892            }
3893        }
3894        else
3895            //Alias this. Coerce to type T.
3896            emplace(chunk, cast(T)args[0]);
3897    }
3898    else static if (is(typeof(chunk.__ctor(args))))
3899    {
3900        // T defines a genuine constructor accepting args
3901        // Go the classic route: write .init first, then call ctor
3902        emplaceInitializer(chunk);
3903        chunk.__ctor(args);
3904    }
3905    else static if (is(typeof(T.opCall(args))))
3906    {
3907        //Can be built calling opCall
3908        emplaceOpCaller(chunk, args); //emplaceOpCaller is deprecated
3909    }
3910    else static if (is(typeof(T(args))))
3911    {
3912        // Struct without constructor that has one matching field for
3913        // each argument. Individually emplace each field
3914        emplaceInitializer(chunk);
3915        foreach (i, ref field; chunk.tupleof[0 .. Args.length])
3916            emplace(emplaceGetAddr(field), args[i]);
3917    }
3918    else
3919    {
3920        //We can't emplace. Try to diagnose a disabled postblit.
3921        static assert(!(Args.length == 1 && is(Args[0] : T)),
3922            format("Cannot emplace a %1$s because %1$s.this(this) is annotated with @disable.", T.stringof));
3923
3924        //We can't emplace.
3925        static assert(false,
3926            format("%s cannot be emplaced from %s.", T.stringof, Args[].stringof));
3927    }
3928
3929    return chunk;
3930}
3931
3932//emplace helper functions
3933private T* emplaceInitializer(T)(T* chunk) @trusted pure nothrow
3934{
3935    static if (isAssignable!T && !hasElaborateAssign!T)
3936        *chunk = T.init;
3937    else
3938    {
3939        static immutable T init = T.init;
3940        memcpy(chunk, &init, T.sizeof);
3941    }
3942    return chunk;
3943}
3944private deprecated("Using static opCall for emplace is deprecated. Plase use emplace(chunk, T(args)) instead.")
3945T* emplaceOpCaller(T, Args...)(T* chunk, auto ref Args args)
3946{
3947    static assert (is(typeof({T t = T.opCall(args);})),
3948        format("%s.opCall does not return adequate data for construction.", T.stringof));
3949    return emplace(chunk, chunk.opCall(args));
3950}
3951private
3952{
3953    //Helper to keep simple aggregate emplace safe.
3954    auto emplaceGetAddr(T)(ref T t) @trusted
3955    if (is(T == Unqual!T))
3956    {
3957        return &t;
3958    }
3959    auto emplaceGetAddr(T)(ref T t)
3960    if (!is(T == Unqual!T))
3961    {
3962        return cast(Unqual!T*)&t;
3963    }
3964}
3965
3966// Test constructor branch
3967unittest
3968{
3969    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
3970    struct S
3971    {
3972        double x = 5, y = 6;
3973        this(int a, int b)
3974        {
3975            assert(x == 5 && y == 6);
3976            x = a;
3977            y = b;
3978        }
3979    }
3980
3981    auto s1 = new void[S.sizeof];
3982    auto s2 = S(42, 43);
3983    assert(*emplace!S(cast(S*) s1.ptr, s2) == s2);
3984    assert(*emplace!S(cast(S*) s1, 44, 45) == S(44, 45));
3985}
3986
3987unittest
3988{
3989    __conv_EmplaceTest k = void;
3990    emplace(&k, 5);
3991    assert(k.i == 5);
3992}
3993
3994unittest
3995{
3996    int var = 6;
3997    __conv_EmplaceTest k = void;
3998    emplace(&k, 5, var);
3999    assert(k.i == 5);
4000    assert(var == 7);
4001}
4002
4003// Test matching fields branch
4004unittest
4005{
4006    struct S { uint n; }
4007    S s;
4008    emplace!S(&s, 2U);
4009    assert(s.n == 2);
4010}
4011
4012unittest
4013{
4014    struct S { int a, b; this(int){} }
4015    S s;
4016    static assert(!__traits(compiles, emplace!S(&s, 2, 3)));
4017}
4018
4019unittest
4020{
4021    struct S { int a, b = 7; }
4022    S s1 = void, s2 = void;
4023
4024    emplace!S(&s1, 2);
4025    assert(s1.a == 2 && s1.b == 7);
4026
4027    emplace!S(&s2, 2, 3);
4028    assert(s2.a == 2 && s2.b == 3);
4029}
4030
4031//opAssign
4032unittest
4033{
4034    static struct S
4035    {
4036        int i = 5;
4037        void opAssign(int){assert(0);}
4038        void opAssign(S){assert(0);}
4039    }
4040    S sa1 = void;
4041    S sa2 = void;
4042    S sb1 = S(1);
4043    emplace(&sa1, sb1);
4044    emplace(&sa2, 2);
4045    assert(sa1.i == 1);
4046    assert(sa2.i == 2);
4047}
4048
4049//postblit precedence
4050unittest
4051{
4052    //Works, but breaks in "-w -O" because of @@@9332@@@.
4053    //Uncomment test when 9332 is fixed.
4054    static struct S
4055    {
4056        int i;
4057
4058        this(S other){assert(false);}
4059        this(int i){this.i = i;}
4060        this(this){}
4061    }
4062    S a = void;
4063    assert(is(typeof({S b = a;})));    //Postblit
4064    assert(is(typeof({S b = S(a);}))); //Constructor
4065    auto b = S(5);
4066    emplace(&a, b);
4067    assert(a.i == 5);
4068
4069    static struct S2
4070    {
4071        int* p;
4072        this(const S2){};
4073    }
4074    static assert(!is(immutable S2 : S2));
4075    S2 s2 = void;
4076    immutable is2 = (immutable S2).init;
4077    emplace(&s2, is2);
4078}
4079
4080//nested structs and postblit
4081unittest
4082{
4083    static struct S
4084    {
4085        int* p;
4086        this(int i){p = [i].ptr;}
4087        this(this)
4088        {
4089            if (p)
4090                p = [*p].ptr;
4091        }
4092    }
4093    static struct SS
4094    {
4095        S s;
4096        void opAssign(const SS)
4097        {
4098            assert(0);
4099        }
4100    }
4101    SS ssa = void;
4102    SS ssb = SS(S(5));
4103    emplace(&ssa, ssb);
4104    assert(*ssa.s.p == 5);
4105    assert(ssa.s.p != ssb.s.p);
4106}
4107
4108//disabled postblit
4109unittest
4110{
4111    static struct S1
4112    {
4113        int i;
4114        @disable this(this);
4115    }
4116    S1 s1 = void;
4117    static assert( __traits(compiles, emplace(&s1, 1)));
4118    static assert(!__traits(compiles, emplace(&s1, S1.init)));
4119
4120    static struct S2
4121    {
4122        int i;
4123        @disable this(this);
4124        this(ref S2){}
4125    }
4126    S2 s2 = void;
4127    static assert(!__traits(compiles, emplace(&s2, 1)));
4128    static assert( __traits(compiles, emplace(&s2, S2.init)));
4129
4130    static struct SS1
4131    {
4132        S1 s;
4133    }
4134    SS1 ss1 = void;
4135    static assert( __traits(compiles, emplace(&ss1)));
4136    static assert(!__traits(compiles, emplace(&ss1, SS1.init)));
4137
4138    static struct SS2
4139    {
4140        S2 s;
4141    }
4142    SS2 ss2 = void;
4143    static assert( __traits(compiles, emplace(&ss2)));
4144    static assert(!__traits(compiles, emplace(&ss2, SS2.init)));
4145
4146
4147    // SS1 sss1 = s1;      //This doesn't compile
4148    // SS1 sss1 = SS1(s1); //This doesn't compile
4149    // So emplace shouldn't compile either
4150    static assert(!__traits(compiles, emplace(&sss1, s1)));
4151    static assert(!__traits(compiles, emplace(&sss2, s2)));
4152}
4153
4154//Imutability
4155unittest
4156{
4157    //Castable immutability
4158    {
4159        static struct S1
4160        {
4161            int i;
4162        }
4163        static assert(is( immutable(S1) : S1));
4164        S1 sa = void;
4165        auto sb = immutable(S1)(5);
4166        emplace(&sa, sb);
4167        assert(sa.i == 5);
4168    }
4169    //Un-castable immutability
4170    {
4171        static struct S2
4172        {
4173            int* p;
4174        }
4175        static assert(!is(immutable(S2) : S2));
4176        S2 sa = void;
4177        auto sb = immutable(S2)(null);
4178        assert(!__traits(compiles, emplace(&sa, sb)));
4179    }
4180}
4181
4182unittest
4183{
4184    static struct S
4185    {
4186        immutable int i;
4187        immutable(int)* j;
4188    }
4189    S s = void;
4190    emplace(&s, 1, null);
4191    emplace(&s, 2, &s.i);
4192    assert(s is S(2, &s.i));
4193}
4194
4195//Context pointer
4196unittest
4197{
4198    int i = 0;
4199    {
4200        struct S1
4201        {
4202            void foo(){++i;}
4203        }
4204        S1 sa = void;
4205        S1 sb;
4206        emplace(&sa, sb);
4207        sa.foo();
4208        assert(i == 1);
4209    }
4210    {
4211        struct S2
4212        {
4213            void foo(){++i;}
4214            this(this){}
4215        }
4216        S2 sa = void;
4217        S2 sb;
4218        emplace(&sa, sb);
4219        sa.foo();
4220        assert(i == 2);
4221    }
4222
4223    ////NOTE: THESE WILL COMPILE
4224    ////But will not correctly emplace the context pointer
4225    ////The problem lies with voldemort, and not emplace.
4226    //{
4227    //    struct S3
4228    //    {
4229    //        int k;
4230    //        void foo(){++i;}
4231    //    }
4232    //}
4233    //S3 s3 = void;
4234    //emplace(&s3);    //S3.init has no context pointer information
4235    //emplace(&s3, 1); //No way to obtain context pointer once inside emplace
4236}
4237
4238//Alias this
4239unittest
4240{
4241    static struct S
4242    {
4243        int i;
4244    }
4245    //By Ref
4246    {
4247        static struct SS1
4248        {
4249            int j;
4250            S s;
4251            alias s this;
4252        }
4253        S s = void;
4254        SS1 ss = SS1(1, S(2));
4255        emplace(&s, ss);
4256        assert(s.i == 2);
4257    }
4258    //By Value
4259    {
4260        static struct SS2
4261        {
4262            int j;
4263            S s;
4264            S foo() @property{return s;}
4265            alias foo this;
4266        }
4267        S s = void;
4268        SS2 ss = SS2(1, S(2));
4269        emplace(&s, ss);
4270        assert(s.i == 2);
4271    }
4272}
4273version(unittest)
4274{
4275    //Ambiguity
4276    struct __std_conv_S
4277    {
4278        int i;
4279        this(__std_conv_SS ss)         {assert(0);}
4280        static opCall(__std_conv_SS ss)
4281        {
4282            __std_conv_S s; s.i = ss.j;
4283            return s;
4284        }
4285    }
4286    struct __std_conv_SS
4287    {
4288        int j;
4289        __std_conv_S s;
4290        ref __std_conv_S foo() @property {s.i = j; return s;}
4291        alias foo this;
4292    }
4293    static assert(is(__std_conv_SS : __std_conv_S));
4294    unittest
4295    {
4296        __std_conv_S s = void;
4297        __std_conv_SS ss = __std_conv_SS(1);
4298
4299        __std_conv_S sTest1 = ss; //this calls "SS alias this" (and not "S.this(SS)")
4300        emplace(&s, ss); //"alias this" should take precedence in emplace over "opCall"
4301        assert(s.i == 1);
4302    }
4303}
4304
4305//Nested classes
4306unittest
4307{
4308    class A{}
4309    static struct S
4310    {
4311        A a;
4312    }
4313    S s1 = void;
4314    S s2 = S(new A);
4315    emplace(&s1, s2);
4316    assert(s1.a is s2.a);
4317}
4318
4319//safety & nothrow & CTFE
4320unittest
4321{
4322    //emplace should be safe for anything with no elaborate opassign
4323    static struct S1
4324    {
4325        int i;
4326    }
4327    static struct S2
4328    {
4329        int i;
4330        this(int j)@safe nothrow{i = j;}
4331    }
4332
4333    int i;
4334    S1 s1 = void;
4335    S2 s2 = void;
4336
4337    auto pi = &i;
4338    auto ps1 = &s1;
4339    auto ps2 = &s2;
4340
4341    void foo() @safe nothrow
4342    {
4343        emplace(pi);
4344        emplace(pi, 5);
4345        emplace(ps1);
4346        emplace(ps1, 5);
4347        emplace(ps1, S1.init);
4348        emplace(ps2);
4349        emplace(ps2, 5);
4350        emplace(ps2, S2.init);
4351    }
4352
4353    T bar(T)() @property
4354    {
4355        T t/+ = void+/; //CTFE void illegal
4356        emplace(&t, 5);
4357        return t;
4358    }
4359    enum a = bar!int;
4360    enum b = bar!S1;
4361    enum c = bar!S2;
4362}
4363
4364
4365unittest
4366{
4367    struct S
4368    {
4369        int[2] get(){return [1, 2];}
4370        alias get this;
4371    }
4372    struct SS
4373    {
4374        int[2] ii;
4375    }
4376    struct ISS
4377    {
4378        int[2] ii;
4379    }
4380    S s;
4381    SS ss = void;
4382    ISS iss = void;
4383    emplace(&ss, s);
4384    emplace(&iss, s);
4385    assert(ss.ii == [1, 2]);
4386    assert(iss.ii == [1, 2]);
4387}
4388
4389//disable opAssign
4390unittest
4391{
4392    static struct S
4393    {
4394        @disable void opAssign(S);
4395    }
4396    S s;
4397    emplace(&s, S.init);
4398}
4399
4400//opCall
4401unittest
4402{
4403    int i;
4404    //Without constructor
4405    {
4406        static struct S1
4407        {
4408            int i;
4409            static S1 opCall(int*){assert(0);}
4410        }
4411        S1 s = void;
4412        static assert(!__traits(compiles, emplace(&s,  1)));
4413        static assert( __traits(compiles, emplace(&s, &i))); //(works, but deprected)
4414    }
4415    //With constructor
4416    {
4417        static struct S2
4418        {
4419            int i = 0;
4420            static S2 opCall(int*){assert(0);}
4421            static S2 opCall(int){assert(0);}
4422            this(int i){this.i = i;}
4423        }
4424        S2 s = void;
4425        static assert( __traits(compiles, emplace(&s, 1)));  //(works, but deprected)
4426        static assert( __traits(compiles, emplace(&s, &i))); //(works, but deprected)
4427        emplace(&s,  1);
4428        assert(s.i == 1);
4429    }
4430    //With postblit ambiguity
4431    {
4432        static struct S3
4433        {
4434            int i = 0;
4435            static S3 opCall(ref S3){assert(0);}
4436        }
4437        S3 s = void;
4438        static assert( __traits(compiles, emplace(&s, S3.init)));
4439    }
4440}
4441
4442unittest //@@@9559@@@
4443{
4444    alias Nullable!int I;
4445    auto ints = [0, 1, 2].map!(i => i & 1 ? I.init : I(i))();
4446    auto asArray = std.array.array(ints);
4447}
4448
4449unittest //http://forum.dlang.org/thread/nxbdgtdlmwscocbiypjs@forum.dlang.org
4450{
4451    import std.array : array;
4452    import std.datetime : SysTime, UTC;
4453    import std.math : isNaN;
4454
4455    static struct A
4456    {
4457        double i;
4458    }
4459
4460    static struct B
4461    {
4462        invariant()
4463        {
4464            if(j == 0)
4465                assert(a.i.isNaN, "why is 'j' zero?? and i is not NaN?");
4466            else
4467                assert(!a.i.isNaN);
4468        }
4469        SysTime when; // comment this line avoid the breakage
4470        int j;
4471        A a;
4472    }
4473
4474    B b1 = B.init;
4475    assert(&b1); // verify that default eyes invariants are ok;
4476
4477    auto b2 = B(SysTime(0, UTC()), 1, A(1));
4478    assert(&b2);
4479    auto b3 = B(SysTime(0, UTC()), 1, A(1));
4480    assert(&b3);
4481
4482    auto arr = [b2, b3];
4483
4484    assert(arr[0].j == 1);
4485    assert(arr[1].j == 1);
4486    auto a2 = arr.array(); // << bang, invariant is raised, also if b2 and b3 are good
4487}
4488
4489//static arrays
4490unittest
4491{
4492    static struct S
4493    {
4494        int[2] ii;
4495    }
4496    static struct IS
4497    {
4498        immutable int[2] ii;
4499    }
4500    int[2] ii;
4501    S  s   = void;
4502    IS ims = void;
4503    ubyte ub = 2;
4504    emplace(&s, ub);
4505    emplace(&s, ii);
4506    emplace(&ims, ub);
4507    emplace(&ims, ii);
4508    uint[2] uu;
4509    static assert(!__traits(compiles, {S ss = S(uu);}));
4510    static assert(!__traits(compiles, emplace(&s, uu)));
4511}
4512
4513unittest
4514{
4515    int[2]  sii;
4516    int[2]  sii2;
4517    uint[2] uii;
4518    uint[2] uii2;
4519    emplace(&sii, 1);
4520    emplace(&sii, 1U);
4521    emplace(&uii, 1);
4522    emplace(&uii, 1U);
4523    emplace(&sii, sii2);
4524    //emplace(&sii, uii2); //Sorry, this implementation doesn't know how to...
4525    //emplace(&uii, sii2); //Sorry, this implementation doesn't know how to...
4526    emplace(&uii, uii2);
4527    emplace(&sii, sii2[]);
4528    //emplace(&sii, uii2[]); //Sorry, this implementation doesn't know how to...
4529    //emplace(&uii, sii2[]); //Sorry, this implementation doesn't know how to...
4530    emplace(&uii, uii2[]);
4531}
4532
4533unittest
4534{
4535    bool allowDestruction = false;
4536    struct S
4537    {
4538        int i;
4539        this(this){}
4540        ~this(){assert(allowDestruction);}
4541    }
4542    S s = S(1);
4543    S[2] ss1 = void;
4544    S[2] ss2 = void;
4545    S[2] ss3 = void;
4546    emplace(&ss1, s);
4547    emplace(&ss2, ss1);
4548    emplace(&ss3, ss2[]);
4549    assert(ss1[1] == s);
4550    assert(ss2[1] == s);
4551    assert(ss3[1] == s);
4552    allowDestruction = true;
4553}
4554
4555unittest
4556{
4557    //Checks postblit, construction, and context pointer
4558    int count = 0;
4559    struct S
4560    {
4561        this(this)
4562        {
4563            ++count;
4564        }
4565        ~this()
4566        {
4567            --count;
4568        }
4569    }
4570
4571    S s;
4572    {
4573        S[4] ss = void;
4574        emplace(&ss, s);
4575        assert(count == 4);
4576    }
4577    assert(count == 0);
4578}
4579
4580unittest
4581{
4582    struct S
4583    {
4584        int i;
4585    }
4586    S s;
4587    S[2][2][2] sss = void;
4588    emplace(&sss, s);
4589}
4590
4591private void testEmplaceChunk(void[] chunk, size_t typeSize, size_t typeAlignment, string typeName)
4592{
4593    enforceEx!ConvException(chunk.length >= typeSize,
4594        format("emplace: Chunk size too small: %s < %s size = %s",
4595        chunk.length, typeName, typeSize));
4596    enforceEx!ConvException((cast(size_t) chunk.ptr) % typeAlignment == 0,
4597        format("emplace: Misaligned memory block (0x%X): it must be %s-byte aligned for type %s",
4598        chunk.ptr, typeAlignment, typeName));
4599}
4600
4601/**
4602Given a raw memory area $(D chunk), constructs an object of $(D class)
4603type $(D T) at that address. The constructor is passed the arguments
4604$(D Args). The $(D chunk) must be as least as large as $(D T) needs
4605and should have an alignment multiple of $(D T)'s alignment. (The size
4606of a $(D class) instance is obtained by using $(D
4607__traits(classInstanceSize, T))).
4608
4609This function can be $(D @trusted) if the corresponding constructor of
4610$(D T) is $(D @safe).
4611
4612Returns: A pointer to the newly constructed object.
4613 */
4614T emplace(T, Args...)(void[] chunk, auto ref Args args)
4615    if (is(T == class))
4616{
4617    enum classSize = __traits(classInstanceSize, T);
4618    testEmplaceChunk(chunk, classSize, classInstanceAlignment!T, T.stringof);
4619    auto result = cast(T) chunk.ptr;
4620
4621    // Initialize the object in its pre-ctor state
4622    (cast(byte[]) chunk)[0 .. classSize] = typeid(T).init[];
4623
4624    // Call the ctor if any
4625    static if (is(typeof(result.__ctor(args))))
4626    {
4627        // T defines a genuine constructor accepting args
4628        // Go the classic route: write .init first, then call ctor
4629        result.__ctor(args);
4630    }
4631    else
4632    {
4633        static assert(args.length == 0 && !is(typeof(&T.__ctor)),
4634                "Don't know how to initialize an object of type "
4635                ~ T.stringof ~ " with arguments " ~ Args.stringof);
4636    }
4637    return result;
4638}
4639
4640unittest
4641{
4642    int var = 6;
4643    auto k = emplace!__conv_EmplaceTestClass(new void[__traits(classInstanceSize, __conv_EmplaceTestClass)], 5, var);
4644    assert(k.i == 5);
4645    assert(var == 7);
4646}
4647
4648/**
4649Given a raw memory area $(D chunk), constructs an object of non-$(D
4650class) type $(D T) at that address. The constructor is passed the
4651arguments $(D args), if any. The $(D chunk) must be as least as large
4652as $(D T) needs and should have an alignment multiple of $(D T)'s
4653alignment.
4654
4655This function can be $(D @trusted) if the corresponding constructor of
4656$(D T) is $(D @safe).
4657
4658Returns: A pointer to the newly constructed object.
4659 */
4660T* emplace(T, Args...)(void[] chunk, auto ref Args args)
4661    if (!is(T == class))
4662{
4663    testEmplaceChunk(chunk, T.sizeof, T.alignof, T.stringof);
4664    return emplace(cast(T*) chunk.ptr, args);
4665}
4666
4667unittest
4668{
4669    struct S
4670    {
4671        int a, b;
4672    }
4673    auto p = new void[S.sizeof];
4674    S s;
4675    s.a = 42;
4676    s.b = 43;
4677    auto s1 = emplace!S(p, s);
4678    assert(s1.a == 42 && s1.b == 43);
4679}
4680
4681unittest
4682{
4683    int var = 6;
4684    auto k = emplace!__conv_EmplaceTest(new void[__conv_EmplaceTest.sizeof], 5, var);
4685    assert(k.i == 5);
4686    assert(var == 7);
4687}
4688
4689unittest
4690{
4691    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
4692    class A
4693    {
4694        int x = 5;
4695        int y = 42;
4696        this(int z)
4697        {
4698            assert(x == 5 && y == 42);
4699            x = y = z;
4700        }
4701    }
4702    void[] buf;
4703
4704    static byte[__traits(classInstanceSize, A)] sbuf;
4705    buf = sbuf[];
4706    auto a = emplace!A(buf, 55);
4707    assert(a.x == 55 && a.y == 55);
4708
4709    // emplace in bigger buffer
4710    buf = new byte[](__traits(classInstanceSize, A) + 10);
4711    a = emplace!A(buf, 55);
4712    assert(a.x == 55 && a.y == 55);
4713
4714    // need ctor args
4715    static assert(!is(typeof(emplace!A(buf))));
4716}
4717
4718unittest
4719{
4720    debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
4721    // Check fix for http://d.puremagic.com/issues/show_bug.cgi?id=2971
4722    assert(equal(map!(to!int)(["42", "34", "345"]), [42, 34, 345]));
4723}
4724
4725// Undocumented for the time being
4726void toTextRange(T, W)(T value, W writer)
4727    if (isIntegral!T && isOutputRange!(W, char))
4728{
4729    char[value.sizeof * 4] buffer = void;
4730    uint i = cast(uint) (buffer.length - 1);
4731
4732    bool negative = value < 0;
4733    Unqual!(Unsigned!T) v = negative ? -value : value;
4734
4735    while (v >= 10)
4736    {
4737        auto c = cast(uint) (v % 10);
4738        v /= 10;
4739        buffer[i--] = cast(char) (c + '0');
4740    }
4741
4742    buffer[i] = cast(char) (v + '0'); //hexDigits[cast(uint) v];
4743    if (negative)
4744        buffer[--i] = '-';
4745    put(writer, buffer[i .. $]);
4746}
4747
4748unittest
4749{
4750    auto result = appender!(char[])();
4751    toTextRange(-1, result);
4752    assert(result.data == "-1");
4753}
4754
4755
4756/**
4757    Returns the corresponding unsigned value for $(D x) (e.g. if $(D x) has type
4758    $(D int), it returns $(D cast(uint) x)). The advantage compared to the cast
4759    is that you do not need to rewrite the cast if $(D x) later changes type
4760    (e.g from $(D int) to $(D long)).
4761
4762    Note that the result is always mutable even if the original type was const
4763    or immutable. In order to retain the constness, use $(XREF traits, Unsigned).
4764 */
4765auto unsigned(T)(T x) if (isIntegral!T)
4766{
4767    return cast(Unqual!(Unsigned!T))x;
4768}
4769
4770///
4771unittest
4772{
4773    uint s = 42;
4774    auto u1 = unsigned(s); //not qualified
4775    Unsigned!(typeof(s)) u2 = unsigned(s); //same qualification
4776    immutable u3 = unsigned(s); //totally qualified
4777}
4778
4779unittest
4780{
4781    foreach(T; TypeTuple!(byte, ubyte))
4782    {
4783        static assert(is(typeof(unsigned(cast(T)1)) == ubyte));
4784        static assert(is(typeof(unsigned(cast(const T)1)) == ubyte));
4785        static assert(is(typeof(unsigned(cast(immutable T)1)) == ubyte));
4786    }
4787
4788    foreach(T; TypeTuple!(short, ushort))
4789    {
4790        static assert(is(typeof(unsigned(cast(T)1)) == ushort));
4791        static assert(is(typeof(unsigned(cast(const T)1)) == ushort));
4792        static assert(is(typeof(unsigned(cast(immutable T)1)) == ushort));
4793    }
4794
4795    foreach(T; TypeTuple!(int, uint))
4796    {
4797        static assert(is(typeof(unsigned(cast(T)1)) == uint));
4798        static assert(is(typeof(unsigned(cast(const T)1)) == uint));
4799        static assert(is(typeof(unsigned(cast(immutable T)1)) == uint));
4800    }
4801
4802    foreach(T; TypeTuple!(long, ulong))
4803    {
4804        static assert(is(typeof(unsigned(cast(T)1)) == ulong));
4805        static assert(is(typeof(unsigned(cast(const T)1)) == ulong));
4806        static assert(is(typeof(unsigned(cast(immutable T)1)) == ulong));
4807    }
4808}
4809
4810auto unsigned(T)(T x) if (isSomeChar!T)
4811{
4812    // All characters are unsigned
4813    static assert(T.min == 0);
4814    return cast(Unqual!T) x;
4815}
4816
4817unittest
4818{
4819    foreach(T; TypeTuple!(char, wchar, dchar))
4820    {
4821        static assert(is(typeof(unsigned(cast(T)'A')) == T));
4822        static assert(is(typeof(unsigned(cast(const T)'A')) == T));
4823        static assert(is(typeof(unsigned(cast(immutable T)'A')) == T));
4824    }
4825}
4826
4827
4828/**
4829    Returns the corresponding signed value for $(D x) (e.g. if $(D x) has type
4830    $(D uint), it returns $(D cast(int) x)). The advantage compared to the cast
4831    is that you do not need to rewrite the cast if $(D x) later changes type
4832    (e.g from $(D uint) to $(D ulong)).
4833
4834    Note that the result is always mutable even if the original type was const
4835    or immutable. In order to retain the constness, use $(XREF traits, Signed).
4836 */
4837auto signed(T)(T x) if (isIntegral!T)
4838{
4839    return cast(Unqual!(Signed!T))x;
4840}
4841
4842///
4843unittest
4844{
4845    uint u = 42;
4846    auto s1 = unsigned(u); //not qualified
4847    Unsigned!(typeof(u)) s2 = unsigned(u); //same qualification
4848    immutable s3 = unsigned(u); //totally qualified
4849}
4850
4851unittest
4852{
4853    foreach(T; TypeTuple!(byte, ubyte))
4854    {
4855        static assert(is(typeof(signed(cast(T)1)) == byte));
4856        static assert(is(typeof(signed(cast(const T)1)) == byte));
4857        static assert(is(typeof(signed(cast(immutable T)1)) == byte));
4858    }
4859
4860    foreach(T; TypeTuple!(short, ushort))
4861    {
4862        static assert(is(typeof(signed(cast(T)1)) == short));
4863        static assert(is(typeof(signed(cast(const T)1)) == short));
4864        static assert(is(typeof(signed(cast(immutable T)1)) == short));
4865    }
4866
4867    foreach(T; TypeTuple!(int, uint))
4868    {
4869        static assert(is(typeof(signed(cast(T)1)) == int));
4870        static assert(is(typeof(signed(cast(const T)1)) == int));
4871        static assert(is(typeof(signed(cast(immutable T)1)) == int));
4872    }
4873
4874    foreach(T; TypeTuple!(long, ulong))
4875    {
4876        static assert(is(typeof(signed(cast(T)1)) == long));
4877        static assert(is(typeof(signed(cast(const T)1)) == long));
4878        static assert(is(typeof(signed(cast(immutable T)1)) == long));
4879    }
4880}
4881
4882unittest
4883{
4884    // issue 10874
4885    enum Test { a = 0 }
4886    ulong l = 0;
4887    auto t = l.to!Test;
4888}