1 /** Functions for user-defined _lifetime implementation.
2 
3 Copyright: Denis Shelomovskij 2012-2014
4 
5 License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 
7 Authors: Denis Shelomovskij
8 */
9 module unstd.lifetime;
10 
11 import unstd.array;
12 import unstd.casts;
13 import unstd.traits;
14 import unstd.generictuple;
15 import std.exception;
16 
17 
18 /**
19 Moves $(D source) into $(D target).
20 
21 Specifically:
22 $(UL
23 	$(LI Does nothing if $(D &source is &target) (for the first overload only).
24 		)
25 	$(LI Destroys $(D target) if needed (for the first overload only, see
26 		$(STDREF traits, hasElaborateDestructor))
27 		)
28 	$(LI Bitwise copies $(D source) into $(D target).
29 		)
30 	$(LI If $(D hasElaborateCopyConstructor!T || hasElaborateDestructor!T)
31 		is $(D true) (see $(STDREF traits, hasElaborateCopyConstructor)),
32 		then sets $(D source) to $(D T.init).
33 		)
34 )
35 See also $(STDREF exception, doesPointTo).
36 
37 Preconditions:
38 $(D &source == &target || !doesPointTo(source, source))
39 */
40 void move(T)(ref T source, ref T target)
41 in { assert(&source == &target || !doesPointTo(source, source)); }
42 body
43 {
44 	// Performance optimization:
45 	// Do not compare addresses if we don't have side effects,
46 	// T is assignable, and T fits in register.
47 	static if(hasElaborateCopyConstructor!T || hasElaborateDestructor!T ||
48 		!isAssignable!T || hasElaborateAssign!T ||
49 		T.sizeof > size_t.sizeof)
50 		if (&source == &target) return;
51 
52 	static if(hasElaborateDestructor!T)
53 		destruct(target, false);
54 
55 	static if(!isAssignable!T || hasElaborateAssign!T)
56 		rawCopy(source._unqual, target._unqual);
57 	else
58 		target = source;
59 
60 	static if(hasElaborateCopyConstructor!T || hasElaborateDestructor!T)
61 		setToInitialState(source);
62 }
63 
64 unittest
65 {
66 	Object obj1 = new Object;
67 	Object obj2 = obj1;
68 	Object obj3;
69 	move(obj2, obj3);
70 	assert(obj3 is obj1);
71 
72 	static struct S1 { int a = 1, b = 2; }
73 	S1 s11 = { 10, 11 };
74 	S1 s12;
75 	move(s11, s12);
76 	assert(s11.a == 10 && s11.b == 11 && s12.a == 10 && s12.b == 11);
77 
78 	shared S1 sharedS11, sharedS12;
79 	move(sharedS11, sharedS12);
80 
81 	const int constI11, constI12;
82 	void constTest(in int ci1) { const ci2 = move(ci1); }
83 
84 	static struct S2 { int a = 1; int * b; }
85 	S2 s21 = { 10, null };
86 	s21.b = new int;
87 	S2 s22;
88 	move(s21, s22);
89 	assert(s21 == s22);
90 
91 	// Issue 5661 test(1)
92 	static struct S3
93 	{
94 		static struct X { int n = 0; ~this(){n = 0;} }
95 		X x;
96 	}
97 	static assert(hasElaborateDestructor!S3);
98 	S3 s31, s32;
99 	s31.x.n = 1;
100 	move(s31, s32);
101 	assert(s31.x.n == 0);
102 	assert(s32.x.n == 1);
103 
104 	// Issue 5661 test(2)
105 	static struct S4
106 	{
107 		static struct X { int n = 0; this(this){n = 0;} }
108 		X x;
109 	}
110 	static assert(hasElaborateCopyConstructor!S4);
111 	S4 s41, s42;
112 	s41.x.n = 1;
113 	move(s41, s42);
114 	assert(s41.x.n == 0);
115 	assert(s42.x.n == 1);
116 }
117 
118 /// Ditto
119 T move(T)(ref T source)
120 {
121 	// Can avoid to check aliasing here.
122 
123 	static if(hasElaborateCopyConstructor!T || hasElaborateDestructor!T)
124 	{
125 		T result = void;
126 		rawCopy(source, result);
127 		setToInitialState(source);
128 		return result;
129 	}
130 	else
131 	{
132 		return source;
133 	}
134 }
135 
136 unittest
137 {
138 	Object obj1 = new Object;
139 	Object obj2 = obj1;
140 	Object obj3 = move(obj2);
141 	assert(obj3 is obj1);
142 
143 	static struct S1 { int a = 1, b = 2; }
144 	S1 s11 = { 10, 11 };
145 	S1 s12 = move(s11);
146 	assert(s11.a == 10 && s11.b == 11 && s12.a == 10 && s12.b == 11);
147 
148 	shared S1 sharedS11, sharedS12 = move(sharedS11);
149 	void constTest(in int ci1, in int ci2) { move(ci1, ci2); }
150 
151 	static struct S2 { int a = 1; int * b; }
152 	S2 s21 = { 10, null };
153 	s21.b = new int;
154 	S2 s22 = move(s21);
155 	assert(s21 == s22);
156 
157 	// Issue 5661 test(1)
158 	static struct S3
159 	{
160 		static struct X { int n = 0; ~this(){n = 0;} }
161 		X x;
162 	}
163 	static assert(hasElaborateDestructor!S3);
164 	S3 s31;
165 	s31.x.n = 1;
166 	S3 s32 = move(s31);
167 	assert(s31.x.n == 0);
168 	assert(s32.x.n == 1);
169 
170 	// Issue 5661 test(2)
171 	static struct S4
172 	{
173 		static struct X { int n = 0; this(this){n = 0;} }
174 		X x;
175 	}
176 	static assert(hasElaborateCopyConstructor!S4);
177 	S4 s41;
178 	s41.x.n = 1;
179 	S4 s42 = move(s41);
180 	assert(s41.x.n == 0);
181 	assert(s42.x.n == 1);
182 }
183 
184 unittest//Issue 6217
185 {
186 	import std.algorithm;
187 	auto x = map!"a"([1,2,3]);
188 	x = move(x);
189 }
190 
191 unittest// Issue 8055
192 {
193 	static struct S
194 	{
195 		int x;
196 		~this() { assert(x == 0); }
197 	}
198 	S foo(S s) { return move(s); }
199 	S a;
200 	a.x = 0;
201 	auto b = foo(a);
202 	assert(b.x == 0);
203 }
204 
205 unittest// Issue 8057
206 {
207 	int n = 10;
208 	struct S
209 	{
210 		int x;
211 		~this()
212 		{
213 			// Struct always can equal to its `init`
214 			if(this == S.init) return;
215 			// Access to enclosing scope
216 			assert(n == 10);
217 		}
218 	}
219 	S foo(S s)
220 	{
221 		// Move nested struct
222 		return move(s);
223 	}
224 	S a;
225 	a.x = 1;
226 	auto b = foo(a);
227 	assert(b.x == 1);
228 
229 	// Regression 8171
230 	static struct Array(T)
231 	{
232 		// nested struct has no member
233 		struct Payload
234 		{
235 			~this() {}
236 		}
237 	}
238 	Array!int.Payload x = void;
239 	static assert(__traits(compiles, move(x)    ));
240 	static assert(__traits(compiles, move(x, x) ));
241 }
242 
243 
244 /**
245 Forwards function arguments with saving ref-ness.
246 
247 Example:
248 ---
249 int foo(int n) { return 1; }
250 int foo(ref int n) { return 2; }
251 int bar()(auto ref int x) { return foo(forward!x); }
252 
253 assert(bar(1) == 1);
254 int i;
255 assert(bar(i) == 2);
256 ---
257 
258 ---
259 void foo(int n, ref string s) { s = null; foreach (i; 0..n) s ~= "Hello"; }
260 
261 // forwards all arguments which are bound to parameter tuple
262 void bar(Args...)(auto ref Args args) { return foo(forward!args); }
263 
264 // forwards all arguments with swapping order
265 void baz(Args...)(auto ref Args args) { return foo(forward!args[$/2..$], forward!args[0..$/2]); }
266 
267 string s;
268 bar(1, s);
269 assert(s == "Hello");
270 baz(s, 2);
271 assert(s == "HelloHello");
272 ---
273 
274 Note:
275 This is just a copy of $(STDREF algorithm, _forward)
276 implementation except it uses fixed $(D move).
277 */
278 template forward(args...)
279 {
280 	static if (args.length)
281 	{
282 		alias arg = args[0];
283 		static if (__traits(isRef, arg))
284 			alias fwd = arg;
285 		else
286 			@property fwd()() { return move(arg); }
287 		alias forward = expressionTuple!(fwd, forward!(args[1 .. $]));
288 	}
289 	else
290 		alias forward = expressionTuple!();
291 }
292 
293 // Note: unittest can't be used as an example here as there is no way to place it before `Note` section.
294 
295 unittest
296 {
297 	class C
298 	{
299 		static int foo(int n) { return 1; }
300 		static int foo(ref int n) { return 2; }
301 	}
302 	int bar()(auto ref int x) { return C.foo(forward!x); }
303 
304 	assert(bar(1) == 1);
305 	int i;
306 	assert(bar(i) == 2);
307 }
308 
309 unittest
310 {
311 	void foo(int n, ref string s) { s = null; foreach (i; 0..n) s ~= "Hello"; }
312 
313 	void bar(Args...)(auto ref Args args) { return foo(forward!args); }
314 
315 	void baz(Args...)(auto ref Args args) { return foo(forward!args[$/2..$], forward!args[0..$/2]); }
316 
317 	string s;
318 	bar(1, s);
319 	assert(s == "Hello");
320 	baz(s, 2);
321 	assert(s == "HelloHello");
322 }
323 
324 unittest
325 {
326 	auto foo(TL...)(auto ref TL args)
327 	{
328 		string result = "";
329 		foreach (i, _; args)
330 		{
331 			//pragma(msg, "[",i,"] ", __traits(isRef, args[i]) ? "L" : "R");
332 			result ~= __traits(isRef, args[i]) ? "L" : "R";
333 		}
334 		return result;
335 	}
336 
337 	string bar(TL...)(auto ref TL args)
338 	{
339 		return foo(forward!args);
340 	}
341 	string baz(TL...)(auto ref TL args)
342 	{
343 		int x;
344 		return foo(forward!args[3], forward!args[2], 1, forward!args[1], forward!args[0], x);
345 	}
346 
347 	struct S {}
348 	S makeS(){ return S(); }
349 	int n;
350 	string s;
351 	assert(bar(S(), makeS(), n, s) == "RRLL");
352 	assert(baz(S(), makeS(), n, s) == "LLRRRL");
353 }
354 
355 unittest
356 {
357 	ref int foo(ref int a) { return a; }
358 	ref int bar(Args)(auto ref Args args)
359 	{
360 		return foo(forward!args);
361 	}
362 	static assert(!__traits(compiles, { auto x1 = bar(3); })); // case of NG
363 	int value = 3;
364 	auto x2 = bar(value); // case of OK
365 }
366 
367 
368 // Used in `_initializeFromImplicitlyConvertible` and `constructFrom` overload for static arrays.
369 private template _implicitlyConvertibleDim(From, To)
370 {
371 	template impl(To, From, size_t dim)
372 	{
373 		static if(isImplicitlyConvertible!(From, To))
374 			enum impl = dim;
375 		else static if(isStaticArray!To)
376 			enum impl = impl!(ArrayElementType!To, From, dim + 1);
377 		else
378 			enum impl = -1;
379 	}
380 
381 	enum _implicitlyConvertibleDim = impl!(To, From, 0);
382 }
383 
384 unittest
385 {
386 	alias dim = _implicitlyConvertibleDim;
387 
388 	static assert(dim!(int, int) == 0);
389 	static assert(dim!(int, int[1][1]) == 2);
390 	static assert(dim!(int[1], int[1][1]) == 1);
391 	static assert(dim!(int[1], int) == -1);
392 	static assert(dim!(int, long) == 0);
393 	static assert(dim!(int, long[1][1]) == 2);
394 	static assert(dim!(long, int) == -1);
395 }
396 
397 
398 // Used in `constructFrom` and `constructFromLiteral`.
399 private void _initializeFromImplicitlyConvertible(D, S)(ref D dest, ref S src)
400 	if(__traits(compiles, { D d = S.init; }))
401 {
402 	enum dim = _implicitlyConvertibleDim!(S, Unqual!D);
403 	static assert(dim != -1); // should never fail
404 	foreach(ref element; asFlatStaticArray!dim(dest))
405 	{
406 		static if(is(S == struct))
407 		{
408 			// Argument is implicitly convertible to `D` or to it's element type.
409 			// As we are dealing with structs here, this means both types are
410 			// the same type with, possibly, different qualifiers.
411 			static assert(is(Unqual!(typeof(element)) == Unqual!S)); // should never fail
412 
413 			rawCopy(src._unqual, element._unqual);
414 			callPostblits(element);
415 		}
416 		else static if(isAssignable!D)
417 		{
418 			element = src;
419 		}
420 		else
421 		{
422 			element._unqual = src;
423 		}
424 	}
425 }
426 
427 unittest
428 {
429 	alias init = _initializeFromImplicitlyConvertible;
430 
431 	static assert( __traits(compiles, init!(int, int)));
432 	static assert( __traits(compiles, init!(long, int)));
433 	static assert(!__traits(compiles, init!(int, long)));
434 	static assert( __traits(compiles, init!(const int*, int*)));
435 	static assert( __traits(compiles, init!(const int*, immutable int*)));
436 	static assert(!__traits(compiles, init!(immutable int*, const int*)));
437 	static assert( __traits(compiles, init!(shared int*, shared int*)));
438 	static assert( __traits(compiles, init!(const shared int*, shared int*)));
439 
440 	{
441 		int src = 1, dest;
442 		init(dest, src);
443 		assert(dest == 1);
444 	}
445 	{
446 		int src = 1;
447 		long dest;
448 		init(dest, src);
449 		assert(dest == 1);
450 	}
451 	{
452 		int src = 1;
453 		long[2][1] dest;
454 		init(dest, src);
455 		assert(dest == [[1, 1]]);
456 	}
457 	{
458 		int* src = cast(int*) 1;
459 		const(int*)[2][1] dest;
460 		init(dest, src);
461 		assert(dest == [[cast(int*) 1, cast(int*) 1]]);
462 	}
463 	{
464 		static struct S
465 		{ int* p; }
466 
467 		S src = S(cast(int*) 1);
468 		const S dest;
469 		init(dest, src);
470 		assert(cast(int) dest.p == 1);
471 	}
472 }
473 
474 
475 /**
476 Constructs an object of type $(D T) in given chunk of uninitialized memory
477 just like $(D T t = arg;).
478 */
479 void constructFrom(T, Arg)(ref T chunk, auto ref Arg arg)
480 {
481 	static if(is(T == struct))
482 	{
483 		static if(is(Unqual!T == Unqual!Arg))
484 		{
485 			// Initializing struct with the same type
486 
487 			static if(isImplicitlyConvertible!(Arg, T))
488 			{
489 				_initializeFromImplicitlyConvertible(chunk, arg);
490 			}
491 			else
492 			{
493 				static assert(0, "Can't implicitly convert expression of type "
494 					~ Arg.stringof ~ " to " ~ T.stringof);
495 			}
496 		}
497 		else
498 		{
499 			constructFromLiteral(chunk, forward!arg);
500 		}
501 	}
502 	else static if(__traits(compiles, { T t = arg; }))
503 	{
504 		_initializeFromImplicitlyConvertible(chunk, arg);
505 	}
506 	else
507 	{
508 		static assert(0, "`" ~ T.stringof ~ " t = " ~ Arg.stringof
509 			~ ";` doesn't compile.");
510 	}
511 }
512 
513 // Test copying from same struct branch
514 
515 unittest
516 {
517 	static struct S
518 	{
519 		int i = 1;
520 		this(int _i) inout { i = _i; }
521 		this(const S);
522 	}
523 
524 	// Initializing struct with the same type doesn't call constructor.
525 	S s = void;
526 	constructFrom(s, S(2));
527 	assert(s.i == 2);
528 	constructFrom(s, immutable S(3));
529 	assert(s.i == 3);
530 }
531 
532 unittest
533 {
534 	static struct S
535 	{
536 		int* p;
537 		this(const S);
538 	}
539 
540 	// Initializing struct with the same type requires implicit cast.
541 	S s = void;
542 	static assert(!__traits(compiles, constructFrom(s, immutable S())));
543 }
544 
545 // Test redirection to `constructFromLiteral` branch
546 
547 pure nothrow unittest // constructors
548 {
549 	static struct S
550 	{
551 	pure nothrow:
552 		this(int n) { assert(n == 2); }
553 		this(ref int n) { assert(n == 3); }
554 	}
555 
556 	S s;
557 	short sh = 2;
558 	int i = 3;
559 
560 	constructFrom(s, 2);   // calls this(int n)
561 	constructFrom(s, sh);  // calls this(int n)
562 	constructFrom(s, i);   // calls this(ref int n)
563 }
564 
565 // Test non-struct branches
566 
567 unittest
568 {
569 	{
570 		uint i = void;
571 
572 		constructFrom(i, 3);
573 		assert(cast(int) i == 3);
574 
575 		constructFrom(i, 4U);
576 		assert(cast(int) i == 4);
577 
578 		static assert(!__traits(compiles, constructFrom(i, 0L)));
579 		static assert(!__traits(compiles, constructFrom(i, 0UL)));
580 	}
581 
582 	{
583 		void* p = void;
584 
585 		constructFrom(p, cast(void*) 3);
586 		assert(cast(int) p == 3);
587 
588 		static assert(!__traits(compiles, constructFrom(p, 0)));
589 		static assert(!__traits(compiles, constructFrom(p, 0, 0)));
590 		static assert(!__traits(compiles, constructFrom(p, (const void*).init)));
591 		static assert(!__traits(compiles, constructFrom(p, (shared void*).init)));
592 	}
593 
594 	// shared
595 	{
596 		shared void* p;
597 		constructFrom(p, cast(shared void*) 3);
598 		assert(cast(int) p == 3);
599 
600 		static assert(!__traits(compiles, constructFrom(p, (const void*).init)));
601 		static assert(!__traits(compiles, constructFrom(p, (void*).init)));
602 	}
603 
604 	// const
605 	{
606 		foreach(T; TypeTuple!(immutable void, const void, void))
607 		{
608 			void* p = void;
609 			constructFrom(cast(const) p, cast(T*) 1);
610 			assert(cast(int) p == 1);
611 		}
612 
613 		void* p = void;
614 		static assert(!__traits(compiles, constructFrom(cast(const) p, (shared void*).init)));
615 	}
616 }
617 
618 
619 /*
620 Constructs an object of type $(D T) at given chunk of uninitialized memory
621 just like $(D T t = arg;).
622 
623 The function is $(D @safe) iff copy construction is $(D @safe).
624 */
625 package void _assumeSafeCopyConstructFrom(T, U)(ref T chunk, ref U from)
626 if(__traits(compiles, { T t = rvalueOf!U; }) && is(Unqual!T == Unqual!U))
627 {
628 	static if(is(T == struct) || is(T == union))
629 	{
630 		() @trusted { rawCopy(from._unqual, chunk._unqual); } ();
631 		callPostblits(chunk);
632 	}
633 	else static if(isAssignable!T)
634 	{
635 		chunk = from;
636 	}
637 	else
638 	{
639 		() @trusted { chunk._unqual = from; } ();
640 	}
641 }
642 
643 @safe pure nothrow @nogc unittest
644 {
645 	static struct S { }
646 	S s, s0;
647 	_assumeSafeCopyConstructFrom(s, s0);
648 	
649 	int i = 0, j = 1;
650 	_assumeSafeCopyConstructFrom(i, j);
651 	assert(i == 1);
652 	j = 2;
653 	(ref const a) { _assumeSafeCopyConstructFrom(a, j); } (i);
654 	assert(i == 2);
655 }
656 
657 
658 /**
659 Constructs an object of $(D struct) type $(D S) in given chunk of uninitialized memory
660 just like $(D auto s = S(args);).
661 */
662 void constructFromLiteral(S, Args...)(ref S chunk, auto ref Args args)
663 	if(is(S == struct))
664 {
665 	static if(hasMember!(S, "__ctor"))
666 	{
667 		// `S` defines a constructor.
668 
669 		static assert(!isNested!S, "Can't initialize nested struct "
670 			~ S.stringof ~ " with context pointer using constructor.");
671 
672 		// Let's initialize `chunk` and call the constructor!
673 		setToInitialState(chunk);
674 
675 		chunk.__ctor(forward!args);
676 	}
677 	else static if(hasMember!(S, "opCall"))
678 	{
679 		static assert(0, "Can't initialize struct " ~ S.stringof ~ " using `opCall`." ~
680 			" Use `constructFrom(chunk, " ~ S.stringof ~ "(...))` instead.");
681 	}
682 	else static if(__traits(compiles, { auto t = S(args); }))
683 	{
684 		// Struct without constructor that has one matching field for
685 		// each argument (i.e. each field is initializable from the
686 		// corresponding argument).
687 
688 		static assert(!anyTuple!(hasNested, FieldTypeTuple!S[Args.length .. $]),
689 			"To initialize struct "  ~ S.stringof ~ " using static initialization" ~
690 			" you must explicitly pass arguments for all fields with context pointers.");
691 
692 		// If struct fields doesn't have copy constructors
693 		// and every field has corresponding argument,
694 		// we still need to initialize the struct
695 		// because of possible padding holes.
696 		setToInitialState(chunk);
697 
698 		foreach(i, ref field; chunk.tupleof[0 .. Args.length])
699 			_initializeFromImplicitlyConvertible(field, args[i]);
700 	}
701 	else
702 	{
703 		static assert(0, "`auto t = "~ S.stringof
704 			~ "(" ~ Args.stringof ~ ");` doesn't compile.");
705 	}
706 }
707 
708 // Test constructor branch
709 
710 unittest // copying from same struct
711 {
712 	static struct S
713 	{
714 		int i = 1;
715 		this(int _i) inout { i = _i; }
716 		this(const S s) { i = 10 + s.i; }
717 	}
718 
719 	// Call constructor even if copying from same struct.
720 	S s = void;
721 	constructFromLiteral(s, S(2));
722 	assert(s.i == 12);
723 	constructFromLiteral(s, immutable S(3));
724 	assert(s.i == 13);
725 }
726 
727 unittest // copying from same struct if implicit cast isn't allowed
728 {
729 	static struct S
730 	{
731 		int i = 1;
732 		void* p = cast(void*) 7;
733 		this(const S) { i = 2; }
734 	}
735 
736 	S s = void;
737 	constructFromLiteral(s, immutable S());
738 	assert(s.i == 2);
739 }
740 
741 unittest // context pointer
742 {
743 	int i;
744 	struct S { this(int) { ++i; } }
745 	S s = void;
746 	static assert(!__traits(compiles, constructFromLiteral(s, 0)));
747 
748 	static int si = 0;
749 	static struct S3 { S s; this(int) { s = S.init; ++si; } }
750 	S3 s3 = void;
751 	constructFromLiteral(s3, 0);
752 	assert(si == 1);
753 }
754 
755 unittest // constructors
756 {
757 
758 	static void* p;
759 	static int i = 2, j = 2;
760 	static struct S
761 	{
762 		int[2] arr = 1;
763 		this(int n1, int n2, ref int _i, out int _j)
764 		{
765 			assert(&this == p && arr == [1, 1]);
766 			assert(n1 == 1 && n2 == 2);
767 			assert(&_i == &i && &_j == &j);
768 			assert(_i++ == 2 && _j++ == 0);
769 		}
770 
771 		this(int n)
772 		{ assert(n == 2); }
773 
774 		this(ref int n)
775 		{ assert(n == 3); }
776 	}
777 	S s; p = &s;
778 	short sh = 2;
779 	constructFromLiteral(s, 1, sh, i, j);
780 	assert(i == 3 && j == 1);
781 
782 	static assert(!__traits(compiles, constructFromLiteral(s, 1, 1, 0, j)));
783 	static assert(!__traits(compiles, constructFromLiteral(s, 1, 1, i, 0)));
784 	static assert(!__traits(compiles, constructFromLiteral(s, 1, 1, sh, j)));
785 	static assert(!__traits(compiles, constructFromLiteral(s, 1, 1, i, sh)));
786 
787 	constructFromLiteral(s, 2);   // calls this(int n)
788 	constructFromLiteral(s, sh);  // calls this(int n)
789 	constructFromLiteral(s, i);   // calls this(ref int n)
790 }
791 
792 unittest // templated constructors
793 {
794 	static void* p;
795 	static int i = 0;
796 	static struct S
797 	{
798 		int[2] arr = 1;
799 		this(T)(auto ref T t)
800 		{
801 			assert(&this == p && arr == [1, 1]);
802 			assert(i++ == __traits(isRef, t));
803 		}
804 	}
805 	S s; p = &s;
806 	constructFromLiteral(s, 1);  // calls this(int t)
807 	assert(i == 1);
808 	short sh = 1;
809 	constructFromLiteral(s, sh); // calls this(ref int t)
810 	assert(i == 2);
811 }
812 
813 // Test opCall branch
814 
815 unittest // opCall
816 {
817 	int i;
818 	struct S
819 	{
820 		int i;
821 		static S opCall(int);
822 	}
823 	S s = void;
824 	static assert(!__traits(compiles, constructFromLiteral(s, 0)));
825 }
826 
827 // Test matching fields branch
828 
829 unittest
830 {
831 	struct S { int a, b; this(int) {} }
832 	S s;
833 	static assert(!__traits(compiles, constructFromLiteral(s, 0, 0)));
834 }
835 
836 unittest // context pointer
837 {
838 	int i;
839 	struct S { this(int) { ++i; } }
840 	S s = void;
841 
842 	static struct S2 { int i; S s; }
843 	S2 s2 = void;
844 	static assert(!__traits(compiles, constructFromLiteral(s2, 0)));
845 	constructFromLiteral(s2, 0, S(0));
846 	assert(i == 1);
847 }
848 
849 unittest // qualifiers
850 {
851 	static struct S
852 	{ uint a = 1; void* b = null; }
853 
854 	{
855 		S s;
856 
857 		constructFromLiteral(s, 2U);
858 		assert(s.a == 2 && !s.b);
859 
860 		constructFromLiteral(s, 3);
861 		assert(s.a == 3 && !s.b);
862 
863 		immutable int immutableI = 4;
864 		constructFromLiteral(s, immutableI);
865 		assert(s.a == 4 && !s.b);
866 
867 		constructFromLiteral(s, 0, cast(void*) 3);
868 		assert(!s.a && cast(int) s.b == 3);
869 
870 		// Note: S(0L) compiles because compiler knows constan value.
871 		static assert(!__traits(compiles, constructFromLiteral(s, 0L)));
872 		static assert(!__traits(compiles, constructFromLiteral(s, 0, 0)));
873 		static assert(!__traits(compiles, constructFromLiteral(s, 0, 0, 0)));
874 		static assert(!__traits(compiles, constructFromLiteral(s, 0, (const void*).init)));
875 		static assert(!__traits(compiles, constructFromLiteral(s, 0, (shared void*).init)));
876 	}
877 
878 	// shared
879 	{
880 		shared S s;
881 		constructFromLiteral(s, 0, cast(shared void*) 3);
882 		assert(!s.a && cast(int) s.b == 3);
883 
884 		static assert(!__traits(compiles, constructFromLiteral(s, 0, (const void*).init)));
885 		static assert(!__traits(compiles, constructFromLiteral(s, 0, (void*).init)));
886 	}
887 
888 	// const
889 	{
890 		foreach(T; TypeTuple!(immutable void, const void, void))
891 		{
892 			S s = void;
893 			constructFromLiteral(*cast(const) &s, 0, cast(T*) 1);
894 			assert(!s.a && cast(int) s.b == 1);
895 		}
896 
897 		S s = void;
898 		static assert(!__traits(compiles, constructFromLiteral(*cast(const) &s, 0, (shared void*).init)));
899 	}
900 }
901 
902 unittest // static array
903 {
904 	static struct S
905 	{ int[2][1] sarr; }
906 
907 	{
908 		S s = void;
909 		constructFromLiteral(s, 2);
910 		assert(s.sarr[0] == [2, 2]);
911 	}
912 	{
913 		S s = void;
914 		static assert(!__traits(compiles, constructFromLiteral(s, (int[1]).init)));
915 		// Note: S([3, 4]) compiles without cast because compiler knows array literal value.
916 		constructFromLiteral(s, cast(int[2]) [3, 4]);
917 		assert(s.sarr[0] == [3, 4]);
918 	}
919 }
920 
921 
922 /**
923 Constructs an object of $(D class) type $(D C) at given reference to uninitialized memory
924 just like $(D auto c = new C(args);) except given memory is used instead of allocating.
925 */
926 void initializeClassInstance(C, Args...)(C chunk, auto ref Args args)
927 	if(is(C == class))
928 {
929 	static assert(!isNested!C, "Can't initialize nested class " ~ C.stringof);
930 
931 	chunk.viewAs!(byte*)[0 .. __traits(classInstanceSize, C)] = typeid(Unqual!C).init[];
932 
933 	static if(hasMember!(C, "__ctor"))
934 	{
935 		chunk.__ctor(forward!args);
936 	}
937 	else static if(Args.length)
938 	{
939 		static assert(0, "No constructor for class " ~ C.stringof);
940 	}
941 	else
942 	{
943 		static assert(!anyTuple!(hasNested, FieldTypeTuple!C),
944 			"Can't initialize class " ~ C.stringof
945 			~ " without constructor but with nested fields.");
946 	}
947 }
948 
949 // Test context pointer check
950 
951 unittest
952 {
953 	int i;
954 	{
955 		class C { void f() { ++i; } }
956 		C c;
957 		static assert(!__traits(compiles, initializeClassInstance(c)));
958 	}
959 
960 	{
961 		struct S { void f() { ++i; } }
962 		static int si = 0;
963 		static class C2 { S s; this(int) { s = S.init; ++si; } }
964 
965 		void[__traits(classInstanceSize, C2)] buff = void;
966 		auto c2 = cast(C2) buff.ptr;
967 		initializeClassInstance(c2, 0);
968 		assert(si == 1);
969 	}
970 }
971 
972 // Test constructor branch
973 
974 unittest
975 {
976 	static void* p;
977 	static int i = 2, j = 2;
978 	static class C
979 	{
980 		int[2] arr = 1;
981 		this(int n1, int n2, ref int _i, out int _j)
982 		{
983 			assert(cast(void*) this == p && arr == [1, 1]);
984 			assert(n1 == 1 && n2 == 2);
985 			assert(&_i == &i && &_j == &j);
986 			assert(_i++ == 2 && _j++ == 0);
987 		}
988 
989 		this(int n)
990 		{ assert(n == 2); }
991 
992 		this(ref int n)
993 		{ assert(n == 3); }
994 	}
995 
996 	void[__traits(classInstanceSize, C)] buff = void;
997 	auto c = cast(C) (p = buff.ptr);
998 	short sh = 2;
999 	initializeClassInstance(c, 1, sh, i, j);
1000 	assert(i == 3 && j == 1);
1001 
1002 	static assert(!__traits(compiles, initializeClassInstance(c, 1, 1, 0, j)));
1003 	static assert(!__traits(compiles, initializeClassInstance(c, 1, 1, i, 0)));
1004 	static assert(!__traits(compiles, initializeClassInstance(c, 1, 1, sh, j)));
1005 	static assert(!__traits(compiles, initializeClassInstance(c, 1, 1, i, sh)));
1006 
1007 	initializeClassInstance(c, 2);   // calls this(int n)
1008 	initializeClassInstance(c, sh);  // calls this(int n)
1009 	initializeClassInstance(c, i);   // calls this(ref int n)
1010 }
1011 
1012 // Test no-constructor branches
1013 
1014 unittest
1015 {
1016 	static class C { int i = -1; }
1017 
1018 	void[__traits(classInstanceSize, C)] buff = void;
1019 	auto c = cast(C) buff.ptr;
1020 	initializeClassInstance(c);
1021 	assert(c.i == -1);
1022 
1023 	static assert(!__traits(compiles, initializeClassInstance(c, 0)));
1024 }
1025 
1026 unittest
1027 {
1028 	int i;
1029 	struct S
1030 	{ int i = -1; void f() { ++i; } }
1031 
1032 	static class C1 { S s; }
1033 	C1 c1;
1034 	static assert(!__traits(compiles, initializeClassInstance(c1)));
1035 
1036 	static class C2
1037 	{ S s; this() { s = S.init; } }
1038 	void[__traits(classInstanceSize, C2)] buff2 = void;
1039 	auto c2 = cast(C2) buff2.ptr;
1040 	initializeClassInstance(c2);
1041 	assert(c2.s.i == -1);
1042 }
1043 
1044 
1045 private extern (C) void rt_finalize2(void* p, bool det, bool resetMemory);
1046 
1047 /**
1048 Destroys the given class instance and puts it in an invalid state. It's used
1049 to destroy an object so that any cleanup which its destructor or finalizer
1050 does is done.
1051 It does $(I not) initiate a GC cycle or free any GC memory.
1052 It $(I always) zero class instance $(D __vptr).
1053 If $(D resetMemory) is $(D true) it will also set class instance memory to
1054 its initial state so that it no longer references any other objects.
1055 */
1056 void finalizeClassInstance(T)(T t, bool resetMemory = true)
1057 {
1058 	static assert(is(T == class) || is(T == interface), "Can only finalize class or interface, not " ~ T.stringof);
1059 	rt_finalize2(t.toRawPtr, true, resetMemory);
1060 }
1061 
1062 unittest
1063 {
1064 	interface I { }
1065 	static bool destroyed = false;
1066 	static class A: I
1067 	{
1068 		int n = -1;
1069 		this() {}
1070 		~this() { destroyed = true; }
1071 	}
1072 
1073 	auto a = new A, b = new A;
1074 	a.n = b.n = 2;
1075 	finalizeClassInstance(a);
1076 	assert(destroyed);
1077 	assert(a.n == -1);
1078 
1079 	destroyed = false;
1080 	I i = b;
1081 	finalizeClassInstance(i);
1082 	assert(destroyed);
1083 	assert(b.n == -1);
1084 }
1085 
1086 /**
1087 Determines whether class instance $(D t) is finalized.
1088 
1089 Also returns $(D true) if $(D t)'s memory is zero-filled.
1090 
1091 $(D T) must be either $(D class) or $(D interface).
1092 */
1093 bool isFinalized(T)(in T t)
1094 {
1095 	static if(is(T == class))
1096 	{
1097 		alias obj = t;
1098 	}
1099 	else static if(is(T == interface))
1100 	{
1101 		const ppi = *t.viewAs!(const Interface***);
1102 		if(!ppi)
1103 			return true;
1104 		auto obj = cast(Object) (t.viewAs!(void*) - (*ppi).offset);
1105 	}
1106 	else
1107 		static assert(0, "Can only check class or interface to be finalized, not " ~ T.stringof);
1108 
1109 	return !obj.__vptr;
1110 }
1111 
1112 /// ditto
1113 @property bool finalized(T)(in T t)
1114 { return isFinalized(t); }
1115 
1116 unittest
1117 {
1118 	interface I { }
1119 	static class A: I
1120 	{
1121 		int n = -1;
1122 		this() { n = 2; }
1123 	}
1124 
1125 	{
1126 		// Object reference
1127 
1128 		auto a1 = new A, a2 = new A;
1129 		const ca1 = a1;
1130 		assert(!a1.finalized && !isFinalized(a2));
1131 		assert(!ca1.finalized);
1132 		finalizeClassInstance(a1);
1133 		finalizeClassInstance(a2, false);
1134 		assert(a1.finalized && isFinalized(a2));
1135 		assert(ca1.finalized);
1136 	}
1137 
1138 	{
1139 		// Interface reference
1140 
1141 		I ia1 = new A, ia2 = new A;
1142 		const cia1 = ia1, cia2 = ia2;
1143 		assert(!ia1.finalized && !isFinalized(ia2));
1144 		assert(!cia1.finalized);
1145 		finalizeClassInstance(ia1);
1146 		finalizeClassInstance(ia2, !false);
1147 		assert(ia1.finalized && isFinalized(ia2));
1148 		assert(cia1.finalized);
1149 	}
1150 
1151 	{
1152 		// Zero-filled memory
1153 
1154 		const size_t buff = 0;
1155 		assert((cast(const A) &buff).finalized);
1156 		assert((cast(const I) &buff).finalized);
1157 	}
1158 
1159 	{
1160 		int i;
1161 		assert(!__traits(compiles, i.finalized));
1162 		assert(!__traits(compiles, isFinalized(i)));
1163 		struct S { }
1164 		assert(!__traits(compiles, S().finalized));
1165 	}
1166 }
1167 
1168 
1169 /**
1170 Destructs $(D t) exactly the same way a compiler does in a case it goes out of scope.
1171 Also puts destructed object in its $(D init) state if $(D resetInitialState)
1172 is $(D true), otherwise object state will be undefined (i.e. possibly invalid).
1173 */
1174 void destruct(T)(ref T t, bool resetInitialState = true)
1175 {
1176 	callDestructors(t);
1177 	if(resetInitialState)
1178 		setToInitialState(t);
1179 }
1180 
1181 unittest
1182 {
1183 	int i = -1;
1184 	destruct(i, false);
1185 	assert(i == -1);
1186 	destruct(i);
1187 	assert(i == 0);
1188 
1189 	static assert(!__traits(compiles, destruct(5))); // doesn't accept rvalue
1190 }
1191 
1192 unittest
1193 {
1194 	static int n = 0;
1195 	static struct S
1196 	{
1197 		int i = -1;
1198 		~this() { ++n; }
1199 	}
1200 
1201 	auto s = S(1);
1202 	destruct(s, false);
1203 	assert(s.i == 1 && n == 1);
1204 	destruct(s);
1205 	assert(s.i == -1 && n == 2);
1206 }
1207 
1208 
1209 /**
1210 Sets the passed object to its `init` state.
1211 
1212 Use this function instead of dealing with tricky $(D typeid(T).init()).
1213 */
1214 void setToInitialState(T)(ref T t)
1215 {
1216 	alias U = Unqual!T;
1217 
1218 	static if((!isAssignable!T || hasElaborateAssign!T) && (!isAssignable!U || hasElaborateAssign!U))
1219 	{
1220 		import core.stdc..string;
1221 
1222 		// `typeid(T)` will also work but will cost a virtual call per each array
1223 		// dimension. We will not be here for [static arrays of] classes so
1224 		// there is no problems with `TypeInfo_Class.init` field name clash.
1225 		if(const p = typeid(MultidimStaticArrayElementType!U).init().ptr)
1226 			foreach(ref el; asFlatStaticArray(t._unqual))
1227 				memcpy(&el, p, typeof(el).sizeof);
1228 		else
1229 			memset(cast(void*) &t, 0, T.sizeof);
1230 	}
1231 	else static if(!isAssignable!T || hasElaborateAssign!T)
1232 	{
1233 		t._unqual = U.init;
1234 	}
1235 	else
1236 	{
1237 		t = T.init;
1238 	}
1239 }
1240 
1241 unittest
1242 {
1243 	int i = -1;
1244 	setToInitialState(i);
1245 	assert(i == 0);
1246 
1247 	static assert(!__traits(compiles, setToInitialState(5))); // doesn't accept rvalue
1248 
1249 	static bool exited = false;
1250 
1251 	static struct S(int def)
1252 	{
1253 		int i = def;
1254 		@disable this();
1255 		this(this)  { assert(0); }
1256 		~this()     { assert(exited); }
1257 	}
1258 
1259 	S!0 s0 = void; s0.i = -1;
1260 	setToInitialState(s0);
1261 	assert(s0.i == 0);
1262 
1263 	S!1 s1 = void; s1.i = -1;
1264 	setToInitialState(s1);
1265 	assert(s1.i == 1);
1266 
1267 	S!1[2][1] sArr = void;
1268 	foreach(ref el; sArr[0])
1269 		el.i = -1;
1270 	setToInitialState(sArr);
1271 	assert(sArr == (S!1[2][1]).init);
1272 
1273 	exited = true;
1274 }
1275 
1276 unittest // const
1277 {
1278 	static struct Int1
1279 	{ int i = 1; }
1280 
1281 	static struct S
1282 	{ const Int1 i; }
1283 
1284 	int i = 0;
1285 	static assert(S.sizeof == i.sizeof);
1286 	setToInitialState(i.viewAs!S);
1287 	assert(i == 1); i = 0;
1288 
1289 	setToInitialState(i.viewAs!(const S));
1290 	assert(i == 1); i = 0;
1291 }
1292 
1293 
1294 /**
1295 Sets all elements of the passed dynamic array to its `init` state.
1296 
1297 Use this function for better performance instead of calling
1298 $(MREF setToInitialState) on each element.
1299 */
1300 void setElementsToInitialState(T)(T[] arr)
1301 {
1302 	alias U = Unqual!T;
1303 
1304 	// This is just a copy of `setToInitialState` implementation.
1305 
1306 	static if((!isAssignable!T || hasElaborateAssign!T) && (!isAssignable!U || hasElaborateAssign!U))
1307 	{
1308 		import core.stdc..string;
1309 
1310 		static if(is(U == void))
1311 			memset(cast(void*) arr.ptr, 0, arr.length);
1312 		else if(const p = typeid(MultidimStaticArrayElementType!U).init().ptr)
1313 			foreach(ref t; arr)
1314 				foreach(ref el; asFlatStaticArray(t._unqual))
1315 					memcpy(&el, p, typeof(el).sizeof);
1316 		else
1317 			memset(cast(void*) arr.ptr, 0, T.sizeof * arr.length);
1318 	}
1319 	else static if(!isAssignable!T || hasElaborateAssign!T)
1320 	{
1321 		(cast(U[]) arr)[] = U.init;
1322 	}
1323 	else
1324 	{
1325 		arr[] = T.init;
1326 	}
1327 }
1328 
1329 unittest
1330 {
1331 	int[] i = new int[3];
1332 	i[] = -1;
1333 	setElementsToInitialState(i);
1334 	assert(i == [0, 0, 0]);
1335 
1336 	static bool exited = false;
1337 
1338 	static struct S(int def)
1339 	{
1340 		int i = def;
1341 		@disable this();
1342 		this(this)  { assert(0); }
1343 		~this()     { assert(exited); }
1344 	}
1345 
1346 	auto s0 = [S!0.init, S!0.init]; s0[0].i = s0[1].i = -1;
1347 	setElementsToInitialState(s0);
1348 	assert(s0[0].i == 0 && s0[1].i == 0);
1349 
1350 	auto s1 = [S!1.init, S!1.init]; s1[0].i = s1[1].i = -1;
1351 	setElementsToInitialState(s1);
1352 	assert(s1[0].i == 1 && s1[1].i == 1);
1353 
1354 	auto sArr = [(S!1[2][1]).init];
1355 	foreach(ref el; sArr[0][0])
1356 		el.i = -1;
1357 	setElementsToInitialState(sArr);
1358 	assert(sArr[0] == (S!1[2][1]).init);
1359 
1360 	exited = true;
1361 
1362 	byte[2] bArr = -1;
1363 	setElementsToInitialState(cast(const void[]) bArr);
1364 	assert(bArr == [0, 0]);
1365 }
1366 
1367 unittest // const
1368 {
1369 	static struct Int1
1370 	{ int i = 1; }
1371 
1372 	static struct S
1373 	{ const Int1 i; }
1374 
1375 	int i = 0;
1376 	static assert(S.sizeof == i.sizeof);
1377 	setElementsToInitialState((cast(S*) &i)[0 .. 1]);
1378 	assert(i == 1); i = 0;
1379 
1380 	setElementsToInitialState((cast(const S*) &i)[0 .. 1]);
1381 	assert(i == 1); i = 0;
1382 }
1383 
1384 
1385 /** Calls the postblit of the given object, if any.
1386 
1387 Faster and convenient replacement for $(D typeid(T).postblit(&t)).
1388 */
1389 void callPostblits(T)(ref T t)
1390 {
1391 	static if(hasElaborateCopyConstructor!T)
1392 	{
1393 		foreach(ref el; asFlatStaticArray(t))
1394 		{
1395 			foreach(ref field; el.tupleof)
1396 				static if(hasElaborateCopyConstructor!(typeof(field)))
1397 					callPostblits(field);
1398 
1399 			static if(hasMember!(typeof(el), "__postblit"))
1400 				el.__postblit();
1401 		}
1402 	}
1403 }
1404 
1405 unittest
1406 {
1407 	int i = -1;
1408 	callPostblits(i); // no-op for non-elaborate types
1409 
1410 	static assert(!__traits(compiles, callPostblits(5))); // doesn't accept rvalue
1411 
1412 	static int[] log;
1413 	static void checkLog(int[] arr...)
1414 	{ assert(log == arr); log = null; }
1415 
1416 	static bool exited = false;
1417 
1418 	static struct S
1419 	{
1420 		int i;
1421 		@disable this();
1422 		this(this)  { log ~= i; }
1423 		~this()     { assert(exited); }
1424 	}
1425 
1426 	S s = void; s.i = -1;
1427 	callPostblits(s);
1428 	checkLog(-1);
1429 
1430 	S[3][2][1] sArr = void;
1431 	foreach(uint j, ref el; sArr.viewAs!(S[6]))
1432 		el.i = j;
1433 	callPostblits(sArr);
1434 	checkLog(0, 1, 2, 3, 4, 5);
1435 
1436 	static struct S2
1437 	{
1438 		S s;
1439 		S[2] sArr;
1440 
1441 		@disable this();
1442 		this(this)  { log ~= -1; }
1443 		~this()     { assert(exited); }
1444 	}
1445 
1446 	S2 s2 = void;
1447 	foreach(uint j, ref el; s2.viewAs!(S[3]))
1448 		el.i = j;
1449 	callPostblits(s2);
1450 	checkLog(0, 1, 2, -1);
1451 
1452 	exited = true;
1453 }
1454 
1455 
1456 /** Calls the destructor of the given object, if any.
1457 
1458 Faster and convenient replacement for $(D typeid(T).destroy(&t)).
1459 */
1460 void callDestructors(T)(ref T t)
1461 {
1462 	static if(hasElaborateDestructor!T)
1463 	{
1464 		foreach_reverse(ref el; asFlatStaticArray(t))
1465 		{
1466 			static if(hasMember!(typeof(el), "__dtor"))
1467 				el.__dtor();
1468 
1469 			foreach_reverse(ref field; el.tupleof)
1470 				static if(hasElaborateDestructor!(typeof(field)))
1471 					callDestructors(field);
1472 		}
1473 	}
1474 }
1475 
1476 unittest
1477 {
1478 	int i = -1;
1479 	callDestructors(i); // no-op for non-elaborate types
1480 
1481 	static assert(!__traits(compiles, callDestructors(5))); // doesn't accept rvalue
1482 
1483 	static int[] log;
1484 	static void checkLog(int[] arr...)
1485 	{ assert(log == arr); log = null; }
1486 
1487 	static bool exited = false;
1488 
1489 	static struct S
1490 	{
1491 		int i;
1492 		@disable this();
1493 		this(this)  { assert(exited); }
1494 		~this()     { log ~= i; }
1495 	}
1496 
1497 	S s = void; s.i = -1;
1498 	callDestructors(s);
1499 	checkLog(-1);
1500 
1501 	S[3][2][1] sArr = void;
1502 	foreach(uint j, ref el; sArr.viewAs!(S[6]))
1503 		el.i = j;
1504 	callDestructors(sArr);
1505 	checkLog(5, 4, 3, 2, 1, 0);
1506 
1507 	static struct S2
1508 	{
1509 		S s;
1510 		S[2] sArr;
1511 
1512 		@disable this();
1513 		this(this)  { assert(exited); }
1514 		~this()     { log ~= -1; }
1515 	}
1516 
1517 	S2 s2 = void;
1518 	foreach(uint j, ref el; s2.viewAs!(S[3]))
1519 		el.i = j;
1520 	callDestructors(s2);
1521 	checkLog(-1, 2, 1, 0);
1522 
1523 	exited = true;
1524 }
1525 
1526 
1527 // Utility function to unqualify a value.
1528 package @property ref _unqual(T)(ref T val) @system
1529 {
1530 	return *cast(Unqual!T*) &val;
1531 }
1532 
1533 @trusted unittest
1534 {
1535 	static assert(!__traits(compiles, 1._unqual));
1536 
1537 	int i = 0;
1538 	(ref const a) { ++a._unqual; } (i);
1539 	assert(i == 1);
1540 }