Derived Utilities

5.1  Tagged C Pointer Types

(cpointer-has-tag? cptr tag)      PROCEDURE

(cpointer-push-tag! cptr tag)      PROCEDURE

These two functions treat pointer tags as lists of tags. As described in Section 4, a pointer tag does not have any role except for Scheme code that uses it to distinguish pointers -- these functions treat the tag value as a list of tags, which makes it possible to construct pointer types that can be treated as other pointer types, mainly for implementing inheritance via upcasts (when a struct contains a super struct as its first element).

cpointer-has-tag? checks if the given cptr has the tag -- a pointer has a tag t when its tag is either eq? to t or a list that contains (memq) t.

cpointer-push-tag! pushes the given tag value on cptr's tags. The main properties of this operation are: (a) pushing any tag will make later calls to cpointer-has-tag? succeed with this tag, (b) the pushed tag will be used when printing the pointer (until a new value is pushed). (Technically, pushing a tag will simply set it if there is no tag set, otherwise push it on an existing list or an existing value (treated as a single-element list).)

(_cpointer tag [ptr-type [scheme-to-C-proc C-to-scheme-proc]])      PROCEDURE

(_cpointer/null tag [ptr-type [scheme-to-C-proc C-to-scheme-proc]])      PROCEDURE

These functions construct a kind of a pointer that gets a specific tag when converted to Scheme, and accept only such tagged pointers when going to C. An optional ptr-type can be given to be used as the base pointer type, instead of _pointer. (See set-cpointer-tag! and cpointer-tag in section 4 for more details.)

Pointer tags are checked with cpointer-has-tag? and changed with cpointer-push-tag! which means that other tags are preserved. Specifically, if a base ptr-type is given and is itself a _cpointer, then the new type will handle pointers that have the new tag in addition to ptr-type's tag(s). When the tag is a pair, its first value is used for printing, so the most recently pushed tag which corresponds to the inheriting type will be displayed.

Note that tags are compared with eq? (or memq), which means an interface can hide its value from users (e.g., not provide the cpointer-tag accessor), which makes such pointers un-fake-able.

_cpointer/null is similar to _cpointer except that it tolerates NULL pointers both going to C and back. Note that NULL pointers are represented as #f in Scheme, so they are not tagged.

(define-cpointer-type _name [ptr-type [scheme-to-C-proc C-to-scheme-proc]])      SYNTAX

A macro version of _cpointer and _cpointer/null above, using the defined name for a tag string, and defining a predicate too. The name should look like `_foo', the predicate will be `foo?', and the tag will be "foo". In addition, `foo-tag' will be bound to the tag. The optional arguments are the same as those of _cpointer. `_foo' will be bound to the _cpointer type, and `_foo/null' to the _cpointer/null type.

5.2  Safe C Vectors

(make-cvector ctype length)      PROCEDURE

Creates a C vector using the given ctype and length. This will allocate a memory block for the vector.

(cvector ctype vals ···)      PROCEDURE

Creates a C vector using the given ctype, initialized to the given list of values.

(cvector? x)      PROCEDURE

Predicate for C vectors.

(cvector-length cvec)      PROCEDURE

Returns the length of a C vector.

(cvector-type cvec)      PROCEDURE

Returns the C type object of a C vector.

(cvector-ref cvec idx)      PROCEDURE

References the idxth element of the cvec C vector. The result will have the type that the C vector uses.

(cvector-set! cvec idx val)      PROCEDURE

Sets the idxth element of the cvec C vector to val. val should be a value that can be used with the type that the C vector uses.

(cvector->list cvec)      PROCEDURE

Converts the cvec C vector object to a list of values.

(list->cvector list ctype)      PROCEDURE

Converts the list list to a C vector of the given ctype.

(make-cvector* cptr ctype length)      PROCEDURE

Constructs a C vector using an existing pointer object. This operation is not safe, so it is intended to be used in specific situations where the ctype and length are known.

_cvector      C TYPE

An input type for C vectors, which uses the pointer to the memory block. Also, see the _cvector custom type in section 3.5.1.

5.3  SRFI-4 Vectors

SRFI-4 vectors are similar to the above C vector, except it defines different types of vectors, each with a hard-wired type.

An internal `make-srfi-4' macro defines and provides 8 functions for each TAG type -- a `make-TAGvector' constructor, a `TAGvector' constructor (uses its arguments), a `TAGvector?' predicate, a `TAGvector-length' function, a `TAGvector-ref' accessor and a `TAGvector-set!' setter, and conversions to and from a list, `TAGvector->list' and `list->TAGvector'. The functions are the same as the corresponding cvector functions above, except that there is no type argument.

In addition, there is a _TAGvector type similar to _cvector that can be used when interfacing foreign functions. Just like _cvector, _TAGvector can be used both as a simple type to pass a pointer value to foreign code, or as a custom type, expecting a mode flag for input, output, or input-output, where output-mode requires specifying the size of the result.

The following homogeneous vector types are defined, for a total of 80 functions.

The implementation of u8vector is an exception: it is implemented as MzScheme's byte-strings (section 3.6 in PLT MzScheme: Language Manual).