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