Struct wrapping

Wrapping D's structs is similar to wrapping classes. In fact, many of the operations are identical.

struct wrapped_struct(T, char[] structname = symbolnameof!(T));

To expose the data members, member functions, and properties of the class, wrapped_struct provides a series of template member functions.

static void member(M, size_t offset, char[] name) (char[] docstring="");
This exposes a data member of the struct to Python. M is the type of the member, and must be a convertible type. offset is the offset (in bytes) of the member in the struct. name is the name of the data member as it will be used in Python. (Optimally, one would simply be able to pass an alias to the member, or at worst an alias and a name, but DMD currently has some issues with this.)
static void def(alias fn, char[] name = symbolnameof!(fn), fn_t = typeof(&fn)) (char[] docstring="");
This wraps a member function of the struct. It functions exactly like the def function used to wrap class methods, including the lack of support for default arguments.
static void static_def(alias fn, char[] name = symbolnameof!(fn), fn_t = typeof(&fn), uint MIN_ARGS = minArgs!(fn)) (char[] docstring="");
This wraps a static member function of the struct. It functions exactly like the static_def function used to wrap static class member functions, and also includes support for default arguments.
static void prop(alias fn, char[] name = symbolnameof!(fn), bool RO = false) (char[] docstring="");
This wraps a property. It is identical to the prop function used to wrap class properties.
static void iter(iter_t) ();
This allows the user to specify a different overload of opApply than the default. (The default is always the one that is lexically first.) It is identical to the iter function used in class wrapping.
static void alt_iter(alias fn, char[] name = symbolnameof!(fn), iter_t = implementationDetail) (char[] docstring="");
This wraps alternate iterator methods as Python methods that return iterator objects. It is is identical to the alt_iter function used in class wrapping.

(Future enhancements: Support for struct ctors.)

Once you have called all of the member functions of wrapped_struct that you wish to, you must issue a call to finalize_struct.

void finalize_struct(S) (S s, char[] docstring="");

This does some final initialization of the type and then registers it with Python. As with calls to finalize_class, calls to finalize_struct must occur after calling module_init. The s function argument should be an instance of wrapped_struct.

The is_wrapped template is available for wrapped structs, just like it is for wrapped classes.

It is important to note that wrapping a struct S makes both S itself and S* available as convertible types.

Automatic operator overloading

Support for operator overloading in structs is identical to that available for classes.

Examples

(Todo.)