MLib Alpha 1 API Reference

MLib Alpha 1 API Reference

Lists

The MLib contains two implementations of lists, in order to please several kinds of developers and users. Note that both implementations use the same type for the list nodes though.

First of all, the M_ListRec type is used to model an easy-to-use doubly-linked list of nodes. It is implemented as a _circular_ list for efficiency and compactness

Second, the ?M_GList type is defined similarly to the GLib "GList*" type. A M_GList is a pointer to the head of a _linear_ doubly-linked list of nodes. It is NULL if the list is empty.


M_ListPool


  typedef struct M_ListPoolRec_*   M_ListPool;

handle to a list pool object. A List pool is a _static_ core object used to allocate and release list nodes efficiently.



M_ListNode


  typedef struct M_ListNodeRec_*      M_ListNode;

handle to a simple doubly-linked list node. see M_ListNodeRec



M_ListNodeRec


  typedef struct M_ListNodeRec_
  {
    M_ListNode  next;
    M_ListNode  prev;
    M_Pointer   data;

  } M_ListNodeRec;

a simple doubly-linked list node structure.


fields
next

handle to next node in list. NULL if last node

prev

handle to previous node in list. NULL if first node

data

generic pointer to listed element


M_CList


  typedef M_ListNode   M_CList;

a simple circular list node/item.

note that the same type is used for both the list head and a pointer to a list node.


note

in a circular list, the 'prev' and 'next' fields of each node _cannot_ be NULL.


M_List


  typedef struct M_ListRec_*           M_List;

handle to a simple doubly-linked list. see M_ListRec



M_ListRec


  typedef struct M_ListRec_
  {
    M_ListPool  pool;
    M_CList     head;

  } M_ListRec;

an easy-to-use _circular_ doubly-linked list structure.


fields
pool

the pool to use

head

handle to first list node. can be NULL


M_ListNodeFunc


  typedef void  (*M_ListNodeFunc)(  M_ListNode  node,
                                    M_Pointer   user_data );

a function used to process a given list node. For example, to delete its data member..


input
node

handle to the target list node

user_data

user-provided data


m_list_pool


  MLIB_API(M_ListPool)   m_list_pool( M_Memory  memory );

retrieves a handle to the current static list pool a list and destroy it.


input
memory

memory manager handle

return

handle to list pool

throws

m_err_memory_alloc (but very unlikely)


m_list_node_alloc


  MLIB_API(M_ListNode)
  m_list_node_alloc( M_ListPool  pool,
                     M_Pointer   data );

allocate a new list node


input
pool

handle to list pool

data

data for this list node

return

handle to new list node

throws

m_err_memory_alloc


m_list_node_free


  MLIB_API(void)
  m_list_node_free( M_ListNode  node,
                    M_ListPool  pool );

release a given list node


input
node

handle to target list node

pool

handle to list pool


m_clist_append_node


  MLIB_API(void)
  m_clist_append_node( M_CList*   list,
                       M_CList    node );

append a given node to an existing circular list


input
list

address of target list

node

handle to node


m_clist_prepend_node


  MLIB_API(void)
  m_clist_prepend_node( M_CList*  list,
                        M_CList   node );

prepend a given node to an existing circular list


input
list

address of target list

node

handle to node


m_clist_remove_node


  MLIB_API(void)
  m_clist_remove_node( M_CList*   list,
                       M_CList    node );

remove a given node from a circular list


input
list

address of target list

node

handle to node


M_CLIST


#define  M_CLIST(x)    ((M_CList)(x))

a useful macro to convert any pointer to a M_CList



M_CLIST_P


#define  M_CLIST_P(x)  ((M_CList*)(x))

a useful macro to convert any pointer to a pointer to a M_CList



m_clist_next


#define  m_clist_next(node)   ( (node) ? M_CLIST(node)->next : NULL )

returns the next node in a circular list. Note that if "node" is the last node in the list, this macro will return the first one.



m_clist_prev


#define  m_clist_prev(node)   ( (node) ? M_CLIST(node)->prev : NULL )

returns the previous node in a circular list. Note that if "node" is the first node in the list, this macro will return the last one.



m_clist_first


#define  m_clist_first(list)  (list)

returns the first node in a circular list, or NULL if it's empty



m_clist_last


#define  m_clist_last(list)   m_clist_prev(list)

returns the last node in a circular list, or NULL if it's empty



