mirror of
https://github.com/samba-team/samba.git
synced 2024-12-28 07:21:54 +03:00
116 lines
3.4 KiB
C
116 lines
3.4 KiB
C
|
/* Placed into the public domain */
|
||
|
#ifndef CCAN_TCON_H
|
||
|
#define CCAN_TCON_H
|
||
|
#include "config.h"
|
||
|
|
||
|
/**
|
||
|
* TCON - declare a _tcon type containing canary variables.
|
||
|
* @decls: the semi-colon separated list of type canaries.
|
||
|
*
|
||
|
* This declares a _tcon member for a structure. It should be the
|
||
|
* last element in your structure; with sufficient compiler support it
|
||
|
* will not use any actual storage. tcon_check() will compare
|
||
|
* expressions with one of these "type canaries" to cause warnings if
|
||
|
* the container is misused.
|
||
|
*
|
||
|
* A type of "void *" will allow tcon_check() to pass on any (pointer) type.
|
||
|
*
|
||
|
* Example:
|
||
|
* // Simply typesafe linked list.
|
||
|
* struct list_head {
|
||
|
* struct list_head *prev, *next;
|
||
|
* };
|
||
|
*
|
||
|
* struct string_list {
|
||
|
* struct list_head raw;
|
||
|
* TCON(char *canary);
|
||
|
* };
|
||
|
*
|
||
|
* // More complex: mapping from one type to another.
|
||
|
* struct map {
|
||
|
* void *contents;
|
||
|
* };
|
||
|
*
|
||
|
* struct int_to_string_map {
|
||
|
* struct map raw;
|
||
|
* TCON(char *charp_canary; int int_canary);
|
||
|
* };
|
||
|
*/
|
||
|
#if HAVE_FLEXIBLE_ARRAY_MEMBER
|
||
|
#define TCON(decls) struct { decls; } _tcon[]
|
||
|
#else
|
||
|
#define TCON(decls) struct { decls; } _tcon[1]
|
||
|
#endif
|
||
|
|
||
|
/**
|
||
|
* tcon_check - typecheck a typed container
|
||
|
* @x: the structure containing the TCON.
|
||
|
* @canary: which canary to check against.
|
||
|
* @expr: the expression whose type must match the TCON (not evaluated)
|
||
|
*
|
||
|
* This macro is used to check that the expression is the type
|
||
|
* expected for this structure (note the "useless" sizeof() argument
|
||
|
* which contains this comparison with the type canary).
|
||
|
*
|
||
|
* It evaluates to @x so you can chain it.
|
||
|
*
|
||
|
* Example:
|
||
|
* #define tlist_add(h, n, member) \
|
||
|
* list_add(&tcon_check((h), canary, (n))->raw, &(n)->member)
|
||
|
*/
|
||
|
#define tcon_check(x, canary, expr) \
|
||
|
(sizeof((x)->_tcon[0].canary == (expr)) ? (x) : (x))
|
||
|
|
||
|
/**
|
||
|
* tcon_check_ptr - typecheck a typed container
|
||
|
* @x: the structure containing the TCON.
|
||
|
* @canary: which canary to check against.
|
||
|
* @expr: the expression whose type must match &TCON (not evaluated)
|
||
|
*
|
||
|
* This macro is used to check that the expression is a pointer to the type
|
||
|
* expected for this structure (note the "useless" sizeof() argument
|
||
|
* which contains this comparison with the type canary), or NULL.
|
||
|
*
|
||
|
* It evaluates to @x so you can chain it.
|
||
|
*/
|
||
|
#define tcon_check_ptr(x, canary, expr) \
|
||
|
(sizeof(&(x)->_tcon[0].canary == (expr)) ? (x) : (x))
|
||
|
|
||
|
|
||
|
/**
|
||
|
* tcon_type - the type within a container (or void *)
|
||
|
* @x: the structure containing the TCON.
|
||
|
* @canary: which canary to check against.
|
||
|
*/
|
||
|
#if HAVE_TYPEOF
|
||
|
#define tcon_type(x, canary) __typeof__((x)->_tcon[0].canary)
|
||
|
#else
|
||
|
#define tcon_type(x, canary) void *
|
||
|
#endif
|
||
|
|
||
|
/**
|
||
|
* tcon_ptr_type - pointer to the type within a container (or void *)
|
||
|
* @x: the structure containing the TCON.
|
||
|
* @canary: which canary to check against.
|
||
|
*/
|
||
|
#if HAVE_TYPEOF
|
||
|
#define tcon_ptr_type(x, canary) __typeof__(&(x)->_tcon[0].canary)
|
||
|
#else
|
||
|
#define tcon_ptr_type(x, canary) void *
|
||
|
#endif
|
||
|
|
||
|
/**
|
||
|
* tcon_cast - cast to a canary type for this container (or void *)
|
||
|
* @x: a structure containing the TCON.
|
||
|
* @canary: which canary to cast to.
|
||
|
* @expr: the value to cast
|
||
|
*
|
||
|
* This is used to cast to the correct type for this container. If the
|
||
|
* platform doesn't HAVE_TYPEOF, then it casts to void * (which will
|
||
|
* cause a warning if the user doesn't expect a pointer type).
|
||
|
*/
|
||
|
#define tcon_cast(x, canary, expr) ((tcon_type((x), canary))(expr))
|
||
|
#define tcon_cast_ptr(x, canary, expr) ((tcon_ptr_type((x), canary))(expr))
|
||
|
|
||
|
#endif /* CCAN_TCON_H */
|