std.exception

This module defines tools related to exceptions and general error handling.

Synopsis:
 string synopsis()
 {
     FILE* f = enforce(fopen("some/file"));
     // f is not null from here on
     FILE* g = enforceEx!(WriteException)(fopen("some/other/file", "w"));
     // g is not null from here on
     Exception e = collectException(write(g, readln(f)));
     if (e)
     {
         ... an exception occurred...
     }
     char[] line;
     enforce(readln(f, line));
     return assumeUnique(line);
 }

License:
Boost License 1.0

Authors:
Andrei Alexandrescu

Source:
std/exception.d

T enforce(T, string file = __FILE__, int line = __LINE__)(T value, lazy const(char)[] msg = null);
If value is nonzero, returns it. Otherwise, throws new Exception(msg).

Example:
 auto f = enforce(fopen("data.txt"));
 auto line = readln(f);
 enforce(line.length); // expect a non-empty line

T enforce(T)(T value, lazy Throwable ex);
If value is nonzero, returns it. Otherwise, throws ex.

Example:
 auto f = enforce(fopen("data.txt"));
 auto line = readln(f);
 enforce(line.length, new IOException); // expect a non-empty line

T errnoEnforce(T, string file = __FILE__, int line = __LINE__)(T value, lazy string msg = null);
If value is nonzero, returns it. Otherwise, throws new ErrnoException(msg). The ErrnoException class assumes that the last operation has set errno to an error code.

Example:
 auto f = errnoEnforce(fopen("data.txt"));
 auto line = readln(f);
 enforce(line.length); // expect a non-empty line

template enforceEx(E)
If value is nonzero, returns it. Otherwise, throws new E(msg).

Example:
 auto f = enforceEx!(FileMissingException)(fopen("data.txt"));
 auto line = readln(f);
 enforceEx!(DataCorruptionException)(line.length);

Exception collectException(T)(lazy T expression, ref T target);
Evaluates expression. If evaluation throws an exception, return that exception. Otherwise, deposit the resulting value in target and return null.

Example:
 int[] a = new int[3];
 int b;
 assert(collectException(a[4], b));

Exception collectException(T)(lazy T expression);
Evaluates expression. If evaluation throws an exception, return that exception. Otherwise, return null. T can be void.

immutable(T)[] assumeUnique(T)(ref T[] array);
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 strenghten 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.

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

Example:
 string letters()
 {
   char[] result = new char['z' - 'a' + 1];
   foreach (i, ref e; result)
   {
     e = 'a' + i;
   }
   return assumeUnique(result);
 }
The use in the example above is correct because result was private to letters and is unaccessible 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 = '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.

Checking for uniqueness during compilation is possible in certain cases (see the unique and lent keywords in the ArchJava language), but complicates the language considerably. The downside of 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.

bool pointsTo(S, T)(ref const S source, ref const T target);
Returns true if source's representation embeds a pointer that points to target's representation or somewhere inside it. Note that evaluating pointsTo(x, x) checks whether x has internal pointers.

class ErrnoException: object.Exception;
Thrown if errors that set errno happen.