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 (is(typeof(mixin("a."~name))) || __traits(getOverloads, a, name).length != 0)
5937         {
5938             // field or property function
5939             @property auto ref opDispatch(this X)()                { return mixin("a."~name);        }
5940             @property auto ref opDispatch(this X, V)(auto ref V v) { return mixin("a."~name~" = v"); }
5941         }
5942         else
5943         {
5944             // member template
5945             template opDispatch(T...)
5946             {
5947                 enum targs = T.length ? "!T" : "";
5948                 auto ref opDispatch(this X, Args...)(auto ref Args args){ return mixin("a."~name~targs~"(args)"); }
5949             }
5950         }
5951     }
5952 
5953     import std.traits : isArray;
5954 
5955     static if (isArray!ValueType)
5956     {
5957         auto opDollar() const { return a.length; }
5958     }
5959     else static if (is(typeof(a.opDollar!0)))
5960     {
5961         auto ref opDollar(size_t pos)() { return a.opDollar!pos(); }
5962     }
5963     else static if (is(typeof(a.opDollar) == function))
5964     {
5965         auto ref opDollar() { return a.opDollar(); }
5966     }
5967     else static if (is(typeof(a.opDollar)))
5968     {
5969         alias opDollar = a.opDollar;
5970     }
5971 }
5972 
5973 ///
5974 @safe unittest
5975 {
5976     struct MyInt
5977     {
5978         private int value;
5979         mixin Proxy!value;
5980 
5981         this(int n){ value = n; }
5982     }
5983 
5984     MyInt n = 10;
5985 
5986     // Enable operations that original type has.
5987     ++n;
5988     assert(n == 11);
5989     assert(n * 2 == 22);
5990 
5991     void func(int n) { }
5992 
5993     // Disable implicit conversions to original type.
5994     //int x = n;
5995     //func(n);
5996 }
5997 
5998 ///The proxied value must be an $(B lvalue).
5999 @safe unittest
6000 {
6001     struct NewIntType
6002     {
6003         //Won't work; the literal '1'
6004         //is an rvalue, not an lvalue
6005         //mixin Proxy!1;
6006 
6007         //Okay, n is an lvalue
6008         int n;
6009         mixin Proxy!n;
6010 
6011         this(int n) { this.n = n; }
6012     }
6013 
6014     NewIntType nit = 0;
6015     nit++;
6016     assert(nit == 1);
6017 
6018 
6019     struct NewObjectType
6020     {
6021         Object obj;
6022         //Ok, obj is an lvalue
6023         mixin Proxy!obj;
6024 
6025         this (Object o) { obj = o; }
6026     }
6027 
6028     NewObjectType not = new Object();
6029     assert(__traits(compiles, not.toHash()));
6030 }
6031 
6032 /**
6033     There is one exception to the fact that the new type is not related to the
6034     old type. $(DDSUBLINK spec/function,pseudo-member, Pseudo-member)
6035     functions are usable with the new type; they will be forwarded on to the
6036     proxied value.
6037  */
6038 @safe unittest
6039 {
6040     import std.math;
6041 
6042     float f = 1.0;
6043     assert(!f.isInfinity);
6044 
6045     struct NewFloat
6046     {
6047         float _;
6048         mixin Proxy!_;
6049 
6050         this(float f) { _ = f; }
6051     }
6052 
6053     NewFloat nf = 1.0f;
6054     assert(!nf.isInfinity);
6055 }
6056 
6057 @safe unittest
6058 {
6059     static struct MyInt
6060     {
6061         private int value;
6062         mixin Proxy!value;
6063         this(int n) inout { value = n; }
6064 
6065         enum str = "str";
6066         static immutable arr = [1,2,3];
6067     }
6068 
6069     foreach (T; AliasSeq!(MyInt, const MyInt, immutable MyInt))
6070     {
6071         T m = 10;
6072         static assert(!__traits(compiles, { int x = m; }));
6073         static assert(!__traits(compiles, { void func(int n){} func(m); }));
6074         assert(m == 10);
6075         assert(m != 20);
6076         assert(m < 20);
6077         assert(+m == 10);
6078         assert(-m == -10);
6079         assert(cast(double) m == 10.0);
6080         assert(m + 10 == 20);
6081         assert(m - 5 == 5);
6082         assert(m * 20 == 200);
6083         assert(m / 2 == 5);
6084         assert(10 + m == 20);
6085         assert(15 - m == 5);
6086         assert(20 * m == 200);
6087         assert(50 / m == 5);
6088         static if (is(T == MyInt))  // mutable
6089         {
6090             assert(++m == 11);
6091             assert(m++ == 11); assert(m == 12);
6092             assert(--m == 11);
6093             assert(m-- == 11); assert(m == 10);
6094             m = m;
6095             m = 20; assert(m == 20);
6096         }
6097         static assert(T.max == int.max);
6098         static assert(T.min == int.min);
6099         static assert(T.init == int.init);
6100         static assert(T.str == "str");
6101         static assert(T.arr == [1,2,3]);
6102     }
6103 }
6104 @system unittest
6105 {
6106     static struct MyArray
6107     {
6108         private int[] value;
6109         mixin Proxy!value;
6110         this(int[] arr) { value = arr; }
6111         this(immutable int[] arr) immutable { value = arr; }
6112     }
6113 
6114     foreach (T; AliasSeq!(MyArray, const MyArray, immutable MyArray))
6115     {
6116       static if (is(T == immutable) && !is(typeof({ T a = [1,2,3,4]; })))
6117         T a = [1,2,3,4].idup;   // workaround until qualified ctor is properly supported
6118       else
6119         T a = [1,2,3,4];
6120         assert(a == [1,2,3,4]);
6121         assert(a != [5,6,7,8]);
6122         assert(+a[0]    == 1);
6123         version (LittleEndian)
6124             assert(cast(ulong[]) a == [0x0000_0002_0000_0001, 0x0000_0004_0000_0003]);
6125         else
6126             assert(cast(ulong[]) a == [0x0000_0001_0000_0002, 0x0000_0003_0000_0004]);
6127         assert(a ~ [10,11] == [1,2,3,4,10,11]);
6128         assert(a[0]    == 1);
6129         assert(a[]     == [1,2,3,4]);
6130         assert(a[2 .. 4] == [3,4]);
6131         static if (is(T == MyArray))    // mutable
6132         {
6133             a = a;
6134             a = [5,6,7,8];  assert(a == [5,6,7,8]);
6135             a[0]     = 0;   assert(a == [0,6,7,8]);
6136             a[]      = 1;   assert(a == [1,1,1,1]);
6137             a[0 .. 3]  = 2;   assert(a == [2,2,2,1]);
6138             a[0]    += 2;   assert(a == [4,2,2,1]);
6139             a[]     *= 2;   assert(a == [8,4,4,2]);
6140             a[0 .. 2] /= 2;   assert(a == [4,2,4,2]);
6141         }
6142     }
6143 }
6144 @system unittest
6145 {
6146     class Foo
6147     {
6148         int field;
6149 
6150         @property int val1() const { return field; }
6151         @property void val1(int n) { field = n; }
6152 
6153         @property ref int val2() { return field; }
6154 
6155         int func(int x, int y) const { return x; }
6156         void func1(ref int a) { a = 9; }
6157 
6158         T ifti1(T)(T t) { return t; }
6159         void ifti2(Args...)(Args args) { }
6160         void ifti3(T, Args...)(Args args) { }
6161 
6162         T opCast(T)(){ return T.init; }
6163 
6164         T tempfunc(T)() { return T.init; }
6165     }
6166     class Hoge
6167     {
6168         Foo foo;
6169         mixin Proxy!foo;
6170         this(Foo f) { foo = f; }
6171     }
6172 
6173     auto h = new Hoge(new Foo());
6174     int n;
6175 
6176     static assert(!__traits(compiles, { Foo f = h; }));
6177 
6178     // field
6179     h.field = 1;            // lhs of assign
6180     n = h.field;            // rhs of assign
6181     assert(h.field == 1);   // lhs of BinExp
6182     assert(1 == h.field);   // rhs of BinExp
6183     assert(n == 1);
6184 
6185     // getter/setter property function
6186     h.val1 = 4;
6187     n = h.val1;
6188     assert(h.val1 == 4);
6189     assert(4 == h.val1);
6190     assert(n == 4);
6191 
6192     // ref getter property function
6193     h.val2 = 8;
6194     n = h.val2;
6195     assert(h.val2 == 8);
6196     assert(8 == h.val2);
6197     assert(n == 8);
6198 
6199     // member function
6200     assert(h.func(2,4) == 2);
6201     h.func1(n);
6202     assert(n == 9);
6203 
6204     // IFTI
6205     assert(h.ifti1(4) == 4);
6206     h.ifti2(4);
6207     h.ifti3!int(4, 3);
6208 
6209     // bug5896 test
6210     assert(h.opCast!int() == 0);
6211     assert(cast(int) h == 0);
6212     const ih = new const Hoge(new Foo());
6213     static assert(!__traits(compiles, ih.opCast!int()));
6214     static assert(!__traits(compiles, cast(int) ih));
6215 
6216     // template member function
6217     assert(h.tempfunc!int() == 0);
6218 }
6219 
6220 @system unittest // about Proxy inside a class
6221 {
6222     class MyClass
6223     {
6224         int payload;
6225         mixin Proxy!payload;
6226         this(int i){ payload = i; }
6227         string opCall(string msg){ return msg; }
6228         int pow(int i){ return payload ^^ i; }
6229     }
6230 
6231     class MyClass2
6232     {
6233         MyClass payload;
6234         mixin Proxy!payload;
6235         this(int i){ payload = new MyClass(i); }
6236     }
6237 
6238     class MyClass3
6239     {
6240         int payload;
6241         mixin Proxy!payload;
6242         this(int i){ payload = i; }
6243     }
6244 
6245     // opEquals
6246     Object a = new MyClass(5);
6247     Object b = new MyClass(5);
6248     Object c = new MyClass2(5);
6249     Object d = new MyClass3(5);
6250     assert(a == b);
6251     assert((cast(MyClass) a) == 5);
6252     assert(5 == (cast(MyClass) b));
6253     assert(5 == cast(MyClass2) c);
6254     assert(a != d);
6255 
6256     assert(c != a);
6257     // oops! above line is unexpected, isn't it?
6258     // the reason is below.
6259     // MyClass2.opEquals knows MyClass but,
6260     // MyClass.opEquals doesn't know MyClass2.
6261     // so, c.opEquals(a) is true, but a.opEquals(c) is false.
6262     // furthermore, opEquals(T) couldn't be invoked.
6263     assert((cast(MyClass2) c) != (cast(MyClass) a));
6264 
6265     // opCmp
6266     Object e = new MyClass2(7);
6267     assert(a < cast(MyClass2) e); // OK. and
6268     assert(e > a); // OK, but...
6269     // assert(a < e); // RUNTIME ERROR!
6270     // assert((cast(MyClass) a) < e); // RUNTIME ERROR!
6271     assert(3 < cast(MyClass) a);
6272     assert((cast(MyClass2) e) < 11);
6273 
6274     // opCall
6275     assert((cast(MyClass2) e)("hello") == "hello");
6276 
6277     // opCast
6278     assert((cast(MyClass)(cast(MyClass2) c)) == a);
6279     assert((cast(int)(cast(MyClass2) c)) == 5);
6280 
6281     // opIndex
6282     class MyClass4
6283     {
6284         string payload;
6285         mixin Proxy!payload;
6286         this(string s){ payload = s; }
6287     }
6288     class MyClass5
6289     {
6290         MyClass4 payload;
6291         mixin Proxy!payload;
6292         this(string s){ payload = new MyClass4(s); }
6293     }
6294     auto f = new MyClass4("hello");
6295     assert(f[1] == 'e');
6296     auto g = new MyClass5("hello");
6297     assert(f[1] == 'e');
6298 
6299     // opSlice
6300     assert(f[2 .. 4] == "ll");
6301 
6302     // opUnary
6303     assert(-(cast(MyClass2) c) == -5);
6304 
6305     // opBinary
6306     assert((cast(MyClass) a) + (cast(MyClass2) c) == 10);
6307     assert(5 + cast(MyClass) a == 10);
6308 
6309     // opAssign
6310     (cast(MyClass2) c) = 11;
6311     assert((cast(MyClass2) c) == 11);
6312     (cast(MyClass2) c) = new MyClass(13);
6313     assert((cast(MyClass2) c) == 13);
6314 
6315     // opOpAssign
6316     assert((cast(MyClass2) c) += 4);
6317     assert((cast(MyClass2) c) == 17);
6318 
6319     // opDispatch
6320     assert((cast(MyClass2) c).pow(2) == 289);
6321 
6322     // opDollar
6323     assert(f[2..$-1] == "ll");
6324 
6325     // toHash
6326     int[Object] hash;
6327     hash[a] = 19;
6328     hash[c] = 21;
6329     assert(hash[b] == 19);
6330     assert(hash[c] == 21);
6331 }
6332 
6333 @safe unittest
6334 {
6335     struct MyInt
6336     {
6337         int payload;
6338 
6339         mixin Proxy!payload;
6340     }
6341 
6342     MyInt v;
6343     v = v;
6344 
6345     struct Foo
6346     {
6347         @disable void opAssign(typeof(this));
6348     }
6349     struct MyFoo
6350     {
6351         Foo payload;
6352 
6353         mixin Proxy!payload;
6354     }
6355     MyFoo f;
6356     static assert(!__traits(compiles, f = f));
6357 
6358     struct MyFoo2
6359     {
6360         Foo payload;
6361 
6362         mixin Proxy!payload;
6363 
6364         // override default Proxy behavior
6365         void opAssign(typeof(this) rhs){}
6366     }
6367     MyFoo2 f2;
6368     f2 = f2;
6369 }
6370 @safe unittest
6371 {
6372     // bug8613
6373     static struct Name
6374     {
6375         mixin Proxy!val;
6376         private string val;
6377         this(string s) { val = s; }
6378     }
6379 
6380     bool[Name] names;
6381     names[Name("a")] = true;
6382     bool* b = Name("a") in names;
6383 }
6384 
6385 @system unittest
6386 {
6387     // bug14213, using function for the payload
6388     static struct S
6389     {
6390         int foo() { return 12; }
6391         mixin Proxy!foo;
6392     }
6393     static class C
6394     {
6395         int foo() { return 12; }
6396         mixin Proxy!foo;
6397     }
6398     S s;
6399     assert(s + 1 == 13);
6400     C c = new C();
6401     assert(s * 2 == 24);
6402 }
6403 
6404 // Check all floating point comparisons for both Proxy and Typedef,
6405 // also against int and a Typedef!int, to be as regression-proof
6406 // as possible. bug 15561
6407 @safe unittest
6408 {
6409     static struct MyFloatImpl
6410     {
6411         float value;
6412         mixin Proxy!value;
6413     }
6414     static void allFail(T0, T1)(T0 a, T1 b)
6415     {
6416         assert(!(a == b));
6417         assert(!(a<b));
6418         assert(!(a <= b));
6419         assert(!(a>b));
6420         assert(!(a >= b));
6421     }
6422     foreach (T1; AliasSeq!(MyFloatImpl, Typedef!float, Typedef!double,
6423         float, real, Typedef!int, int))
6424     {
6425         foreach (T2; AliasSeq!(MyFloatImpl, Typedef!float))
6426         {
6427             T1 a;
6428             T2 b;
6429 
6430             static if (isFloatingPoint!T1 || isFloatingPoint!(TypedefType!T1))
6431                 allFail(a, b);
6432             a = 3;
6433             allFail(a, b);
6434 
6435             b = 4;
6436             assert(a != b);
6437             assert(a<b);
6438             assert(a <= b);
6439             assert(!(a>b));
6440             assert(!(a >= b));
6441 
6442             a = 4;
6443             assert(a == b);
6444             assert(!(a<b));
6445             assert(a <= b);
6446             assert(!(a>b));
6447             assert(a >= b);
6448         }
6449     }
6450 }
6451 
6452 /**
6453 $(B Typedef) allows the creation of a unique type which is
6454 based on an existing type. Unlike the $(D alias) feature,
6455 $(B Typedef) ensures the two types are not considered as equals.
6456 
6457 Example:
6458 ----
6459 alias MyInt = Typedef!int;
6460 static void takeInt(int) { }
6461 static void takeMyInt(MyInt) { }
6462 
6463 int i;
6464 takeInt(i);    // ok
6465 takeMyInt(i);  // fails
6466 
6467 MyInt myInt;
6468 takeInt(myInt);    // fails
6469 takeMyInt(myInt);  // ok
6470 ----
6471 
6472 Params:
6473 
6474 init = Optional initial value for the new type. For example:
6475 
6476 ----
6477 alias MyInt = Typedef!(int, 10);
6478 MyInt myInt;
6479 assert(myInt == 10);  // default-initialized to 10
6480 ----
6481 
6482 cookie = Optional, used to create multiple unique types which are
6483 based on the same origin type $(D T). For example:
6484 
6485 ----
6486 alias TypeInt1 = Typedef!int;
6487 alias TypeInt2 = Typedef!int;
6488 
6489 // The two Typedefs are the same type.
6490 static assert(is(TypeInt1 == TypeInt2));
6491 
6492 alias MoneyEuros = Typedef!(float, float.init, "euros");
6493 alias MoneyDollars = Typedef!(float, float.init, "dollars");
6494 
6495 // The two Typedefs are _not_ the same type.
6496 static assert(!is(MoneyEuros == MoneyDollars));
6497 ----
6498 
6499 Note: If a library routine cannot handle the Typedef type,
6500 you can use the $(D TypedefType) template to extract the
6501 type which the Typedef wraps.
6502  */
6503 struct Typedef(T, T init = T.init, string cookie=null)
6504 {
6505     private T Typedef_payload = init;
6506 
6507     this(T init)
6508     {
6509         Typedef_payload = init;
6510     }
6511 
6512     this(Typedef tdef)
6513     {
6514         this(tdef.Typedef_payload);
6515     }
6516 
6517     // We need to add special overload for cast(Typedef!X) exp,
6518     // thus we can't simply inherit Proxy!Typedef_payload
6519     T2 opCast(T2 : Typedef!(T, Unused), this X, T, Unused...)()
6520     {
6521         return T2(cast(T) Typedef_payload);
6522     }
6523 
6524     auto ref opCast(T2, this X)()
6525     {
6526         return cast(T2) Typedef_payload;
6527     }
6528 
6529     mixin Proxy!Typedef_payload;
6530 
6531     pure nothrow @nogc @safe @property
6532     {
6533         alias TD = typeof(this);
6534         static if (isIntegral!T)
6535         {
6536             static TD min() {return TD(T.min);}
6537             static TD max() {return TD(T.max);}
6538         }
6539         else static if (isFloatingPoint!T)
6540         {
6541             static TD infinity() {return TD(T.infinity);}
6542             static TD nan() {return TD(T.nan);}
6543             static TD dig() {return TD(T.dig);}
6544             static TD epsilon() {return TD(T.epsilon);}
6545             static TD mant_dig() {return TD(T.mant_dig);}
6546             static TD max_10_exp() {return TD(T.max_10_exp);}
6547             static TD max_exp()  {return TD(T.max_exp);}
6548             static TD min_10_exp() {return TD(T.min_10_exp);}
6549             static TD min_exp() {return TD(T.min_exp);}
6550             static TD max() {return TD(T.max);}
6551             static TD min_normal() {return TD(T.min_normal);}
6552             TD re() {return TD(Typedef_payload.re);}
6553             TD im() {return TD(Typedef_payload.im);}
6554         }
6555     }
6556 }
6557 
6558 /**
6559 Get the underlying type which a $(D Typedef) wraps.
6560 If $(D T) is not a $(D Typedef) it will alias itself to $(D T).
6561 */
6562 template TypedefType(T)
6563 {
6564     static if (is(T : Typedef!Arg, Arg))
6565         alias TypedefType = Arg;
6566     else
6567         alias TypedefType = T;
6568 }
6569 
6570 ///
6571 @safe unittest
6572 {
6573     import std.typecons : Typedef, TypedefType;
6574     import std.conv : to;
6575 
6576     alias MyInt = Typedef!int;
6577     static assert(is(TypedefType!MyInt == int));
6578 
6579     /// Instantiating with a non-Typedef will return that type
6580     static assert(is(TypedefType!int == int));
6581 
6582     string num = "5";
6583 
6584     // extract the needed type
6585     MyInt myInt = MyInt( num.to!(TypedefType!MyInt) );
6586     assert(myInt == 5);
6587 
6588     // cast to the underlying type to get the value that's being wrapped
6589     int x = cast(TypedefType!MyInt) myInt;
6590 
6591     alias MyIntInit = Typedef!(int, 42);
6592     static assert(is(TypedefType!MyIntInit == int));
6593     static assert(MyIntInit() == 42);
6594 }
6595 
6596 @safe unittest
6597 {
6598     Typedef!int x = 10;
6599     static assert(!__traits(compiles, { int y = x; }));
6600     static assert(!__traits(compiles, { long z = x; }));
6601 
6602     Typedef!int y = 10;
6603     assert(x == y);
6604 
6605     static assert(Typedef!int.init == int.init);
6606 
6607     Typedef!(float, 1.0) z; // specifies the init
6608     assert(z == 1.0);
6609 
6610     static assert(typeof(z).init == 1.0);
6611 
6612     alias Dollar = Typedef!(int, 0, "dollar");
6613     alias Yen    = Typedef!(int, 0, "yen");
6614     static assert(!is(Dollar == Yen));
6615 
6616     Typedef!(int[3]) sa;
6617     static assert(sa.length == 3);
6618     static assert(typeof(sa).length == 3);
6619 
6620     Typedef!(int[3]) dollar1;
6621     assert(dollar1[0..$] is dollar1[0 .. 3]);
6622 
6623     Typedef!(int[]) dollar2;
6624     dollar2.length = 3;
6625     assert(dollar2[0..$] is dollar2[0 .. 3]);
6626 
6627     static struct Dollar1
6628     {
6629         static struct DollarToken {}
6630         enum opDollar = DollarToken.init;
6631         auto opSlice(size_t, DollarToken) { return 1; }
6632         auto opSlice(size_t, size_t) { return 2; }
6633     }
6634 
6635     Typedef!Dollar1 drange1;
6636     assert(drange1[0..$] == 1);
6637     assert(drange1[0 .. 1] == 2);
6638 
6639     static struct Dollar2
6640     {
6641         size_t opDollar(size_t pos)() { return pos == 0 ? 1 : 100; }
6642         size_t opIndex(size_t i, size_t j) { return i + j; }
6643     }
6644 
6645     Typedef!Dollar2 drange2;
6646     assert(drange2[$, $] == 101);
6647 
6648     static struct Dollar3
6649     {
6650         size_t opDollar() { return 123; }
6651         size_t opIndex(size_t i) { return i; }
6652     }
6653 
6654     Typedef!Dollar3 drange3;
6655     assert(drange3[$] == 123);
6656 }
6657 
6658 @safe @nogc pure nothrow unittest // Bugzilla 11703
6659 {
6660     alias I = Typedef!int;
6661     static assert(is(typeof(I.min) == I));
6662     static assert(is(typeof(I.max) == I));
6663 
6664     alias F = Typedef!double;
6665     static assert(is(typeof(F.infinity) == F));
6666     static assert(is(typeof(F.epsilon) == F));
6667 
6668     F f;
6669     assert(!is(typeof(F.re).stringof == double));
6670     assert(!is(typeof(F.im).stringof == double));
6671 }
6672 
6673 @safe unittest
6674 {
6675     // bug8655
6676     import std.typecons;
6677     import std.bitmanip;
6678     static import core.stdc.config;
6679 
6680     alias c_ulong = Typedef!(core.stdc.config.c_ulong);
6681 
6682     static struct Foo
6683     {
6684         mixin(bitfields!(
6685             c_ulong, "NameOffset", 31,
6686             c_ulong, "NameIsString", 1
6687         ));
6688     }
6689 }
6690 
6691 @safe unittest // Issue 12596
6692 {
6693     import std.typecons;
6694     alias TD = Typedef!int;
6695     TD x = TD(1);
6696     TD y = TD(x);
6697     assert(x == y);
6698 }
6699 
6700 @safe unittest // about toHash
6701 {
6702     import std.typecons;
6703     {
6704         alias TD = Typedef!int;
6705         int[TD] td;
6706         td[TD(1)] = 1;
6707         assert(td[TD(1)] == 1);
6708     }
6709 
6710     {
6711         alias TD = Typedef!(int[]);
6712         int[TD] td;
6713         td[TD([1,2,3,4])] = 2;
6714         assert(td[TD([1,2,3,4])] == 2);
6715     }
6716 
6717     {
6718         alias TD = Typedef!(int[][]);
6719         int[TD] td;
6720         td[TD([[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]])] = 3;
6721         assert(td[TD([[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]])] == 3);
6722     }
6723 
6724     {
6725         struct MyStruct{ int x; }
6726         alias TD = Typedef!MyStruct;
6727         int[TD] td;
6728         td[TD(MyStruct(10))] = 4;
6729         assert(TD(MyStruct(20)) !in td);
6730         assert(td[TD(MyStruct(10))] == 4);
6731     }
6732 
6733     {
6734         static struct MyStruct2
6735         {
6736             int x;
6737             size_t toHash() const nothrow @safe { return x; }
6738             bool opEquals(ref const MyStruct2 r) const { return r.x == x; }
6739         }
6740 
6741         alias TD = Typedef!MyStruct2;
6742         int[TD] td;
6743         td[TD(MyStruct2(50))] = 5;
6744         assert(td[TD(MyStruct2(50))] == 5);
6745     }
6746 
6747     {
6748         class MyClass{}
6749         alias TD = Typedef!MyClass;
6750         int[TD] td;
6751         auto c = new MyClass;
6752         td[TD(c)] = 6;
6753         assert(TD(new MyClass) !in td);
6754         assert(td[TD(c)] == 6);
6755     }
6756 }
6757 
6758 @system unittest
6759 {
6760     alias String = Typedef!(char[]);
6761     alias CString = Typedef!(const(char)[]);
6762     CString cs = "fubar";
6763     String s = cast(String) cs;
6764     assert(cs == s);
6765     char[] s2 = cast(char[]) cs;
6766     const(char)[] cs2 = cast(const(char)[])s;
6767     assert(s2 == cs2);
6768 }
6769 
6770 /**
6771 Allocates a $(D class) object right inside the current scope,
6772 therefore avoiding the overhead of $(D new). This facility is unsafe;
6773 it is the responsibility of the user to not escape a reference to the
6774 object outside the scope.
6775 
6776 The class destructor will be called when the result of `scoped()` is
6777 itself destroyed.
6778 
6779 Scoped class instances can be embedded in a parent `class` or `struct`,
6780 just like a child struct instance. Scoped member variables must have
6781 type `typeof(scoped!Class(args))`, and be initialized with a call to
6782 scoped. See below for an example.
6783 
6784 Note:
6785 It's illegal to move a class instance even if you are sure there
6786 are no pointers to it. As such, it is illegal to move a scoped object.
6787  */
6788 template scoped(T)
6789     if (is(T == class))
6790 {
6791     // _d_newclass now use default GC alignment (looks like (void*).sizeof * 2 for
6792     // small objects). We will just use the maximum of filed alignments.
6793     alias alignment = classInstanceAlignment!T;
6794     alias aligned = _alignUp!alignment;
6795 
6796     static struct Scoped
6797     {
6798         // Addition of `alignment` is required as `Scoped_store` can be misaligned in memory.
6799         private void[aligned(__traits(classInstanceSize, T) + size_t.sizeof) + alignment] Scoped_store = void;
6800 
6801         @property inout(T) Scoped_payload() inout
6802         {
6803             void* alignedStore = cast(void*) aligned(cast(uintptr_t) Scoped_store.ptr);
6804             // As `Scoped` can be unaligned moved in memory class instance should be moved accordingly.
6805             immutable size_t d = alignedStore - Scoped_store.ptr;
6806             size_t* currD = cast(size_t*) &Scoped_store[$ - size_t.sizeof];
6807             if (d != *currD)
6808             {
6809                 import core.stdc.string : memmove;
6810                 memmove(alignedStore, Scoped_store.ptr + *currD, __traits(classInstanceSize, T));
6811                 *currD = d;
6812             }
6813             return cast(inout(T)) alignedStore;
6814         }
6815         alias Scoped_payload this;
6816 
6817         @disable this();
6818         @disable this(this);
6819 
6820         ~this()
6821         {
6822             // `destroy` will also write .init but we have no functions in druntime
6823             // for deterministic finalization and memory releasing for now.
6824             .destroy(Scoped_payload);
6825         }
6826     }
6827 
6828     /** Returns the _scoped object.
6829     Params: args = Arguments to pass to $(D T)'s constructor.
6830     */
6831     @system auto scoped(Args...)(auto ref Args args)
6832     {
6833         import std.conv : emplace;
6834 
6835         Scoped result = void;
6836         void* alignedStore = cast(void*) aligned(cast(uintptr_t) result.Scoped_store.ptr);
6837         immutable size_t d = alignedStore - result.Scoped_store.ptr;
6838         *cast(size_t*) &result.Scoped_store[$ - size_t.sizeof] = d;
6839         emplace!(Unqual!T)(result.Scoped_store[d .. $ - size_t.sizeof], args);
6840         return result;
6841     }
6842 }
6843 
6844 ///
6845 @system unittest
6846 {
6847     class A
6848     {
6849         int x;
6850         this()     {x = 0;}
6851         this(int i){x = i;}
6852         ~this()    {}
6853     }
6854 
6855     // Standard usage, constructing A on the stack
6856     auto a1 = scoped!A();
6857     a1.x = 42;
6858 
6859     // Result of `scoped` call implicitly converts to a class reference
6860     A aRef = a1;
6861     assert(aRef.x == 42);
6862 
6863     // Scoped destruction
6864     {
6865         auto a2 = scoped!A(1);
6866         assert(a2.x == 1);
6867         aRef = a2;
6868         // a2 is destroyed here, calling A's destructor
6869     }
6870     // aRef is now an invalid reference
6871 
6872     // Here the temporary scoped A is immediately destroyed.
6873     // This means the reference is then invalid.
6874     version (Bug)
6875     {
6876         // Wrong, should use `auto`
6877         A invalid = scoped!A();
6878     }
6879 
6880     // Restrictions
6881     version (Bug)
6882     {
6883         import std.algorithm.mutation : move;
6884         auto invalid = a1.move; // illegal, scoped objects can't be moved
6885     }
6886     static assert(!is(typeof({
6887         auto e1 = a1; // illegal, scoped objects can't be copied
6888         assert([a1][0].x == 42); // ditto
6889     })));
6890     static assert(!is(typeof({
6891         alias ScopedObject = typeof(a1);
6892         auto e2 = ScopedObject();  // illegal, must be built via scoped!A
6893         auto e3 = ScopedObject(1); // ditto
6894     })));
6895 
6896     // Use with alias
6897     alias makeScopedA = scoped!A;
6898     auto a3 = makeScopedA();
6899     auto a4 = makeScopedA(1);
6900 
6901     // Use as member variable
6902     struct B
6903     {
6904         typeof(scoped!A()) a; // note the trailing parentheses
6905 
6906         this(int i)
6907         {
6908             // construct member
6909             a = scoped!A(i);
6910         }
6911     }
6912 
6913     // Stack-allocate
6914     auto b1 = B(5);
6915     aRef = b1.a;
6916     assert(aRef.x == 5);
6917     destroy(b1); // calls A's destructor for b1.a
6918     // aRef is now an invalid reference
6919 
6920     // Heap-allocate
6921     auto b2 = new B(6);
6922     assert(b2.a.x == 6);
6923     destroy(*b2); // calls A's destructor for b2.a
6924 }
6925 
6926 private uintptr_t _alignUp(uintptr_t alignment)(uintptr_t n)
6927     if (alignment > 0 && !((alignment - 1) & alignment))
6928 {
6929     enum badEnd = alignment - 1; // 0b11, 0b111, ...
6930     return (n + badEnd) & ~badEnd;
6931 }
6932 
6933 @system unittest // Issue 6580 testcase
6934 {
6935     enum alignment = (void*).alignof;
6936 
6937     static class C0 { }
6938     static class C1 { byte b; }
6939     static class C2 { byte[2] b; }
6940     static class C3 { byte[3] b; }
6941     static class C7 { byte[7] b; }
6942     static assert(scoped!C0().sizeof % alignment == 0);
6943     static assert(scoped!C1().sizeof % alignment == 0);
6944     static assert(scoped!C2().sizeof % alignment == 0);
6945     static assert(scoped!C3().sizeof % alignment == 0);
6946     static assert(scoped!C7().sizeof % alignment == 0);
6947 
6948     enum longAlignment = long.alignof;
6949     static class C1long
6950     {
6951         long long_; byte byte_ = 4;
6952         this() { }
6953         this(long _long, ref int i) { long_ = _long; ++i; }
6954     }
6955     static class C2long { byte[2] byte_ = [5, 6]; long long_ = 7; }
6956     static assert(scoped!C1long().sizeof % longAlignment == 0);
6957     static assert(scoped!C2long().sizeof % longAlignment == 0);
6958 
6959     void alignmentTest()
6960     {
6961         int var = 5;
6962         auto c1long = scoped!C1long(3, var);
6963         assert(var == 6);
6964         auto c2long = scoped!C2long();
6965         assert(cast(uint)&c1long.long_ % longAlignment == 0);
6966         assert(cast(uint)&c2long.long_ % longAlignment == 0);
6967         assert(c1long.long_ == 3 && c1long.byte_ == 4);
6968         assert(c2long.byte_ == [5, 6] && c2long.long_ == 7);
6969     }
6970 
6971     alignmentTest();
6972 
6973     version (DigitalMars)
6974     {
6975         void test(size_t size)
6976         {
6977             import core.stdc.stdlib;
6978             alloca(size);
6979             alignmentTest();
6980         }
6981         foreach (i; 0 .. 10)
6982             test(i);
6983     }
6984     else
6985     {
6986         void test(size_t size)()
6987         {
6988             byte[size] arr;
6989             alignmentTest();
6990         }
6991         foreach (i; AliasSeq!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
6992             test!i();
6993     }
6994 }
6995 
6996 @system unittest // Original Issue 6580 testcase
6997 {
6998     class C { int i; byte b; }
6999 
7000     auto sa = [scoped!C(), scoped!C()];
7001     assert(cast(uint)&sa[0].i % int.alignof == 0);
7002     assert(cast(uint)&sa[1].i % int.alignof == 0); // fails
7003 }
7004 
7005 @system unittest
7006 {
7007     class A { int x = 1; }
7008     auto a1 = scoped!A();
7009     assert(a1.x == 1);
7010     auto a2 = scoped!A();
7011     a1.x = 42;
7012     a2.x = 53;
7013     assert(a1.x == 42);
7014 }
7015 
7016 @system unittest
7017 {
7018     class A { int x = 1; this() { x = 2; } }
7019     auto a1 = scoped!A();
7020     assert(a1.x == 2);
7021     auto a2 = scoped!A();
7022     a1.x = 42;
7023     a2.x = 53;
7024     assert(a1.x == 42);
7025 }
7026 
7027 @system unittest
7028 {
7029     class A { int x = 1; this(int y) { x = y; } ~this() {} }
7030     auto a1 = scoped!A(5);
7031     assert(a1.x == 5);
7032     auto a2 = scoped!A(42);
7033     a1.x = 42;
7034     a2.x = 53;
7035     assert(a1.x == 42);
7036 }
7037 
7038 @system unittest
7039 {
7040     class A { static bool dead; ~this() { dead = true; } }
7041     class B : A { static bool dead; ~this() { dead = true; } }
7042     {
7043         auto b = scoped!B();
7044     }
7045     assert(B.dead, "asdasd");
7046     assert(A.dead, "asdasd");
7047 }
7048 
7049 @system unittest // Issue 8039 testcase
7050 {
7051     static int dels;
7052     static struct S { ~this(){ ++dels; } }
7053 
7054     static class A { S s; }
7055     dels = 0; { scoped!A(); }
7056     assert(dels == 1);
7057 
7058     static class B { S[2] s; }
7059     dels = 0; { scoped!B(); }
7060     assert(dels == 2);
7061 
7062     static struct S2 { S[3] s; }
7063     static class C { S2[2] s; }
7064     dels = 0; { scoped!C(); }
7065     assert(dels == 6);
7066 
7067     static class D: A { S2[2] s; }
7068     dels = 0; { scoped!D(); }
7069     assert(dels == 1+6);
7070 }
7071 
7072 @system unittest
7073 {
7074     // bug4500
7075     class A
7076     {
7077         this() { a = this; }
7078         this(int i) { a = this; }
7079         A a;
7080         bool check() { return this is a; }
7081     }
7082 
7083     auto a1 = scoped!A();
7084     assert(a1.check());
7085 
7086     auto a2 = scoped!A(1);
7087     assert(a2.check());
7088 
7089     a1.a = a1;
7090     assert(a1.check());
7091 }
7092 
7093 @system unittest
7094 {
7095     static class A
7096     {
7097         static int sdtor;
7098 
7099         this() { ++sdtor; assert(sdtor == 1); }
7100         ~this() { assert(sdtor == 1); --sdtor; }
7101     }
7102 
7103     interface Bob {}
7104 
7105     static class ABob : A, Bob
7106     {
7107         this() { ++sdtor; assert(sdtor == 2); }
7108         ~this() { assert(sdtor == 2); --sdtor; }
7109     }
7110 
7111     A.sdtor = 0;
7112     scope(exit) assert(A.sdtor == 0);
7113     auto abob = scoped!ABob();
7114 }
7115 
7116 @safe unittest
7117 {
7118     static class A { this(int) {} }
7119     static assert(!__traits(compiles, scoped!A()));
7120 }
7121 
7122 @system unittest
7123 {
7124     static class A { @property inout(int) foo() inout { return 1; } }
7125 
7126     auto a1 = scoped!A();
7127     assert(a1.foo == 1);
7128     static assert(is(typeof(a1.foo) == int));
7129 
7130     auto a2 = scoped!(const(A))();
7131     assert(a2.foo == 1);
7132     static assert(is(typeof(a2.foo) == const(int)));
7133 
7134     auto a3 = scoped!(immutable(A))();
7135     assert(a3.foo == 1);
7136     static assert(is(typeof(a3.foo) == immutable(int)));
7137 
7138     const c1 = scoped!A();
7139     assert(c1.foo == 1);
7140     static assert(is(typeof(c1.foo) == const(int)));
7141 
7142     const c2 = scoped!(const(A))();
7143     assert(c2.foo == 1);
7144     static assert(is(typeof(c2.foo) == const(int)));
7145 
7146     const c3 = scoped!(immutable(A))();
7147     assert(c3.foo == 1);
7148     static assert(is(typeof(c3.foo) == immutable(int)));
7149 }
7150 
7151 @system unittest
7152 {
7153     class C { this(ref int val) { assert(val == 3); ++val; } }
7154 
7155     int val = 3;
7156     auto s = scoped!C(val);
7157     assert(val == 4);
7158 }
7159 
7160 @system unittest
7161 {
7162     class C
7163     {
7164         this(){}
7165         this(int){}
7166         this(int, int){}
7167     }
7168     alias makeScopedC = scoped!C;
7169 
7170     auto a = makeScopedC();
7171     auto b = makeScopedC(1);
7172     auto c = makeScopedC(1, 1);
7173 
7174     static assert(is(typeof(a) == typeof(b)));
7175     static assert(is(typeof(b) == typeof(c)));
7176 }
7177 
7178 /**
7179 Defines a simple, self-documenting yes/no flag. This makes it easy for
7180 APIs to define functions accepting flags without resorting to $(D
7181 bool), which is opaque in calls, and without needing to define an
7182 enumerated type separately. Using $(D Flag!"Name") instead of $(D
7183 bool) makes the flag's meaning visible in calls. Each yes/no flag has
7184 its own type, which makes confusions and mix-ups impossible.
7185 
7186 Example:
7187 
7188 Code calling $(D getLine) (usually far away from its definition) can't be
7189 understood without looking at the documentation, even by users familiar with
7190 the API:
7191 ----
7192 string getLine(bool keepTerminator)
7193 {
7194     ...
7195     if (keepTerminator) ...
7196     ...
7197 }
7198 ...
7199 auto line = getLine(false);
7200 ----
7201 
7202 Assuming the reverse meaning (i.e. "ignoreTerminator") and inserting the wrong
7203 code compiles and runs with erroneous results.
7204 
7205 After replacing the boolean parameter with an instantiation of $(D Flag), code
7206 calling $(D getLine) can be easily read and understood even by people not
7207 fluent with the API:
7208 
7209 ----
7210 string getLine(Flag!"keepTerminator" keepTerminator)
7211 {
7212     ...
7213     if (keepTerminator) ...
7214     ...
7215 }
7216 ...
7217 auto line = getLine(Yes.keepTerminator);
7218 ----
7219 
7220 The structs $(D Yes) and $(D No) are provided as shorthand for
7221 $(D Flag!"Name".yes) and $(D Flag!"Name".no) and are preferred for brevity and
7222 readability. These convenience structs mean it is usually unnecessary and
7223 counterproductive to create an alias of a $(D Flag) as a way of avoiding typing
7224 out the full type while specifying the affirmative or negative options.
7225 
7226 Passing categorical data by means of unstructured $(D bool)
7227 parameters is classified under "simple-data coupling" by Steve
7228 McConnell in the $(LUCKY Code Complete) book, along with three other
7229 kinds of coupling. The author argues citing several studies that
7230 coupling has a negative effect on code quality. $(D Flag) offers a
7231 simple structuring method for passing yes/no flags to APIs.
7232  */
7233 template Flag(string name) {
7234     ///
7235     enum Flag : bool
7236     {
7237         /**
7238          When creating a value of type $(D Flag!"Name"), use $(D
7239          Flag!"Name".no) for the negative option. When using a value
7240          of type $(D Flag!"Name"), compare it against $(D
7241          Flag!"Name".no) or just $(D false) or $(D 0).  */
7242         no = false,
7243 
7244         /** When creating a value of type $(D Flag!"Name"), use $(D
7245          Flag!"Name".yes) for the affirmative option. When using a
7246          value of type $(D Flag!"Name"), compare it against $(D
7247          Flag!"Name".yes).
7248         */
7249         yes = true
7250     }
7251 }
7252 
7253 /**
7254 Convenience names that allow using e.g. $(D Yes.encryption) instead of
7255 $(D Flag!"encryption".yes) and $(D No.encryption) instead of $(D
7256 Flag!"encryption".no).
7257 */
7258 struct Yes
7259 {
7260     template opDispatch(string name)
7261     {
7262         enum opDispatch = Flag!name.yes;
7263     }
7264 }
7265 //template yes(string name) { enum Flag!name yes = Flag!name.yes; }
7266 
7267 /// Ditto
7268 struct No
7269 {
7270     template opDispatch(string name)
7271     {
7272         enum opDispatch = Flag!name.no;
7273     }
7274 }
7275 
7276 ///
7277 @safe unittest
7278 {
7279     Flag!"abc" flag1;
7280     assert(flag1 == Flag!"abc".no);
7281     assert(flag1 == No.abc);
7282     assert(!flag1);
7283     if (flag1) assert(false);
7284     flag1 = Yes.abc;
7285     assert(flag1);
7286     if (!flag1) assert(false);
7287     if (flag1) {} else assert(false);
7288     assert(flag1 == Yes.abc);
7289 }
7290 
7291 /**
7292 Detect whether an enum is of integral type and has only "flag" values
7293 (i.e. values with a bit count of exactly 1).
7294 Additionally, a zero value is allowed for compatibility with enums including
7295 a "None" value.
7296 */
7297 template isBitFlagEnum(E)
7298 {
7299     static if (is(E Base == enum) && isIntegral!Base)
7300     {
7301         enum isBitFlagEnum = (E.min >= 0) &&
7302         {
7303             foreach (immutable flag; EnumMembers!E)
7304             {
7305                 Base value = flag;
7306                 value &= value - 1;
7307                 if (value != 0) return false;
7308             }
7309             return true;
7310         }();
7311     }
7312     else
7313     {
7314         enum isBitFlagEnum = false;
7315     }
7316 }
7317 
7318 ///
7319 @safe pure nothrow unittest
7320 {
7321     enum A
7322     {
7323         None,
7324         A = 1 << 0,
7325         B = 1 << 1,
7326         C = 1 << 2,
7327         D = 1 << 3,
7328     }
7329 
7330     static assert(isBitFlagEnum!A);
7331 
7332     enum B
7333     {
7334         A,
7335         B,
7336         C,
7337         D // D == 3
7338     }
7339 
7340     static assert(!isBitFlagEnum!B);
7341 
7342     enum C: double
7343     {
7344         A = 1 << 0,
7345         B = 1 << 1
7346     }
7347 
7348     static assert(!isBitFlagEnum!C);
7349 }
7350 
7351 /**
7352 A typesafe structure for storing combinations of enum values.
7353 
7354 This template defines a simple struct to represent bitwise OR combinations of
7355 enum values. It can be used if all the enum values are integral constants with
7356 a bit count of at most 1, or if the $(D unsafe) parameter is explicitly set to
7357 Yes.
7358 This is much safer than using the enum itself to store
7359 the OR combination, which can produce surprising effects like this:
7360 ----
7361 enum E
7362 {
7363     A = 1 << 0,
7364     B = 1 << 1
7365 }
7366 E e = E.A | E.B;
7367 // will throw SwitchError
7368 final switch (e)
7369 {
7370     case E.A:
7371         return;
7372     case E.B:
7373         return;
7374 }
7375 ----
7376 */
7377 struct BitFlags(E, Flag!"unsafe" unsafe = No.unsafe) if (unsafe || isBitFlagEnum!(E))
7378 {
7379 @safe @nogc pure nothrow:
7380 private:
7381     enum isBaseEnumType(T) = is(E == T);
7382     alias Base = OriginalType!E;
7383     Base mValue;
7384     static struct Negation
7385     {
7386     @safe @nogc pure nothrow:
7387     private:
7388         Base mValue;
7389 
7390         // Prevent non-copy construction outside the module.
7391         @disable this();
7392         this(Base value)
7393         {
7394             mValue = value;
7395         }
7396     }
7397 
7398 public:
7399     this(E flag)
7400     {
7401         this = flag;
7402     }
7403 
7404     this(T...)(T flags)
7405         if (allSatisfy!(isBaseEnumType, T))
7406     {
7407         this = flags;
7408     }
7409 
7410     bool opCast(B: bool)() const
7411     {
7412         return mValue != 0;
7413     }
7414 
7415     Base opCast(B)() const
7416         if (isImplicitlyConvertible!(Base, B))
7417     {
7418         return mValue;
7419     }
7420 
7421     Negation opUnary(string op)() const
7422         if (op == "~")
7423     {
7424         return Negation(~mValue);
7425     }
7426 
7427     auto ref opAssign(T...)(T flags)
7428         if (allSatisfy!(isBaseEnumType, T))
7429     {
7430         mValue = 0;
7431         foreach (E flag; flags)
7432         {
7433             mValue |= flag;
7434         }
7435         return this;
7436     }
7437 
7438     auto ref opAssign(E flag)
7439     {
7440         mValue = flag;
7441         return this;
7442     }
7443 
7444     auto ref opOpAssign(string op: "|")(BitFlags flags)
7445     {
7446         mValue |= flags.mValue;
7447         return this;
7448     }
7449 
7450     auto ref opOpAssign(string op: "&")(BitFlags  flags)
7451     {
7452         mValue &= flags.mValue;
7453         return this;
7454     }
7455 
7456     auto ref opOpAssign(string op: "|")(E flag)
7457     {
7458         mValue |= flag;
7459         return this;
7460     }
7461 
7462     auto ref opOpAssign(string op: "&")(E flag)
7463     {
7464         mValue &= flag;
7465         return this;
7466     }
7467 
7468     auto ref opOpAssign(string op: "&")(Negation negatedFlags)
7469     {
7470         mValue &= negatedFlags.mValue;
7471         return this;
7472     }
7473 
7474     auto opBinary(string op)(BitFlags flags) const
7475         if (op == "|" || op == "&")
7476     {
7477         BitFlags result = this;
7478         result.opOpAssign!op(flags);
7479         return result;
7480     }
7481 
7482     auto opBinary(string op)(E flag) const
7483         if (op == "|" || op == "&")
7484     {
7485         BitFlags result = this;
7486         result.opOpAssign!op(flag);
7487         return result;
7488     }
7489 
7490     auto opBinary(string op: "&")(Negation negatedFlags) const
7491     {
7492         BitFlags result = this;
7493         result.opOpAssign!op(negatedFlags);
7494         return result;
7495     }
7496 
7497     auto opBinaryRight(string op)(E flag) const
7498         if (op == "|" || op == "&")
7499     {
7500         return opBinary!op(flag);
7501     }
7502 }
7503 
7504 /// BitFlags can be manipulated with the usual operators
7505 @safe @nogc pure nothrow unittest
7506 {
7507     import std.traits : EnumMembers;
7508 
7509     // You can use such an enum with BitFlags straight away
7510     enum Enum
7511     {
7512         None,
7513         A = 1 << 0,
7514         B = 1 << 1,
7515         C = 1 << 2
7516     }
7517     BitFlags!Enum flags1;
7518     assert(!(flags1 & (Enum.A | Enum.B | Enum.C)));
7519 
7520     // You need to specify the `unsafe` parameter for enum with custom values
7521     enum UnsafeEnum
7522     {
7523         A,
7524         B,
7525         C,
7526         D = B|C
7527     }
7528     static assert(!__traits(compiles, { BitFlags!UnsafeEnum flags2; }));
7529     BitFlags!(UnsafeEnum, Yes.unsafe) flags3;
7530 
7531     immutable BitFlags!Enum flags_empty;
7532     // A default constructed BitFlags has no value set
7533     assert(!(flags_empty & Enum.A) && !(flags_empty & Enum.B) && !(flags_empty & Enum.C));
7534 
7535     // Value can be set with the | operator
7536     immutable BitFlags!Enum flags_A = flags_empty | Enum.A;
7537 
7538     // And tested with the & operator
7539     assert(flags_A & Enum.A);
7540 
7541     // Which commutes
7542     assert(Enum.A & flags_A);
7543 
7544     // BitFlags can be variadically initialized
7545     immutable BitFlags!Enum flags_AB = BitFlags!Enum(Enum.A, Enum.B);
7546     assert((flags_AB & Enum.A) && (flags_AB & Enum.B) && !(flags_AB & Enum.C));
7547 
7548     // Use the ~ operator for subtracting flags
7549     immutable BitFlags!Enum flags_B = flags_AB & ~BitFlags!Enum(Enum.A);
7550     assert(!(flags_B & Enum.A) && (flags_B & Enum.B) && !(flags_B & Enum.C));
7551 
7552     // You can use the EnumMembers template to set all flags
7553     immutable BitFlags!Enum flags_all = EnumMembers!Enum;
7554 
7555     // use & between BitFlags for intersection
7556     immutable BitFlags!Enum flags_BC = BitFlags!Enum(Enum.B, Enum.C);
7557     assert(flags_B == (flags_BC & flags_AB));
7558 
7559     // All the binary operators work in their assignment version
7560     BitFlags!Enum temp = flags_empty;
7561     temp |= flags_AB;
7562     assert(temp == (flags_empty | flags_AB));
7563     temp = flags_empty;
7564     temp |= Enum.B;
7565     assert(temp == (flags_empty | Enum.B));
7566     temp = flags_empty;
7567     temp &= flags_AB;
7568     assert(temp == (flags_empty & flags_AB));
7569     temp = flags_empty;
7570     temp &= Enum.A;
7571     assert(temp == (flags_empty & Enum.A));
7572 
7573     // BitFlags with no value set evaluate to false
7574     assert(!flags_empty);
7575 
7576     // BitFlags with at least one value set evaluate to true
7577     assert(flags_A);
7578 
7579     // This can be useful to check intersection between BitFlags
7580     assert(flags_A & flags_AB);
7581     assert(flags_AB & Enum.A);
7582 
7583     // Finally, you can of course get you raw value out of flags
7584     auto value = cast(int) flags_A;
7585     assert(value == Enum.A);
7586 }
7587 
7588 // ReplaceType
7589 /**
7590 Replaces all occurrences of `From` into `To`, in one or more types `T`. For
7591 example, $(D ReplaceType!(int, uint, Tuple!(int, float)[string])) yields
7592 $(D Tuple!(uint, float)[string]). The types in which replacement is performed
7593 may be arbitrarily complex, including qualifiers, built-in type constructors
7594 (pointers, arrays, associative arrays, functions, and delegates), and template
7595 instantiations; replacement proceeds transitively through the type definition.
7596 However, member types in `struct`s or `class`es are not replaced because there
7597 are no ways to express the types resulting after replacement.
7598 
7599 This is an advanced type manipulation necessary e.g. for replacing the
7600 placeholder type `This` in $(REF Algebraic, std,variant).
7601 
7602 Returns: `ReplaceType` aliases itself to the type(s) that result after
7603 replacement.
7604 */
7605 template ReplaceType(From, To, T...)
7606 {
7607     static if (T.length == 1)
7608     {
7609         static if (is(T[0] == From))
7610             alias ReplaceType = To;
7611         else static if (is(T[0] == const(U), U))
7612             alias ReplaceType = const(ReplaceType!(From, To, U));
7613         else static if (is(T[0] == immutable(U), U))
7614             alias ReplaceType = immutable(ReplaceType!(From, To, U));
7615         else static if (is(T[0] == shared(U), U))
7616             alias ReplaceType = shared(ReplaceType!(From, To, U));
7617         else static if (is(T[0] == U*, U))
7618         {
7619             static if (is(U == function))
7620                 alias ReplaceType = replaceTypeInFunctionType!(From, To, T[0]);
7621             else
7622                 alias ReplaceType = ReplaceType!(From, To, U)*;
7623         }
7624         else static if (is(T[0] == delegate))
7625         {
7626             alias ReplaceType = replaceTypeInFunctionType!(From, To, T[0]);
7627         }
7628         else static if (is(T[0] == function))
7629         {
7630             static assert(0, "Function types not supported," ~
7631                 " use a function pointer type instead of " ~ T[0].stringof);
7632         }
7633         else static if (is(T[0] : U!V, alias U, V...))
7634         {
7635             template replaceTemplateArgs(T...)
7636             {
7637                 static if (is(typeof(T[0])))    // template argument is value or symbol
7638                     enum replaceTemplateArgs = T[0];
7639                 else
7640                     alias replaceTemplateArgs = ReplaceType!(From, To, T[0]);
7641             }
7642             alias ReplaceType = U!(staticMap!(replaceTemplateArgs, V));
7643         }
7644         else static if (is(T[0] == struct))
7645             // don't match with alias this struct below (Issue 15168)
7646             alias ReplaceType = T[0];
7647         else static if (is(T[0] == U[], U))
7648             alias ReplaceType = ReplaceType!(From, To, U)[];
7649         else static if (is(T[0] == U[n], U, size_t n))
7650             alias ReplaceType = ReplaceType!(From, To, U)[n];
7651         else static if (is(T[0] == U[V], U, V))
7652             alias ReplaceType =
7653                 ReplaceType!(From, To, U)[ReplaceType!(From, To, V)];
7654         else
7655             alias ReplaceType = T[0];
7656     }
7657     else static if (T.length > 1)
7658     {
7659         alias ReplaceType = AliasSeq!(ReplaceType!(From, To, T[0]),
7660             ReplaceType!(From, To, T[1 .. $]));
7661     }
7662     else
7663     {
7664         alias ReplaceType = AliasSeq!();
7665     }
7666 }
7667 
7668 ///
7669 @safe unittest
7670 {
7671     static assert(
7672         is(ReplaceType!(int, string, int[]) == string[]) &&
7673         is(ReplaceType!(int, string, int[int]) == string[string]) &&
7674         is(ReplaceType!(int, string, const(int)[]) == const(string)[]) &&
7675         is(ReplaceType!(int, string, Tuple!(int[], float))
7676             == Tuple!(string[], float))
7677     );
7678 }
7679 
7680 private template replaceTypeInFunctionType(From, To, fun)
7681 {
7682     alias RX = ReplaceType!(From, To, ReturnType!fun);
7683     alias PX = AliasSeq!(ReplaceType!(From, To, Parameters!fun));
7684     // Wrapping with AliasSeq is neccesary because ReplaceType doesn't return
7685     // tuple if Parameters!fun.length == 1
7686 
7687     string gen()
7688     {
7689         enum  linkage = functionLinkage!fun;
7690         alias attributes = functionAttributes!fun;
7691         enum  variadicStyle = variadicFunctionStyle!fun;
7692         alias storageClasses = ParameterStorageClassTuple!fun;
7693 
7694         string result;
7695 
7696         result ~= "extern(" ~ linkage ~ ") ";
7697         static if (attributes & FunctionAttribute.ref_)
7698         {
7699             result ~= "ref ";
7700         }
7701 
7702         result ~= "RX";
7703         static if (is(fun == delegate))
7704             result ~= " delegate";
7705         else
7706             result ~= " function";
7707 
7708         result ~= "(";
7709         foreach (i, _; PX)
7710         {
7711             if (i)
7712                 result ~= ", ";
7713             if (storageClasses[i] & ParameterStorageClass.scope_)
7714                 result ~= "scope ";
7715             if (storageClasses[i] & ParameterStorageClass.out_)
7716                 result ~= "out ";
7717             if (storageClasses[i] & ParameterStorageClass.ref_)
7718                 result ~= "ref ";
7719             if (storageClasses[i] & ParameterStorageClass.lazy_)
7720                 result ~= "lazy ";
7721             if (storageClasses[i] & ParameterStorageClass.return_)
7722                 result ~= "return ";
7723 
7724             result ~= "PX[" ~ i.stringof ~ "]";
7725         }
7726         static if (variadicStyle == Variadic.typesafe)
7727             result ~= " ...";
7728         else static if (variadicStyle != Variadic.no)
7729             result ~= ", ...";
7730         result ~= ")";
7731 
7732         static if (attributes & FunctionAttribute.pure_)
7733             result ~= " pure";
7734         static if (attributes & FunctionAttribute.nothrow_)
7735             result ~= " nothrow";
7736         static if (attributes & FunctionAttribute.property)
7737             result ~= " @property";
7738         static if (attributes & FunctionAttribute.trusted)
7739             result ~= " @trusted";
7740         static if (attributes & FunctionAttribute.safe)
7741             result ~= " @safe";
7742         static if (attributes & FunctionAttribute.nogc)
7743             result ~= " @nogc";
7744         static if (attributes & FunctionAttribute.system)
7745             result ~= " @system";
7746         static if (attributes & FunctionAttribute.const_)
7747             result ~= " const";
7748         static if (attributes & FunctionAttribute.immutable_)
7749             result ~= " immutable";
7750         static if (attributes & FunctionAttribute.inout_)
7751             result ~= " inout";
7752         static if (attributes & FunctionAttribute.shared_)
7753             result ~= " shared";
7754         static if (attributes & FunctionAttribute.return_)
7755             result ~= " return";
7756 
7757         return result;
7758     }
7759     //pragma(msg, "gen ==> ", gen());
7760 
7761     mixin("alias replaceTypeInFunctionType = " ~ gen() ~ ";");
7762 }
7763 
7764 @safe unittest
7765 {
7766     template Test(Ts...)
7767     {
7768         static if (Ts.length)
7769         {
7770             //pragma(msg, "Testing: ReplaceType!("~Ts[0].stringof~", "
7771             //    ~Ts[1].stringof~", "~Ts[2].stringof~")");
7772             static assert(is(ReplaceType!(Ts[0], Ts[1], Ts[2]) == Ts[3]),
7773                 "ReplaceType!("~Ts[0].stringof~", "~Ts[1].stringof~", "
7774                     ~Ts[2].stringof~") == "
7775                     ~ReplaceType!(Ts[0], Ts[1], Ts[2]).stringof);
7776             alias Test = Test!(Ts[4 .. $]);
7777         }
7778         else alias Test = void;
7779     }
7780 
7781     //import core.stdc.stdio;
7782     alias RefFun1 = ref int function(float, long);
7783     alias RefFun2 = ref float function(float, long);
7784     extern(C) int printf(const char*, ...) nothrow @nogc @system;
7785     extern(C) float floatPrintf(const char*, ...) nothrow @nogc @system;
7786     int func(float);
7787 
7788     int x;
7789     struct S1 { void foo() { x = 1; } }
7790     struct S2 { void bar() { x = 2; } }
7791 
7792     alias Pass = Test!(
7793         int, float, typeof(&func), float delegate(float),
7794         int, float, typeof(&printf), typeof(&floatPrintf),
7795         int, float, int function(out long, ...),
7796             float function(out long, ...),
7797         int, float, int function(ref float, long),
7798             float function(ref float, long),
7799         int, float, int function(ref int, long),
7800             float function(ref float, long),
7801         int, float, int function(out int, long),
7802             float function(out float, long),
7803         int, float, int function(lazy int, long),
7804             float function(lazy float, long),
7805         int, float, int function(out long, ref const int),
7806             float function(out long, ref const float),
7807         int, int, int, int,
7808         int, float, int, float,
7809         int, float, const int, const float,
7810         int, float, immutable int, immutable float,
7811         int, float, shared int, shared float,
7812         int, float, int*, float*,
7813         int, float, const(int)*, const(float)*,
7814         int, float, const(int*), const(float*),
7815         const(int)*, float, const(int*), const(float),
7816         int*, float, const(int)*, const(int)*,
7817         int, float, int[], float[],
7818         int, float, int[42], float[42],
7819         int, float, const(int)[42], const(float)[42],
7820         int, float, const(int[42]), const(float[42]),
7821         int, float, int[int], float[float],
7822         int, float, int[double], float[double],
7823         int, float, double[int], double[float],
7824         int, float, int function(float, long), float function(float, long),
7825         int, float, int function(float), float function(float),
7826         int, float, int function(float, int), float function(float, float),
7827         int, float, int delegate(float, long), float delegate(float, long),
7828         int, float, int delegate(float), float delegate(float),
7829         int, float, int delegate(float, int), float delegate(float, float),
7830         int, float, Unique!int, Unique!float,
7831         int, float, Tuple!(float, int), Tuple!(float, float),
7832         int, float, RefFun1, RefFun2,
7833         S1, S2,
7834             S1[1][][S1]* function(),
7835             S2[1][][S2]* function(),
7836         int, string,
7837                int[3] function(   int[] arr,    int[2] ...) pure @trusted,
7838             string[3] function(string[] arr, string[2] ...) pure @trusted,
7839     );
7840 
7841     // Bugzilla 15168
7842     static struct T1 { string s; alias s this; }
7843     static struct T2 { char[10] s; alias s this; }
7844     static struct T3 { string[string] s; alias s this; }
7845     alias Pass2 = Test!(
7846         ubyte, ubyte, T1, T1,
7847         ubyte, ubyte, T2, T2,
7848         ubyte, ubyte, T3, T3,
7849     );
7850 }
7851 
7852 @safe unittest // Bugzilla 17116
7853 {
7854     alias ConstDg = void delegate(float) const;
7855     alias B = void delegate(int) const;
7856     alias A = ReplaceType!(float, int, ConstDg);
7857     static assert(is(B == A));
7858 }
7859 
7860 /**
7861 Ternary type with three truth values:
7862 
7863 $(UL
7864     $(LI `Ternary.yes` for `true`)
7865     $(LI `Ternary.no` for `false`)
7866     $(LI `Ternary.unknown` as an unknown state)
7867 )
7868 
7869 Also known as trinary, trivalent, or trilean.
7870 
7871 See_Also:
7872     $(HTTP en.wikipedia.org/wiki/Three-valued_logic,
7873         Three Valued Logic on Wikipedia)
7874 */
7875 struct Ternary
7876 {
7877     @safe @nogc nothrow pure:
7878 
7879     private ubyte value = 6;
7880     private static Ternary make(ubyte b)
7881     {
7882         Ternary r = void;
7883         r.value = b;
7884         return r;
7885     }
7886 
7887     /**
7888         The possible states of the `Ternary`
7889     */
7890     enum no = make(0);
7891     /// ditto
7892     enum yes = make(2);
7893     /// ditto
7894     enum unknown = make(6);
7895 
7896     /**
7897      Construct and assign from a `bool`, receiving `no` for `false` and `yes`
7898      for `true`.
7899     */
7900     this(bool b) { value = b << 1; }
7901 
7902     /// ditto
7903     void opAssign(bool b) { value = b << 1; }
7904 
7905     /**
7906     Construct a ternary value from another ternary value
7907     */
7908     this(const Ternary b) { value = b.value; }
7909 
7910     /**
7911     $(TABLE Truth table for logical operations,
7912       $(TR $(TH `a`) $(TH `b`) $(TH `$(TILDE)a`) $(TH `a | b`) $(TH `a & b`) $(TH `a ^ b`))
7913       $(TR $(TD `no`) $(TD `no`) $(TD `yes`) $(TD `no`) $(TD `no`) $(TD `no`))
7914       $(TR $(TD `no`) $(TD `yes`) $(TD) $(TD `yes`) $(TD `no`) $(TD `yes`))
7915       $(TR $(TD `no`) $(TD `unknown`) $(TD) $(TD `unknown`) $(TD `no`) $(TD `unknown`))
7916       $(TR $(TD `yes`) $(TD `no`) $(TD `no`) $(TD `yes`) $(TD `no`) $(TD `yes`))
7917       $(TR $(TD `yes`) $(TD `yes`) $(TD) $(TD `yes`) $(TD `yes`) $(TD `no`))
7918       $(TR $(TD `yes`) $(TD `unknown`) $(TD) $(TD `yes`) $(TD `unknown`) $(TD `unknown`))
7919       $(TR $(TD `unknown`) $(TD `no`) $(TD `unknown`) $(TD `unknown`) $(TD `no`) $(TD `unknown`))
7920       $(TR $(TD `unknown`) $(TD `yes`) $(TD) $(TD `yes`) $(TD `unknown`) $(TD `unknown`))
7921       $(TR $(TD `unknown`) $(TD `unknown`) $(TD) $(TD `unknown`) $(TD `unknown`) $(TD `unknown`))
7922     )
7923     */
7924     Ternary opUnary(string s)() if (s == "~")
7925     {
7926         return make((386 >> value) & 6);
7927     }
7928 
7929     /// ditto
7930     Ternary opBinary(string s)(Ternary rhs) if (s == "|")
7931     {
7932         return make((25_512 >> (value + rhs.value)) & 6);
7933     }
7934 
7935     /// ditto
7936     Ternary opBinary(string s)(Ternary rhs) if (s == "&")
7937     {
7938         return make((26_144 >> (value + rhs.value)) & 6);
7939     }
7940 
7941     /// ditto
7942     Ternary opBinary(string s)(Ternary rhs) if (s == "^")
7943     {
7944         return make((26_504 >> (value + rhs.value)) & 6);
7945     }
7946 }
7947 
7948 ///
7949 @safe @nogc nothrow pure
7950 unittest
7951 {
7952     Ternary a;
7953     assert(a == Ternary.unknown);
7954 
7955     assert(~Ternary.yes == Ternary.no);
7956     assert(~Ternary.no == Ternary.yes);
7957     assert(~Ternary.unknown == Ternary.unknown);
7958 }
7959 
7960 @safe @nogc nothrow pure
7961 unittest
7962 {
7963     alias f = Ternary.no, t = Ternary.yes, u = Ternary.unknown;
7964     Ternary[27] truthTableAnd =
7965     [
7966         t, t, t,
7967         t, u, u,
7968         t, f, f,
7969         u, t, u,
7970         u, u, u,
7971         u, f, f,
7972         f, t, f,
7973         f, u, f,
7974         f, f, f,
7975     ];
7976 
7977     Ternary[27] truthTableOr =
7978     [
7979         t, t, t,
7980         t, u, t,
7981         t, f, t,
7982         u, t, t,
7983         u, u, u,
7984         u, f, u,
7985         f, t, t,
7986         f, u, u,
7987         f, f, f,
7988     ];
7989 
7990     Ternary[27] truthTableXor =
7991     [
7992         t, t, f,
7993         t, u, u,
7994         t, f, t,
7995         u, t, u,
7996         u, u, u,
7997         u, f, u,
7998         f, t, t,
7999         f, u, u,
8000         f, f, f,
8001     ];
8002 
8003     for (auto i = 0; i != truthTableAnd.length; i += 3)
8004     {
8005         assert((truthTableAnd[i] & truthTableAnd[i + 1])
8006             == truthTableAnd[i + 2]);
8007         assert((truthTableOr[i] | truthTableOr[i + 1])
8008             == truthTableOr[i + 2]);
8009         assert((truthTableXor[i] ^ truthTableXor[i + 1])
8010             == truthTableXor[i + 2]);
8011     }
8012 
8013     Ternary a;
8014     assert(a == Ternary.unknown);
8015     static assert(!is(typeof({ if (a) {} })));
8016     assert(!is(typeof({ auto b = Ternary(3); })));
8017     a = true;
8018     assert(a == Ternary.yes);
8019     a = false;
8020     assert(a == Ternary.no);
8021     a = Ternary.unknown;
8022     assert(a == Ternary.unknown);
8023     Ternary b;
8024     b = a;
8025     assert(b == a);
8026     assert(~Ternary.yes == Ternary.no);
8027     assert(~Ternary.no == Ternary.yes);
8028     assert(~Ternary.unknown == Ternary.unknown);
8029 }
8030