Function std.exception.doesPointTo
Checks whether a given source
object
contains pointers or references to a given
target
object
.
Prototypes
bool doesPointTo(S, T, Tdummy)( S source, T target ) pure nothrow @trusted if (__traits(isRef, source) || isDynamicArray!S || isPointer!S || is(S == class)); bool doesPointTo(S, T)( S source, T target ) pure nothrow @trusted;
Parameters
Name | Description |
---|---|
source | The source object |
target | The target object |
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 it will be handled as a pointer.
source
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
will return mayPointTo
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
Note
Evaluating
checks whether doesPointTo
(x, x)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 // 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: () { 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