Function std.exception.doesPointTo
The "pointsTo" functions,
and doesPointTo
mayPointTo
.
Returns true
if
's representation embeds a pointer
that points to source
's representation or somewhere inside
it.
target
If
is or contains a dynamic array, then, then these functions will check
if there is overlap between the dynamic array and source
's representation.
target
If
is a class, then pointsTo will source
handle
it as a pointer.
If
is a pointer, a dynamic array or a class, then these functions will only
check if target
points to source
, not what target
references.
target
If
is or contains a union, then there may be either false positives or
false negatives:
source
will return doesPointTo
true
if it is absolutely certain
points to source
. It may produce false negatives, but never
false positives. This function should be prefered when trying to validate
input data.
target
mayPointTo
will return false
if it is absolutely certain
does not point to source
. It may produce false positives, but never
false negatives. This function should be prefered for defensively choosing a
code path.
target
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