Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 1752

Show
Ignore:
Timestamp:
07/12/10 14:18:21 (14 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  
    36273627 
    36283628// Bugzilla 3961 
    36293629unittest 
    36303630{ 
    36313631    struct Int { int x; } 
    36323632    Int i = to!Int(1); 
    36333633} 
    36343634 
    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 
    36433643$(D T) is $(D @safe). 
    36443644 
    36453645Returns: A pointer to the newly constructed object. 
    36463646 */ 
    36473647T* emplace(T, Args...)(void[] chunk, Args args) if (!is(T == class)) 
    36483648{ 
    36493649    enforce(chunk.length >= T.sizeof); 
    36503650    auto a = cast(size_t) chunk.ptr; 
     
    36983698        double x = 5, y = 6; 
    36993699        this(int a, int b) { assert(x == 5 && y == 6); x = a; y = b; } 
    37003700    } 
    37013701 
    37023702    auto s1 = new void[S.sizeof]; 
    37033703    auto s2 = S(42, 43); 
    37043704    assert(*emplace!S(s1, s2) == s2); 
    37053705    assert(*emplace!S(s1, 44, 45) == S(44, 45)); 
    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{ 
    37103764    // Check fix for http://d.puremagic.com/issues/show_bug.cgi?id=2971 
    37113765    assert(equal(map!(to!int)(["42", "34", "345"]), [42, 34, 345])); 
    37123766} 
    37133767