Function std.exception.assumeUnique
Casts a mutable array to an immutable array in an idiomatic
manner. Technically, just inserts a cast,
but its name documents assumptions on the part of the
caller. assumeUnique should only be called when
there are no more active mutable aliases to elements of assumeUnique(arr)arr. To strengthen this assumption,
also clears assumeUnique(arr)arr before returning. Essentially indicates commitment from the caller that there
is no more mutable access to any of assumeUnique(arr)arr's elements
(transitively), and that all future accesses will be done through
the immutable array returned by .
assumeUnique
Typically, is used to return arrays from
functions that have allocated and built them.
assumeUnique
Prototypes
immutable(T)[] assumeUnique(T)( T[] array ) pure nothrow; immutable(T)[] assumeUnique(T)( T[] array ) pure nothrow;
Example
string letters()
{
char[] result = new char['z' - 'a' + 1];
foreach (i, ref e; result)
{
e = cast(char)('a' + i);
}
return assumeUnique(result);
}
The use in the example above is correct because result
was private to letters and is inaccessible in writing
after the function returns. The following example shows an
incorrect use of .
assumeUnique
Bad
private char[] buffer;
string letters(char first, char last)
{
if (first >= last) return null; // fine
auto sneaky = buffer;
sneaky.length = last - first + 1;
foreach (i, ref e; sneaky)
{
e = cast(char)('a' + i);
}
return assumeUnique(sneaky); // BAD
}
The example above wreaks havoc on client code because it is
modifying arrays that callers considered immutable. To obtain an
immutable array from the writable array buffer, replace
the last line with:
return to!(string)(sneaky); // not that sneaky anymore
The call will duplicate the array appropriately.
Note that checking for uniqueness during compilation is
possible in certain cases, especially when a function is
marked as a pure function. The following example does not
need to call assumeUnique because the compiler can infer the
uniqueness of the array in the pure function:
string letters() pure
{
char[] result = new char['z' - 'a' + 1];
foreach (i, ref e; result)
{
e = cast(char)('a' + i);
}
return result;
}
For more on infering uniqueness see the unique and lent keywords in the ArchJava language.
The downside of using 's
convention-based usage is that at this time there is no
formal checking of the correctness of the assumption;
on the upside, the idiomatic use of assumeUnique is
simple and rare enough to be tolerable.
assumeUnique
Authors
Andrei Alexandrescu and Jonathan M Davis