Macros For Typesafe List Handling


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 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)
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_LIST1GWEN_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_ELEMENTGWEN_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);

Detailed Description

Necessary for MSVC compiler because it does not accept a left-out macro argument.

The macros of this group facilitates typesafe use of lists.

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);
   }
 }
Please note the three macros used in the code file:

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 Documentation

#define GWEN_LIST_ELEMENT (  )     GWEN_LIST1_ELEMENT *_list1_element;

Use this inside the declaration of a struct for which you want to create lists.

Definition at line 249 of file list1.h.

#define GWEN_LIST_FINI ( t,
element   ) 

#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.

Definition at line 344 of file list1.h.

#define GWEN_LIST_FUNCTION_DEFS_CONST ( t,
pr   )     GWEN_LIST_FUNCTION_LIB_DEFS_CONST(t, pr, GWEN_DUMMY_EMPTY_ARG)

Definition at line 281 of file list1.h.

#define GWEN_LIST_FUNCTION_DEFS_NOCONST ( t,
pr   )     GWEN_LIST_FUNCTION_LIB_DEFS_NOCONST(t, pr, GWEN_DUMMY_EMPTY_ARG)

Definition at line 284 of file list1.h.

#define GWEN_LIST_FUNCTION_LIB_DEFS ( t,
pr,
decl   ) 

Value:

Use this in public header files to define some prototypes for list functions. Let's assume the type of your list elements is "MYTYPE" and you want to use the prefix "MyType_" for the list functions. The following function prototypes will then be created:
  • void MyType_List_Add(MYTYPE *element, MYTYPE_LIST *list);
    Adds (appends) a MYTYPE struct at the end of the given list. (We apologize for the unusual argument order here.)
  • void MyType_List_Del(MYTYPE *element);
    Removes a MyType struct from the list it is enlisted to.
  • MYTYPE *MyType_List_First(MYTYPE *element);
    Returns the first element of the given list.
  • MYTYPE* MyType_List_Next(const MYTYPE *element);
    Returns the next list element to the given one (the successor) in its list.
  • MYTYPE* MyType_List_Previous(const MYTYPE *element);
    Returns the previous list element to the given one (the predecessor) in its list.
  • void MyType_List_Clear(MYTYPE *element);
    Frees all entries of the given list. This function assumes that there is a function Mytype_free().
  • MYTYPE_LIST *MyType_List_new();
    Creates a new list of elements of MYTYPE type.
  • void MyType_List_free(MYTYPE_LIST *l);
    Clears and frees a list of elements of MYTYPE type. All objects inside the list are freed.

Definition at line 335 of file list1.h.

#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 uint32_t pr##_List_GetCount(const t##_LIST *l); \
  decl int pr##_List_HasElement(const t##_LIST *l, const t *element);
Use this macro in your public header files to export only list functions which do not modify a list. This allows your code to return lists which can not be modified by callers. It also prevents callers from creating their own lists (this is sometimes needed).

Definition at line 258 of file list1.h.

#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); \

Definition at line 269 of file list1.h.

#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.

Definition at line 353 of file list1.h.

#define GWEN_LIST_INIT ( t,
element   )     element->_list1_element=GWEN_List1Element_new(element);


Typedef Documentation

typedef struct GWEN_LIST1 GWEN_LIST1

Definition at line 158 of file list1.h.

Definition at line 159 of file list1.h.


Function Documentation

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.)

Definition at line 63 of file list1.c.

References DBG_ERROR, and GWEN_LOGDOMAIN.

Referenced by GWEN_List1_AddList().

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.)

Definition at line 89 of file list1.c.

References GWEN_List1_Add(), and GWEN_List1_Del().

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.)

Definition at line 128 of file list1.c.

References DBG_ERROR, and GWEN_LOGDOMAIN.

Referenced by GWEN_List1_AddList(), and GWEN_List1Element_free().

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.

Definition at line 48 of file list1.c.

References GWEN_FREE_OBJECT.

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.

Definition at line 56 of file list1.c.

GWENHYWFAR_API void* GWEN_List1_GetFirst ( const GWEN_LIST1 l  ) 

Returns the data pointer of the first list element.

Definition at line 164 of file list1.c.

GWENHYWFAR_API void* GWEN_List1_GetLast ( const GWEN_LIST1 l  ) 

Returns the data pointer of the last list element.

Definition at line 172 of file list1.c.

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.)

Definition at line 105 of file list1.c.

References DBG_ERROR, and GWEN_LOGDOMAIN.

GWENHYWFAR_API GWEN_LIST1* GWEN_List1_new (  ) 

Allocate (create) a new empty list.

Definition at line 40 of file list1.c.

References GWEN_NEW_OBJECT.

GWENHYWFAR_API void GWEN_List1Element_free ( GWEN_LIST1_ELEMENT el  ) 

Free (delete) a list element structure.

Definition at line 194 of file list1.c.

References GWEN_FREE_OBJECT, and GWEN_List1_Del().

GWENHYWFAR_API void* GWEN_List1Element_GetData ( const GWEN_LIST1_ELEMENT el  ) 

Returns the data pointer of the given list element structure.

Definition at line 204 of file list1.c.

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.

Definition at line 218 of file list1.c.

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.

Definition at line 210 of file list1.c.

GWENHYWFAR_API GWEN_LIST1_ELEMENT* GWEN_List1Element_new ( void *  d  ) 

Allocate (create) a new list element structure.

Definition at line 183 of file list1.c.

References GWEN_NEW_OBJECT.


Generated on Fri Apr 11 01:53:50 2008 for gwenhywfar by  doxygen 1.5.5