1// Written in the D programming language.
2
3/**
4A one-stop shop for converting values from one type to another.
5
6$(SCRIPT inhibitQuickIndex = 1;)
7$(BOOKTABLE,
8$(TR $(TH Category) $(TH Functions))
9$(TR $(TD Generic) $(TD
10        $(LREF asOriginalType)
11        $(LREF castFrom)
12        $(LREF emplace)
13        $(LREF parse)
14        $(LREF to)
15        $(LREF toChars)
16))
17$(TR $(TD Strings) $(TD
18        $(LREF text)
19        $(LREF wtext)
20        $(LREF dtext)
21        $(LREF hexString)
22))
23$(TR $(TD Numeric) $(TD
24        $(LREF octal)
25        $(LREF roundTo)
26        $(LREF signed)
27        $(LREF unsigned)
28))
29$(TR $(TD Exceptions) $(TD
30        $(LREF ConvException)
31        $(LREF ConvOverflowException)
32))
33)
34
35Copyright: Copyright Digital Mars 2007-.
36
37License:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
38
39Authors:   $(HTTP digitalmars.com, Walter Bright),
40           $(HTTP erdani.org, Andrei Alexandrescu),
41           Shin Fujishiro,
42           Adam D. Ruppe,
43           Kenji Hara
44
45Source:    $(PHOBOSSRC std/_conv.d)
46
47*/
48module std.conv;
49
50public import std.ascii : LetterCase;
51
52import std.meta;
53import std.range.primitives;
54import std.traits;
55
56// Same as std.string.format, but "self-importing".
57// Helps reduce code and imports, particularly in static asserts.
58// Also helps with missing imports errors.
59package template convFormat()
60{
61    import std.format : format;
62    alias convFormat = format;
63}
64
65/* ************* Exceptions *************** */
66
67/**
68 * Thrown on conversion errors.
69 */
70class ConvException : Exception
71{
72    import std.exception : basicExceptionCtors;
73    ///
74    mixin basicExceptionCtors;
75}
76
77private auto convError(S, T)(S source, string fn = __FILE__, size_t ln = __LINE__)
78{
79    string msg;
80
81    if (source.empty)
82        msg = "Unexpected end of input when converting from type " ~ S.stringof ~ " to type " ~ T.stringof;
83    else
84    {
85        ElementType!S el = source.front;
86
87        if (el == '\n')
88            msg = text("Unexpected '\\n' when converting from type " ~ S.stringof ~ " to type " ~ T.stringof);
89        else
90            msg =  text("Unexpected '", el,
91                 "' when converting from type " ~ S.stringof ~ " to type " ~ T.stringof);
92    }
93
94    return new ConvException(msg, fn, ln);
95}
96
97private auto convError(S, T)(S source, int radix, string fn = __FILE__, size_t ln = __LINE__)
98{
99    string msg;
100
101    if (source.empty)
102        msg = text("Unexpected end of input when converting from type " ~ S.stringof ~ " base ", radix,
103                " to type " ~ T.stringof);
104    else
105        msg = text("Unexpected '", source.front,
106            "' when converting from type " ~ S.stringof ~ " base ", radix,
107            " to type " ~ T.stringof);
108
109    return new ConvException(msg, fn, ln);
110}
111
112@safe pure/* nothrow*/  // lazy parameter bug
113private auto parseError(lazy string msg, string fn = __FILE__, size_t ln = __LINE__)
114{
115    return new ConvException(text("Can't parse string: ", msg), fn, ln);
116}
117
118private void parseCheck(alias source)(dchar c, string fn = __FILE__, size_t ln = __LINE__)
119{
120    if (source.empty)
121        throw parseError(text("unexpected end of input when expecting", "\"", c, "\""));
122    if (source.front != c)
123        throw parseError(text("\"", c, "\" is missing"), fn, ln);
124    source.popFront();
125}
126
127private
128{
129    T toStr(T, S)(S src)
130    if (isSomeString!T)
131    {
132        // workaround for Bugzilla 14198
133        static if (is(S == bool) && is(typeof({ T s = "string"; })))
134        {
135            return src ? "true" : "false";
136        }
137        else
138        {
139            import std.array : appender;
140            import std.format : FormatSpec, formatValue;
141
142            auto w = appender!T();
143            FormatSpec!(ElementEncodingType!T) f;
144            formatValue(w, src, f);
145            return w.data;
146        }
147    }
148
149    template isExactSomeString(T)
150    {
151        enum isExactSomeString = isSomeString!T && !is(T == enum);
152    }
153
154    template isEnumStrToStr(S, T)
155    {
156        enum isEnumStrToStr = isImplicitlyConvertible!(S, T) &&
157                              is(S == enum) && isExactSomeString!T;
158    }
159    template isNullToStr(S, T)
160    {
161        enum isNullToStr = isImplicitlyConvertible!(S, T) &&
162                           (is(Unqual!S == typeof(null))) && isExactSomeString!T;
163    }
164}
165
166/**
167 * Thrown on conversion overflow errors.
168 */
169class ConvOverflowException : ConvException
170{
171    @safe pure nothrow
172    this(string s, string fn = __FILE__, size_t ln = __LINE__)
173    {
174        super(s, fn, ln);
175    }
176}
177
178/**
179The `to` template converts a value from one type _to another.
180The source type is deduced and the target type must be specified, for example the
181expression `to!int(42.0)` converts the number 42 from
182`double` _to `int`. The conversion is "safe", i.e.,
183it checks for overflow; `to!int(4.2e10)` would throw the
184`ConvOverflowException` exception. Overflow checks are only
185inserted when necessary, e.g., `to!double(42)` does not do
186any checking because any `int` fits in a `double`.
187
188Conversions from string _to numeric types differ from the C equivalents
189`atoi()` and `atol()` by checking for overflow and not allowing whitespace.
190
191For conversion of strings _to signed types, the grammar recognized is:
192$(PRE $(I Integer): $(I Sign UnsignedInteger)
193$(I UnsignedInteger)
194$(I Sign):
195    $(B +)
196    $(B -))
197
198For conversion _to unsigned types, the grammar recognized is:
199$(PRE $(I UnsignedInteger):
200    $(I DecimalDigit)
201    $(I DecimalDigit) $(I UnsignedInteger))
202 */
203template to(T)
204{
205    T to(A...)(A args)
206        if (A.length > 0)
207    {
208        return toImpl!T(args);
209    }
210
211    // Fix issue 6175
212    T to(S)(ref S arg)
213        if (isStaticArray!S)
214    {
215        return toImpl!T(arg);
216    }
217
218    // Fix issue 16108
219    T to(S)(ref S arg)
220        if (isAggregateType!S && !isCopyable!S)
221    {
222        return toImpl!T(arg);
223    }
224}
225
226/**
227 * Converting a value _to its own type (useful mostly for generic code)
228 * simply returns its argument.
229 */
230@safe pure unittest
231{
232    int a = 42;
233    int b = to!int(a);
234    double c = to!double(3.14); // c is double with value 3.14
235}
236
237/**
238 * Converting among numeric types is a safe way _to cast them around.
239 *
240 * Conversions from floating-point types _to integral types allow loss of
241 * precision (the fractional part of a floating-point number). The
242 * conversion is truncating towards zero, the same way a cast would
243 * truncate. (_To round a floating point value when casting _to an
244 * integral, use `roundTo`.)
245 */
246@safe pure unittest
247{
248    import std.exception : assertThrown;
249
250    int a = 420;
251    assert(to!long(a) == a);
252    assertThrown!ConvOverflowException(to!byte(a));
253
254    assert(to!int(4.2e6) == 4200000);
255    assertThrown!ConvOverflowException(to!uint(-3.14));
256    assert(to!uint(3.14) == 3);
257    assert(to!uint(3.99) == 3);
258    assert(to!int(-3.99) == -3);
259}
260
261/**
262 * When converting strings _to numeric types, note that the D hexadecimal and binary
263 * literals are not handled. Neither the prefixes that indicate the base, nor the
264 * horizontal bar used _to separate groups of digits are recognized. This also
265 * applies to the suffixes that indicate the type.
266 *
267 * _To work around this, you can specify a radix for conversions involving numbers.
268 */
269@safe pure unittest
270{
271    auto str = to!string(42, 16);
272    assert(str == "2A");
273    auto i = to!int(str, 16);
274    assert(i == 42);
275}
276
277/**
278 * Conversions from integral types _to floating-point types always
279 * succeed, but might lose accuracy. The largest integers with a
280 * predecessor representable in floating-point format are `2^24-1` for
281 * `float`, `2^53-1` for `double`, and `2^64-1` for `real` (when
282 * `real` is 80-bit, e.g. on Intel machines).
283 */
284@safe pure unittest
285{
286    // 2^24 - 1, largest proper integer representable as float
287    int a = 16_777_215;
288    assert(to!int(to!float(a)) == a);
289    assert(to!int(to!float(-a)) == -a);
290}
291
292/**
293 * Converting an array _to another array type works by converting each
294 * element in turn. Associative arrays can be converted _to associative
295 * arrays as long as keys and values can in turn be converted.
296 */
297@safe pure unittest
298{
299    import std.string : split;
300
301    int[] a = [1, 2, 3];
302    auto b = to!(float[])(a);
303    assert(b == [1.0f, 2, 3]);
304    string str = "1 2 3 4 5 6";
305    auto numbers = to!(double[])(split(str));
306    assert(numbers == [1.0, 2, 3, 4, 5, 6]);
307    int[string] c;
308    c["a"] = 1;
309    c["b"] = 2;
310    auto d = to!(double[wstring])(c);
311    assert(d["a"w] == 1 && d["b"w] == 2);
312}
313
314/**
315 * Conversions operate transitively, meaning that they work on arrays and
316 * associative arrays of any complexity.
317 *
318 * This conversion works because `to!short` applies _to an `int`, `to!wstring`
319 * applies _to a `string`, `to!string` applies _to a `double`, and
320 * `to!(double[])` applies _to an `int[]`. The conversion might throw an
321 * exception because `to!short` might fail the range check.
322 */
323@safe unittest
324{
325    int[string][double[int[]]] a;
326    auto b = to!(short[wstring][string[double[]]])(a);
327}
328
329/**
330 * Object-to-object conversions by dynamic casting throw exception when
331 * the source is non-null and the target is null.
332 */
333@safe pure unittest
334{
335    import std.exception : assertThrown;
336    // Testing object conversions
337    class A {}
338    class B : A {}
339    class C : A {}
340    A a1 = new A, a2 = new B, a3 = new C;
341    assert(to!B(a2) is a2);
342    assert(to!C(a3) is a3);
343    assertThrown!ConvException(to!B(a3));
344}
345
346/**
347 * Stringize conversion from all types is supported.
348 * $(UL
349 *   $(LI String _to string conversion works for any two string types having
350 *        ($(D char), $(D wchar), $(D dchar)) character widths and any
351 *        combination of qualifiers (mutable, $(D const), or $(D immutable)).)
352 *   $(LI Converts array (other than strings) _to string.
353 *        Each element is converted by calling $(D to!T).)
354 *   $(LI Associative array _to string conversion.
355 *        Each element is printed by calling $(D to!T).)
356 *   $(LI Object _to string conversion calls $(D toString) against the object or
357 *        returns $(D "null") if the object is null.)
358 *   $(LI Struct _to string conversion calls $(D toString) against the struct if
359 *        it is defined.)
360 *   $(LI For structs that do not define $(D toString), the conversion _to string
361 *        produces the list of fields.)
362 *   $(LI Enumerated types are converted _to strings as their symbolic names.)
363 *   $(LI Boolean values are printed as $(D "true") or $(D "false").)
364 *   $(LI $(D char), $(D wchar), $(D dchar) _to a string type.)
365 *   $(LI Unsigned or signed integers _to strings.
366 *        $(DL $(DT [special case])
367 *             $(DD Convert integral value _to string in $(D_PARAM radix) radix.
368 *             radix must be a value from 2 to 36.
369 *             value is treated as a signed value only if radix is 10.
370 *             The characters A through Z are used to represent values 10 through 36
371 *             and their case is determined by the $(D_PARAM letterCase) parameter.)))
372 *   $(LI All floating point types _to all string types.)
373 *   $(LI Pointer to string conversions prints the pointer as a $(D size_t) value.
374 *        If pointer is $(D char*), treat it as C-style strings.
375 *        In that case, this function is $(D @system).))
376 */
377@system pure unittest // @system due to cast and ptr
378{
379    // Conversion representing dynamic/static array with string
380    long[] a = [ 1, 3, 5 ];
381    assert(to!string(a) == "[1, 3, 5]");
382
383    // Conversion representing associative array with string
384    int[string] associativeArray = ["0":1, "1":2];
385    assert(to!string(associativeArray) == `["0":1, "1":2]` ||
386           to!string(associativeArray) == `["1":2, "0":1]`);
387
388    // char* to string conversion
389    assert(to!string(cast(char*) null) == "");
390    assert(to!string("foo\0".ptr) == "foo");
391
392    // Conversion reinterpreting void array to string
393    auto w = "abcx"w;
394    const(void)[] b = w;
395    assert(b.length == 8);
396
397    auto c = to!(wchar[])(b);
398    assert(c == "abcx");
399}
400
401// Tests for issue 6175
402@safe pure nothrow unittest
403{
404    char[9] sarr = "blablabla";
405    auto darr = to!(char[])(sarr);
406    assert(sarr.ptr == darr.ptr);
407    assert(sarr.length == darr.length);
408}
409
410// Tests for issue 7348
411@safe pure /+nothrow+/ unittest
412{
413    assert(to!string(null) == "null");
414    assert(text(null) == "null");
415}
416
417// Tests for issue 11390
418@safe pure /+nothrow+/ unittest
419{
420    const(typeof(null)) ctn;
421    immutable(typeof(null)) itn;
422    assert(to!string(ctn) == "null");
423    assert(to!string(itn) == "null");
424}
425
426// Tests for issue 8729: do NOT skip leading WS
427@safe pure unittest
428{
429    import std.exception;
430    foreach (T; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))
431    {
432        assertThrown!ConvException(to!T(" 0"));
433        assertThrown!ConvException(to!T(" 0", 8));
434    }
435    foreach (T; AliasSeq!(float, double, real))
436    {
437        assertThrown!ConvException(to!T(" 0"));
438    }
439
440    assertThrown!ConvException(to!bool(" true"));
441
442    alias NullType = typeof(null);
443    assertThrown!ConvException(to!NullType(" null"));
444
445    alias ARR = int[];
446    assertThrown!ConvException(to!ARR(" [1]"));
447
448    alias AA = int[int];
449    assertThrown!ConvException(to!AA(" [1:1]"));
450}
451
452/**
453If the source type is implicitly convertible to the target type, $(D
454to) simply performs the implicit conversion.
455 */
456private T toImpl(T, S)(S value)
457if (isImplicitlyConvertible!(S, T) &&
458    !isEnumStrToStr!(S, T) && !isNullToStr!(S, T))
459{
460    template isSignedInt(T)
461    {
462        enum isSignedInt = isIntegral!T && isSigned!T;
463    }
464    alias isUnsignedInt = isUnsigned;
465
466    // Conversion from integer to integer, and changing its sign
467    static if (isUnsignedInt!S && isSignedInt!T && S.sizeof == T.sizeof)
468    {   // unsigned to signed & same size
469        import std.exception : enforce;
470        enforce(value <= cast(S) T.max,
471                new ConvOverflowException("Conversion positive overflow"));
472    }
473    else static if (isSignedInt!S && isUnsignedInt!T)
474    {   // signed to unsigned
475        import std.exception : enforce;
476        enforce(0 <= value,
477                new ConvOverflowException("Conversion negative overflow"));
478    }
479
480    return value;
481}
482
483@safe pure nothrow unittest
484{
485    enum E { a }  // Issue 9523 - Allow identity enum conversion
486    auto e = to!E(E.a);
487    assert(e == E.a);
488}
489
490@safe pure nothrow unittest
491{
492    int a = 42;
493    auto b = to!long(a);
494    assert(a == b);
495}
496
497// Tests for issue 6377
498@safe pure unittest
499{
500    import std.exception;
501    // Conversion between same size
502    foreach (S; AliasSeq!(byte, short, int, long))
503    (){ // avoid slow optimizations for large functions @@@BUG@@@ 2396
504        alias U = Unsigned!S;
505
506        foreach (Sint; AliasSeq!(S, const S, immutable S))
507        foreach (Uint; AliasSeq!(U, const U, immutable U))
508        {
509            // positive overflow
510            Uint un = Uint.max;
511            assertThrown!ConvOverflowException(to!Sint(un),
512                text(Sint.stringof, ' ', Uint.stringof, ' ', un));
513
514            // negative overflow
515            Sint sn = -1;
516            assertThrown!ConvOverflowException(to!Uint(sn),
517                text(Sint.stringof, ' ', Uint.stringof, ' ', un));
518        }
519    }();
520
521    // Conversion between different size
522    foreach (i, S1; AliasSeq!(byte, short, int, long))
523    foreach (   S2; AliasSeq!(byte, short, int, long)[i+1..$])
524    (){ // avoid slow optimizations for large functions @@@BUG@@@ 2396
525        alias U1 = Unsigned!S1;
526        alias U2 = Unsigned!S2;
527
528        static assert(U1.sizeof < S2.sizeof);
529
530        // small unsigned to big signed
531        foreach (Uint; AliasSeq!(U1, const U1, immutable U1))
532        foreach (Sint; AliasSeq!(S2, const S2, immutable S2))
533        {
534            Uint un = Uint.max;
535            assertNotThrown(to!Sint(un));
536            assert(to!Sint(un) == un);
537        }
538
539        // big unsigned to small signed
540        foreach (Uint; AliasSeq!(U2, const U2, immutable U2))
541        foreach (Sint; AliasSeq!(S1, const S1, immutable S1))
542        {
543            Uint un = Uint.max;
544            assertThrown(to!Sint(un));
545        }
546
547        static assert(S1.sizeof < U2.sizeof);
548
549        // small signed to big unsigned
550        foreach (Sint; AliasSeq!(S1, const S1, immutable S1))
551        foreach (Uint; AliasSeq!(U2, const U2, immutable U2))
552        {
553            Sint sn = -1;
554            assertThrown!ConvOverflowException(to!Uint(sn));
555        }
556
557        // big signed to small unsigned
558        foreach (Sint; AliasSeq!(S2, const S2, immutable S2))
559        foreach (Uint; AliasSeq!(U1, const U1, immutable U1))
560        {
561            Sint sn = -1;
562            assertThrown!ConvOverflowException(to!Uint(sn));
563        }
564    }();
565}
566
567/*
568  Converting static arrays forwards to their dynamic counterparts.
569 */
570private T toImpl(T, S)(ref S s)
571if (isStaticArray!S)
572{
573    return toImpl!(T, typeof(s[0])[])(s);
574}
575
576@safe pure nothrow unittest
577{
578    char[4] test = ['a', 'b', 'c', 'd'];
579    static assert(!isInputRange!(Unqual!(char[4])));
580    assert(to!string(test) == test);
581}
582
583/**
584When source type supports member template function opCast, it is used.
585*/
586private T toImpl(T, S)(S value)
587if (!isImplicitlyConvertible!(S, T) &&
588    is(typeof(S.init.opCast!T()) : T) &&
589    !isExactSomeString!T &&
590    !is(typeof(T(value))))
591{
592    return value.opCast!T();
593}
594
595@safe pure unittest
596{
597    static struct Test
598    {
599        struct T
600        {
601            this(S s) @safe pure { }
602        }
603        struct S
604        {
605            T opCast(U)() @safe pure { assert(false); }
606        }
607    }
608    cast(void) to!(Test.T)(Test.S());
609
610    // make sure std.conv.to is doing the same thing as initialization
611    Test.S s;
612    Test.T t = s;
613}
614
615@safe pure unittest
616{
617    class B
618    {
619        T opCast(T)() { return 43; }
620    }
621    auto b = new B;
622    assert(to!int(b) == 43);
623
624    struct S
625    {
626        T opCast(T)() { return 43; }
627    }
628    auto s = S();
629    assert(to!int(s) == 43);
630}
631
632/**
633When target type supports 'converting construction', it is used.
634$(UL $(LI If target type is struct, $(D T(value)) is used.)
635     $(LI If target type is class, $(D new T(value)) is used.))
636*/
637private T toImpl(T, S)(S value)
638if (!isImplicitlyConvertible!(S, T) &&
639    is(T == struct) && is(typeof(T(value))))
640{
641    return T(value);
642}
643
644// Bugzilla 3961
645@safe pure unittest
646{
647    struct Int
648    {
649        int x;
650    }
651    Int i = to!Int(1);
652
653    static struct Int2
654    {
655        int x;
656        this(int x) @safe pure { this.x = x; }
657    }
658    Int2 i2 = to!Int2(1);
659
660    static struct Int3
661    {
662        int x;
663        static Int3 opCall(int x) @safe pure
664        {
665            Int3 i;
666            i.x = x;
667            return i;
668        }
669    }
670    Int3 i3 = to!Int3(1);
671}
672
673// Bugzilla 6808
674@safe pure unittest
675{
676    static struct FakeBigInt
677    {
678        this(string s) @safe pure {}
679    }
680
681    string s = "101";
682    auto i3 = to!FakeBigInt(s);
683}
684
685/// ditto
686private T toImpl(T, S)(S value)
687if (!isImplicitlyConvertible!(S, T) &&
688    is(T == class) && is(typeof(new T(value))))
689{
690    return new T(value);
691}
692
693@safe pure unittest
694{
695    static struct S
696    {
697        int x;
698    }
699    static class C
700    {
701        int x;
702        this(int x) @safe pure { this.x = x; }
703    }
704
705    static class B
706    {
707        int value;
708        this(S src) @safe pure { value = src.x; }
709        this(C src) @safe pure { value = src.x; }
710    }
711
712    S s = S(1);
713    auto b1 = to!B(s);  // == new B(s)
714    assert(b1.value == 1);
715
716    C c = new C(2);
717    auto b2 = to!B(c);  // == new B(c)
718    assert(b2.value == 2);
719
720    auto c2 = to!C(3);   // == new C(3)
721    assert(c2.x == 3);
722}
723
724@safe pure unittest
725{
726    struct S
727    {
728        class A
729        {
730            this(B b) @safe pure {}
731        }
732        class B : A
733        {
734            this() @safe pure { super(this); }
735        }
736    }
737
738    S.B b = new S.B();
739    S.A a = to!(S.A)(b);      // == cast(S.A) b
740                              // (do not run construction conversion like new S.A(b))
741    assert(b is a);
742
743    static class C : Object
744    {
745        this() @safe pure {}
746        this(Object o) @safe pure {}
747    }
748
749    Object oc = new C();
750    C a2 = to!C(oc);    // == new C(a)
751                        // Construction conversion overrides down-casting conversion
752    assert(a2 !is a);   //
753}
754
755/**
756Object-to-object conversions by dynamic casting throw exception when the source is
757non-null and the target is null.
758 */
759private T toImpl(T, S)(S value)
760if (!isImplicitlyConvertible!(S, T) &&
761    (is(S == class) || is(S == interface)) && !is(typeof(value.opCast!T()) : T) &&
762    (is(T == class) || is(T == interface)) && !is(typeof(new T(value))))
763{
764    static if (is(T == immutable))
765    {
766            // immutable <- immutable
767            enum isModConvertible = is(S == immutable);
768    }
769    else static if (is(T == const))
770    {
771        static if (is(T == shared))
772        {
773            // shared const <- shared
774            // shared const <- shared const
775            // shared const <- immutable
776            enum isModConvertible = is(S == shared) || is(S == immutable);
777        }
778        else
779        {
780            // const <- mutable
781            // const <- immutable
782            enum isModConvertible = !is(S == shared);
783        }
784    }
785    else
786    {
787        static if (is(T == shared))
788        {
789            // shared <- shared mutable
790            enum isModConvertible = is(S == shared) && !is(S == const);
791        }
792        else
793        {
794            // (mutable) <- (mutable)
795            enum isModConvertible = is(Unqual!S == S);
796        }
797    }
798    static assert(isModConvertible, "Bad modifier conversion: "~S.stringof~" to "~T.stringof);
799
800    auto result = ()@trusted{ return cast(T) value; }();
801    if (!result && value)
802    {
803        throw new ConvException("Cannot convert object of static type "
804                ~S.classinfo.name~" and dynamic type "~value.classinfo.name
805                ~" to type "~T.classinfo.name);
806    }
807    return result;
808}
809
810// Unittest for 6288
811@safe pure unittest
812{
813    import std.exception;
814
815    alias Identity(T)      =              T;
816    alias toConst(T)       =        const T;
817    alias toShared(T)      =       shared T;
818    alias toSharedConst(T) = shared const T;
819    alias toImmutable(T)   =    immutable T;
820    template AddModifier(int n)
821    if (0 <= n && n < 5)
822    {
823             static if (n == 0) alias AddModifier = Identity;
824        else static if (n == 1) alias AddModifier = toConst;
825        else static if (n == 2) alias AddModifier = toShared;
826        else static if (n == 3) alias AddModifier = toSharedConst;
827        else static if (n == 4) alias AddModifier = toImmutable;
828    }
829
830    interface I {}
831    interface J {}
832
833    class A {}
834    class B : A {}
835    class C : B, I, J {}
836    class D : I {}
837
838    foreach (m1; AliasSeq!(0,1,2,3,4)) // enumerate modifiers
839    foreach (m2; AliasSeq!(0,1,2,3,4)) // ditto
840    (){ // avoid slow optimizations for large functions @@@BUG@@@ 2396
841        alias srcmod = AddModifier!m1;
842        alias tgtmod = AddModifier!m2;
843
844        // Compile time convertible equals to modifier convertible.
845        static if (isImplicitlyConvertible!(srcmod!Object, tgtmod!Object))
846        {
847            // Test runtime conversions: class to class, class to interface,
848            // interface to class, and interface to interface
849
850            // Check that the runtime conversion to succeed
851            srcmod!A ac = new srcmod!C();
852            srcmod!I ic = new srcmod!C();
853            assert(to!(tgtmod!C)(ac) !is null); // A(c) to C
854            assert(to!(tgtmod!I)(ac) !is null); // A(c) to I
855            assert(to!(tgtmod!C)(ic) !is null); // I(c) to C
856            assert(to!(tgtmod!J)(ic) !is null); // I(c) to J
857
858            // Check that the runtime conversion fails
859            srcmod!A ab = new srcmod!B();
860            srcmod!I id = new srcmod!D();
861            assertThrown(to!(tgtmod!C)(ab));    // A(b) to C
862            assertThrown(to!(tgtmod!I)(ab));    // A(b) to I
863            assertThrown(to!(tgtmod!C)(id));    // I(d) to C
864            assertThrown(to!(tgtmod!J)(id));    // I(d) to J
865        }
866        else
867        {
868            // Check that the conversion is rejected statically
869            static assert(!is(typeof(to!(tgtmod!C)(srcmod!A.init))));   // A to C
870            static assert(!is(typeof(to!(tgtmod!I)(srcmod!A.init))));   // A to I
871            static assert(!is(typeof(to!(tgtmod!C)(srcmod!I.init))));   // I to C
872            static assert(!is(typeof(to!(tgtmod!J)(srcmod!I.init))));   // I to J
873        }
874    }();
875}
876
877/**
878Handles type _to string conversions
879*/
880private T toImpl(T, S)(S value)
881if (!(isImplicitlyConvertible!(S, T) &&
882    !isEnumStrToStr!(S, T) && !isNullToStr!(S, T)) &&
883    !isInfinite!S && isExactSomeString!T)
884{
885    static if (isExactSomeString!S && value[0].sizeof == ElementEncodingType!T.sizeof)
886    {
887        // string-to-string with incompatible qualifier conversion
888        static if (is(ElementEncodingType!T == immutable))
889        {
890            // conversion (mutable|const) -> immutable
891            return value.idup;
892        }
893        else
894        {
895            // conversion (immutable|const) -> mutable
896            return value.dup;
897        }
898    }
899    else static if (isExactSomeString!S)
900    {
901        import std.array : appender;
902        // other string-to-string
903        //Use Appender directly instead of toStr, which also uses a formatedWrite
904        auto w = appender!T();
905        w.put(value);
906        return w.data;
907    }
908    else static if (isIntegral!S && !is(S == enum))
909    {
910        // other integral-to-string conversions with default radix
911        return toImpl!(T, S)(value, 10);
912    }
913    else static if (is(S == void[]) || is(S == const(void)[]) || is(S == immutable(void)[]))
914    {
915        import core.stdc.string : memcpy;
916        import std.exception : enforce;
917        // Converting void array to string
918        alias Char = Unqual!(ElementEncodingType!T);
919        auto raw = cast(const(ubyte)[]) value;
920        enforce(raw.length % Char.sizeof == 0,
921                new ConvException("Alignment mismatch in converting a "
922                        ~ S.stringof ~ " to a "
923                        ~ T.stringof));
924        auto result = new Char[raw.length / Char.sizeof];
925        ()@trusted{ memcpy(result.ptr, value.ptr, value.length); }();
926        return cast(T) result;
927    }
928    else static if (isPointer!S && isSomeChar!(PointerTarget!S))
929    {
930        // This is unsafe because we cannot guarantee that the pointer is null terminated.
931        return () @system {
932            static if (is(S : const(char)*))
933                import core.stdc.string : strlen;
934            else
935                size_t strlen(S s) nothrow
936                {
937                    S p = s;
938                    while (*p++) {}
939                    return p-s-1;
940                }
941            return toImpl!T(value ? value[0 .. strlen(value)].dup : null);
942        }();
943    }
944    else static if (isSomeString!T && is(S == enum))
945    {
946        static if (isSwitchable!(OriginalType!S) && EnumMembers!S.length <= 50)
947        {
948            switch (value)
949            {
950                foreach (member; NoDuplicates!(EnumMembers!S))
951                {
952                    case member:
953                        return to!T(enumRep!(immutable(T), S, member));
954                }
955                default:
956            }
957        }
958        else
959        {
960            foreach (member; EnumMembers!S)
961            {
962                if (value == member)
963                    return to!T(enumRep!(immutable(T), S, member));
964            }
965        }
966
967        import std.array : appender;
968        import std.format : FormatSpec, formatValue;
969
970        //Default case, delegate to format
971        //Note: we don't call toStr directly, to avoid duplicate work.
972        auto app = appender!T();
973        app.put("cast(" ~ S.stringof ~ ")");
974        FormatSpec!char f;
975        formatValue(app, cast(OriginalType!S) value, f);
976        return app.data;
977    }
978    else
979    {
980        // other non-string values runs formatting
981        return toStr!T(value);
982    }
983}
984
985// Bugzilla 14042
986@system unittest
987{
988    immutable(char)* ptr = "hello".ptr;
989    auto result = ptr.to!(char[]);
990}
991// Bugzilla 8384
992@system unittest
993{
994    void test1(T)(T lp, string cmp)
995    {
996        foreach (e; AliasSeq!(char, wchar, dchar))
997        {
998            test2!(e[])(lp, cmp);
999            test2!(const(e)[])(lp, cmp);
1000            test2!(immutable(e)[])(lp, cmp);
1001        }
1002    }
1003
1004    void test2(D, S)(S lp, string cmp)
1005    {
1006        assert(to!string(to!D(lp)) == cmp);
1007    }
1008
1009    foreach (e; AliasSeq!("Hello, world!", "Hello, world!"w, "Hello, world!"d))
1010    {
1011        test1(e, "Hello, world!");
1012        test1(e.ptr, "Hello, world!");
1013    }
1014    foreach (e; AliasSeq!("", ""w, ""d))
1015    {
1016        test1(e, "");
1017        test1(e.ptr, "");
1018    }
1019}
1020
1021/*
1022    To string conversion for non copy-able structs
1023 */
1024private T toImpl(T, S)(ref S value)
1025if (!(isImplicitlyConvertible!(S, T) &&
1026    !isEnumStrToStr!(S, T) && !isNullToStr!(S, T)) &&
1027    !isInfinite!S && isExactSomeString!T && !isCopyable!S)
1028{
1029    import std.array : appender;
1030    import std.format : FormatSpec, formatValue;
1031
1032    auto w = appender!T();
1033    FormatSpec!(ElementEncodingType!T) f;
1034    formatValue(w, value, f);
1035    return w.data;
1036}
1037
1038// Bugzilla 16108
1039@system unittest
1040{
1041    static struct A
1042    {
1043        int val;
1044        bool flag;
1045
1046        string toString() { return text(val, ":", flag); }
1047
1048        @disable this(this);
1049    }
1050
1051    auto a = A();
1052    assert(to!string(a) == "0:false");
1053
1054    static struct B
1055    {
1056        int val;
1057        bool flag;
1058
1059        @disable this(this);
1060    }
1061
1062    auto b = B();
1063    assert(to!string(b) == "B(0, false)");
1064}
1065
1066/*
1067    Check whether type $(D T) can be used in a switch statement.
1068    This is useful for compile-time generation of switch case statements.
1069*/
1070private template isSwitchable(E)
1071{
1072    enum bool isSwitchable = is(typeof({
1073        switch (E.init) { default: }
1074    }));
1075}
1076
1077//
1078@safe unittest
1079{
1080    static assert(isSwitchable!int);
1081    static assert(!isSwitchable!double);
1082    static assert(!isSwitchable!real);
1083}
1084
1085//Static representation of the index I of the enum S,
1086//In representation T.
1087//T must be an immutable string (avoids un-necessary initializations).
1088private template enumRep(T, S, S value)
1089if (is (T == immutable) && isExactSomeString!T && is(S == enum))
1090{
1091    static T enumRep = toStr!T(value);
1092}
1093
1094@safe pure unittest
1095{
1096    import std.exception;
1097    void dg()
1098    {
1099        // string to string conversion
1100        alias Chars = AliasSeq!(char, wchar, dchar);
1101        foreach (LhsC; Chars)
1102        {
1103            alias LhStrings = AliasSeq!(LhsC[], const(LhsC)[], immutable(LhsC)[]);
1104            foreach (Lhs; LhStrings)
1105            {
1106                foreach (RhsC; Chars)
1107                {
1108                    alias RhStrings = AliasSeq!(RhsC[], const(RhsC)[], immutable(RhsC)[]);
1109                    foreach (Rhs; RhStrings)
1110                    {
1111                        Lhs s1 = to!Lhs("wyda");
1112                        Rhs s2 = to!Rhs(s1);
1113                        //writeln(Lhs.stringof, " -> ", Rhs.stringof);
1114                        assert(s1 == to!Lhs(s2));
1115                    }
1116                }
1117            }
1118        }
1119
1120        foreach (T; Chars)
1121        {
1122            foreach (U; Chars)
1123            {
1124                T[] s1 = to!(T[])("Hello, world!");
1125                auto s2 = to!(U[])(s1);
1126                assert(s1 == to!(T[])(s2));
1127                auto s3 = to!(const(U)[])(s1);
1128                assert(s1 == to!(T[])(s3));
1129                auto s4 = to!(immutable(U)[])(s1);
1130                assert(s1 == to!(T[])(s4));
1131            }
1132        }
1133    }
1134    dg();
1135    assertCTFEable!dg;
1136}
1137
1138@safe pure unittest
1139{
1140    // Conversion representing bool value with string
1141    bool b;
1142    assert(to!string(b) == "false");
1143    b = true;
1144    assert(to!string(b) == "true");
1145}
1146
1147@safe pure unittest
1148{
1149    // Conversion representing character value with string
1150    alias AllChars =
1151        AliasSeq!( char, const( char), immutable( char),
1152                  wchar, const(wchar), immutable(wchar),
1153                  dchar, const(dchar), immutable(dchar));
1154    foreach (Char1; AllChars)
1155    {
1156        foreach (Char2; AllChars)
1157        {
1158            Char1 c = 'a';
1159            assert(to!(Char2[])(c)[0] == c);
1160        }
1161        uint x = 4;
1162        assert(to!(Char1[])(x) == "4");
1163    }
1164
1165    string s = "foo";
1166    string s2;
1167    foreach (char c; s)
1168    {
1169        s2 ~= to!string(c);
1170    }
1171    assert(s2 == "foo");
1172}
1173
1174@safe pure nothrow unittest
1175{
1176    import std.exception;
1177    // Conversion representing integer values with string
1178
1179    foreach (Int; AliasSeq!(ubyte, ushort, uint, ulong))
1180    {
1181        assert(to!string(Int(0)) == "0");
1182        assert(to!string(Int(9)) == "9");
1183        assert(to!string(Int(123)) == "123");
1184    }
1185
1186    foreach (Int; AliasSeq!(byte, short, int, long))
1187    {
1188        assert(to!string(Int(0)) == "0");
1189        assert(to!string(Int(9)) == "9");
1190        assert(to!string(Int(123)) == "123");
1191        assert(to!string(Int(-0)) == "0");
1192        assert(to!string(Int(-9)) == "-9");
1193        assert(to!string(Int(-123)) == "-123");
1194        assert(to!string(const(Int)(6)) == "6");
1195    }
1196
1197    assert(wtext(int.max) == "2147483647"w);
1198    assert(wtext(int.min) == "-2147483648"w);
1199    assert(to!string(0L) == "0");
1200
1201    assertCTFEable!(
1202    {
1203        assert(to!string(1uL << 62) == "4611686018427387904");
1204        assert(to!string(0x100000000) == "4294967296");
1205        assert(to!string(-138L) == "-138");
1206    });
1207}
1208
1209@safe unittest // sprintf issue
1210{
1211    double[2] a = [ 1.5, 2.5 ];
1212    assert(to!string(a) == "[1.5, 2.5]");
1213}
1214
1215@system unittest
1216{
1217    // Conversion representing class object with string
1218    class A
1219    {
1220        override string toString() const { return "an A"; }
1221    }
1222    A a;
1223    assert(to!string(a) == "null");
1224    a = new A;
1225    assert(to!string(a) == "an A");
1226
1227    // Bug 7660
1228    class C { override string toString() const { return "C"; } }
1229    struct S { C c; alias c this; }
1230    S s; s.c = new C();
1231    assert(to!string(s) == "C");
1232}
1233
1234@safe unittest
1235{
1236    // Conversion representing struct object with string
1237    struct S1
1238    {
1239        string toString() { return "wyda"; }
1240    }
1241    assert(to!string(S1()) == "wyda");
1242
1243    struct S2
1244    {
1245        int a = 42;
1246        float b = 43.5;
1247    }
1248    S2 s2;
1249    assert(to!string(s2) == "S2(42, 43.5)");
1250
1251    // Test for issue 8080
1252    struct S8080
1253    {
1254        short[4] data;
1255        alias data this;
1256        string toString() { return "<S>"; }
1257    }
1258    S8080 s8080;
1259    assert(to!string(s8080) == "<S>");
1260}
1261
1262@safe unittest
1263{
1264    // Conversion representing enum value with string
1265    enum EB : bool { a = true }
1266    enum EU : uint { a = 0, b = 1, c = 2 }  // base type is unsigned
1267    enum EI : int { a = -1, b = 0, c = 1 }  // base type is signed (bug 7909)
1268    enum EF : real { a = 1.414, b = 1.732, c = 2.236 }
1269    enum EC : char { a = 'x', b = 'y' }
1270    enum ES : string { a = "aaa", b = "bbb" }
1271
1272    foreach (E; AliasSeq!(EB, EU, EI, EF, EC, ES))
1273    {
1274        assert(to! string(E.a) == "a"c);
1275        assert(to!wstring(E.a) == "a"w);
1276        assert(to!dstring(E.a) == "a"d);
1277    }
1278
1279    // Test an value not corresponding to an enum member.
1280    auto o = cast(EU) 5;
1281    assert(to! string(o) == "cast(EU)5"c);
1282    assert(to!wstring(o) == "cast(EU)5"w);
1283    assert(to!dstring(o) == "cast(EU)5"d);
1284}
1285
1286@safe unittest
1287{
1288    enum E
1289    {
1290        foo,
1291        doo = foo, // check duplicate switch statements
1292        bar,
1293    }
1294
1295    //Test regression 12494
1296    assert(to!string(E.foo) == "foo");
1297    assert(to!string(E.doo) == "foo");
1298    assert(to!string(E.bar) == "bar");
1299
1300    foreach (S; AliasSeq!(string, wstring, dstring, const(char[]), const(wchar[]), const(dchar[])))
1301    {
1302        auto s1 = to!S(E.foo);
1303        auto s2 = to!S(E.foo);
1304        assert(s1 == s2);
1305        // ensure we don't allocate when it's unnecessary
1306        assert(s1 is s2);
1307    }
1308
1309    foreach (S; AliasSeq!(char[], wchar[], dchar[]))
1310    {
1311        auto s1 = to!S(E.foo);
1312        auto s2 = to!S(E.foo);
1313        assert(s1 == s2);
1314        // ensure each mutable array is unique
1315        assert(s1 !is s2);
1316    }
1317}
1318
1319// ditto
1320@trusted pure private T toImpl(T, S)(S value, uint radix, LetterCase letterCase = LetterCase.upper)
1321if (isIntegral!S &&
1322    isExactSomeString!T)
1323in
1324{
1325    assert(radix >= 2 && radix <= 36);
1326}
1327body
1328{
1329    alias EEType = Unqual!(ElementEncodingType!T);
1330
1331    T toStringRadixConvert(size_t bufLen)(uint runtimeRadix = 0)
1332    {
1333        Unsigned!(Unqual!S) div = void, mValue = unsigned(value);
1334
1335        size_t index = bufLen;
1336        EEType[bufLen] buffer = void;
1337        char baseChar = letterCase == LetterCase.lower ? 'a' : 'A';
1338        char mod = void;
1339
1340        do
1341        {
1342            div = cast(S)(mValue / runtimeRadix );
1343            mod = cast(ubyte)(mValue % runtimeRadix);
1344            mod += mod < 10 ? '0' : baseChar - 10;
1345            buffer[--index] = cast(char) mod;
1346            mValue = div;
1347        } while (mValue);
1348
1349        return cast(T) buffer[index .. $].dup;
1350    }
1351
1352    import std.array : array;
1353    switch (radix)
1354    {
1355        case 10:
1356            // The (value+0) is so integral promotions happen to the type
1357            return toChars!(10, EEType)(value + 0).array;
1358        case 16:
1359            // The unsigned(unsigned(value)+0) is so unsigned integral promotions happen to the type
1360            if (letterCase == letterCase.upper)
1361                return toChars!(16, EEType, LetterCase.upper)(unsigned(unsigned(value) + 0)).array;
1362            else
1363                return toChars!(16, EEType, LetterCase.lower)(unsigned(unsigned(value) + 0)).array;
1364        case 2:
1365            return toChars!(2, EEType)(unsigned(unsigned(value) + 0)).array;
1366        case 8:
1367            return toChars!(8, EEType)(unsigned(unsigned(value) + 0)).array;
1368
1369        default:
1370            return toStringRadixConvert!(S.sizeof * 6)(radix);
1371    }
1372}
1373
1374@safe pure nothrow unittest
1375{
1376    foreach (Int; AliasSeq!(uint, ulong))
1377    {
1378        assert(to!string(Int(16), 16) == "10");
1379        assert(to!string(Int(15), 2u) == "1111");
1380        assert(to!string(Int(1), 2u) == "1");
1381        assert(to!string(Int(0x1234AF), 16u) == "1234AF");
1382        assert(to!string(Int(0x1234BCD), 16u, LetterCase.upper) == "1234BCD");
1383        assert(to!string(Int(0x1234AF), 16u, LetterCase.lower) == "1234af");
1384    }
1385
1386    foreach (Int; AliasSeq!(int, long))
1387    {
1388        assert(to!string(Int(-10), 10u) == "-10");
1389    }
1390
1391    assert(to!string(byte(-10), 16) == "F6");
1392    assert(to!string(long.min) == "-9223372036854775808");
1393    assert(to!string(long.max) == "9223372036854775807");
1394}
1395
1396/**
1397Narrowing numeric-numeric conversions throw when the value does not
1398fit in the narrower type.
1399 */
1400private T toImpl(T, S)(S value)
1401if (!isImplicitlyConvertible!(S, T) &&
1402    (isNumeric!S || isSomeChar!S || isBoolean!S) &&
1403    (isNumeric!T || isSomeChar!T || isBoolean!T) && !is(T == enum))
1404{
1405    enum sSmallest = mostNegative!S;
1406    enum tSmallest = mostNegative!T;
1407    static if (sSmallest < 0)
1408    {
1409        // possible underflow converting from a signed
1410        static if (tSmallest == 0)
1411        {
1412            immutable good = value >= 0;
1413        }
1414        else
1415        {
1416            static assert(tSmallest < 0);
1417            immutable good = value >= tSmallest;
1418        }
1419        if (!good)
1420            throw new ConvOverflowException("Conversion negative overflow");
1421    }
1422    static if (S.max > T.max)
1423    {
1424        // possible overflow
1425        if (value > T.max)
1426            throw new ConvOverflowException("Conversion positive overflow");
1427    }
1428    return (ref value)@trusted{ return cast(T) value; }(value);
1429}
1430
1431@safe pure unittest
1432{
1433    import std.exception;
1434
1435    dchar a = ' ';
1436    assert(to!char(a) == ' ');
1437    a = 300;
1438    assert(collectException(to!char(a)));
1439
1440    dchar from0 = 'A';
1441    char to0 = to!char(from0);
1442
1443    wchar from1 = 'A';
1444    char to1 = to!char(from1);
1445
1446    char from2 = 'A';
1447    char to2 = to!char(from2);
1448
1449    char from3 = 'A';
1450    wchar to3 = to!wchar(from3);
1451
1452    char from4 = 'A';
1453    dchar to4 = to!dchar(from4);
1454}
1455
1456@safe unittest
1457{
1458    import std.exception;
1459
1460    // Narrowing conversions from enum -> integral should be allowed, but they
1461    // should throw at runtime if the enum value doesn't fit in the target
1462    // type.
1463    enum E1 : ulong { A = 1, B = 1UL << 48, C = 0 }
1464    assert(to!int(E1.A) == 1);
1465    assert(to!bool(E1.A) == true);
1466    assertThrown!ConvOverflowException(to!int(E1.B)); // E1.B overflows int
1467    assertThrown!ConvOverflowException(to!bool(E1.B)); // E1.B overflows bool
1468    assert(to!bool(E1.C) == false);
1469
1470    enum E2 : long { A = -1L << 48, B = -1 << 31, C = 1 << 31 }
1471    assertThrown!ConvOverflowException(to!int(E2.A)); // E2.A overflows int
1472    assertThrown!ConvOverflowException(to!uint(E2.B)); // E2.B overflows uint
1473    assert(to!int(E2.B) == -1 << 31); // but does not overflow int
1474    assert(to!int(E2.C) == 1 << 31);  // E2.C does not overflow int
1475
1476    enum E3 : int { A = -1, B = 1, C = 255, D = 0 }
1477    assertThrown!ConvOverflowException(to!ubyte(E3.A));
1478    assertThrown!ConvOverflowException(to!bool(E3.A));
1479    assert(to!byte(E3.A) == -1);
1480    assert(to!byte(E3.B) == 1);
1481    assert(to!ubyte(E3.C) == 255);
1482    assert(to!bool(E3.B) == true);
1483    assertThrown!ConvOverflowException(to!byte(E3.C));
1484    assertThrown!ConvOverflowException(to!bool(E3.C));
1485    assert(to!bool(E3.D) == false);
1486
1487}
1488
1489/**
1490Array-to-array conversion (except when target is a string type)
1491converts each element in turn by using $(D to).
1492 */
1493private T toImpl(T, S)(S value)
1494if (!isImplicitlyConvertible!(S, T) &&
1495    !isSomeString!S && isDynamicArray!S &&
1496    !isExactSomeString!T && isArray!T)
1497{
1498    alias E = typeof(T.init[0]);
1499
1500    static if (isStaticArray!T)
1501    {
1502        import std.exception : enforce;
1503        auto res = to!(E[])(value);
1504        enforce!ConvException(T.length == res.length,
1505            convFormat("Length mismatch when converting to static array: %s vs %s", T.length, res.length));
1506        return res[0 .. T.length];
1507    }
1508    else
1509    {
1510        import std.array : appender;
1511        auto w = appender!(E[])();
1512        w.reserve(value.length);
1513        foreach (i, ref e; value)
1514        {
1515            w.put(to!E(e));
1516        }
1517        return w.data;
1518    }
1519}
1520
1521@safe pure unittest
1522{
1523    import std.exception;
1524
1525    // array to array conversions
1526    uint[] a = [ 1u, 2, 3 ];
1527    auto b = to!(float[])(a);
1528    assert(b == [ 1.0f, 2, 3 ]);
1529
1530    immutable(int)[3] d = [ 1, 2, 3 ];
1531    b = to!(float[])(d);
1532    assert(b == [ 1.0f, 2, 3 ]);
1533
1534    uint[][] e = [ a, a ];
1535    auto f = to!(float[][])(e);
1536    assert(f[0] == b && f[1] == b);
1537
1538    // Test for bug 8264
1539    struct Wrap
1540    {
1541        string wrap;
1542        alias wrap this;
1543    }
1544    Wrap[] warr = to!(Wrap[])(["foo", "bar"]);  // should work
1545
1546    // Issue 12633
1547    import std.conv : to;
1548    const s2 = ["10", "20"];
1549
1550    immutable int[2] a3 = s2.to!(int[2]);
1551    assert(a3 == [10, 20]);
1552
1553    // verify length mismatches are caught
1554    immutable s4 = [1, 2, 3, 4];
1555    foreach (i; [1, 4])
1556    {
1557        auto ex = collectException(s4[0 .. i].to!(int[2]));
1558            assert(ex && ex.msg == "Length mismatch when converting to static array: 2 vs " ~ [cast(char)(i + '0')],
1559                ex ? ex.msg : "Exception was not thrown!");
1560    }
1561}
1562
1563@safe unittest
1564{
1565    auto b = [ 1.0f, 2, 3 ];
1566
1567    auto c = to!(string[])(b);
1568    assert(c[0] == "1" && c[1] == "2" && c[2] == "3");
1569}
1570
1571/**
1572Associative array to associative array conversion converts each key
1573and each value in turn.
1574 */
1575private T toImpl(T, S)(S value)
1576if (isAssociativeArray!S &&
1577    isAssociativeArray!T && !is(T == enum))
1578{
1579    /* This code is potentially unsafe.
1580     */
1581    alias K2 = KeyType!T;
1582    alias V2 = ValueType!T;
1583
1584    // While we are "building" the AA, we need to unqualify its values, and only re-qualify at the end
1585    Unqual!V2[K2] result;
1586
1587    foreach (k1, v1; value)
1588    {
1589        // Cast values temporarily to Unqual!V2 to store them to result variable
1590        result[to!K2(k1)] = cast(Unqual!V2) to!V2(v1);
1591    }
1592    // Cast back to original type
1593    return cast(T) result;
1594}
1595
1596@safe unittest
1597{
1598    // hash to hash conversions
1599    int[string] a;
1600    a["0"] = 1;
1601    a["1"] = 2;
1602    auto b = to!(double[dstring])(a);
1603    assert(b["0"d] == 1 && b["1"d] == 2);
1604}
1605@safe unittest // Bugzilla 8705, from doc
1606{
1607    import std.exception;
1608    int[string][double[int[]]] a;
1609    auto b = to!(short[wstring][string[double[]]])(a);
1610    a = [null:["hello":int.max]];
1611    assertThrown!ConvOverflowException(to!(short[wstring][string[double[]]])(a));
1612}
1613@system unittest // Extra cases for AA with qualifiers conversion
1614{
1615    int[][int[]] a;// = [[], []];
1616    auto b = to!(immutable(short[])[immutable short[]])(a);
1617
1618    double[dstring][int[long[]]] c;
1619    auto d = to!(immutable(short[immutable wstring])[immutable string[double[]]])(c);
1620}
1621
1622private void testIntegralToFloating(Integral, Floating)()
1623{
1624    Integral a = 42;
1625    auto b = to!Floating(a);
1626    assert(a == b);
1627    assert(a == to!Integral(b));
1628}
1629
1630private void testFloatingToIntegral(Floating, Integral)()
1631{
1632    bool convFails(Source, Target, E)(Source src)
1633    {
1634        try
1635            auto t = to!Target(src);
1636        catch (E)
1637            return true;
1638        return false;
1639    }
1640
1641    // convert some value
1642    Floating a = 4.2e1;
1643    auto b = to!Integral(a);
1644    assert(is(typeof(b) == Integral) && b == 42);
1645    // convert some negative value (if applicable)
1646    a = -4.2e1;
1647    static if (Integral.min < 0)
1648    {
1649        b = to!Integral(a);
1650        assert(is(typeof(b) == Integral) && b == -42);
1651    }
1652    else
1653    {
1654        // no go for unsigned types
1655        assert(convFails!(Floating, Integral, ConvOverflowException)(a));
1656    }
1657    // convert to the smallest integral value
1658    a = 0.0 + Integral.min;
1659    static if (Integral.min < 0)
1660    {
1661        a = -a; // -Integral.min not representable as an Integral
1662        assert(convFails!(Floating, Integral, ConvOverflowException)(a)
1663                || Floating.sizeof <= Integral.sizeof);
1664    }
1665    a = 0.0 + Integral.min;
1666    assert(to!Integral(a) == Integral.min);
1667    --a; // no more representable as an Integral
1668    assert(convFails!(Floating, Integral, ConvOverflowException)(a)
1669            || Floating.sizeof <= Integral.sizeof);
1670    a = 0.0 + Integral.max;
1671    assert(to!Integral(a) == Integral.max || Floating.sizeof <= Integral.sizeof);
1672    ++a; // no more representable as an Integral
1673    assert(convFails!(Floating, Integral, ConvOverflowException)(a)
1674            || Floating.sizeof <= Integral.sizeof);
1675    // convert a value with a fractional part
1676    a = 3.14;
1677    assert(to!Integral(a) == 3);
1678    a = 3.99;
1679    assert(to!Integral(a) == 3);
1680    static if (Integral.min < 0)
1681    {
1682        a = -3.14;
1683        assert(to!Integral(a) == -3);
1684        a = -3.99;
1685        assert(to!Integral(a) == -3);
1686    }
1687}
1688
1689@safe pure unittest
1690{
1691    alias AllInts = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong);
1692    alias AllFloats = AliasSeq!(float, double, real);
1693    alias AllNumerics = AliasSeq!(AllInts, AllFloats);
1694    // test with same type
1695    {
1696        foreach (T; AllNumerics)
1697        {
1698            T a = 42;
1699            auto b = to!T(a);
1700            assert(is(typeof(a) == typeof(b)) && a == b);
1701        }
1702    }
1703    // test that floating-point numbers convert properly to largest ints
1704    // see http://oregonstate.edu/~peterseb/mth351/docs/351s2001_fp80x87.html
1705    // look for "largest fp integer with a predecessor"
1706    {
1707        // float
1708        int a = 16_777_215; // 2^24 - 1
1709        assert(to!int(to!float(a)) == a);
1710        assert(to!int(to!float(-a)) == -a);
1711        // double
1712        long b = 9_007_199_254_740_991; // 2^53 - 1
1713        assert(to!long(to!double(b)) == b);
1714        assert(to!long(to!double(-b)) == -b);
1715        // real
1716        static if (real.mant_dig >= 64)
1717        {
1718            ulong c = 18_446_744_073_709_551_615UL; // 2^64 - 1
1719            assert(to!ulong(to!real(c)) == c);
1720        }
1721    }
1722    // test conversions floating => integral
1723    {
1724        // AllInts[0 .. $ - 1] should be AllInts
1725        // @@@ BUG IN COMPILER @@@
1726        foreach (Integral; AllInts[0 .. $ - 1])
1727        {
1728            foreach (Floating; AllFloats)
1729            {
1730                testFloatingToIntegral!(Floating, Integral)();
1731            }
1732        }
1733    }
1734    // test conversion integral => floating
1735    {
1736        foreach (Integral; AllInts[0 .. $ - 1])
1737        {
1738            foreach (Floating; AllFloats)
1739            {
1740                testIntegralToFloating!(Integral, Floating)();
1741            }
1742        }
1743    }
1744    // test parsing
1745    {
1746        foreach (T; AllNumerics)
1747        {
1748            // from type immutable(char)[2]
1749            auto a = to!T("42");
1750            assert(a == 42);
1751            // from type char[]
1752            char[] s1 = "42".dup;
1753            a = to!T(s1);
1754            assert(a == 42);
1755            // from type char[2]
1756            char[2] s2;
1757            s2[] = "42";
1758            a = to!T(s2);
1759            assert(a == 42);
1760            // from type immutable(wchar)[2]
1761            a = to!T("42"w);
1762            assert(a == 42);
1763        }
1764    }
1765}
1766
1767@safe unittest
1768{
1769    alias AllInts = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong);
1770    alias AllFloats = AliasSeq!(float, double, real);
1771    alias AllNumerics = AliasSeq!(AllInts, AllFloats);
1772    // test conversions to string
1773    {
1774        foreach (T; AllNumerics)
1775        {
1776            T a = 42;
1777            assert(to!string(a) == "42");
1778            assert(to!wstring(a) == "42"w);
1779            assert(to!dstring(a) == "42"d);
1780            // array test
1781            T[] b = new T[2];
1782            b[0] = 42;
1783            b[1] = 33;
1784            assert(to!string(b) == "[42, 33]");
1785        }
1786    }
1787    // test array to string conversion
1788    foreach (T ; AllNumerics)
1789    {
1790        auto a = [to!T(1), 2, 3];
1791        assert(to!string(a) == "[1, 2, 3]");
1792    }
1793    // test enum to int conversion
1794    enum Testing { Test1, Test2 }
1795    Testing t;
1796    auto a = to!string(t);
1797    assert(a == "Test1");
1798}
1799
1800
1801/**
1802String, or string-like input range, to non-string conversion runs parsing.
1803$(UL
1804  $(LI When the source is a wide string, it is first converted to a narrow
1805       string and then parsed.)
1806  $(LI When the source is a narrow string, normal text parsing occurs.))
1807*/
1808private T toImpl(T, S)(S value)
1809if (isInputRange!S && isSomeChar!(ElementEncodingType!S) &&
1810    !isExactSomeString!T && is(typeof(parse!T(value))))
1811{
1812    scope(success)
1813    {
1814        if (!value.empty)
1815        {
1816            throw convError!(S, T)(value);
1817        }
1818    }
1819    return parse!T(value);
1820}
1821
1822/// ditto
1823private T toImpl(T, S)(S value, uint radix)
1824if (isInputRange!S && !isInfinite!S && isSomeChar!(ElementEncodingType!S) &&
1825    isIntegral!T && is(typeof(parse!T(value, radix))))
1826{
1827    scope(success)
1828    {
1829        if (!value.empty)
1830        {
1831            throw convError!(S, T)(value);
1832        }
1833    }
1834    return parse!T(value, radix);
1835}
1836
1837@safe pure unittest
1838{
1839    // Issue 6668 - ensure no collaterals thrown
1840    try { to!uint("-1"); }
1841    catch (ConvException e) { assert(e.next is null); }
1842}
1843
1844@safe pure unittest
1845{
1846    foreach (Str; AliasSeq!(string, wstring, dstring))
1847    {
1848        Str a = "123";
1849        assert(to!int(a) == 123);
1850        assert(to!double(a) == 123);
1851    }
1852
1853    // 6255
1854    auto n = to!int("FF", 16);
1855    assert(n == 255);
1856}
1857
1858// bugzilla 15800
1859@safe unittest
1860{
1861    import std.utf : byCodeUnit, byChar, byWchar, byDchar;
1862
1863    assert(to!int(byCodeUnit("10")) == 10);
1864    assert(to!int(byCodeUnit("10"), 10) == 10);
1865    assert(to!int(byCodeUnit("10"w)) == 10);
1866    assert(to!int(byCodeUnit("10"w), 10) == 10);
1867
1868    assert(to!int(byChar("10")) == 10);
1869    assert(to!int(byChar("10"), 10) == 10);
1870    assert(to!int(byWchar("10")) == 10);
1871    assert(to!int(byWchar("10"), 10) == 10);
1872    assert(to!int(byDchar("10")) == 10);
1873    assert(to!int(byDchar("10"), 10) == 10);
1874}
1875
1876/**
1877Convert a value that is implicitly convertible to the enum base type
1878into an Enum value. If the value does not match any enum member values
1879a ConvException is thrown.
1880Enums with floating-point or string base types are not supported.
1881*/
1882private T toImpl(T, S)(S value)
1883if (is(T == enum) && !is(S == enum)
1884    && is(typeof(value == OriginalType!T.init))
1885    && !isFloatingPoint!(OriginalType!T) && !isSomeString!(OriginalType!T))
1886{
1887    foreach (Member; EnumMembers!T)
1888    {
1889        if (Member == value)
1890            return Member;
1891    }
1892    throw new ConvException(convFormat("Value (%s) does not match any member value of enum '%s'", value, T.stringof));
1893}
1894
1895@safe pure unittest
1896{
1897    import std.exception;
1898    enum En8143 : int { A = 10, B = 20, C = 30, D = 20 }
1899    enum En8143[][] m3 = to!(En8143[][])([[10, 30], [30, 10]]);
1900    static assert(m3 == [[En8143.A, En8143.C], [En8143.C, En8143.A]]);
1901
1902    En8143 en1 = to!En8143(10);
1903    assert(en1 == En8143.A);
1904    assertThrown!ConvException(to!En8143(5));   // matches none
1905    En8143[][] m1 = to!(En8143[][])([[10, 30], [30, 10]]);
1906    assert(m1 == [[En8143.A, En8143.C], [En8143.C, En8143.A]]);
1907}
1908
1909/***************************************************************
1910 Rounded conversion from floating point to integral.
1911
1912Rounded conversions do not work with non-integral target types.
1913 */
1914
1915template roundTo(Target)
1916{
1917    Target roundTo(Source)(Source value)
1918    {
1919        import std.math : trunc;
1920
1921        static assert(isFloatingPoint!Source);
1922        static assert(isIntegral!Target);
1923        return to!Target(trunc(value + (value < 0 ? -0.5L : 0.5L)));
1924    }
1925}
1926
1927///
1928@safe unittest
1929{
1930    assert(roundTo!int(3.14) == 3);
1931    assert(roundTo!int(3.49) == 3);
1932    assert(roundTo!int(3.5) == 4);
1933    assert(roundTo!int(3.999) == 4);
1934    assert(roundTo!int(-3.14) == -3);
1935    assert(roundTo!int(-3.49) == -3);
1936    assert(roundTo!int(-3.5) == -4);
1937    assert(roundTo!int(-3.999) == -4);
1938    assert(roundTo!(const int)(to!(const double)(-3.999)) == -4);
1939}
1940
1941@safe unittest
1942{
1943    import std.exception;
1944    // boundary values
1945    foreach (Int; AliasSeq!(byte, ubyte, short, ushort, int, uint))
1946    {
1947        assert(roundTo!Int(Int.min - 0.4L) == Int.min);
1948        assert(roundTo!Int(Int.max + 0.4L) == Int.max);
1949        assertThrown!ConvOverflowException(roundTo!Int(Int.min - 0.5L));
1950        assertThrown!ConvOverflowException(roundTo!Int(Int.max + 0.5L));
1951    }
1952}
1953
1954/**
1955The $(D parse) family of functions works quite like the $(D to)
1956family, except that:
1957$(OL
1958    $(LI It only works with character ranges as input.)
1959    $(LI It takes the input by reference. (This means that rvalues - such
1960    as string literals - are not accepted: use $(D to) instead.))
1961    $(LI It advances the input to the position following the conversion.)
1962    $(LI It does not throw if it could not convert the entire input.))
1963
1964This overload converts an character input range to a `bool`.
1965
1966Params:
1967    Target = the type to convert to
1968    source = the lvalue of an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
1969
1970Returns:
1971    A `bool`
1972
1973Throws:
1974    A $(LREF ConvException) if the range does not represent a `bool`.
1975
1976Note:
1977    All character input range conversions using $(LREF to) are forwarded
1978    to `parse` and do not require lvalues.
1979*/
1980Target parse(Target, Source)(ref Source source)
1981if (isInputRange!Source &&
1982    isSomeChar!(ElementType!Source) &&
1983    is(Unqual!Target == bool))
1984{
1985    import std.ascii : toLower;
1986
1987    static if (isNarrowString!Source)
1988    {
1989        import std.string : representation;
1990        auto s = source.representation;
1991    }
1992    else
1993    {
1994        alias s = source;
1995    }
1996
1997    if (!s.empty)
1998    {
1999        auto c1 = toLower(s.front);
2000        bool result = c1 == 't';
2001        if (result || c1 == 'f')
2002        {
2003            s.popFront();
2004            foreach (c; result ? "rue" : "alse")
2005            {
2006                if (s.empty || toLower(s.front) != c)
2007                    goto Lerr;
2008                s.popFront();
2009            }
2010
2011            static if (isNarrowString!Source)
2012                source = cast(Source) s;
2013
2014            return result;
2015        }
2016    }
2017Lerr:
2018    throw parseError("bool should be case-insensitive 'true' or 'false'");
2019}
2020
2021///
2022@safe unittest
2023{
2024    auto s = "true";
2025    bool b = parse!bool(s);
2026    assert(b);
2027}
2028
2029@safe unittest
2030{
2031    import std.algorithm.comparison : equal;
2032    import std.exception;
2033    struct InputString
2034    {
2035        string _s;
2036        @property auto front() { return _s.front; }
2037        @property bool empty() { return _s.empty; }
2038        void popFront() { _s.popFront(); }
2039    }
2040
2041    auto s = InputString("trueFALSETrueFalsetRUEfALSE");
2042    assert(parse!bool(s) == true);
2043    assert(s.equal("FALSETrueFalsetRUEfALSE"));
2044    assert(parse!bool(s) == false);
2045    assert(s.equal("TrueFalsetRUEfALSE"));
2046    assert(parse!bool(s) == true);
2047    assert(s.equal("FalsetRUEfALSE"));
2048    assert(parse!bool(s) == false);
2049    assert(s.equal("tRUEfALSE"));
2050    assert(parse!bool(s) == true);
2051    assert(s.equal("fALSE"));
2052    assert(parse!bool(s) == false);
2053    assert(s.empty);
2054
2055    foreach (ss; ["tfalse", "ftrue", "t", "f", "tru", "fals", ""])
2056    {
2057        s = InputString(ss);
2058        assertThrown!ConvException(parse!bool(s));
2059    }
2060}
2061
2062/**
2063Parses a character $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
2064to an integral value.
2065
2066Params:
2067    Target = the integral type to convert to
2068    s = the lvalue of an input range
2069
2070Returns:
2071    A number of type `Target`
2072
2073Throws:
2074    A $(LREF ConvException) If an overflow occurred during conversion or
2075    if no character of the input was meaningfully converted.
2076*/
2077Target parse(Target, Source)(ref Source s)
2078if (isSomeChar!(ElementType!Source) &&
2079    isIntegral!Target && !is(Target == enum))
2080{
2081    static if (Target.sizeof < int.sizeof)
2082    {
2083        // smaller types are handled like integers
2084        auto v = .parse!(Select!(Target.min < 0, int, uint))(s);
2085        auto result = ()@trusted{ return cast(Target) v; }();
2086        if (result == v)
2087            return result;
2088        throw new ConvOverflowException("Overflow in integral conversion");
2089    }
2090    else
2091    {
2092        // int or larger types
2093
2094        static if (Target.min < 0)
2095            bool sign = false;
2096        else
2097            enum bool sign = false;
2098
2099        enum char maxLastDigit = Target.min < 0 ? 7 : 5;
2100        uint c;
2101
2102        static if (isNarrowString!Source)
2103        {
2104            import std.string : representation;
2105            auto source = s.representation;
2106        }
2107        else
2108        {
2109            alias source = s;
2110        }
2111
2112        if (source.empty)
2113            goto Lerr;
2114
2115        c = source.front;
2116
2117        static if (Target.min < 0)
2118        {
2119            switch (c)
2120            {
2121                case '-':
2122                    sign = true;
2123                    goto case '+';
2124                case '+':
2125                    source.popFront();
2126
2127                    if (source.empty)
2128                        goto Lerr;
2129
2130                    c = source.front;
2131
2132                    break;
2133
2134                default:
2135                    break;
2136            }
2137        }
2138        c -= '0';
2139        if (c <= 9)
2140        {
2141            Target v = cast(Target) c;
2142
2143            source.popFront();
2144
2145            while (!source.empty)
2146            {
2147                c = cast(typeof(c)) (source.front - '0');
2148
2149                if (c > 9)
2150                    break;
2151
2152                if (v >= 0 && (v < Target.max/10 ||
2153                    (v == Target.max/10 && c <= maxLastDigit + sign)))
2154                {
2155                    // Note: `v` can become negative here in case of parsing
2156                    // the most negative value:
2157                    v = cast(Target) (v * 10 + c);
2158
2159                    source.popFront();
2160                }
2161                else
2162                    throw new ConvOverflowException("Overflow in integral conversion");
2163            }
2164
2165            if (sign)
2166                v = -v;
2167
2168            static if (isNarrowString!Source)
2169                s = cast(Source) source;
2170
2171            return v;
2172        }
2173Lerr:
2174        static if (isNarrowString!Source)
2175            throw convError!(Source, Target)(cast(Source) source);
2176        else
2177            throw convError!(Source, Target)(source);
2178    }
2179}
2180
2181///
2182@safe pure unittest
2183{
2184    string s = "123";
2185    auto a = parse!int(s);
2186    assert(a == 123);
2187
2188    // parse only accepts lvalues
2189    static assert(!__traits(compiles, parse!int("123")));
2190}
2191
2192///
2193@safe pure unittest
2194{
2195    import std.string : tr;
2196    string test = "123 \t  76.14";
2197    auto a = parse!uint(test);
2198    assert(a == 123);
2199    assert(test == " \t  76.14"); // parse bumps string
2200    test = tr(test, " \t\n\r", "", "d"); // skip ws
2201    assert(test == "76.14");
2202    auto b = parse!double(test);
2203    assert(b == 76.14);
2204    assert(test == "");
2205}
2206
2207@safe pure unittest
2208{
2209    foreach (Int; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))
2210    {
2211        {
2212            assert(to!Int("0") == 0);
2213
2214            static if (isSigned!Int)
2215            {
2216                assert(to!Int("+0") == 0);
2217                assert(to!Int("-0") == 0);
2218            }
2219        }
2220
2221        static if (Int.sizeof >= byte.sizeof)
2222        {
2223                assert(to!Int("6") == 6);
2224                assert(to!Int("23") == 23);
2225                assert(to!Int("68") == 68);
2226                assert(to!Int("127") == 0x7F);
2227
2228            static if (isUnsigned!Int)
2229            {
2230                assert(to!Int("255") == 0xFF);
2231            }
2232            static if (isSigned!Int)
2233            {
2234                assert(to!Int("+6") == 6);
2235                assert(to!Int("+23") == 23);
2236                assert(to!Int("+68") == 68);
2237                assert(to!Int("+127") == 0x7F);
2238
2239                assert(to!Int("-6") == -6);
2240                assert(to!Int("-23") == -23);
2241                assert(to!Int("-68") == -68);
2242                assert(to!Int("-128") == -128);
2243            }
2244        }
2245
2246        static if (Int.sizeof >= short.sizeof)
2247        {
2248                assert(to!Int("468") == 468);
2249                assert(to!Int("32767") == 0x7FFF);
2250
2251            static if (isUnsigned!Int)
2252            {
2253                assert(to!Int("65535") == 0xFFFF);
2254            }
2255            static if (isSigned!Int)
2256            {
2257                assert(to!Int("+468") == 468);
2258                assert(to!Int("+32767") == 0x7FFF);
2259
2260                assert(to!Int("-468") == -468);
2261                assert(to!Int("-32768") == -32768);
2262            }
2263        }
2264
2265        static if (Int.sizeof >= int.sizeof)
2266        {
2267                assert(to!Int("2147483647") == 0x7FFFFFFF);
2268
2269            static if (isUnsigned!Int)
2270            {
2271                assert(to!Int("4294967295") == 0xFFFFFFFF);
2272            }
2273
2274            static if (isSigned!Int)
2275            {
2276                assert(to!Int("+2147483647") == 0x7FFFFFFF);
2277
2278                assert(to!Int("-2147483648") == -2147483648);
2279            }
2280        }
2281
2282        static if (Int.sizeof >= long.sizeof)
2283        {
2284                assert(to!Int("9223372036854775807") == 0x7FFFFFFFFFFFFFFF);
2285
2286            static if (isUnsigned!Int)
2287            {
2288                assert(to!Int("18446744073709551615") == 0xFFFFFFFFFFFFFFFF);
2289            }
2290
2291            static if (isSigned!Int)
2292            {
2293                assert(to!Int("+9223372036854775807") == 0x7FFFFFFFFFFFFFFF);
2294
2295                assert(to!Int("-9223372036854775808") == 0x8000000000000000);
2296            }
2297        }
2298    }
2299}
2300
2301@safe pure unittest
2302{
2303    import std.exception;
2304    // parsing error check
2305    foreach (Int; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))
2306    {
2307        {
2308            immutable string[] errors1 =
2309            [
2310                "",
2311                "-",
2312                "+",
2313                "-+",
2314                " ",
2315                " 0",
2316                "0 ",
2317                "- 0",
2318                "1-",
2319                "xx",
2320                "123h",
2321                "-+1",
2322                "--1",
2323                "+-1",
2324                "++1",
2325            ];
2326            foreach (j, s; errors1)
2327                assertThrown!ConvException(to!Int(s));
2328        }
2329
2330        // parse!SomeUnsigned cannot parse head sign.
2331        static if (isUnsigned!Int)
2332        {
2333            immutable string[] errors2 =
2334            [
2335                "+5",
2336                "-78",
2337            ];
2338            foreach (j, s; errors2)
2339                assertThrown!ConvException(to!Int(s));
2340        }
2341    }
2342
2343    // positive overflow check
2344    foreach (i, Int; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))
2345    {
2346        immutable string[] errors =
2347        [
2348            "128",                  // > byte.max
2349            "256",                  // > ubyte.max
2350            "32768",                // > short.max
2351            "65536",                // > ushort.max
2352            "2147483648",           // > int.max
2353            "4294967296",           // > uint.max
2354            "9223372036854775808",  // > long.max
2355            "18446744073709551616", // > ulong.max
2356        ];
2357        foreach (j, s; errors[i..$])
2358            assertThrown!ConvOverflowException(to!Int(s));
2359    }
2360
2361    // negative overflow check
2362    foreach (i, Int; AliasSeq!(byte, short, int, long))
2363    {
2364        immutable string[] errors =
2365        [
2366            "-129",                 // < byte.min
2367            "-32769",               // < short.min
2368            "-2147483649",          // < int.min
2369            "-9223372036854775809", // < long.min
2370        ];
2371        foreach (j, s; errors[i..$])
2372            assertThrown!ConvOverflowException(to!Int(s));
2373    }
2374}
2375
2376@safe pure unittest
2377{
2378    void checkErrMsg(string input, dchar charInMsg, dchar charNotInMsg)
2379    {
2380        try
2381        {
2382            int x = input.to!int();
2383            assert(false, "Invalid conversion did not throw");
2384        }
2385        catch (ConvException e)
2386        {
2387            // Ensure error message contains failing character, not the character
2388            // beyond.
2389            import std.algorithm.searching : canFind;
2390            assert( e.msg.canFind(charInMsg) &&
2391                   !e.msg.canFind(charNotInMsg));
2392        }
2393        catch (Exception e)
2394        {
2395            assert(false, "Did not throw ConvException");
2396        }
2397    }
2398    checkErrMsg("@$", '@', '$');
2399    checkErrMsg("@$123", '@', '$');
2400    checkErrMsg("1@$23", '@', '$');
2401    checkErrMsg("1@$", '@', '$');
2402    checkErrMsg("1@$2", '@', '$');
2403    checkErrMsg("12@$", '@', '$');
2404}
2405
2406@safe pure unittest
2407{
2408    import std.exception;
2409    assertCTFEable!({ string s =  "1234abc"; assert(parse! int(s) ==  1234 && s == "abc"); });
2410    assertCTFEable!({ string s = "-1234abc"; assert(parse! int(s) == -1234 && s == "abc"); });
2411    assertCTFEable!({ string s =  "1234abc"; assert(parse!uint(s) ==  1234 && s == "abc"); });
2412}
2413
2414// Issue 13931
2415@safe pure unittest
2416{
2417    import std.exception;
2418
2419    assertThrown!ConvOverflowException("-21474836480".to!int());
2420    assertThrown!ConvOverflowException("-92233720368547758080".to!long());
2421}
2422
2423// Issue 14396
2424@safe pure unittest
2425{
2426    struct StrInputRange
2427    {
2428        this (string s) { str = s; }
2429        char front() const @property { return str[front_index]; }
2430        char popFront() { return str[front_index++]; }
2431        bool empty() const @property { return str.length <= front_index; }
2432        string str;
2433        size_t front_index = 0;
2434    }
2435    auto input = StrInputRange("777");
2436    assert(parse!int(input) == 777);
2437}
2438
2439/// ditto
2440Target parse(Target, Source)(ref Source source, uint radix)
2441if (isSomeChar!(ElementType!Source) &&
2442    isIntegral!Target && !is(Target == enum))
2443in
2444{
2445    assert(radix >= 2 && radix <= 36);
2446}
2447body
2448{
2449    import core.checkedint : mulu, addu;
2450    import std.exception : enforce;
2451
2452    if (radix == 10)
2453        return parse!Target(source);
2454
2455    enforce!ConvException(!source.empty, "s must not be empty in integral parse");
2456
2457    immutable uint beyond = (radix < 10 ? '0' : 'a'-10) + radix;
2458    Target v = 0;
2459
2460    static if (isNarrowString!Source)
2461    {
2462        import std.string : representation;
2463        auto s = source.representation;
2464    }
2465    else
2466    {
2467        alias s = source;
2468    }
2469
2470    do
2471    {
2472        uint c = s.front;
2473        if (c < '0')
2474            break;
2475        if (radix < 10)
2476        {
2477            if (c >= beyond)
2478                break;
2479        }
2480        else
2481        {
2482            if (c > '9')
2483            {
2484                c |= 0x20;//poorman's tolower
2485                if (c < 'a' || c >= beyond)
2486                    break;
2487                c -= 'a'-10-'0';
2488            }
2489        }
2490
2491        bool overflow = false;
2492        auto nextv = v.mulu(radix, overflow).addu(c - '0', overflow);
2493        enforce!ConvOverflowException(!overflow && nextv <= Target.max, "Overflow in integral conversion");
2494        v = cast(Target) nextv;
2495        s.popFront();
2496    } while (!s.empty);
2497
2498    static if (isNarrowString!Source)
2499        source = cast(Source) s;
2500
2501    return v;
2502}
2503
2504@safe pure unittest
2505{
2506    string s; // parse doesn't accept rvalues
2507    foreach (i; 2 .. 37)
2508    {
2509        assert(parse!int(s = "0", i) == 0);
2510        assert(parse!int(s = "1", i) == 1);
2511        assert(parse!byte(s = "10", i) == i);
2512    }
2513
2514    assert(parse!int(s = "0011001101101", 2) == 0b0011001101101);
2515    assert(parse!int(s = "765", 8) == octal!765);
2516    assert(parse!int(s = "fCDe", 16) == 0xfcde);
2517
2518    // 6609
2519    assert(parse!int(s = "-42", 10) == -42);
2520
2521    assert(parse!ubyte(s = "ff", 16) == 0xFF);
2522}
2523
2524@safe pure unittest // bugzilla 7302
2525{
2526    import std.range : cycle;
2527    auto r = cycle("2A!");
2528    auto u = parse!uint(r, 16);
2529    assert(u == 42);
2530    assert(r.front == '!');
2531}
2532
2533@safe pure unittest // bugzilla 13163
2534{
2535    import std.exception;
2536    foreach (s; ["fff", "123"])
2537        assertThrown!ConvOverflowException(s.parse!ubyte(16));
2538}
2539
2540@safe pure unittest // bugzilla 17282
2541{
2542    auto str = "0=\x00\x02\x55\x40&\xff\xf0\n\x00\x04\x55\x40\xff\xf0~4+10\n";
2543    assert(parse!uint(str) == 0);
2544}
2545
2546/**
2547 * Takes a string representing an `enum` type and returns that type.
2548 *
2549 * Params:
2550 *     Target = the `enum` type to convert to
2551 *     s = the lvalue of the range to _parse
2552 *
2553 * Returns:
2554 *     An `enum` of type `Target`
2555 *
2556 * Throws:
2557 *     A $(LREF ConvException) if type `Target` does not have a member
2558 *     represented by `s`.
2559 */
2560Target parse(Target, Source)(ref Source s)
2561if (isSomeString!Source && !is(Source == enum) &&
2562    is(Target == enum))
2563{
2564    import std.algorithm.searching : startsWith;
2565    Target result;
2566    size_t longest_match = 0;
2567
2568    foreach (i, e; EnumMembers!Target)
2569    {
2570        auto ident = __traits(allMembers, Target)[i];
2571        if (longest_match < ident.length && s.startsWith(ident))
2572        {
2573            result = e;
2574            longest_match = ident.length ;
2575        }
2576    }
2577
2578    if (longest_match > 0)
2579    {
2580        s = s[longest_match .. $];
2581        return result ;
2582    }
2583
2584    throw new ConvException(
2585        Target.stringof ~ " does not have a member named '"
2586        ~ to!string(s) ~ "'");
2587}
2588
2589///
2590@safe unittest
2591{
2592    enum EnumType : bool { a = true, b = false, c = a }
2593
2594    auto str = "a";
2595    assert(parse!EnumType(str) == EnumType.a);
2596}
2597
2598@safe unittest
2599{
2600    import std.exception;
2601
2602    enum EB : bool { a = true, b = false, c = a }
2603    enum EU { a, b, c }
2604    enum EI { a = -1, b = 0, c = 1 }
2605    enum EF : real { a = 1.414, b = 1.732, c = 2.236 }
2606    enum EC : char { a = 'a', b = 'b', c = 'c' }
2607    enum ES : string { a = "aaa", b = "bbb", c = "ccc" }
2608
2609    foreach (E; AliasSeq!(EB, EU, EI, EF, EC, ES))
2610    {
2611        assert(to!E("a"c) == E.a);
2612        assert(to!E("b"w) == E.b);
2613        assert(to!E("c"d) == E.c);
2614
2615        assertThrown!ConvException(to!E("d"));
2616    }
2617}
2618
2619@safe pure unittest // bugzilla 4744
2620{
2621    enum A { member1, member11, member111 }
2622    assert(to!A("member1"  ) == A.member1  );
2623    assert(to!A("member11" ) == A.member11 );
2624    assert(to!A("member111") == A.member111);
2625    auto s = "member1111";
2626    assert(parse!A(s) == A.member111 && s == "1");
2627}
2628
2629/**
2630 * Parses a character range to a floating point number.
2631 *
2632 * Params:
2633 *     Target = a floating point type
2634 *     source = the lvalue of the range to _parse
2635 *
2636 * Returns:
2637 *     A floating point number of type `Target`
2638 *
2639 * Throws:
2640 *     A $(LREF ConvException) if `p` is empty, if no number could be
2641 *     parsed, or if an overflow occurred.
2642 */
2643Target parse(Target, Source)(ref Source source)
2644if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum) &&
2645    isFloatingPoint!Target && !is(Target == enum))
2646{
2647    import std.ascii : isDigit, isAlpha, toLower, toUpper, isHexDigit;
2648    import std.exception : enforce;
2649
2650    static if (isNarrowString!Source)
2651    {
2652        import std.string : representation;
2653        auto p = source.representation;
2654    }
2655    else
2656    {
2657        alias p = source;
2658    }
2659
2660    static immutable real[14] negtab =
2661        [ 1e-4096L,1e-2048L,1e-1024L,1e-512L,1e-256L,1e-128L,1e-64L,1e-32L,
2662                1e-16L,1e-8L,1e-4L,1e-2L,1e-1L,1.0L ];
2663    static immutable real[13] postab =
2664        [ 1e+4096L,1e+2048L,1e+1024L,1e+512L,1e+256L,1e+128L,1e+64L,1e+32L,
2665                1e+16L,1e+8L,1e+4L,1e+2L,1e+1L ];
2666
2667    ConvException bailOut()(string msg = null, string fn = __FILE__, size_t ln = __LINE__)
2668    {
2669        if (msg == null)
2670            msg = "Floating point conversion error";
2671        return new ConvException(text(msg, " for input \"", source, "\"."), fn, ln);
2672    }
2673
2674
2675    enforce(!p.empty, bailOut());
2676
2677    bool sign = false;
2678    switch (p.front)
2679    {
2680    case '-':
2681        sign = true;
2682        p.popFront();
2683        enforce(!p.empty, bailOut());
2684        if (toLower(p.front) == 'i')
2685            goto case 'i';
2686        break;
2687    case '+':
2688        p.popFront();
2689        enforce(!p.empty, bailOut());
2690        break;
2691    case 'i': case 'I':
2692        // inf
2693        p.popFront();
2694        enforce(!p.empty && toUpper(p.front) == 'N',
2695               bailOut("error converting input to floating point"));
2696        p.popFront();
2697        enforce(!p.empty && toUpper(p.front) == 'F',
2698               bailOut("error converting input to floating point"));
2699        // skip past the last 'f'
2700        p.popFront();
2701        static if (isNarrowString!Source)
2702            source = cast(Source) p;
2703        return sign ? -Target.infinity : Target.infinity;
2704    default: {}
2705    }
2706
2707    bool isHex = false;
2708    bool startsWithZero = p.front == '0';
2709    if (startsWithZero)
2710    {
2711        p.popFront();
2712        if (p.empty)
2713        {
2714            static if (isNarrowString!Source)
2715                source = cast(Source) p;
2716            return sign ? -0.0 : 0.0;
2717        }
2718
2719        isHex = p.front == 'x' || p.front == 'X';
2720        if (isHex) p.popFront();
2721    }
2722    else if (toLower(p.front) == 'n')
2723    {
2724        // nan
2725        p.popFront();
2726        enforce(!p.empty && toUpper(p.front) == 'A',
2727               bailOut("error converting input to floating point"));
2728        p.popFront();
2729        enforce(!p.empty && toUpper(p.front) == 'N',
2730               bailOut("error converting input to floating point"));
2731        // skip past the last 'n'
2732        p.popFront();
2733        static if (isNarrowString!Source)
2734            source = cast(Source) p;
2735        return typeof(return).nan;
2736    }
2737
2738    /*
2739     * The following algorithm consists of 2 steps:
2740     * 1) parseDigits processes the textual input into msdec and possibly
2741     *    lsdec/msscale variables, followed by the exponent parser which sets
2742     *    exp below.
2743     *    Hex: input is 0xaaaaa...p+000... where aaaa is the mantissa in hex
2744     *    and 000 is the exponent in decimal format with base 2.
2745     *    Decimal: input is 0.00333...p+000... where 0.0033 is the mantissa
2746     *    in decimal and 000 is the exponent in decimal format with base 10.
2747     * 2) Convert msdec/lsdec and exp into native real format
2748     */
2749
2750    real ldval = 0.0;
2751    char dot = 0;                        /* if decimal point has been seen */
2752    int exp = 0;
2753    ulong msdec = 0, lsdec = 0;
2754    ulong msscale = 1;
2755    bool sawDigits;
2756
2757    enum { hex, decimal }
2758
2759    // sets msdec, lsdec/msscale, and sawDigits by parsing the mantissa digits
2760    void parseDigits(alias FloatFormat)()
2761    {
2762        static if (FloatFormat == hex)
2763        {
2764            enum uint base = 16;
2765            enum ulong msscaleMax = 0x1000_0000_0000_0000UL; // largest power of 16 a ulong holds
2766            enum ubyte expIter = 4; // iterate the base-2 exponent by 4 for every hex digit
2767            alias checkDigit = isHexDigit;
2768            /*
2769             * convert letter to binary representation: First clear bit
2770             * to convert lower space chars to upperspace, then -('A'-10)
2771             * converts letter A to 10, letter B to 11, ...
2772             */
2773            alias convertDigit = (int x) => isAlpha(x) ? ((x & ~0x20) - ('A' - 10)) : x - '0';
2774            sawDigits = false;
2775        }
2776        else static if (FloatFormat == decimal)
2777        {
2778            enum uint base = 10;
2779            enum ulong msscaleMax = 10_000_000_000_000_000_000UL; // largest power of 10 a ulong holds
2780            enum ubyte expIter = 1; // iterate the base-10 exponent once for every decimal digit
2781            alias checkDigit = isDigit;
2782            alias convertDigit = (int x) => x - '0';
2783            // Used to enforce that any mantissa digits are present
2784            sawDigits = startsWithZero;
2785        }
2786        else
2787            static assert(false, "Unrecognized floating-point format used.");
2788
2789        while (!p.empty)
2790        {
2791            int i = p.front;
2792            while (checkDigit(i))
2793            {
2794                sawDigits = true;        /* must have at least 1 digit   */
2795
2796                i = convertDigit(i);
2797
2798                if (msdec < (ulong.max - base)/base)
2799                {
2800                    // For base 16: Y = ... + y3*16^3 + y2*16^2 + y1*16^1 + y0*16^0
2801                    msdec = msdec * base + i;
2802                }
2803                else if (msscale < msscaleMax)
2804                {
2805                    lsdec = lsdec * base + i;
2806                    msscale *= base;
2807                }
2808                else
2809                {
2810                    exp += expIter;
2811                }
2812                exp -= dot;
2813                p.popFront();
2814                if (p.empty)
2815                    break;
2816                i = p.front;
2817                if (i == '_')
2818                {
2819                    p.popFront();
2820                    if (p.empty)
2821                        break;
2822                    i = p.front;
2823                }
2824            }
2825            if (i == '.' && !dot)
2826            {
2827                p.popFront();
2828                dot += expIter;
2829            }
2830            else
2831                break;
2832        }
2833
2834        // Have we seen any mantissa digits so far?
2835        enforce(sawDigits, bailOut("no digits seen"));
2836        static if (FloatFormat == hex)
2837            enforce(!p.empty && (p.front == 'p' || p.front == 'P'),
2838                    bailOut("Floating point parsing: exponent is required"));
2839    }
2840
2841    if (isHex)
2842        parseDigits!hex;
2843    else
2844        parseDigits!decimal;
2845
2846    if (isHex || (!p.empty && (p.front == 'e' || p.front == 'E')))
2847    {
2848        char sexp = 0;
2849        int e = 0;
2850
2851        p.popFront();
2852        enforce(!p.empty, new ConvException("Unexpected end of input"));
2853        switch (p.front)
2854        {
2855            case '-':    sexp++;
2856                         goto case;
2857            case '+':    p.popFront();
2858                         break;
2859            default: {}
2860        }
2861        sawDigits = false;
2862        while (!p.empty && isDigit(p.front))
2863        {
2864            if (e < 0x7FFFFFFF / 10 - 10)   // prevent integer overflow
2865            {
2866                e = e * 10 + p.front - '0';
2867            }
2868            p.popFront();
2869            sawDigits = true;
2870        }
2871        exp += (sexp) ? -e : e;
2872        enforce(sawDigits, new ConvException("No digits seen."));
2873    }
2874
2875    ldval = msdec;
2876    if (msscale != 1)               /* if stuff was accumulated in lsdec */
2877        ldval = ldval * msscale + lsdec;
2878    if (isHex)
2879    {
2880        import std.math : ldexp;
2881
2882        // Exponent is power of 2, not power of 10
2883        ldval = ldexp(ldval,exp);
2884    }
2885    else if (ldval)
2886    {
2887        uint u = 0;
2888        int pow = 4096;
2889
2890        while (exp > 0)
2891        {
2892            while (exp >= pow)
2893            {
2894                ldval *= postab[u];
2895                exp -= pow;
2896            }
2897            pow >>= 1;
2898            u++;
2899        }
2900        while (exp < 0)
2901        {
2902            while (exp <= -pow)
2903            {
2904                ldval *= negtab[u];
2905                enforce(ldval != 0, new ConvException("Range error"));
2906                exp += pow;
2907            }
2908            pow >>= 1;
2909            u++;
2910        }
2911    }
2912
2913    // if overflow occurred
2914    enforce(ldval != real.infinity, new ConvException("Range error"));
2915
2916    static if (isNarrowString!Source)
2917        source = cast(Source) p;
2918    return sign ? -ldval : ldval;
2919}
2920
2921///
2922@safe unittest
2923{
2924    import std.math : approxEqual;
2925    auto str = "123.456";
2926
2927    assert(parse!double(str).approxEqual(123.456));
2928}
2929
2930@safe unittest
2931{
2932    import std.exception;
2933    import std.math : isNaN, fabs;
2934
2935    // Compare reals with given precision
2936    bool feq(in real rx, in real ry, in real precision = 0.000001L)
2937    {
2938        if (rx == ry)
2939            return 1;
2940
2941        if (isNaN(rx))
2942            return cast(bool) isNaN(ry);
2943
2944        if (isNaN(ry))
2945            return 0;
2946
2947        return cast(bool)(fabs(rx - ry) <= precision);
2948    }
2949
2950    // Make given typed literal
2951    F Literal(F)(F f)
2952    {
2953        return f;
2954    }
2955
2956    foreach (Float; AliasSeq!(float, double, real))
2957    {
2958        assert(to!Float("123") == Literal!Float(123));
2959        assert(to!Float("+123") == Literal!Float(+123));
2960        assert(to!Float("-123") == Literal!Float(-123));
2961        assert(to!Float("123e2") == Literal!Float(123e2));
2962        assert(to!Float("123e+2") == Literal!Float(123e+2));
2963        assert(to!Float("123e-2") == Literal!Float(123e-2));
2964        assert(to!Float("123.") == Literal!Float(123.0));
2965        assert(to!Float(".375") == Literal!Float(.375));
2966
2967        assert(to!Float("1.23375E+2") == Literal!Float(1.23375E+2));
2968
2969        assert(to!Float("0") is 0.0);
2970        assert(to!Float("-0") is -0.0);
2971
2972        assert(isNaN(to!Float("nan")));
2973
2974        assertThrown!ConvException(to!Float("\x00"));
2975    }
2976
2977    // min and max
2978    float f = to!float("1.17549e-38");
2979    assert(feq(cast(real) f, cast(real) 1.17549e-38));
2980    assert(feq(cast(real) f, cast(real) float.min_normal));
2981    f = to!float("3.40282e+38");
2982    assert(to!string(f) == to!string(3.40282e+38));
2983
2984    // min and max
2985    double d = to!double("2.22508e-308");
2986    assert(feq(cast(real) d, cast(real) 2.22508e-308));
2987    assert(feq(cast(real) d, cast(real) double.min_normal));
2988    d = to!double("1.79769e+308");
2989    assert(to!string(d) == to!string(1.79769e+308));
2990    assert(to!string(d) == to!string(double.max));
2991
2992    assert(to!string(to!real(to!string(real.max / 2L))) == to!string(real.max / 2L));
2993
2994    // min and max
2995    real r = to!real(to!string(real.min_normal));
2996    version (NetBSD)
2997    {
2998        // NetBSD notice
2999        // to!string returns 3.3621e-4932L. It is less than real.min_normal and it is subnormal value
3000        // Simple C code
3001        //     long double rd = 3.3621e-4932L;
3002        //     printf("%Le\n", rd);
3003        // has unexpected result: 1.681050e-4932
3004        //
3005        // Bug report: http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=50937
3006    }
3007    else
3008    {
3009        assert(to!string(r) == to!string(real.min_normal));
3010    }
3011    r = to!real(to!string(real.max));
3012    assert(to!string(r) == to!string(real.max));
3013}
3014
3015// Tests for the double implementation
3016@system unittest
3017{
3018    // @system because strtod is not @safe.
3019    static if (real.mant_dig == 53)
3020    {
3021        import core.stdc.stdlib, std.exception, std.math;
3022
3023        //Should be parsed exactly: 53 bit mantissa
3024        string s = "0x1A_BCDE_F012_3456p10";
3025        auto x = parse!real(s);
3026        assert(x == 0x1A_BCDE_F012_3456p10L);
3027        //1 bit is implicit
3028        assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0xA_BCDE_F012_3456);
3029        assert(strtod("0x1ABCDEF0123456p10", null) == x);
3030
3031        //Should be parsed exactly: 10 bit mantissa
3032        s = "0x3FFp10";
3033        x = parse!real(s);
3034        assert(x == 0x03FFp10);
3035        //1 bit is implicit
3036        assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x000F_F800_0000_0000);
3037        assert(strtod("0x3FFp10", null) == x);
3038
3039        //60 bit mantissa, round up
3040        s = "0xFFF_FFFF_FFFF_FFFFp10";
3041        x = parse!real(s);
3042        assert(approxEqual(x, 0xFFF_FFFF_FFFF_FFFFp10));
3043        //1 bit is implicit
3044        assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x0000_0000_0000_0000);
3045        assert(strtod("0xFFFFFFFFFFFFFFFp10", null) == x);
3046
3047        //60 bit mantissa, round down
3048        s = "0xFFF_FFFF_FFFF_FF90p10";
3049        x = parse!real(s);
3050        assert(approxEqual(x, 0xFFF_FFFF_FFFF_FF90p10));
3051        //1 bit is implicit
3052        assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x000F_FFFF_FFFF_FFFF);
3053        assert(strtod("0xFFFFFFFFFFFFF90p10", null) == x);
3054
3055        //61 bit mantissa, round up 2
3056        s = "0x1F0F_FFFF_FFFF_FFFFp10";
3057        x = parse!real(s);
3058        assert(approxEqual(x, 0x1F0F_FFFF_FFFF_FFFFp10));
3059        //1 bit is implicit
3060        assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x000F_1000_0000_0000);
3061        assert(strtod("0x1F0FFFFFFFFFFFFFp10", null) == x);
3062
3063        //61 bit mantissa, round down 2
3064        s = "0x1F0F_FFFF_FFFF_FF10p10";
3065        x = parse!real(s);
3066        assert(approxEqual(x, 0x1F0F_FFFF_FFFF_FF10p10));
3067        //1 bit is implicit
3068        assert(((*cast(ulong*)&x) & 0x000F_FFFF_FFFF_FFFF) == 0x000F_0FFF_FFFF_FFFF);
3069        assert(strtod("0x1F0FFFFFFFFFFF10p10", null) == x);
3070
3071        //Huge exponent
3072        s = "0x1F_FFFF_FFFF_FFFFp900";
3073        x = parse!real(s);
3074        assert(strtod("0x1FFFFFFFFFFFFFp900", null) == x);
3075
3076        //exponent too big -> converror
3077        s = "";
3078        assertThrown!ConvException(x = parse!real(s));
3079        assert(strtod("0x1FFFFFFFFFFFFFp1024", null) == real.infinity);
3080
3081        //-exponent too big -> 0
3082        s = "0x1FFFFFFFFFFFFFp-2000";
3083        x = parse!real(s);
3084        assert(x == 0);
3085        assert(strtod("0x1FFFFFFFFFFFFFp-2000", null) == x);
3086    }
3087}
3088
3089@system unittest
3090{
3091    import core.stdc.errno;
3092    import core.stdc.stdlib;
3093    import std.math : floatTraits, RealFormat;
3094
3095    errno = 0;  // In case it was set by another unittest in a different module.
3096    struct longdouble
3097    {
3098        static if (floatTraits!real.realFormat == RealFormat.ieeeQuadruple)
3099        {
3100            ushort[8] value;
3101        }
3102        else static if (floatTraits!real.realFormat == RealFormat.ieeeExtended)
3103        {
3104            ushort[5] value;
3105        }
3106        else static if (floatTraits!real.realFormat == RealFormat.ieeeDouble)
3107        {
3108            ushort[4] value;
3109        }
3110        else
3111            static assert(false, "Not implemented");
3112    }
3113
3114    real ld;
3115    longdouble x;
3116    real ld1;
3117    longdouble x1;
3118    int i;
3119
3120    static if (floatTraits!real.realFormat == RealFormat.ieeeQuadruple)
3121        // Our parser is currently limited to ieeeExtended precision
3122        enum s = "0x1.FFFFFFFFFFFFFFFEp-16382";
3123    else static if (floatTraits!real.realFormat == RealFormat.ieeeExtended)
3124        enum s = "0x1.FFFFFFFFFFFFFFFEp-16382";
3125    else static if (floatTraits!real.realFormat == RealFormat.ieeeDouble)
3126        enum s = "0x1.FFFFFFFFFFFFFFFEp-1000";
3127    else
3128        static assert(false, "Floating point format for real not supported");
3129
3130    auto s2 = s.idup;
3131    ld = parse!real(s2);
3132    assert(s2.empty);
3133    x = *cast(longdouble *)&ld;
3134
3135    static if (floatTraits!real.realFormat == RealFormat.ieeeExtended)
3136    {
3137        version (CRuntime_Microsoft)
3138            ld1 = 0x1.FFFFFFFFFFFFFFFEp-16382L; // strtold currently mapped to strtod
3139        else version (CRuntime_Bionic)
3140            ld1 = 0x1.FFFFFFFFFFFFFFFEp-16382L; // strtold currently mapped to strtod
3141        else
3142            ld1 = strtold(s.ptr, null);
3143    }
3144    else
3145        ld1 = strtold(s.ptr, null);
3146
3147    x1 = *cast(longdouble *)&ld1;
3148    assert(x1 == x && ld1 == ld);
3149
3150    assert(!errno);
3151
3152    s2 = "1.0e5";
3153    ld = parse!real(s2);
3154    assert(s2.empty);
3155    x = *cast(longdouble *)&ld;
3156    ld1 = strtold("1.0e5", null);
3157    x1 = *cast(longdouble *)&ld1;
3158}
3159
3160@safe pure unittest
3161{
3162    import std.exception;
3163
3164    // Bugzilla 4959
3165    {
3166        auto s = "0 ";
3167        auto x = parse!double(s);
3168        assert(s == " ");
3169        assert(x == 0.0);
3170    }
3171
3172    // Bugzilla 3369
3173    assert(to!float("inf") == float.infinity);
3174    assert(to!float("-inf") == -float.infinity);
3175
3176    // Bugzilla 6160
3177    assert(6_5.536e3L == to!real("6_5.536e3"));                     // 2^16
3178    assert(0x1000_000_000_p10 == to!real("0x1000_000_000_p10"));    // 7.03687e+13
3179
3180    // Bugzilla 6258
3181    assertThrown!ConvException(to!real("-"));
3182    assertThrown!ConvException(to!real("in"));
3183
3184    // Bugzilla 7055
3185    assertThrown!ConvException(to!float("INF2"));
3186
3187    //extra stress testing
3188    auto ssOK    = ["1.", "1.1.1", "1.e5", "2e1e", "2a", "2e1_1",
3189                    "inf", "-inf", "infa", "-infa", "inf2e2", "-inf2e2"];
3190    auto ssKO    = ["", " ", "2e", "2e+", "2e-", "2ee", "2e++1", "2e--1", "2e_1", "+inf"];
3191    foreach (s; ssOK)
3192        parse!double(s);
3193    foreach (s; ssKO)
3194        assertThrown!ConvException(parse!double(s));
3195}
3196
3197/**
3198Parsing one character off a range returns the first element and calls `popFront`.
3199
3200Params:
3201    Target = the type to convert to
3202    s = the lvalue of an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
3203
3204Returns:
3205    A character of type `Target`
3206
3207Throws:
3208    A $(LREF ConvException) if the range is empty.
3209 */
3210Target parse(Target, Source)(ref Source s)
3211if (isSomeString!Source && !is(Source == enum) &&
3212    staticIndexOf!(Unqual!Target, dchar, Unqual!(ElementEncodingType!Source)) >= 0)
3213{
3214    if (s.empty)
3215        throw convError!(Source, Target)(s);
3216    static if (is(Unqual!Target == dchar))
3217    {
3218        Target result = s.front;
3219        s.popFront();
3220        return result;
3221    }
3222    else
3223    {
3224        // Special case: okay so parse a Char off a Char[]
3225        Target result = s[0];
3226        s = s[1 .. $];
3227        return result;
3228    }
3229}
3230
3231@safe pure unittest
3232{
3233    foreach (Str; AliasSeq!(string, wstring, dstring))
3234    {
3235        foreach (Char; AliasSeq!(char, wchar, dchar))
3236        {
3237            static if (is(Unqual!Char == dchar) ||
3238                       Char.sizeof == ElementEncodingType!Str.sizeof)
3239            {
3240                Str s = "aaa";
3241                assert(parse!Char(s) == 'a');
3242                assert(s == "aa");
3243            }
3244        }
3245    }
3246}
3247
3248/// ditto
3249Target parse(Target, Source)(ref Source s)
3250if (!isSomeString!Source && isInputRange!Source && isSomeChar!(ElementType!Source) &&
3251    isSomeChar!Target && Target.sizeof >= ElementType!Source.sizeof && !is(Target == enum))
3252{
3253    if (s.empty)
3254        throw convError!(Source, Target)(s);
3255    Target result = s.front;
3256    s.popFront();
3257    return result;
3258}
3259
3260///
3261@safe pure unittest
3262{
3263    auto s = "Hello, World!";
3264    char first = parse!char(s);
3265    assert(first == 'H');
3266    assert(s == "ello, World!");
3267}
3268
3269
3270/*
3271    Tests for to!bool and parse!bool
3272*/
3273@safe pure unittest
3274{
3275    import std.exception;
3276
3277    assert(to!bool("TruE") == true);
3278    assert(to!bool("faLse"d) == false);
3279    assertThrown!ConvException(to!bool("maybe"));
3280
3281    auto t = "TrueType";
3282    assert(parse!bool(t) == true);
3283    assert(t == "Type");
3284
3285    auto f = "False killer whale"d;
3286    assert(parse!bool(f) == false);
3287    assert(f == " killer whale"d);
3288
3289    auto m = "maybe";
3290    assertThrown!ConvException(parse!bool(m));
3291    assert(m == "maybe");  // m shouldn't change on failure
3292
3293    auto s = "true";
3294    auto b = parse!(const(bool))(s);
3295    assert(b == true);
3296}
3297
3298/**
3299Parsing a character range to `typeof(null)` returns `null` if the range
3300spells `"null"`. This function is case insensitive.
3301
3302Params:
3303    Target = the type to convert to
3304    s = the lvalue of an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
3305
3306Returns:
3307    `null`
3308
3309Throws:
3310    A $(LREF ConvException) if the range doesn't represent `null`.
3311 */
3312Target parse(Target, Source)(ref Source s)
3313if (isInputRange!Source &&
3314    isSomeChar!(ElementType!Source) &&
3315    is(Unqual!Target == typeof(null)))
3316{
3317    import std.ascii : toLower;
3318    foreach (c; "null")
3319    {
3320        if (s.empty || toLower(s.front) != c)
3321            throw parseError("null should be case-insensitive 'null'");
3322        s.popFront();
3323    }
3324    return null;
3325}
3326
3327///
3328@safe pure unittest
3329{
3330    import std.exception : assertThrown;
3331
3332    alias NullType = typeof(null);
3333    auto s1 = "null";
3334    assert(parse!NullType(s1) is null);
3335    assert(s1 == "");
3336
3337    auto s2 = "NUll"d;
3338    assert(parse!NullType(s2) is null);
3339    assert(s2 == "");
3340
3341    auto m = "maybe";
3342    assertThrown!ConvException(parse!NullType(m));
3343    assert(m == "maybe");  // m shouldn't change on failure
3344
3345    auto s = "NULL";
3346    assert(parse!(const NullType)(s) is null);
3347}
3348
3349//Used internally by parse Array/AA, to remove ascii whites
3350package void skipWS(R)(ref R r)
3351{
3352    import std.ascii : isWhite;
3353    static if (isSomeString!R)
3354    {
3355        //Implementation inspired from stripLeft.
3356        foreach (i, c; r)
3357        {
3358            if (!isWhite(c))
3359            {
3360                r = r[i .. $];
3361                return;
3362            }
3363        }
3364        r = r[0 .. 0]; //Empty string with correct type.
3365        return;
3366    }
3367    else
3368    {
3369        for (; !r.empty && isWhite(r.front); r.popFront())
3370        {}
3371    }
3372}
3373
3374/**
3375 * Parses an array from a string given the left bracket (default $(D
3376 * '[')), right bracket (default $(D ']')), and element separator (by
3377 * default $(D ',')). A trailing separator is allowed.
3378 *
3379 * Params:
3380 *     s = The string to parse
3381 *     lbracket = the character that starts the array
3382 *     rbracket = the character that ends the array
3383 *     comma = the character that separates the elements of the array
3384 *
3385 * Returns:
3386 *     An array of type `Target`
3387 */
3388Target parse(Target, Source)(ref Source s, dchar lbracket = '[', dchar rbracket = ']', dchar comma = ',')
3389if (isSomeString!Source && !is(Source == enum) &&
3390    isDynamicArray!Target && !is(Target == enum))
3391{
3392    import std.array : appender;
3393
3394    auto result = appender!Target();
3395
3396    parseCheck!s(lbracket);
3397    skipWS(s);
3398    if (s.empty)
3399        throw convError!(Source, Target)(s);
3400    if (s.front == rbracket)
3401    {
3402        s.popFront();
3403        return result.data;
3404    }
3405    for (;; s.popFront(), skipWS(s))
3406    {
3407        if (!s.empty && s.front == rbracket)
3408            break;
3409        result ~= parseElement!(ElementType!Target)(s);
3410        skipWS(s);
3411        if (s.empty)
3412            throw convError!(Source, Target)(s);
3413        if (s.front != comma)
3414            break;
3415    }
3416    parseCheck!s(rbracket);
3417
3418    return result.data;
3419}
3420
3421///
3422@safe pure unittest
3423{
3424    auto s1 = `[['h', 'e', 'l', 'l', 'o'], "world"]`;
3425    auto a1 = parse!(string[])(s1);
3426    assert(a1 == ["hello", "world"]);
3427
3428    auto s2 = `["aaa", "bbb", "ccc"]`;
3429    auto a2 = parse!(string[])(s2);
3430    assert(a2 == ["aaa", "bbb", "ccc"]);
3431}
3432
3433@safe unittest // Bugzilla 9615
3434{
3435    string s0 = "[1,2, ]";
3436    string s1 = "[1,2, \t\v\r\n]";
3437    string s2 = "[1,2]";
3438    assert(s0.parse!(int[]) == [1,2]);
3439    assert(s1.parse!(int[]) == [1,2]);
3440    assert(s2.parse!(int[]) == [1,2]);
3441
3442    string s3 = `["a","b",]`;
3443    string s4 = `["a","b"]`;
3444    assert(s3.parse!(string[]) == ["a","b"]);
3445    assert(s4.parse!(string[]) == ["a","b"]);
3446
3447    import std.exception : assertThrown;
3448    string s5 = "[,]";
3449    string s6 = "[, \t,]";
3450    assertThrown!ConvException(parse!(string[])(s5));
3451    assertThrown!ConvException(parse!(int[])(s6));
3452}
3453
3454@safe unittest
3455{
3456    int[] a = [1, 2, 3, 4, 5];
3457    auto s = to!string(a);
3458    assert(to!(int[])(s) == a);
3459}
3460
3461@safe unittest
3462{
3463    int[][] a = [ [1, 2] , [3], [4, 5] ];
3464    auto s = to!string(a);
3465    assert(to!(int[][])(s) == a);
3466}
3467
3468@safe unittest
3469{
3470    int[][][] ia = [ [[1,2],[3,4],[5]] , [[6],[],[7,8,9]] , [[]] ];
3471
3472    char[] s = to!(char[])(ia);
3473    int[][][] ia2;
3474
3475    ia2 = to!(typeof(ia2))(s);
3476    assert( ia == ia2);
3477}
3478
3479@safe pure unittest
3480{
3481    import std.exception;
3482
3483    //Check proper failure
3484    auto s = "[ 1 , 2 , 3 ]";
3485    foreach (i ; 0 .. s.length-1)
3486    {
3487        auto ss = s[0 .. i];
3488        assertThrown!ConvException(parse!(int[])(ss));
3489    }
3490    int[] arr = parse!(int[])(s);
3491}
3492
3493@safe pure unittest
3494{
3495    //Checks parsing of strings with escaped characters
3496    string s1 = `[
3497        "Contains a\0null!",
3498        "tab\there",
3499        "line\nbreak",
3500        "backslash \\ slash / question \?",
3501        "number \x35 five",
3502        "unicode \u65E5 sun",
3503        "very long \U000065E5 sun"
3504    ]`;
3505
3506    //Note: escaped characters purposefully replaced and isolated to guarantee
3507    //there are no typos in the escape syntax
3508    string[] s2 = [
3509        "Contains a" ~ '\0' ~ "null!",
3510        "tab" ~ '\t' ~ "here",
3511        "line" ~ '\n' ~ "break",
3512        "backslash " ~ '\\' ~ " slash / question ?",
3513        "number 5 five",
3514        "unicode ��� sun",
3515        "very long ��� sun"
3516    ];
3517    assert(s2 == parse!(string[])(s1));
3518    assert(s1.empty);
3519}
3520
3521/// ditto
3522Target parse(Target, Source)(ref Source s, dchar lbracket = '[', dchar rbracket = ']', dchar comma = ',')
3523if (isExactSomeString!Source &&
3524    isStaticArray!Target && !is(Target == enum))
3525{
3526    static if (hasIndirections!Target)
3527        Target result = Target.init[0].init;
3528    else
3529        Target result = void;
3530
3531    parseCheck!s(lbracket);
3532    skipWS(s);
3533    if (s.empty)
3534        throw convError!(Source, Target)(s);
3535    if (s.front == rbracket)
3536    {
3537        static if (result.length != 0)
3538            goto Lmanyerr;
3539        else
3540        {
3541            s.popFront();
3542            return result;
3543        }
3544    }
3545    for (size_t i = 0; ; s.popFront(), skipWS(s))
3546    {
3547        if (i == result.length)
3548            goto Lmanyerr;
3549        result[i++] = parseElement!(ElementType!Target)(s);
3550        skipWS(s);
3551        if (s.empty)
3552            throw convError!(Source, Target)(s);
3553        if (s.front != comma)
3554        {
3555            if (i != result.length)
3556                goto Lfewerr;
3557            break;
3558        }
3559    }
3560    parseCheck!s(rbracket);
3561
3562    return result;
3563
3564Lmanyerr:
3565    throw parseError(text("Too many elements in input, ", result.length, " elements expected."));
3566
3567Lfewerr:
3568    throw parseError(text("Too few elements in input, ", result.length, " elements expected."));
3569}
3570
3571@safe pure unittest
3572{
3573    import std.exception;
3574
3575    auto s1 = "[1,2,3,4]";
3576    auto sa1 = parse!(int[4])(s1);
3577    assert(sa1 == [1,2,3,4]);
3578
3579    auto s2 = "[[1],[2,3],[4]]";
3580    auto sa2 = parse!(int[][3])(s2);
3581    assert(sa2 == [[1],[2,3],[4]]);
3582
3583    auto s3 = "[1,2,3]";
3584    assertThrown!ConvException(parse!(int[4])(s3));
3585
3586    auto s4 = "[1,2,3,4,5]";
3587    assertThrown!ConvException(parse!(int[4])(s4));
3588}
3589
3590/**
3591 * Parses an associative array from a string given the left bracket (default $(D
3592 * '[')), right bracket (default $(D ']')), key-value separator (default $(D
3593 * ':')), and element seprator (by default $(D ',')).
3594 *
3595 * Params:
3596 *     s = the string to parse
3597 *     lbracket = the character that starts the associative array
3598 *     rbracket = the character that ends the associative array
3599 *     keyval = the character that associates the key with the value
3600 *     comma = the character that separates the elements of the associative array
3601 *
3602 * Returns:
3603 *     An associative array of type `Target`
3604 */
3605Target parse(Target, Source)(ref Source s, dchar lbracket = '[',
3606                             dchar rbracket = ']', dchar keyval = ':', dchar comma = ',')
3607if (isSomeString!Source && !is(Source == enum) &&
3608    isAssociativeArray!Target && !is(Target == enum))
3609{
3610    alias KeyType = typeof(Target.init.keys[0]);
3611    alias ValType = typeof(Target.init.values[0]);
3612
3613    Target result;
3614
3615    parseCheck!s(lbracket);
3616    skipWS(s);
3617    if (s.empty)
3618        throw convError!(Source, Target)(s);
3619    if (s.front == rbracket)
3620    {
3621        s.popFront();
3622        return result;
3623    }
3624    for (;; s.popFront(), skipWS(s))
3625    {
3626        auto key = parseElement!KeyType(s);
3627        skipWS(s);
3628        parseCheck!s(keyval);
3629        skipWS(s);
3630        auto val = parseElement!ValType(s);
3631        skipWS(s);
3632        result[key] = val;
3633        if (s.empty)
3634            throw convError!(Source, Target)(s);
3635        if (s.front != comma)
3636            break;
3637    }
3638    parseCheck!s(rbracket);
3639
3640    return result;
3641}
3642
3643///
3644@safe pure unittest
3645{
3646    auto s1 = "[1:10, 2:20, 3:30]";
3647    auto aa1 = parse!(int[int])(s1);
3648    assert(aa1 == [1:10, 2:20, 3:30]);
3649
3650    auto s2 = `["aaa":10, "bbb":20, "ccc":30]`;
3651    auto aa2 = parse!(int[string])(s2);
3652    assert(aa2 == ["aaa":10, "bbb":20, "ccc":30]);
3653
3654    auto s3 = `["aaa":[1], "bbb":[2,3], "ccc":[4,5,6]]`;
3655    auto aa3 = parse!(int[][string])(s3);
3656    assert(aa3 == ["aaa":[1], "bbb":[2,3], "ccc":[4,5,6]]);
3657}
3658
3659@safe pure unittest
3660{
3661    import std.exception;
3662
3663    //Check proper failure
3664    auto s = "[1:10, 2:20, 3:30]";
3665    foreach (i ; 0 .. s.length-1)
3666    {
3667        auto ss = s[0 .. i];
3668        assertThrown!ConvException(parse!(int[int])(ss));
3669    }
3670    int[int] aa = parse!(int[int])(s);
3671}
3672
3673private dchar parseEscape(Source)(ref Source s)
3674if (isInputRange!Source && isSomeChar!(ElementType!Source))
3675{
3676    parseCheck!s('\\');
3677    if (s.empty)
3678        throw parseError("Unterminated escape sequence");
3679
3680    dchar getHexDigit()(ref Source s_ = s)  // workaround
3681    {
3682        import std.ascii : isAlpha, isHexDigit;
3683        if (s_.empty)
3684            throw parseError("Unterminated escape sequence");
3685        s_.popFront();
3686        if (s_.empty)
3687            throw parseError("Unterminated escape sequence");
3688        dchar c = s_.front;
3689        if (!isHexDigit(c))
3690            throw parseError("Hex digit is missing");
3691        return isAlpha(c) ? ((c & ~0x20) - ('A' - 10)) : c - '0';
3692    }
3693
3694    dchar result;
3695
3696    switch (s.front)
3697    {
3698        case '"':   result = '\"';  break;
3699        case '\'':  result = '\'';  break;
3700        case '0':   result = '\0';  break;
3701        case '?':   result = '\?';  break;
3702        case '\\':  result = '\\';  break;
3703        case 'a':   result = '\a';  break;
3704        case 'b':   result = '\b';  break;
3705        case 'f':   result = '\f';  break;
3706        case 'n':   result = '\n';  break;
3707        case 'r':   result = '\r';  break;
3708        case 't':   result = '\t';  break;
3709        case 'v':   result = '\v';  break;
3710        case 'x':
3711            result  = getHexDigit() << 4;
3712            result |= getHexDigit();
3713            break;
3714        case 'u':
3715            result  = getHexDigit() << 12;
3716            result |= getHexDigit() << 8;
3717            result |= getHexDigit() << 4;
3718            result |= getHexDigit();
3719            break;
3720        case 'U':
3721            result  = getHexDigit() << 28;
3722            result |= getHexDigit() << 24;
3723            result |= getHexDigit() << 20;
3724            result |= getHexDigit() << 16;
3725            result |= getHexDigit() << 12;
3726            result |= getHexDigit() << 8;
3727            result |= getHexDigit() << 4;
3728            result |= getHexDigit();
3729            break;
3730        default:
3731            throw parseError("Unknown escape character " ~ to!string(s.front));
3732    }
3733    if (s.empty)
3734        throw parseError("Unterminated escape sequence");
3735
3736    s.popFront();
3737
3738    return result;
3739}
3740
3741@safe pure unittest
3742{
3743    string[] s1 = [
3744        `\"`, `\'`, `\?`, `\\`, `\a`, `\b`, `\f`, `\n`, `\r`, `\t`, `\v`, //Normal escapes
3745        //`\141`, //@@@9621@@@ Octal escapes.
3746        `\x61`,
3747        `\u65E5`, `\U00012456`
3748        //`\&amp;`, `\&quot;`, //@@@9621@@@ Named Character Entities.
3749    ];
3750
3751    const(dchar)[] s2 = [
3752        '\"', '\'', '\?', '\\', '\a', '\b', '\f', '\n', '\r', '\t', '\v', //Normal escapes
3753        //'\141', //@@@9621@@@ Octal escapes.
3754        '\x61',
3755        '\u65E5', '\U00012456'
3756        //'\&amp;', '\&quot;', //@@@9621@@@ Named Character Entities.
3757    ];
3758
3759    foreach (i ; 0 .. s1.length)
3760    {
3761        assert(s2[i] == parseEscape(s1[i]));
3762        assert(s1[i].empty);
3763    }
3764}
3765
3766@safe pure unittest
3767{
3768    import std.exception;
3769
3770    string[] ss = [
3771        `hello!`,  //Not an escape
3772        `\`,       //Premature termination
3773        `\/`,      //Not an escape
3774        `\gggg`,   //Not an escape
3775        `\xzz`,    //Not an hex
3776        `\x0`,     //Premature hex end
3777        `\XB9`,    //Not legal hex syntax
3778        `\u!!`,    //Not a unicode hex
3779        `\777`,    //Octal is larger than a byte //Note: Throws, but simply because octals are unsupported
3780        `\u123`,   //Premature hex end
3781        `\U123123` //Premature hex end
3782    ];
3783    foreach (s ; ss)
3784        assertThrown!ConvException(parseEscape(s));
3785}
3786
3787// Undocumented
3788Target parseElement(Target, Source)(ref Source s)
3789if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum) &&
3790    isExactSomeString!Target)
3791{
3792    import std.array : appender;
3793    auto result = appender!Target();
3794
3795    // parse array of chars
3796    if (s.empty)
3797        throw convError!(Source, Target)(s);
3798    if (s.front == '[')
3799        return parse!Target(s);
3800
3801    parseCheck!s('\"');
3802    if (s.empty)
3803        throw convError!(Source, Target)(s);
3804    if (s.front == '\"')
3805    {
3806        s.popFront();
3807        return result.data;
3808    }
3809    while (true)
3810    {
3811        if (s.empty)
3812            throw parseError("Unterminated quoted string");
3813        switch (s.front)
3814        {
3815            case '\"':
3816                s.popFront();
3817                return result.data;
3818            case '\\':
3819                result.put(parseEscape(s));
3820                break;
3821            default:
3822                result.put(s.front);
3823                s.popFront();
3824                break;
3825        }
3826    }
3827    assert(0);
3828}
3829
3830// ditto
3831Target parseElement(Target, Source)(ref Source s)
3832if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum) &&
3833    isSomeChar!Target && !is(Target == enum))
3834{
3835    Target c;
3836
3837    parseCheck!s('\'');
3838    if (s.empty)
3839        throw convError!(Source, Target)(s);
3840    if (s.front != '\\')
3841    {
3842        c = s.front;
3843        s.popFront();
3844    }
3845    else
3846        c = parseEscape(s);
3847    parseCheck!s('\'');
3848
3849    return c;
3850}
3851
3852// ditto
3853Target parseElement(Target, Source)(ref Source s)
3854if (isInputRange!Source && isSomeChar!(ElementType!Source) &&
3855    !isSomeString!Target && !isSomeChar!Target)
3856{
3857    return parse!Target(s);
3858}
3859
3860
3861/***************************************************************
3862 * Convenience functions for converting one or more arguments
3863 * of any type into _text (the three character widths).
3864 */
3865string text(T...)(T args)
3866if (T.length > 0) { return textImpl!string(args); }
3867
3868///ditto
3869wstring wtext(T...)(T args)
3870if (T.length > 0) { return textImpl!wstring(args); }
3871
3872///ditto
3873dstring dtext(T...)(T args)
3874if (T.length > 0) { return textImpl!dstring(args); }
3875
3876///
3877@safe unittest
3878{
3879    assert( text(42, ' ', 1.5, ": xyz") == "42 1.5: xyz"c);
3880    assert(wtext(42, ' ', 1.5, ": xyz") == "42 1.5: xyz"w);
3881    assert(dtext(42, ' ', 1.5, ": xyz") == "42 1.5: xyz"d);
3882}
3883
3884@safe unittest
3885{
3886    char  c = 'h';
3887    wchar w = '���';
3888    dchar d = '���';
3889
3890    assert( text(c, "ello", ' ', w, "��� ", d, "��� ��������� ������") == "hello ������ ������ ��������� ������"c);
3891    assert(wtext(c, "ello", ' ', w, "��� ", d, "��� ��������� ������") == "hello ������ ������ ��������� ������"w);
3892    assert(dtext(c, "ello", ' ', w, "��� ", d, "��� ��������� ������") == "hello ������ ������ ��������� ������"d);
3893
3894    string  cs = "���������";
3895    wstring ws = "������������";
3896    dstring ds = "������������������������";
3897
3898    assert( text(cs, ' ', ws, " ", ds) == "��������� ������������ ������������������������"c);
3899    assert(wtext(cs, ' ', ws, " ", ds) == "��������� ������������ ������������������������"w);
3900    assert(dtext(cs, ' ', ws, " ", ds) == "��������� ������������ ������������������������"d);
3901}
3902
3903private S textImpl(S, U...)(U args)
3904{
3905    static if (U.length == 0)
3906    {
3907        return null;
3908    }
3909    else static if (U.length == 1)
3910    {
3911        return to!S(args[0]);
3912    }
3913    else
3914    {
3915        import std.array : appender;
3916
3917        auto app = appender!S();
3918
3919        foreach (arg; args)
3920            app.put(to!S(arg));
3921        return app.data;
3922    }
3923}
3924
3925
3926/***************************************************************
3927The $(D octal) facility provides a means to declare a number in base 8.
3928Using $(D octal!177) or $(D octal!"177") for 127 represented in octal
3929(same as 0177 in C).
3930
3931The rules for strings are the usual for literals: If it can fit in an
3932$(D int), it is an $(D int). Otherwise, it is a $(D long). But, if the
3933user specifically asks for a $(D long) with the $(D L) suffix, always
3934give the $(D long). Give an unsigned iff it is asked for with the $(D
3935U) or $(D u) suffix. _Octals created from integers preserve the type
3936of the passed-in integral.
3937
3938See_Also:
3939    $(LREF parse) for parsing octal strings at runtime.
3940 */
3941template octal(string num)
3942if (isOctalLiteral(num))
3943{
3944    static if ((octalFitsInInt!num && !literalIsLong!num) && !literalIsUnsigned!num)
3945        enum octal = octal!int(num);
3946    else static if ((!octalFitsInInt!num || literalIsLong!num) && !literalIsUnsigned!num)
3947        enum octal = octal!long(num);
3948    else static if ((octalFitsInInt!num && !literalIsLong!num) && literalIsUnsigned!num)
3949        enum octal = octal!uint(num);
3950    else static if ((!octalFitsInInt!(num) || literalIsLong!(num)) && literalIsUnsigned!(num))
3951        enum octal = octal!ulong(num);
3952    else
3953        static assert(false);
3954}
3955
3956/// Ditto
3957template octal(alias decimalInteger)
3958if (isIntegral!(typeof(decimalInteger)))
3959{
3960    enum octal = octal!(typeof(decimalInteger))(to!string(decimalInteger));
3961}
3962
3963///
3964@safe unittest
3965{
3966    // same as 0177
3967    auto x = octal!177;
3968    // octal is a compile-time device
3969    enum y = octal!160;
3970    // Create an unsigned octal
3971    auto z = octal!"1_000_000u";
3972}
3973
3974/*
3975    Takes a string, num, which is an octal literal, and returns its
3976    value, in the type T specified.
3977*/
3978private T octal(T)(const string num)
3979{
3980    assert(isOctalLiteral(num));
3981
3982    T value = 0;
3983
3984    foreach (const char s; num)
3985    {
3986        if (s < '0' || s > '7') // we only care about digits; skip the rest
3987        // safe to skip - this is checked out in the assert so these
3988        // are just suffixes
3989            continue;
3990
3991        value *= 8;
3992        value += s - '0';
3993    }
3994
3995    return value;
3996}
3997
3998@safe unittest
3999{
4000    int a = octal!int("10");
4001    assert(a == 8);
4002}
4003
4004/*
4005Take a look at int.max and int.max+1 in octal and the logic for this
4006function follows directly.
4007 */
4008private template octalFitsInInt(string octalNum)
4009{
4010    // note it is important to strip the literal of all
4011    // non-numbers. kill the suffix and underscores lest they mess up
4012    // the number of digits here that we depend on.
4013    enum bool octalFitsInInt = strippedOctalLiteral(octalNum).length < 11 ||
4014        strippedOctalLiteral(octalNum).length == 11 &&
4015        strippedOctalLiteral(octalNum)[0] == '1';
4016}
4017
4018private string strippedOctalLiteral(string original)
4019{
4020    string stripped = "";
4021    foreach (c; original)
4022        if (c >= '0' && c <= '7')
4023            stripped ~= c;
4024    return stripped;
4025}
4026
4027private template literalIsLong(string num)
4028{
4029    static if (num.length > 1)
4030    // can be xxL or xxLu according to spec
4031        enum literalIsLong = (num[$-1] == 'L' || num[$-2] == 'L');
4032    else
4033        enum literalIsLong = false;
4034}
4035
4036private template literalIsUnsigned(string num)
4037{
4038    static if (num.length > 1)
4039    // can be xxU or xxUL according to spec
4040        enum literalIsUnsigned = (num[$-1] == 'u' || num[$-2] == 'u')
4041            // both cases are allowed too
4042            || (num[$-1] == 'U' || num[$-2] == 'U');
4043    else
4044        enum literalIsUnsigned = false;
4045}
4046
4047/*
4048Returns if the given string is a correctly formatted octal literal.
4049
4050The format is specified in spec/lex.html. The leading zero is allowed, but
4051not required.
4052 */
4053@safe pure nothrow @nogc
4054private bool isOctalLiteral(const string num)
4055{
4056    if (num.length == 0)
4057        return false;
4058
4059    // Must start with a number. To avoid confusion, literals that
4060    // start with a '0' are not allowed
4061    if (num[0] == '0' && num.length > 1)
4062        return false;
4063    if (num[0] < '0' || num[0] > '7')
4064        return false;
4065
4066    foreach (i, c; num)
4067    {
4068        if ((c < '0' || c > '7') && c != '_') // not a legal character
4069        {
4070            if (i < num.length - 2)
4071                    return false;
4072            else   // gotta check for those suffixes
4073            {
4074                if (c != 'U' && c != 'u' && c != 'L')
4075                        return false;
4076                if (i != num.length - 1)
4077                {
4078                    // if we're not the last one, the next one must
4079                    // also be a suffix to be valid
4080                    char c2 = num[$-1];
4081                    if (c2 != 'U' && c2 != 'u' && c2 != 'L')
4082                        return false; // spam at the end of the string
4083                    if (c2 == c)
4084                        return false; // repeats are disallowed
4085                }
4086            }
4087        }
4088    }
4089
4090    return true;
4091}
4092
4093@safe unittest
4094{
4095    // ensure that you get the right types, even with embedded underscores
4096    auto w = octal!"100_000_000_000";
4097    static assert(!is(typeof(w) == int));
4098    auto w2 = octal!"1_000_000_000";
4099    static assert(is(typeof(w2) == int));
4100
4101    static assert(octal!"45" == 37);
4102    static assert(octal!"0" == 0);
4103    static assert(octal!"7" == 7);
4104    static assert(octal!"10" == 8);
4105    static assert(octal!"666" == 438);
4106
4107    static assert(octal!45 == 37);
4108    static assert(octal!0 == 0);
4109    static assert(octal!7 == 7);
4110    static assert(octal!10 == 8);
4111    static assert(octal!666 == 438);
4112
4113    static assert(octal!"66_6" == 438);
4114
4115    static assert(octal!2520046213 == 356535435);
4116    static assert(octal!"2520046213" == 356535435);
4117
4118    static assert(octal!17777777777 == int.max);
4119
4120    static assert(!__traits(compiles, octal!823));
4121
4122    static assert(!__traits(compiles, octal!"823"));
4123
4124    static assert(!__traits(compiles, octal!"_823"));
4125    static assert(!__traits(compiles, octal!"spam"));
4126    static assert(!__traits(compiles, octal!"77%"));
4127
4128    static assert(is(typeof(octal!"17777777777") == int));
4129    static assert(octal!"17777777777" == int.max);
4130
4131    static assert(is(typeof(octal!"20000000000U") == ulong)); // Shouldn't this be uint?
4132    static assert(octal!"20000000000" == uint(int.max) + 1);
4133
4134    static assert(is(typeof(octal!"777777777777777777777") == long));
4135    static assert(octal!"777777777777777777777" == long.max);
4136
4137    static assert(is(typeof(octal!"1000000000000000000000U") == ulong));
4138    static assert(octal!"1000000000000000000000" == ulong(long.max) + 1);
4139
4140    int a;
4141    long b;
4142
4143    // biggest value that should fit in an it
4144    a = octal!"17777777777";
4145    assert(a == int.max);
4146    // should not fit in the int
4147    static assert(!__traits(compiles, a = octal!"20000000000"));
4148    // ... but should fit in a long
4149    b = octal!"20000000000";
4150    assert(b == 1L + int.max);
4151
4152    b = octal!"1L";
4153    assert(b == 1);
4154    b = octal!1L;
4155    assert(b == 1);
4156}
4157
4158/+
4159emplaceRef is a package function for phobos internal use. It works like
4160emplace, but takes its argument by ref (as opposed to "by pointer").
4161
4162This makes it easier to use, easier to be safe, and faster in a non-inline
4163build.
4164
4165Furthermore, emplaceRef optionally takes a type paremeter, which specifies
4166the type we want to build. This helps to build qualified objects on mutable
4167buffer, without breaking the type system with unsafe casts.
4168+/
4169package void emplaceRef(T, UT, Args...)(ref UT chunk, auto ref Args args)
4170{
4171    static if (args.length == 0)
4172    {
4173        static assert(is(typeof({static T i;})),
4174            convFormat("Cannot emplace a %1$s because %1$s.this() is annotated with @disable.", T.stringof));
4175        static if (is(T == class)) static assert(!isAbstractClass!T,
4176            T.stringof ~ " is abstract and it can't be emplaced");
4177        emplaceInitializer(chunk);
4178    }
4179    else static if (
4180        !is(T == struct) && Args.length == 1 /* primitives, enums, arrays */
4181        ||
4182        Args.length == 1 && is(typeof({T t = args[0];})) /* conversions */
4183        ||
4184        is(typeof(T(args))) /* general constructors */)
4185    {
4186        static struct S
4187        {
4188            T payload;
4189            this(ref Args x)
4190            {
4191                static if (Args.length == 1)
4192                    static if (is(typeof(payload = x[0])))
4193                        payload = x[0];
4194                    else
4195                        payload = T(x[0]);
4196                else
4197                    payload = T(x);
4198            }
4199        }
4200        if (__ctfe)
4201        {
4202            static if (is(typeof(chunk = T(args))))
4203                chunk = T(args);
4204            else static if (args.length == 1 && is(typeof(chunk = args[0])))
4205                chunk = args[0];
4206            else assert(0, "CTFE emplace doesn't support "
4207                ~ T.stringof ~ " from " ~ Args.stringof);
4208        }
4209        else
4210        {
4211            S* p = () @trusted { return cast(S*) &chunk; }();
4212            emplaceInitializer(*p);
4213            p.__ctor(args);
4214        }
4215    }
4216    else static if (is(typeof(chunk.__ctor(args))))
4217    {
4218        // This catches the rare case of local types that keep a frame pointer
4219        emplaceInitializer(chunk);
4220        chunk.__ctor(args);
4221    }
4222    else
4223    {
4224        //We can't emplace. Try to diagnose a disabled postblit.
4225        static assert(!(Args.length == 1 && is(Args[0] : T)),
4226            convFormat("Cannot emplace a %1$s because %1$s.this(this) is annotated with @disable.", T.stringof));
4227
4228        //We can't emplace.
4229        static assert(false,
4230            convFormat("%s cannot be emplaced from %s.", T.stringof, Args[].stringof));
4231    }
4232}
4233// ditto
4234package void emplaceRef(UT, Args...)(ref UT chunk, auto ref Args args)
4235if (is(UT == Unqual!UT))
4236{
4237    emplaceRef!(UT, UT)(chunk, args);
4238}
4239
4240//emplace helper functions
4241private void emplaceInitializer(T)(ref T chunk) @trusted pure nothrow
4242{
4243    static if (!hasElaborateAssign!T && isAssignable!T)
4244        chunk = T.init;
4245    else
4246    {
4247        import core.stdc.string : memcpy;
4248        static immutable T init = T.init;
4249        memcpy(&chunk, &init, T.sizeof);
4250    }
4251}
4252
4253// emplace
4254/**
4255Given a pointer $(D chunk) to uninitialized memory (but already typed
4256as $(D T)), constructs an object of non-$(D class) type $(D T) at that
4257address. If `T` is a class, initializes the class reference to null.
4258
4259Returns: A pointer to the newly constructed object (which is the same
4260as $(D chunk)).
4261 */
4262T* emplace(T)(T* chunk) @safe pure nothrow
4263{
4264    emplaceRef!T(*chunk);
4265    return chunk;
4266}
4267
4268///
4269@system unittest
4270{
4271    static struct S
4272    {
4273        int i = 42;
4274    }
4275    S[2] s2 = void;
4276    emplace(&s2);
4277    assert(s2[0].i == 42 && s2[1].i == 42);
4278}
4279
4280///
4281@system unittest
4282{
4283    interface I {}
4284    class K : I {}
4285
4286    K k = void;
4287    emplace(&k);
4288    assert(k is null);
4289
4290    I i = void;
4291    emplace(&i);
4292    assert(i is null);
4293}
4294
4295/**
4296Given a pointer $(D chunk) to uninitialized memory (but already typed
4297as a non-class type $(D T)), constructs an object of type $(D T) at
4298that address from arguments $(D args). If `T` is a class, initializes
4299the class reference to `args[0]`.
4300
4301This function can be $(D @trusted) if the corresponding constructor of
4302$(D T) is $(D @safe).
4303
4304Returns: A pointer to the newly constructed object (which is the same
4305as $(D chunk)).
4306 */
4307T* emplace(T, Args...)(T* chunk, auto ref Args args)
4308if (is(T == struct) || Args.length == 1)
4309{
4310    emplaceRef!T(*chunk, args);
4311    return chunk;
4312}
4313
4314///
4315@system unittest
4316{
4317    int a;
4318    int b = 42;
4319    assert(*emplace!int(&a, b) == 42);
4320}
4321
4322@system unittest
4323{
4324    shared int i;
4325    emplace(&i, 42);
4326    assert(i == 42);
4327}
4328
4329private void testEmplaceChunk(void[] chunk, size_t typeSize, size_t typeAlignment, string typeName) @nogc pure nothrow
4330{
4331    assert(chunk.length >= typeSize, "emplace: Chunk size too small.");
4332    assert((cast(size_t) chunk.ptr) % typeAlignment == 0, "emplace: Chunk is not aligned.");
4333}
4334
4335/**
4336Given a raw memory area $(D chunk), constructs an object of $(D class)
4337type $(D T) at that address. The constructor is passed the arguments
4338$(D Args).
4339
4340If `T` is an inner class whose `outer` field can be used to access an instance
4341of the enclosing class, then `Args` must not be empty, and the first member of it
4342must be a valid initializer for that `outer` field. Correct initialization of
4343this field is essential to access members of the outer class inside `T` methods.
4344
4345Preconditions:
4346$(D chunk) must be at least as large as $(D T) needs
4347and should have an alignment multiple of $(D T)'s alignment. (The size
4348of a $(D class) instance is obtained by using $(D
4349__traits(classInstanceSize, T))).
4350
4351Note:
4352This function can be $(D @trusted) if the corresponding constructor of
4353$(D T) is $(D @safe).
4354
4355Returns: The newly constructed object.
4356 */
4357T emplace(T, Args...)(void[] chunk, auto ref Args args)
4358if (is(T == class))
4359{
4360    static assert(!isAbstractClass!T, T.stringof ~
4361        " is abstract and it can't be emplaced");
4362
4363    enum classSize = __traits(classInstanceSize, T);
4364    testEmplaceChunk(chunk, classSize, classInstanceAlignment!T, T.stringof);
4365    auto result = cast(T) chunk.ptr;
4366
4367    // Initialize the object in its pre-ctor state
4368    chunk[0 .. classSize] = typeid(T).initializer[];
4369
4370    static if (isInnerClass!T)
4371    {
4372        static assert(Args.length > 0,
4373            "Initializing an inner class requires a pointer to the outer class");
4374        static assert(is(Args[0] : typeof(T.outer)),
4375            "The first argument must be a pointer to the outer class");
4376
4377        result.outer = args[0];
4378        alias args1 = args[1..$];
4379    }
4380    else alias args1 = args;
4381
4382    // Call the ctor if any
4383    static if (is(typeof(result.__ctor(args1))))
4384    {
4385        // T defines a genuine constructor accepting args
4386        // Go the classic route: write .init first, then call ctor
4387        result.__ctor(args1);
4388    }
4389    else
4390    {
4391        static assert(args1.length == 0 && !is(typeof(&T.__ctor)),
4392            "Don't know how to initialize an object of type "
4393            ~ T.stringof ~ " with arguments " ~ typeof(args1).stringof);
4394    }
4395    return result;
4396}
4397
4398///
4399@system unittest
4400{
4401    static class C
4402    {
4403        int i;
4404        this(int i){this.i = i;}
4405    }
4406    auto buf = new void[__traits(classInstanceSize, C)];
4407    auto c = emplace!C(buf, 5);
4408    assert(c.i == 5);
4409}
4410
4411@system unittest
4412{
4413    class Outer
4414    {
4415        int i = 3;
4416        class Inner
4417        {
4418            auto getI() { return i; }
4419        }
4420    }
4421    auto outerBuf = new void[__traits(classInstanceSize, Outer)];
4422    auto innerBuf = new void[__traits(classInstanceSize, Outer.Inner)];
4423    auto inner = innerBuf.emplace!(Outer.Inner)(outerBuf.emplace!Outer);
4424    assert(inner.getI == 3);
4425}
4426
4427@nogc pure nothrow @system unittest
4428{
4429    int var = 6;
4430    align(__conv_EmplaceTestClass.alignof) ubyte[__traits(classInstanceSize, __conv_EmplaceTestClass)] buf;
4431    auto k = emplace!__conv_EmplaceTestClass(buf, 5, var);
4432    assert(k.i == 5);
4433    assert(var == 7);
4434}
4435
4436/**
4437Given a raw memory area $(D chunk), constructs an object of non-$(D
4438class) type $(D T) at that address. The constructor is passed the
4439arguments $(D args), if any.
4440
4441Preconditions:
4442$(D chunk) must be at least as large
4443as $(D T) needs and should have an alignment multiple of $(D T)'s
4444alignment.
4445
4446Note:
4447This function can be $(D @trusted) if the corresponding constructor of
4448$(D T) is $(D @safe).
4449
4450Returns: A pointer to the newly constructed object.
4451 */
4452T* emplace(T, Args...)(void[] chunk, auto ref Args args)
4453if (!is(T == class))
4454{
4455    testEmplaceChunk(chunk, T.sizeof, T.alignof, T.stringof);
4456    emplaceRef!(T, Unqual!T)(*cast(Unqual!T*) chunk.ptr, args);
4457    return cast(T*) chunk.ptr;
4458}
4459
4460///
4461@system unittest
4462{
4463    struct S
4464    {
4465        int a, b;
4466    }
4467    auto buf = new void[S.sizeof];
4468    S s;
4469    s.a = 42;
4470    s.b = 43;
4471    auto s1 = emplace!S(buf, s);
4472    assert(s1.a == 42 && s1.b == 43);
4473}
4474
4475// Bulk of emplace unittests starts here
4476
4477@system unittest /* unions */
4478{
4479    static union U
4480    {
4481        string a;
4482        int b;
4483        struct
4484        {
4485            long c;
4486            int[] d;
4487        }
4488    }
4489    U u1 = void;
4490    U u2 = { "hello" };
4491    emplace(&u1, u2);
4492    assert(u1.a == "hello");
4493}
4494
4495version (unittest) private struct __conv_EmplaceTest
4496{
4497    int i = 3;
4498    this(int i)
4499    {
4500        assert(this.i == 3 && i == 5);
4501        this.i = i;
4502    }
4503    this(int i, ref int j)
4504    {
4505        assert(i == 5 && j == 6);
4506        this.i = i;
4507        ++j;
4508    }
4509
4510@disable:
4511    this();
4512    this(this);
4513    void opAssign();
4514}
4515
4516version (unittest) private class __conv_EmplaceTestClass
4517{
4518    int i = 3;
4519    this(int i) @nogc @safe pure nothrow
4520    {
4521        assert(this.i == 3 && i == 5);
4522        this.i = i;
4523    }
4524    this(int i, ref int j) @nogc @safe pure nothrow
4525    {
4526        assert(i == 5 && j == 6);
4527        this.i = i;
4528        ++j;
4529    }
4530}
4531
4532@system unittest // bugzilla 15772
4533{
4534    abstract class Foo {}
4535    class Bar: Foo {}
4536    void[] memory;
4537    // test in emplaceInitializer
4538    static assert(!is(typeof(emplace!Foo(cast(Foo*) memory.ptr))));
4539    static assert( is(typeof(emplace!Bar(cast(Bar*) memory.ptr))));
4540    // test in the emplace overload that takes void[]
4541    static assert(!is(typeof(emplace!Foo(memory))));
4542    static assert( is(typeof(emplace!Bar(memory))));
4543}
4544
4545@system unittest
4546{
4547    struct S { @disable this(); }
4548    S s = void;
4549    static assert(!__traits(compiles, emplace(&s)));
4550    emplace(&s, S.init);
4551}
4552
4553@system unittest
4554{
4555    struct S1
4556    {}
4557
4558    struct S2
4559    {
4560        void opAssign(S2);
4561    }
4562
4563    S1 s1 = void;
4564    S2 s2 = void;
4565    S1[2] as1 = void;
4566    S2[2] as2 = void;
4567    emplace(&s1);
4568    emplace(&s2);
4569    emplace(&as1);
4570    emplace(&as2);
4571}
4572
4573@system unittest
4574{
4575    static struct S1
4576    {
4577        this(this) @disable;
4578    }
4579    static struct S2
4580    {
4581        this() @disable;
4582    }
4583    S1[2] ss1 = void;
4584    S2[2] ss2 = void;
4585    emplace(&ss1);
4586    static assert(!__traits(compiles, emplace(&ss2)));
4587    S1 s1 = S1.init;
4588    S2 s2 = S2.init;
4589    static assert(!__traits(compiles, emplace(&ss1, s1)));
4590    emplace(&ss2, s2);
4591}
4592
4593@system unittest
4594{
4595    struct S
4596    {
4597        immutable int i;
4598    }
4599    S s = void;
4600    S[2] ss1 = void;
4601    S[2] ss2 = void;
4602    emplace(&s, 5);
4603    assert(s.i == 5);
4604    emplace(&ss1, s);
4605    assert(ss1[0].i == 5 && ss1[1].i == 5);
4606    emplace(&ss2, ss1);
4607    assert(ss2 == ss1);
4608}
4609
4610//Start testing emplace-args here
4611
4612@system unittest
4613{
4614    interface I {}
4615    class K : I {}
4616
4617    K k = null, k2 = new K;
4618    assert(k !is k2);
4619    emplace!K(&k, k2);
4620    assert(k is k2);
4621
4622    I i = null;
4623    assert(i !is k);
4624    emplace!I(&i, k);
4625    assert(i is k);
4626}
4627
4628@system unittest
4629{
4630    static struct S
4631    {
4632        int i = 5;
4633        void opAssign(S){assert(0);}
4634    }
4635    S[2] sa = void;
4636    S[2] sb;
4637    emplace(&sa, sb);
4638    assert(sa[0].i == 5 && sa[1].i == 5);
4639}
4640
4641//Start testing emplace-struct here
4642
4643// Test constructor branch
4644@system unittest
4645{
4646    struct S
4647    {
4648        double x = 5, y = 6;
4649        this(int a, int b)
4650        {
4651            assert(x == 5 && y == 6);
4652            x = a;
4653            y = b;
4654        }
4655    }
4656
4657    auto s1 = new void[S.sizeof];
4658    auto s2 = S(42, 43);
4659    assert(*emplace!S(cast(S*) s1.ptr, s2) == s2);
4660    assert(*emplace!S(cast(S*) s1, 44, 45) == S(44, 45));
4661}
4662
4663@system unittest
4664{
4665    __conv_EmplaceTest k = void;
4666    emplace(&k, 5);
4667    assert(k.i == 5);
4668}
4669
4670@system unittest
4671{
4672    int var = 6;
4673    __conv_EmplaceTest k = void;
4674    emplace(&k, 5, var);
4675    assert(k.i == 5);
4676    assert(var == 7);
4677}
4678
4679// Test matching fields branch
4680@system unittest
4681{
4682    struct S { uint n; }
4683    S s;
4684    emplace!S(&s, 2U);
4685    assert(s.n == 2);
4686}
4687
4688@safe unittest
4689{
4690    struct S { int a, b; this(int){} }
4691    S s;
4692    static assert(!__traits(compiles, emplace!S(&s, 2, 3)));
4693}
4694
4695@system unittest
4696{
4697    struct S { int a, b = 7; }
4698    S s1 = void, s2 = void;
4699
4700    emplace!S(&s1, 2);
4701    assert(s1.a == 2 && s1.b == 7);
4702
4703    emplace!S(&s2, 2, 3);
4704    assert(s2.a == 2 && s2.b == 3);
4705}
4706
4707//opAssign
4708@system unittest
4709{
4710    static struct S
4711    {
4712        int i = 5;
4713        void opAssign(int){assert(0);}
4714        void opAssign(S){assert(0);}
4715    }
4716    S sa1 = void;
4717    S sa2 = void;
4718    S sb1 = S(1);
4719    emplace(&sa1, sb1);
4720    emplace(&sa2, 2);
4721    assert(sa1.i == 1);
4722    assert(sa2.i == 2);
4723}
4724
4725//postblit precedence
4726@system unittest
4727{
4728    //Works, but breaks in "-w -O" because of @@@9332@@@.
4729    //Uncomment test when 9332 is fixed.
4730    static struct S
4731    {
4732        int i;
4733
4734        this(S other){assert(false);}
4735        this(int i){this.i = i;}
4736        this(this){}
4737    }
4738    S a = void;
4739    assert(is(typeof({S b = a;})));    //Postblit
4740    assert(is(typeof({S b = S(a);}))); //Constructor
4741    auto b = S(5);
4742    emplace(&a, b);
4743    assert(a.i == 5);
4744
4745    static struct S2
4746    {
4747        int* p;
4748        this(const S2){}
4749    }
4750    static assert(!is(immutable S2 : S2));
4751    S2 s2 = void;
4752    immutable is2 = (immutable S2).init;
4753    emplace(&s2, is2);
4754}
4755
4756//nested structs and postblit
4757@system unittest
4758{
4759    static struct S
4760    {
4761        int* p;
4762        this(int i){p = [i].ptr;}
4763        this(this)
4764        {
4765            if (p)
4766                p = [*p].ptr;
4767        }
4768    }
4769    static struct SS
4770    {
4771        S s;
4772        void opAssign(const SS)
4773        {
4774            assert(0);
4775        }
4776    }
4777    SS ssa = void;
4778    SS ssb = SS(S(5));
4779    emplace(&ssa, ssb);
4780    assert(*ssa.s.p == 5);
4781    assert(ssa.s.p != ssb.s.p);
4782}
4783
4784//disabled postblit
4785@system unittest
4786{
4787    static struct S1
4788    {
4789        int i;
4790        @disable this(this);
4791    }
4792    S1 s1 = void;
4793    emplace(&s1, 1);
4794    assert(s1.i == 1);
4795    static assert(!__traits(compiles, emplace(&s1, S1.init)));
4796
4797    static struct S2
4798    {
4799        int i;
4800        @disable this(this);
4801        this(ref S2){}
4802    }
4803    S2 s2 = void;
4804    static assert(!__traits(compiles, emplace(&s2, 1)));
4805    emplace(&s2, S2.init);
4806
4807    static struct SS1
4808    {
4809        S1 s;
4810    }
4811    SS1 ss1 = void;
4812    emplace(&ss1);
4813    static assert(!__traits(compiles, emplace(&ss1, SS1.init)));
4814
4815    static struct SS2
4816    {
4817        S2 s;
4818    }
4819    SS2 ss2 = void;
4820    emplace(&ss2);
4821    static assert(!__traits(compiles, emplace(&ss2, SS2.init)));
4822
4823
4824    // SS1 sss1 = s1;      //This doesn't compile
4825    // SS1 sss1 = SS1(s1); //This doesn't compile
4826    // So emplace shouldn't compile either
4827    static assert(!__traits(compiles, emplace(&sss1, s1)));
4828    static assert(!__traits(compiles, emplace(&sss2, s2)));
4829}
4830
4831//Imutability
4832@system unittest
4833{
4834    //Castable immutability
4835    {
4836        static struct S1
4837        {
4838            int i;
4839        }
4840        static assert(is( immutable(S1) : S1));
4841        S1 sa = void;
4842        auto sb = immutable(S1)(5);
4843        emplace(&sa, sb);
4844        assert(sa.i == 5);
4845    }
4846    //Un-castable immutability
4847    {
4848        static struct S2
4849        {
4850            int* p;
4851        }
4852        static assert(!is(immutable(S2) : S2));
4853        S2 sa = void;
4854        auto sb = immutable(S2)(null);
4855        assert(!__traits(compiles, emplace(&sa, sb)));
4856    }
4857}
4858
4859@system unittest
4860{
4861    static struct S
4862    {
4863        immutable int i;
4864        immutable(int)* j;
4865    }
4866    S s = void;
4867    emplace(&s, 1, null);
4868    emplace(&s, 2, &s.i);
4869    assert(s is S(2, &s.i));
4870}
4871
4872//Context pointer
4873@system unittest
4874{
4875    int i = 0;
4876    {
4877        struct S1
4878        {
4879            void foo(){++i;}
4880        }
4881        S1 sa = void;
4882        S1 sb;
4883        emplace(&sa, sb);
4884        sa.foo();
4885        assert(i == 1);
4886    }
4887    {
4888        struct S2
4889        {
4890            void foo(){++i;}
4891            this(this){}
4892        }
4893        S2 sa = void;
4894        S2 sb;
4895        emplace(&sa, sb);
4896        sa.foo();
4897        assert(i == 2);
4898    }
4899}
4900
4901//Alias this
4902@system unittest
4903{
4904    static struct S
4905    {
4906        int i;
4907    }
4908    //By Ref
4909    {
4910        static struct SS1
4911        {
4912            int j;
4913            S s;
4914            alias s this;
4915        }
4916        S s = void;
4917        SS1 ss = SS1(1, S(2));
4918        emplace(&s, ss);
4919        assert(s.i == 2);
4920    }
4921    //By Value
4922    {
4923        static struct SS2
4924        {
4925            int j;
4926            S s;
4927            S foo() @property{return s;}
4928            alias foo this;
4929        }
4930        S s = void;
4931        SS2 ss = SS2(1, S(2));
4932        emplace(&s, ss);
4933        assert(s.i == 2);
4934    }
4935}
4936version (unittest)
4937{
4938    //Ambiguity
4939    struct __std_conv_S
4940    {
4941        int i;
4942        this(__std_conv_SS ss)         {assert(0);}
4943        static opCall(__std_conv_SS ss)
4944        {
4945            __std_conv_S s; s.i = ss.j;
4946            return s;
4947        }
4948    }
4949    struct __std_conv_SS
4950    {
4951        int j;
4952        __std_conv_S s;
4953        ref __std_conv_S foo() return @property {s.i = j; return s;}
4954        alias foo this;
4955    }
4956    static assert(is(__std_conv_SS : __std_conv_S));
4957    @system unittest
4958    {
4959        __std_conv_S s = void;
4960        __std_conv_SS ss = __std_conv_SS(1);
4961
4962        __std_conv_S sTest1 = ss; //this calls "SS alias this" (and not "S.this(SS)")
4963        emplace(&s, ss); //"alias this" should take precedence in emplace over "opCall"
4964        assert(s.i == 1);
4965    }
4966}
4967
4968//Nested classes
4969@system unittest
4970{
4971    class A{}
4972    static struct S
4973    {
4974        A a;
4975    }
4976    S s1 = void;
4977    S s2 = S(new A);
4978    emplace(&s1, s2);
4979    assert(s1.a is s2.a);
4980}
4981
4982//safety & nothrow & CTFE
4983@system unittest
4984{
4985    //emplace should be safe for anything with no elaborate opassign
4986    static struct S1
4987    {
4988        int i;
4989    }
4990    static struct S2
4991    {
4992        int i;
4993        this(int j)@safe nothrow{i = j;}
4994    }
4995
4996    int i;
4997    S1 s1 = void;
4998    S2 s2 = void;
4999
5000    auto pi = &i;
5001    auto ps1 = &s1;
5002    auto ps2 = &s2;
5003
5004    void foo() @safe nothrow
5005    {
5006        emplace(pi);
5007        emplace(pi, 5);
5008        emplace(ps1);
5009        emplace(ps1, 5);
5010        emplace(ps1, S1.init);
5011        emplace(ps2);
5012        emplace(ps2, 5);
5013        emplace(ps2, S2.init);
5014    }
5015    foo();
5016
5017    T bar(T)() @property
5018    {
5019        T t/+ = void+/; //CTFE void illegal
5020        emplace(&t, 5);
5021        return t;
5022    }
5023    // CTFE
5024    enum a = bar!int;
5025    static assert(a == 5);
5026    enum b = bar!S1;
5027    static assert(b.i == 5);
5028    enum c = bar!S2;
5029    static assert(c.i == 5);
5030    // runtime
5031    auto aa = bar!int;
5032    assert(aa == 5);
5033    auto bb = bar!S1;
5034    assert(bb.i == 5);
5035    auto cc = bar!S2;
5036    assert(cc.i == 5);
5037}
5038
5039
5040@system unittest
5041{
5042    struct S
5043    {
5044        int[2] get(){return [1, 2];}
5045        alias get this;
5046    }
5047    struct SS
5048    {
5049        int[2] ii;
5050    }
5051    struct ISS
5052    {
5053        int[2] ii;
5054    }
5055    S s;
5056    SS ss = void;
5057    ISS iss = void;
5058    emplace(&ss, s);
5059    emplace(&iss, s);
5060    assert(ss.ii == [1, 2]);
5061    assert(iss.ii == [1, 2]);
5062}
5063
5064//disable opAssign
5065@system unittest
5066{
5067    static struct S
5068    {
5069        @disable void opAssign(S);
5070    }
5071    S s;
5072    emplace(&s, S.init);
5073}
5074
5075//opCall
5076@system unittest
5077{
5078    int i;
5079    //Without constructor
5080    {
5081        static struct S1
5082        {
5083            int i;
5084            static S1 opCall(int*){assert(0);}
5085        }
5086        S1 s = void;
5087        static assert(!__traits(compiles, emplace(&s,  1)));
5088    }
5089    //With constructor
5090    {
5091        static struct S2
5092        {
5093            int i = 0;
5094            static S2 opCall(int*){assert(0);}
5095            static S2 opCall(int){assert(0);}
5096            this(int i){this.i = i;}
5097        }
5098        S2 s = void;
5099        emplace(&s,  1);
5100        assert(s.i == 1);
5101    }
5102    //With postblit ambiguity
5103    {
5104        static struct S3
5105        {
5106            int i = 0;
5107            static S3 opCall(ref S3){assert(0);}
5108        }
5109        S3 s = void;
5110        emplace(&s, S3.init);
5111    }
5112}
5113
5114@safe unittest //@@@9559@@@
5115{
5116    import std.algorithm.iteration : map;
5117    import std.array : array;
5118    import std.typecons : Nullable;
5119    alias I = Nullable!int;
5120    auto ints = [0, 1, 2].map!(i => i & 1 ? I.init : I(i))();
5121    auto asArray = array(ints);
5122}
5123
5124@system unittest //http://forum.dlang.org/post/nxbdgtdlmwscocbiypjs@forum.dlang.org
5125{
5126    import std.array : array;
5127    import std.datetime : SysTime, UTC;
5128    import std.math : isNaN;
5129
5130    static struct A
5131    {
5132        double i;
5133    }
5134
5135    static struct B
5136    {
5137        invariant()
5138        {
5139            if (j == 0)
5140                assert(a.i.isNaN(), "why is 'j' zero?? and i is not NaN?");
5141            else
5142                assert(!a.i.isNaN());
5143        }
5144        SysTime when; // comment this line avoid the breakage
5145        int j;
5146        A a;
5147    }
5148
5149    B b1 = B.init;
5150    assert(&b1); // verify that default eyes invariants are ok;
5151
5152    auto b2 = B(SysTime(0, UTC()), 1, A(1));
5153    assert(&b2);
5154    auto b3 = B(SysTime(0, UTC()), 1, A(1));
5155    assert(&b3);
5156
5157    auto arr = [b2, b3];
5158
5159    assert(arr[0].j == 1);
5160    assert(arr[1].j == 1);
5161    auto a2 = arr.array(); // << bang, invariant is raised, also if b2 and b3 are good
5162}
5163
5164//static arrays
5165@system unittest
5166{
5167    static struct S
5168    {
5169        int[2] ii;
5170    }
5171    static struct IS
5172    {
5173        immutable int[2] ii;
5174    }
5175    int[2] ii;
5176    S  s   = void;
5177    IS ims = void;
5178    ubyte ub = 2;
5179    emplace(&s, ub);
5180    emplace(&s, ii);
5181    emplace(&ims, ub);
5182    emplace(&ims, ii);
5183    uint[2] uu;
5184    static assert(!__traits(compiles, {S ss = S(uu);}));
5185    static assert(!__traits(compiles, emplace(&s, uu)));
5186}
5187
5188@system unittest
5189{
5190    int[2]  sii;
5191    int[2]  sii2;
5192    uint[2] uii;
5193    uint[2] uii2;
5194    emplace(&sii, 1);
5195    emplace(&sii, 1U);
5196    emplace(&uii, 1);
5197    emplace(&uii, 1U);
5198    emplace(&sii, sii2);
5199    //emplace(&sii, uii2); //Sorry, this implementation doesn't know how to...
5200    //emplace(&uii, sii2); //Sorry, this implementation doesn't know how to...
5201    emplace(&uii, uii2);
5202    emplace(&sii, sii2[]);
5203    //emplace(&sii, uii2[]); //Sorry, this implementation doesn't know how to...
5204    //emplace(&uii, sii2[]); //Sorry, this implementation doesn't know how to...
5205    emplace(&uii, uii2[]);
5206}
5207
5208@system unittest
5209{
5210    bool allowDestruction = false;
5211    struct S
5212    {
5213        int i;
5214        this(this){}
5215        ~this(){assert(allowDestruction);}
5216    }
5217    S s = S(1);
5218    S[2] ss1 = void;
5219    S[2] ss2 = void;
5220    S[2] ss3 = void;
5221    emplace(&ss1, s);
5222    emplace(&ss2, ss1);
5223    emplace(&ss3, ss2[]);
5224    assert(ss1[1] == s);
5225    assert(ss2[1] == s);
5226    assert(ss3[1] == s);
5227    allowDestruction = true;
5228}
5229
5230@system unittest
5231{
5232    //Checks postblit, construction, and context pointer
5233    int count = 0;
5234    struct S
5235    {
5236        this(this)
5237        {
5238            ++count;
5239        }
5240        ~this()
5241        {
5242            --count;
5243        }
5244    }
5245
5246    S s;
5247    {
5248        S[4] ss = void;
5249        emplace(&ss, s);
5250        assert(count == 4);
5251    }
5252    assert(count == 0);
5253}
5254
5255@system unittest
5256{
5257    struct S
5258    {
5259        int i;
5260    }
5261    S s;
5262    S[2][2][2] sss = void;
5263    emplace(&sss, s);
5264}
5265
5266@system unittest //Constness
5267{
5268    import std.stdio;
5269
5270    int a = void;
5271    emplaceRef!(const int)(a, 5);
5272
5273    immutable i = 5;
5274    const(int)* p = void;
5275    emplaceRef!(const int*)(p, &i);
5276
5277    struct S
5278    {
5279        int* p;
5280    }
5281    alias IS = immutable(S);
5282    S s = void;
5283    emplaceRef!IS(s, IS());
5284    S[2] ss = void;
5285    emplaceRef!(IS[2])(ss, IS());
5286
5287    IS[2] iss = IS.init;
5288    emplaceRef!(IS[2])(ss, iss);
5289    emplaceRef!(IS[2])(ss, iss[]);
5290}
5291
5292pure nothrow @safe @nogc unittest
5293{
5294    int i;
5295    emplaceRef(i);
5296    emplaceRef!int(i);
5297    emplaceRef(i, 5);
5298    emplaceRef!int(i, 5);
5299}
5300
5301// Test attribute propagation for UDTs
5302pure nothrow @safe /* @nogc */ unittest
5303{
5304    static struct Safe
5305    {
5306        this(this) pure nothrow @safe @nogc {}
5307    }
5308
5309    Safe safe = void;
5310    emplaceRef(safe, Safe());
5311
5312    Safe[1] safeArr = [Safe()];
5313    Safe[1] uninitializedSafeArr = void;
5314    emplaceRef(uninitializedSafeArr, safe);
5315    emplaceRef(uninitializedSafeArr, safeArr);
5316
5317    static struct Unsafe
5318    {
5319        this(this) @system {}
5320    }
5321
5322    Unsafe unsafe = void;
5323    static assert(!__traits(compiles, emplaceRef(unsafe, Unsafe())));
5324
5325    Unsafe[1] unsafeArr = [Unsafe()];
5326    Unsafe[1] uninitializedUnsafeArr = void;
5327    static assert(!__traits(compiles, emplaceRef(uninitializedUnsafeArr, unsafe)));
5328    static assert(!__traits(compiles, emplaceRef(uninitializedUnsafeArr, unsafeArr)));
5329}
5330
5331@system unittest
5332{
5333    // Issue 15313
5334    static struct Node
5335    {
5336        int payload;
5337        Node* next;
5338        uint refs;
5339    }
5340
5341    import core.stdc.stdlib : malloc;
5342    void[] buf = malloc(Node.sizeof)[0 .. Node.sizeof];
5343
5344    import std.conv : emplace;
5345    const Node* n = emplace!(const Node)(buf, 42, null, 10);
5346    assert(n.payload == 42);
5347    assert(n.next == null);
5348    assert(n.refs == 10);
5349}
5350
5351@system unittest
5352{
5353    int var = 6;
5354    auto k = emplace!__conv_EmplaceTest(new void[__conv_EmplaceTest.sizeof], 5, var);
5355    assert(k.i == 5);
5356    assert(var == 7);
5357}
5358
5359@system unittest
5360{
5361    class A
5362    {
5363        int x = 5;
5364        int y = 42;
5365        this(int z)
5366        {
5367            assert(x == 5 && y == 42);
5368            x = y = z;
5369        }
5370    }
5371    void[] buf;
5372
5373    static align(A.alignof) byte[__traits(classInstanceSize, A)] sbuf;
5374    buf = sbuf[];
5375    auto a = emplace!A(buf, 55);
5376    assert(a.x == 55 && a.y == 55);
5377
5378    // emplace in bigger buffer
5379    buf = new byte[](__traits(classInstanceSize, A) + 10);
5380    a = emplace!A(buf, 55);
5381    assert(a.x == 55 && a.y == 55);
5382
5383    // need ctor args
5384    static assert(!is(typeof(emplace!A(buf))));
5385}
5386// Bulk of emplace unittests ends here
5387
5388@safe unittest
5389{
5390    import std.algorithm.comparison : equal;
5391    import std.algorithm.iteration : map;
5392    // Check fix for http://d.puremagic.com/issues/show_bug.cgi?id=2971
5393    assert(equal(map!(to!int)(["42", "34", "345"]), [42, 34, 345]));
5394}
5395
5396// Undocumented for the time being
5397void toTextRange(T, W)(T value, W writer)
5398if (isIntegral!T && isOutputRange!(W, char))
5399{
5400    import core.internal.string : SignedStringBuf, signedToTempString,
5401                                  UnsignedStringBuf, unsignedToTempString;
5402
5403    if (value < 0)
5404    {
5405        SignedStringBuf buf = void;
5406        put(writer, signedToTempString(value, buf, 10));
5407    }
5408    else
5409    {
5410        UnsignedStringBuf buf = void;
5411        put(writer, unsignedToTempString(value, buf, 10));
5412    }
5413}
5414
5415@safe unittest
5416{
5417    import std.array : appender;
5418    auto result = appender!(char[])();
5419    toTextRange(-1, result);
5420    assert(result.data == "-1");
5421}
5422
5423
5424/**
5425    Returns the corresponding _unsigned value for $(D x) (e.g. if $(D x) has type
5426    $(D int), it returns $(D cast(uint) x)). The advantage compared to the cast
5427    is that you do not need to rewrite the cast if $(D x) later changes type
5428    (e.g from $(D int) to $(D long)).
5429
5430    Note that the result is always mutable even if the original type was const
5431    or immutable. In order to retain the constness, use $(REF Unsigned, std,traits).
5432 */
5433auto unsigned(T)(T x)
5434if (isIntegral!T)
5435{
5436    return cast(Unqual!(Unsigned!T))x;
5437}
5438
5439///
5440@safe unittest
5441{
5442    import std.traits : Unsigned;
5443    immutable int s = 42;
5444    auto u1 = unsigned(s); //not qualified
5445    static assert(is(typeof(u1) == uint));
5446    Unsigned!(typeof(s)) u2 = unsigned(s); //same qualification
5447    static assert(is(typeof(u2) == immutable uint));
5448    immutable u3 = unsigned(s); //explicitly qualified
5449}
5450
5451@safe unittest
5452{
5453    foreach (T; AliasSeq!(byte, ubyte))
5454    {
5455        static assert(is(typeof(unsigned(cast(T) 1)) == ubyte));
5456        static assert(is(typeof(unsigned(cast(const T) 1)) == ubyte));
5457        static assert(is(typeof(unsigned(cast(immutable T) 1)) == ubyte));
5458    }
5459
5460    foreach (T; AliasSeq!(short, ushort))
5461    {
5462        static assert(is(typeof(unsigned(cast(T) 1)) == ushort));
5463        static assert(is(typeof(unsigned(cast(const T) 1)) == ushort));
5464        static assert(is(typeof(unsigned(cast(immutable T) 1)) == ushort));
5465    }
5466
5467    foreach (T; AliasSeq!(int, uint))
5468    {
5469        static assert(is(typeof(unsigned(cast(T) 1)) == uint));
5470        static assert(is(typeof(unsigned(cast(const T) 1)) == uint));
5471        static assert(is(typeof(unsigned(cast(immutable T) 1)) == uint));
5472    }
5473
5474    foreach (T; AliasSeq!(long, ulong))
5475    {
5476        static assert(is(typeof(unsigned(cast(T) 1)) == ulong));
5477        static assert(is(typeof(unsigned(cast(const T) 1)) == ulong));
5478        static assert(is(typeof(unsigned(cast(immutable T) 1)) == ulong));
5479    }
5480}
5481
5482auto unsigned(T)(T x)
5483if (isSomeChar!T)
5484{
5485    // All characters are unsigned
5486    static assert(T.min == 0);
5487    return cast(Unqual!T) x;
5488}
5489
5490@safe unittest
5491{
5492    foreach (T; AliasSeq!(char, wchar, dchar))
5493    {
5494        static assert(is(typeof(unsigned(cast(T)'A')) == T));
5495        static assert(is(typeof(unsigned(cast(const T)'A')) == T));
5496        static assert(is(typeof(unsigned(cast(immutable T)'A')) == T));
5497    }
5498}
5499
5500
5501/**
5502    Returns the corresponding _signed value for $(D x) (e.g. if $(D x) has type
5503    $(D uint), it returns $(D cast(int) x)). The advantage compared to the cast
5504    is that you do not need to rewrite the cast if $(D x) later changes type
5505    (e.g from $(D uint) to $(D ulong)).
5506
5507    Note that the result is always mutable even if the original type was const
5508    or immutable. In order to retain the constness, use $(REF Signed, std,traits).
5509 */
5510auto signed(T)(T x)
5511if (isIntegral!T)
5512{
5513    return cast(Unqual!(Signed!T))x;
5514}
5515
5516///
5517@safe unittest
5518{
5519    import std.traits : Signed;
5520
5521    immutable uint u = 42;
5522    auto s1 = signed(u); //not qualified
5523    static assert(is(typeof(s1) == int));
5524    Signed!(typeof(u)) s2 = signed(u); //same qualification
5525    static assert(is(typeof(s2) == immutable int));
5526    immutable s3 = signed(u); //explicitly qualified
5527}
5528
5529@system unittest
5530{
5531    foreach (T; AliasSeq!(byte, ubyte))
5532    {
5533        static assert(is(typeof(signed(cast(T) 1)) == byte));
5534        static assert(is(typeof(signed(cast(const T) 1)) == byte));
5535        static assert(is(typeof(signed(cast(immutable T) 1)) == byte));
5536    }
5537
5538    foreach (T; AliasSeq!(short, ushort))
5539    {
5540        static assert(is(typeof(signed(cast(T) 1)) == short));
5541        static assert(is(typeof(signed(cast(const T) 1)) == short));
5542        static assert(is(typeof(signed(cast(immutable T) 1)) == short));
5543    }
5544
5545    foreach (T; AliasSeq!(int, uint))
5546    {
5547        static assert(is(typeof(signed(cast(T) 1)) == int));
5548        static assert(is(typeof(signed(cast(const T) 1)) == int));
5549        static assert(is(typeof(signed(cast(immutable T) 1)) == int));
5550    }
5551
5552    foreach (T; AliasSeq!(long, ulong))
5553    {
5554        static assert(is(typeof(signed(cast(T) 1)) == long));
5555        static assert(is(typeof(signed(cast(const T) 1)) == long));
5556        static assert(is(typeof(signed(cast(immutable T) 1)) == long));
5557    }
5558}
5559
5560@safe unittest
5561{
5562    // issue 10874
5563    enum Test { a = 0 }
5564    ulong l = 0;
5565    auto t = l.to!Test;
5566}
5567
5568// asOriginalType
5569/**
5570Returns the representation of an enumerated value, i.e. the value converted to
5571the base type of the enumeration.
5572*/
5573OriginalType!E asOriginalType(E)(E value) if (is(E == enum))
5574{
5575    return value;
5576}
5577
5578///
5579@safe unittest
5580{
5581    enum A { a = 42 }
5582    static assert(is(typeof(A.a.asOriginalType) == int));
5583    assert(A.a.asOriginalType == 42);
5584    enum B : double { a = 43 }
5585    static assert(is(typeof(B.a.asOriginalType) == double));
5586    assert(B.a.asOriginalType == 43);
5587}
5588
5589/**
5590    A wrapper on top of the built-in cast operator that allows one to restrict
5591    casting of the original type of the value.
5592
5593    A common issue with using a raw cast is that it may silently continue to
5594    compile even if the value's type has changed during refactoring,
5595    which breaks the initial assumption about the cast.
5596
5597    Params:
5598        From  = The type to cast from. The programmer must ensure it is legal
5599                to make this cast.
5600 */
5601template castFrom(From)
5602{
5603    /**
5604        Params:
5605            To    = The type _to cast _to.
5606            value = The value _to cast. It must be of type $(D From),
5607                    otherwise a compile-time error is emitted.
5608
5609        Returns:
5610            the value after the cast, returned by reference if possible.
5611     */
5612    auto ref to(To, T)(auto ref T value) @system
5613    {
5614        static assert(
5615            is(From == T),
5616            "the value to cast is not of specified type '" ~ From.stringof ~
5617                 "', it is of type '" ~ T.stringof ~ "'"
5618        );
5619
5620        static assert(
5621            is(typeof(cast(To) value)),
5622            "can't cast from '" ~ From.stringof ~ "' to '" ~ To.stringof ~ "'"
5623        );
5624
5625        return cast(To) value;
5626    }
5627}
5628
5629///
5630@system unittest
5631{
5632    // Regular cast, which has been verified to be legal by the programmer:
5633    {
5634        long x;
5635        auto y = cast(int) x;
5636    }
5637
5638    // However this will still compile if 'x' is changed to be a pointer:
5639    {
5640        long* x;
5641        auto y = cast(int) x;
5642    }
5643
5644    // castFrom provides a more reliable alternative to casting:
5645    {
5646        long x;
5647        auto y = castFrom!long.to!int(x);
5648    }
5649
5650    // Changing the type of 'x' will now issue a compiler error,
5651    // allowing bad casts to be caught before it's too late:
5652    {
5653        long* x;
5654        static assert(
5655            !__traits(compiles, castFrom!long.to!int(x))
5656        );
5657
5658        // if cast is still needed, must be changed to:
5659        auto y = castFrom!(long*).to!int(x);
5660    }
5661}
5662
5663// https://issues.dlang.org/show_bug.cgi?id=16667
5664@system unittest
5665{
5666    ubyte[] a = ['a', 'b', 'c'];
5667    assert(castFrom!(ubyte[]).to!(string)(a) == "abc");
5668}
5669
5670/**
5671Check the correctness of a string for $(D hexString).
5672The result is true if and only if the input string is composed of whitespace
5673characters (\f\n\r\t\v lineSep paraSep nelSep) and
5674an even number of hexadecimal digits (regardless of the case).
5675*/
5676@safe pure @nogc
5677private bool isHexLiteral(String)(scope const String hexData)
5678{
5679    import std.ascii : isHexDigit;
5680    import std.uni : lineSep, paraSep, nelSep;
5681    size_t i;
5682    foreach (const dchar c; hexData)
5683    {
5684        switch (c)
5685        {
5686            case ' ':
5687            case '\t':
5688            case '\v':
5689            case '\f':
5690            case '\r':
5691            case '\n':
5692            case lineSep:
5693            case paraSep:
5694            case nelSep:
5695                continue;
5696
5697            default:
5698                break;
5699        }
5700        if (c.isHexDigit)
5701            ++i;
5702        else
5703            return false;
5704    }
5705    return !(i & 1);
5706}
5707
5708@safe unittest
5709{
5710    // test all the hex digits
5711    static assert( ("0123456789abcdefABCDEF").isHexLiteral);
5712    // empty or white strings are not valid
5713    static assert( "\r\n\t".isHexLiteral);
5714    // but are accepted if the count of hex digits is even
5715    static assert( "A\r\n\tB".isHexLiteral);
5716}
5717
5718@safe unittest
5719{
5720    import std.ascii;
5721    // empty/whites
5722    static assert( "".isHexLiteral);
5723    static assert( " \r".isHexLiteral);
5724    static assert( whitespace.isHexLiteral);
5725    static assert( ""w.isHexLiteral);
5726    static assert( " \r"w.isHexLiteral);
5727    static assert( ""d.isHexLiteral);
5728    static assert( " \r"d.isHexLiteral);
5729    static assert( "\u2028\u2029\u0085"d.isHexLiteral);
5730    // odd x strings
5731    static assert( !("5" ~ whitespace).isHexLiteral);
5732    static assert( !"123".isHexLiteral);
5733    static assert( !"1A3".isHexLiteral);
5734    static assert( !"1 23".isHexLiteral);
5735    static assert( !"\r\n\tC".isHexLiteral);
5736    static assert( !"123"w.isHexLiteral);
5737    static assert( !"1A3"w.isHexLiteral);
5738    static assert( !"1 23"w.isHexLiteral);
5739    static assert( !"\r\n\tC"w.isHexLiteral);
5740    static assert( !"123"d.isHexLiteral);
5741    static assert( !"1A3"d.isHexLiteral);
5742    static assert( !"1 23"d.isHexLiteral);
5743    static assert( !"\r\n\tC"d.isHexLiteral);
5744    // even x strings with invalid charset
5745    static assert( !"12gG".isHexLiteral);
5746    static assert( !"2A  3q".isHexLiteral);
5747    static assert( !"12gG"w.isHexLiteral);
5748    static assert( !"2A  3q"w.isHexLiteral);
5749    static assert( !"12gG"d.isHexLiteral);
5750    static assert( !"2A  3q"d.isHexLiteral);
5751    // valid x strings
5752    static assert( ("5A" ~ whitespace).isHexLiteral);
5753    static assert( ("5A 01A C FF de 1b").isHexLiteral);
5754    static assert( ("0123456789abcdefABCDEF").isHexLiteral);
5755    static assert( (" 012 34 5 6789 abcd ef\rAB\nCDEF").isHexLiteral);
5756    static assert( ("5A 01A C FF de 1b"w).isHexLiteral);
5757    static assert( ("0123456789abcdefABCDEF"w).isHexLiteral);
5758    static assert( (" 012 34 5 6789 abcd ef\rAB\nCDEF"w).isHexLiteral);
5759    static assert( ("5A 01A C FF de 1b"d).isHexLiteral);
5760    static assert( ("0123456789abcdefABCDEF"d).isHexLiteral);
5761    static assert( (" 012 34 5 6789 abcd ef\rAB\nCDEF"d).isHexLiteral);
5762    // library version allows what's pointed by issue 10454
5763    static assert( ("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF").isHexLiteral);
5764}
5765
5766/**
5767Converts a hex literal to a string at compile time.
5768
5769Takes a string made of hexadecimal digits and returns
5770the matching string by converting each pair of digits to a character.
5771The input string can also include white characters, which can be used
5772to keep the literal string readable in the source code.
5773
5774The function is intended to replace the hexadecimal literal strings
5775starting with $(D 'x'), which could be removed to simplify the core language.
5776
5777Params:
5778    hexData = string to be converted.
5779
5780Returns:
5781    a $(D string), a $(D wstring) or a $(D dstring), according to the type of hexData.
5782 */
5783template hexString(string hexData)
5784if (hexData.isHexLiteral)
5785{
5786    immutable hexString = hexStrImpl(hexData);
5787}
5788
5789/// ditto
5790template hexString(wstring hexData)
5791if (hexData.isHexLiteral)
5792{
5793    immutable hexString = hexStrImpl(hexData);
5794}
5795
5796/// ditto
5797template hexString(dstring hexData)
5798if (hexData.isHexLiteral)
5799{
5800    immutable hexString = hexStrImpl(hexData);
5801}
5802
5803///
5804@safe unittest
5805{
5806    // conversion at compile time
5807    auto string1 = hexString!"304A314B";
5808    assert(string1 == "0J1K");
5809    auto string2 = hexString!"304A314B"w;
5810    assert(string2 == "0J1K"w);
5811    auto string3 = hexString!"304A314B"d;
5812    assert(string3 == "0J1K"d);
5813}
5814
5815/*
5816    Takes a hexadecimal string literal and returns its representation.
5817    hexData is granted to be a valid string by the caller.
5818    C is granted to be a valid char type by the caller.
5819*/
5820@safe nothrow pure
5821private auto hexStrImpl(String)(scope String hexData)
5822{
5823    import std.ascii : isHexDigit;
5824    alias C = Unqual!(ElementEncodingType!String);
5825    C[] result;
5826    result.length = hexData.length / 2;
5827    size_t cnt;
5828    ubyte v;
5829    foreach (c; hexData)
5830    {
5831        if (c.isHexDigit)
5832        {
5833            ubyte x;
5834            if (c >= '0' && c <= '9')
5835                x = cast(ubyte)(c - '0');
5836            else if (c >= 'a' && c <= 'f')
5837                x = cast(ubyte)(c - ('a' - 10));
5838            else if (c >= 'A' && c <= 'F')
5839                x = cast(ubyte)(c - ('A' - 10));
5840            if (cnt & 1)
5841            {
5842                v = cast(ubyte)((v << 4) | x);
5843                result[cnt / 2] = v;
5844            }
5845            else
5846                v = x;
5847            ++cnt;
5848        }
5849    }
5850    result.length = cnt / 2;
5851    return result;
5852}
5853
5854@safe unittest
5855{
5856    // compile time
5857    assert(hexString!"46 47 48 49 4A 4B" == "FGHIJK");
5858    assert(hexString!"30\r\n\t\f\v31 32 33 32 31 30" == "0123210");
5859    assert(hexString!"ab cd" == hexString!"ABCD");
5860}
5861
5862
5863/**
5864 * Convert integer to a range of characters.
5865 * Intended to be lightweight and fast.
5866 *
5867 * Params:
5868 *      radix = 2, 8, 10, 16
5869 *      Char = character type for output
5870 *      letterCase = lower for deadbeef, upper for DEADBEEF
5871 *      value = integer to convert. Can be uint or ulong. If radix is 10, can also be
5872 *              int or long.
5873 * Returns:
5874 *      Random access range with slicing and everything
5875 */
5876
5877auto toChars(ubyte radix = 10, Char = char, LetterCase letterCase = LetterCase.lower, T)(T value)
5878    pure nothrow @nogc @safe
5879if ((radix == 2 || radix == 8 || radix == 10 || radix == 16) &&
5880    (is(Unqual!T == uint) || is(Unqual!T == ulong) ||
5881    radix == 10 && (is(Unqual!T == int) || is(Unqual!T == long))))
5882{
5883    alias UT = Unqual!T;
5884
5885    static if (radix == 10)
5886    {
5887        /* uint.max  is 42_9496_7295
5888         *  int.max  is 21_4748_3647
5889         * ulong.max is 1844_6744_0737_0955_1615
5890         *  long.max is  922_3372_0368_5477_5807
5891         */
5892        static struct Result
5893        {
5894            void initialize(UT value)
5895            {
5896                bool neg = false;
5897                if (value < 10)
5898                {
5899                    if (value >= 0)
5900                    {
5901                        lwr = 0;
5902                        upr = 1;
5903                        buf[0] = cast(char)(cast(uint) value + '0');
5904                        return;
5905                    }
5906                    value = -value;
5907                    neg = true;
5908                }
5909                auto i = cast(uint) buf.length - 1;
5910                while (cast(Unsigned!UT) value >= 10)
5911                {
5912                    buf[i] = cast(ubyte)('0' + cast(Unsigned!UT) value % 10);
5913                    value = unsigned(value) / 10;
5914                    --i;
5915                }
5916                buf[i] = cast(char)(cast(uint) value + '0');
5917                if (neg)
5918                {
5919                    buf[i - 1] = '-';
5920                    --i;
5921                }
5922                lwr = i;
5923                upr = cast(uint) buf.length;
5924            }
5925
5926            @property size_t length() { return upr - lwr; }
5927
5928            alias opDollar = length;
5929
5930            @property bool empty() { return upr == lwr; }
5931
5932            @property Char front() { return buf[lwr]; }
5933
5934            void popFront() { ++lwr; }
5935
5936            @property Char back() { return buf[upr - 1]; }
5937
5938            void popBack() { --upr; }
5939
5940            @property Result save() { return this; }
5941
5942            Char opIndex(size_t i) { return buf[lwr + i]; }
5943
5944            Result opSlice(size_t lwr, size_t upr)
5945            {
5946                Result result = void;
5947                result.buf = buf;
5948                result.lwr = cast(uint)(this.lwr + lwr);
5949                result.upr = cast(uint)(this.lwr + upr);
5950                return result;
5951            }
5952
5953          private:
5954            uint lwr = void, upr = void;
5955            char[(UT.sizeof == 4) ? 10 + isSigned!T : 20] buf = void;
5956        }
5957
5958        Result result = void;
5959        result.initialize(value);
5960        return result;
5961    }
5962    else
5963    {
5964        static if (radix == 2)
5965            enum SHIFT = 1;
5966        else static if (radix == 8)
5967            enum SHIFT = 3;
5968        else static if (radix == 16)
5969            enum SHIFT = 4;
5970        else
5971            static assert(0);
5972        static struct Result
5973        {
5974            this(UT value)
5975            {
5976                this.value = value;
5977
5978                ubyte len = 1;
5979                while (value >>>= SHIFT)
5980                   ++len;
5981                this.len = len;
5982            }
5983
5984            @property size_t length() { return len; }
5985
5986            @property bool empty() { return len == 0; }
5987
5988            @property Char front() { return opIndex(0); }
5989
5990            void popFront() { --len; }
5991
5992            @property Char back() { return opIndex(len - 1); }
5993
5994            void popBack()
5995            {
5996                value >>>= SHIFT;
5997                --len;
5998            }
5999
6000            @property Result save() { return this; }
6001
6002            Char opIndex(size_t i)
6003            {
6004                Char c = (value >>> ((len - i - 1) * SHIFT)) & ((1 << SHIFT) - 1);
6005                return cast(Char)((radix < 10 || c < 10) ? c + '0'
6006                                                         : (letterCase == LetterCase.upper ? c + 'A' - 10
6007                                                                                           : c + 'a' - 10));
6008            }
6009
6010            Result opSlice(size_t lwr, size_t upr)
6011            {
6012                Result result = void;
6013                result.value = value >>> ((len - upr) * SHIFT);
6014                result.len = cast(ubyte)(upr - lwr);
6015                return result;
6016            }
6017
6018          private:
6019            UT value;
6020            ubyte len;
6021        }
6022
6023        return Result(value);
6024    }
6025}
6026
6027
6028@safe unittest
6029{
6030    import std.array;
6031    import std.range;
6032
6033    {
6034        assert(toChars!2(0u).array == "0");
6035        assert(toChars!2(0Lu).array == "0");
6036        assert(toChars!2(1u).array == "1");
6037        assert(toChars!2(1Lu).array == "1");
6038
6039        auto r = toChars!2(2u);
6040        assert(r.length == 2);
6041        assert(r[0] == '1');
6042        assert(r[1 .. 2].array == "0");
6043        auto s = r.save;
6044        assert(r.array == "10");
6045        assert(s.retro.array == "01");
6046    }
6047    {
6048        assert(toChars!8(0u).array == "0");
6049        assert(toChars!8(0Lu).array == "0");
6050        assert(toChars!8(1u).array == "1");
6051        assert(toChars!8(1234567Lu).array == "4553207");
6052
6053        auto r = toChars!8(8u);
6054        assert(r.length == 2);
6055        assert(r[0] == '1');
6056        assert(r[1 .. 2].array == "0");
6057        auto s = r.save;
6058        assert(r.array == "10");
6059        assert(s.retro.array == "01");
6060    }
6061    {
6062        assert(toChars!10(0u).array == "0");
6063        assert(toChars!10(0Lu).array == "0");
6064        assert(toChars!10(1u).array == "1");
6065        assert(toChars!10(1234567Lu).array == "1234567");
6066        assert(toChars!10(uint.max).array == "4294967295");
6067        assert(toChars!10(ulong.max).array == "18446744073709551615");
6068
6069        auto r = toChars(10u);
6070        assert(r.length == 2);
6071        assert(r[0] == '1');
6072        assert(r[1 .. 2].array == "0");
6073        auto s = r.save;
6074        assert(r.array == "10");
6075        assert(s.retro.array == "01");
6076    }
6077    {
6078        assert(toChars!10(0).array == "0");
6079        assert(toChars!10(0L).array == "0");
6080        assert(toChars!10(1).array == "1");
6081        assert(toChars!10(1234567L).array == "1234567");
6082        assert(toChars!10(int.max).array == "2147483647");
6083        assert(toChars!10(long.max).array == "9223372036854775807");
6084        assert(toChars!10(-int.max).array == "-2147483647");
6085        assert(toChars!10(-long.max).array == "-9223372036854775807");
6086        assert(toChars!10(int.min).array == "-2147483648");
6087        assert(toChars!10(long.min).array == "-9223372036854775808");
6088
6089        auto r = toChars!10(10);
6090        assert(r.length == 2);
6091        assert(r[0] == '1');
6092        assert(r[1 .. 2].array == "0");
6093        auto s = r.save;
6094        assert(r.array == "10");
6095        assert(s.retro.array == "01");
6096    }
6097    {
6098        assert(toChars!(16)(0u).array == "0");
6099        assert(toChars!(16)(0Lu).array == "0");
6100        assert(toChars!(16)(10u).array == "a");
6101        assert(toChars!(16, char, LetterCase.upper)(0x12AF34567Lu).array == "12AF34567");
6102
6103        auto r = toChars!(16)(16u);
6104        assert(r.length == 2);
6105        assert(r[0] == '1');
6106        assert(r[1 .. 2].array == "0");
6107        auto s = r.save;
6108        assert(r.array == "10");
6109        assert(s.retro.array == "01");
6110    }
6111}
6112
6113@safe unittest // opSlice (issue 16192)
6114{
6115    import std.meta : AliasSeq;
6116
6117    static struct Test { ubyte radix; uint number; }
6118
6119    alias tests = AliasSeq!(
6120        Test(2, 0b1_0110_0111u),
6121        Test(2, 0b10_1100_1110u),
6122        Test(8, octal!123456701u),
6123        Test(8, octal!1234567012u),
6124        Test(10, 123456789u),
6125        Test(10, 1234567890u),
6126        Test(16, 0x789ABCDu),
6127        Test(16, 0x789ABCDEu),
6128    );
6129
6130    foreach (test; tests)
6131    {
6132        enum ubyte radix = test.radix;
6133        auto original = toChars!radix(test.number);
6134
6135        // opSlice vs popFront
6136        auto r = original.save;
6137        size_t i = 0;
6138        for (; !r.empty; r.popFront(), ++i)
6139        {
6140            assert(original[i .. original.length].tupleof == r.tupleof);
6141                // tupleof is used to work around issue 16216.
6142        }
6143
6144        // opSlice vs popBack
6145        r = original.save;
6146        i = 0;
6147        for (; !r.empty; r.popBack(), ++i)
6148        {
6149            assert(original[0 .. original.length - i].tupleof == r.tupleof);
6150        }
6151
6152        // opSlice vs both popFront and popBack
6153        r = original.save;
6154        i = 0;
6155        for (; r.length >= 2; r.popFront(), r.popBack(), ++i)
6156        {
6157            assert(original[i .. original.length - i].tupleof == r.tupleof);
6158        }
6159    }
6160}
6161