View source code
Display the source code in std/exception.d from which this page was generated on github.
Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using local clone.

Function std.exception.assumeUnique

Casts a mutable array to an immutable array in an idiomatic manner. Technically, assumeUnique just inserts a cast, but its name documents assumptions on the part of the caller. assumeUnique(arr) should only be called when there are no more active mutable aliases to elements of arr. To strengthen this assumption, assumeUnique(arr) also clears arr before returning. Essentially assumeUnique(arr) indicates commitment from the caller that there is no more mutable access to any of arr's elements (transitively), and that all future accesses will be done through the immutable array returned by assumeUnique.

immutable(T)[] assumeUnique(T) (
  T[] array
) pure nothrow;

immutable(T)[] assumeUnique(T) (
  ref T[] array
) pure nothrow;

immutable(T[U]) assumeUnique(T, U) (
  ref T[U] array
) pure nothrow;

Typically, assumeUnique is used to return arrays from functions that have allocated and built them.

Parameters

NameDescription
array The array to cast to immutable.

Returns

The immutable array.

Example

---- string letters() { char[] result = new char['z' - 'a' + 1]; foreach (i, ref e; result) { e = cast(char)('a' + i); } return assumeUnique(result); }

</div>

The use in the example above is correct because <code class="lang-d"><span class="pln">result</span></code>
was private to <code class="lang-d"><span class="pln">letters</span></code> and is inaccessible in writing
after the function returns. The following example shows an
incorrect use of <code class="lang-d"><span class="pln">assumeUnique</span></code>.

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 }

</div>

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 <code class="lang-d"><span class="pln">buffer</span></code>, 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:

<div class="runnable-examples"> ----
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 assumeUnique'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.

Example

int[] arr = new int[1];
auto arr1 = arr.assumeUnique;
static assert(is(typeof(arr1) == immutable(int)[]));
writeln(arr); // null
writeln(arr1); // [0]

Example

int[string] arr = ["a":1];
auto arr1 = arr.assumeUnique;
static assert(is(typeof(arr1) == immutable(int[string])));
writeln(arr); // null
writeln(arr1.keys); // ["a"]

Authors

Andrei Alexandrescu and Jonathan M Davis

License

Boost License 1.0