View source code Display the source code in std/exception.d from which this page was generated on github. 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. Page wiki View or edit the community-maintained wiki page associated with this page.

Function std.exception.doesPointTo

The "pointsTo" functions, doesPointTo and mayPointTo.

Returns true if source's representation embeds a pointer that points to target's representation or somewhere inside it.

If source is or contains a dynamic array, then, then these functions will check if there is overlap between the dynamic array and target's representation.

If source is a class, then pointsTo will handle it as a pointer.

If target is a pointer, a dynamic array or a class, then these functions will only check if source points to target, not what target references.

If source is or contains a union, then there may be either false positives or false negatives:

doesPointTo will return true if it is absolutely certain source points to target. It may produce false negatives, but never false positives. This function should be prefered when trying to validate input data.

mayPointTo will return false if it is absolutely certain source does not point to target. It may produce false positives, but never false negatives. This function should be prefered for defensively choosing a code path.

Prototype

bool doesPointTo(S, T, Tdummy)(
  S source,
  T target
) pure nothrow @trusted
if (__traits(isRef, source) || isDynamicArray!S || isPointer!S || is(S == class));

Note

Evaluating pointsTo(x, x) checks whether x has internal pointers. This should only be done as an assertive test, as the language is free to assume objects don't have internal pointers (TDPL 7.1.3.5).

Example

Pointers

int  i = 0;
int* p = null;
assert(!p.doesPointTo(i));
p = &i;
assert( p.doesPointTo(i));

Example

Structs and Unions

struct S
{
    int v;
    int* p;
}
int i;
auto s = S(0, &i);

//structs and unions "own" their members
//pointsTo will answer true if one of the members pointsTo.
assert(!s.doesPointTo(s.v)); //s.v is just v member of s, so not pointed.
assert( s.p.doesPointTo(i)); //i is pointed by s.p.
assert( s  .doesPointTo(i)); //which means i is pointed by s itself.

//Unions will behave exactly the same. Points to will check each "member"
//individually, even if they share the same memory

Example

Arrays (dynamic and static)

int i;
int[]  slice = [0, 1, 2, 3, 4];
int[5] arr   = [0, 1, 2, 3, 4];
int*[]  slicep = [&i];
int*[1] arrp   = [&i];

//A slice points to all of its members:
assert( slice.doesPointTo(slice[3]));
assert(!slice[0 .. 2].doesPointTo(slice[3])); //Object 3 is outside of the slice [0 .. 2]

//Note that a slice will not take into account what its members point to.
assert( slicep[0].doesPointTo(i));
assert(!slicep   .doesPointTo(i));

//static arrays are objects that own their members, just like structs:
assert(!arr.doesPointTo(arr[0])); //arr[0] is just a member of arr, so not pointed.
assert( arrp[0].doesPointTo(i));  //i is pointed by arrp[0].
assert( arrp   .doesPointTo(i));  //which means i is pointed by arrp itslef.

//Notice the difference between static and dynamic arrays:
assert(!arr  .doesPointTo(arr[0]));
assert( arr[].doesPointTo(arr[0]));
assert( arrp  .doesPointTo(i));
assert(!arrp[].doesPointTo(i));

Example

Classes

class C
{
    this(int* p){this.p = p;}
    int* p;
}
int i;
C a = new C(&i);
C b = a;
//Classes are a bit particular, as they are treated like simple pointers
//to a class payload.
assert( a.p.doesPointTo(i)); //a.p points to i.
assert(!a  .doesPointTo(i)); //Yet a itself does not point i.

//To check the class payload itself, iterate on its members:
()
{
    foreach (index, _; FieldTypeTuple!C)
        if (doesPointTo(a.tupleof[index], i))
            return;
    assert(0);
}();

//To check if a class points a specific payload, a direct memmory check can be done:
auto aLoc = cast(ubyte[__traits(classInstanceSize, C)]*) a;
assert(b.doesPointTo(*aLoc)); //b points to where a is pointing

Authors

Andrei Alexandrescu and Jonathan M Davis

License

Boost License 1.0

Comments