Changeset 1774

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

Added scoped() function

Files:

Legend:

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

    r1743 r1774  
    22552255} 
    22562256 
     2257/** 
     2258Allocates a $(D class) object right inside the current scope, 
     2259therefore avoiding the overhead of $(D new). This facility is unsafe; 
     2260it is the responsibility of the user to not escape a reference to the 
     2261object outside the scope. 
     2262 
     2263Example: 
     2264---- 
     2265unittest 
     2266{ 
     2267    class A { int x; } 
     2268    auto a1 = scoped!A(); 
     2269    auto a2 = scoped!A(); 
     2270    a1.x = 42; 
     2271    a2.x = 53; 
     2272    assert(a1.x == 42); 
     2273} 
     2274---- 
     2275 */ 
     2276@system auto scoped(T, Args...)(Args args) if (is(T == class)) 
     2277{ 
     2278    struct Scoped 
     2279    { 
     2280        private ubyte[__traits(classInstanceSize, T)] Scoped_store = void; 
     2281        @property T Scoped_payload() 
     2282        { 
     2283            return cast(T) (Scoped_store.ptr); 
     2284        } 
     2285        alias Scoped_payload this; 
     2286 
     2287        this(Args...)(Args args) if (is(typeof(T.init.__ctor(args)))) 
     2288        { 
     2289            emplace!T(cast(void[]) Scoped_store, args); 
     2290        } 
     2291 
     2292        @disable this(this) { writeln("Scoped this(this)"); assert(false); } 
     2293 
     2294        static if (is(typeof(T.init.__dtor()))) 
     2295        { 
     2296            ~this() 
     2297            { 
     2298                Scoped.__dtor(); 
     2299            } 
     2300        } 
     2301    } 
     2302 
     2303    static if (Args.length == 0) 
     2304    { 
     2305        byte[__traits(classInstanceSize, T)] result; 
     2306        result[] = typeid(T).init[]; 
     2307        static if (is(typeof(T.init.__ctor()))) 
     2308        { 
     2309            (cast(T) result.ptr).__ctor(); 
     2310        } 
     2311        return cast(Scoped) result; 
     2312    } 
     2313    else 
     2314    { 
     2315        return Scoped(args); 
     2316    } 
     2317} 
     2318 
     2319unittest 
     2320{ 
     2321    class A { int x = 1; } 
     2322    auto a1 = scoped!A(); 
     2323    assert(a1.x == 1); 
     2324    auto a2 = scoped!A(); 
     2325    a1.x = 42; 
     2326    a2.x = 53; 
     2327    assert(a1.x == 42); 
     2328} 
     2329 
     2330unittest 
     2331{ 
     2332    class A { int x = 1; this() { x = 2; } } 
     2333    auto a1 = scoped!A(); 
     2334    assert(a1.x == 2); 
     2335    auto a2 = scoped!A(); 
     2336    a1.x = 42; 
     2337    a2.x = 53; 
     2338    assert(a1.x == 42); 
     2339} 
     2340 
     2341unittest 
     2342{ 
     2343    class A { int x = 1; this(int y) { x = y; } } 
     2344    auto a1 = scoped!A(5); 
     2345    assert(a1.x == 5); 
     2346    auto a2 = scoped!A(); 
     2347    a1.x = 42; 
     2348    a2.x = 53; 
     2349    assert(a1.x == 42); 
     2350}