Template Codegen + Tupleof
Frits van Bommel
fvbommel at REMwOVExCAPSs.nl
Tue Feb 6 11:12:10 PST 2007
Kyle Furlong wrote:
> Yes, thanks for the verification of the bug. But yeah, my code is not
> very sophisticated yet due to frustration with the bug. Once this is
> fixed I can move on to a complete correct solution.
By the way, I've got something similar working pretty well (code attached).
I'm not using a function though, just a raw template that aliases to a
struct instance with type information. That type information includes
pointers to recursively generated type information for any members.
The current public interface is basically:
----
/// Represents a type. At most one of fields and base will be non-null.
struct RttiData {
/** 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).
*/
const TypeInfo typeinfo;
/** The type of the data pointed to if this instance represents a
pointer
* or class reference.
*/
const RttiData* base;
/** 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.
*/
const FieldData[] fields;
// Plus implementations of toString, opEquals, opCmp and toHash
}
/// Represents a field in a class body, struct or union.
struct FieldData {
/// A pointer to the type data of the type of the field.
const RttiData* rtti;
/// The _offset of this field from the start of the data block.
const size_t offset;
// Plus toString, opEquals, opCmp and toHash
}
/// Aliases to a const RttiData instance describing T.
template Rtti(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.
*/
struct ClassBody(T) {}
-----
Some notes:
* Classes are treated as pointers, their bodies as structs.
* Delegates and dynamic arrays are considered equivalent to structs
(with void*/void function() or size_t/T* members, respectively).
Similarly, associative arrays are treated as void*s.
* It requires a static constructor for each aggregate type, and for each
of their fields. (Though fields of the same type and offset from
different aggregates should be folded together by DMD)
* When compiled with version=ShowHiddenClassFields the generated class
metadata monitor and vtable pointers (including those for interface
vtables).
Unportabilities and bugs :(:
* It assumes that static constructors of alias member parameters 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.
* Generated information 'unfolds' typedefs, aliasing to the information
generated for the base type. I haven't found any way around this without
using a static constructor, but I don't think it's worth it.
* 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.
Another "problem" is that I've yet to find a good way to handle dynamic
arrays. Currently they're identical to a struct { size_t length; void*
ptr; }, but in this case it's known (at least at run-time) to how many
elements that pointer points. I have yet to find a way to express this
in my data. Unless you count 'If RttiData.typeinfo.toString() (or
toUtf8(), for Tango users) ends in "[]", it's a dynamic array'.
*phew* long post. Hope I didn't forget anything...
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ext_rtti.zip
Type: application/zip
Size: 12109 bytes
Desc: not available
Url : http://lists.puremagic.com/pipermail/digitalmars-d-bugs/attachments/20070206/31f804dc/attachment.zip
More information about the Digitalmars-d-bugs
mailing list