m_clist_append


  MLIB_API(void)
  m_clist_append( M_CList*    list,
                  M_Pointer   data,
                  M_ListPool  pool );

append a new node with given value to a circular list


input
list

address of target list

data

value for the new node

pool

handle to list pool used to allocate the new list node

throws

?m_err_mem_alloc


m_clist_prepend


  MLIB_API(void)
  m_clist_prepend( M_CList*    list,
                   M_Pointer   data,
                   M_ListPool  pool );

prepend a new node with given value to a circular list


input
list

address of target list

data

value for the new node

pool

handle to list pool used to allocate the new list node

throws

?m_err_mem_alloc


m_clist_find


  MLIB_API(M_CList)
  m_clist_find( const M_CList*  list,
                M_Pointer       data );

find an element with a given value in a circular list


input
list

address of list

data

value to lookup in list

return

list node, or NULL if not found


m_clist_remove


  MLIB_API(void)
  m_clist_remove( M_CList*     list,
                  M_Pointer    data,
                  M_ListPool   pool );

find a nod in a clist with specific data, and remove it


input
list

address of target list

data

value to lookup in the list

pool

handle to list pool used to allocate the new list node


m_clist_size


  MLIB_API(M_UInt)
  m_clist_size( const M_CList*  list );

returns the length in nodes of a given circular list


input
list

address of target list

return

list length


m_clist_foreach


  MLIB_API(void)
  m_clist_foreach( const M_CList*  list,
                   M_ListNodeFunc  node_func,
                   M_Pointer       node_data );

process each node in a list serially


input
list

address of target list

node_func

node function

node_data

user data passed to the node function

note

see also the macros M_CLIST_LOOP and ?M_CLIST_LOOP_END to be able to process a circular list efficiently..


m_clist_clear


  MLIB_API(void)
  m_clist_clear( M_CList*    list,
                 M_ListPool  pool );

clear a list, i.e. delete all its nodes. the list node data isn't touched.


input
list

address of target list

pool

list pool handle


m_clist_clear_custom


  MLIB_API(void)
  m_clist_clear_custom( M_CList*           list,
                        M_ListPool         pool,
                        M_DestroyDataFunc  destroy,
                        M_Pointer          destroy_data );

clear a list, i.e. delete all its nodes. the list node data is processed by a node function before each deletion.


input
list

address of target list

pool

list pool handle

destroy_func

node value destructor

destory_data

pointer passed to destructor


M_CLIST_LOOP


#define  M_CLIST_LOOP_ROOT( list )                       \
          {                                              \
            M_CList  __clist_first = M_CLIST(list);      \
            M_CList  __clist_node;                       \
            if (__clist_first)                           \
            {                                            \
              __clist_node = __clist_first;              \
              do                                         \
              {

#define  M_CLIST_LOOP( _list, _data )               \
            M_LOOP_CLIST_ROOT( _list )              \
            M_Pointer  _data = __clist_node->data;

this macro is used in association with M_CLIST_END to parse the content of a given M_CList.


input
list

the source list handle

data

the name of an _undefined_ variable that will be assigned the current node's value on each iteration.

note

it's ok to exit the loop with "break" or "return"

here's a simple usage example, it is used to print the list of values as signed integers

      M_CList    list = 0;

      ...

      printf( "listed values = [" );

      // note that "data" doesn't need to be defined before the loop !!

      M_CLIST_LOOP( list, data )
        printf( " %d", M_POINTER_TO_INT(data) );
      M_CLIST_END

M_CLIST_END


#define  M_CLIST_LOOP_END                                   \
                __clist_node = __clist_node->next;          \
              }                                             \
              while ( __clist_node != __clist_first );      \
            }                                               \
          }

this macro is used in association with M_CLIST_LOOP or ?M_CLIST_LOOP_NODE to parse the content of a given M_CList.


note

see the description of ?M_LOOP_CLIST for a usage example


m_list_init


  MLIB_API(void)  m_list_init( M_List    list,
                               M_Memory  memory );

initialize a given list from the current memory manager. this must be called before _any_ other operation on the list


input
list

handle to target list

memory

current memory manager handle

note

this function extracts the list pool from the current memory manager, and set it in "list->pool".


m_list_init_from_pool


  MLIB_API(void)  m_list_init_from_pool( M_List       list,
                                         M_ListPool  pool );

initialize a given list from the current list pool. this must be called before _any_ other operation on the list


input
list

handle to target list

pool

