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.mayPointTo

Checks whether a given source object contains pointers or references to a given target object.

bool mayPointTo(S, T, Tdummy) (
  auto const ref S source,
  const ref T target
) pure nothrow @trusted
if (__traits(isRef, source) || isDynamicArray!S || is(S == U*, U) || is(S == class));

bool mayPointTo(S, T) (
  auto const shared ref S source,
  const shared ref T target
) pure nothrow @trusted;

Parameters

NameDescription
source The source object
target The target object

Bugs

The function is explicitly annotated @nogc because inference could fail, see Bugzilla issue 17084.

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 it will be handled 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 or void[n], 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.

Note

Evaluating doesPointTo(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;
 // trick the compiler when initializing slice
 // https://issues.dlang.org/show_bug.cgi?id=18637
int* p = &i;
int[]  slice = [0, 1, 2, 3, 4];
int[5] arr   = [0, 1, 2, 3, 4];
int*[]  slicep = [p];
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
                                  // itself.

// 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:
()
{
    import std.traits : Fields;

    foreach (index, _; Fields!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