EzC
Data Structures | Macros | Typedefs
ezc_list.h File Reference

Featureful singly linked list implementation. More...

#include "ezc/ezc_macro.h"
#include <stdarg.h>
#include <stddef.h>

Go to the source code of this file.

Data Structures

struct  ezc_list
 List item structure. More...
 

Macros

#define ezc_list_new(self, ...)   (ezc_list_new__((self), ##__VA_ARGS__, NULL))
 Initialize a list. More...
 
#define ezc_list_copy(orig)   (ezc_list_copy__((orig)))
 Create deep copy. More...
 
#define ezc_list_swap(a, b)   (ezc_list_swap__((a), (b)))
 Swap contents of two lists. More...
 
#define ezc_list_cat(self, ...)   (ezc_list_cat__((self), ##__VA_ARGS__, NULL))
 Join multiple lists (no new memory allocated). More...
 
#define ezc_list_delete(self, ...)
 Free given lists. More...
 
#define ezc_list_length(self)   (ezc_list_length__((self)))
 Length of list. More...
 
#define ezc_list_map(self, fn, ...)
 Apply function to each item of list. More...
 
#define ezc_list_get_index_of(self, head)   (ezc_list_get_index_of__((self), (head)))
 Get index of item. More...
 
#define ezc_list_get_at(self, n)   (ezc_list_get_at__((self), (n)))
 Get item at index n. More...
 
#define ezc_list_get_match(self, data)   (ezc_list_get_match_fn__((self), NULL, (data)))
 Get item matching given data (via != operator). More...
 
#define ezc_list_get_match_fn(self, neq, data)   (ezc_list_get_match_fn__((self), (neq), (data)))
 Get item matching given data (via custom comparison function). More...
 
#define ezc_list_push_at(self, n, ...)
 Push items to index n. More...
 
#define ezc_list_push_front(self, ...)
 Push items to the front. More...
 
#define ezc_list_push_back(self, ...)
 Push items to the back. More...
 
#define ezc_list_pop_at(self, n)   (ezc_list_pop_at__(&(self), (n)))
 Pop item at index n. More...
 
#define ezc_list_pop_front(self)   (ezc_list_pop_at__(&(self), 0))
 Pop first item. More...
 
#define ezc_list_pop_back(self)   (ezc_list_pop_at__(&(self), ezc_list_length__((self))-1))
 Pop last item. More...
 
#define ezc_list_pop_match(self, data)   (ezc_list_pop_match_fn__((self), NULL, (data)))
 Pop item matching given data (via != operator). More...
 
#define ezc_list_pop_match_fn(self, neq, data, ...)   (ezc_list_pop_match_fn__((self), (neq), (data)))
 Pop item matching given data (via custom comparison function). More...
 
#define ezc_list_erase_at(self, n)   (ezc_list_delete__(ezc_list_pop_at__(&(self), (n)), NULL))
 Erase item at index n. More...
 
#define ezc_list_erase_front(self)   (ezc_list_delete__(ezc_list_pop_at__(&(self), 0), NULL))
 Erase first item. More...
 
#define ezc_list_erase_back(self)
 Erase last item. More...
 
#define ezc_list_erase_match(self, data)   (ezc_list_delete__(ezc_list_pop_match_fn__((self), NULL, (data)), NULL))
 Erase item matching given data (via != operator). More...
 
#define ezc_list_erase_match_fn(self, neq, data, ...)   (ezc_list_delete__(ezc_list_pop_match_fn__((self), (neq), (data)), NULL))
 Erase item matching given data (via custom comparison function). More...
 

Typedefs

typedef struct ezc_list ezc_list
 List item structure. More...
 

Detailed Description

Featureful singly linked list implementation.

The included functions and macros allow for this module to be used like a stack, queue, or vector. Note to Contributors: I've found that when implementing macros, it is best to have the macros use the actual functions themselves.

Macro Definition Documentation

◆ ezc_list_cat

