Changeset 1752

Show
Ignore:
Timestamp:
07/12/10 10:18:21 (4 years ago)
Author:
andrei
Message:

Added emplace for class types

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/phobos/std/conv.d

    r1747 r1752  
    36353635// emplace 
    36363636/** 
    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. 
     3637Given a raw memory area $(D chunk), constructs an object of non-$(D 
     3638class) type $(D T) at that address. The constructor is passed the 
     3639arguments $(D Args). The $(D chunk) must be as least as large as $(D 
     3640T) needs and should have an alignment multiple of $(D T)'s alignment. 
    36413641 
    36423642This function can be $(D @trusted) if the corresponding constructor of 
     
    37063706} 
    37073707 
     3708// emplace 
     3709/** 
     3710Given a raw memory area $(D chunk), constructs an object of $(D class) 
     3711type $(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 
     3713and should have an alignment multiple of $(D T)'s alignment. (The size 
     3714of a $(D class) instance is obtained by using $(D 
     3715__traits(classInstanceSize, T))). 
     3716 
     3717This function can be $(D @trusted) if the corresponding constructor of 
     3718$(D T) is $(D @safe). 
     3719 
     3720Returns: A pointer to the newly constructed object. 
     3721 */ 
     3722T 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 
     3748unittest 
     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 
    37083762unittest 
    37093763{