list pool handle


m_list_size


#define  m_list_size(list)   ( (list) ? m_clist_size( (list)->head ) : 0 )

returns the number of nodes in a list


input
list

handle to target list

return

number of elements


m_list_is_empty


#define  m_list_is_empty(list)  ( (list) ? (list)->head == 0 : 1 )

a macro that returns TRUE iff a list is empty



m_list_append


  MLIB_API(void)
  m_list_append( M_List     list,
                 M_Pointer  data );

append a given value to a list


input
list

target list

data

value for new list node

throws

m_err_memory_alloc


m_list_prepend


  MLIB_API(void)
  m_list_prepend( M_List     list,
                  M_Pointer  data );

prepend a given value to a list


input
list

target list

data

value for new list node

throws

m_err_memory_alloc


m_list_find


  MLIB_API(M_ListNode)
  m_list_find( M_List     list,
               M_Pointer  data );

parse a list to find the node corresponding to a given data


input
list

handle to target list

data

value to look for in list nodes

return

handle to list node. NULL if not found


m_list_remove


  MLIB_API(void)
  m_list_remove( M_List     list,
                 M_Pointer  data );

find a list node corresponding to a given value, remove it from a list and destroy it.


input
list

handle to target list

data

data to look for in list nodes


m_list_first


#define  m_list_first(list)  ( (list) ? (list)->head : NULL )

returns the first node of a list



m_list_last


#define  m_list_last(list)   ( (list) && (list)->head       \
                                ? (list)->head->prev : NULL )

returns the last node of a list



m_list_next


#define  m_list_next(node)  m_clist_next(node)

returns the next node of a list. Note that if the node is the last in the list, the macro will return the first node.



m_list_prev


#define  m_list_prev(node)  m_clist_prev(node)

returns the previous node of a list. Note that if the node is the first in the list, the macro will return the last node.



M_LIST_LOOP


#define  M_LIST_LOOP( _list, _data )                 \
            M_BEGIN_STMNT                            \
              m_assert( _list  );                    \
              M_CLIST_LOOP( (_list)->head, _data )

this macro is used in assocation with M_LIST_END . They are used to parse the content of a list simply. See the descriptions of M_CLIST_LOOP and M_CLIST_END for an idea of how to use them



M_LIST_END


#define  M_LIST_END                   \
                M_CLIST_END           \
            M_END_STMNT

this macro is used in assocation with M_LIST_LOOP . They are used to parse the content of a list simply. See the descriptions of M_CLIST_LOOP and M_CLIST_END for an idea of how to use them



m_list_append_node


#define  m_list_append_node( list, node )                  \
            M_BEGIN_STMNT                                  \
              m_assert( list );                            \
              m_clist_append_node( &(list)->head, node );  \
            M_END_STMNT

this macro is used to append a node to a given list.


input
list

handle to target list

node

node handle

note

this is defined as a macro rather than a function because an application should rarely use it in practice, and because it's such a thin wrapper around m_clist_append_node


m_list_prepend_node


#define  m_list_prepend_node( list, node )                  \
            M_BEGIN_STMNT                                   \
              m_assert( list );                             \
              m_clist_prepend_node( &(list)->head, node );  \
            M_END_STMNT

this macro is used to prepend a node to a given list.


input
list

handle to target list

node

node handle

note

this is defined as a macro rather than a function because an application should rarely use it in practice, and because it's such a thin wrapper around m_clist_prepend_node


m_list_remove_node


#define  m_list_remove_node( list, node )                  \
            M_BEGIN_STMNT                                  \
              m_assert( list );                            \
              m_clist_remove_node( &(list)->head, node );  \
            M_END_STMNT

this macro is used to prepend a node to a given list.


input
list

handle to target list

node

node handle

note

this is defined as a macro rather than a function because an application should rarely use it in practice, and because it's such a thin wrapper around m_clist_remove_node


m_list_clear


  MLIB_API(void)
  m_list_clear( M_List   list );

clear a list, i.e. destroy all its nodes (without touching their values).


input
list

handle to target list


m_list_clear_custom


  MLIB_API(void)
  m_list_clear_custom( M_List             list,
                       M_DestroyDataFunc  destroy_func,
                       M_Pointer          destroy_data );

clear a given list, i.e. remove its list node, using a node function


input
list

handle to target list

node_func

node function

node_data

user data passed to node function


generated on Tue Oct 09 23:59:46 2001