#define ezc_list_cat (   self,
  ... 
)    (ezc_list_cat__((self), ##__VA_ARGS__, NULL))

Join multiple lists (no new memory allocated).

Attach tail-to-head the given lists.

Parameters
selfezc_list * Pointer to the list you want to be the front-most.
...ezc_list * Pointers to other lists in the order that you want them to be appended.
Returns
ezc_list * The head of the new list, which should equal the first argument. Returns NULL if any problems occured.

◆ ezc_list_copy

#define ezc_list_copy (   orig)    (ezc_list_copy__((orig)))

Create deep copy.

Creates a deep copy of the provided list.

Parameters
origezc_list const * Pointer to the list that you want copied.
Returns
ezc_list * Pointer to allocated list. If provided list was NULL, returns NULL.

◆ ezc_list_delete

#define ezc_list_delete (   self,
  ... 
)
Value:
(ezc_list_delete__((self), ##__VA_ARGS__, NULL), \
SST_MAP(EZC_TO_ZERO, (self), ##__VA_ARGS__))

Free given lists.

Free the memory holding the lists. Also set the pointers to equal NULL to help prevent dangling pointers.

Parameters
selfezc_list * Pointer to a list.
...ezc_list * Optional pointers to additional lists to be freed.
Returns
N/A

◆ ezc_list_erase_at

#define ezc_list_erase_at (   self,
 
)    (ezc_list_delete__(ezc_list_pop_at__(&(self), (n)), NULL))

Erase item at index n.

Asserts that n must be not out-of-bounds.

Parameters
selfezc_list const * Pointer to a list.
nlong The index of the item you want to be erased.
Returns
N/A

◆ ezc_list_erase_back

#define ezc_list_erase_back (   self)
Value:
(ezc_list_delete__( \
ezc_list_pop_at__(&(self), ezc_list_length__((self))-1), \
NULL))

Erase last item.

Equivalent to ezc_list_erase_at(self, ezc_list_length(self)-1).

Parameters
selfezc_list const * Pointer to a list.
Returns
N/A

◆ ezc_list_erase_front

#define ezc_list_erase_front (   self)    (ezc_list_delete__(ezc_list_pop_at__(&(self), 0), NULL))

Erase first item.

Equivalent to ezc_list_erase_at(self, 0).

Parameters
selfezc_list const * Pointer to a list.
Returns
N/A

◆ ezc_list_erase_match

#define ezc_list_erase_match (   self,
  data 
)    (ezc_list_delete__(ezc_list_pop_match_fn__((self), NULL, (data)), NULL))

Erase item matching given data (via != operator).

Erase the first item in the list whose data matches what is provided.

Parameters
selfezc_list const * Pointer to a list.
datavoid const * Pointer to data that you want the erased item to match.
Returns
N/A

◆ ezc_list_erase_match_fn

#define ezc_list_erase_match_fn (   self,
  neq,
  data,
  ... 
)    (ezc_list_delete__(ezc_list_pop_match_fn__((self), (neq), (data)), NULL))

Erase item matching given data (via custom comparison function).

Erase the first item in the list whose data matches what is provided. When checking whether an item does or does not equal the provided data, use a custom comparison function.

Parameters
selfezc_list const * Pointer to a list.
neqPointer to a function. This function should accept two void const * arguments. It should return 0 if the two are equal, anything else otherwise.
datavoid const * Pointer to data that you want the erased item to match.
Returns
N/A

◆ ezc_list_get_at

#define ezc_list_get_at (   self,
 
)    (ezc_list_get_at__((self), (n)))

Get item at index n.

Asserts that n must be not out-of-bounds.

Parameters
selfezc_list const * Pointer to a list.
nlong Index you want to look at.
Returns
ezc_list * Pointer to the item at index n. Returns NULL if any problems occured.

◆ ezc_list_get_index_of

#define ezc_list_get_index_of (   self,
  head 
)    (ezc_list_get_index_of__((self), (head)))

Get index of item.

Out-of-bounds (negative) indices are this module's way of communicating errors or otherwise not finding the item.

