Functions

Create typed memory blocks

The main use case for libxnd is to create and manage typed memory blocks. These blocks are fully initialized to 0. References to additional memory blocks are allocated and initialized recursively.

bytes and string types are initialized to NULL, since their actual length is not known yet.

xnd_master_t *xnd_empty_from_string(const char *s, uint32_t flags, ndt_context_t *ctx);

Return a new master buffer according to the type string in s. flags must include XND_OWN_TYPE.

xnd_master_t *xnd_empty_from_type(const ndt_t *t, uint32_t flags, ndt_context_t *ctx);

Return a new master buffer according to type. flags must not include XND_OWN_TYPE, i.e. the type is externally managed.

This is the case in the Python bindings, where the ndtypes module creates and manages types.

Delete typed memory blocks

void xnd_del(xnd_master_t *x);

Delete the master buffer according to its flags. x may be NULL. x->master.ptr and x->master.type may be NULL.

The latter situation should only arise when breaking up reference cycles. This is used in the Python module.

Bitmaps

xnd_bitmap_t xnd_bitmap_next(const xnd_t *x, int64_t i, ndt_context_t *ctx);

Get the next bitmap for the Tuple, Record, Ref and Constr types.

This is a convenience function that checks if the types have optional subtrees.

If yes, return the bitmap at index i. If not, it return an empty bitmap that must not be accessed.

void xnd_set_valid(xnd_t *x);

Set the validity bit at x->index. x must have an optional type.

void xnd_set_na(xnd_t *x);

Clear the validity bit at x->index. x must have an optional type.

int xnd_is_valid(const xnd_t *x);

Check if the element at x->index is valid. If x does not have an optional type, return 1. Otherwise, return the validity bit (zero or nonzero).

int xnd_is_na(const xnd_t *x);

Check if the element at x->index is valid. If x does not have an optional type, return 0. Otherwise, return the negation of the validity bit.

xnd_t xnd_subtree(const xnd_t *x, const xnd_index_t indices[], int len,
                  ndt_context_t *ctx);

Apply zero or more indices to the input x and return a typed view. Valid indices are integers or strings for record fields.

This function is more general than pure array indexing, hence the name. For example, it is possible to index into nested records that in turn contain arrays.

xnd_t xnd_multikey(const xnd_t *x, const xnd_index_t indices[], int len,
                   ndt_context_t *ctx);

Apply zero or more keys to the input x and return a typed view. Valid keys are integers or slices.

This function differs from xnd_subtree in that it allows mixed indexing and slicing for fixed dimensions. Records and tuples cannot be sliced.

Variable dimensions can be sliced, but do not support mixed indexing and slicing.