Previous: Structure Basics, Up: Structures


22.5.4 Vtables

Vtables are structures that are used to represent structure types. Each vtable contains a layout specification in field vtable-index-layout – instances of the type are laid out according to that specification. Vtables contain additional fields which are used only internally to libguile. The variable vtable-offset-user is bound to a field number. Vtable fields at that position or greater are user definable.

— Scheme Procedure: struct-vtable s
— C Function: scm_struct_vtable (s)

Return the vtable structure that describes the type of struct s.

— Scheme Procedure: struct-vtable? x
— C Function: scm_struct_vtable_p (x)

Return #t iff obj is a vtable structure.

If you have a vtable structure, V, you can create an instance of the type it describes by using (make-struct V ...). But where does V itself come from? One possibility is that V is an instance of a user-defined vtable type, V', so that V is created by using (make-struct V' ...). Another possibility is that V is an instance of the type it itself describes. Vtable structures of the second sort are created by this procedure:

— Scheme Procedure: make-vtable-vtable new-fields tail-size [inits ...]
— C Function: scm_make_vtable_vtable (new-fields, tail-size, inits)

Return a new, self-describing vtable structure.

new-fields is a layout specification describing fields of the resulting structure beginning at the position bound to vtable-offset-user.

tail-size specifies the size of the tail-array (if any) of this vtable.

inits initializes the fields of the vtable. Minimally, one initializer must be provided: the layout specification for instances of the type this vtable will describe. If a second initializer is provided, it will be interpreted as a print call-back function.

Here is a small session that demonstrates make-vtable-vtable:

     guile> (define x (make-vtable-vtable (make-struct-layout (quote pw))
                                          0
                                          #f
                                          'foo))
     guile> (struct? x)
     #t
     guile> (struct-vtable? x)
     #t
     guile> (eq? x (struct-vtable x))
     #t
     guile> (struct-ref x vtable-offset-user)
     foo
     guile> (struct-ref x 0)
     pruosrpwpw

Here is a continuation of the session that demonstrates make-struct-layout, using x:

     guile> (define y (make-struct x 0
                                   (make-struct-layout (quote pwpwpw))
                                   #f
                                   'bar))
     guile> (struct? y)
     #t
     guile> (struct-vtable? y)
     #t
     guile> (eq? x y)
     #f
     guile> (eq? x (struct-vtable y))
     #t
     guile> (struct-ref y 0)
     pwpwpw
     guile> (struct-ref y vtable-offset-user)
     bar
     #

Here is the last part of the session that passes y to make-struct:

     guile> (define z (make-struct y 0 'a 'b 'c))
     guile> (struct? z)
     #t
     guile> (struct-vtable? z)
     #f
     guile> (eq? y (struct-vtable z))
     #t
     guile> (map (lambda (n) (struct-ref z n)) '(0 1 2))
     (a b c)
— Scheme Procedure: struct-vtable-name vtable
— C Function: scm_struct_vtable_name (vtable)

Return the name of vtable.

— Scheme Procedure: set-struct-vtable-name! vtable name
— C Function: scm_set_struct_vtable_name_x (vtable, name)

Associate with vtable vtable the symbol name.

— Scheme Procedure: struct-vtable-tag vtable
— C Function: scm_struct_vtable_tag (vtable)

Return the tag of vtable, a struct vtable. The tag is a number.