Internal Functions | |
All functions and structs within this group should be considered internal. They just implement the functionality behind the typesafe list macros (see GWEN_LIST_FUNCTION_LIB_DEFS and following). | |
typedef GWEN_LIST1 | GWEN_LIST1 |
typedef GWEN_LIST1_ELEMENT | GWEN_LIST1_ELEMENT |
GWENHYWFAR_API int | GWEN_List1_Add (GWEN_LIST1 *l, GWEN_LIST1_ELEMENT *el) |
GWENHYWFAR_API int | GWEN_List1_AddList (GWEN_LIST1 *dest, GWEN_LIST1 *l) |
GWENHYWFAR_API int | GWEN_List1_Del (GWEN_LIST1_ELEMENT *el) |
GWENHYWFAR_API void | GWEN_List1_free (GWEN_LIST1 *l) |
GWENHYWFAR_API int | GWEN_List1_GetCount (const GWEN_LIST1 *l) |
GWENHYWFAR_API void * | GWEN_List1_GetFirst (const GWEN_LIST1 *l) |
GWENHYWFAR_API void * | GWEN_List1_GetLast (const GWEN_LIST1 *l) |
GWENHYWFAR_API int | GWEN_List1_Insert (GWEN_LIST1 *l, GWEN_LIST1_ELEMENT *el) |
GWENHYWFAR_API GWEN_LIST1 * | GWEN_List1_new () |
GWENHYWFAR_API void | GWEN_List1Element_free (GWEN_LIST1_ELEMENT *el) |
GWENHYWFAR_API void * | GWEN_List1Element_GetData (const GWEN_LIST1_ELEMENT *el) |
GWENHYWFAR_API void * | GWEN_List1Element_GetNext (const GWEN_LIST1_ELEMENT *el) |
GWENHYWFAR_API void * | GWEN_List1Element_GetPrevious (const GWEN_LIST1_ELEMENT *el) |
GWENHYWFAR_API GWEN_LIST1_ELEMENT * | GWEN_List1Element_new (void *d) |
Typesafe Macros | |
#define | GWEN_LIST_ELEMENT(t) GWEN_LIST1_ELEMENT *_list1_element; |
#define | GWEN_LIST_FINI(t, element) |
#define | GWEN_LIST_FUNCTION_DEFS(t, pr) GWEN_LIST_FUNCTION_LIB_DEFS(t, pr, GWEN_DUMMY_EMPTY_ARG) |
#define | GWEN_LIST_FUNCTION_DEFS_CONST(t, pr) GWEN_LIST_FUNCTION_LIB_DEFS_CONST(t, pr, GWEN_DUMMY_EMPTY_ARG) |
#define | GWEN_LIST_FUNCTION_DEFS_NOCONST(t, pr) GWEN_LIST_FUNCTION_LIB_DEFS_NOCONST(t, pr, GWEN_DUMMY_EMPTY_ARG) |
#define | GWEN_LIST_FUNCTION_LIB_DEFS(t, pr, decl) |
#define | GWEN_LIST_FUNCTION_LIB_DEFS_CONST(t, pr, decl) |
#define | GWEN_LIST_FUNCTION_LIB_DEFS_NOCONST(t, pr, decl) |
#define | GWEN_LIST_FUNCTIONS(t, pr) |
#define | GWEN_LIST_INIT(t, element) element->_list1_element=GWEN_List1Element_new(element); |
Let's assume you have a structure type called MYSTRUCT and you want to manage lists of them. Let's further assume that you want the functions dealing with that struct have prefixes like MyStruct (as in MyStruct_new) The header file would look like this:
/ * mystruct.h * / #ifndef MYSTRUCT_H #define MYSTRUCT_H typedef struct MYSTRUCT MYSTRUCT; GWEN_LIST_FUNCTION_DEFS(MYSTRUCT, MyStruct); struct MYSTRUCT { GWEN_LIST_ELEMENT(MYSTRUCT); int myData; } MYSTRUCT *MyStruct_new(int myData); void MyStruct_free(MYSTRUCT *myStruct); #endif
This defines all necessary data and function prototypes needed for list management.
The code file would look quite similar to the following:
/ * mystruct.c * / GWEN_LIST_FUNCTIONS(MYSTRUCT, MyStruct) MYSTRUCT *MyStruct_new(int myData) { MYSTRUCT *pMyStruct; pMyStruct=(MYSTRUCT*)malloc(sizeof(MYSTRUCT)); memset(pMyStruct, 0, sizeof(MYSTRUCT)); GWEN_LIST_INIT(MYSTRUCT, pMyStruct) pMyStruct->myData=myData; return pMyStruct; } void MyStruct_free(MYSTRUCT *pMyStruct) { if (pMyStruct) { pMyStruct->myData=0; GWEN_LIST_FINI(MYSTRUCT, pMyStruct) free(pMyStruct); } }
Note: When writing these macro code lines, the original ISO C89 standard for the C language does not allow terminating the macro statement with a semicolon ';'. Any recent compiler will probably silently ignore such an extra ';', but you should be aware that this can cause problems once one of your users tries to compile this with a different compiler. Therefore these code lines should end directly with the closing parentheses.
The list management code assumes that there is a function called (in this example) MyStruct_free() (or generally: TYPEPREFIX_free). This is used when destroying a list of MYSTRUCT elements. In this case all elements still enlisted are destroyed upon destruction of the list.
#define GWEN_LIST_ELEMENT | ( | t | ) | GWEN_LIST1_ELEMENT *_list1_element; |
#define GWEN_LIST_FINI | ( | t, | |||
element | ) |
Value:
if (element && element->_list1_element) { \ GWEN_List1Element_free(element->_list1_element); \ element->_list1_element=0; \ }
#define GWEN_LIST_FUNCTION_DEFS | ( | t, | |||
pr | ) | GWEN_LIST_FUNCTION_LIB_DEFS(t, pr, GWEN_DUMMY_EMPTY_ARG) |
This macro should be used in applications, not in libraries. In libraries please use the macro GWEN_LIST_FUNCTION_LIB_DEFS.
#define GWEN_LIST_FUNCTION_DEFS_CONST | ( | t, | |||
pr | ) | GWEN_LIST_FUNCTION_LIB_DEFS_CONST(t, pr, GWEN_DUMMY_EMPTY_ARG) |
#define GWEN_LIST_FUNCTION_DEFS_NOCONST | ( | t, | |||
pr | ) | GWEN_LIST_FUNCTION_LIB_DEFS_NOCONST(t, pr, GWEN_DUMMY_EMPTY_ARG) |
#define GWEN_LIST_FUNCTION_LIB_DEFS | ( | t, | |||
pr, | |||||
decl | ) |
Value:
GWEN_LIST_FUNCTION_LIB_DEFS_CONST(t, pr, decl) \ GWEN_LIST_FUNCTION_LIB_DEFS_NOCONST(t, pr, decl)
#define GWEN_LIST_FUNCTION_LIB_DEFS_CONST | ( | t, | |||
pr, | |||||
decl | ) |
Value:
typedef GWEN_LIST1 t##_LIST; \ \ decl t* pr##_List_First(const t##_LIST *l); \ decl t* pr##_List_Last(const t##_LIST *l); \ decl t* pr##_List_Next(const t *element); \ decl t* pr##_List_Previous(const t *element); \ decl GWEN_TYPE_UINT32 pr##_List_GetCount(const t##_LIST *l);
#define GWEN_LIST_FUNCTION_LIB_DEFS_NOCONST | ( | t, | |||
pr, | |||||
decl | ) |
Value:
typedef GWEN_LIST1_ELEMENT t##_LIST_ELEMENT; \ \ decl void pr##_List_Clear(t##_LIST *l); \ decl t##_LIST* pr##_List_new(); \ decl void pr##_List_free(t##_LIST *l); \ decl int pr##_List_AddList(t##_LIST *dst, t##_LIST *l); \ decl int pr##_List_Add(t *element, t##_LIST *list); \ decl int pr##_List_Insert(t *element, t##_LIST *list); \ decl int pr##_List_Del(t *element); \
#define GWEN_LIST_FUNCTIONS | ( | t, | |||
pr | ) |
Use this inside your code files (*.c). Actually implements the functions for which the prototypes have been defined via GWEN_LIST_FUNCTION_DEFS.
#define GWEN_LIST_INIT | ( | t, | |||
element | ) | element->_list1_element=GWEN_List1Element_new(element); |
typedef struct GWEN_LIST1 GWEN_LIST1 |
typedef struct GWEN_LIST1_ELEMENT GWEN_LIST1_ELEMENT |
GWENHYWFAR_API int GWEN_List1_Add | ( | GWEN_LIST1 * | l, | |
GWEN_LIST1_ELEMENT * | el | |||
) |
Adds (appends) a list element at the end of the list. (This operation is also called "append" or "push_back" elsewhere.)
GWENHYWFAR_API int GWEN_List1_AddList | ( | GWEN_LIST1 * | dest, | |
GWEN_LIST1 * | l | |||
) |
Adds (appends) the second list to the end of the first list. (This operation is also called "append" or "concatenate" elsewhere.)
GWENHYWFAR_API int GWEN_List1_Del | ( | GWEN_LIST1_ELEMENT * | el | ) |
Deletes (removes) a list element from the list it used to belong to. The list element is not free'd or anything, it is only removed from the list it used to belong to. (This operation is also called "remove" or "unlink" elsewhere.)
GWENHYWFAR_API void GWEN_List1_free | ( | GWEN_LIST1 * | l | ) |
Free (delete) an existing list. The list elements are untouched by this function; they need to be freed beforehand.
GWENHYWFAR_API int GWEN_List1_GetCount | ( | const GWEN_LIST1 * | l | ) |
Returns the number of elements in this list. This value is cached in the list structure, so this function is a cheap function.
GWENHYWFAR_API void* GWEN_List1_GetFirst | ( | const GWEN_LIST1 * | l | ) |
Returns the data pointer of the first list element.
GWENHYWFAR_API void* GWEN_List1_GetLast | ( | const GWEN_LIST1 * | l | ) |
Returns the data pointer of the last list element.
GWENHYWFAR_API int GWEN_List1_Insert | ( | GWEN_LIST1 * | l, | |
GWEN_LIST1_ELEMENT * | el | |||
) |
Inserts (prepends) a list element at the beginning of the list. (This operation is also called "prepend" or "push_front" elsewhere.)
GWENHYWFAR_API GWEN_LIST1* GWEN_List1_new | ( | ) |
Allocate (create) a new empty list.
GWENHYWFAR_API void GWEN_List1Element_free | ( | GWEN_LIST1_ELEMENT * | el | ) |
Free (delete) a list element structure.
GWENHYWFAR_API void* GWEN_List1Element_GetData | ( | const GWEN_LIST1_ELEMENT * | el | ) |
Returns the data pointer of the given list element structure.
GWENHYWFAR_API void* GWEN_List1Element_GetNext | ( | const GWEN_LIST1_ELEMENT * | el | ) |
Returns the data pointer of the list element that is the next one (successor) to the given one in its list. If there is no such prepending list element, returns NULL.
GWENHYWFAR_API void* GWEN_List1Element_GetPrevious | ( | const GWEN_LIST1_ELEMENT * | el | ) |
Returns the data pointer of the list element that is the previous (predecessor) to the given one in its list. If there is no such prepending list element, returns NULL.
GWENHYWFAR_API GWEN_LIST1_ELEMENT* GWEN_List1Element_new | ( | void * | d | ) |
Allocate (create) a new list element structure.