Parameters
selfezc_list const * Pointer to the item in question.
headezc_list const * Pointer to the list containing the item self.
Returns
long The index of the item, assuming it was found. Returns -1 and pushes an EZC_LOG_WARN if the item was not found or if any other problems occured.

◆ ezc_list_get_match

#define ezc_list_get_match (   self,
  data 
)    (ezc_list_get_match_fn__((self), NULL, (data)))

Get item matching given data (via != operator).

Get the first item in the list whose data matches what is provided.

Parameters
selfezc_list const * Pointer to a list.
datavoid const * Pointer to data that you want the fetched item to match.
Returns
ezc_list * Pointer to the first matching item. Returns NULL if any problems occured.

◆ ezc_list_get_match_fn

#define ezc_list_get_match_fn (   self,
  neq,
  data 
)    (ezc_list_get_match_fn__((self), (neq), (data)))

Get item matching given data (via custom comparison function).

Get the first item in the list whose data matches what is provided. When checking whether an item does or does not equal the provided data, use a custom comparison function.

Parameters
selfezc_list const * Pointer to a list.
neqPointer to a function. This function should accept two void const * arguments. It should return 0 if the two are equal, anything else otherwise.
datavoid const * Pointer to data that you want the fetched item to match.
Returns
ezc_list * Pointer to the first matching item. Returns NULL if any problems occured.

◆ ezc_list_length

#define ezc_list_length (   self)    (ezc_list_length__((self)))

Length of list.

The use of signed long is encouraged so that overflow is easier to detect.

Parameters
selfezc_list const * Pointer to a list.
Returns
long Length of the given list.

◆ ezc_list_map

#define ezc_list_map (   self,
  fn,
  ... 
)
Value:
do { ezc_list *iter = (self); while (iter != NULL) { \
(fn)(iter->data, ##__VA_ARGS__); iter = iter->next; \
} } while(0)
List item structure.
Definition: ezc_list.h:50
void * data
Definition: ezc_list.h:53
struct ezc_list * next
Definition: ezc_list.h:56

Apply function to each item of list.

See fn documentation for how to design the function's interface.

Parameters
selfezc_list * Pointer to a list.
fnPointer to a function. The first argument of the function must accept a pointer to the type of item in the list self. The arguments that it accepts thereafter should match what you provide in the ....
...The arguments to be passed to fn following the pointer to the list item.
Returns
N/A

◆ ezc_list_new

#define ezc_list_new (   self,
  ... 
)    (ezc_list_new__((self), ##__VA_ARGS__, NULL))

Initialize a list.

Blank lists cannot be initialized. Attempting so will result in this function returning NULL. Populate the list by writing as many arguments as you want. For example, ezc_list *names = ezc_list_new("Adam", "Bob", "Carlos");

Parameters
selfvoid const * First item of the list. You must provide at least one argument to this function.
...void const * Optional additional list item arguments.
Returns
ezc_list * Pointer to allocated list.

◆ ezc_list_pop_at

#define ezc_list_pop_at (   self,
 
)    (ezc_list_pop_at__(&(self), (n)))

Pop item at index n.

Asserts that n must be not out-of-bounds.

Parameters
selfezc_list const * Pointer to a list.
nlong The index of the item you want to be popped.
Returns
ezc_list * Pointer to the item that got popped. Note: no memory is freed by this function. It is your responsability to free the popped item. Consider using ezc_list_erase_at if you don't want to worry about freeing memory yourself. Returns NULL if any problems occured.

◆ ezc_list_pop_back

#define ezc_list_pop_back (   self)    (ezc_list_pop_at__(&(self), ezc_list_length__((self))-1))

Pop last item.

Equivalent to ezc_list_pop_at(self, ezc_list_length(self)-1).

Parameters
selfezc_list const * Pointer to a list.
Returns
ezc_list * Pointer to the item that got popped. See ezc_list_pop_at documentation for more details.

◆ ezc_list_pop_front

#define ezc_list_pop_front (   self)    (ezc_list_pop_at__(&(self), 0))

Pop first item.

Equivalent to ezc_list_pop_at(self, 0).

Parameters
selfezc_list const * Pointer to a list.
Returns
ezc_list * Pointer to the item that got popped. See ezc_list_pop_at documentation for more details.

◆ ezc_list_pop_match

#define ezc_list_pop_match (   self,
  data 
)    (ezc_list_pop_match_fn__((self), NULL, (data)))

