Several programs use linked lists of structures:
struct eksample {
<various declarations>;
struct eksample *e_next;
};
There are quite a few of these datastructures and each one uses its
own function that counts the number of elements in the linked list. Is
it possible to have just one function which may be used for all
structs and returns the number of elements in the linked list?
On the flip side, if you're willing to write a list interface that
uses a void* to point to an object, you can do something along these
lines.
\code snippet
/*!
* \struct c_list
* \brief The \c c_list struct is used as the list node for a
* double-linked list.
*/
struct c_list
{
/*!
* \brief The list node object, which can reference any type, and
* may point to a dynamically allocated object.
*/
void* object;
/*! \brief The link to the previous object in the list. */
struct c_list* prev;
/*! \brief The link to the next object in the list. */
struct c_list* next;
};
/*!
* \brief Get the number of objects in a \c c_list.
* \param list A \c c_list.
* \return The number of objects in the \c c_list.
*
* This function iterates over the whole list to count its objects,
* meaning that it can be slow for large lists.
*/
size_t c_list_length( struct c_list* list )
{
size_t length = 0;
while ( list ) /* equivalent to 'list != NULL' */
{
++length;
list = list->next;
}
return length;
}
\endcode
Whether you prefer linked lists that are embedded in the struct
object, or reference objects from a void* is a matter of preference,
with different pros and cons. Referencing an object from a void*
removes the need to use offsetof and other struct tricks to count
nodes in a list, and c_list_length will be the only function you ever
need to count objects in a double linked list stored using c_list
nodes. Of course this comes with a maintenance cost of manual type
casting (whether directly to the node object or packaging the cast
through a macro), and an extra level of indirection to access a list
node's data. GLib is an example library that uses this style of
linked list.
Best regards,
John D.