1 // Written in the D programming language.
2 
3 /**
4 This module implements a variety of type constructors, i.e., templates
5 that allow construction of new, useful general-purpose types.
6 
7 $(SCRIPT inhibitQuickIndex = 1;)
8 $(BOOKTABLE,
9 $(TR $(TH Category) $(TH Functions))
10 $(TR $(TD Tuple) $(TD
11     $(LREF isTuple)
12     $(LREF Tuple)
13     $(LREF tuple)
14     $(LREF reverse)
15 ))
16 $(TR $(TD Flags) $(TD
17     $(LREF BitFlags)
18     $(LREF isBitFlagEnum)
19     $(LREF Flag)
20     $(LREF No)
21     $(LREF Yes)
22 ))
23 $(TR $(TD Memory allocation) $(TD
24     $(LREF RefCounted)
25     $(LREF refCounted)
26     $(LREF RefCountedAutoInitialize)
27     $(LREF scoped)
28     $(LREF Unique)
29 ))
30 $(TR $(TD Code generation) $(TD
31     $(LREF AutoImplement)
32     $(LREF BlackHole)
33     $(LREF generateAssertTrap)
34     $(LREF generateEmptyFunction)
35     $(LREF WhiteHole)
36 ))
37 $(TR $(TD Nullable) $(TD
38     $(LREF Nullable)
39     $(LREF nullable)
40     $(LREF NullableRef)
41     $(LREF nullableRef)
42 ))
43 $(TR $(TD Proxies) $(TD
44     $(LREF Proxy)
45     $(LREF rebindable)
46     $(LREF Rebindable)
47     $(LREF ReplaceType)
48     $(LREF unwrap)
49     $(LREF wrap)
50 ))
51 $(TR $(TD Types) $(TD
52     $(LREF alignForSize)
53     $(LREF Ternary)
54     $(LREF Typedef)
55     $(LREF TypedefType)
56     $(LREF UnqualRef)
57 ))
58 )
59 
60 Copyright: Copyright the respective authors, 2008-
61 License:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
62 Source:    $(PHOBOSSRC std/_typecons.d)
63 Authors:   $(HTTP erdani.org, Andrei Alexandrescu),
64            $(HTTP bartoszmilewski.wordpress.com, Bartosz Milewski),
65            Don Clugston,
66            Shin Fujishiro,
67            Kenji Hara
68  */
69 module std.typecons;
70 
71 import core.stdc.stdint : uintptr_t;
72 import std.meta; // : AliasSeq, allSatisfy;
73 import std.traits;
74 
75 ///
76 @safe unittest
77 {
78     // value tuples
79     alias Coord = Tuple!(int, "x", int, "y", int, "z");
80     Coord c;
81     c[1] = 1;       // access by index
82     c.z = 1;        // access by given name
83     assert(c == Coord(0, 1, 1));
84 
85     // names can be omitted
86     alias DicEntry = Tuple!(string, string);
87 
88     // tuples can also be constructed on instantiation
89     assert(tuple(2, 3, 4)[1] == 3);
90     // construction on instantiation works with names too
91     assert(tuple!("x", "y", "z")(2, 3, 4).y == 3);
92 
93     // Rebindable references to const and immutable objects
94     {
foo()95         class Widget { void foo() const @safe {} }
96         const w1 = new Widget, w2 = new Widget;
97         w1.foo();
98         // w1 = w2 would not work; can't rebind const object
99         auto r = Rebindable!(const Widget)(w1);
100         // invoke method as if r were a Widget object
101         r.foo();
102         // rebind r to refer to another object
103         r = w2;
104     }
105 }
106 
107 debug(Unique) import std.stdio;
108 
109 /**
110 Encapsulates unique ownership of a resource.
111 
112 When a $(D Unique!T) goes out of scope it will call $(D destroy)
113 on the resource $(D T) that it manages, unless it is transferred.
114 One important consequence of $(D destroy) is that it will call the
115 destructor of the resource $(D T).  GC-managed references are not
116 guaranteed to be valid during a destructor call, but other members of
117 $(D T), such as file handles or pointers to $(D malloc) memory, will
118 still be valid during the destructor call.  This allows the resource
119 $(D T) to deallocate or clean up any non-GC resources.
120 
121 If it is desirable to persist a $(D Unique!T) outside of its original
122 scope, then it can be transferred.  The transfer can be explicit, by
123 calling $(D release), or implicit, when returning Unique from a
124 function. The resource $(D T) can be a polymorphic class object or
125 instance of an interface, in which case Unique behaves polymorphically
126 too.
127 
128 If $(D T) is a value type, then $(D Unique!T) will be implemented
129 as a reference to a $(D T).
130 */
Unique(T)131 struct Unique(T)
132 {
133 /** Represents a reference to $(D T). Resolves to $(D T*) if $(D T) is a value type. */
134 static if (is(T == class) || is(T == interface))
135     alias RefT = T;
136 else
137     alias RefT = T*;
138 
139 public:
140     // Deferred in case we get some language support for checking uniqueness.
141     version (None)
142     /**
143     Allows safe construction of $(D Unique). It creates the resource and
144     guarantees unique ownership of it (unless $(D T) publishes aliases of
145     $(D this)).
146     Note: Nested structs/classes cannot be created.
147     Params:
148     args = Arguments to pass to $(D T)'s constructor.
149     ---
150     static class C {}
151     auto u = Unique!(C).create();
152     ---
153     */
154     static Unique!T create(A...)(auto ref A args)
155     if (__traits(compiles, new T(args)))
156     {
157         debug(Unique) writeln("Unique.create for ", T.stringof);
158         Unique!T u;
159         u._p = new T(args);
160         return u;
161     }
162 
163     /**
164     Constructor that takes an rvalue.
165     It will ensure uniqueness, as long as the rvalue
166     isn't just a view on an lvalue (e.g., a cast).
167     Typical usage:
168     ----
169     Unique!Foo f = new Foo;
170     ----
171     */
172     this(RefT p)
173     {
174         debug(Unique) writeln("Unique constructor with rvalue");
175         _p = p;
176     }
177     /**
178     Constructor that takes an lvalue. It nulls its source.
179     The nulling will ensure uniqueness as long as there
180     are no previous aliases to the source.
181     */
182     this(ref RefT p)
183     {
184         _p = p;
185         debug(Unique) writeln("Unique constructor nulling source");
186         p = null;
187         assert(p is null);
188     }
189     /**
190     Constructor that takes a $(D Unique) of a type that is convertible to our type.
191 
192     Typically used to transfer a $(D Unique) rvalue of derived type to
193     a $(D Unique) of base type.
194     Example:
195     ---
196     class C : Object {}
197 
198     Unique!C uc = new C;
199     Unique!Object uo = uc.release;
200     ---
201     */
202     this(U)(Unique!U u)
203     if (is(u.RefT:RefT))
204     {
205         debug(Unique) writeln("Unique constructor converting from ", U.stringof);
206         _p = u._p;
207         u._p = null;
208     }
209 
210     /// Transfer ownership from a $(D Unique) of a type that is convertible to our type.
211     void opAssign(U)(Unique!U u)
212     if (is(u.RefT:RefT))
213     {
214         debug(Unique) writeln("Unique opAssign converting from ", U.stringof);
215         // first delete any resource we own
216         destroy(this);
217         _p = u._p;
218         u._p = null;
219     }
220 
221     ~this()
222     {
223         debug(Unique) writeln("Unique destructor of ", (_p is null)? null: _p);
224         if (_p !is null)
225         {
226             destroy(_p);
227             _p = null;
228         }
229     }
230 
231     /** Returns whether the resource exists. */
232     @property bool isEmpty() const
233     {
234         return _p is null;
235     }
236     /** Transfer ownership to a $(D Unique) rvalue. Nullifies the current contents.
237     Same as calling std.algorithm.move on it.
238     */
239     Unique release()
240     {
241         debug(Unique) writeln("Unique Release");
242         import std.algorithm.mutation : move;
243         return this.move;
244     }
245 
246     /** Forwards member access to contents. */
247     mixin Proxy!_p;
248 
249     /**
250     Postblit operator is undefined to prevent the cloning of $(D Unique) objects.
251     */
252     @disable this(this);
253 
254 private:
255     RefT _p;
256 }
257 
258 ///
259 @system unittest
260 {
261     static struct S
262     {
263         int i;
thisS264         this(int i){this.i = i;}
265     }
266     Unique!S produce()
267     {
268         // Construct a unique instance of S on the heap
269         Unique!S ut = new S(5);
270         // Implicit transfer of ownership
271         return ut;
272     }
273     // Borrow a unique resource by ref
274     void increment(ref Unique!S ur)
275     {
276         ur.i++;
277     }
278     void consume(Unique!S u2)
279     {
280         assert(u2.i == 6);
281         // Resource automatically deleted here
282     }
283     Unique!S u1;
284     assert(u1.isEmpty);
285     u1 = produce();
286     increment(u1);
287     assert(u1.i == 6);
288     //consume(u1); // Error: u1 is not copyable
289     // Transfer ownership of the resource
290     consume(u1.release);
291     assert(u1.isEmpty);
292 }
293 
294 @system unittest
295 {
296     // test conversion to base ref
297     int deleted = 0;
298     class C
299     {
~this()300         ~this(){deleted++;}
301     }
302     // constructor conversion
303     Unique!Object u = Unique!C(new C);
304     static assert(!__traits(compiles, {u = new C;}));
305     assert(!u.isEmpty);
306     destroy(u);
307     assert(deleted == 1);
308 
309     Unique!C uc = new C;
310     static assert(!__traits(compiles, {Unique!Object uo = uc;}));
311     Unique!Object uo = new C;
312     // opAssign conversion, deleting uo resource first
313     uo = uc.release;
314     assert(uc.isEmpty);
315     assert(!uo.isEmpty);
316     assert(deleted == 2);
317 }
318 
319 @system unittest
320 {
321     debug(Unique) writeln("Unique class");
322     class Bar
323     {
~this()324         ~this() { debug(Unique) writeln("    Bar destructor"); }
val()325         int val() const { return 4; }
326     }
327     alias UBar = Unique!(Bar);
g(UBar u)328     UBar g(UBar u)
329     {
330         debug(Unique) writeln("inside g");
331         return u.release;
332     }
333     auto ub = UBar(new Bar);
334     assert(!ub.isEmpty);
335     assert(ub.val == 4);
336     static assert(!__traits(compiles, {auto ub3 = g(ub);}));
337     debug(Unique) writeln("Calling g");
338     auto ub2 = g(ub.release);
339     debug(Unique) writeln("Returned from g");
340     assert(ub.isEmpty);
341     assert(!ub2.isEmpty);
342 }
343 
344 @system unittest
345 {
346     debug(Unique) writeln("Unique interface");
347     interface Bar
348     {
349         int val() const;
350     }
351     class BarImpl : Bar
352     {
353         static int count;
this()354         this()
355         {
356             count++;
357         }
~this()358         ~this()
359         {
360             count--;
361         }
val()362         int val() const { return 4; }
363     }
364     alias UBar = Unique!Bar;
g(UBar u)365     UBar g(UBar u)
366     {
367         debug(Unique) writeln("inside g");
368         return u.release;
369     }
consume(UBar u)370     void consume(UBar u)
371     {
372         assert(u.val() == 4);
373         // Resource automatically deleted here
374     }
375     auto ub = UBar(new BarImpl);
376     assert(BarImpl.count == 1);
377     assert(!ub.isEmpty);
378     assert(ub.val == 4);
379     static assert(!__traits(compiles, {auto ub3 = g(ub);}));
380     debug(Unique) writeln("Calling g");
381     auto ub2 = g(ub.release);
382     debug(Unique) writeln("Returned from g");
383     assert(ub.isEmpty);
384     assert(!ub2.isEmpty);
385     consume(ub2.release);
386     assert(BarImpl.count == 0);
387 }
388 
389 @system unittest
390 {
391     debug(Unique) writeln("Unique struct");
392     struct Foo
393     {
~thisFoo394         ~this() { debug(Unique) writeln("    Foo destructor"); }
valFoo395         int val() const { return 3; }
396         @disable this(this);
397     }
398     alias UFoo = Unique!(Foo);
399 
f(UFoo u)400     UFoo f(UFoo u)
401     {
402         debug(Unique) writeln("inside f");
403         return u.release;
404     }
405 
406     auto uf = UFoo(new Foo);
407     assert(!uf.isEmpty);
408     assert(uf.val == 3);
409     static assert(!__traits(compiles, {auto uf3 = f(uf);}));
410     debug(Unique) writeln("Unique struct: calling f");
411     auto uf2 = f(uf.release);
412     debug(Unique) writeln("Unique struct: returned from f");
413     assert(uf.isEmpty);
414     assert(!uf2.isEmpty);
415 }
416 
417 // ensure Unique behaves correctly through const access paths
418 @system unittest
419 {
420     struct Bar {int val;}
421     struct Foo
422     {
423         Unique!Bar bar = new Bar;
424     }
425 
426     Foo foo;
427     foo.bar.val = 6;
428     const Foo* ptr = &foo;
429     static assert(is(typeof(ptr) == const(Foo*)));
430     static assert(is(typeof(ptr.bar) == const(Unique!Bar)));
431     static assert(is(typeof(ptr.bar.val) == const(int)));
432     assert(ptr.bar.val == 6);
433     foo.bar.val = 7;
434     assert(ptr.bar.val == 7);
435 }
436 
437 // Used in Tuple.toString
438 private template sharedToString(alias field)
439     if (is(typeof(field) == shared))
440 {
441     static immutable sharedToString = typeof(field).stringof;
442 }
443 
444 private template sharedToString(alias field)
445     if (!is(typeof(field) == shared))
446 {
447     alias sharedToString = field;
448 }
449 
450 /**
451 _Tuple of values, for example $(D Tuple!(int, string)) is a record that
452 stores an $(D int) and a $(D string). $(D Tuple) can be used to bundle
453 values together, notably when returning multiple values from a
454 function. If $(D obj) is a `Tuple`, the individual members are
455 accessible with the syntax $(D obj[0]) for the first field, $(D obj[1])
456 for the second, and so on.
457 
458 The choice of zero-based indexing instead of one-base indexing was
459 motivated by the ability to use value tuples with various compile-time
460 loop constructs (e.g. $(REF AliasSeq, std,meta) iteration), all of which use
461 zero-based indexing.
462 
463 See_Also: $(LREF tuple).
464 
465 Params:
466     Specs = A list of types (and optionally, member names) that the `Tuple` contains.
467 */
Tuple(Specs...)468 template Tuple(Specs...)
469 {
470     import std.meta : staticMap;
471 
472     // Parse (type,name) pairs (FieldSpecs) out of the specified
473     // arguments. Some fields would have name, others not.
474     template parseSpecs(Specs...)
475     {
476         static if (Specs.length == 0)
477         {
478             alias parseSpecs = AliasSeq!();
479         }
480         else static if (is(Specs[0]))
481         {
482             static if (is(typeof(Specs[1]) : string))
483             {
484                 alias parseSpecs =
485                     AliasSeq!(FieldSpec!(Specs[0 .. 2]),
486                               parseSpecs!(Specs[2 .. $]));
487             }
488             else
489             {
490                 alias parseSpecs =
491                     AliasSeq!(FieldSpec!(Specs[0]),
492                               parseSpecs!(Specs[1 .. $]));
493             }
494         }
495         else
496         {
497             static assert(0, "Attempted to instantiate Tuple with an "
498                             ~"invalid argument: "~ Specs[0].stringof);
499         }
500     }
501 
502     template FieldSpec(T, string s = "")
503     {
504         alias Type = T;
505         alias name = s;
506     }
507 
508     alias fieldSpecs = parseSpecs!Specs;
509 
510     // Used with staticMap.
511     alias extractType(alias spec) = spec.Type;
512     alias extractName(alias spec) = spec.name;
513 
514     // Generates named fields as follows:
515     //    alias name_0 = Identity!(field[0]);
516     //    alias name_1 = Identity!(field[1]);
517     //      :
518     // NOTE: field[k] is an expression (which yields a symbol of a
519     //       variable) and can't be aliased directly.
520     string injectNamedFields()
521     {
522         string decl = "";
523         foreach (i, name; staticMap!(extractName, fieldSpecs))
524         {
525             import std.format : format;
526 
527             decl ~= format("alias _%s = Identity!(field[%s]);", i, i);
528             if (name.length != 0)
529             {
530                 decl ~= format("alias %s = _%s;", name, i);
531             }
532         }
533         return decl;
534     }
535 
536     // Returns Specs for a subtuple this[from .. to] preserving field
537     // names if any.
538     alias sliceSpecs(size_t from, size_t to) =
539         staticMap!(expandSpec, fieldSpecs[from .. to]);
540 
541     template expandSpec(alias spec)
542     {
543         static if (spec.name.length == 0)
544         {
545             alias expandSpec = AliasSeq!(spec.Type);
546         }
547         else
548         {
549             alias expandSpec = AliasSeq!(spec.Type, spec.name);
550         }
551     }
552 
553     enum areCompatibleTuples(Tup1, Tup2, string op) = isTuple!Tup2 && is(typeof(
554     (ref Tup1 tup1, ref Tup2 tup2)
555     {
556         static assert(tup1.field.length == tup2.field.length);
557         foreach (i, _; Tup1.Types)
558         {
559             auto lhs = typeof(tup1.field[i]).init;
560             auto rhs = typeof(tup2.field[i]).init;
561             static if (op == "=")
562                 lhs = rhs;
563             else
564                 auto result = mixin("lhs "~op~" rhs");
565         }
566     }));
567 
568     enum areBuildCompatibleTuples(Tup1, Tup2) = isTuple!Tup2 && is(typeof(
569     {
570         static assert(Tup1.Types.length == Tup2.Types.length);
571         foreach (i, _; Tup1.Types)
572             static assert(isBuildable!(Tup1.Types[i], Tup2.Types[i]));
573     }));
574 
575     /+ Returns $(D true) iff a $(D T) can be initialized from a $(D U). +/
576     enum isBuildable(T, U) =  is(typeof(
577     {
578         U u = U.init;
579         T t = u;
580     }));
581     /+ Helper for partial instanciation +/
582     template isBuildableFrom(U)
583     {
584         enum isBuildableFrom(T) = isBuildable!(T, U);
585     }
586 
587     struct Tuple
588     {
589         /**
590          * The types of the `Tuple`'s components.
591          */
592         alias Types = staticMap!(extractType, fieldSpecs);
593 
594         ///
595         static if (Specs.length == 0) @safe unittest
596         {
597             alias Fields = Tuple!(int, "id", string, float);
598             static assert(is(Fields.Types == AliasSeq!(int, string, float)));
599         }
600 
601         /**
602          * The names of the `Tuple`'s components. Unnamed fields have empty names.
603          */
604         alias fieldNames = staticMap!(extractName, fieldSpecs);
605 
606         ///
607         static if (Specs.length == 0) @safe unittest
608         {
609             alias Fields = Tuple!(int, "id", string, float);
610             static assert(Fields.fieldNames == AliasSeq!("id", "", ""));
611         }
612 
613         /**
614          * Use $(D t.expand) for a `Tuple` $(D t) to expand it into its
615          * components. The result of $(D expand) acts as if the `Tuple`'s components
616          * were listed as a list of values. (Ordinarily, a $(D Tuple) acts as a
617          * single value.)
618          */
619         Types expand;
620         mixin(injectNamedFields());
621 
622         ///
623         static if (Specs.length == 0) @safe unittest
624         {
625             auto t1 = tuple(1, " hello ", 2.3);
626             assert(t1.toString() == `Tuple!(int, string, double)(1, " hello ", 2.3)`);
627 
628             void takeSeveralTypes(int n, string s, bool b)
629             {
630                 assert(n == 4 && s == "test" && b == false);
631             }
632 
633             auto t2 = tuple(4, "test", false);
634             //t.expand acting as a list of values
635             takeSeveralTypes(t2.expand);
636         }
637 
638         static if (is(Specs))
639         {
640             // This is mostly to make t[n] work.
641             alias expand this;
642         }
643         else
644         {
645             @property
646             ref inout(Tuple!Types) _Tuple_super() inout @trusted
647             {
648                 foreach (i, _; Types)   // Rely on the field layout
649                 {
650                     static assert(typeof(return).init.tupleof[i].offsetof ==
651                                                        expand[i].offsetof);
652                 }
653                 return *cast(typeof(return)*) &(field[0]);
654             }
655             // This is mostly to make t[n] work.
656             alias _Tuple_super this;
657         }
658 
659         // backwards compatibility
660         alias field = expand;
661 
662         /**
663          * Constructor taking one value for each field.
664          *
665          * Params:
666          *     values = A list of values that are either the same
667          *              types as those given by the `Types` field
668          *              of this `Tuple`, or can implicitly convert
669          *              to those types. They must be in the same
670          *              order as they appear in `Types`.
671          */
672         static if (Types.length > 0)
673         {
674             this(Types values)
675             {
676                 field[] = values[];
677             }
678         }
679 
680         ///
681         static if (Specs.length == 0) @safe unittest
682         {
683             alias ISD = Tuple!(int, string, double);
684             auto tup = ISD(1, "test", 3.2);
685             assert(tup.toString() == `Tuple!(int, string, double)(1, "test", 3.2)`);
686         }
687 
688         /**
689          * Constructor taking a compatible array.
690          *
691          * Params:
692          *     values = A compatible static array to build the `Tuple` from.
693          *              Array slices are not supported.
694          */
695         this(U, size_t n)(U[n] values)
696         if (n == Types.length && allSatisfy!(isBuildableFrom!U, Types))
697         {
698             foreach (i, _; Types)
699             {
700                 field[i] = values[i];
701             }
702         }
703 
704         ///
705         static if (Specs.length == 0) @safe unittest
706         {
707             int[2] ints;
708             Tuple!(int, int) t = ints;
709         }
710 
711         /**
712          * Constructor taking a compatible `Tuple`. Two `Tuple`s are compatible
713          * $(B iff) they are both of the same length, and, for each type `T` on the
714          * left-hand side, the corresponding type `U` on the right-hand side can
715          * implicitly convert to `T`.
716          *
717          * Params:
718          *     another = A compatible `Tuple` to build from. Its type must be
719          *               compatible with the target `Tuple`'s type.
720          */
721         this(U)(U another)
722         if (areBuildCompatibleTuples!(typeof(this), U))
723         {
724             field[] = another.field[];
725         }
726 
727         ///
728         static if (Specs.length == 0) @safe unittest
729         {
730             alias IntVec = Tuple!(int, int, int);
731             alias DubVec = Tuple!(double, double, double);
732 
733             IntVec iv = tuple(1, 1, 1);
734 
735             //Ok, int can implicitly convert to double
736             DubVec dv = iv;
737             //Error: double cannot implicitly convert to int
738             //IntVec iv2 = dv;
739         }
740 
741         /**
742          * Comparison for equality. Two `Tuple`s are considered equal
743          * $(B iff) they fulfill the following criteria:
744          *
745          * $(UL
746          *   $(LI Each `Tuple` is the same length.)
747          *   $(LI For each type `T` on the left-hand side and each type
748          *        `U` on the right-hand side, values of type `T` can be
749          *        compared with values of type `U`.)
750          *   $(LI For each value `v1` on the left-hand side and each value
751          *        `v2` on the right-hand side, the expression `v1 == v2` is
752          *        true.))
753          *
754          * Params:
755          *     rhs = The `Tuple` to compare against. It must meeting the criteria
756          *           for comparison between `Tuple`s.
757          *
758          * Returns:
759          *     true if both `Tuple`s are equal, otherwise false.
760          */
761         bool opEquals(R)(R rhs)
762         if (areCompatibleTuples!(typeof(this), R, "=="))
763         {
764             return field[] == rhs.field[];
765         }
766 
767         /// ditto
768         bool opEquals(R)(R rhs) const
769         if (areCompatibleTuples!(typeof(this), R, "=="))
770         {
771             return field[] == rhs.field[];
772         }
773 
774         ///
775         static if (Specs.length == 0) @safe unittest
776         {
777             Tuple!(int, string) t1 = tuple(1, "test");
778             Tuple!(double, string) t2 =  tuple(1.0, "test");
779             //Ok, int can be compared with double and
780             //both have a value of 1
781             assert(t1 == t2);
782         }
783 
784         /**
785          * Comparison for ordering.
786          *
787          * Params:
788          *     rhs = The `Tuple` to compare against. It must meet the criteria
789          *           for comparison between `Tuple`s.
790          *
791          * Returns:
792          * For any values `v1` on the right-hand side and `v2` on the
793          * left-hand side:
794          *
795          * $(UL
796          *   $(LI A negative integer if the expression `v1 < v2` is true.)
797          *   $(LI A positive integer if the expression `v1 > v2` is true.)
798          *   $(LI 0 if the expression `v1 == v2` is true.))
799          */
800         int opCmp(R)(R rhs)
801         if (areCompatibleTuples!(typeof(this), R, "<"))
802         {
803             foreach (i, Unused; Types)
804             {
805                 if (field[i] != rhs.field[i])
806                 {
807                     return field[i] < rhs.field[i] ? -1 : 1;
808                 }
809             }
810             return 0;
811         }
812 
813         /// ditto
814         int opCmp(R)(R rhs) const
815         if (areCompatibleTuples!(typeof(this), R, "<"))
816         {
817             foreach (i, Unused; Types)
818             {
819                 if (field[i] != rhs.field[i])
820                 {
821                     return field[i] < rhs.field[i] ? -1 : 1;
822                 }
823             }
824             return 0;
825         }
826 
827         /**
828             The first `v1` for which `v1 > v2` is true determines
829             the result. This could lead to unexpected behaviour.
830          */
831         static if (Specs.length == 0) @safe unittest
832         {
833             auto tup1 = tuple(1, 1, 1);
834             auto tup2 = tuple(1, 100, 100);
835             assert(tup1 < tup2);
836 
837             //Only the first result matters for comparison
838             tup1[0] = 2;
839             assert(tup1 > tup2);
840         }
841 
842         /**
843          * Assignment from another `Tuple`.
844          *
845          * Params:
846          *     rhs = The source `Tuple` to assign from. Each element of the
847          *           source `Tuple` must be implicitly assignable to each
848          *           respective element of the target `Tuple`.
849          */
850         void opAssign(R)(auto ref R rhs)
851         if (areCompatibleTuples!(typeof(this), R, "="))
852         {
853             import std.algorithm.mutation : swap;
854 
855             static if (is(R : Tuple!Types) && !__traits(isRef, rhs))
856             {
857                 if (__ctfe)
858                 {
859                     // Cannot use swap at compile time
860                     field[] = rhs.field[];
861                 }
862                 else
863                 {
864                     // Use swap-and-destroy to optimize rvalue assignment
865                     swap!(Tuple!Types)(this, rhs);
866                 }
867             }
868             else
869             {
870                 // Do not swap; opAssign should be called on the fields.
871                 field[] = rhs.field[];
872             }
873         }
874 
875         /**
876          * Renames the elements of a $(LREF Tuple).
877          *
878          * `rename` uses the passed `names` and returns a new
879          * $(LREF Tuple) using these names, with the content
880          * unchanged.
881          * If fewer names are passed than there are members
882          * of the $(LREF Tuple) then those trailing members are unchanged.
883          * An empty string will remove the name for that member.
884          * It is an compile-time error to pass more names than
885          * there are members of the $(LREF Tuple).
886          */
887         ref rename(names...)() return
888         if (names.length == 0 || allSatisfy!(isSomeString, typeof(names)))
889         {
890             import std.algorithm.comparison : equal;
891             // to circumvent bug 16418
892             static if (names.length == 0 || equal([names], [fieldNames]))
893                 return this;
894             else
895             {
896                 enum nT = Types.length;
897                 enum nN = names.length;
898                 static assert(nN <= nT, "Cannot have more names than tuple members");
899                 alias allNames = AliasSeq!(names, fieldNames[nN .. $]);
900 
901                 template GetItem(size_t idx)
902                 {
903                     import std.array : empty;
904                     static if (idx < nT)
905                         alias GetItem = Alias!(Types[idx]);
906                     else static if (allNames[idx - nT].empty)
907                         alias GetItem = AliasSeq!();
908                     else
909                         alias GetItem = Alias!(allNames[idx - nT]);
910                 }
911 
912                 import std.range : roundRobin, iota;
913                 alias NewTupleT = Tuple!(staticMap!(GetItem, aliasSeqOf!(
914                         roundRobin(iota(nT), iota(nT, 2*nT)))));
915                 return *(() @trusted => cast(NewTupleT*)&this)();
916             }
917         }
918 
919         ///
920         static if (Specs.length == 0) @safe unittest
921         {
922             auto t0 = tuple(4, "hello");
923 
924             auto t0Named = t0.rename!("val", "tag");
925             assert(t0Named.val == 4);
926             assert(t0Named.tag == "hello");
927 
928             Tuple!(float, "dat", size_t[2], "pos") t1;
929             t1.pos = [2, 1];
930             auto t1Named = t1.rename!"height";
931             t1Named.height = 3.4f;
932             assert(t1Named.height == 3.4f);
933             assert(t1Named.pos == [2, 1]);
934             t1Named.rename!"altitude".altitude = 5;
935             assert(t1Named.height == 5);
936 
937             Tuple!(int, "a", int, int, "c") t2;
938             t2 = tuple(3,4,5);
939             auto t2Named = t2.rename!("", "b");
940             // "a" no longer has a name
941             static assert(!hasMember!(typeof(t2Named), "a"));
942             assert(t2Named[0] == 3);
943             assert(t2Named.b == 4);
944             assert(t2Named.c == 5);
945 
946             // not allowed to specify more names than the tuple has members
947             static assert(!__traits(compiles, t2.rename!("a","b","c","d")));
948 
949             // use it in a range pipeline
950             import std.range : iota, zip;
951             import std.algorithm.iteration : map, sum;
952             auto res = zip(iota(1, 4), iota(10, 13))
953                 .map!(t => t.rename!("a", "b"))
954                 .map!(t => t.a * t.b)
955                 .sum;
956             assert(res == 68);
957         }
958 
959         /**
960          * Overload of $(LREF _rename) that takes an associative array
961          * `translate` as a template parameter, where the keys are
962          * either the names or indices of the members to be changed
963          * and the new names are the corresponding values.
964          * Every key in `translate` must be the name of a member of the
965          * $(LREF tuple).
966          * The same rules for empty strings apply as for the variadic
967          * template overload of $(LREF _rename).
968         */
969         ref rename(alias translate)()
970         if (is(typeof(translate) : V[K], V, K) && isSomeString!V &&
971                 (isSomeString!K || is(K : size_t)))
972         {
973             import std.range : ElementType;
974             static if (isSomeString!(ElementType!(typeof(translate.keys))))
975             {
976                 {
977                     import std.conv : to;
978                     import std.algorithm.iteration : filter;
979                     import std.algorithm.searching : canFind;
980                     enum notFound = translate.keys
981                         .filter!(k => fieldNames.canFind(k) == -1);
982                     static assert(notFound.empty, "Cannot find members "
983                         ~ notFound.to!string ~ " in type "
984                         ~ typeof(this).stringof);
985                 }
986                 return this.rename!(aliasSeqOf!(
987                     {
988                         import std.array : empty;
989                         auto names = [fieldNames];
990                         foreach (ref n; names)
991                             if (!n.empty)
992                                 if (auto p = n in translate)
993                                     n = *p;
994                         return names;
995                     }()));
996             }
997             else
998             {
999                 {
1000                     import std.algorithm.iteration : filter;
1001                     import std.conv : to;
1002                     enum invalid = translate.keys.
1003                         filter!(k => k < 0 || k >= this.length);
1004                     static assert(invalid.empty, "Indices " ~ invalid.to!string
1005                         ~ " are out of bounds for tuple with length "
1006                         ~ this.length.to!string);
1007                 }
1008                 return this.rename!(aliasSeqOf!(
1009                     {
1010                         auto names = [fieldNames];
1011                         foreach (k, v; translate)
1012                             names[k] = v;
1013                         return names;
1014                     }()));
1015             }
1016         }
1017 
1018         ///
1019         static if (Specs.length == 0) @safe unittest
1020         {
1021             //replacing names by their current name
1022 
1023             Tuple!(float, "dat", size_t[2], "pos") t1;
1024             t1.pos = [2, 1];
1025             auto t1Named = t1.rename!(["dat": "height"]);
1026             t1Named.height = 3.4;
1027             assert(t1Named.pos == [2, 1]);
1028             t1Named.rename!(["height": "altitude"]).altitude = 5;
1029             assert(t1Named.height == 5);
1030 
1031             Tuple!(int, "a", int, "b") t2;
1032             t2 = tuple(3, 4);
1033             auto t2Named = t2.rename!(["a": "b", "b": "c"]);
1034             assert(t2Named.b == 3);
1035             assert(t2Named.c == 4);
1036         }
1037 
1038         ///
1039         static if (Specs.length == 0) @safe unittest
1040         {
1041             //replace names by their position
1042 
1043             Tuple!(float, "dat", size_t[2], "pos") t1;
1044             t1.pos = [2, 1];
1045             auto t1Named = t1.rename!([0: "height"]);
1046             t1Named.height = 3.4;
1047             assert(t1Named.pos == [2, 1]);
1048             t1Named.rename!([0: "altitude"]).altitude = 5;
1049             assert(t1Named.height == 5);
1050 
1051             Tuple!(int, "a", int, "b", int, "c") t2;
1052             t2 = tuple(3, 4, 5);
1053             auto t2Named = t2.rename!([0: "c", 2: "a"]);
1054             assert(t2Named.a == 5);
1055             assert(t2Named.b == 4);
1056             assert(t2Named.c == 3);
1057         }
1058 
1059         static if (Specs.length == 0) @safe unittest
1060         {
1061             //check that empty translations work fine
1062             enum string[string] a0 = null;
1063             enum string[int] a1 = null;
1064             Tuple!(float, "a", float, "b") t0;
1065 
1066             auto t1 = t0.rename!a0;
1067 
1068             t1.a = 3;
1069             t1.b = 4;
1070             auto t2 = t0.rename!a1;
1071             t2.a = 3;
1072             t2.b = 4;
1073             auto t3 = t0.rename;
1074             t3.a = 3;
1075             t3.b = 4;
1076         }
1077 
1078         /**
1079          * Takes a slice by-reference of this `Tuple`.
1080          *
1081          * Params:
1082          *     from = A `size_t` designating the starting position of the slice.
1083          *     to = A `size_t` designating the ending position (exclusive) of the slice.
1084          *
1085          * Returns:
1086          *     A new `Tuple` that is a slice from `[from, to$(RPAREN)` of the original.
1087          *     It has the same types and values as the range `[from, to$(RPAREN)` in
1088          *     the original.
1089          */
1090         @property
1091         ref inout(Tuple!(sliceSpecs!(from, to))) slice(size_t from, size_t to)() inout @trusted
1092         if (from <= to && to <= Types.length)
1093         {
1094             static assert(
1095                 (typeof(this).alignof % typeof(return).alignof == 0) &&
1096                 (expand[from].offsetof % typeof(return).alignof == 0),
1097                 "Slicing by reference is impossible because of an alignment mistmatch. (See Phobos issue #15645.)");
1098 
1099             return *cast(typeof(return)*) &(field[from]);
1100         }
1101 
1102         ///
1103         static if (Specs.length == 0) @safe unittest
1104         {
1105             Tuple!(int, string, float, double) a;
1106             a[1] = "abc";
1107             a[2] = 4.5;
1108             auto s = a.slice!(1, 3);
1109             static assert(is(typeof(s) == Tuple!(string, float)));
1110             assert(s[0] == "abc" && s[1] == 4.5);
1111 
1112             // Phobos issue #15645
1113             Tuple!(int, short, bool, double) b;
1114             static assert(!__traits(compiles, b.slice!(2, 4)));
1115         }
1116 
1117         /**
1118             Creates a hash of this `Tuple`.
1119 
1120             Returns:
1121                 A `size_t` representing the hash of this `Tuple`.
1122          */
1123         size_t toHash() const nothrow @trusted
1124         {
1125             size_t h = 0;
1126             foreach (i, T; Types)
1127                 h += typeid(T).getHash(cast(const void*)&field[i]);
1128             return h;
1129         }
1130 
1131         ///
1132         template toString()
1133         {
1134             /**
1135              * Converts to string.
1136              *
1137              * Returns:
1138              *     The string representation of this `Tuple`.
1139              */
1140             string toString()() const
1141             {
1142                 import std.array : appender;
1143                 auto app = appender!string();
1144                 this.toString((const(char)[] chunk) => app ~= chunk);
1145                 return app.data;
1146             }
1147 
1148             import std.format : FormatSpec;
1149 
1150             /**
1151              * Formats `Tuple` with either `%s`, `%(inner%)` or `%(inner%|sep%)`.
1152              *
1153              * $(TABLE2 Formats supported by Tuple,
1154              * $(THEAD Format, Description)
1155              * $(TROW $(P `%s`), $(P Format like `Tuple!(types)(elements formatted with %s each)`.))
1156              * $(TROW $(P `%(inner%)`), $(P The format `inner` is applied the expanded `Tuple`, so
1157              *      it may contain as many formats as the `Tuple` has fields.))
1158              * $(TROW $(P `%(inner%|sep%)`), $(P The format `inner` is one format, that is applied
1159              *      on all fields of the `Tuple`. The inner format must be compatible to all
1160              *      of them.)))
1161              * ---
1162              *  Tuple!(int, double)[3] tupList = [ tuple(1, 1.0), tuple(2, 4.0), tuple(3, 9.0) ];
1163              *
1164              *  // Default format
1165              *  assert(format("%s", tuple("a", 1)) == `Tuple!(string, int)("a", 1)`);
1166              *
1167              *  // One Format for each individual component
1168              *  assert(format("%(%#x v %.4f w %#x%)", tuple(1, 1.0, 10))         == `0x1 v 1.0000 w 0xa`);
1169              *  assert(format(  "%#x v %.4f w %#x"  , tuple(1, 1.0, 10).expand)  == `0x1 v 1.0000 w 0xa`);
1170              *
1171              *  // One Format for all components
1172              *  assert(format("%(>%s<%| & %)", tuple("abc", 1, 2.3, [4, 5])) == `>abc< & >1< & >2.3< & >[4, 5]<`);
1173              *
1174              *  // Array of Tuples
1175              *  assert(format("%(%(f(%d) = %.1f%);  %)", tupList) == `f(1) = 1.0;  f(2) = 4.0;  f(3) = 9.0`);
1176              *
1177              *
1178              *  // Error: %( %) missing.
1179              *  assertThrown!FormatException(
1180              *      format("%d, %f", tuple(1, 2.0)) == `1, 2.0`
1181              *  );
1182              *
1183              *  // Error: %( %| %) missing.
1184              *  assertThrown!FormatException(
1185              *      format("%d", tuple(1, 2)) == `1, 2`
1186              *  );
1187              *
1188              *  // Error: %d inadequate for double.
1189              *  assertThrown!FormatException(
1190              *      format("%(%d%|, %)", tuple(1, 2.0)) == `1, 2.0`
1191              *  );
1192              * ---
1193              */
1194             void toString(DG)(scope DG sink) const
1195             {
1196                 toString(sink, FormatSpec!char());
1197             }
1198 
1199             /// ditto
1200             void toString(DG, Char)(scope DG sink, FormatSpec!Char fmt) const
1201             {
1202                 import std.format : formatElement, formattedWrite, FormatException;
1203                 if (fmt.nested)
1204                 {
1205                     if (fmt.sep)
1206                     {
1207                         foreach (i, Type; Types)
1208                         {
1209                             static if (i > 0)
1210                             {
1211                                 sink(fmt.sep);
1212                             }
1213                             // TODO: Change this once formattedWrite() works for shared objects.
1214                             static if (is(Type == class) && is(Type == shared))
1215                             {
1216                                 sink(Type.stringof);
1217                             }
1218                             else
1219                             {
1220                                 formattedWrite(sink, fmt.nested, this.field[i]);
1221                             }
1222                         }
1223                     }
1224                     else
1225                     {
1226                         formattedWrite(sink, fmt.nested, staticMap!(sharedToString, this.expand));
1227                     }
1228                 }
1229                 else if (fmt.spec == 's')
1230                 {
1231                     enum header = Unqual!(typeof(this)).stringof ~ "(",
1232                          footer = ")",
1233                          separator = ", ";
1234                     sink(header);
1235                     foreach (i, Type; Types)
1236                     {
1237                         static if (i > 0)
1238                         {
1239                             sink(separator);
1240                         }
1241                         // TODO: Change this once formatElement() works for shared objects.
1242                         static if (is(Type == class) && is(Type == shared))
1243                         {
1244                             sink(Type.stringof);
1245                         }
1246                         else
1247                         {
1248                             FormatSpec!Char f;
1249                             formatElement(sink, field[i], f);
1250                         }
1251                     }
1252                     sink(footer);
1253                 }
1254                 else
1255                 {
1256                     throw new FormatException(
1257                         "Expected '%s' or '%(...%)' or '%(...%|...%)' format specifier for type '" ~
1258                             Unqual!(typeof(this)).stringof ~ "', not '%" ~ fmt.spec ~ "'.");
1259                 }
1260             }
1261         }
1262     }
1263 }
1264 
1265 ///
1266 @safe unittest
1267 {
1268     Tuple!(int, int) point;
1269     // assign coordinates
1270     point[0] = 5;
1271     point[1] = 6;
1272     // read coordinates
1273     auto x = point[0];
1274     auto y = point[1];
1275 }
1276 
1277 /**
1278     `Tuple` members can be named. It is legal to mix named and unnamed
1279     members. The method above is still applicable to all fields.
1280  */
1281 @safe unittest
1282 {
1283     alias Entry = Tuple!(int, "index", string, "value");
1284     Entry e;
1285     e.index = 4;
1286     e.value = "Hello";
1287     assert(e[1] == "Hello");
1288     assert(e[0] == 4);
1289 }
1290 
1291 /**
1292     A `Tuple` with named fields is a distinct type from a `Tuple` with unnamed
1293     fields, i.e. each naming imparts a separate type for the `Tuple`. Two
1294     `Tuple`s differing in naming only are still distinct, even though they
1295     might have the same structure.
1296  */
1297 @safe unittest
1298 {
1299     Tuple!(int, "x", int, "y") point1;
1300     Tuple!(int, int) point2;
1301     assert(!is(typeof(point1) == typeof(point2)));
1302 }
1303 
1304 /**
1305     Creates a copy of a $(LREF Tuple) with its fields in _reverse order.
1306 
1307     Params:
1308         t = The `Tuple` to copy.
1309 
1310     Returns:
1311         A new `Tuple`.
1312  */
1313 auto reverse(T)(T t)
1314     if (isTuple!T)
1315 {
1316     import std.meta : Reverse;
1317     // @@@BUG@@@ Cannot be an internal function due to forward reference issues.
1318 
1319     // @@@BUG@@@ 9929 Need 'this' when calling template with expanded tuple
1320     // return tuple(Reverse!(t.expand));
1321 
1322     ReverseTupleType!T result;
1323     auto tup = t.expand;
1324     result.expand = Reverse!tup;
1325     return result;
1326 }
1327 
1328 ///
1329 @safe unittest
1330 {
1331     auto tup = tuple(1, "2");
1332     assert(tup.reverse == tuple("2", 1));
1333 }
1334 
1335 /* Get a Tuple type with the reverse specification of Tuple T. */
1336 private template ReverseTupleType(T)
1337     if (isTuple!T)
1338 {
1339     static if (is(T : Tuple!A, A...))
1340         alias ReverseTupleType = Tuple!(ReverseTupleSpecs!A);
1341 }
1342 
1343 /* Reverse the Specs of a Tuple. */
1344 private template ReverseTupleSpecs(T...)
1345 {
1346     static if (T.length > 1)
1347     {
1348         static if (is(typeof(T[$-1]) : string))
1349         {
1350             alias ReverseTupleSpecs = AliasSeq!(T[$-2], T[$-1], ReverseTupleSpecs!(T[0 .. $-2]));
1351         }
1352         else
1353         {
1354             alias ReverseTupleSpecs = AliasSeq!(T[$-1], ReverseTupleSpecs!(T[0 .. $-1]));
1355         }
1356     }
1357     else
1358     {
1359         alias ReverseTupleSpecs = T;
1360     }
1361 }
1362 
1363 // ensure that internal Tuple unittests are compiled
1364 @safe unittest
1365 {
1366     Tuple!() t;
1367 }
1368 
1369 @safe unittest
1370 {
1371     import std.conv;
1372     {
1373         Tuple!(int, "a", int, "b") nosh;
1374         static assert(nosh.length == 2);
1375         nosh.a = 5;
1376         nosh.b = 6;
1377         assert(nosh.a == 5);
1378         assert(nosh.b == 6);
1379     }
1380     {
1381         Tuple!(short, double) b;
1382         static assert(b.length == 2);
1383         b[1] = 5;
1384         auto a = Tuple!(int, real)(b);
1385         assert(a[0] == 0 && a[1] == 5);
1386         a = Tuple!(int, real)(1, 2);
1387         assert(a[0] == 1 && a[1] == 2);
1388         auto c = Tuple!(int, "a", double, "b")(a);
1389         assert(c[0] == 1 && c[1] == 2);
1390     }
1391     {
1392         Tuple!(int, real) nosh;
1393         nosh[0] = 5;
1394         nosh[1] = 0;
1395         assert(nosh[0] == 5 && nosh[1] == 0);
1396         assert(nosh.to!string == "Tuple!(int, real)(5, 0)", nosh.to!string);
1397         Tuple!(int, int) yessh;
1398         nosh = yessh;
1399     }
1400     {
1401         class A {}
1402         Tuple!(int, shared A) nosh;
1403         nosh[0] = 5;
1404         assert(nosh[0] == 5 && nosh[1] is null);
1405         assert(nosh.to!string == "Tuple!(int, shared(A))(5, shared(A))");
1406     }
1407     {
1408         Tuple!(int, string) t;
1409         t[0] = 10;
1410         t[1] = "str";
1411         assert(t[0] == 10 && t[1] == "str");
1412         assert(t.to!string == `Tuple!(int, string)(10, "str")`, t.to!string);
1413     }
1414     {
1415         Tuple!(int, "a", double, "b") x;
1416         static assert(x.a.offsetof == x[0].offsetof);
1417         static assert(x.b.offsetof == x[1].offsetof);
1418         x.b = 4.5;
1419         x.a = 5;
1420         assert(x[0] == 5 && x[1] == 4.5);
1421         assert(x.a == 5 && x.b == 4.5);
1422     }
1423     // indexing
1424     {
1425         Tuple!(int, real) t;
1426         static assert(is(typeof(t[0]) == int));
1427         static assert(is(typeof(t[1]) == real));
1428         int* p0 = &t[0];
1429         real* p1 = &t[1];
1430         t[0] = 10;
1431         t[1] = -200.0L;
1432         assert(*p0 == t[0]);
1433         assert(*p1 == t[1]);
1434     }
1435     // slicing
1436     {
1437         Tuple!(int, "x", real, "y", double, "z", string) t;
1438         t[0] = 10;
1439         t[1] = 11;
1440         t[2] = 12;
1441         t[3] = "abc";
1442         auto a = t.slice!(0, 3);
1443         assert(a.length == 3);
1444         assert(a.x == t.x);
1445         assert(a.y == t.y);
1446         assert(a.z == t.z);
1447         auto b = t.slice!(2, 4);
1448         assert(b.length == 2);
1449         assert(b.z == t.z);
1450         assert(b[1] == t[3]);
1451     }
1452     // nesting
1453     {
1454         Tuple!(Tuple!(int, real), Tuple!(string, "s")) t;
1455         static assert(is(typeof(t[0]) == Tuple!(int, real)));
1456         static assert(is(typeof(t[1]) == Tuple!(string, "s")));
1457         static assert(is(typeof(t[0][0]) == int));
1458         static assert(is(typeof(t[0][1]) == real));
1459         static assert(is(typeof(t[1].s) == string));
1460         t[0] = tuple(10, 20.0L);
1461         t[1].s = "abc";
1462         assert(t[0][0] == 10);
1463         assert(t[0][1] == 20.0L);
1464         assert(t[1].s == "abc");
1465     }
1466     // non-POD
1467     {
1468         static struct S
1469         {
1470             int count;
1471             this(this) { ++count; }
1472             ~this() { --count; }
1473             void opAssign(S rhs) { count = rhs.count; }
1474         }
1475         Tuple!(S, S) ss;
1476         Tuple!(S, S) ssCopy = ss;
1477         assert(ssCopy[0].count == 1);
1478         assert(ssCopy[1].count == 1);
1479         ssCopy[1] = ssCopy[0];
1480         assert(ssCopy[1].count == 2);
1481     }
1482     // bug 2800
1483     {
1484         static struct R
1485         {
1486             Tuple!(int, int) _front;
1487             @property ref Tuple!(int, int) front() return { return _front;  }
1488             @property bool empty() { return _front[0] >= 10; }
1489             void popFront() { ++_front[0]; }
1490         }
1491         foreach (a; R())
1492         {
1493             static assert(is(typeof(a) == Tuple!(int, int)));
1494             assert(0 <= a[0] && a[0] < 10);
1495             assert(a[1] == 0);
1496         }
1497     }
1498     // Construction with compatible elements
1499     {
1500         auto t1 = Tuple!(int, double)(1, 1);
1501 
1502         // 8702
1503         auto t8702a = tuple(tuple(1));
1504         auto t8702b = Tuple!(Tuple!(int))(Tuple!(int)(1));
1505     }
1506     // Construction with compatible tuple
1507     {
1508         Tuple!(int, int) x;
1509         x[0] = 10;
1510         x[1] = 20;
1511         Tuple!(int, "a", double, "b") y = x;
1512         assert(y.a == 10);
1513         assert(y.b == 20);
1514         // incompatible
1515         static assert(!__traits(compiles, Tuple!(int, int)(y)));
1516     }
1517     // 6275
1518     {
1519         const int x = 1;
1520         auto t1 = tuple(x);
1521         alias T = Tuple!(const(int));
1522         auto t2 = T(1);
1523     }
1524     // 9431
1525     {
1526         alias T = Tuple!(int[1][]);
1527         auto t = T([[10]]);
1528     }
1529     // 7666
1530     {
1531         auto tup = tuple(1, "2");
1532         assert(tup.reverse == tuple("2", 1));
1533     }
1534     {
1535         Tuple!(int, "x", string, "y") tup = tuple(1, "2");
1536         auto rev = tup.reverse;
1537         assert(rev == tuple("2", 1));
1538         assert(rev.x == 1 && rev.y == "2");
1539     }
1540     {
1541         Tuple!(wchar, dchar, int, "x", string, "y", char, byte, float) tup;
1542         tup = tuple('a', 'b', 3, "4", 'c', cast(byte) 0x0D, 0.00);
1543         auto rev = tup.reverse;
1544         assert(rev == tuple(0.00, cast(byte) 0x0D, 'c', "4", 3, 'b', 'a'));
1545         assert(rev.x == 3 && rev.y == "4");
1546     }
1547 }
1548 @safe unittest
1549 {
1550     // opEquals
1551     {
1552         struct Equ1 { bool opEquals(Equ1) { return true; } }
1553         auto  tm1 = tuple(Equ1.init);
1554         const tc1 = tuple(Equ1.init);
1555         static assert( is(typeof(tm1 == tm1)));
1556         static assert(!is(typeof(tm1 == tc1)));
1557         static assert(!is(typeof(tc1 == tm1)));
1558         static assert(!is(typeof(tc1 == tc1)));
1559 
1560         struct Equ2 { bool opEquals(const Equ2) const { return true; } }
1561         auto  tm2 = tuple(Equ2.init);
1562         const tc2 = tuple(Equ2.init);
1563         static assert( is(typeof(tm2 == tm2)));
1564         static assert( is(typeof(tm2 == tc2)));
1565         static assert( is(typeof(tc2 == tm2)));
1566         static assert( is(typeof(tc2 == tc2)));
1567 
1568         struct Equ3 { bool opEquals(T)(T) { return true; } }
1569         auto  tm3 = tuple(Equ3.init);           // bugzilla 8686
1570         const tc3 = tuple(Equ3.init);
1571         static assert( is(typeof(tm3 == tm3)));
1572         static assert( is(typeof(tm3 == tc3)));
1573         static assert(!is(typeof(tc3 == tm3)));
1574         static assert(!is(typeof(tc3 == tc3)));
1575 
1576         struct Equ4 { bool opEquals(T)(T) const { return true; } }
1577         auto  tm4 = tuple(Equ4.init);
1578         const tc4 = tuple(Equ4.init);
1579         static assert( is(typeof(tm4 == tm4)));
1580         static assert( is(typeof(tm4 == tc4)));
1581         static assert( is(typeof(tc4 == tm4)));
1582         static assert( is(typeof(tc4 == tc4)));
1583     }
1584     // opCmp
1585     {
1586         struct Cmp1 { int opCmp(Cmp1) { return 0; } }
1587         auto  tm1 = tuple(Cmp1.init);
1588         const tc1 = tuple(Cmp1.init);
1589         static assert( is(typeof(tm1 < tm1)));
1590         static assert(!is(typeof(tm1 < tc1)));
1591         static assert(!is(typeof(tc1 < tm1)));
1592         static assert(!is(typeof(tc1 < tc1)));
1593 
1594         struct Cmp2 { int opCmp(const Cmp2) const { return 0; } }
1595         auto  tm2 = tuple(Cmp2.init);
1596         const tc2 = tuple(Cmp2.init);
1597         static assert( is(typeof(tm2 < tm2)));
1598         static assert( is(typeof(tm2 < tc2)));
1599         static assert( is(typeof(tc2 < tm2)));
1600         static assert( is(typeof(tc2 < tc2)));
1601 
1602         struct Cmp3 { int opCmp(T)(T) { return 0; } }
1603         auto  tm3 = tuple(Cmp3.init);
1604         const tc3 = tuple(Cmp3.init);
1605         static assert( is(typeof(tm3 < tm3)));
1606         static assert( is(typeof(tm3 < tc3)));
1607         static assert(!is(typeof(tc3 < tm3)));
1608         static assert(!is(typeof(tc3 < tc3)));
1609 
1610         struct Cmp4 { int opCmp(T)(T) const { return 0; } }
1611         auto  tm4 = tuple(Cmp4.init);
1612         const tc4 = tuple(Cmp4.init);
1613         static assert( is(typeof(tm4 < tm4)));
1614         static assert( is(typeof(tm4 < tc4)));
1615         static assert( is(typeof(tc4 < tm4)));
1616         static assert( is(typeof(tc4 < tc4)));
1617     }
1618     // Bugzilla 14890
1619     static void test14890(inout int[] dummy)
1620     {
1621         alias V = Tuple!(int, int);
1622 
1623                     V mv;
1624               const V cv;
1625           immutable V iv;
1626               inout V wv;   // OK <- NG
1627         inout const V wcv;  // OK <- NG
1628 
1629         foreach (v1; AliasSeq!(mv, cv, iv, wv, wcv))
1630         foreach (v2; AliasSeq!(mv, cv, iv, wv, wcv))
1631         {
1632             assert(!(v1 < v2));
1633         }
1634     }
1635     {
1636         int[2] ints = [ 1, 2 ];
1637         Tuple!(int, int) t = ints;
1638         assert(t[0] == 1 && t[1] == 2);
1639         Tuple!(long, uint) t2 = ints;
1640         assert(t2[0] == 1 && t2[1] == 2);
1641     }
1642 }
1643 @safe unittest
1644 {
1645     auto t1 = Tuple!(int, "x", string, "y")(1, "a");
1646     assert(t1.x == 1);
1647     assert(t1.y == "a");
1648     void foo(Tuple!(int, string) t2) {}
1649     foo(t1);
1650 
1651     Tuple!(int, int)[] arr;
1652     arr ~= tuple(10, 20); // OK
1653     arr ~= Tuple!(int, "x", int, "y")(10, 20); // NG -> OK
1654 
1655     static assert(is(typeof(Tuple!(int, "x", string, "y").tupleof) ==
1656                      typeof(Tuple!(int,      string     ).tupleof)));
1657 }
1658 @safe unittest
1659 {
1660     // Bugzilla 10686
1661     immutable Tuple!(int) t1;
1662     auto r1 = t1[0]; // OK
1663     immutable Tuple!(int, "x") t2;
1664     auto r2 = t2[0]; // error
1665 }
1666 @safe unittest
1667 {
1668     import std.exception : assertCTFEable;
1669 
1670     // Bugzilla 10218
1671     assertCTFEable!(
1672     {
1673         auto t = tuple(1);
1674         t = tuple(2);   // assignment
1675     });
1676 }
1677 @safe unittest
1678 {
1679     class Foo{}
1680     Tuple!(immutable(Foo)[]) a;
1681 }
1682 
1683 @safe unittest
1684 {
1685     //Test non-assignable
1686     static struct S
1687     {
1688         int* p;
1689     }
1690     alias IS = immutable S;
1691     static assert(!isAssignable!IS);
1692 
1693     auto s = IS.init;
1694 
1695     alias TIS = Tuple!IS;
1696     TIS a = tuple(s);
1697     TIS b = a;
1698 
1699     alias TISIS = Tuple!(IS, IS);
1700     TISIS d = tuple(s, s);
1701     IS[2] ss;
1702     TISIS e = TISIS(ss);
1703 }
1704 
1705 // Bugzilla #9819
1706 @safe unittest
1707 {
1708     alias T = Tuple!(int, "x", double, "foo");
1709     static assert(T.fieldNames[0] == "x");
1710     static assert(T.fieldNames[1] == "foo");
1711 
1712     alias Fields = Tuple!(int, "id", string, float);
1713     static assert(Fields.fieldNames == AliasSeq!("id", "", ""));
1714 }
1715 
1716 // Bugzilla 13837
1717 @safe unittest
1718 {
1719     // New behaviour, named arguments.
1720     static assert(is(
1721         typeof(tuple!("x")(1)) == Tuple!(int, "x")));
1722     static assert(is(
1723         typeof(tuple!("x")(1.0)) == Tuple!(double, "x")));
1724     static assert(is(
1725         typeof(tuple!("x")("foo")) == Tuple!(string, "x")));
1726     static assert(is(
1727         typeof(tuple!("x", "y")(1, 2.0)) == Tuple!(int, "x", double, "y")));
1728 
1729     auto a = tuple!("a", "b", "c")("1", 2, 3.0f);
1730     static assert(is(typeof(a.a) == string));
1731     static assert(is(typeof(a.b) == int));
1732     static assert(is(typeof(a.c) == float));
1733 
1734     // Old behaviour, but with explicit type parameters.
1735     static assert(is(
1736         typeof(tuple!(int, double)(1, 2.0)) == Tuple!(int, double)));
1737     static assert(is(
1738         typeof(tuple!(const int)(1)) == Tuple!(const int)));
1739     static assert(is(
1740         typeof(tuple()) == Tuple!()));
1741 
1742     // Nonsensical behaviour
1743     static assert(!__traits(compiles, tuple!(1)(2)));
1744     static assert(!__traits(compiles, tuple!("x")(1, 2)));
1745     static assert(!__traits(compiles, tuple!("x", "y")(1)));
1746     static assert(!__traits(compiles, tuple!("x")()));
1747     static assert(!__traits(compiles, tuple!("x", int)(2)));
1748 }
1749 
1750 @safe unittest
1751 {
1752     class C {}
1753     Tuple!(Rebindable!(const C)) a;
1754     Tuple!(const C) b;
1755     a = b;
1756 }
1757 
1758 @nogc @safe unittest
1759 {
1760     alias T = Tuple!(string, "s");
1761     T x;
1762     x = T.init;
1763 }
1764 
1765 @safe unittest
1766 {
1767     import std.format : format, FormatException;
1768     import std.exception : assertThrown;
1769 
1770     // enum tupStr = tuple(1, 1.0).toString; // toString is *impure*.
1771     //static assert(tupStr == `Tuple!(int, double)(1, 1)`);
1772 
1773     Tuple!(int, double)[3] tupList = [ tuple(1, 1.0), tuple(2, 4.0), tuple(3, 9.0) ];
1774 
1775     // Default format
1776     assert(format("%s", tuple("a", 1)) == `Tuple!(string, int)("a", 1)`);
1777 
1778     // One Format for each individual component
1779     assert(format("%(%#x v %.4f w %#x%)", tuple(1, 1.0, 10))         == `0x1 v 1.0000 w 0xa`);
1780     assert(format(  "%#x v %.4f w %#x"  , tuple(1, 1.0, 10).expand)  == `0x1 v 1.0000 w 0xa`);
1781 
1782     // One Format for all components
1783     assert(format("%(>%s<%| & %)", tuple("abc", 1, 2.3, [4, 5])) == `>abc< & >1< & >2.3< & >[4, 5]<`);
1784 
1785     // Array of Tuples
1786     assert(format("%(%(f(%d) = %.1f%);  %)", tupList) == `f(1) = 1.0;  f(2) = 4.0;  f(3) = 9.0`);
1787 
1788 
1789     // Error: %( %) missing.
1790     assertThrown!FormatException(
1791         format("%d, %f", tuple(1, 2.0)) == `1, 2.0`
1792     );
1793 
1794     // Error: %( %| %) missing.
1795     assertThrown!FormatException(
1796         format("%d", tuple(1, 2)) == `1, 2`
1797     );
1798 
1799     // Error: %d inadequate for double
1800     assertThrown!FormatException(
1801         format("%(%d%|, %)", tuple(1, 2.0)) == `1, 2.0`
1802     );
1803 }
1804 
1805 /**
1806     Constructs a $(LREF Tuple) object instantiated and initialized according to
1807     the given arguments.
1808 
1809     Params:
1810         Names = An optional list of strings naming each successive field of the `Tuple`.
1811                 Each name matches up with the corresponding field given by `Args`.
1812                 A name does not have to be provided for every field, but as
1813                 the names must proceed in order, it is not possible to skip
1814                 one field and name the next after it.
1815 */
1816 template tuple(Names...)
1817 {
1818     /**
1819     Params:
1820         args = Values to initialize the `Tuple` with. The `Tuple`'s type will
1821                be inferred from the types of the values given.
1822 
1823     Returns:
1824         A new `Tuple` with its type inferred from the arguments given.
1825      */
1826     auto tuple(Args...)(Args args)
1827     {
1828         static if (Names.length == 0)
1829         {
1830             // No specified names, just infer types from Args...
1831             return Tuple!Args(args);
1832         }
1833         else static if (!is(typeof(Names[0]) : string))
1834         {
1835             // Names[0] isn't a string, must be explicit types.
1836             return Tuple!Names(args);
1837         }
1838         else
1839         {
1840             // Names[0] is a string, so must be specifying names.
1841             static assert(Names.length == Args.length,
1842                 "Insufficient number of names given.");
1843 
1844             // Interleave(a, b).and(c, d) == (a, c, b, d)
1845             // This is to get the interleaving of types and names for Tuple
1846             // e.g. Tuple!(int, "x", string, "y")
1847             template Interleave(A...)
1848             {
1849                 template and(B...) if (B.length == 1)
1850                 {
1851                     alias and = AliasSeq!(A[0], B[0]);
1852                 }
1853 
1854                 template and(B...) if (B.length != 1)
1855                 {
1856                     alias and = AliasSeq!(A[0], B[0],
1857                         Interleave!(A[1..$]).and!(B[1..$]));
1858                 }
1859             }
1860             return Tuple!(Interleave!(Args).and!(Names))(args);
1861         }
1862     }
1863 }
1864 
1865 ///
1866 @safe unittest
1867 {
1868     auto value = tuple(5, 6.7, "hello");
1869     assert(value[0] == 5);
1870     assert(value[1] == 6.7);
1871     assert(value[2] == "hello");
1872 
1873     // Field names can be provided.
1874     auto entry = tuple!("index", "value")(4, "Hello");
1875     assert(entry.index == 4);
1876     assert(entry.value == "Hello");
1877 }
1878 
1879 /**
1880     Returns $(D true) if and only if $(D T) is an instance of $(D std.typecons.Tuple).
1881 
1882     Params:
1883         T = The type to check.
1884 
1885     Returns:
1886         true if `T` is a `Tuple` type, false otherwise.
1887  */
1888 enum isTuple(T) = __traits(compiles,
1889                            {
1890                                void f(Specs...)(Tuple!Specs tup) {}
1891                                f(T.init);
1892                            } );
1893 
1894 ///
1895 @safe unittest
1896 {
1897     static assert(isTuple!(Tuple!()));
1898     static assert(isTuple!(Tuple!(int)));
1899     static assert(isTuple!(Tuple!(int, real, string)));
1900     static assert(isTuple!(Tuple!(int, "x", real, "y")));
1901     static assert(isTuple!(Tuple!(int, Tuple!(real), string)));
1902 }
1903 
1904 @safe unittest
1905 {
1906     static assert(isTuple!(const Tuple!(int)));
1907     static assert(isTuple!(immutable Tuple!(int)));
1908 
1909     static assert(!isTuple!(int));
1910     static assert(!isTuple!(const int));
1911 
1912     struct S {}
1913     static assert(!isTuple!(S));
1914 }
1915 
1916 // used by both Rebindable and UnqualRef
1917 private mixin template RebindableCommon(T, U, alias This)
1918     if (is(T == class) || is(T == interface) || isAssociativeArray!T)
1919 {
1920     private union
1921     {
1922         T original;
1923         U stripped;
1924     }
1925 
1926     @trusted pure nothrow @nogc
1927     {
1928         void opAssign(T another)
1929         {
1930             stripped = cast(U) another;
1931         }
1932 
1933         void opAssign(typeof(this) another)
1934         {
1935             stripped = another.stripped;
1936         }
1937 
1938         static if (is(T == const U) && is(T == const shared U))
1939         {
1940             // safely assign immutable to const / const shared
1941             void opAssign(This!(immutable U) another)
1942             {
1943                 stripped = another.stripped;
1944             }
1945         }
1946 
1947         this(T initializer)
1948         {
1949             opAssign(initializer);
1950         }
1951 
1952         @property inout(T) get() inout
1953         {
1954             return original;
1955         }
1956     }
1957 
1958     alias get this;
1959 }
1960 
1961 /**
1962 $(D Rebindable!(T)) is a simple, efficient wrapper that behaves just
1963 like an object of type $(D T), except that you can reassign it to
1964 refer to another object. For completeness, $(D Rebindable!(T)) aliases
1965 itself away to $(D T) if $(D T) is a non-const object type.
1966 
1967 You may want to use $(D Rebindable) when you want to have mutable
1968 storage referring to $(D const) objects, for example an array of
1969 references that must be sorted in place. $(D Rebindable) does not
1970 break the soundness of D's type system and does not incur any of the
1971 risks usually associated with $(D cast).
1972 
1973 Params:
1974     T = An object, interface, array slice type, or associative array type.
1975  */
1976 template Rebindable(T)
1977     if (is(T == class) || is(T == interface) || isDynamicArray!T || isAssociativeArray!T)
1978 {
1979     static if (is(T == const U, U) || is(T == immutable U, U))
1980     {
1981         static if (isDynamicArray!T)
1982         {
1983             import std.range.primitives : ElementEncodingType;
1984             alias Rebindable = const(ElementEncodingType!T)[];
1985         }
1986         else
1987         {
1988             struct Rebindable
1989             {
1990                 mixin RebindableCommon!(T, U, Rebindable);
1991             }
1992         }
1993     }
1994     else
1995     {
1996         alias Rebindable = T;
1997     }
1998 }
1999 
2000 ///Regular $(D const) object references cannot be reassigned.
2001 @system unittest
2002 {
2003     class Widget { int x; int y() const { return x; } }
2004     const a = new Widget;
2005     // Fine
2006     a.y();
2007     // error! can't modify const a
2008     // a.x = 5;
2009     // error! can't modify const a
2010     // a = new Widget;
2011 }
2012 
2013 /**
2014     However, $(D Rebindable!(Widget)) does allow reassignment,
2015     while otherwise behaving exactly like a $(D const Widget).
2016  */
2017 @system unittest
2018 {
2019     class Widget { int x; int y() const { return x; } }
2020     auto a = Rebindable!(const Widget)(new Widget);
2021     // Fine
2022     a.y();
2023     // error! can't modify const a
2024     // a.x = 5;
2025     // Fine
2026     a = new Widget;
2027 }
2028 
2029 @safe unittest // issue 16054
2030 {
2031     Rebindable!(immutable Object) r;
2032     static assert(__traits(compiles, r.get()));
2033     static assert(!__traits(compiles, &r.get()));
2034 }
2035 
2036 /**
2037 Convenience function for creating a $(D Rebindable) using automatic type
2038 inference.
2039 
2040 Params:
2041     obj = A reference to an object, interface, associative array, or an array slice
2042           to initialize the `Rebindable` with.
2043 
2044 Returns:
2045     A newly constructed `Rebindable` initialized with the given reference.
2046 */
2047 Rebindable!T rebindable(T)(T obj)
2048     if (is(T == class) || is(T == interface) || isDynamicArray!T || isAssociativeArray!T)
2049 {
2050     typeof(return) ret;
2051     ret = obj;
2052     return ret;
2053 }
2054 
2055 /**
2056 This function simply returns the $(D Rebindable) object passed in.  It's useful
2057 in generic programming cases when a given object may be either a regular
2058 $(D class) or a $(D Rebindable).
2059 
2060 Params:
2061     obj = An instance of Rebindable!T.
2062 
2063 Returns:
2064     `obj` without any modification.
2065 */
2066 Rebindable!T rebindable(T)(Rebindable!T obj)
2067 {
2068     return obj;
2069 }
2070 
2071 @system unittest
2072 {
2073     interface CI { int foo() const; }
2074     class C : CI {
2075       int foo() const { return 42; }
2076       @property int bar() const { return 23; }
2077     }
2078     Rebindable!(C) obj0;
2079     static assert(is(typeof(obj0) == C));
2080 
2081     Rebindable!(const(C)) obj1;
2082     static assert(is(typeof(obj1.get) == const(C)), typeof(obj1.get).stringof);
2083     static assert(is(typeof(obj1.stripped) == C));
2084     obj1 = new C;
2085     assert(obj1.get !is null);
2086     obj1 = new const(C);
2087     assert(obj1.get !is null);
2088 
2089     Rebindable!(immutable(C)) obj2;
2090     static assert(is(typeof(obj2.get) == immutable(C)));
2091     static assert(is(typeof(obj2.stripped) == C));
2092     obj2 = new immutable(C);
2093     assert(obj1.get !is null);
2094 
2095     // test opDot
2096     assert(obj2.foo() == 42);
2097     assert(obj2.bar == 23);
2098 
2099     interface I { final int foo() const { return 42; } }
2100     Rebindable!(I) obj3;
2101     static assert(is(typeof(obj3) == I));
2102 
2103     Rebindable!(const I) obj4;
2104     static assert(is(typeof(obj4.get) == const I));
2105     static assert(is(typeof(obj4.stripped) == I));
2106     static assert(is(typeof(obj4.foo()) == int));
2107     obj4 = new class I {};
2108 
2109     Rebindable!(immutable C) obj5i;
2110     Rebindable!(const C) obj5c;
2111     obj5c = obj5c;
2112     obj5c = obj5i;
2113     obj5i = obj5i;
2114     static assert(!__traits(compiles, obj5i = obj5c));
2115 
2116     // Test the convenience functions.
2117     auto obj5convenience = rebindable(obj5i);
2118     assert(obj5convenience is obj5i);
2119 
2120     auto obj6 = rebindable(new immutable(C));
2121     static assert(is(typeof(obj6) == Rebindable!(immutable C)));
2122     assert(obj6.foo() == 42);
2123 
2124     auto obj7 = rebindable(new C);
2125     CI interface1 = obj7;
2126     auto interfaceRebind1 = rebindable(interface1);
2127     assert(interfaceRebind1.foo() == 42);
2128 
2129     const interface2 = interface1;
2130     auto interfaceRebind2 = rebindable(interface2);
2131     assert(interfaceRebind2.foo() == 42);
2132 
2133     auto arr = [1,2,3,4,5];
2134     const arrConst = arr;
2135     assert(rebindable(arr) == arr);
2136     assert(rebindable(arrConst) == arr);
2137 
2138     // Issue 7654
2139     immutable(char[]) s7654;
2140     Rebindable!(typeof(s7654)) r7654 = s7654;
2141 
2142     foreach (T; AliasSeq!(char, wchar, char, int))
2143     {
2144         static assert(is(Rebindable!(immutable(T[])) == immutable(T)[]));
2145         static assert(is(Rebindable!(const(T[])) == const(T)[]));
2146         static assert(is(Rebindable!(T[]) == T[]));
2147     }
2148 
2149     // Issue 12046
2150     static assert(!__traits(compiles, Rebindable!(int[1])));
2151     static assert(!__traits(compiles, Rebindable!(const int[1])));
2152 
2153     // Pull request 3341
2154     Rebindable!(immutable int[int]) pr3341 = [123:345];
2155     assert(pr3341[123] == 345);
2156     immutable int[int] pr3341_aa = [321:543];
2157     pr3341 = pr3341_aa;
2158     assert(pr3341[321] == 543);
2159     assert(rebindable(pr3341_aa)[321] == 543);
2160 }
2161 
2162 /**
2163     Similar to $(D Rebindable!(T)) but strips all qualifiers from the reference as
2164     opposed to just constness / immutability. Primary intended use case is with
2165     shared (having thread-local reference to shared class data)
2166 
2167     Params:
2168         T = A class or interface type.
2169  */
2170 template UnqualRef(T)
2171     if (is(T == class) || is(T == interface))
2172 {
2173     static if (is(T == const U, U)
2174         || is(T == immutable U, U)
2175         || is(T == shared U, U)
2176         || is(T == const shared U, U))
2177     {
2178         struct UnqualRef
2179         {
2180             mixin RebindableCommon!(T, U, UnqualRef);
2181         }
2182     }
2183     else
2184     {
2185         alias UnqualRef = T;
2186     }
2187 }
2188 
2189 ///
2190 @system unittest
2191 {
2192     class Data {}
2193 
2194     static shared(Data) a;
2195     static UnqualRef!(shared Data) b;
2196 
2197     import core.thread;
2198 
2199     auto thread = new core.thread.Thread({
2200         a = new shared Data();
2201         b = new shared Data();
2202     });
2203 
2204     thread.start();
2205     thread.join();
2206 
2207     assert(a !is null);
2208     assert(b is null);
2209 }
2210 
2211 @safe unittest
2212 {
2213     class C { }
2214     alias T = UnqualRef!(const shared C);
2215     static assert(is(typeof(T.stripped) == C));
2216 }
2217 
2218 
2219 
2220 /**
2221   Order the provided members to minimize size while preserving alignment.
2222   Alignment is not always optimal for 80-bit reals, nor for structs declared
2223   as align(1).
2224 
2225   Params:
2226       E = A list of the types to be aligned, representing fields
2227           of an aggregate such as a `struct` or `class`.
2228 
2229       names = The names of the fields that are to be aligned.
2230 
2231   Returns:
2232       A string to be mixed in to an aggregate, such as a `struct` or `class`.
2233 */
2234 string alignForSize(E...)(const char[][] names...)
2235 {
2236     // Sort all of the members by .alignof.
2237     // BUG: Alignment is not always optimal for align(1) structs
2238     // or 80-bit reals or 64-bit primitives on x86.
2239     // TRICK: Use the fact that .alignof is always a power of 2,
2240     // and maximum 16 on extant systems. Thus, we can perform
2241     // a very limited radix sort.
2242     // Contains the members with .alignof = 64,32,16,8,4,2,1
2243 
2244     assert(E.length == names.length,
2245         "alignForSize: There should be as many member names as the types");
2246 
2247     string[7] declaration = ["", "", "", "", "", "", ""];
2248 
2249     foreach (i, T; E)
2250     {
2251         auto a = T.alignof;
2252         auto k = a >= 64? 0 : a >= 32? 1 : a >= 16? 2 : a >= 8? 3 : a >= 4? 4 : a >= 2? 5 : 6;
2253         declaration[k] ~= T.stringof ~ " " ~ names[i] ~ ";\n";
2254     }
2255 
2256     auto s = "";
2257     foreach (decl; declaration)
2258         s ~= decl;
2259     return s;
2260 }
2261 
2262 ///
2263 @safe unittest
2264 {
2265     struct Banner {
2266         mixin(alignForSize!(byte[6], double)(["name", "height"]));
2267     }
2268 }
2269 
2270 @safe unittest
2271 {
2272     enum x = alignForSize!(int[], char[3], short, double[5])("x", "y","z", "w");
2273     struct Foo { int x; }
2274     enum y = alignForSize!(ubyte, Foo, cdouble)("x", "y", "z");
2275 
2276     enum passNormalX = x == "double[5] w;\nint[] x;\nshort z;\nchar[3] y;\n";
2277     enum passNormalY = y == "cdouble z;\nFoo y;\nubyte x;\n";
2278 
2279     enum passAbnormalX = x == "int[] x;\ndouble[5] w;\nshort z;\nchar[3] y;\n";
2280     enum passAbnormalY = y == "Foo y;\ncdouble z;\nubyte x;\n";
2281     // ^ blame http://d.puremagic.com/issues/show_bug.cgi?id=231
2282 
2283     static assert(passNormalX || passAbnormalX && double.alignof <= (int[]).alignof);
2284     static assert(passNormalY || passAbnormalY && double.alignof <= int.alignof);
2285 }
2286 
2287 // Issue 12914
2288 @safe unittest
2289 {
2290     immutable string[] fieldNames = ["x", "y"];
2291     struct S
2292     {
2293         mixin(alignForSize!(byte, int)(fieldNames));
2294     }
2295 }
2296 
2297 /**
2298 Defines a value paired with a distinctive "null" state that denotes
2299 the absence of a value. If default constructed, a $(D
2300 Nullable!T) object starts in the null state. Assigning it renders it
2301 non-null. Calling $(D nullify) can nullify it again.
2302 
2303 Practically $(D Nullable!T) stores a $(D T) and a $(D bool).
2304  */
2305 struct Nullable(T)
2306 {
2307     private T _value;
2308     private bool _isNull = true;
2309 
2310 /**
2311 Constructor initializing $(D this) with $(D value).
2312 
2313 Params:
2314     value = The value to initialize this `Nullable` with.
2315  */
2316     this(inout T value) inout
2317     {
2318         _value = value;
2319         _isNull = false;
2320     }
2321 
2322     /**
2323       If they are both null, then they are equal. If one is null and the other
2324       is not, then they are not equal. If they are both non-null, then they are
2325       equal if their values are equal.
2326       */
2327     bool opEquals()(auto ref const(typeof(this)) rhs) const
2328     {
2329         if (_isNull)
2330             return rhs._isNull;
2331         if (rhs._isNull)
2332             return false;
2333         return _value == rhs._value;
2334     }
2335 
2336     /// Ditto
2337     bool opEquals(U)(auto ref const(U) rhs) const
2338     if (is(typeof(this.get == rhs)))
2339     {
2340         return _isNull ? false : rhs == _value;
2341     }
2342 
2343     ///
2344     @safe unittest
2345     {
2346         Nullable!int empty;
2347         Nullable!int a = 42;
2348         Nullable!int b = 42;
2349         Nullable!int c = 27;
2350 
2351         assert(empty == empty);
2352         assert(empty == Nullable!int.init);
2353         assert(empty != a);
2354         assert(empty != b);
2355         assert(empty != c);
2356 
2357         assert(a == b);
2358         assert(a != c);
2359 
2360         assert(empty != 42);
2361         assert(a == 42);
2362         assert(c != 42);
2363     }
2364 
2365     @safe unittest
2366     {
2367         // Test constness
2368         immutable Nullable!int a = 42;
2369         Nullable!int b = 42;
2370         immutable Nullable!int c = 29;
2371         Nullable!int d = 29;
2372         immutable e = 42;
2373         int f = 29;
2374         assert(a == a);
2375         assert(a == b);
2376         assert(a != c);
2377         assert(a != d);
2378         assert(a == e);
2379         assert(a != f);
2380 
2381         // Test rvalue
2382         assert(a == const Nullable!int(42));
2383         assert(a != Nullable!int(29));
2384     }
2385 
2386     // Issue 17482
2387     @system unittest
2388     {
2389         import std.variant : Variant;
2390         Nullable!Variant a = Variant(12);
2391         assert(a == 12);
2392         Nullable!Variant e;
2393         assert(e != 12);
2394     }
2395 
2396     template toString()
2397     {
2398         import std.format : FormatSpec, formatValue;
2399         // Needs to be a template because of DMD @@BUG@@ 13737.
2400         void toString()(scope void delegate(const(char)[]) sink, FormatSpec!char fmt)
2401         {
2402             if (isNull)
2403             {
2404                 sink.formatValue("Nullable.null", fmt);
2405             }
2406             else
2407             {
2408                 sink.formatValue(_value, fmt);
2409             }
2410         }
2411 
2412         // Issue 14940
2413         void toString()(scope void delegate(const(char)[]) @safe sink, FormatSpec!char fmt)
2414         {
2415             if (isNull)
2416             {
2417                 sink.formatValue("Nullable.null", fmt);
2418             }
2419             else
2420             {
2421                 sink.formatValue(_value, fmt);
2422             }
2423         }
2424     }
2425 
2426 /**
2427 Check if `this` is in the null state.
2428 
2429 Returns:
2430     true $(B iff) `this` is in the null state, otherwise false.
2431  */
2432     @property bool isNull() const @safe pure nothrow
2433     {
2434         return _isNull;
2435     }
2436 
2437 ///
2438 @system unittest
2439 {
2440     Nullable!int ni;
2441     assert(ni.isNull);
2442 
2443     ni = 0;
2444     assert(!ni.isNull);
2445 }
2446 
2447 // Issue 14940
2448 @safe unittest
2449 {
2450     import std.array : appender;
2451     import std.format : formattedWrite;
2452 
2453     auto app = appender!string();
2454     Nullable!int a = 1;
2455     formattedWrite(app, "%s", a);
2456     assert(app.data == "1");
2457 }
2458 
2459 /**
2460 Forces $(D this) to the null state.
2461  */
2462     void nullify()()
2463     {
2464         .destroy(_value);
2465         _isNull = true;
2466     }
2467 
2468 ///
2469 @safe unittest
2470 {
2471     Nullable!int ni = 0;
2472     assert(!ni.isNull);
2473 
2474     ni.nullify();
2475     assert(ni.isNull);
2476 }
2477 
2478 /**
2479 Assigns $(D value) to the internally-held state. If the assignment
2480 succeeds, $(D this) becomes non-null.
2481 
2482 Params:
2483     value = A value of type `T` to assign to this `Nullable`.
2484  */
2485     void opAssign()(T value)
2486     {
2487         _value = value;
2488         _isNull = false;
2489     }
2490 
2491 /**
2492     If this `Nullable` wraps a type that already has a null value
2493     (such as a pointer), then assigning the null value to this
2494     `Nullable` is no different than assigning any other value of
2495     type `T`, and the resulting code will look very strange. It
2496     is strongly recommended that this be avoided by instead using
2497     the version of `Nullable` that takes an additional `nullValue`
2498     template argument.
2499  */
2500 @safe unittest
2501 {
2502     //Passes
2503     Nullable!(int*) npi;
2504     assert(npi.isNull);
2505 
2506     //Passes?!
2507     npi = null;
2508     assert(!npi.isNull);
2509 }
2510 
2511 /**
2512 Gets the value. $(D this) must not be in the null state.
2513 This function is also called for the implicit conversion to $(D T).
2514 
2515 Returns:
2516     The value held internally by this `Nullable`.
2517  */
2518     @property ref inout(T) get() inout @safe pure nothrow
2519     {
2520         enum message = "Called `get' on null Nullable!" ~ T.stringof ~ ".";
2521         assert(!isNull, message);
2522         return _value;
2523     }
2524 
2525 ///
2526 @system unittest
2527 {
2528     import core.exception : AssertError;
2529     import std.exception : assertThrown, assertNotThrown;
2530 
2531     Nullable!int ni;
2532     int i = 42;
2533     //`get` is implicitly called. Will throw
2534     //an AssertError in non-release mode
2535     assertThrown!AssertError(i = ni);
2536     assert(i == 42);
2537 
2538     ni = 5;
2539     assertNotThrown!AssertError(i = ni);
2540     assert(i == 5);
2541 }
2542 
2543 /**
2544 Implicitly converts to $(D T).
2545 $(D this) must not be in the null state.
2546  */
2547     alias get this;
2548 }
2549 
2550 /// ditto
2551 auto nullable(T)(T t)
2552 {
2553     return Nullable!T(t);
2554 }
2555 
2556 ///
2557 @safe unittest
2558 {
2559     struct CustomerRecord
2560     {
2561         string name;
2562         string address;
2563         int customerNum;
2564     }
2565 
2566     Nullable!CustomerRecord getByName(string name)
2567     {
2568         //A bunch of hairy stuff
2569 
2570         return Nullable!CustomerRecord.init;
2571     }
2572 
2573     auto queryResult = getByName("Doe, John");
2574     if (!queryResult.isNull)
2575     {
2576         //Process Mr. Doe's customer record
2577         auto address = queryResult.address;
2578         auto customerNum = queryResult.customerNum;
2579 
2580         //Do some things with this customer's info
2581     }
2582     else
2583     {
2584         //Add the customer to the database
2585     }
2586 }
2587 
2588 ///
2589 @system unittest
2590 {
2591     import std.exception : assertThrown;
2592 
2593     auto a = 42.nullable;
2594     assert(!a.isNull);
2595     assert(a.get == 42);
2596 
2597     a.nullify();
2598     assert(a.isNull);
2599     assertThrown!Throwable(a.get);
2600 }
2601 
2602 @system unittest
2603 {
2604     import std.exception : assertThrown;
2605 
2606     Nullable!int a;
2607     assert(a.isNull);
2608     assertThrown!Throwable(a.get);
2609     a = 5;
2610     assert(!a.isNull);
2611     assert(a == 5);
2612     assert(a != 3);
2613     assert(a.get != 3);
2614     a.nullify();
2615     assert(a.isNull);
2616     a = 3;
2617     assert(a == 3);
2618     a *= 6;
2619     assert(a == 18);
2620     a = a;
2621     assert(a == 18);
2622     a.nullify();
2623     assertThrown!Throwable(a += 2);
2624 }
2625 @safe unittest
2626 {
2627     auto k = Nullable!int(74);
2628     assert(k == 74);
2629     k.nullify();
2630     assert(k.isNull);
2631 }
2632 @safe unittest
2633 {
2634     static int f(in Nullable!int x) {
2635         return x.isNull ? 42 : x.get;
2636     }
2637     Nullable!int a;
2638     assert(f(a) == 42);
2639     a = 8;
2640     assert(f(a) == 8);
2641     a.nullify();
2642     assert(f(a) == 42);
2643 }
2644 @system unittest
2645 {
2646     import std.exception : assertThrown;
2647 
2648     static struct S { int x; }
2649     Nullable!S s;
2650     assert(s.isNull);
2651     s = S(6);
2652     assert(s == S(6));
2653     assert(s != S(0));
2654     assert(s.get != S(0));
2655     s.x = 9190;
2656     assert(s.x == 9190);
2657     s.nullify();
2658     assertThrown!Throwable(s.x = 9441);
2659 }
2660 @safe unittest
2661 {
2662     // Ensure Nullable can be used in pure/nothrow/@safe environment.
2663     function() @safe pure nothrow
2664     {
2665         Nullable!int n;
2666         assert(n.isNull);
2667         n = 4;
2668         assert(!n.isNull);
2669         assert(n == 4);
2670         n.nullify();
2671         assert(n.isNull);
2672     }();
2673 }
2674 @system unittest
2675 {
2676     // Ensure Nullable can be used when the value is not pure/nothrow/@safe
2677     static struct S
2678     {
2679         int x;
2680         this(this) @system {}
2681     }
2682 
2683     Nullable!S s;
2684     assert(s.isNull);
2685     s = S(5);
2686     assert(!s.isNull);
2687     assert(s.x == 5);
2688     s.nullify();
2689     assert(s.isNull);
2690 }
2691 @safe unittest
2692 {
2693     // Bugzilla 9404
2694     alias N = Nullable!int;
2695 
2696     void foo(N a)
2697     {
2698         N b;
2699         b = a; // `N b = a;` works fine
2700     }
2701     N n;
2702     foo(n);
2703 }
2704 @safe unittest
2705 {
2706     //Check nullable immutable is constructable
2707     {
2708         auto a1 = Nullable!(immutable int)();
2709         auto a2 = Nullable!(immutable int)(1);
2710         auto i = a2.get;
2711     }
2712     //Check immutable nullable is constructable
2713     {
2714         auto a1 = immutable (Nullable!int)();
2715         auto a2 = immutable (Nullable!int)(1);
2716         auto i = a2.get;
2717     }
2718 }
2719 @safe unittest
2720 {
2721     alias NInt   = Nullable!int;
2722 
2723     //Construct tests
2724     {
2725         //from other Nullable null
2726         NInt a1;
2727         NInt b1 = a1;
2728         assert(b1.isNull);
2729 
2730         //from other Nullable non-null
2731         NInt a2 = NInt(1);
2732         NInt b2 = a2;
2733         assert(b2 == 1);
2734 
2735         //Construct from similar nullable
2736         auto a3 = immutable(NInt)();
2737         NInt b3 = a3;
2738         assert(b3.isNull);
2739     }
2740 
2741     //Assign tests
2742     {
2743         //from other Nullable null
2744         NInt a1;
2745         NInt b1;
2746         b1 = a1;
2747         assert(b1.isNull);
2748 
2749         //from other Nullable non-null
2750         NInt a2 = NInt(1);
2751         NInt b2;
2752         b2 = a2;
2753         assert(b2 == 1);
2754 
2755         //Construct from similar nullable
2756         auto a3 = immutable(NInt)();
2757         NInt b3 = a3;
2758         b3 = a3;
2759         assert(b3.isNull);
2760     }
2761 }
2762 @safe unittest
2763 {
2764     //Check nullable is nicelly embedable in a struct
2765     static struct S1
2766     {
2767         Nullable!int ni;
2768     }
2769     static struct S2 //inspired from 9404
2770     {
2771         Nullable!int ni;
2772         this(S2 other)
2773         {
2774             ni = other.ni;
2775         }
2776         void opAssign(S2 other)
2777         {
2778             ni = other.ni;
2779         }
2780     }
2781     foreach (S; AliasSeq!(S1, S2))
2782     {
2783         S a;
2784         S b = a;
2785         S c;
2786         c = a;
2787     }
2788 }
2789 @system unittest
2790 {
2791     // Bugzilla 10268
2792     import std.json;
2793     JSONValue value = null;
2794     auto na = Nullable!JSONValue(value);
2795 
2796     struct S1 { int val; }
2797     struct S2 { int* val; }
2798     struct S3 { immutable int* val; }
2799 
2800     {
2801         auto sm = S1(1);
2802         immutable si = immutable S1(1);
2803         auto x1 =           Nullable!S1(sm);
2804         auto x2 = immutable Nullable!S1(sm);
2805         auto x3 =           Nullable!S1(si);
2806         auto x4 = immutable Nullable!S1(si);
2807         assert(x1.val == 1);
2808         assert(x2.val == 1);
2809         assert(x3.val == 1);
2810         assert(x4.val == 1);
2811     }
2812 
2813     auto nm = 10;
2814     immutable ni = 10;
2815 
2816     {
2817         auto sm = S2(&nm);
2818         immutable si = immutable S2(&ni);
2819         auto x1 =           Nullable!S2(sm);
2820         static assert(!__traits(compiles, { auto x2 = immutable Nullable!S2(sm); }));
2821         static assert(!__traits(compiles, { auto x3 =           Nullable!S2(si); }));
2822         auto x4 = immutable Nullable!S2(si);
2823         assert(*x1.val == 10);
2824         assert(*x4.val == 10);
2825     }
2826 
2827     {
2828         auto sm = S3(&ni);
2829         immutable si = immutable S3(&ni);
2830         auto x1 =           Nullable!S3(sm);
2831         auto x2 = immutable Nullable!S3(sm);
2832         auto x3 =           Nullable!S3(si);
2833         auto x4 = immutable Nullable!S3(si);
2834         assert(*x1.val == 10);
2835         assert(*x2.val == 10);
2836         assert(*x3.val == 10);
2837         assert(*x4.val == 10);
2838     }
2839 }
2840 @safe unittest
2841 {
2842     // Bugzila 10357
2843     import std.datetime;
2844     Nullable!SysTime time = SysTime(0);
2845 }
2846 @system unittest
2847 {
2848     import std.conv : to;
2849     import std.array;
2850 
2851     // Bugzilla 10915
2852     Appender!string buffer;
2853 
2854     Nullable!int ni;
2855     assert(ni.to!string() == "Nullable.null");
2856 
2857     struct Test { string s; }
2858     alias NullableTest = Nullable!Test;
2859 
2860     NullableTest nt = Test("test");
2861     assert(nt.to!string() == `Test("test")`);
2862 
2863     NullableTest ntn = Test("null");
2864     assert(ntn.to!string() == `Test("null")`);
2865 
2866     class TestToString
2867     {
2868         double d;
2869 
2870         this (double d)
2871         {
2872             this.d = d;
2873         }
2874 
2875         override string toString()
2876         {
2877             return d.to!string();
2878         }
2879     }
2880     Nullable!TestToString ntts = new TestToString(2.5);
2881     assert(ntts.to!string() == "2.5");
2882 }
2883 
2884 /**
2885 Just like $(D Nullable!T), except that the null state is defined as a
2886 particular value. For example, $(D Nullable!(uint, uint.max)) is an
2887 $(D uint) that sets aside the value $(D uint.max) to denote a null
2888 state. $(D Nullable!(T, nullValue)) is more storage-efficient than $(D
2889 Nullable!T) because it does not need to store an extra $(D bool).
2890 
2891 Params:
2892     T = The wrapped type for which Nullable provides a null value.
2893 
2894     nullValue = The null value which denotes the null state of this
2895                 `Nullable`. Must be of type `T`.
2896  */
2897 struct Nullable(T, T nullValue)
2898 {
2899     private T _value = nullValue;
2900 
2901 /**
2902 Constructor initializing $(D this) with $(D value).
2903 
2904 Params:
2905     value = The value to initialize this `Nullable` with.
2906  */
2907     this(T value)
2908     {
2909         _value = value;
2910     }
2911 
2912     template toString()
2913     {
2914         import std.format : FormatSpec, formatValue;
2915         // Needs to be a template because of DMD @@BUG@@ 13737.
2916         void toString()(scope void delegate(const(char)[]) sink, FormatSpec!char fmt)
2917         {
2918             if (isNull)
2919             {
2920                 sink.formatValue("Nullable.null", fmt);
2921             }
2922             else
2923             {
2924                 sink.formatValue(_value, fmt);
2925             }
2926         }
2927     }
2928 
2929 /**
2930 Check if `this` is in the null state.
2931 
2932 Returns:
2933     true $(B iff) `this` is in the null state, otherwise false.
2934  */
2935     @property bool isNull() const
2936     {
2937         //Need to use 'is' if T is a nullable type and
2938         //nullValue is null, or it's a compiler error
2939         static if (is(CommonType!(T, typeof(null)) == T) && nullValue is null)
2940         {
2941             return _value is nullValue;
2942         }
2943         //Need to use 'is' if T is a float type
2944         //because NaN != NaN
2945         else static if (isFloatingPoint!T)
2946         {
2947             return _value is nullValue;
2948         }
2949         else
2950         {
2951             return _value == nullValue;
2952         }
2953     }
2954 
2955 ///
2956 @system unittest
2957 {
2958     Nullable!(int, -1) ni;
2959     //Initialized to "null" state
2960     assert(ni.isNull);
2961 
2962     ni = 0;
2963     assert(!ni.isNull);
2964 }
2965 
2966 // https://issues.dlang.org/show_bug.cgi?id=11135
2967 // disable test until https://issues.dlang.org/show_bug.cgi?id=15316 gets fixed
2968 version (none) @system unittest
2969 {
2970     foreach (T; AliasSeq!(float, double, real))
2971     {
2972         Nullable!(T, T.init) nf;
2973         //Initialized to "null" state
2974         assert(nf.isNull);
2975         assert(nf is typeof(nf).init);
2976 
2977         nf = 0;
2978         assert(!nf.isNull);
2979 
2980         nf.nullify();
2981         assert(nf.isNull);
2982     }
2983 }
2984 
2985 /**
2986 Forces $(D this) to the null state.
2987  */
2988     void nullify()()
2989     {
2990         _value = nullValue;
2991     }
2992 
2993 ///
2994 @system unittest
2995 {
2996     Nullable!(int, -1) ni = 0;
2997     assert(!ni.isNull);
2998 
2999     ni = -1;
3000     assert(ni.isNull);
3001 }
3002 
3003 /**
3004 Assigns $(D value) to the internally-held state. If the assignment
3005 succeeds, $(D this) becomes non-null. No null checks are made. Note
3006 that the assignment may leave $(D this) in the null state.
3007 
3008 Params:
3009     value = A value of type `T` to assign to this `Nullable`.
3010             If it is `nullvalue`, then the internal state of
3011             this `Nullable` will be set to null.
3012  */
3013     void opAssign()(T value)
3014     {
3015         _value = value;
3016     }
3017 
3018 /**
3019     If this `Nullable` wraps a type that already has a null value
3020     (such as a pointer), and that null value is not given for
3021     `nullValue`, then assigning the null value to this `Nullable`
3022     is no different than assigning any other value of type `T`,
3023     and the resulting code will look very strange. It is strongly
3024     recommended that this be avoided by using `T`'s "built in"
3025     null value for `nullValue`.
3026  */
3027 @system unittest
3028 {
3029     //Passes
3030     enum nullVal = cast(int*) 0xCAFEBABE;
3031     Nullable!(int*, nullVal) npi;
3032     assert(npi.isNull);
3033 
3034     //Passes?!
3035     npi = null;
3036     assert(!npi.isNull);
3037 }
3038 
3039 /**
3040 Gets the value. $(D this) must not be in the null state.
3041 This function is also called for the implicit conversion to $(D T).
3042 
3043 Returns:
3044     The value held internally by this `Nullable`.
3045  */
3046     @property ref inout(T) get() inout
3047     {
3048         //@@@6169@@@: We avoid any call that might evaluate nullValue's %s,
3049         //Because it might messup get's purity and safety inference.
3050         enum message = "Called `get' on null Nullable!(" ~ T.stringof ~ ",nullValue).";
3051         assert(!isNull, message);
3052         return _value;
3053     }
3054 
3055 ///
3056 @system unittest
3057 {
3058     import std.exception : assertThrown, assertNotThrown;
3059 
3060     Nullable!(int, -1) ni;
3061     //`get` is implicitly called. Will throw
3062     //an error in non-release mode
3063     assertThrown!Throwable(ni == 0);
3064 
3065     ni = 0;
3066     assertNotThrown!Throwable(ni == 0);
3067 }
3068 
3069 /**
3070 Implicitly converts to $(D T).
3071 $(D this) must not be in the null state.
3072  */
3073     alias get this;
3074 }
3075 
3076 /// ditto
3077 auto nullable(alias nullValue, T)(T t)
3078     if (is (typeof(nullValue) == T))
3079 {
3080     return Nullable!(T, nullValue)(t);
3081 }
3082 
3083 ///
3084 @safe unittest
3085 {
3086     Nullable!(size_t, size_t.max) indexOf(string[] haystack, string needle)
3087     {
3088         //Find the needle, returning -1 if not found
3089 
3090         return Nullable!(size_t, size_t.max).init;
3091     }
3092 
3093     void sendLunchInvite(string name)
3094     {
3095     }
3096 
3097     //It's safer than C...
3098     auto coworkers = ["Jane", "Jim", "Marry", "Fred"];
3099     auto pos = indexOf(coworkers, "Bob");
3100     if (!pos.isNull)
3101     {
3102         //Send Bob an invitation to lunch
3103         sendLunchInvite(coworkers[pos]);
3104     }
3105     else
3106     {
3107         //Bob not found; report the error
3108     }
3109 
3110     //And there's no overhead
3111     static assert(Nullable!(size_t, size_t.max).sizeof == size_t.sizeof);
3112 }
3113 
3114 ///
3115 @system unittest
3116 {
3117     import std.exception : assertThrown;
3118 
3119     Nullable!(int, int.min) a;
3120     assert(a.isNull);
3121     assertThrown!Throwable(a.get);
3122     a = 5;
3123     assert(!a.isNull);
3124     assert(a == 5);
3125     static assert(a.sizeof == int.sizeof);
3126 }
3127 
3128 ///
3129 @safe unittest
3130 {
3131     auto a = nullable!(int.min)(8);
3132     assert(a == 8);
3133     a.nullify();
3134     assert(a.isNull);
3135 }
3136 
3137 @safe unittest
3138 {
3139     static int f(in Nullable!(int, int.min) x) {
3140         return x.isNull ? 42 : x.get;
3141     }
3142     Nullable!(int, int.min) a;
3143     assert(f(a) == 42);
3144     a = 8;
3145     assert(f(a) == 8);
3146     a.nullify();
3147     assert(f(a) == 42);
3148 }
3149 @safe unittest
3150 {
3151     // Ensure Nullable can be used in pure/nothrow/@safe environment.
3152     function() @safe pure nothrow
3153     {
3154         Nullable!(int, int.min) n;
3155         assert(n.isNull);
3156         n = 4;
3157         assert(!n.isNull);
3158         assert(n == 4);
3159         n.nullify();
3160         assert(n.isNull);
3161     }();
3162 }
3163 @system unittest
3164 {
3165     // Ensure Nullable can be used when the value is not pure/nothrow/@system
3166     static struct S
3167     {
3168         int x;
3169         bool opEquals(const S s) const @system { return s.x == x; }
3170     }
3171 
3172     Nullable!(S, S(711)) s;
3173     assert(s.isNull);
3174     s = S(5);
3175     assert(!s.isNull);
3176     assert(s.x == 5);
3177     s.nullify();
3178     assert(s.isNull);
3179 }
3180 @safe unittest
3181 {
3182     //Check nullable is nicelly embedable in a struct
3183     static struct S1
3184     {
3185         Nullable!(int, 0) ni;
3186     }
3187     static struct S2 //inspired from 9404
3188     {
3189         Nullable!(int, 0) ni;
3190         this(S2 other)
3191         {
3192             ni = other.ni;
3193         }
3194         void opAssign(S2 other)
3195         {
3196             ni = other.ni;
3197         }
3198     }
3199     foreach (S; AliasSeq!(S1, S2))
3200     {
3201         S a;
3202         S b = a;
3203         S c;
3204         c = a;
3205     }
3206 }
3207 @system unittest
3208 {
3209     import std.conv : to;
3210 
3211     // Bugzilla 10915
3212     Nullable!(int, 1) ni = 1;
3213     assert(ni.to!string() == "Nullable.null");
3214 
3215     struct Test { string s; }
3216     alias NullableTest = Nullable!(Test, Test("null"));
3217 
3218     NullableTest nt = Test("test");
3219     assert(nt.to!string() == `Test("test")`);
3220 
3221     NullableTest ntn = Test("null");
3222     assert(ntn.to!string() == "Nullable.null");
3223 
3224     class TestToString
3225     {
3226         double d;
3227 
3228         this(double d)
3229         {
3230             this.d = d;
3231         }
3232 
3233         override string toString()
3234         {
3235             return d.to!string();
3236         }
3237     }
3238     alias NullableTestToString = Nullable!(TestToString, null);
3239 
3240     NullableTestToString ntts = new TestToString(2.5);
3241     assert(ntts.to!string() == "2.5");
3242 }
3243 
3244 
3245 /**
3246 Just like $(D Nullable!T), except that the object refers to a value
3247 sitting elsewhere in memory. This makes assignments overwrite the
3248 initially assigned value. Internally $(D NullableRef!T) only stores a
3249 pointer to $(D T) (i.e., $(D Nullable!T.sizeof == (T*).sizeof)).
3250  */
3251 struct NullableRef(T)
3252 {
3253     private T* _value;
3254 
3255 /**
3256 Constructor binding $(D this) to $(D value).
3257 
3258 Params:
3259     value = The value to bind to.
3260  */
3261     this(T* value) @safe pure nothrow
3262     {
3263         _value = value;
3264     }
3265 
3266     template toString()
3267     {
3268         import std.format : FormatSpec, formatValue;
3269         // Needs to be a template because of DMD @@BUG@@ 13737.
3270         void toString()(scope void delegate(const(char)[]) sink, FormatSpec!char fmt)
3271         {
3272             if (isNull)
3273             {
3274                 sink.formatValue("Nullable.null", fmt);
3275             }
3276             else
3277             {
3278                 sink.formatValue(*_value, fmt);
3279             }
3280         }
3281     }
3282 
3283 /**
3284 Binds the internal state to $(D value).
3285 
3286 Params:
3287     value = A pointer to a value of type `T` to bind this `NullableRef` to.
3288  */
3289     void bind(T* value) @safe pure nothrow
3290     {
3291         _value = value;
3292     }
3293 
3294     ///
3295     @safe unittest
3296     {
3297         NullableRef!int nr = new int(42);
3298         assert(nr == 42);
3299 
3300         int* n = new int(1);
3301         nr.bind(n);
3302         assert(nr == 1);
3303     }
3304 
3305 /**
3306 Returns $(D true) if and only if $(D this) is in the null state.
3307 
3308 Returns:
3309     true if `this` is in the null state, otherwise false.
3310  */
3311     @property bool isNull() const @safe pure nothrow
3312     {
3313         return _value is null;
3314     }
3315 
3316     ///
3317     @safe unittest
3318     {
3319         NullableRef!int nr;
3320         assert(nr.isNull);
3321 
3322         int* n = new int(42);
3323         nr.bind(n);
3324         assert(!nr.isNull && nr == 42);
3325     }
3326 
3327 /**
3328 Forces $(D this) to the null state.
3329  */
3330     void nullify() @safe pure nothrow
3331     {
3332         _value = null;
3333     }
3334 
3335     ///
3336     @safe unittest
3337     {
3338         NullableRef!int nr = new int(42);
3339         assert(!nr.isNull);
3340 
3341         nr.nullify();
3342         assert(nr.isNull);
3343     }
3344 
3345 /**
3346 Assigns $(D value) to the internally-held state.
3347 
3348 Params:
3349     value = A value of type `T` to assign to this `NullableRef`.
3350             If the internal state of this `NullableRef` has not
3351             been initialized, an error will be thrown in
3352             non-release mode.
3353  */
3354     void opAssign()(T value)
3355         if (isAssignable!T) //@@@9416@@@
3356     {
3357         enum message = "Called `opAssign' on null NullableRef!" ~ T.stringof ~ ".";
3358         assert(!isNull, message);
3359         *_value = value;
3360     }
3361 
3362     ///
3363     @system unittest
3364     {
3365         import std.exception : assertThrown, assertNotThrown;
3366 
3367         NullableRef!int nr;
3368         assert(nr.isNull);
3369         assertThrown!Throwable(nr = 42);
3370 
3371         nr.bind(new int(0));
3372         assert(!nr.isNull);
3373         assertNotThrown!Throwable(nr = 42);
3374         assert(nr == 42);
3375     }
3376 
3377 /**
3378 Gets the value. $(D this) must not be in the null state.
3379 This function is also called for the implicit conversion to $(D T).
3380  */
3381     @property ref inout(T) get() inout @safe pure nothrow
3382     {
3383         enum message = "Called `get' on null NullableRef!" ~ T.stringof ~ ".";
3384         assert(!isNull, message);
3385         return *_value;
3386     }
3387 
3388     ///
3389     @system unittest
3390     {
3391         import std.exception : assertThrown, assertNotThrown;
3392 
3393         NullableRef!int nr;
3394         //`get` is implicitly called. Will throw
3395         //an error in non-release mode
3396         assertThrown!Throwable(nr == 0);
3397 
3398         nr.bind(new int(0));
3399         assertNotThrown!Throwable(nr == 0);
3400     }
3401 
3402 /**
3403 Implicitly converts to $(D T).
3404 $(D this) must not be in the null state.
3405  */
3406     alias get this;
3407 }
3408 
3409 /// ditto
3410 auto nullableRef(T)(T* t)
3411 {
3412     return NullableRef!T(t);
3413 }
3414 
3415 ///
3416 @system unittest
3417 {
3418     import std.exception : assertThrown;
3419 
3420     int x = 5, y = 7;
3421     auto a = nullableRef(&x);
3422     assert(!a.isNull);
3423     assert(a == 5);
3424     assert(x == 5);
3425     a = 42;
3426     assert(x == 42);
3427     assert(!a.isNull);
3428     assert(a == 42);
3429     a.nullify();
3430     assert(x == 42);
3431     assert(a.isNull);
3432     assertThrown!Throwable(a.get);
3433     assertThrown!Throwable(a = 71);
3434     a.bind(&y);
3435     assert(a == 7);
3436     y = 135;
3437     assert(a == 135);
3438 }
3439 @system unittest
3440 {
3441     static int f(in NullableRef!int x) {
3442         return x.isNull ? 42 : x.get;
3443     }
3444     int x = 5;
3445     auto a = nullableRef(&x);
3446     assert(f(a) == 5);
3447     a.nullify();
3448     assert(f(a) == 42);
3449 }
3450 @safe unittest
3451 {
3452     // Ensure NullableRef can be used in pure/nothrow/@safe environment.
3453     function() @safe pure nothrow
3454     {
3455         auto storage = new int;
3456         *storage = 19902;
3457         NullableRef!int n;
3458         assert(n.isNull);
3459         n.bind(storage);
3460         assert(!n.isNull);
3461         assert(n == 19902);
3462         n = 2294;
3463         assert(n == 2294);
3464         assert(*storage == 2294);
3465         n.nullify();
3466         assert(n.isNull);
3467     }();
3468 }
3469 @system unittest
3470 {
3471     // Ensure NullableRef can be used when the value is not pure/nothrow/@safe
3472     static struct S
3473     {
3474         int x;
3475         this(this) @system {}
3476         bool opEquals(const S s) const @system { return s.x == x; }
3477     }
3478 
3479     auto storage = S(5);
3480 
3481     NullableRef!S s;
3482     assert(s.isNull);
3483     s.bind(&storage);
3484     assert(!s.isNull);
3485     assert(s.x == 5);
3486     s.nullify();
3487     assert(s.isNull);
3488 }
3489 @safe unittest
3490 {
3491     //Check nullable is nicelly embedable in a struct
3492     static struct S1
3493     {
3494         NullableRef!int ni;
3495     }
3496     static struct S2 //inspired from 9404
3497     {
3498         NullableRef!int ni;
3499         this(S2 other)
3500         {
3501             ni = other.ni;
3502         }
3503         void opAssign(S2 other)
3504         {
3505             ni = other.ni;
3506         }
3507     }
3508     foreach (S; AliasSeq!(S1, S2))
3509     {
3510         S a;
3511         S b = a;
3512         S c;
3513         c = a;
3514     }
3515 }
3516 @system unittest
3517 {
3518     import std.conv : to;
3519 
3520     // Bugzilla 10915
3521     NullableRef!int nri;
3522     assert(nri.to!string() == "Nullable.null");
3523 
3524     struct Test
3525     {
3526         string s;
3527     }
3528     NullableRef!Test nt = new Test("test");
3529     assert(nt.to!string() == `Test("test")`);
3530 
3531     class TestToString
3532     {
3533         double d;
3534 
3535         this(double d)
3536         {
3537             this.d = d;
3538         }
3539 
3540         override string toString()
3541         {
3542             return d.to!string();
3543         }
3544     }
3545     TestToString tts = new TestToString(2.5);
3546     NullableRef!TestToString ntts = &tts;
3547     assert(ntts.to!string() == "2.5");
3548 }
3549 
3550 
3551 /**
3552 $(D BlackHole!Base) is a subclass of $(D Base) which automatically implements
3553 all abstract member functions in $(D Base) as do-nothing functions.  Each
3554 auto-implemented function just returns the default value of the return type
3555 without doing anything.
3556 
3557 The name came from
3558 $(HTTP search.cpan.org/~sburke/Class-_BlackHole-0.04/lib/Class/_BlackHole.pm, Class::_BlackHole)
3559 Perl module by Sean M. Burke.
3560 
3561 Params:
3562     Base = A non-final class for `BlackHole` to inherit from.
3563 
3564 See_Also:
3565   $(LREF AutoImplement), $(LREF generateEmptyFunction)
3566  */
3567 alias BlackHole(Base) = AutoImplement!(Base, generateEmptyFunction, isAbstractFunction);
3568 
3569 ///
3570 @system unittest
3571 {
3572     import std.math : isNaN;
3573 
3574     static abstract class C
3575     {
3576         int m_value;
3577         this(int v) { m_value = v; }
3578         int value() @property { return m_value; }
3579 
3580         abstract real realValue() @property;
3581         abstract void doSomething();
3582     }
3583 
3584     auto c = new BlackHole!C(42);
3585     assert(c.value == 42);
3586 
3587     // Returns real.init which is NaN
3588     assert(c.realValue.isNaN);
3589     // Abstract functions are implemented as do-nothing
3590     c.doSomething();
3591 }
3592 
3593 @system unittest
3594 {
3595     import std.math : isNaN;
3596 
3597     // return default
3598     {
3599         interface I_1 { real test(); }
3600         auto o = new BlackHole!I_1;
3601         assert(o.test().isNaN()); // NaN
3602     }
3603     // doc example
3604     {
3605         static class C
3606         {
3607             int m_value;
3608             this(int v) { m_value = v; }
3609             int value() @property { return m_value; }
3610 
3611             abstract real realValue() @property;
3612             abstract void doSomething();
3613         }
3614 
3615         auto c = new BlackHole!C(42);
3616         assert(c.value == 42);
3617 
3618         assert(c.realValue.isNaN); // NaN
3619         c.doSomething();
3620     }
3621 
3622     // Bugzilla 12058
3623     interface Foo
3624     {
3625         inout(Object) foo() inout;
3626     }
3627     BlackHole!Foo o;
3628 }
3629 
3630 
3631 /**
3632 $(D WhiteHole!Base) is a subclass of $(D Base) which automatically implements
3633 all abstract member functions as functions that always fail. These functions
3634 simply throw an $(D Error) and never return. `Whitehole` is useful for
3635 trapping the use of class member functions that haven't been implemented.
3636 
3637 The name came from
3638 $(HTTP search.cpan.org/~mschwern/Class-_WhiteHole-0.04/lib/Class/_WhiteHole.pm, Class::_WhiteHole)
3639 Perl module by Michael G Schwern.
3640 
3641 Params:
3642     Base = A non-final class for `WhiteHole` to inherit from.
3643 
3644 See_Also:
3645   $(LREF AutoImplement), $(LREF generateAssertTrap)
3646  */
3647 alias WhiteHole(Base) = AutoImplement!(Base, generateAssertTrap, isAbstractFunction);
3648 
3649 ///
3650 @system unittest
3651 {
3652     import std.exception : assertThrown;
3653 
3654     static class C
3655     {
3656         abstract void notYetImplemented();
3657     }
3658 
3659     auto c = new WhiteHole!C;
3660     assertThrown!NotImplementedError(c.notYetImplemented()); // throws an Error
3661 }
3662 
3663 // / ditto
3664 class NotImplementedError : Error
3665 {
3666     this(string method)
3667     {
3668         super(method ~ " is not implemented");
3669     }
3670 }
3671 
3672 @system unittest
3673 {
3674     import std.exception : assertThrown;
3675     // nothrow
3676     {
3677         interface I_1
3678         {
3679             void foo();
3680             void bar() nothrow;
3681         }
3682         auto o = new WhiteHole!I_1;
3683         assertThrown!NotImplementedError(o.foo());
3684         assertThrown!NotImplementedError(o.bar());
3685     }
3686     // doc example
3687     {
3688         static class C
3689         {
3690             abstract void notYetImplemented();
3691         }
3692 
3693         auto c = new WhiteHole!C;
3694         try
3695         {
3696             c.notYetImplemented();
3697             assert(0);
3698         }
3699         catch (Error e) {}
3700     }
3701 }
3702 
3703 
3704 /**
3705 $(D AutoImplement) automatically implements (by default) all abstract member
3706 functions in the class or interface $(D Base) in specified way.
3707 
3708 The second version of $(D AutoImplement) automatically implements
3709 $(D Interface), while deriving from $(D BaseClass).
3710 
3711 Params:
3712   how  = template which specifies _how functions will be implemented/overridden.
3713 
3714          Two arguments are passed to $(D how): the type $(D Base) and an alias
3715          to an implemented function.  Then $(D how) must return an implemented
3716          function body as a string.
3717 
3718          The generated function body can use these keywords:
3719          $(UL
3720             $(LI $(D a0), $(D a1), &hellip;: arguments passed to the function;)
3721             $(LI $(D args): a tuple of the arguments;)
3722             $(LI $(D self): an alias to the function itself;)
3723             $(LI $(D parent): an alias to the overridden function (if any).)
3724          )
3725 
3726         You may want to use templated property functions (instead of Implicit
3727         Template Properties) to generate complex functions:
3728 --------------------
3729 // Prints log messages for each call to overridden functions.
3730 string generateLogger(C, alias fun)() @property
3731 {
3732     import std.traits;
3733     enum qname = C.stringof ~ "." ~ __traits(identifier, fun);
3734     string stmt;
3735 
3736     stmt ~= q{ struct Importer { import std.stdio; } };
3737     stmt ~= `Importer.writeln("Log: ` ~ qname ~ `(", args, ")");`;
3738     static if (!__traits(isAbstractFunction, fun))
3739     {
3740         static if (is(ReturnType!fun == void))
3741             stmt ~= q{ parent(args); };
3742         else
3743             stmt ~= q{
3744                 auto r = parent(args);
3745                 Importer.writeln("--> ", r);
3746                 return r;
3747             };
3748     }
3749     return stmt;
3750 }
3751 --------------------
3752 
3753   what = template which determines _what functions should be
3754          implemented/overridden.
3755 
3756          An argument is passed to $(D what): an alias to a non-final member
3757          function in $(D Base).  Then $(D what) must return a boolean value.
3758          Return $(D true) to indicate that the passed function should be
3759          implemented/overridden.
3760 
3761 --------------------
3762 // Sees if fun returns something.
3763 enum bool hasValue(alias fun) = !is(ReturnType!(fun) == void);
3764 --------------------
3765 
3766 
3767 Note:
3768 
3769 Generated code is inserted in the scope of $(D std.typecons) module.  Thus,
3770 any useful functions outside $(D std.typecons) cannot be used in the generated
3771 code.  To workaround this problem, you may $(D import) necessary things in a
3772 local struct, as done in the $(D generateLogger()) template in the above
3773 example.
3774 
3775 
3776 BUGS:
3777 
3778 $(UL
3779  $(LI Variadic arguments to constructors are not forwarded to super.)
3780  $(LI Deep interface inheritance causes compile error with messages like
3781       "Error: function std.typecons._AutoImplement!(Foo)._AutoImplement.bar
3782       does not override any function".  [$(BUGZILLA 2525), $(BUGZILLA 3525)] )
3783  $(LI The $(D parent) keyword is actually a delegate to the super class'
3784       corresponding member function.  [$(BUGZILLA 2540)] )
3785  $(LI Using alias template parameter in $(D how) and/or $(D what) may cause
3786      strange compile error.  Use template tuple parameter instead to workaround
3787      this problem.  [$(BUGZILLA 4217)] )
3788 )
3789  */
3790 class AutoImplement(Base, alias how, alias what = isAbstractFunction) : Base
3791     if (!is(how == class))
3792 {
3793     private alias autoImplement_helper_ =
3794         AutoImplement_Helper!("autoImplement_helper_", "Base", Base, typeof(this), how, what);
3795     mixin(autoImplement_helper_.code);
3796 }
3797 
3798 /// ditto
3799 class AutoImplement(
3800     Interface, BaseClass, alias how,
3801     alias what = isAbstractFunction) : BaseClass, Interface
3802     if (is(Interface == interface) && is(BaseClass == class))
3803 {
3804     private alias autoImplement_helper_ = AutoImplement_Helper!(
3805             "autoImplement_helper_", "Interface", Interface, typeof(this), how, what);
3806     mixin(autoImplement_helper_.code);
3807 }
3808 
3809 /*
3810  * Code-generating stuffs are encupsulated in this helper template so that
3811  * namespace pollution, which can cause name confliction with Base's public
3812  * members, should be minimized.
3813  */
3814 private template AutoImplement_Helper(string myName, string baseName,
3815         Base, Self, alias generateMethodBody, alias cherrypickMethod)
3816 {
3817 private static:
3818     //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
3819     // Internal stuffs
3820     //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
3821 
3822     // Returns function overload sets in the class C, filtered with pred.
3823     template enumerateOverloads(C, alias pred)
3824     {
3825         template Impl(names...)
3826         {
3827             import std.meta : Filter;
3828             static if (names.length > 0)
3829             {
3830                 alias methods = Filter!(pred, MemberFunctionsTuple!(C, names[0]));
3831                 alias next = Impl!(names[1 .. $]);
3832 
3833                 static if (methods.length > 0)
3834                     alias Impl = AliasSeq!(OverloadSet!(names[0], methods), next);
3835                 else
3836                     alias Impl = next;
3837             }
3838             else
3839                 alias Impl = AliasSeq!();
3840         }
3841 
3842         alias enumerateOverloads = Impl!(__traits(allMembers, C));
3843     }
3844 
3845     //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
3846     // Target functions
3847     //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
3848 
3849     // Add a non-final check to the cherrypickMethod.
3850     enum bool canonicalPicker(fun.../+[BUG 4217]+/) =
3851         !__traits(isFinalFunction, fun[0]) && cherrypickMethod!(fun);
3852 
3853     /*
3854      * A tuple of overload sets, each item of which consists of functions to be
3855      * implemented by the generated code.
3856      */
3857     alias targetOverloadSets = enumerateOverloads!(Base, canonicalPicker);
3858 
3859     /*
3860      * Super class of this AutoImplement instance
3861      */
3862     alias Super = BaseTypeTuple!(Self)[0];
3863     static assert(is(Super == class));
3864     static assert(is(Base == interface) || is(Super == Base));
3865 
3866     /*
3867      * A tuple of the super class' constructors.  Used for forwarding
3868      * constructor calls.
3869      */
3870     static if (__traits(hasMember, Super, "__ctor"))
3871         alias ctorOverloadSet = OverloadSet!("__ctor", __traits(getOverloads, Super, "__ctor"));
3872     else
3873         alias ctorOverloadSet = OverloadSet!("__ctor"); // empty
3874 
3875 
3876     //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
3877     // Type information
3878     //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
3879 
3880     /*
3881      * The generated code will be mixed into AutoImplement, which will be
3882      * instantiated in this module's scope.  Thus, any user-defined types are
3883      * out of scope and cannot be used directly (i.e. by their names).
3884      *
3885      * We will use FuncInfo instances for accessing return types and parameter
3886      * types of the implemented functions.  The instances will be populated to
3887      * the AutoImplement's scope in a certain way; see the populate() below.
3888      */
3889 
3890     // Returns the preferred identifier for the FuncInfo instance for the i-th
3891     // overloaded function with the name.
3892     template INTERNAL_FUNCINFO_ID(string name, size_t i)
3893     {
3894         import std.format : format;
3895 
3896         enum string INTERNAL_FUNCINFO_ID = format("F_%s_%s", name, i);
3897     }
3898 
3899     /*
3900      * Insert FuncInfo instances about all the target functions here.  This
3901      * enables the generated code to access type information via, for example,
3902      * "autoImplement_helper_.F_foo_1".
3903      */
3904     template populate(overloads...)
3905     {
3906         static if (overloads.length > 0)
3907         {
3908             mixin populate!(overloads[0].name, overloads[0].contents);
3909             mixin populate!(overloads[1 .. $]);
3910         }
3911     }
3912     template populate(string name, methods...)
3913     {
3914         static if (methods.length > 0)
3915         {
3916             mixin populate!(name, methods[0 .. $ - 1]);
3917             //
3918             alias target = methods[$ - 1];
3919             enum ith = methods.length - 1;
3920             mixin("alias " ~ INTERNAL_FUNCINFO_ID!(name, ith) ~ " = FuncInfo!target;");
3921         }
3922     }
3923 
3924     public mixin populate!(targetOverloadSets);
3925     public mixin populate!(  ctorOverloadSet );
3926 
3927 
3928     //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
3929     // Code-generating policies
3930     //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
3931 
3932     /* Common policy configurations for generating constructors and methods. */
3933     template CommonGeneratingPolicy()
3934     {
3935         // base class identifier which generated code should use
3936         enum string BASE_CLASS_ID = baseName;
3937 
3938         // FuncInfo instance identifier which generated code should use
3939         template FUNCINFO_ID(string name, size_t i)
3940         {
3941             enum string FUNCINFO_ID =
3942                 myName ~ "." ~ INTERNAL_FUNCINFO_ID!(name, i);
3943         }
3944     }
3945 
3946     /* Policy configurations for generating constructors. */
3947     template ConstructorGeneratingPolicy()
3948     {
3949         mixin CommonGeneratingPolicy;
3950 
3951         /* Generates constructor body.  Just forward to the base class' one. */
3952         string generateFunctionBody(ctor.../+[BUG 4217]+/)() @property
3953         {
3954             enum varstyle = variadicFunctionStyle!(typeof(&ctor[0]));
3955 
3956             static if (varstyle & (Variadic.c | Variadic.d))
3957             {
3958                 // the argptr-forwarding problem
3959                 //pragma(msg, "Warning: AutoImplement!(", Base, ") ",
3960                 //        "ignored variadic arguments to the constructor ",
3961                 //        FunctionTypeOf!(typeof(&ctor[0])) );
3962             }
3963             return "super(args);";
3964         }
3965     }
3966 
3967     /* Policy configurations for genearting target methods. */
3968     template MethodGeneratingPolicy()
3969     {
3970         mixin CommonGeneratingPolicy;
3971 
3972         /* Geneartes method body. */
3973         string generateFunctionBody(func.../+[BUG 4217]+/)() @property
3974         {
3975             return generateMethodBody!(Base, func); // given
3976         }
3977     }
3978 
3979 
3980     //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
3981     // Generated code
3982     //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
3983 
3984     alias ConstructorGenerator = MemberFunctionGenerator!(ConstructorGeneratingPolicy!());
3985     alias MethodGenerator      = MemberFunctionGenerator!(MethodGeneratingPolicy!());
3986 
3987     public enum string code =
3988         ConstructorGenerator.generateCode!(  ctorOverloadSet ) ~ "\n" ~
3989              MethodGenerator.generateCode!(targetOverloadSets);
3990 
3991     debug (SHOW_GENERATED_CODE)
3992     {
3993         pragma(msg, "-------------------- < ", Base, " >");
3994         pragma(msg, code);
3995         pragma(msg, "--------------------");
3996     }
3997 }
3998 
3999 //debug = SHOW_GENERATED_CODE;
4000 @system unittest
4001 {
4002     import core.vararg;
4003     // no function to implement
4004     {
4005         interface I_1 {}
4006         auto o = new BlackHole!I_1;
4007     }
4008     // parameters
4009     {
4010         interface I_3 { void test(int, in int, out int, ref int, lazy int); }
4011         auto o = new BlackHole!I_3;
4012     }
4013     // use of user-defined type
4014     {
4015         struct S {}
4016         interface I_4 { S test(); }
4017         auto o = new BlackHole!I_4;
4018     }
4019     // overloads
4020     {
4021         interface I_5
4022         {
4023             void test(string);
4024             real test(real);
4025             int  test();
4026         }
4027         auto o = new BlackHole!I_5;
4028     }
4029     // constructor forwarding
4030     {
4031         static class C_6
4032         {
4033             this(int n) { assert(n == 42); }
4034             this(string s) { assert(s == "Deeee"); }
4035             this(...) {}
4036         }
4037         auto o1 = new BlackHole!C_6(42);
4038         auto o2 = new BlackHole!C_6("Deeee");
4039         auto o3 = new BlackHole!C_6(1, 2, 3, 4);
4040     }
4041     // attributes
4042     {
4043         interface I_7
4044         {
4045             ref int test_ref();
4046             int test_pure() pure;
4047             int test_nothrow() nothrow;
4048             int test_property() @property;
4049             int test_safe() @safe;
4050             int test_trusted() @trusted;
4051             int test_system() @system;
4052             int test_pure_nothrow() pure nothrow;
4053         }
4054         auto o = new BlackHole!I_7;
4055     }
4056     // storage classes
4057     {
4058         interface I_8
4059         {
4060             void test_const() const;
4061             void test_immutable() immutable;
4062             void test_shared() shared;
4063             void test_shared_const() shared const;
4064         }
4065         auto o = new BlackHole!I_8;
4066     }
4067     // use baseclass
4068     {
4069         static class C_9
4070         {
4071             private string foo_;
4072 
4073             this(string s) {
4074                 foo_ = s;
4075             }
4076 
4077             protected string boilerplate() @property
4078             {
4079                 return "Boilerplate stuff.";
4080             }
4081 
4082             public string foo() @property
4083             {
4084                 return foo_;
4085             }
4086         }
4087 
4088         interface I_10
4089         {
4090             string testMethod(size_t);
4091         }
4092 
4093         static string generateTestMethod(C, alias fun)() @property
4094         {
4095             return "return this.boilerplate[0 .. a0];";
4096         }
4097 
4098         auto o = new AutoImplement!(I_10, C_9, generateTestMethod)("Testing");
4099         assert(o.testMethod(11) == "Boilerplate");
4100         assert(o.foo == "Testing");
4101     }
4102     /+ // deep inheritance
4103     {
4104     // XXX [BUG 2525,3525]
4105     // NOTE: [r494] func.c(504-571) FuncDeclaration::semantic()
4106         interface I { void foo(); }
4107         interface J : I {}
4108         interface K : J {}
4109         static abstract class C_9 : K {}
4110         auto o = new BlackHole!C_9;
4111     }+/
4112 }
4113 
4114 // Issue 17177 - AutoImplement fails on function overload sets with "cannot infer type from overloaded function symbol"
4115 @system unittest
4116 {
4117     static class Issue17177
4118     {
4119         private string n_;
4120 
4121         public {
4122             Issue17177 overloaded(string n)
4123             {
4124                 this.n_ = n;
4125 
4126                 return this;
4127             }
4128 
4129             string overloaded()
4130             {
4131                 return this.n_;
4132             }
4133         }
4134     }
4135 
4136     static string how(C, alias fun)()
4137     {
4138         static if (!is(ReturnType!fun == void))
4139         {
4140             return q{
4141                 return parent(args);
4142             };
4143         }
4144         else
4145         {
4146             return q{
4147                 parent(args);
4148             };
4149         }
4150     }
4151 
4152     alias Implementation = AutoImplement!(Issue17177, how, templateNot!isFinalFunction);
4153 }
4154 
4155 version (unittest)
4156 {
4157     // Issue 10647
4158     // Add prefix "issue10647_" as a workaround for issue 1238
4159     private string issue10647_generateDoNothing(C, alias fun)() @property
4160     {
4161         string stmt;
4162 
4163         static if (is(ReturnType!fun == void))
4164             stmt ~= "";
4165         else
4166         {
4167             string returnType = ReturnType!fun.stringof;
4168             stmt ~= "return "~returnType~".init;";
4169         }
4170         return stmt;
4171     }
4172 
4173     private template issue10647_isAlwaysTrue(alias fun)
4174     {
4175         enum issue10647_isAlwaysTrue = true;
4176     }
4177 
4178     // Do nothing template
4179     private template issue10647_DoNothing(Base)
4180     {
4181         alias issue10647_DoNothing = AutoImplement!(Base, issue10647_generateDoNothing, issue10647_isAlwaysTrue);
4182     }
4183 
4184     // A class to be overridden
4185     private class issue10647_Foo{
4186         void bar(int a) { }
4187     }
4188 }
4189 @system unittest
4190 {
4191     auto foo = new issue10647_DoNothing!issue10647_Foo();
4192     foo.bar(13);
4193 }
4194 
4195 /*
4196 Used by MemberFunctionGenerator.
4197  */
4198 package template OverloadSet(string nam, T...)
4199 {
4200     enum string name = nam;
4201     alias contents = T;
4202 }
4203 
4204 /*
4205 Used by MemberFunctionGenerator.
4206  */
4207 package template FuncInfo(alias func, /+[BUG 4217 ?]+/ T = typeof(&func))
4208 {
4209     alias RT = ReturnType!T;
4210     alias PT = Parameters!T;
4211 }
4212 package template FuncInfo(Func)
4213 {
4214     alias RT = ReturnType!Func;
4215     alias PT = Parameters!Func;
4216 }
4217 
4218 /*
4219 General-purpose member function generator.
4220 --------------------
4221 template GeneratingPolicy()
4222 {
4223     // [optional] the name of the class where functions are derived
4224     enum string BASE_CLASS_ID;
4225 
4226     // [optional] define this if you have only function types
4227     enum bool WITHOUT_SYMBOL;
4228 
4229     // [optional] Returns preferred identifier for i-th parameter.
4230     template PARAMETER_VARIABLE_ID(size_t i);
4231 
4232     // Returns the identifier of the FuncInfo instance for the i-th overload
4233     // of the specified name.  The identifier must be accessible in the scope
4234     // where generated code is mixed.
4235     template FUNCINFO_ID(string name, size_t i);
4236 
4237     // Returns implemented function body as a string.  When WITHOUT_SYMBOL is
4238     // defined, the latter is used.
4239     template generateFunctionBody(alias func);
4240     template generateFunctionBody(string name, FuncType);
4241 }
4242 --------------------
4243  */
4244 package template MemberFunctionGenerator(alias Policy)
4245 {
4246 private static:
4247     //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
4248     // Internal stuffs
4249     //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
4250     import std.format;
4251 
4252     enum CONSTRUCTOR_NAME = "__ctor";
4253 
4254     // true if functions are derived from a base class
4255     enum WITH_BASE_CLASS = __traits(hasMember, Policy, "BASE_CLASS_ID");
4256 
4257     // true if functions are specified as types, not symbols
4258     enum WITHOUT_SYMBOL = __traits(hasMember, Policy, "WITHOUT_SYMBOL");
4259 
4260     // preferred identifier for i-th parameter variable
4261     static if (__traits(hasMember, Policy, "PARAMETER_VARIABLE_ID"))
4262     {
4263         alias PARAMETER_VARIABLE_ID = Policy.PARAMETER_VARIABLE_ID;
4264     }
4265     else
4266     {
4267         enum string PARAMETER_VARIABLE_ID(size_t i) = format("a%s", i);
4268             // default: a0, a1, ...
4269     }
4270 
4271     // Returns a tuple consisting of 0,1,2,...,n-1.  For static foreach.
4272     template CountUp(size_t n)
4273     {
4274         static if (n > 0)
4275             alias CountUp = AliasSeq!(CountUp!(n - 1), n - 1);
4276         else
4277             alias CountUp = AliasSeq!();
4278     }
4279 
4280 
4281     //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
4282     // Code generator
4283     //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::://
4284 
4285     /*
4286      * Runs through all the target overload sets and generates D code which
4287      * implements all the functions in the overload sets.
4288      */
4289     public string generateCode(overloads...)() @property
4290     {
4291         string code = "";
4292 
4293         // run through all the overload sets
4294         foreach (i_; CountUp!(0 + overloads.length)) // workaround
4295         {
4296             enum i = 0 + i_; // workaround
4297             alias oset = overloads[i];
4298 
4299             code ~= generateCodeForOverloadSet!(oset);
4300 
4301             static if (WITH_BASE_CLASS && oset.name != CONSTRUCTOR_NAME)
4302             {
4303                 // The generated function declarations may hide existing ones
4304                 // in the base class (cf. HiddenFuncError), so we put an alias
4305                 // declaration here to reveal possible hidden functions.
4306                 code ~= format("alias %s = %s.%s;\n",
4307                             oset.name,
4308                             Policy.BASE_CLASS_ID, // [BUG 2540] super.
4309                             oset.name);
4310             }
4311         }
4312         return code;
4313     }
4314 
4315     // handle each overload set
4316     private string generateCodeForOverloadSet(alias oset)() @property
4317     {
4318         string code = "";
4319 
4320         foreach (i_; CountUp!(0 + oset.contents.length)) // workaround
4321         {
4322             enum i = 0 + i_; // workaround
4323             code ~= generateFunction!(
4324                     Policy.FUNCINFO_ID!(oset.name, i), oset.name,
4325                     oset.contents[i]) ~ "\n";
4326         }
4327         return code;
4328     }
4329 
4330     /*
4331      * Returns D code which implements the function func.  This function
4332      * actually generates only the declarator part; the function body part is
4333      * generated by the functionGenerator() policy.
4334      */
4335     public string generateFunction(
4336             string myFuncInfo, string name, func... )() @property
4337     {
4338         import std.format : format;
4339 
4340         enum isCtor = (name == CONSTRUCTOR_NAME);
4341 
4342         string code; // the result
4343 
4344         auto paramsRes = generateParameters!(myFuncInfo, func)();
4345         code ~= paramsRes.imports;
4346 
4347         /*** Function Declarator ***/
4348         {
4349             alias Func = FunctionTypeOf!(func);
4350             alias FA = FunctionAttribute;
4351             enum atts     = functionAttributes!(func);
4352             enum realName = isCtor ? "this" : name;
4353 
4354             // FIXME?? Make it so that these aren't CTFE funcs any more, since
4355             // Format is deprecated, and format works at compile time?
4356             /* Made them CTFE funcs just for the sake of Format!(...) */
4357 
4358             // return type with optional "ref"
4359             static string make_returnType()
4360             {
4361                 string rtype = "";
4362 
4363                 if (!isCtor)
4364                 {
4365                     if (atts & FA.ref_) rtype ~= "ref ";
4366                     rtype ~= myFuncInfo ~ ".RT";
4367                 }
4368                 return rtype;
4369             }
4370             enum returnType = make_returnType();
4371 
4372             // function attributes attached after declaration
4373             static string make_postAtts()
4374             {
4375                 string poatts = "";
4376                 if (atts & FA.pure_   ) poatts ~= " pure";
4377                 if (atts & FA.nothrow_) poatts ~= " nothrow";
4378                 if (atts & FA.property) poatts ~= " @property";
4379                 if (atts & FA.safe    ) poatts ~= " @safe";
4380                 if (atts & FA.trusted ) poatts ~= " @trusted";
4381                 return poatts;
4382             }
4383             enum postAtts = make_postAtts();
4384 
4385             // function storage class
4386             static string make_storageClass()
4387             {
4388                 string postc = "";
4389                 if (is(Func ==    shared)) postc ~= " shared";
4390                 if (is(Func ==     const)) postc ~= " const";
4391                 if (is(Func ==     inout)) postc ~= " inout";
4392                 if (is(Func == immutable)) postc ~= " immutable";
4393                 return postc;
4394             }
4395             enum storageClass = make_storageClass();
4396 
4397             //
4398             if (__traits(isVirtualMethod, func))
4399                 code ~= "override ";
4400             code ~= format("extern(%s) %s %s(%s) %s %s\n",
4401                     functionLinkage!(func),
4402                     returnType,
4403                     realName,
4404                     paramsRes.params,
4405                     postAtts, storageClass );
4406         }
4407 
4408         /*** Function Body ***/
4409         code ~= "{\n";
4410         {
4411             enum nparams = Parameters!(func).length;
4412 
4413             /* Declare keywords: args, self and parent. */
4414             string preamble;
4415 
4416             preamble ~= "alias args = AliasSeq!(" ~ enumerateParameters!(nparams) ~ ");\n";
4417             if (!isCtor)
4418             {
4419                 preamble ~= "alias self = " ~ name ~ ";\n";
4420                 if (WITH_BASE_CLASS && !__traits(isAbstractFunction, func))
4421                     preamble ~= "alias parent = AliasSeq!(__traits(getMember, super, \"" ~ name ~ "\"))[0];";
4422             }
4423 
4424             // Function body
4425             static if (WITHOUT_SYMBOL)
4426                 enum fbody = Policy.generateFunctionBody!(name, func);
4427             else
4428                 enum fbody = Policy.generateFunctionBody!(func);
4429 
4430             code ~= preamble;
4431             code ~= fbody;
4432         }
4433         code ~= "}";
4434 
4435         return code;
4436     }
4437 
4438     /*
4439      * Returns D code which declares function parameters,
4440      * and optionally any imports (e.g. core.vararg)
4441      * "ref int a0, real a1, ..."
4442      */
4443     static struct GenParams { string imports, params; }
4444     private GenParams generateParameters(string myFuncInfo, func...)()
4445     {
4446         alias STC = ParameterStorageClass;
4447         alias stcs = ParameterStorageClassTuple!(func);
4448         enum nparams = stcs.length;
4449 
4450         string imports = ""; // any imports required
4451         string params = ""; // parameters
4452 
4453         foreach (i, stc; stcs)
4454         {
4455             if (i > 0) params ~= ", ";
4456 
4457             // Parameter storage classes.
4458             if (stc & STC.scope_) params ~= "scope ";
4459             if (stc & STC.out_  ) params ~= "out ";
4460             if (stc & STC.ref_  ) params ~= "ref ";
4461             if (stc & STC.lazy_ ) params ~= "lazy ";
4462 
4463             // Take parameter type from the FuncInfo.
4464             params ~= format("%s.PT[%s]", myFuncInfo, i);
4465 
4466             // Declare a parameter variable.
4467             params ~= " " ~ PARAMETER_VARIABLE_ID!(i);
4468         }
4469 
4470         // Add some ellipsis part if needed.
4471         auto style = variadicFunctionStyle!(func);
4472         final switch (style)
4473         {
4474             case Variadic.no:
4475                 break;
4476 
4477             case Variadic.c, Variadic.d:
4478                 imports ~= "import core.vararg;\n";
4479                 // (...) or (a, b, ...)
4480                 params ~= (nparams == 0) ? "..." : ", ...";
4481                 break;
4482 
4483             case Variadic.typesafe:
4484                 params ~= " ...";
4485                 break;
4486         }
4487 
4488         return typeof(return)(imports, params);
4489     }
4490 
4491     // Returns D code which enumerates n parameter variables using comma as the
4492     // separator.  "a0, a1, a2, a3"
4493     private string enumerateParameters(size_t n)() @property
4494     {
4495         string params = "";
4496 
4497         foreach (i_; CountUp!(n))
4498         {
4499             enum i = 0 + i_; // workaround
4500             if (i > 0) params ~= ", ";
4501             params ~= PARAMETER_VARIABLE_ID!(i);
4502         }
4503         return params;
4504     }
4505 }
4506 
4507 
4508 /**
4509 Predefined how-policies for $(D AutoImplement).  These templates are also used by
4510 $(D BlackHole) and $(D WhiteHole), respectively.
4511  */
4512 template generateEmptyFunction(C, func.../+[BUG 4217]+/)
4513 {
4514     static if (is(ReturnType!(func) == void))
4515         enum string generateEmptyFunction = q{
4516         };
4517     else static if (functionAttributes!(func) & FunctionAttribute.ref_)
4518         enum string generateEmptyFunction = q{
4519             static typeof(return) dummy;
4520             return dummy;
4521         };
4522     else
4523         enum string generateEmptyFunction = q{
4524             return typeof(return).init;
4525         };
4526 }
4527 
4528 /// ditto
4529 template generateAssertTrap(C, func...)
4530 {
4531     enum string generateAssertTrap =
4532         `throw new NotImplementedError("` ~ C.stringof ~ "."
4533                 ~ __traits(identifier, func) ~ `");`;
4534 }
4535 
4536 private
4537 {
4538     pragma(mangle, "_d_toObject")
4539     extern(C) pure nothrow Object typecons_d_toObject(void* p);
4540 }
4541 
4542 /*
4543  * Avoids opCast operator overloading.
4544  */
4545 private template dynamicCast(T)
4546 if (is(T == class) || is(T == interface))
4547 {
4548     @trusted
4549     T dynamicCast(S)(inout S source)
4550     if (is(S == class) || is(S == interface))
4551     {
4552         static if (is(Unqual!S : Unqual!T))
4553         {
4554             import std.traits : QualifierOf;
4555             alias Qual = QualifierOf!S; // SharedOf or MutableOf
4556             alias TmpT = Qual!(Unqual!T);
4557             inout(TmpT) tmp = source;   // bypass opCast by implicit conversion
4558             return *cast(T*)(&tmp);     // + variable pointer cast + dereference
4559         }
4560         else
4561         {
4562             return cast(T) typecons_d_toObject(*cast(void**)(&source));
4563         }
4564     }
4565 }
4566 
4567 @system unittest
4568 {
4569     class C { @disable opCast(T)() {} }
4570     auto c = new C;
4571     static assert(!__traits(compiles, cast(Object) c));
4572     auto o = dynamicCast!Object(c);
4573     assert(c is o);
4574 
4575     interface I { @disable opCast(T)() {} Object instance(); }
4576     interface J { @disable opCast(T)() {} Object instance(); }
4577     class D : I, J { Object instance() { return this; } }
4578     I i = new D();
4579     static assert(!__traits(compiles, cast(J) i));
4580     J j = dynamicCast!J(i);
4581     assert(i.instance() is j.instance());
4582 }
4583 
4584 /**
4585  * Supports structural based typesafe conversion.
4586  *
4587  * If $(D Source) has structural conformance with the $(D interface) $(D Targets),
4588  * wrap creates internal wrapper class which inherits $(D Targets) and
4589  * wrap $(D src) object, then return it.
4590  */
4591 template wrap(Targets...)
4592 if (Targets.length >= 1 && allSatisfy!(isMutable, Targets))
4593 {
4594     import std.meta : staticMap;
4595 
4596     // strict upcast
4597     auto wrap(Source)(inout Source src) @trusted pure nothrow
4598     if (Targets.length == 1 && is(Source : Targets[0]))
4599     {
4600         alias T = Select!(is(Source == shared), shared Targets[0], Targets[0]);
4601         return dynamicCast!(inout T)(src);
4602     }
4603     // structural upcast
4604     template wrap(Source)
4605     if (!allSatisfy!(Bind!(isImplicitlyConvertible, Source), Targets))
4606     {
4607         auto wrap(inout Source src)
4608         {
4609             static assert(hasRequireMethods!(),
4610                           "Source "~Source.stringof~
4611                           " does not have structural conformance to "~
4612                           Targets.stringof);
4613 
4614             alias T = Select!(is(Source == shared), shared Impl, Impl);
4615             return new inout T(src);
4616         }
4617 
4618         template FuncInfo(string s, F)
4619         {
4620             enum name = s;
4621             alias type = F;
4622         }
4623 
4624         // Concat all Targets function members into one tuple
4625         template Concat(size_t i = 0)
4626         {
4627             static if (i >= Targets.length)
4628                 alias Concat = AliasSeq!();
4629             else
4630             {
4631                 alias Concat = AliasSeq!(GetOverloadedMethods!(Targets[i]), Concat!(i + 1));
4632             }
4633         }
4634         // Remove duplicated functions based on the identifier name and function type covariance
4635         template Uniq(members...)
4636         {
4637             static if (members.length == 0)
4638                 alias Uniq = AliasSeq!();
4639             else
4640             {
4641                 alias func = members[0];
4642                 enum  name = __traits(identifier, func);
4643                 alias type = FunctionTypeOf!func;
4644                 template check(size_t i, mem...)
4645                 {
4646                     static if (i >= mem.length)
4647                         enum ptrdiff_t check = -1;
4648                     else
4649                     {
4650                         enum ptrdiff_t check =
4651                             __traits(identifier, func) == __traits(identifier, mem[i]) &&
4652                             !is(DerivedFunctionType!(type, FunctionTypeOf!(mem[i])) == void)
4653                           ? i : check!(i + 1, mem);
4654                     }
4655                 }
4656                 enum ptrdiff_t x = 1 + check!(0, members[1 .. $]);
4657                 static if (x >= 1)
4658                 {
4659                     alias typex = DerivedFunctionType!(type, FunctionTypeOf!(members[x]));
4660                     alias remain = Uniq!(members[1 .. x], members[x + 1 .. $]);
4661 
4662                     static if (remain.length >= 1 && remain[0].name == name &&
4663                                !is(DerivedFunctionType!(typex, remain[0].type) == void))
4664                     {
4665                         alias F = DerivedFunctionType!(typex, remain[0].type);
4666                         alias Uniq = AliasSeq!(FuncInfo!(name, F), remain[1 .. $]);
4667                     }
4668                     else
4669                         alias Uniq = AliasSeq!(FuncInfo!(name, typex), remain);
4670                 }
4671                 else
4672                 {
4673                     alias Uniq = AliasSeq!(FuncInfo!(name, type), Uniq!(members[1 .. $]));
4674                 }
4675             }
4676         }
4677         alias TargetMembers = Uniq!(Concat!());             // list of FuncInfo
4678         alias SourceMembers = GetOverloadedMethods!Source;  // list of function symbols
4679 
4680         // Check whether all of SourceMembers satisfy covariance target in TargetMembers
4681         template hasRequireMethods(size_t i = 0)
4682         {
4683             static if (i >= TargetMembers.length)
4684                 enum hasRequireMethods = true;
4685             else
4686             {
4687                 enum hasRequireMethods =
4688                     findCovariantFunction!(TargetMembers[i], Source, SourceMembers) != -1 &&
4689                     hasRequireMethods!(i + 1);
4690             }
4691         }
4692 
4693         // Internal wrapper class
4694         final class Impl : Structural, Targets
4695         {
4696         private:
4697             Source _wrap_source;
4698 
4699             this(       inout Source s)        inout @safe pure nothrow { _wrap_source = s; }
4700             this(shared inout Source s) shared inout @safe pure nothrow { _wrap_source = s; }
4701 
4702             // BUG: making private should work with NVI.
4703             protected final inout(Object) _wrap_getSource() inout @trusted
4704             {
4705                 return dynamicCast!(inout Object)(_wrap_source);
4706             }
4707 
4708             import std.conv : to;
4709             import std.functional : forward;
4710             template generateFun(size_t i)
4711             {
4712                 enum name = TargetMembers[i].name;
4713                 enum fa = functionAttributes!(TargetMembers[i].type);
4714                 static @property stc()
4715                 {
4716                     string r;
4717                     if (fa & FunctionAttribute.property)    r ~= "@property ";
4718                     if (fa & FunctionAttribute.ref_)        r ~= "ref ";
4719                     if (fa & FunctionAttribute.pure_)       r ~= "pure ";
4720                     if (fa & FunctionAttribute.nothrow_)    r ~= "nothrow ";
4721                     if (fa & FunctionAttribute.trusted)     r ~= "@trusted ";
4722                     if (fa & FunctionAttribute.safe)        r ~= "@safe ";
4723                     return r;
4724                 }
4725                 static @property mod()
4726                 {
4727                     alias type = AliasSeq!(TargetMembers[i].type)[0];
4728                     string r;
4729                     static if (is(type == immutable))       r ~= " immutable";
4730                     else
4731                     {
4732                         static if (is(type == shared))      r ~= " shared";
4733                         static if (is(type == const))       r ~= " const";
4734                         else static if (is(type == inout))  r ~= " inout";
4735                         //else  --> mutable
4736                     }
4737                     return r;
4738                 }
4739                 enum n = to!string(i);
4740                 static if (fa & FunctionAttribute.property)
4741                 {
4742                     static if (Parameters!(TargetMembers[i].type).length == 0)
4743                         enum fbody = "_wrap_source."~name;
4744                     else
4745                         enum fbody = "_wrap_source."~name~" = forward!args";
4746                 }
4747                 else
4748                 {
4749                         enum fbody = "_wrap_source."~name~"(forward!args)";
4750                 }
4751                 enum generateFun =
4752                     "override "~stc~"ReturnType!(TargetMembers["~n~"].type) "
4753                     ~ name~"(Parameters!(TargetMembers["~n~"].type) args) "~mod~
4754                     "{ return "~fbody~"; }";
4755             }
4756 
4757         public:
4758             mixin mixinAll!(
4759                 staticMap!(generateFun, staticIota!(0, TargetMembers.length)));
4760         }
4761     }
4762 }
4763 /// ditto
4764 template wrap(Targets...)
4765 if (Targets.length >= 1 && !allSatisfy!(isMutable, Targets))
4766 {
4767     import std.meta : staticMap;
4768 
4769     alias wrap = .wrap!(staticMap!(Unqual, Targets));
4770 }
4771 
4772 // Internal class to support dynamic cross-casting
4773 private interface Structural
4774 {
4775     inout(Object) _wrap_getSource() inout @safe pure nothrow;
4776 }
4777 
4778 /**
4779  * Extract object which wrapped by $(D wrap).
4780  */
4781 template unwrap(Target)
4782 if (isMutable!Target)
4783 {
4784     // strict downcast
4785     auto unwrap(Source)(inout Source src) @trusted pure nothrow
4786     if (is(Target : Source))
4787     {
4788         alias T = Select!(is(Source == shared), shared Target, Target);
4789         return dynamicCast!(inout T)(src);
4790     }
4791     // structural downcast
4792     auto unwrap(Source)(inout Source src) @trusted pure nothrow
4793     if (!is(Target : Source))
4794     {
4795         alias T = Select!(is(Source == shared), shared Target, Target);
4796         Object o = dynamicCast!(Object)(src);   // remove qualifier
4797         do
4798         {
4799             if (auto a = dynamicCast!(Structural)(o))
4800             {
4801                 if (auto d = dynamicCast!(inout T)(o = a._wrap_getSource()))
4802                     return d;
4803             }
4804             else if (auto d = dynamicCast!(inout T)(o))
4805                 return d;
4806             else
4807                 break;
4808         } while (o);
4809         return null;
4810     }
4811 }
4812 /// ditto
4813 template unwrap(Target)
4814 if (!isMutable!Target)
4815 {
4816     alias unwrap = .unwrap!(Unqual!Target);
4817 }
4818 
4819 ///
4820 @system unittest
4821 {
4822     interface Quack
4823     {
4824         int quack();
4825         @property int height();
4826     }
4827     interface Flyer
4828     {
4829         @property int height();
4830     }
4831     class Duck : Quack
4832     {
4833         int quack() { return 1; }
4834         @property int height() { return 10; }
4835     }
4836     class Human
4837     {
4838         int quack() { return 2; }
4839         @property int height() { return 20; }
4840     }
4841 
4842     Duck d1 = new Duck();
4843     Human h1 = new Human();
4844 
4845     interface Refleshable
4846     {
4847         int reflesh();
4848     }
4849     // does not have structural conformance
4850     static assert(!__traits(compiles, d1.wrap!Refleshable));
4851     static assert(!__traits(compiles, h1.wrap!Refleshable));
4852 
4853     // strict upcast
4854     Quack qd = d1.wrap!Quack;
4855     assert(qd is d1);
4856     assert(qd.quack() == 1);    // calls Duck.quack
4857     // strict downcast
4858     Duck d2 = qd.unwrap!Duck;
4859     assert(d2 is d1);
4860 
4861     // structural upcast
4862     Quack qh = h1.wrap!Quack;
4863     assert(qh.quack() == 2);    // calls Human.quack
4864     // structural downcast
4865     Human h2 = qh.unwrap!Human;
4866     assert(h2 is h1);
4867 
4868     // structural upcast (two steps)
4869     Quack qx = h1.wrap!Quack;   // Human -> Quack
4870     Flyer fx = qx.wrap!Flyer;   // Quack -> Flyer
4871     assert(fx.height == 20);    // calls Human.height
4872     // strucural downcast (two steps)
4873     Quack qy = fx.unwrap!Quack; // Flyer -> Quack
4874     Human hy = qy.unwrap!Human; // Quack -> Human
4875     assert(hy is h1);
4876     // strucural downcast (one step)
4877     Human hz = fx.unwrap!Human; // Flyer -> Human
4878     assert(hz is h1);
4879 }
4880 ///
4881 @system unittest
4882 {
4883     import std.traits : FunctionAttribute, functionAttributes;
4884     interface A { int run(); }
4885     interface B { int stop(); @property int status(); }
4886     class X
4887     {
4888         int run() { return 1; }
4889         int stop() { return 2; }
4890         @property int status() { return 3; }
4891     }
4892 
4893     auto x = new X();
4894     auto ab = x.wrap!(A, B);
4895     A a = ab;
4896     B b = ab;
4897     assert(a.run() == 1);
4898     assert(b.stop() == 2);
4899     assert(b.status == 3);
4900     static assert(functionAttributes!(typeof(ab).status) & FunctionAttribute.property);
4901 }
4902 @system unittest
4903 {
4904     class A
4905     {
4906         int draw()              { return 1; }
4907         int draw(int v)         { return v; }
4908 
4909         int draw() const        { return 2; }
4910         int draw() shared       { return 3; }
4911         int draw() shared const { return 4; }
4912         int draw() immutable    { return 5; }
4913     }
4914     interface Drawable
4915     {
4916         int draw();
4917         int draw() const;
4918         int draw() shared;
4919         int draw() shared const;
4920         int draw() immutable;
4921     }
4922     interface Drawable2
4923     {
4924         int draw(int v);
4925     }
4926 
4927     auto ma = new A();
4928     auto sa = new shared A();
4929     auto ia = new immutable A();
4930     {
4931                      Drawable  md = ma.wrap!Drawable;
4932                const Drawable  cd = ma.wrap!Drawable;
4933               shared Drawable  sd = sa.wrap!Drawable;
4934         shared const Drawable scd = sa.wrap!Drawable;
4935            immutable Drawable  id = ia.wrap!Drawable;
4936         assert( md.draw() == 1);
4937         assert( cd.draw() == 2);
4938         assert( sd.draw() == 3);
4939         assert(scd.draw() == 4);
4940         assert( id.draw() == 5);
4941     }
4942     {
4943         Drawable2 d = ma.wrap!Drawable2;
4944         static assert(!__traits(compiles, d.draw()));
4945         assert(d.draw(10) == 10);
4946     }
4947 }
4948 @system unittest
4949 {
4950     // Bugzilla 10377
4951     import std.range, std.algorithm;
4952 
4953     interface MyInputRange(T)
4954     {
4955         @property T front();
4956         void popFront();
4957         @property bool empty();
4958     }
4959 
4960     //auto o = iota(0,10,1).inputRangeObject();
4961     //pragma(msg, __traits(allMembers, typeof(o)));
4962     auto r = iota(0,10,1).inputRangeObject().wrap!(MyInputRange!int)();
4963     assert(equal(r, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
4964 }
4965 @system unittest
4966 {
4967     // Bugzilla 10536
4968     interface Interface
4969     {
4970         int foo();
4971     }
4972     class Pluggable
4973     {
4974         int foo() { return 1; }
4975         @disable void opCast(T, this X)();  // !
4976     }
4977 
4978     Interface i = new Pluggable().wrap!Interface;
4979     assert(i.foo() == 1);
4980 }
4981 @system unittest
4982 {
4983     // Enhancement 10538
4984     interface Interface
4985     {
4986         int foo();
4987         int bar(int);
4988     }
4989     class Pluggable
4990     {
4991         int opDispatch(string name, A...)(A args) { return 100; }
4992     }
4993 
4994     Interface i = wrap!Interface(new Pluggable());
4995     assert(i.foo() == 100);
4996     assert(i.bar(10) == 100);
4997 }
4998 
4999 // Make a tuple of non-static function symbols
5000 package template GetOverloadedMethods(T)
5001 {
5002     import std.meta : Filter;
5003 
5004     alias allMembers = AliasSeq!(__traits(allMembers, T));
5005     template follows(size_t i = 0)
5006     {
5007         static if (i >= allMembers.length)
5008         {
5009             alias follows = AliasSeq!();
5010         }
5011         else static if (!__traits(compiles, mixin("T."~allMembers[i])))
5012         {
5013             alias follows = follows!(i + 1);
5014         }
5015         else
5016         {
5017             enum name = allMembers[i];
5018 
5019             template isMethod(alias f)
5020             {
5021                 static if (is(typeof(&f) F == F*) && is(F == function))
5022                     enum isMethod = !__traits(isStaticFunction, f);
5023                 else
5024                     enum isMethod = false;
5025             }
5026             alias follows = AliasSeq!(
5027                 std.meta.Filter!(isMethod, __traits(getOverloads, T, name)),
5028                 follows!(i + 1));
5029         }
5030     }
5031     alias GetOverloadedMethods = follows!();
5032 }
5033 // find a function from Fs that has same identifier and covariant type with f
5034 private template findCovariantFunction(alias finfo, Source, Fs...)
5035 {
5036     template check(size_t i = 0)
5037     {
5038         static if (i >= Fs.length)
5039             enum ptrdiff_t check = -1;
5040         else
5041         {
5042             enum ptrdiff_t check =
5043                 (finfo.name == __traits(identifier, Fs[i])) &&
5044                 isCovariantWith!(FunctionTypeOf!(Fs[i]), finfo.type)
5045               ? i : check!(i + 1);
5046         }
5047     }
5048     enum x = check!();
5049     static if (x == -1 && is(typeof(Source.opDispatch)))
5050     {
5051         alias Params = Parameters!(finfo.type);
5052         enum ptrdiff_t findCovariantFunction =
5053             is(typeof((             Source).init.opDispatch!(finfo.name)(Params.init))) ||
5054             is(typeof((       const Source).init.opDispatch!(finfo.name)(Params.init))) ||
5055             is(typeof((   immutable Source).init.opDispatch!(finfo.name)(Params.init))) ||
5056             is(typeof((      shared Source).init.opDispatch!(finfo.name)(Params.init))) ||
5057             is(typeof((shared const Source).init.opDispatch!(finfo.name)(Params.init)))
5058           ? ptrdiff_t.max : -1;
5059     }
5060     else
5061         enum ptrdiff_t findCovariantFunction = x;
5062 }
5063 
5064 private enum TypeModifier
5065 {
5066     mutable     = 0,    // type is mutable
5067     const_      = 1,    // type is const
5068     immutable_  = 2,    // type is immutable
5069     shared_     = 4,    // type is shared
5070     inout_      = 8,    // type is wild
5071 }
5072 private template TypeMod(T)
5073 {
5074     static if (is(T == immutable))
5075     {
5076         enum mod1 = TypeModifier.immutable_;
5077         enum mod2 = 0;
5078     }
5079     else
5080     {
5081         enum mod1 = is(T == shared) ? TypeModifier.shared_ : 0;
5082         static if (is(T == const))
5083             enum mod2 = TypeModifier.const_;
5084         else static if (is(T == inout))
5085             enum mod2 = TypeModifier.inout_;
5086         else
5087             enum mod2 = TypeModifier.mutable;
5088     }
5089     enum TypeMod = cast(TypeModifier)(mod1 | mod2);
5090 }
5091 
5092 version (unittest)
5093 {
5094     private template UnittestFuncInfo(alias f)
5095     {
5096         enum name = __traits(identifier, f);
5097         alias type = FunctionTypeOf!f;
5098     }
5099 }
5100 @system unittest
5101 {
5102     class A
5103     {
5104         int draw() { return 1; }
5105         @property int value() { return 2; }
5106         final int run() { return 3; }
5107     }
5108     alias methods = GetOverloadedMethods!A;
5109 
5110     alias int F1();
5111     alias @property int F2();
5112     alias string F3();
5113     alias nothrow @trusted uint F4();
5114     alias int F5(Object);
5115     alias bool F6(Object);
5116     static assert(methods.length == 3 + 4);
5117     static assert(__traits(identifier, methods[0]) == "draw"     && is(typeof(&methods[0]) == F1*));
5118     static assert(__traits(identifier, methods[1]) == "value"    && is(typeof(&methods[1]) == F2*));
5119     static assert(__traits(identifier, methods[2]) == "run"      && is(typeof(&methods[2]) == F1*));
5120 
5121     int draw();
5122     @property int value();
5123     void opEquals();
5124     int nomatch();
5125     static assert(findCovariantFunction!(UnittestFuncInfo!draw,     A, methods) == 0);
5126     static assert(findCovariantFunction!(UnittestFuncInfo!value,    A, methods) == 1);
5127     static assert(findCovariantFunction!(UnittestFuncInfo!opEquals, A, methods) == -1);
5128     static assert(findCovariantFunction!(UnittestFuncInfo!nomatch,  A, methods) == -1);
5129 
5130     // considering opDispatch
5131     class B
5132     {
5133         void opDispatch(string name, A...)(A) {}
5134     }
5135     alias methodsB = GetOverloadedMethods!B;
5136     static assert(findCovariantFunction!(UnittestFuncInfo!draw,     B, methodsB) == ptrdiff_t.max);
5137     static assert(findCovariantFunction!(UnittestFuncInfo!value,    B, methodsB) == ptrdiff_t.max);
5138     static assert(findCovariantFunction!(UnittestFuncInfo!opEquals, B, methodsB) == ptrdiff_t.max);
5139     static assert(findCovariantFunction!(UnittestFuncInfo!nomatch,  B, methodsB) == ptrdiff_t.max);
5140 }
5141 
5142 package template DerivedFunctionType(T...)
5143 {
5144     static if (!T.length)
5145     {
5146         alias DerivedFunctionType = void;
5147     }
5148     else static if (T.length == 1)
5149     {
5150         static if (is(T[0] == function))
5151         {
5152             alias DerivedFunctionType = T[0];
5153         }
5154         else
5155         {
5156             alias DerivedFunctionType = void;
5157         }
5158     }
5159     else static if (is(T[0] P0 == function) && is(T[1] P1 == function))
5160     {
5161         alias FA = FunctionAttribute;
5162 
5163         alias F0 = T[0], R0 = ReturnType!F0, PSTC0 = ParameterStorageClassTuple!F0;
5164         alias F1 = T[1], R1 = ReturnType!F1, PSTC1 = ParameterStorageClassTuple!F1;
5165         enum FA0 = functionAttributes!F0;
5166         enum FA1 = functionAttributes!F1;
5167 
5168         template CheckParams(size_t i = 0)
5169         {
5170             static if (i >= P0.length)
5171                 enum CheckParams = true;
5172             else
5173             {
5174                 enum CheckParams = (is(P0[i] == P1[i]) && PSTC0[i] == PSTC1[i]) &&
5175                                    CheckParams!(i + 1);
5176             }
5177         }
5178         static if (R0.sizeof == R1.sizeof && !is(CommonType!(R0, R1) == void) &&
5179                    P0.length == P1.length && CheckParams!() && TypeMod!F0 == TypeMod!F1 &&
5180                    variadicFunctionStyle!F0 == variadicFunctionStyle!F1 &&
5181                    functionLinkage!F0 == functionLinkage!F1 &&
5182                    ((FA0 ^ FA1) & (FA.ref_ | FA.property)) == 0)
5183         {
5184             alias R = Select!(is(R0 : R1), R0, R1);
5185             alias FX = FunctionTypeOf!(R function(P0));
5186             // @system is default
5187             alias FY = SetFunctionAttributes!(FX, functionLinkage!F0, (FA0 | FA1) & ~FA.system);
5188             alias DerivedFunctionType = DerivedFunctionType!(FY, T[2 .. $]);
5189         }
5190         else
5191             alias DerivedFunctionType = void;
5192     }
5193     else
5194         alias DerivedFunctionType = void;
5195 }
5196 @safe unittest
5197 {
5198     // attribute covariance
5199     alias int F1();
5200     static assert(is(DerivedFunctionType!(F1, F1) == F1));
5201     alias int F2() pure nothrow;
5202     static assert(is(DerivedFunctionType!(F1, F2) == F2));
5203     alias int F3() @safe;
5204     alias int F23() @safe pure nothrow;
5205     static assert(is(DerivedFunctionType!(F2, F3) == F23));
5206 
5207     // return type covariance
5208     alias long F4();
5209     static assert(is(DerivedFunctionType!(F1, F4) == void));
5210     class C {}
5211     class D : C {}
5212     alias C F5();
5213     alias D F6();
5214     static assert(is(DerivedFunctionType!(F5, F6) == F6));
5215     alias typeof(null) F7();
5216     alias int[] F8();
5217     alias int* F9();
5218     static assert(is(DerivedFunctionType!(F5, F7) == F7));
5219     static assert(is(DerivedFunctionType!(F7, F8) == void));
5220     static assert(is(DerivedFunctionType!(F7, F9) == F7));
5221 
5222     // variadic type equality
5223     alias int F10(int);
5224     alias int F11(int...);
5225     alias int F12(int, ...);
5226     static assert(is(DerivedFunctionType!(F10, F11) == void));
5227     static assert(is(DerivedFunctionType!(F10, F12) == void));
5228     static assert(is(DerivedFunctionType!(F11, F12) == void));
5229 
5230     // linkage equality
5231     alias extern(C) int F13(int);
5232     alias extern(D) int F14(int);
5233     alias extern(Windows) int F15(int);
5234     static assert(is(DerivedFunctionType!(F13, F14) == void));
5235     static assert(is(DerivedFunctionType!(F13, F15) == void));
5236     static assert(is(DerivedFunctionType!(F14, F15) == void));
5237 
5238     // ref & @property equality
5239     alias int F16(int);
5240     alias ref int F17(int);
5241     alias @property int F18(int);
5242     static assert(is(DerivedFunctionType!(F16, F17) == void));
5243     static assert(is(DerivedFunctionType!(F16, F18) == void));
5244     static assert(is(DerivedFunctionType!(F17, F18) == void));
5245 }
5246 
5247 package template staticIota(int beg, int end)
5248 {
5249     static if (beg + 1 >= end)
5250     {
5251         static if (beg >= end)
5252         {
5253             alias staticIota = AliasSeq!();
5254         }
5255         else
5256         {
5257             alias staticIota = AliasSeq!(+beg);
5258         }
5259     }
5260     else
5261     {
5262         enum mid = beg + (end - beg) / 2;
5263         alias staticIota = AliasSeq!(staticIota!(beg, mid), staticIota!(mid, end));
5264     }
5265 }
5266 
5267 package template mixinAll(mixins...)
5268 {
5269     static if (mixins.length == 1)
5270     {
5271         static if (is(typeof(mixins[0]) == string))
5272         {
5273             mixin(mixins[0]);
5274         }
5275         else
5276         {
5277             alias it = mixins[0];
5278             mixin it;
5279         }
5280     }
5281     else static if (mixins.length >= 2)
5282     {
5283         mixin mixinAll!(mixins[ 0 .. $/2]);
5284         mixin mixinAll!(mixins[$/2 .. $ ]);
5285     }
5286 }
5287 
5288 package template Bind(alias Template, args1...)
5289 {
5290     alias Bind(args2...) = Template!(args1, args2);
5291 }
5292 
5293 
5294 /**
5295 Options regarding auto-initialization of a $(D RefCounted) object (see
5296 the definition of $(D RefCounted) below).
5297  */
5298 enum RefCountedAutoInitialize
5299 {
5300     /// Do not auto-initialize the object
5301     no,
5302     /// Auto-initialize the object
5303     yes,
5304 }
5305 
5306 /**
5307 Defines a reference-counted object containing a $(D T) value as
5308 payload.
5309 
5310 An instance of $(D RefCounted) is a reference to a structure,
5311 which is referred to as the $(I store), or $(I storage implementation
5312 struct) in this documentation.  The store contains a reference count
5313 and the $(D T) payload.  $(D RefCounted) uses $(D malloc) to allocate
5314 the store.  As instances of $(D RefCounted) are copied or go out of
5315 scope, they will automatically increment or decrement the reference
5316 count.  When the reference count goes down to zero, $(D RefCounted)
5317 will call $(D destroy) against the payload and call $(D free) to
5318 deallocate the store.  If the $(D T) payload contains any references
5319 to GC-allocated memory, then `RefCounted` will add it to the GC memory
5320 that is scanned for pointers, and remove it from GC scanning before
5321 $(D free) is called on the store.
5322 
5323 One important consequence of $(D destroy) is that it will call the
5324 destructor of the $(D T) payload.  GC-managed references are not
5325 guaranteed to be valid during a destructor call, but other members of
5326 $(D T), such as file handles or pointers to $(D malloc) memory, will
5327 still be valid during the destructor call.  This allows the $(D T) to
5328 deallocate or clean up any non-GC resources immediately after the
5329 reference count has reached zero.
5330 
5331 $(D RefCounted) is unsafe and should be used with care. No references
5332 to the payload should be escaped outside the $(D RefCounted) object.
5333 
5334 The $(D autoInit) option makes the object ensure the store is
5335 automatically initialized. Leaving $(D autoInit ==
5336 RefCountedAutoInitialize.yes) (the default option) is convenient but
5337 has the cost of a test whenever the payload is accessed. If $(D
5338 autoInit == RefCountedAutoInitialize.no), user code must call either
5339 $(D refCountedStore.isInitialized) or $(D refCountedStore.ensureInitialized)
5340 before attempting to access the payload. Not doing so results in null
5341 pointer dereference.
5342  */
5343 struct RefCounted(T, RefCountedAutoInitialize autoInit =
5344         RefCountedAutoInitialize.yes)
5345 if (!is(T == class) && !(is(T == interface)))
5346 {
5347     extern(C) private pure nothrow @nogc static // TODO remove pure when https://issues.dlang.org/show_bug.cgi?id=15862 has been fixed
5348     {
5349         pragma(mangle, "free") void pureFree( void *ptr );
5350         pragma(mangle, "gc_addRange") void pureGcAddRange( in void* p, size_t sz, const TypeInfo ti = null );
5351         pragma(mangle, "gc_removeRange") void pureGcRemoveRange( in void* p );
5352     }
5353 
5354     /// $(D RefCounted) storage implementation.
5355     struct RefCountedStore
5356     {
5357         import core.memory : pureMalloc;
5358         private struct Impl
5359         {
5360             T _payload;
5361             size_t _count;
5362         }
5363 
5364         private Impl* _store;
5365 
5366         private void initialize(A...)(auto ref A args)
5367         {
5368             import core.exception : onOutOfMemoryError;
5369             import std.conv : emplace;
5370 
5371             _store = cast(Impl*) pureMalloc(Impl.sizeof);
5372             if (_store is null)
5373                 onOutOfMemoryError();
5374             static if (hasIndirections!T)
5375                 pureGcAddRange(&_store._payload, T.sizeof);
5376             emplace(&_store._payload, args);
5377             _store._count = 1;
5378         }
5379 
5380         private void move(ref T source)
5381         {
5382             import core.exception : onOutOfMemoryError;
5383             import core.stdc.string : memcpy, memset;
5384 
5385             _store = cast(Impl*) pureMalloc(Impl.sizeof);
5386             if (_store is null)
5387                 onOutOfMemoryError();
5388             static if (hasIndirections!T)
5389                 pureGcAddRange(&_store._payload, T.sizeof);
5390 
5391             // Can't use std.algorithm.move(source, _store._payload)
5392             // here because it requires the target to be initialized.
5393             // Might be worth to add this as `moveEmplace`
5394 
5395             // Can avoid destructing result.
5396             static if (hasElaborateAssign!T || !isAssignable!T)
5397                 memcpy(&_store._payload, &source, T.sizeof);
5398             else
5399                 _store._payload = source;
5400 
5401             // If the source defines a destructor or a postblit hook, we must obliterate the
5402             // object in order to avoid double freeing and undue aliasing
5403             static if (hasElaborateDestructor!T || hasElaborateCopyConstructor!T)
5404             {
5405                 // If T is nested struct, keep original context pointer
5406                 static if (__traits(isNested, T))
5407                     enum sz = T.sizeof - (void*).sizeof;
5408                 else
5409                     enum sz = T.sizeof;
5410 
5411                 auto init = typeid(T).initializer();
5412                 if (init.ptr is null) // null ptr means initialize to 0s
5413                     memset(&source, 0, sz);
5414                 else
5415                     memcpy(&source, init.ptr, sz);
5416             }
5417 
5418             _store._count = 1;
5419         }
5420 
5421         /**
5422            Returns $(D true) if and only if the underlying store has been
5423            allocated and initialized.
5424         */
5425         @property nothrow @safe pure @nogc
5426         bool isInitialized() const
5427         {
5428             return _store !is null;
5429         }
5430 
5431         /**
5432            Returns underlying reference count if it is allocated and initialized
5433            (a positive integer), and $(D 0) otherwise.
5434         */
5435         @property nothrow @safe pure @nogc
5436         size_t refCount() const
5437         {
5438             return isInitialized ? _store._count : 0;
5439         }
5440 
5441         /**
5442            Makes sure the payload was properly initialized. Such a
5443            call is typically inserted before using the payload.
5444         */
5445         void ensureInitialized()
5446         {
5447             if (!isInitialized) initialize();
5448         }
5449 
5450     }
5451     RefCountedStore _refCounted;
5452 
5453     /// Returns storage implementation struct.
5454     @property nothrow @safe
5455     ref inout(RefCountedStore) refCountedStore() inout
5456     {
5457         return _refCounted;
5458     }
5459 
5460 /**
5461 Constructor that initializes the payload.
5462 
5463 Postcondition: $(D refCountedStore.isInitialized)
5464  */
5465     this(A...)(auto ref A args) if (A.length > 0)
5466     {
5467         _refCounted.initialize(args);
5468     }
5469 
5470     /// Ditto
5471     this(T val)
5472     {
5473         _refCounted.move(val);
5474     }
5475 
5476 /**
5477 Constructor that tracks the reference count appropriately. If $(D
5478 !refCountedStore.isInitialized), does nothing.
5479  */
5480     this(this) @safe pure nothrow @nogc
5481     {
5482         if (!_refCounted.isInitialized) return;
5483         ++_refCounted._store._count;
5484     }
5485 
5486 /**
5487 Destructor that tracks the reference count appropriately. If $(D
5488 !refCountedStore.isInitialized), does nothing. When the reference count goes
5489 down to zero, calls $(D destroy) agaist the payload and calls $(D free)
5490 to deallocate the corresponding resource.
5491  */
5492     ~this()
5493     {
5494         if (!_refCounted.isInitialized) return;
5495         assert(_refCounted._store._count > 0);
5496         if (--_refCounted._store._count)
5497             return;
5498         // Done, deallocate
5499         .destroy(_refCounted._store._payload);
5500         static if (hasIndirections!T)
5501         {
5502             pureGcRemoveRange(&_refCounted._store._payload);
5503         }
5504 
5505         pureFree(_refCounted._store);
5506         _refCounted._store = null;
5507     }
5508 
5509 /**
5510 Assignment operators
5511  */
5512     void opAssign(typeof(this) rhs)
5513     {
5514         import std.algorithm.mutation : swap;
5515 
5516         swap(_refCounted._store, rhs._refCounted._store);
5517     }
5518 
5519 /// Ditto
5520     void opAssign(T rhs)
5521     {
5522         import std.algorithm.mutation : move;
5523 
5524         static if (autoInit == RefCountedAutoInitialize.yes)
5525         {
5526             _refCounted.ensureInitialized();
5527         }
5528         else
5529         {
5530             assert(_refCounted.isInitialized);
5531         }
5532         move(rhs, _refCounted._store._payload);
5533     }
5534 
5535     //version to have a single properly ddoc'ed function (w/ correct sig)
5536     version (StdDdoc)
5537     {
5538         /**
5539         Returns a reference to the payload. If (autoInit ==
5540         RefCountedAutoInitialize.yes), calls $(D
5541         refCountedStore.ensureInitialized). Otherwise, just issues $(D
5542         assert(refCountedStore.isInitialized)). Used with $(D alias
5543         refCountedPayload this;), so callers can just use the $(D RefCounted)
5544         object as a $(D T).
5545 
5546         $(BLUE The first overload exists only if $(D autoInit == RefCountedAutoInitialize.yes).)
5547         So if $(D autoInit == RefCountedAutoInitialize.no)
5548         or called for a constant or immutable object, then
5549         $(D refCountedPayload) will also be qualified as safe and nothrow
5550         (but will still assert if not initialized).
5551          */
5552         @property
5553         ref T refCountedPayload() return;
5554 
5555         /// ditto
5556         @property nothrow @safe pure @nogc
5557         ref inout(T) refCountedPayload() inout return;
5558     }
5559     else
5560     {
5561         static if (autoInit == RefCountedAutoInitialize.yes)
5562         {
5563             //Can't use inout here because of potential mutation
5564             @property
5565             ref T refCountedPayload() return
5566             {
5567                 _refCounted.ensureInitialized();
5568                 return _refCounted._store._payload;
5569             }
5570         }
5571 
5572         @property nothrow @safe pure @nogc
5573         ref inout(T) refCountedPayload() inout return
5574         {
5575             assert(_refCounted.isInitialized, "Attempted to access an uninitialized payload.");
5576             return _refCounted._store._payload;
5577         }
5578     }
5579 
5580 /**
5581 Returns a reference to the payload. If (autoInit ==
5582 RefCountedAutoInitialize.yes), calls $(D
5583 refCountedStore.ensureInitialized). Otherwise, just issues $(D
5584 assert(refCountedStore.isInitialized)).
5585  */
5586     alias refCountedPayload this;
5587 }
5588 
5589 ///
5590 pure @system nothrow @nogc unittest
5591 {
5592     // A pair of an `int` and a `size_t` - the latter being the
5593     // reference count - will be dynamically allocated
5594     auto rc1 = RefCounted!int(5);
5595     assert(rc1 == 5);
5596     // No more allocation, add just one extra reference count
5597     auto rc2 = rc1;
5598     // Reference semantics
5599     rc2 = 42;
5600     assert(rc1 == 42);
5601     // the pair will be freed when rc1 and rc2 go out of scope
5602 }
5603 
5604 pure @system unittest
5605 {
5606     RefCounted!int* p;
5607     {
5608         auto rc1 = RefCounted!int(5);
5609         p = &rc1;
5610         assert(rc1 == 5);
5611         assert(rc1._refCounted._store._count == 1);
5612         auto rc2 = rc1;
5613         assert(rc1._refCounted._store._count == 2);
5614         // Reference semantics
5615         rc2 = 42;
5616         assert(rc1 == 42);
5617         rc2 = rc2;
5618         assert(rc2._refCounted._store._count == 2);
5619         rc1 = rc2;
5620         assert(rc1._refCounted._store._count == 2);
5621     }
5622     assert(p._refCounted._store == null);
5623 
5624     // RefCounted as a member
5625     struct A
5626     {
5627         RefCounted!int x;
5628         this(int y)
5629         {
5630             x._refCounted.initialize(y);
5631         }
5632         A copy()
5633         {
5634             auto another = this;
5635             return another;
5636         }
5637     }
5638     auto a = A(4);
5639     auto b = a.copy();
5640     assert(a.x._refCounted._store._count == 2, "BUG 4356 still unfixed");
5641 }
5642 
5643 pure @system nothrow @nogc unittest
5644 {
5645     import std.algorithm.mutation : swap;
5646 
5647     RefCounted!int p1, p2;
5648     swap(p1, p2);
5649 }
5650 
5651 // 6606
5652 @safe pure nothrow @nogc unittest
5653 {
5654     union U {
5655        size_t i;
5656        void* p;
5657     }
5658 
5659     struct S {
5660        U u;
5661     }
5662 
5663     alias SRC = RefCounted!S;
5664 }
5665 
5666 // 6436
5667 @system pure unittest
5668 {
5669     struct S { this(ref int val) { assert(val == 3); ++val; } }
5670 
5671     int val = 3;
5672     auto s = RefCounted!S(val);
5673     assert(val == 4);
5674 }
5675 
5676 // gc_addRange coverage
5677 @system pure unittest
5678 {
5679     struct S { int* p; }
5680 
5681     auto s = RefCounted!S(null);
5682 }
5683 
5684 @system pure nothrow @nogc unittest
5685 {
5686     RefCounted!int a;
5687     a = 5; //This should not assert
5688     assert(a == 5);
5689 
5690     RefCounted!int b;
5691     b = a; //This should not assert either
5692     assert(b == 5);
5693 
5694     RefCounted!(int*) c;
5695 }
5696 
5697 /**
5698  * Initializes a `RefCounted` with `val`. The template parameter
5699  * `T` of `RefCounted` is inferred from `val`.
5700  * This function can be used to move non-copyable values to the heap.
5701  * It also disables the `autoInit` option of `RefCounted`.
5702  *
5703  * Params:
5704  *   val = The value to be reference counted
5705  * Returns:
5706  *   An initialized $(D RefCounted) containing $(D val).
5707  * See_Also:
5708  *   $(HTTP en.cppreference.com/w/cpp/memory/shared_ptr/make_shared, C++'s make_shared)
5709  */
5710 RefCounted!(T, RefCountedAutoInitialize.no) refCounted(T)(T val)
5711 {
5712     typeof(return) res;
5713     res._refCounted.move(val);
5714     return res;
5715 }
5716 
5717 ///
5718 @system unittest
5719 {
5720     static struct File
5721     {
5722         string name;
5723         @disable this(this); // not copyable
5724         ~this() { name = null; }
5725     }
5726 
5727     auto file = File("name");
5728     assert(file.name == "name");
5729     // file cannot be copied and has unique ownership
5730     static assert(!__traits(compiles, {auto file2 = file;}));
5731 
5732     // make the file refcounted to share ownership
5733     import std.algorithm.mutation : move;
5734     auto rcFile = refCounted(move(file));
5735     assert(rcFile.name == "name");
5736     assert(file.name == null);
5737     auto rcFile2 = rcFile;
5738     assert(rcFile.refCountedStore.refCount == 2);
5739     // file gets properly closed when last reference is dropped
5740 }
5741 
5742 /**
5743     Creates a proxy for the value `a` that will forward all operations
5744     while disabling implicit conversions. The aliased item `a` must be
5745     an $(B lvalue). This is useful for creating a new type from the
5746     "base" type (though this is $(B not) a subtype-supertype
5747     relationship; the new type is not related to the old type in any way,
5748     by design).
5749 
5750     The new type supports all operations that the underlying type does,
5751     including all operators such as `+`, `--`, `<`, `[]`, etc.
5752 
5753     Params:
5754         a = The value to act as a proxy for all operations. It must
5755             be an lvalue.
5756  */
5757 mixin template Proxy(alias a)
5758 {
5759     private alias ValueType = typeof({ return a; }());
5760 
5761     /* Determine if 'T.a' can referenced via a const(T).
5762      * Use T* as the parameter because 'scope' inference needs a fully
5763      * analyzed T, which doesn't work when accessibleFrom() is used in a
5764      * 'static if' in the definition of Proxy or T.
5765      */
5766     private enum bool accessibleFrom(T) =
5767         is(typeof((T* self){ cast(void) mixin("(*self)."~__traits(identifier, a)); }));
5768 
5769     static if (is(typeof(this) == class))
5770     {
5771         override bool opEquals(Object o)
5772         {
5773             if (auto b = cast(typeof(this))o)
5774             {
5775                 return a == mixin("b."~__traits(identifier, a));
5776             }
5777             return false;
5778         }
5779 
5780         bool opEquals(T)(T b)
5781             if (is(ValueType : T) || is(typeof(a.opEquals(b))) || is(typeof(b.opEquals(a))))
5782         {
5783             static if (is(typeof(a.opEquals(b))))
5784                 return a.opEquals(b);
5785             else static if (is(typeof(b.opEquals(a))))
5786                 return b.opEquals(a);
5787             else
5788                 return a == b;
5789         }
5790 
5791         override int opCmp(Object o)
5792         {
5793             if (auto b = cast(typeof(this))o)
5794             {
5795                 return a < mixin("b."~__traits(identifier, a)) ? -1
5796                      : a > mixin("b."~__traits(identifier, a)) ? +1 : 0;
5797             }
5798             static if (is(ValueType == class))
5799                 return a.opCmp(o);
5800             else
5801                 throw new Exception("Attempt to compare a "~typeid(this).toString~" and a "~typeid(o).toString);
5802         }
5803 
5804         int opCmp(T)(auto ref const T b)
5805             if (is(ValueType : T) || is(typeof(a.opCmp(b))) || is(typeof(b.opCmp(a))))
5806         {
5807             static if (is(typeof(a.opCmp(b))))
5808                 return a.opCmp(b);
5809             else static if (is(typeof(b.opCmp(a))))
5810                 return -b.opCmp(b);
5811             else
5812                 return a < b ? -1 : a > b ? +1 : 0;
5813         }
5814 
5815         static if (accessibleFrom!(const typeof(this)))
5816         {
5817             override hash_t toHash() const nothrow @trusted
5818             {
5819                 static if (is(typeof(&a) == ValueType*))
5820                     alias v = a;
5821                 else
5822                     auto v = a;     // if a is (property) function
5823                 return typeid(ValueType).getHash(cast(const void*)&v);
5824             }
5825         }
5826     }
5827     else
5828     {
5829         auto ref opEquals(this X, B)(auto ref B b)
5830         {
5831             static if (is(immutable B == immutable typeof(this)))
5832             {
5833                 return a == mixin("b."~__traits(identifier, a));
5834             }
5835             else
5836                 return a == b;
5837         }
5838 
5839         auto ref opCmp(this X, B)(auto ref B b)
5840           if (!is(typeof(a.opCmp(b))) || !is(typeof(b.opCmp(a))))
5841         {
5842             static if (is(typeof(a.opCmp(b))))
5843                 return a.opCmp(b);
5844             else static if (is(typeof(b.opCmp(a))))
5845                 return -b.opCmp(a);
5846             else static if (isFloatingPoint!ValueType || isFloatingPoint!B)
5847                 return a < b ? -1 : a > b ? +1 : a == b ? 0 : float.nan;
5848             else
5849                 return a < b ? -1 : (a > b);
5850         }
5851 
5852         static if (accessibleFrom!(const typeof(this)))
5853         {
5854             hash_t toHash() const nothrow @trusted
5855             {
5856                 static if (is(typeof(&a) == ValueType*))
5857                     alias v = a;
5858                 else
5859                     auto v = a;     // if a is (property) function
5860                 return typeid(ValueType).getHash(cast(const void*)&v);
5861             }
5862         }
5863     }
5864 
5865     auto ref opCall(this X, Args...)(auto ref Args args) { return a(args); }
5866 
5867     auto ref opCast(T, this X)() { return cast(T) a; }
5868 
5869     auto ref opIndex(this X, D...)(auto ref D i)               { return a[i]; }
5870     auto ref opSlice(this X      )()                           { return a[]; }
5871     auto ref opSlice(this X, B, E)(auto ref B b, auto ref E e) { return a[b .. e]; }
5872 
5873     auto ref opUnary     (string op, this X      )()                           { return mixin(op~"a"); }
5874     auto ref opIndexUnary(string op, this X, D...)(auto ref D i)               { return mixin(op~"a[i]"); }
5875     auto ref opSliceUnary(string op, this X      )()                           { return mixin(op~"a[]"); }
5876     auto ref opSliceUnary(string op, this X, B, E)(auto ref B b, auto ref E e) { return mixin(op~"a[b .. e]"); }
5877 
5878     auto ref opBinary(string op, this X, B)(auto ref B b)
5879     if (op == "in" && is(typeof(a in b)) || op != "in")
5880     {
5881         return mixin("a "~op~" b");
5882     }
5883     auto ref opBinaryRight(string op, this X, B)(auto ref B b) { return mixin("b "~op~" a"); }
5884 
5885     static if (!is(typeof(this) == class))
5886     {
5887         import std.traits;
5888         static if (isAssignable!ValueType)
5889         {
5890             auto ref opAssign(this X)(auto ref typeof(this) v)
5891             {
5892                 a = mixin("v."~__traits(identifier, a));
5893                 return this;
5894             }
5895         }
5896         else
5897         {
5898             @disable void opAssign(this X)(auto ref typeof(this) v);
5899         }
5900     }
5901 
5902     auto ref opAssign     (this X, V      )(auto ref V v) if (!is(V == typeof(this))) { return a       = v; }
5903     auto ref opIndexAssign(this X, V, D...)(auto ref V v, auto ref D i)               { return a[i]    = v; }
5904     auto ref opSliceAssign(this X, V      )(auto ref V v)                             { return a[]     = v; }
5905     auto ref opSliceAssign(this X, V, B, E)(auto ref V v, auto ref B b, auto ref E e) { return a[b .. e] = v; }
5906 
5907     auto ref opOpAssign     (string op, this X, V      )(auto ref V v)
5908     {
5909         return mixin("a "      ~op~"= v");
5910     }
5911     auto ref opIndexOpAssign(string op, this X, V, D...)(auto ref V v, auto ref D i)
5912     {
5913         return mixin("a[i] "   ~op~"= v");
5914     }
5915     auto ref opSliceOpAssign(string op, this X, V      )(auto ref V v)
5916     {
5917         return mixin("a[] "    ~op~"= v");
5918     }
5919     auto ref opSliceOpAssign(string op, this X, V, B, E)(auto ref V v, auto ref B b, auto ref E e)
5920     {
5921         return mixin("a[b .. e] "~op~"= v");
5922     }
5923 
5924     template opDispatch(string name)
5925     {
5926         static if (is(typeof(__traits(getMember, a, name)) == function))
5927         {
5928             // non template function
5929             auto ref opDispatch(this X, Args...)(auto ref Args args) { return mixin("a."~name~"(args)"); }
5930         }
5931         else static if (is(typeof({ enum x = mixin("a."~name); })))
5932         {
5933             // built-in type field, manifest constant, and static non-mutable field
5934             enum opDispatch = mixin("a."~name);
5935         }
5936         else static if (__traits(isTemplate, mixin("a."~name)))
5937         {
5938             // member template
5939             template opDispatch(T...)
5940             {
5941                 enum targs = T.length ? "!T" : "";
5942                 auto ref opDispatch(this X, Args...)(auto ref Args args){ return mixin("a."~name~targs~"(args)"); }
5943             }
5944         }
5945         else
5946         {
5947             // field or property function
5948             @property auto ref opDispatch(this X)()                { return mixin("a."~name);        }
5949             @property auto ref opDispatch(this X, V)(auto ref V v) { return mixin("a."~name~" = v"); }
5950         }
5951 
5952     }
5953 
5954     import std.traits : isArray;
5955 
5956     static if (isArray!ValueType)
5957     {
5958         auto opDollar() const { return a.length; }
5959     }
5960     else static if (is(typeof(a.opDollar!0)))
5961     {
5962         auto ref opDollar(size_t pos)() { return a.opDollar!pos(); }
5963     }
5964     else static if (is(typeof(a.opDollar) == function))
5965     {
5966         auto ref opDollar() { return a.opDollar(); }
5967     }
5968     else static if (is(typeof(a.opDollar)))
5969     {
5970         alias opDollar = a.opDollar;
5971     }
5972 }
5973 
5974 ///
5975 @safe unittest
5976 {
5977     struct MyInt
5978     {
5979         private int value;
5980         mixin Proxy!value;
5981 
5982         this(int n){ value = n; }
5983     }
5984 
5985     MyInt n = 10;
5986 
5987     // Enable operations that original type has.
5988     ++n;
5989     assert(n == 11);
5990     assert(n * 2 == 22);
5991 
5992     void func(int n) { }
5993 
5994     // Disable implicit conversions to original type.
5995     //int x = n;
5996     //func(n);
5997 }
5998 
5999 ///The proxied value must be an $(B lvalue).
6000 @safe unittest
6001 {
6002     struct NewIntType
6003     {
6004         //Won't work; the literal '1'
6005         //is an rvalue, not an lvalue
6006         //mixin Proxy!1;
6007 
6008         //Okay, n is an lvalue
6009         int n;
6010         mixin Proxy!n;
6011 
6012         this(int n) { this.n = n; }
6013     }
6014 
6015     NewIntType nit = 0;
6016     nit++;
6017     assert(nit == 1);
6018 
6019 
6020     struct NewObjectType
6021     {
6022         Object obj;
6023         //Ok, obj is an lvalue
6024         mixin Proxy!obj;
6025 
6026         this (Object o) { obj = o; }
6027     }
6028 
6029     NewObjectType not = new Object();
6030     assert(__traits(compiles, not.toHash()));
6031 }
6032 
6033 /**
6034     There is one exception to the fact that the new type is not related to the
6035     old type. $(DDSUBLINK spec/function,pseudo-member, Pseudo-member)
6036     functions are usable with the new type; they will be forwarded on to the
6037     proxied value.
6038  */
6039 @safe unittest
6040 {
6041     import std.math;
6042 
6043     float f = 1.0;
6044     assert(!f.isInfinity);
6045 
6046     struct NewFloat
6047     {
6048         float _;
6049         mixin Proxy!_;
6050 
6051         this(float f) { _ = f; }
6052     }
6053 
6054     NewFloat nf = 1.0f;
6055     assert(!nf.isInfinity);
6056 }
6057 
6058 @safe unittest
6059 {
6060     static struct MyInt
6061     {
6062         private int value;
6063         mixin Proxy!value;
6064         this(int n) inout { value = n; }
6065 
6066         enum str = "str";
6067         static immutable arr = [1,2,3];
6068     }
6069 
6070     foreach (T; AliasSeq!(MyInt, const MyInt, immutable MyInt))
6071     {
6072         T m = 10;
6073         static assert(!__traits(compiles, { int x = m; }));
6074         static assert(!__traits(compiles, { void func(int n){} func(m); }));
6075         assert(m == 10);
6076         assert(m != 20);
6077         assert(m < 20);
6078         assert(+m == 10);
6079         assert(-m == -10);
6080         assert(cast(double) m == 10.0);
6081         assert(m + 10 == 20);
6082         assert(m - 5 == 5);
6083         assert(m * 20 == 200);
6084         assert(m / 2 == 5);
6085         assert(10 + m == 20);
6086         assert(15 - m == 5);
6087         assert(20 * m == 200);
6088         assert(50 / m == 5);
6089         static if (is(T == MyInt))  // mutable
6090         {
6091             assert(++m == 11);
6092             assert(m++ == 11); assert(m == 12);
6093             assert(--m == 11);
6094             assert(m-- == 11); assert(m == 10);
6095             m = m;
6096             m = 20; assert(m == 20);
6097         }
6098         static assert(T.max == int.max);
6099         static assert(T.min == int.min);
6100         static assert(T.init == int.init);
6101         static assert(T.str == "str");
6102         static assert(T.arr == [1,2,3]);
6103     }
6104 }
6105 @system unittest
6106 {
6107     static struct MyArray
6108     {
6109         private int[] value;
6110         mixin Proxy!value;
6111         this(int[] arr) { value = arr; }
6112         this(immutable int[] arr) immutable { value = arr; }
6113     }
6114 
6115     foreach (T; AliasSeq!(MyArray, const MyArray, immutable MyArray))
6116     {
6117       static if (is(T == immutable) && !is(typeof({ T a = [1,2,3,4]; })))
6118         T a = [1,2,3,4].idup;   // workaround until qualified ctor is properly supported
6119       else
6120         T a = [1,2,3,4];
6121         assert(a == [1,2,3,4]);
6122         assert(a != [5,6,7,8]);
6123         assert(+a[0]    == 1);
6124         version (LittleEndian)
6125             assert(cast(ulong[]) a == [0x0000_0002_0000_0001, 0x0000_0004_0000_0003]);
6126         else
6127             assert(cast(ulong[]) a == [0x0000_0001_0000_0002, 0x0000_0003_0000_0004]);
6128         assert(a ~ [10,11] == [1,2,3,4,10,11]);
6129         assert(a[0]    == 1);
6130         assert(a[]     == [1,2,3,4]);
6131         assert(a[2 .. 4] == [3,4]);
6132         static if (is(T == MyArray))    // mutable
6133         {
6134             a = a;
6135             a = [5,6,7,8];  assert(a == [5,6,7,8]);
6136             a[0]     = 0;   assert(a == [0,6,7,8]);
6137             a[]      = 1;   assert(a == [1,1,1,1]);
6138             a[0 .. 3]  = 2;   assert(a == [2,2,2,1]);
6139             a[0]    += 2;   assert(a == [4,2,2,1]);
6140             a[]     *= 2;   assert(a == [8,4,4,2]);
6141             a[0 .. 2] /= 2;   assert(a == [4,2,4,2]);
6142         }
6143     }
6144 }
6145 @system unittest
6146 {
6147     class Foo
6148     {
6149         int field;
6150 
6151         @property int val1() const { return field; }
6152         @property void val1(int n) { field = n; }
6153 
6154         @property ref int val2() { return field; }
6155 
6156         int func(int x, int y) const { return x; }
6157         void func1(ref int a) { a = 9; }
6158 
6159         T ifti1(T)(T t) { return t; }
6160         void ifti2(Args...)(Args args) { }
6161         void ifti3(T, Args...)(Args args) { }
6162 
6163         T opCast(T)(){ return T.init; }
6164 
6165         T tempfunc(T)() { return T.init; }
6166     }
6167     class Hoge
6168     {
6169         Foo foo;
6170         mixin Proxy!foo;
6171         this(Foo f) { foo = f; }
6172     }
6173 
6174     auto h = new Hoge(new Foo());
6175     int n;
6176 
6177     static assert(!__traits(compiles, { Foo f = h; }));
6178 
6179     // field
6180     h.field = 1;            // lhs of assign
6181     n = h.field;            // rhs of assign
6182     assert(h.field == 1);   // lhs of BinExp
6183     assert(1 == h.field);   // rhs of BinExp
6184     assert(n == 1);
6185 
6186     // getter/setter property function
6187     h.val1 = 4;
6188     n = h.val1;
6189     assert(h.val1 == 4);
6190     assert(4 == h.val1);
6191     assert(n == 4);
6192 
6193     // ref getter property function
6194     h.val2 = 8;
6195     n = h.val2;
6196     assert(h.val2 == 8);
6197     assert(8 == h.val2);
6198     assert(n == 8);
6199 
6200     // member function
6201     assert(h.func(2,4) == 2);
6202     h.func1(n);
6203     assert(n == 9);
6204 
6205     // IFTI
6206     assert(h.ifti1(4) == 4);
6207     h.ifti2(4);
6208     h.ifti3!int(4, 3);
6209 
6210     // bug5896 test
6211     assert(h.opCast!int() == 0);
6212     assert(cast(int) h == 0);
6213     const ih = new const Hoge(new Foo());
6214     static assert(!__traits(compiles, ih.opCast!int()));
6215     static assert(!__traits(compiles, cast(int) ih));
6216 
6217     // template member function
6218     assert(h.tempfunc!int() == 0);
6219 }
6220 
6221 @system unittest // about Proxy inside a class
6222 {
6223     class MyClass
6224     {
6225         int payload;
6226         mixin Proxy!payload;
6227         this(int i){ payload = i; }
6228         string opCall(string msg){ return msg; }
6229         int pow(int i){ return payload ^^ i; }
6230     }
6231 
6232     class MyClass2
6233     {
6234         MyClass payload;
6235         mixin Proxy!payload;
6236         this(int i){ payload = new MyClass(i); }
6237     }
6238 
6239     class MyClass3
6240     {
6241         int payload;
6242         mixin Proxy!payload;
6243         this(int i){ payload = i; }
6244     }
6245 
6246     // opEquals
6247     Object a = new MyClass(5);
6248     Object b = new MyClass(5);
6249     Object c = new MyClass2(5);
6250     Object d = new MyClass3(5);
6251     assert(a == b);
6252     assert((cast(MyClass) a) == 5);
6253     assert(5 == (cast(MyClass) b));
6254     assert(5 == cast(MyClass2) c);
6255     assert(a != d);
6256 
6257     assert(c != a);
6258     // oops! above line is unexpected, isn't it?
6259     // the reason is below.
6260     // MyClass2.opEquals knows MyClass but,
6261     // MyClass.opEquals doesn't know MyClass2.
6262     // so, c.opEquals(a) is true, but a.opEquals(c) is false.
6263     // furthermore, opEquals(T) couldn't be invoked.
6264     assert((cast(MyClass2) c) != (cast(MyClass) a));
6265 
6266     // opCmp
6267     Object e = new MyClass2(7);
6268     assert(a < cast(MyClass2) e); // OK. and
6269     assert(e > a); // OK, but...
6270     // assert(a < e); // RUNTIME ERROR!
6271     // assert((cast(MyClass) a) < e); // RUNTIME ERROR!
6272     assert(3 < cast(MyClass) a);
6273     assert((cast(MyClass2) e) < 11);
6274 
6275     // opCall
6276     assert((cast(MyClass2) e)("hello") == "hello");
6277 
6278     // opCast
6279     assert((cast(MyClass)(cast(MyClass2) c)) == a);
6280     assert((cast(int)(cast(MyClass2) c)) == 5);
6281 
6282     // opIndex
6283     class MyClass4
6284     {
6285         string payload;
6286         mixin Proxy!payload;
6287         this(string s){ payload = s; }
6288     }
6289     class MyClass5
6290     {
6291         MyClass4 payload;
6292         mixin Proxy!payload;
6293         this(string s){ payload = new MyClass4(s); }
6294     }
6295     auto f = new MyClass4("hello");
6296     assert(f[1] == 'e');
6297     auto g = new MyClass5("hello");
6298     assert(f[1] == 'e');
6299 
6300     // opSlice
6301     assert(f[2 .. 4] == "ll");
6302 
6303     // opUnary
6304     assert(-(cast(MyClass2) c) == -5);
6305 
6306     // opBinary
6307     assert((cast(MyClass) a) + (cast(MyClass2) c) == 10);
6308     assert(5 + cast(MyClass) a == 10);
6309 
6310     // opAssign
6311     (cast(MyClass2) c) = 11;
6312     assert((cast(MyClass2) c) == 11);
6313     (cast(MyClass2) c) = new MyClass(13);
6314     assert((cast(MyClass2) c) == 13);
6315 
6316     // opOpAssign
6317     assert((cast(MyClass2) c) += 4);
6318     assert((cast(MyClass2) c) == 17);
6319 
6320     // opDispatch
6321     assert((cast(MyClass2) c).pow(2) == 289);
6322 
6323     // opDollar
6324     assert(f[2..$-1] == "ll");
6325 
6326     // toHash
6327     int[Object] hash;
6328     hash[a] = 19;
6329     hash[c] = 21;
6330     assert(hash[b] == 19);
6331     assert(hash[c] == 21);
6332 }
6333 
6334 @safe unittest
6335 {
6336     struct MyInt
6337     {
6338         int payload;
6339 
6340         mixin Proxy!payload;
6341     }
6342 
6343     MyInt v;
6344     v = v;
6345 
6346     struct Foo
6347     {
6348         @disable void opAssign(typeof(this));
6349     }
6350     struct MyFoo
6351     {
6352         Foo payload;
6353 
6354         mixin Proxy!payload;
6355     }
6356     MyFoo f;
6357     static assert(!__traits(compiles, f = f));
6358 
6359     struct MyFoo2
6360     {
6361         Foo payload;
6362 
6363         mixin Proxy!payload;
6364 
6365         // override default Proxy behavior
6366         void opAssign(typeof(this) rhs){}
6367     }
6368     MyFoo2 f2;
6369     f2 = f2;
6370 }
6371 @safe unittest
6372 {
6373     // bug8613
6374     static struct Name
6375     {
6376         mixin Proxy!val;
6377         private string val;
6378         this(string s) { val = s; }
6379     }
6380 
6381     bool[Name] names;
6382     names[Name("a")] = true;
6383     bool* b = Name("a") in names;
6384 }
6385 
6386 @system unittest
6387 {
6388     // bug14213, using function for the payload
6389     static struct S
6390     {
6391         int foo() { return 12; }
6392         mixin Proxy!foo;
6393     }
6394     static class C
6395     {
6396         int foo() { return 12; }
6397         mixin Proxy!foo;
6398     }
6399     S s;
6400     assert(s + 1 == 13);
6401     C c = new C();
6402     assert(s * 2 == 24);
6403 }
6404 
6405 // Check all floating point comparisons for both Proxy and Typedef,
6406 // also against int and a Typedef!int, to be as regression-proof
6407 // as possible. bug 15561
6408 @safe unittest
6409 {
6410     static struct MyFloatImpl
6411     {
6412         float value;
6413         mixin Proxy!value;
6414     }
6415     static void allFail(T0, T1)(T0 a, T1 b)
6416     {
6417         assert(!(a == b));
6418         assert(!(a<b));
6419         assert(!(a <= b));
6420         assert(!(a>b));
6421         assert(!(a >= b));
6422     }
6423     foreach (T1; AliasSeq!(MyFloatImpl, Typedef!float, Typedef!double,
6424         float, real, Typedef!int, int))
6425     {
6426         foreach (T2; AliasSeq!(MyFloatImpl, Typedef!float))
6427         {
6428             T1 a;
6429             T2 b;
6430 
6431             static if (isFloatingPoint!T1 || isFloatingPoint!(TypedefType!T1))
6432                 allFail(a, b);
6433             a = 3;
6434             allFail(a, b);
6435 
6436             b = 4;
6437             assert(a != b);
6438             assert(a<b);
6439             assert(a <= b);
6440             assert(!(a>b));
6441             assert(!(a >= b));
6442 
6443             a = 4;
6444             assert(a == b);
6445             assert(!(a<b));
6446             assert(a <= b);
6447             assert(!(a>b));
6448             assert(a >= b);
6449         }
6450     }
6451 }
6452 
6453 /**
6454 $(B Typedef) allows the creation of a unique type which is
6455 based on an existing type. Unlike the $(D alias) feature,
6456 $(B Typedef) ensures the two types are not considered as equals.
6457 
6458 Example:
6459 ----
6460 alias MyInt = Typedef!int;
6461 static void takeInt(int) { }
6462 static void takeMyInt(MyInt) { }
6463 
6464 int i;
6465 takeInt(i);    // ok
6466 takeMyInt(i);  // fails
6467 
6468 MyInt myInt;
6469 takeInt(myInt);    // fails
6470 takeMyInt(myInt);  // ok
6471 ----
6472 
6473 Params:
6474 
6475 init = Optional initial value for the new type. For example:
6476 
6477 ----
6478 alias MyInt = Typedef!(int, 10);
6479 MyInt myInt;
6480 assert(myInt == 10);  // default-initialized to 10
6481 ----
6482 
6483 cookie = Optional, used to create multiple unique types which are
6484 based on the same origin type $(D T). For example:
6485 
6486 ----
6487 alias TypeInt1 = Typedef!int;
6488 alias TypeInt2 = Typedef!int;
6489 
6490 // The two Typedefs are the same type.
6491 static assert(is(TypeInt1 == TypeInt2));
6492 
6493 alias MoneyEuros = Typedef!(float, float.init, "euros");
6494 alias MoneyDollars = Typedef!(float, float.init, "dollars");
6495 
6496 // The two Typedefs are _not_ the same type.
6497 static assert(!is(MoneyEuros == MoneyDollars));
6498 ----
6499 
6500 Note: If a library routine cannot handle the Typedef type,
6501 you can use the $(D TypedefType) template to extract the
6502 type which the Typedef wraps.
6503  */
6504 struct Typedef(T, T init = T.init, string cookie=null)
6505 {
6506     private T Typedef_payload = init;
6507 
6508     this(T init)
6509     {
6510         Typedef_payload = init;
6511     }
6512 
6513     this(Typedef tdef)
6514     {
6515         this(tdef.Typedef_payload);
6516     }
6517 
6518     // We need to add special overload for cast(Typedef!X) exp,
6519     // thus we can't simply inherit Proxy!Typedef_payload
6520     T2 opCast(T2 : Typedef!(T, Unused), this X, T, Unused...)()
6521     {
6522         return T2(cast(T) Typedef_payload);
6523     }
6524 
6525     auto ref opCast(T2, this X)()
6526     {
6527         return cast(T2) Typedef_payload;
6528     }
6529 
6530     mixin Proxy!Typedef_payload;
6531 
6532     pure nothrow @nogc @safe @property
6533     {
6534         alias TD = typeof(this);
6535         static if (isIntegral!T)
6536         {
6537             static TD min() {return TD(T.min);}
6538             static TD max() {return TD(T.max);}
6539         }
6540         else static if (isFloatingPoint!T)
6541         {
6542             static TD infinity() {return TD(T.infinity);}
6543             static TD nan() {return TD(T.nan);}
6544             static TD dig() {return TD(T.dig);}
6545             static TD epsilon() {return TD(T.epsilon);}
6546             static TD mant_dig() {return TD(T.mant_dig);}
6547             static TD max_10_exp() {return TD(T.max_10_exp);}
6548             static TD max_exp()  {return TD(T.max_exp);}
6549             static TD min_10_exp() {return TD(T.min_10_exp);}
6550             static TD min_exp() {return TD(T.min_exp);}
6551             static TD max() {return TD(T.max);}
6552             static TD min_normal() {return TD(T.min_normal);}
6553             TD re() {return TD(Typedef_payload.re);}
6554             TD im() {return TD(Typedef_payload.im);}
6555         }
6556     }
6557 }
6558 
6559 /**
6560 Get the underlying type which a $(D Typedef) wraps.
6561 If $(D T) is not a $(D Typedef) it will alias itself to $(D T).
6562 */
6563 template TypedefType(T)
6564 {
6565     static if (is(T : Typedef!Arg, Arg))
6566         alias TypedefType = Arg;
6567     else
6568         alias TypedefType = T;
6569 }
6570 
6571 ///
6572 @safe unittest
6573 {
6574     import std.typecons : Typedef, TypedefType;
6575     import std.conv : to;
6576 
6577     alias MyInt = Typedef!int;
6578     static assert(is(TypedefType!MyInt == int));
6579 
6580     /// Instantiating with a non-Typedef will return that type
6581     static assert(is(TypedefType!int == int));
6582 
6583     string num = "5";
6584 
6585     // extract the needed type
6586     MyInt myInt = MyInt( num.to!(TypedefType!MyInt) );
6587     assert(myInt == 5);
6588 
6589     // cast to the underlying type to get the value that's being wrapped
6590     int x = cast(TypedefType!MyInt) myInt;
6591 
6592     alias MyIntInit = Typedef!(int, 42);
6593     static assert(is(TypedefType!MyIntInit == int));
6594     static assert(MyIntInit() == 42);
6595 }
6596 
6597 @safe unittest
6598 {
6599     Typedef!int x = 10;
6600     static assert(!__traits(compiles, { int y = x; }));
6601     static assert(!__traits(compiles, { long z = x; }));
6602 
6603     Typedef!int y = 10;
6604     assert(x == y);
6605 
6606     static assert(Typedef!int.init == int.init);
6607 
6608     Typedef!(float, 1.0) z; // specifies the init
6609     assert(z == 1.0);
6610 
6611     static assert(typeof(z).init == 1.0);
6612 
6613     alias Dollar = Typedef!(int, 0, "dollar");
6614     alias Yen    = Typedef!(int, 0, "yen");
6615     static assert(!is(Dollar == Yen));
6616 
6617     Typedef!(int[3]) sa;
6618     static assert(sa.length == 3);
6619     static assert(typeof(sa).length == 3);
6620 
6621     Typedef!(int[3]) dollar1;
6622     assert(dollar1[0..$] is dollar1[0 .. 3]);
6623 
6624     Typedef!(int[]) dollar2;
6625     dollar2.length = 3;
6626     assert(dollar2[0..$] is dollar2[0 .. 3]);
6627 
6628     static struct Dollar1
6629     {
6630         static struct DollarToken {}
6631         enum opDollar = DollarToken.init;
6632         auto opSlice(size_t, DollarToken) { return 1; }
6633         auto opSlice(size_t, size_t) { return 2; }
6634     }
6635 
6636     Typedef!Dollar1 drange1;
6637     assert(drange1[0..$] == 1);
6638     assert(drange1[0 .. 1] == 2);
6639 
6640     static struct Dollar2
6641     {
6642         size_t opDollar(size_t pos)() { return pos == 0 ? 1 : 100; }
6643         size_t opIndex(size_t i, size_t j) { return i + j; }
6644     }
6645 
6646     Typedef!Dollar2 drange2;
6647     assert(drange2[$, $] == 101);
6648 
6649     static struct Dollar3
6650     {
6651         size_t opDollar() { return 123; }
6652         size_t opIndex(size_t i) { return i; }
6653     }
6654 
6655     Typedef!Dollar3 drange3;
6656     assert(drange3[$] == 123);
6657 }
6658 
6659 @safe @nogc pure nothrow unittest // Bugzilla 11703
6660 {
6661     alias I = Typedef!int;
6662     static assert(is(typeof(I.min) == I));
6663     static assert(is(typeof(I.max) == I));
6664 
6665     alias F = Typedef!double;
6666     static assert(is(typeof(F.infinity) == F));
6667     static assert(is(typeof(F.epsilon) == F));
6668 
6669     F f;
6670     assert(!is(typeof(F.re).stringof == double));
6671     assert(!is(typeof(F.im).stringof == double));
6672 }
6673 
6674 @safe unittest
6675 {
6676     // bug8655
6677     import std.typecons;
6678     import std.bitmanip;
6679     static import core.stdc.config;
6680 
6681     alias c_ulong = Typedef!(core.stdc.config.c_ulong);
6682 
6683     static struct Foo
6684     {
6685         mixin(bitfields!(
6686             c_ulong, "NameOffset", 31,
6687             c_ulong, "NameIsString", 1
6688         ));
6689     }
6690 }
6691 
6692 @safe unittest // Issue 12596
6693 {
6694     import std.typecons;
6695     alias TD = Typedef!int;
6696     TD x = TD(1);
6697     TD y = TD(x);
6698     assert(x == y);
6699 }
6700 
6701 @safe unittest // about toHash
6702 {
6703     import std.typecons;
6704     {
6705         alias TD = Typedef!int;
6706         int[TD] td;
6707         td[TD(1)] = 1;
6708         assert(td[TD(1)] == 1);
6709     }
6710 
6711     {
6712         alias TD = Typedef!(int[]);
6713         int[TD] td;
6714         td[TD([1,2,3,4])] = 2;
6715         assert(td[TD([1,2,3,4])] == 2);
6716     }
6717 
6718     {
6719         alias TD = Typedef!(int[][]);
6720         int[TD] td;
6721         td[TD([[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]])] = 3;
6722         assert(td[TD([[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]])] == 3);
6723     }
6724 
6725     {
6726         struct MyStruct{ int x; }
6727         alias TD = Typedef!MyStruct;
6728         int[TD] td;
6729         td[TD(MyStruct(10))] = 4;
6730         assert(TD(MyStruct(20)) !in td);
6731         assert(td[TD(MyStruct(10))] == 4);
6732     }
6733 
6734     {
6735         static struct MyStruct2
6736         {
6737             int x;
6738             size_t toHash() const nothrow @safe { return x; }
6739             bool opEquals(ref const MyStruct2 r) const { return r.x == x; }
6740         }
6741 
6742         alias TD = Typedef!MyStruct2;
6743         int[TD] td;
6744         td[TD(MyStruct2(50))] = 5;
6745         assert(td[TD(MyStruct2(50))] == 5);
6746     }
6747 
6748     {
6749         class MyClass{}
6750         alias TD = Typedef!MyClass;
6751         int[TD] td;
6752         auto c = new MyClass;
6753         td[TD(c)] = 6;
6754         assert(TD(new MyClass) !in td);
6755         assert(td[TD(c)] == 6);
6756     }
6757 }
6758 
6759 @system unittest
6760 {
6761     alias String = Typedef!(char[]);
6762     alias CString = Typedef!(const(char)[]);
6763     CString cs = "fubar";
6764     String s = cast(String) cs;
6765     assert(cs == s);
6766     char[] s2 = cast(char[]) cs;
6767     const(char)[] cs2 = cast(const(char)[])s;
6768     assert(s2 == cs2);
6769 }
6770 
6771 /**
6772 Allocates a $(D class) object right inside the current scope,
6773 therefore avoiding the overhead of $(D new). This facility is unsafe;
6774 it is the responsibility of the user to not escape a reference to the
6775 object outside the scope.
6776 
6777 The class destructor will be called when the result of `scoped()` is
6778 itself destroyed.
6779 
6780 Scoped class instances can be embedded in a parent `class` or `struct`,
6781 just like a child struct instance. Scoped member variables must have
6782 type `typeof(scoped!Class(args))`, and be initialized with a call to
6783 scoped. See below for an example.
6784 
6785 Note:
6786 It's illegal to move a class instance even if you are sure there
6787 are no pointers to it. As such, it is illegal to move a scoped object.
6788  */
6789 template scoped(T)
6790     if (is(T == class))
6791 {
6792     // _d_newclass now use default GC alignment (looks like (void*).sizeof * 2 for
6793     // small objects). We will just use the maximum of filed alignments.
6794     alias alignment = classInstanceAlignment!T;
6795     alias aligned = _alignUp!alignment;
6796 
6797     static struct Scoped
6798     {
6799         // Addition of `alignment` is required as `Scoped_store` can be misaligned in memory.
6800         private void[aligned(__traits(classInstanceSize, T) + size_t.sizeof) + alignment] Scoped_store = void;
6801 
6802         @property inout(T) Scoped_payload() inout
6803         {
6804             void* alignedStore = cast(void*) aligned(cast(uintptr_t) Scoped_store.ptr);
6805             // As `Scoped` can be unaligned moved in memory class instance should be moved accordingly.
6806             immutable size_t d = alignedStore - Scoped_store.ptr;
6807             size_t* currD = cast(size_t*) &Scoped_store[$ - size_t.sizeof];
6808             if (d != *currD)
6809             {
6810                 import core.stdc.string : memmove;
6811                 memmove(alignedStore, Scoped_store.ptr + *currD, __traits(classInstanceSize, T));
6812                 *currD = d;
6813             }
6814             return cast(inout(T)) alignedStore;
6815         }
6816         alias Scoped_payload this;
6817 
6818         @disable this();
6819         @disable this(this);
6820 
6821         ~this()
6822         {
6823             // `destroy` will also write .init but we have no functions in druntime
6824             // for deterministic finalization and memory releasing for now.
6825             .destroy(Scoped_payload);
6826         }
6827     }
6828 
6829     /** Returns the _scoped object.
6830     Params: args = Arguments to pass to $(D T)'s constructor.
6831     */
6832     @system auto scoped(Args...)(auto ref Args args)
6833     {
6834         import std.conv : emplace;
6835 
6836         Scoped result = void;
6837         void* alignedStore = cast(void*) aligned(cast(uintptr_t) result.Scoped_store.ptr);
6838         immutable size_t d = alignedStore - result.Scoped_store.ptr;
6839         *cast(size_t*) &result.Scoped_store[$ - size_t.sizeof] = d;
6840         emplace!(Unqual!T)(result.Scoped_store[d .. $ - size_t.sizeof], args);
6841         return result;
6842     }
6843 }
6844 
6845 ///
6846 @system unittest
6847 {
6848     class A
6849     {
6850         int x;
6851         this()     {x = 0;}
6852         this(int i){x = i;}
6853         ~this()    {}
6854     }
6855 
6856     // Standard usage, constructing A on the stack
6857     auto a1 = scoped!A();
6858     a1.x = 42;
6859 
6860     // Result of `scoped` call implicitly converts to a class reference
6861     A aRef = a1;
6862     assert(aRef.x == 42);
6863 
6864     // Scoped destruction
6865     {
6866         auto a2 = scoped!A(1);
6867         assert(a2.x == 1);
6868         aRef = a2;
6869         // a2 is destroyed here, calling A's destructor
6870     }
6871     // aRef is now an invalid reference
6872 
6873     // Here the temporary scoped A is immediately destroyed.
6874     // This means the reference is then invalid.
6875     version (Bug)
6876     {
6877         // Wrong, should use `auto`
6878         A invalid = scoped!A();
6879     }
6880 
6881     // Restrictions
6882     version (Bug)
6883     {
6884         import std.algorithm.mutation : move;
6885         auto invalid = a1.move; // illegal, scoped objects can't be moved
6886     }
6887     static assert(!is(typeof({
6888         auto e1 = a1; // illegal, scoped objects can't be copied
6889         assert([a1][0].x == 42); // ditto
6890     })));
6891     static assert(!is(typeof({
6892         alias ScopedObject = typeof(a1);
6893         auto e2 = ScopedObject();  // illegal, must be built via scoped!A
6894         auto e3 = ScopedObject(1); // ditto
6895     })));
6896 
6897     // Use with alias
6898     alias makeScopedA = scoped!A;
6899     auto a3 = makeScopedA();
6900     auto a4 = makeScopedA(1);
6901 
6902     // Use as member variable
6903     struct B
6904     {
6905         typeof(scoped!A()) a; // note the trailing parentheses
6906 
6907         this(int i)
6908         {
6909             // construct member
6910             a = scoped!A(i);
6911         }
6912     }
6913 
6914     // Stack-allocate
6915     auto b1 = B(5);
6916     aRef = b1.a;
6917     assert(aRef.x == 5);
6918     destroy(b1); // calls A's destructor for b1.a
6919     // aRef is now an invalid reference
6920 
6921     // Heap-allocate
6922     auto b2 = new B(6);
6923     assert(b2.a.x == 6);
6924     destroy(*b2); // calls A's destructor for b2.a
6925 }
6926 
6927 private uintptr_t _alignUp(uintptr_t alignment)(uintptr_t n)
6928     if (alignment > 0 && !((alignment - 1) & alignment))
6929 {
6930     enum badEnd = alignment - 1; // 0b11, 0b111, ...
6931     return (n + badEnd) & ~badEnd;
6932 }
6933 
6934 @system unittest // Issue 6580 testcase
6935 {
6936     enum alignment = (void*).alignof;
6937 
6938     static class C0 { }
6939     static class C1 { byte b; }
6940     static class C2 { byte[2] b; }
6941     static class C3 { byte[3] b; }
6942     static class C7 { byte[7] b; }
6943     static assert(scoped!C0().sizeof % alignment == 0);
6944     static assert(scoped!C1().sizeof % alignment == 0);
6945     static assert(scoped!C2().sizeof % alignment == 0);
6946     static assert(scoped!C3().sizeof % alignment == 0);
6947     static assert(scoped!C7().sizeof % alignment == 0);
6948 
6949     enum longAlignment = long.alignof;
6950     static class C1long
6951     {
6952         long long_; byte byte_ = 4;
6953         this() { }
6954         this(long _long, ref int i) { long_ = _long; ++i; }
6955     }
6956     static class C2long { byte[2] byte_ = [5, 6]; long long_ = 7; }
6957     static assert(scoped!C1long().sizeof % longAlignment == 0);
6958     static assert(scoped!C2long().sizeof % longAlignment == 0);
6959 
6960     void alignmentTest()
6961     {
6962         int var = 5;
6963         auto c1long = scoped!C1long(3, var);
6964         assert(var == 6);
6965         auto c2long = scoped!C2long();
6966         assert(cast(uint)&c1long.long_ % longAlignment == 0);
6967         assert(cast(uint)&c2long.long_ % longAlignment == 0);
6968         assert(c1long.long_ == 3 && c1long.byte_ == 4);
6969         assert(c2long.byte_ == [5, 6] && c2long.long_ == 7);
6970     }
6971 
6972     alignmentTest();
6973 
6974     version (DigitalMars)
6975     {
6976         void test(size_t size)
6977         {
6978             import core.stdc.stdlib;
6979             alloca(size);
6980             alignmentTest();
6981         }
6982         foreach (i; 0 .. 10)
6983             test(i);
6984     }
6985     else
6986     {
6987         void test(size_t size)()
6988         {
6989             byte[size] arr;
6990             alignmentTest();
6991         }
6992         foreach (i; AliasSeq!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
6993             test!i();
6994     }
6995 }
6996 
6997 @system unittest // Original Issue 6580 testcase
6998 {
6999     class C { int i; byte b; }
7000 
7001     auto sa = [scoped!C(), scoped!C()];
7002     assert(cast(uint)&sa[0].i % int.alignof == 0);
7003     assert(cast(uint)&sa[1].i % int.alignof == 0); // fails
7004 }
7005 
7006 @system unittest
7007 {
7008     class A { int x = 1; }
7009     auto a1 = scoped!A();
7010     assert(a1.x == 1);
7011     auto a2 = scoped!A();
7012     a1.x = 42;
7013     a2.x = 53;
7014     assert(a1.x == 42);
7015 }
7016 
7017 @system unittest
7018 {
7019     class A { int x = 1; this() { x = 2; } }
7020     auto a1 = scoped!A();
7021     assert(a1.x == 2);
7022     auto a2 = scoped!A();
7023     a1.x = 42;
7024     a2.x = 53;
7025     assert(a1.x == 42);
7026 }
7027 
7028 @system unittest
7029 {
7030     class A { int x = 1; this(int y) { x = y; } ~this() {} }
7031     auto a1 = scoped!A(5);
7032     assert(a1.x == 5);
7033     auto a2 = scoped!A(42);
7034     a1.x = 42;
7035     a2.x = 53;
7036     assert(a1.x == 42);
7037 }
7038 
7039 @system unittest
7040 {
7041     class A { static bool dead; ~this() { dead = true; } }
7042     class B : A { static bool dead; ~this() { dead = true; } }
7043     {
7044         auto b = scoped!B();
7045     }
7046     assert(B.dead, "asdasd");
7047     assert(A.dead, "asdasd");
7048 }
7049 
7050 @system unittest // Issue 8039 testcase
7051 {
7052     static int dels;
7053     static struct S { ~this(){ ++dels; } }
7054 
7055     static class A { S s; }
7056     dels = 0; { scoped!A(); }
7057     assert(dels == 1);
7058 
7059     static class B { S[2] s; }
7060     dels = 0; { scoped!B(); }
7061     assert(dels == 2);
7062 
7063     static struct S2 { S[3] s; }
7064     static class C { S2[2] s; }
7065     dels = 0; { scoped!C(); }
7066     assert(dels == 6);
7067 
7068     static class D: A { S2[2] s; }
7069     dels = 0; { scoped!D(); }
7070     assert(dels == 1+6);
7071 }
7072 
7073 @system unittest
7074 {
7075     // bug4500
7076     class A
7077     {
7078         this() { a = this; }
7079         this(int i) { a = this; }
7080         A a;
7081         bool check() { return this is a; }
7082     }
7083 
7084     auto a1 = scoped!A();
7085     assert(a1.check());
7086 
7087     auto a2 = scoped!A(1);
7088     assert(a2.check());
7089 
7090     a1.a = a1;
7091     assert(a1.check());
7092 }
7093 
7094 @system unittest
7095 {
7096     static class A
7097     {
7098         static int sdtor;
7099 
7100         this() { ++sdtor; assert(sdtor == 1); }
7101         ~this() { assert(sdtor == 1); --sdtor; }
7102     }
7103 
7104     interface Bob {}
7105 
7106     static class ABob : A, Bob
7107     {
7108         this() { ++sdtor; assert(sdtor == 2); }
7109         ~this() { assert(sdtor == 2); --sdtor; }
7110     }
7111 
7112     A.sdtor = 0;
7113     scope(exit) assert(A.sdtor == 0);
7114     auto abob = scoped!ABob();
7115 }
7116 
7117 @safe unittest
7118 {
7119     static class A { this(int) {} }
7120     static assert(!__traits(compiles, scoped!A()));
7121 }
7122 
7123 @system unittest
7124 {
7125     static class A { @property inout(int) foo() inout { return 1; } }
7126 
7127     auto a1 = scoped!A();
7128     assert(a1.foo == 1);
7129     static assert(is(typeof(a1.foo) == int));
7130 
7131     auto a2 = scoped!(const(A))();
7132     assert(a2.foo == 1);
7133     static assert(is(typeof(a2.foo) == const(int)));
7134 
7135     auto a3 = scoped!(immutable(A))();
7136     assert(a3.foo == 1);
7137     static assert(is(typeof(a3.foo) == immutable(int)));
7138 
7139     const c1 = scoped!A();
7140     assert(c1.foo == 1);
7141     static assert(is(typeof(c1.foo) == const(int)));
7142 
7143     const c2 = scoped!(const(A))();
7144     assert(c2.foo == 1);
7145     static assert(is(typeof(c2.foo) == const(int)));
7146 
7147     const c3 = scoped!(immutable(A))();
7148     assert(c3.foo == 1);
7149     static assert(is(typeof(c3.foo) == immutable(int)));
7150 }
7151 
7152 @system unittest
7153 {
7154     class C { this(ref int val) { assert(val == 3); ++val; } }
7155 
7156     int val = 3;
7157     auto s = scoped!C(val);
7158     assert(val == 4);
7159 }
7160 
7161 @system unittest
7162 {
7163     class C
7164     {
7165         this(){}
7166         this(int){}
7167         this(int, int){}
7168     }
7169     alias makeScopedC = scoped!C;
7170 
7171     auto a = makeScopedC();
7172     auto b = makeScopedC(1);
7173     auto c = makeScopedC(1, 1);
7174 
7175     static assert(is(typeof(a) == typeof(b)));
7176     static assert(is(typeof(b) == typeof(c)));
7177 }
7178 
7179 /**
7180 Defines a simple, self-documenting yes/no flag. This makes it easy for
7181 APIs to define functions accepting flags without resorting to $(D
7182 bool), which is opaque in calls, and without needing to define an
7183 enumerated type separately. Using $(D Flag!"Name") instead of $(D
7184 bool) makes the flag's meaning visible in calls. Each yes/no flag has
7185 its own type, which makes confusions and mix-ups impossible.
7186 
7187 Example:
7188 
7189 Code calling $(D getLine) (usually far away from its definition) can't be
7190 understood without looking at the documentation, even by users familiar with
7191 the API:
7192 ----
7193 string getLine(bool keepTerminator)
7194 {
7195     ...
7196     if (keepTerminator) ...
7197     ...
7198 }
7199 ...
7200 auto line = getLine(false);
7201 ----
7202 
7203 Assuming the reverse meaning (i.e. "ignoreTerminator") and inserting the wrong
7204 code compiles and runs with erroneous results.
7205 
7206 After replacing the boolean parameter with an instantiation of $(D Flag), code
7207 calling $(D getLine) can be easily read and understood even by people not
7208 fluent with the API:
7209 
7210 ----
7211 string getLine(Flag!"keepTerminator" keepTerminator)
7212 {
7213     ...
7214     if (keepTerminator) ...
7215     ...
7216 }
7217 ...
7218 auto line = getLine(Yes.keepTerminator);
7219 ----
7220 
7221 The structs $(D Yes) and $(D No) are provided as shorthand for
7222 $(D Flag!"Name".yes) and $(D Flag!"Name".no) and are preferred for brevity and
7223 readability. These convenience structs mean it is usually unnecessary and
7224 counterproductive to create an alias of a $(D Flag) as a way of avoiding typing
7225 out the full type while specifying the affirmative or negative options.
7226 
7227 Passing categorical data by means of unstructured $(D bool)
7228 parameters is classified under "simple-data coupling" by Steve
7229 McConnell in the $(LUCKY Code Complete) book, along with three other
7230 kinds of coupling. The author argues citing several studies that
7231 coupling has a negative effect on code quality. $(D Flag) offers a
7232 simple structuring method for passing yes/no flags to APIs.
7233  */
7234 template Flag(string name) {
7235     ///
7236     enum Flag : bool
7237     {
7238         /**
7239          When creating a value of type $(D Flag!"Name"), use $(D
7240          Flag!"Name".no) for the negative option. When using a value
7241          of type $(D Flag!"Name"), compare it against $(D
7242          Flag!"Name".no) or just $(D false) or $(D 0).  */
7243         no = false,
7244 
7245         /** When creating a value of type $(D Flag!"Name"), use $(D
7246          Flag!"Name".yes) for the affirmative option. When using a
7247          value of type $(D Flag!"Name"), compare it against $(D
7248          Flag!"Name".yes).
7249         */
7250         yes = true
7251     }
7252 }
7253 
7254 /**
7255 Convenience names that allow using e.g. $(D Yes.encryption) instead of
7256 $(D Flag!"encryption".yes) and $(D No.encryption) instead of $(D
7257 Flag!"encryption".no).
7258 */
7259 struct Yes
7260 {
7261     template opDispatch(string name)
7262     {
7263         enum opDispatch = Flag!name.yes;
7264     }
7265 }
7266 //template yes(string name) { enum Flag!name yes = Flag!name.yes; }
7267 
7268 /// Ditto
7269 struct No
7270 {
7271     template opDispatch(string name)
7272     {
7273         enum opDispatch = Flag!name.no;
7274     }
7275 }
7276 
7277 ///
7278 @safe unittest
7279 {
7280     Flag!"abc" flag1;
7281     assert(flag1 == Flag!"abc".no);
7282     assert(flag1 == No.abc);
7283     assert(!flag1);
7284     if (flag1) assert(false);
7285     flag1 = Yes.abc;
7286     assert(flag1);
7287     if (!flag1) assert(false);
7288     if (flag1) {} else assert(false);
7289     assert(flag1 == Yes.abc);
7290 }
7291 
7292 /**
7293 Detect whether an enum is of integral type and has only "flag" values
7294 (i.e. values with a bit count of exactly 1).
7295 Additionally, a zero value is allowed for compatibility with enums including
7296 a "None" value.
7297 */
7298 template isBitFlagEnum(E)
7299 {
7300     static if (is(E Base == enum) && isIntegral!Base)
7301     {
7302         enum isBitFlagEnum = (E.min >= 0) &&
7303         {
7304             foreach (immutable flag; EnumMembers!E)
7305             {
7306                 Base value = flag;
7307                 value &= value - 1;
7308                 if (value != 0) return false;
7309             }
7310             return true;
7311         }();
7312     }
7313     else
7314     {
7315         enum isBitFlagEnum = false;
7316     }
7317 }
7318 
7319 ///
7320 @safe pure nothrow unittest
7321 {
7322     enum A
7323     {
7324         None,
7325         A = 1 << 0,
7326         B = 1 << 1,
7327         C = 1 << 2,
7328         D = 1 << 3,
7329     }
7330 
7331     static assert(isBitFlagEnum!A);
7332 
7333     enum B
7334     {
7335         A,
7336         B,
7337         C,
7338         D // D == 3
7339     }
7340 
7341     static assert(!isBitFlagEnum!B);
7342 
7343     enum C: double
7344     {
7345         A = 1 << 0,
7346         B = 1 << 1
7347     }
7348 
7349     static assert(!isBitFlagEnum!C);
7350 }
7351 
7352 /**
7353 A typesafe structure for storing combinations of enum values.
7354 
7355 This template defines a simple struct to represent bitwise OR combinations of
7356 enum values. It can be used if all the enum values are integral constants with
7357 a bit count of at most 1, or if the $(D unsafe) parameter is explicitly set to
7358 Yes.
7359 This is much safer than using the enum itself to store
7360 the OR combination, which can produce surprising effects like this:
7361 ----
7362 enum E
7363 {
7364     A = 1 << 0,
7365     B = 1 << 1
7366 }
7367 E e = E.A | E.B;
7368 // will throw SwitchError
7369 final switch (e)
7370 {
7371     case E.A:
7372         return;
7373     case E.B:
7374         return;
7375 }
7376 ----
7377 */
7378 struct BitFlags(E, Flag!"unsafe" unsafe = No.unsafe) if (unsafe || isBitFlagEnum!(E))
7379 {
7380 @safe @nogc pure nothrow:
7381 private:
7382     enum isBaseEnumType(T) = is(E == T);
7383     alias Base = OriginalType!E;
7384     Base mValue;
7385     static struct Negation
7386     {
7387     @safe @nogc pure nothrow:
7388     private:
7389         Base mValue;
7390 
7391         // Prevent non-copy construction outside the module.
7392         @disable this();
7393         this(Base value)
7394         {
7395             mValue = value;
7396         }
7397     }
7398 
7399 public:
7400     this(E flag)
7401     {
7402         this = flag;
7403     }
7404 
7405     this(T...)(T flags)
7406         if (allSatisfy!(isBaseEnumType, T))
7407     {
7408         this = flags;
7409     }
7410 
7411     bool opCast(B: bool)() const
7412     {
7413         return mValue != 0;
7414     }
7415 
7416     Base opCast(B)() const
7417         if (isImplicitlyConvertible!(Base, B))
7418     {
7419         return mValue;
7420     }
7421 
7422     Negation opUnary(string op)() const
7423         if (op == "~")
7424     {
7425         return Negation(~mValue);
7426     }
7427 
7428     auto ref opAssign(T...)(T flags)
7429         if (allSatisfy!(isBaseEnumType, T))
7430     {
7431         mValue = 0;
7432         foreach (E flag; flags)
7433         {
7434             mValue |= flag;
7435         }
7436         return this;
7437     }
7438 
7439     auto ref opAssign(E flag)
7440     {
7441         mValue = flag;
7442         return this;
7443     }
7444 
7445     auto ref opOpAssign(string op: "|")(BitFlags flags)
7446     {
7447         mValue |= flags.mValue;
7448         return this;
7449     }
7450 
7451     auto ref opOpAssign(string op: "&")(BitFlags  flags)
7452     {
7453         mValue &= flags.mValue;
7454         return this;
7455     }
7456 
7457     auto ref opOpAssign(string op: "|")(E flag)
7458     {
7459         mValue |= flag;
7460         return this;
7461     }
7462 
7463     auto ref opOpAssign(string op: "&")(E flag)
7464     {
7465         mValue &= flag;
7466         return this;
7467     }
7468 
7469     auto ref opOpAssign(string op: "&")(Negation negatedFlags)
7470     {
7471         mValue &= negatedFlags.mValue;
7472         return this;
7473     }
7474 
7475     auto opBinary(string op)(BitFlags flags) const
7476         if (op == "|" || op == "&")
7477     {
7478         BitFlags result = this;
7479         result.opOpAssign!op(flags);
7480         return result;
7481     }
7482 
7483     auto opBinary(string op)(E flag) const
7484         if (op == "|" || op == "&")
7485     {
7486         BitFlags result = this;
7487         result.opOpAssign!op(flag);
7488         return result;
7489     }
7490 
7491     auto opBinary(string op: "&")(Negation negatedFlags) const
7492     {
7493         BitFlags result = this;
7494         result.opOpAssign!op(negatedFlags);
7495         return result;
7496     }
7497 
7498     auto opBinaryRight(string op)(E flag) const
7499         if (op == "|" || op == "&")
7500     {
7501         return opBinary!op(flag);
7502     }
7503 }
7504 
7505 /// BitFlags can be manipulated with the usual operators
7506 @safe @nogc pure nothrow unittest
7507 {
7508     import std.traits : EnumMembers;
7509 
7510     // You can use such an enum with BitFlags straight away
7511     enum Enum
7512     {
7513         None,
7514         A = 1 << 0,
7515         B = 1 << 1,
7516         C = 1 << 2
7517     }
7518     BitFlags!Enum flags1;
7519     assert(!(flags1 & (Enum.A | Enum.B | Enum.C)));
7520 
7521     // You need to specify the `unsafe` parameter for enum with custom values
7522     enum UnsafeEnum
7523     {
7524         A,
7525         B,
7526         C,
7527         D = B|C
7528     }
7529     static assert(!__traits(compiles, { BitFlags!UnsafeEnum flags2; }));
7530     BitFlags!(UnsafeEnum, Yes.unsafe) flags3;
7531 
7532     immutable BitFlags!Enum flags_empty;
7533     // A default constructed BitFlags has no value set
7534     assert(!(flags_empty & Enum.A) && !(flags_empty & Enum.B) && !(flags_empty & Enum.C));
7535 
7536     // Value can be set with the | operator
7537     immutable BitFlags!Enum flags_A = flags_empty | Enum.A;
7538 
7539     // And tested with the & operator
7540     assert(flags_A & Enum.A);
7541 
7542     // Which commutes
7543     assert(Enum.A & flags_A);
7544 
7545     // BitFlags can be variadically initialized
7546     immutable BitFlags!Enum flags_AB = BitFlags!Enum(Enum.A, Enum.B);
7547     assert((flags_AB & Enum.A) && (flags_AB & Enum.B) && !(flags_AB & Enum.C));
7548 
7549     // Use the ~ operator for subtracting flags
7550     immutable BitFlags!Enum flags_B = flags_AB & ~BitFlags!Enum(Enum.A);
7551     assert(!(flags_B & Enum.A) && (flags_B & Enum.B) && !(flags_B & Enum.C));
7552 
7553     // You can use the EnumMembers template to set all flags
7554     immutable BitFlags!Enum flags_all = EnumMembers!Enum;
7555 
7556     // use & between BitFlags for intersection
7557     immutable BitFlags!Enum flags_BC = BitFlags!Enum(Enum.B, Enum.C);
7558     assert(flags_B == (flags_BC & flags_AB));
7559 
7560     // All the binary operators work in their assignment version
7561     BitFlags!Enum temp = flags_empty;
7562     temp |= flags_AB;
7563     assert(temp == (flags_empty | flags_AB));
7564     temp = flags_empty;
7565     temp |= Enum.B;
7566     assert(temp == (flags_empty | Enum.B));
7567     temp = flags_empty;
7568     temp &= flags_AB;
7569     assert(temp == (flags_empty & flags_AB));
7570     temp = flags_empty;
7571     temp &= Enum.A;
7572     assert(temp == (flags_empty & Enum.A));
7573 
7574     // BitFlags with no value set evaluate to false
7575     assert(!flags_empty);
7576 
7577     // BitFlags with at least one value set evaluate to true
7578     assert(flags_A);
7579 
7580     // This can be useful to check intersection between BitFlags
7581     assert(flags_A & flags_AB);
7582     assert(flags_AB & Enum.A);
7583 
7584     // Finally, you can of course get you raw value out of flags
7585     auto value = cast(int) flags_A;
7586     assert(value == Enum.A);
7587 }
7588 
7589 // ReplaceType
7590 /**
7591 Replaces all occurrences of `From` into `To`, in one or more types `T`. For
7592 example, $(D ReplaceType!(int, uint, Tuple!(int, float)[string])) yields
7593 $(D Tuple!(uint, float)[string]). The types in which replacement is performed
7594 may be arbitrarily complex, including qualifiers, built-in type constructors
7595 (pointers, arrays, associative arrays, functions, and delegates), and template
7596 instantiations; replacement proceeds transitively through the type definition.
7597 However, member types in `struct`s or `class`es are not replaced because there
7598 are no ways to express the types resulting after replacement.
7599 
7600 This is an advanced type manipulation necessary e.g. for replacing the
7601 placeholder type `This` in $(REF Algebraic, std,variant).
7602 
7603 Returns: `ReplaceType` aliases itself to the type(s) that result after
7604 replacement.
7605 */
7606 template ReplaceType(From, To, T...)
7607 {
7608     static if (T.length == 1)
7609     {
7610         static if (is(T[0] == From))
7611             alias ReplaceType = To;
7612         else static if (is(T[0] == const(U), U))
7613             alias ReplaceType = const(ReplaceType!(From, To, U));
7614         else static if (is(T[0] == immutable(U), U))
7615             alias ReplaceType = immutable(ReplaceType!(From, To, U));
7616         else static if (is(T[0] == shared(U), U))
7617             alias ReplaceType = shared(ReplaceType!(From, To, U));
7618         else static if (is(T[0] == U*, U))
7619         {
7620             static if (is(U == function))
7621                 alias ReplaceType = replaceTypeInFunctionType!(From, To, T[0]);
7622             else
7623                 alias ReplaceType = ReplaceType!(From, To, U)*;
7624         }
7625         else static if (is(T[0] == delegate))
7626         {
7627             alias ReplaceType = replaceTypeInFunctionType!(From, To, T[0]);
7628         }
7629         else static if (is(T[0] == function))
7630         {
7631             static assert(0, "Function types not supported," ~
7632                 " use a function pointer type instead of " ~ T[0].stringof);
7633         }
7634         else static if (is(T[0] : U!V, alias U, V...))
7635         {
7636             template replaceTemplateArgs(T...)
7637             {
7638                 static if (is(typeof(T[0])))    // template argument is value or symbol
7639                     enum replaceTemplateArgs = T[0];
7640                 else
7641                     alias replaceTemplateArgs = ReplaceType!(From, To, T[0]);
7642             }
7643             alias ReplaceType = U!(staticMap!(replaceTemplateArgs, V));
7644         }
7645         else static if (is(T[0] == struct))
7646             // don't match with alias this struct below (Issue 15168)
7647             alias ReplaceType = T[0];
7648         else static if (is(T[0] == U[], U))
7649             alias ReplaceType = ReplaceType!(From, To, U)[];
7650         else static if (is(T[0] == U[n], U, size_t n))
7651             alias ReplaceType = ReplaceType!(From, To, U)[n];
7652         else static if (is(T[0] == U[V], U, V))
7653             alias ReplaceType =
7654                 ReplaceType!(From, To, U)[ReplaceType!(From, To, V)];
7655         else
7656             alias ReplaceType = T[0];
7657     }
7658     else static if (T.length > 1)
7659     {
7660         alias ReplaceType = AliasSeq!(ReplaceType!(From, To, T[0]),
7661             ReplaceType!(From, To, T[1 .. $]));
7662     }
7663     else
7664     {
7665         alias ReplaceType = AliasSeq!();
7666     }
7667 }
7668 
7669 ///
7670 @safe unittest
7671 {
7672     static assert(
7673         is(ReplaceType!(int, string, int[]) == string[]) &&
7674         is(ReplaceType!(int, string, int[int]) == string[string]) &&
7675         is(ReplaceType!(int, string, const(int)[]) == const(string)[]) &&
7676         is(ReplaceType!(int, string, Tuple!(int[], float))
7677             == Tuple!(string[], float))
7678     );
7679 }
7680 
7681 private template replaceTypeInFunctionType(From, To, fun)
7682 {
7683     alias RX = ReplaceType!(From, To, ReturnType!fun);
7684     alias PX = AliasSeq!(ReplaceType!(From, To, Parameters!fun));
7685     // Wrapping with AliasSeq is neccesary because ReplaceType doesn't return
7686     // tuple if Parameters!fun.length == 1
7687 
7688     string gen()
7689     {
7690         enum  linkage = functionLinkage!fun;
7691         alias attributes = functionAttributes!fun;
7692         enum  variadicStyle = variadicFunctionStyle!fun;
7693         alias storageClasses = ParameterStorageClassTuple!fun;
7694 
7695         string result;
7696 
7697         result ~= "extern(" ~ linkage ~ ") ";
7698         static if (attributes & FunctionAttribute.ref_)
7699         {
7700             result ~= "ref ";
7701         }
7702 
7703         result ~= "RX";
7704         static if (is(fun == delegate))
7705             result ~= " delegate";
7706         else
7707             result ~= " function";
7708 
7709         result ~= "(";
7710         foreach (i, _; PX)
7711         {
7712             if (i)
7713                 result ~= ", ";
7714             if (storageClasses[i] & ParameterStorageClass.scope_)
7715                 result ~= "scope ";
7716             if (storageClasses[i] & ParameterStorageClass.out_)
7717                 result ~= "out ";
7718             if (storageClasses[i] & ParameterStorageClass.ref_)
7719                 result ~= "ref ";
7720             if (storageClasses[i] & ParameterStorageClass.lazy_)
7721                 result ~= "lazy ";
7722             if (storageClasses[i] & ParameterStorageClass.return_)
7723                 result ~= "return ";
7724 
7725             result ~= "PX[" ~ i.stringof ~ "]";
7726         }
7727         static if (variadicStyle == Variadic.typesafe)
7728             result ~= " ...";
7729         else static if (variadicStyle != Variadic.no)
7730             result ~= ", ...";
7731         result ~= ")";
7732 
7733         static if (attributes & FunctionAttribute.pure_)
7734             result ~= " pure";
7735         static if (attributes & FunctionAttribute.nothrow_)
7736             result ~= " nothrow";
7737         static if (attributes & FunctionAttribute.property)
7738             result ~= " @property";
7739         static if (attributes & FunctionAttribute.trusted)
7740             result ~= " @trusted";
7741         static if (attributes & FunctionAttribute.safe)
7742             result ~= " @safe";
7743         static if (attributes & FunctionAttribute.nogc)
7744             result ~= " @nogc";
7745         static if (attributes & FunctionAttribute.system)
7746             result ~= " @system";
7747         static if (attributes & FunctionAttribute.const_)
7748             result ~= " const";
7749         static if (attributes & FunctionAttribute.immutable_)
7750             result ~= " immutable";
7751         static if (attributes & FunctionAttribute.inout_)
7752             result ~= " inout";
7753         static if (attributes & FunctionAttribute.shared_)
7754             result ~= " shared";
7755         static if (attributes & FunctionAttribute.return_)
7756             result ~= " return";
7757 
7758         return result;
7759     }
7760     //pragma(msg, "gen ==> ", gen());
7761 
7762     mixin("alias replaceTypeInFunctionType = " ~ gen() ~ ";");
7763 }
7764 
7765 @safe unittest
7766 {
7767     template Test(Ts...)
7768     {
7769         static if (Ts.length)
7770         {
7771             //pragma(msg, "Testing: ReplaceType!("~Ts[0].stringof~", "
7772             //    ~Ts[1].stringof~", "~Ts[2].stringof~")");
7773             static assert(is(ReplaceType!(Ts[0], Ts[1], Ts[2]) == Ts[3]),
7774                 "ReplaceType!("~Ts[0].stringof~", "~Ts[1].stringof~", "
7775                     ~Ts[2].stringof~") == "
7776                     ~ReplaceType!(Ts[0], Ts[1], Ts[2]).stringof);
7777             alias Test = Test!(Ts[4 .. $]);
7778         }
7779         else alias Test = void;
7780     }
7781 
7782     //import core.stdc.stdio;
7783     alias RefFun1 = ref int function(float, long);
7784     alias RefFun2 = ref float function(float, long);
7785     extern(C) int printf(const char*, ...) nothrow @nogc @system;
7786     extern(C) float floatPrintf(const char*, ...) nothrow @nogc @system;
7787     int func(float);
7788 
7789     int x;
7790     struct S1 { void foo() { x = 1; } }
7791     struct S2 { void bar() { x = 2; } }
7792 
7793     alias Pass = Test!(
7794         int, float, typeof(&func), float delegate(float),
7795         int, float, typeof(&printf), typeof(&floatPrintf),
7796         int, float, int function(out long, ...),
7797             float function(out long, ...),
7798         int, float, int function(ref float, long),
7799             float function(ref float, long),
7800         int, float, int function(ref int, long),
7801             float function(ref float, long),
7802         int, float, int function(out int, long),
7803             float function(out float, long),
7804         int, float, int function(lazy int, long),
7805             float function(lazy float, long),
7806         int, float, int function(out long, ref const int),
7807             float function(out long, ref const float),
7808         int, int, int, int,
7809         int, float, int, float,
7810         int, float, const int, const float,
7811         int, float, immutable int, immutable float,
7812         int, float, shared int, shared float,
7813         int, float, int*, float*,
7814         int, float, const(int)*, const(float)*,
7815         int, float, const(int*), const(float*),
7816         const(int)*, float, const(int*), const(float),
7817         int*, float, const(int)*, const(int)*,
7818         int, float, int[], float[],
7819         int, float, int[42], float[42],
7820         int, float, const(int)[42], const(float)[42],
7821         int, float, const(int[42]), const(float[42]),
7822         int, float, int[int], float[float],
7823         int, float, int[double], float[double],
7824         int, float, double[int], double[float],
7825         int, float, int function(float, long), float function(float, long),
7826         int, float, int function(float), float function(float),
7827         int, float, int function(float, int), float function(float, float),
7828         int, float, int delegate(float, long), float delegate(float, long),
7829         int, float, int delegate(float), float delegate(float),
7830         int, float, int delegate(float, int), float delegate(float, float),
7831         int, float, Unique!int, Unique!float,
7832         int, float, Tuple!(float, int), Tuple!(float, float),
7833         int, float, RefFun1, RefFun2,
7834         S1, S2,
7835             S1[1][][S1]* function(),
7836             S2[1][][S2]* function(),
7837         int, string,
7838                int[3] function(   int[] arr,    int[2] ...) pure @trusted,
7839             string[3] function(string[] arr, string[2] ...) pure @trusted,
7840     );
7841 
7842     // Bugzilla 15168
7843     static struct T1 { string s; alias s this; }
7844     static struct T2 { char[10] s; alias s this; }
7845     static struct T3 { string[string] s; alias s this; }
7846     alias Pass2 = Test!(
7847         ubyte, ubyte, T1, T1,
7848         ubyte, ubyte, T2, T2,
7849         ubyte, ubyte, T3, T3,
7850     );
7851 }
7852 
7853 @safe unittest // Bugzilla 17116
7854 {
7855     alias ConstDg = void delegate(float) const;
7856     alias B = void delegate(int) const;
7857     alias A = ReplaceType!(float, int, ConstDg);
7858     static assert(is(B == A));
7859 }
7860 
7861 /**
7862 Ternary type with three truth values:
7863 
7864 $(UL
7865     $(LI `Ternary.yes` for `true`)
7866     $(LI `Ternary.no` for `false`)
7867     $(LI `Ternary.unknown` as an unknown state)
7868 )
7869 
7870 Also known as trinary, trivalent, or trilean.
7871 
7872 See_Also:
7873     $(HTTP en.wikipedia.org/wiki/Three-valued_logic,
7874         Three Valued Logic on Wikipedia)
7875 */
7876 struct Ternary
7877 {
7878     @safe @nogc nothrow pure:
7879 
7880     private ubyte value = 6;
7881     private static Ternary make(ubyte b)
7882     {
7883         Ternary r = void;
7884         r.value = b;
7885         return r;
7886     }
7887 
7888     /**
7889         The possible states of the `Ternary`
7890     */
7891     enum no = make(0);
7892     /// ditto
7893     enum yes = make(2);
7894     /// ditto
7895     enum unknown = make(6);
7896 
7897     /**
7898      Construct and assign from a `bool`, receiving `no` for `false` and `yes`
7899      for `true`.
7900     */
7901     this(bool b) { value = b << 1; }
7902 
7903     /// ditto
7904     void opAssign(bool b) { value = b << 1; }
7905 
7906     /**
7907     Construct a ternary value from another ternary value
7908     */
7909     this(const Ternary b) { value = b.value; }
7910 
7911     /**
7912     $(TABLE Truth table for logical operations,
7913       $(TR $(TH `a`) $(TH `b`) $(TH `$(TILDE)a`) $(TH `a | b`) $(TH `a & b`) $(TH `a ^ b`))
7914       $(TR $(TD `no`) $(TD `no`) $(TD `yes`) $(TD `no`) $(TD `no`) $(TD `no`))
7915       $(TR $(TD `no`) $(TD `yes`) $(TD) $(TD `yes`) $(TD `no`) $(TD `yes`))
7916       $(TR $(TD `no`) $(TD `unknown`) $(TD) $(TD `unknown`) $(TD `no`) $(TD `unknown`))
7917       $(TR $(TD `yes`) $(TD `no`) $(TD `no`) $(TD `yes`) $(TD `no`) $(TD `yes`))
7918       $(TR $(TD `yes`) $(TD `yes`) $(TD) $(TD `yes`) $(TD `yes`) $(TD `no`))
7919       $(TR $(TD `yes`) $(TD `unknown`) $(TD) $(TD `yes`) $(TD `unknown`) $(TD `unknown`))
7920       $(TR $(TD `unknown`) $(TD `no`) $(TD `unknown`) $(TD `unknown`) $(TD `no`) $(TD `unknown`))
7921       $(TR $(TD `unknown`) $(TD `yes`) $(TD) $(TD `yes`) $(TD `unknown`) $(TD `unknown`))
7922       $(TR $(TD `unknown`) $(TD `unknown`) $(TD) $(TD `unknown`) $(TD `unknown`) $(TD `unknown`))
7923     )
7924     */
7925     Ternary opUnary(string s)() if (s == "~")
7926     {
7927         return make((386 >> value) & 6);
7928     }
7929 
7930     /// ditto
7931     Ternary opBinary(string s)(Ternary rhs) if (s == "|")
7932     {
7933         return make((25_512 >> (value + rhs.value)) & 6);
7934     }
7935 
7936     /// ditto
7937     Ternary opBinary(string s)(Ternary rhs) if (s == "&")
7938     {
7939         return make((26_144 >> (value + rhs.value)) & 6);
7940     }
7941 
7942     /// ditto
7943     Ternary opBinary(string s)(Ternary rhs) if (s == "^")
7944     {
7945         return make((26_504 >> (value + rhs.value)) & 6);
7946     }
7947 }
7948 
7949 ///
7950 @safe @nogc nothrow pure
7951 unittest
7952 {
7953     Ternary a;
7954     assert(a == Ternary.unknown);
7955 
7956     assert(~Ternary.yes == Ternary.no);
7957     assert(~Ternary.no == Ternary.yes);
7958     assert(~Ternary.unknown == Ternary.unknown);
7959 }
7960 
7961 @safe @nogc nothrow pure
7962 unittest
7963 {
7964     alias f = Ternary.no, t = Ternary.yes, u = Ternary.unknown;
7965     Ternary[27] truthTableAnd =
7966     [
7967         t, t, t,
7968         t, u, u,
7969         t, f, f,
7970         u, t, u,
7971         u, u, u,
7972         u, f, f,
7973         f, t, f,
7974         f, u, f,
7975         f, f, f,
7976     ];
7977 
7978     Ternary[27] truthTableOr =
7979     [
7980         t, t, t,
7981         t, u, t,
7982         t, f, t,
7983         u, t, t,
7984         u, u, u,
7985         u, f, u,
7986         f, t, t,
7987         f, u, u,
7988         f, f, f,
7989     ];
7990 
7991     Ternary[27] truthTableXor =
7992     [
7993         t, t, f,
7994         t, u, u,
7995         t, f, t,
7996         u, t, u,
7997         u, u, u,
7998         u, f, u,
7999         f, t, t,
8000         f, u, u,
8001         f, f, f,
8002     ];
8003 
8004     for (auto i = 0; i != truthTableAnd.length; i += 3)
8005     {
8006         assert((truthTableAnd[i] & truthTableAnd[i + 1])
8007             == truthTableAnd[i + 2]);
8008         assert((truthTableOr[i] | truthTableOr[i + 1])
8009             == truthTableOr[i + 2]);
8010         assert((truthTableXor[i] ^ truthTableXor[i + 1])
8011             == truthTableXor[i + 2]);
8012     }
8013 
8014     Ternary a;
8015     assert(a == Ternary.unknown);
8016     static assert(!is(typeof({ if (a) {} })));
8017     assert(!is(typeof({ auto b = Ternary(3); })));
8018     a = true;
8019     assert(a == Ternary.yes);
8020     a = false;
8021     assert(a == Ternary.no);
8022     a = Ternary.unknown;
8023     assert(a == Ternary.unknown);
8024     Ternary b;
8025     b = a;
8026     assert(b == a);
8027     assert(~Ternary.yes == Ternary.no);
8028     assert(~Ternary.no == Ternary.yes);
8029     assert(~Ternary.unknown == Ternary.unknown);
8030 }
8031