Core concepts
Below we summarize the core concepts and rules relevant to resource management in Terra. These concepts will be explained in greater detail in the next sections.
Rule of three
There are three methods that the user can implement for a struct T
in order to manage resources:
__init :: &T -> {}
: Optional object initialization. A default is auto-generated setting pointer fields to nil.__copy :: {&S, &T} -> {}
: Optional copy-assignment. Supports source and receiver to be of different types.__dtor :: &T -> {}
: User-defined destructor.
Managed types
A struct is managed if it implements __dtor
. Managed types require explicit resource cleanup (e.g., freeing heap memory). Without __dtor
, a type behaves as a regular stack-allocated object with no special management.
Copyable types
A type is copyable if:
- It is a primitive type (e.g., int, double) or a simd vector type or a function pointer, which are all trivially copyable by default.
- An unmanaged struct with trivially copyable fields.
- It is a managed struct with a
__copy
method, either:- User-defined;
- Auto-generated for aggregates where all fields are copyable and at least one is a managed type.
- An array with an element type that is trivially copyable or uses
__copy
.
It's easier to remember the types that are not copyable:
- It is a pointer type, excluding function pointers.
- It is a managed struct type that does not implement a
__copy
method. In this case the traitT.iscopyable = false
will be set automatically.
Movable types
Unmanaged types are generally moveable but just invoke a memcopy. A managed type is movable if it can be transferred via a move. Key rules:
- All managed types (those with
__dtor
) are movable by default. - A type
T
can be made immovable by setting the type traitT.ismovable = false
, in which case moving will be prohibited at compile-time.
For managed types the move from a source to a reciever is implemented as follows: (1) the reciever's __dtor
is called first, followed by a memcopy from source to receiver and subsequent initialization of the source.