Pop item matching given data (via != operator).

Pop the first item in the list whose data matches what is provided.

Parameters
selfezc_list const * Pointer to a list.
datavoid const * Pointer to data that you want the popped item to match.
Returns
ezc_list * Pointer to the popped first matching item. Returns NULL if any problems occured. See ezc_list_pop_at documentation for more details regarding memory management.

◆ ezc_list_pop_match_fn

#define ezc_list_pop_match_fn (   self,
  neq,
  data,
  ... 
)    (ezc_list_pop_match_fn__((self), (neq), (data)))

Pop item matching given data (via custom comparison function).

Pop the first item in the list whose data matches what is provided. When checking whether an item does or does not equal the provided data, use a custom comparison function.

Parameters
selfezc_list const * Pointer to a list.
neqPointer to a function. This function should accept two void const * arguments. It should return 0 if the two are equal, anything else otherwise.
datavoid const * Pointer to data that you want the popped item to match.
Returns
ezc_list * Pointer to the popped first matching item. Returns NULL if any problems occured. See ezc_list_pop_at documentation for more details regarding memory management.

◆ ezc_list_push_at

#define ezc_list_push_at (   self,
  n,
  ... 
)
Value:
do { \
if ((self) == NULL) (self) = ezc_list_new__(__VA_ARGS__, NULL); \
else ezc_list_push_at__((self), (n), ##__VA_ARGS__, NULL); \
} while (0)

Push items to index n.

Asserts that n must be not out-of-bounds, with the exception of n == ezc_list_length(self). This case is valid and equivalent to ezc_list_push_back(self).

Parameters
selfezc_list const * Pointer to a list.
nlong Index you want the first pushed item to be at.
...void const * Data you want to be pushed to the list. Provide as many as you want.
Returns
N/A

◆ ezc_list_push_back

#define ezc_list_push_back (   self,
  ... 
)
Value:
do { \
if ((self) == NULL) (self) = ezc_list_new__(__VA_ARGS__, NULL); \
else ezc_list_push_at__((self), \
ezc_list_length((self)), \
##__VA_ARGS__, \
NULL); \
} while (0)
#define ezc_list_length(self)
Length of list.
Definition: ezc_list.h:146

Push items to the back.

Equivalent to ezc_list_push_at(self, ezc_list_length(self), ...).

Parameters
selfezc_list const * Pointer to a list.
...void const * Data you want to be pushed to the list. Provide as many as you want.
Returns
N/A

◆ ezc_list_push_front

#define ezc_list_push_front (   self,
  ... 
)
Value:
do { \
if ((self) == NULL) (self) = ezc_list_new__(__VA_ARGS__, NULL); \
else ezc_list_push_at__((self), 0, ##__VA_ARGS__, NULL); \
} while (0)

Push items to the front.

Equivalent to ezc_list_push_at(self, 0, ...).

Parameters
selfezc_list const * Pointer to a list.
...void const * Data you want to be pushed to the list. Provide as many as you want.
Returns
N/A

◆ ezc_list_swap

#define ezc_list_swap (   a,
 
)    (ezc_list_swap__((a), (b)))

Swap contents of two lists.

Neither list can be NULL. This can be used to switch two items in a list or switch what list each pointer is pointing to, for example.

Parameters
aezc_list * Pointer to a list.
bezc_list * Pointer to another list.
Returns
N/A

Typedef Documentation

◆ ezc_list

typedef struct ezc_list ezc_list

List item structure.

Because the first block stores the data, list items can in theory be case to the desired type, i.e. (char *) item. In practice, however, this is not recommended, do item->data instead.