rtti
This module provides some reflection capabilities, by referring at run time
to data generated at compile time.
The latter is achieved by using templates to recursively define (const)
struct instances describing types.
To include vtable and monitor pointers in class bodies (including interface
vtable pointers), compile with version ShowHiddenClassFields enabled.
Note:
This module was only tested using DMD running on Linux. See below for
some portability concerns.
BUGS:
The code is currently Tango-only, but that should be relatively easy to
change.
(for Tango users) This code is affected by
DMD bug #887.
(Should be fixed in DMD v1.005, AFAIK not yet in Tango)
The workaround is in place, and can be disabled by disabling version
Bug_887_Workaround which is in place by default. Since the workaround
requires TypeInfo.toString() to be called when it shouldn't be necessary,
RttiData's member functions are probably less efficient than they should be.
It's also affected by
DMD bug #902,
which means you can't use it from more than one module until that bug is
fixed.
Static constructors of alias member parameters are assumed to have been run
before that of the template itself. Fortunately this seems to be exactly
what DMD does.
Unions are used to avoid some extra static constructors. (Unless disabled
by removing version=UnionHack, but that of course introduces extra static
constructors) These assume that a dynamic array has the exact layout of a
struct { size_t length; void* ptr; }.
Because of DMD bug #902 you can't instantiate the templates (including
internal ones) from more than one module without getting 'multiple
definition' errors.
The current version requires Tango, but that can easily be changed.
Assumes the current DMD layout for dynamic arrays and delegates.
The extra data generated with version=ShowHiddenClassFields seems to be
correct for DMD, but I have no idea if (a) it is correct in all cases and
(b) if it's correct for GDC at all.
(If anyone can tell me whether this works on GDC please do so.
Specifically, the exact layout of class bodies (including interface vptrs) would
be nice to know)
Type information does not preserve typedefs.
Authors:
Frits van Bommel
- struct RttiData;
- Represents a type. At most one of fields and base will be non-null.
- TypeInfo typeinfo;
- The TypeInfo of the represented type.
Note:
Class references use the TypeInfo of the class, their bodies are
represented by the TypeInfo of ClassBody!(ClassName).
- RttiData * base;
- The type of the data pointed to if this instance represents a pointer
or class reference.
- FieldData [] fields;
- The fields of the type.
If the type is a class body, struct or union, this contains the
fields of the type.
For dynamic arrays, this contains their length and ptr,
for static arrays their elements, and
for delegates their context pointer and function pointer.
- char[] toString();
- Convert to a pretty-printed string.
Note:
This can get pretty long, especially for types containing
class references, structs, unions, arrays or pointers.
BUGS:
Not re-entrant, due to the way it avoids infinite recursion.
- int opEquals(RttiData other);
- Returns !=0 if this instance represents the same type as the other
instance.
- int opCmp(RttiData other);
- uint toHash();
- struct FieldData;
- Represents a field in a class body, struct or union.
- RttiData * rtti;
- A pointer to the type data of the type of the field.
- uint offset;
- The offset of this field from the start of the data block.
- char[] toString();
- Convert to a pretty-printed string.
Note:
This can get pretty long, especially for fields containing class
references, structs, unions, arrays or pointers.
BUGS:
Not re-entrant because it calls RttiData.toString, which isn't
re-entrant.
- int opEquals(FieldData other);
- int opCmp(FieldData other);
- uint toHash();
- template Rtti(T)
- Returns an RttiData instance describing T.
- struct ClassBody(T);
- RttiData instances for class bodies use the TypeInfo of ClassBody,
templated on the class, as their type.
(the class' own TypeInfo is used for the reference)
For instance, Rtti!(Object).base.typeinfo == typeid(ClassBody!(Object)).
This type does not have any members, and its only value is the fact that it
has TypeInfo data associated with it.
- template ClassFieldsRtti(T)
- Returns a tuple of FieldData structs that represent a class' fields
(including those of base classes) and, with version=ShowHiddenClassFields
enabled, its hidden vptr and monitor pointers.
- template FieldsRtti(T)
- Returns a FieldData tuple representing the fields of a struct or union.
ClassFieldsRtti should be used to generate such tuples for classes.
(Internally ClassFieldsRtti uses FieldsRtti)
- template FieldRtti(T,uint Offset)
- Returns a FieldData instance for a field of type T at offset Offset from the
start of an instance.
Page generated by Ddoc.