Constructor that takes an rvalue. It will ensure uniqueness, as long as the rvalue isn't just a view on an lvalue (e.g., a cast). Typical usage:
Constructor that takes an lvalue. It nulls its source. The nulling will ensure uniqueness as long as there are no previous aliases to the source.
Constructor that takes a Unique of a type that is convertible to our type.
A destructor is present on this object, but not explicitly documented in the source.
Postblit operator is undefined to prevent the cloning of Unique objects.
Represents a reference to T. Resolves to T* if T is a value type.
Allows safe construction of Unique. It creates the resource and guarantees unique ownership of it (unless T publishes aliases of this). Note: Nested structs/classes cannot be created.
Transfer ownership from a Unique of a type that is convertible to our type.
Transfer ownership to a Unique rvalue. Nullifies the current contents. Same as calling std.algorithm.move on it.
Forwards member access to contents.
Returns whether the resource exists.
1 static struct S 2 { 3 int i; 4 this(int i){this.i = i;} 5 } 6 Unique!S produce() 7 { 8 // Construct a unique instance of S on the heap 9 Unique!S ut = new S(5); 10 // Implicit transfer of ownership 11 return ut; 12 } 13 // Borrow a unique resource by ref 14 void increment(ref Unique!S ur) 15 { 16 ur.i++; 17 } 18 void consume(Unique!S u2) 19 { 20 assert(u2.i == 6); 21 // Resource automatically deleted here 22 } 23 Unique!S u1; 24 assert(u1.isEmpty); 25 u1 = produce(); 26 increment(u1); 27 assert(u1.i == 6); 28 //consume(u1); // Error: u1 is not copyable 29 // Transfer ownership of the resource 30 consume(u1.release); 31 assert(u1.isEmpty);
Encapsulates unique ownership of a resource.
When a Unique!T goes out of scope it will call destroy on the resource T that it manages, unless it is transferred. One important consequence of destroy is that it will call the destructor of the resource T. GC-managed references are not guaranteed to be valid during a destructor call, but other members of T, such as file handles or pointers to malloc memory, will still be valid during the destructor call. This allows the resource T to deallocate or clean up any non-GC resources.
If it is desirable to persist a Unique!T outside of its original scope, then it can be transferred. The transfer can be explicit, by calling release, or implicit, when returning Unique from a function. The resource T can be a polymorphic class object or instance of an interface, in which case Unique behaves polymorphically too.
If T is a value type, then Unique!T will be implemented as a reference to a T.