| 3637 | | Given a raw memory area $(D chunk), constructs an object of type $(D |
|---|
| 3638 | | T) at that address. The constructor is passed the arguments $(D |
|---|
| 3639 | | Args). The $(D chunk) must be as least as large as $(D T) needs and |
|---|
| 3640 | | should have an alignment multiple of $(D T)'s alignment. |
|---|
| | 3637 | Given a raw memory area $(D chunk), constructs an object of non-$(D |
|---|
| | 3638 | class) type $(D T) at that address. The constructor is passed the |
|---|
| | 3639 | arguments $(D Args). The $(D chunk) must be as least as large as $(D |
|---|
| | 3640 | T) needs and should have an alignment multiple of $(D T)'s alignment. |
|---|
| | 3708 | // emplace |
|---|
| | 3709 | /** |
|---|
| | 3710 | Given a raw memory area $(D chunk), constructs an object of $(D class) |
|---|
| | 3711 | type $(D T) at that address. The constructor is passed the arguments |
|---|
| | 3712 | $(D Args). The $(D chunk) must be as least as large as $(D T) needs |
|---|
| | 3713 | and should have an alignment multiple of $(D T)'s alignment. (The size |
|---|
| | 3714 | of a $(D class) instance is obtained by using $(D |
|---|
| | 3715 | __traits(classInstanceSize, T))). |
|---|
| | 3716 | |
|---|
| | 3717 | This function can be $(D @trusted) if the corresponding constructor of |
|---|
| | 3718 | $(D T) is $(D @safe). |
|---|
| | 3719 | |
|---|
| | 3720 | Returns: A pointer to the newly constructed object. |
|---|
| | 3721 | */ |
|---|
| | 3722 | T emplace(T, Args...)(void[] chunk, Args args) if (is(T == class)) |
|---|
| | 3723 | { |
|---|
| | 3724 | enforce(chunk.length >= __traits(classInstanceSize, T)); |
|---|
| | 3725 | auto a = cast(size_t) chunk.ptr; |
|---|
| | 3726 | enforce(a % real.alignof == 0); |
|---|
| | 3727 | auto result = cast(typeof(return)) chunk.ptr; |
|---|
| | 3728 | |
|---|
| | 3729 | // Initialize the object in its pre-ctor state |
|---|
| | 3730 | (cast(byte[]) chunk)[] = typeid(T).init[]; |
|---|
| | 3731 | |
|---|
| | 3732 | // Call the ctor if any |
|---|
| | 3733 | static if (is(typeof(result.__ctor(args)))) |
|---|
| | 3734 | { |
|---|
| | 3735 | // T defines a genuine constructor accepting args |
|---|
| | 3736 | // Go the classic route: write .init first, then call ctor |
|---|
| | 3737 | result.__ctor(args); |
|---|
| | 3738 | } |
|---|
| | 3739 | else |
|---|
| | 3740 | { |
|---|
| | 3741 | static assert(args.length == 0 && !is(typeof(&T.__ctor)), |
|---|
| | 3742 | "Don't know how to initialize an object of type " |
|---|
| | 3743 | ~ T.stringof ~ " with arguments " ~ Args.stringof); |
|---|
| | 3744 | } |
|---|
| | 3745 | return result; |
|---|
| | 3746 | } |
|---|
| | 3747 | |
|---|
| | 3748 | unittest |
|---|
| | 3749 | { |
|---|
| | 3750 | class A |
|---|
| | 3751 | { |
|---|
| | 3752 | int x = 5; |
|---|
| | 3753 | int y = 42; |
|---|
| | 3754 | this(int z) { assert(x == 5 && y == 42); x = y = z;} |
|---|
| | 3755 | } |
|---|
| | 3756 | static byte[__traits(classInstanceSize,A)] buf; |
|---|
| | 3757 | auto a = emplace!A(cast(void[]) buf, 55); |
|---|
| | 3758 | assert(a.x == 55 && a.y == 55); |
|---|
| | 3759 | static assert(!is(typeof(emplace!A(cast(void[]) buf)))); |
|---|
| | 3760 | } |
|---|
| | 3761 | |
|---|