This commit is contained in:
parent
f4b28ffb6a
commit
580520d195
@ -15,6 +15,7 @@
|
||||
*/
|
||||
typedef struct ase_sll_t ase_sll_t;
|
||||
typedef struct ase_sll_node_t ase_sll_node_t;
|
||||
typedef enum ase_sll_walk_t ase_sll_walk_t;
|
||||
|
||||
struct ase_sll_node_t
|
||||
{
|
||||
@ -29,7 +30,13 @@ struct ase_sll_node_t
|
||||
|
||||
typedef void* (*ase_sll_copier_t) (ase_sll_t* sll, void* data, ase_size_t len);
|
||||
typedef void (*ase_sll_freeer_t) (ase_sll_t* sll, void* data, ase_size_t len);
|
||||
typedef int (*ase_sll_walker_t) (ase_sll_t* sll, ase_sll_node_t* node, void* arg);
|
||||
typedef ase_sll_walk_t (*ase_sll_walker_t) (ase_sll_t* sll, ase_sll_node_t* node, void* arg);
|
||||
|
||||
enum ase_sll_walk_t
|
||||
{
|
||||
ASE_SLL_WALK_STOP = 0,
|
||||
ASE_SLL_WALK_FORWARD = 1
|
||||
};
|
||||
|
||||
#define ASE_SLL_COPIER_INLINE ase_sll_copyinline
|
||||
|
||||
@ -85,6 +92,10 @@ void ase_sll_setcopier (
|
||||
ase_sll_copier_t copier /* a element copier */
|
||||
);
|
||||
|
||||
ase_sll_copier_t ase_sll_getcopier (
|
||||
ase_sll_t* sll /* a singly linked list */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME specifies how to destroy an element
|
||||
*
|
||||
@ -96,30 +107,51 @@ void ase_sll_setfreeer (
|
||||
ase_sll_freeer_t freeer /* a element freeer */
|
||||
);
|
||||
|
||||
ase_sll_freeer_t ase_sll_getfreeer (
|
||||
ase_sll_t* sll /* a singly linked list */
|
||||
);
|
||||
|
||||
/*
|
||||
* Returns the pointer to the extension area
|
||||
* NAME Gets the pointer to the extension area
|
||||
* RETURN the pointer to the extension area
|
||||
*/
|
||||
void* ase_sll_getextension (
|
||||
ase_sll_t* sll /* a singly linked list */
|
||||
);
|
||||
|
||||
/*
|
||||
* Gets the number of elements held in a singly linked list
|
||||
* RETURNS the number of elements the list holds
|
||||
* NAME Gets the number of elements held in a singly linked list
|
||||
* RETURN the number of elements the list holds
|
||||
*/
|
||||
ase_size_t ase_sll_getsize (
|
||||
ase_sll_t* sll /* a singly linked list */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME Gets the head(first) node
|
||||
* RETURN the tail node of a singly linked list
|
||||
*/
|
||||
ase_sll_node_t* ase_sll_gethead (
|
||||
ase_sll_t* sll /* a singly linked list */
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME Gets the tail(last) node
|
||||
* RETURN the tail node of a singly linked list
|
||||
*/
|
||||
ase_sll_node_t* ase_sll_gettail (
|
||||
ase_sll_t* sll /* a singly linked list */
|
||||
);
|
||||
|
||||
/* Inserts data before a positional node given */
|
||||
/*
|
||||
* NAME Inserts data before a positional node given
|
||||
*
|
||||
* DESCRIPTION
|
||||
* There is performance penalty unless the positional node is neither
|
||||
* the head node nor ASE_NULL. You should consider a different data
|
||||
* structure such as a doubly linked list if you need to insert data
|
||||
* into a random position.
|
||||
*/
|
||||
ase_sll_node_t* ase_sll_insert (
|
||||
ase_sll_t* sll /* a singly linked list */,
|
||||
ase_sll_node_t* pos /* a node before which a new node is inserted */,
|
||||
@ -127,14 +159,60 @@ ase_sll_node_t* ase_sll_insert (
|
||||
ase_size_t dlen /* the length of the data in bytes */
|
||||
);
|
||||
|
||||
/* Traverses s singly linked list */
|
||||
void ase_sll_walk (ase_sll_t* sll, ase_sll_walker_t walker, void* arg);
|
||||
ase_sll_node_t* ase_sll_pushhead (
|
||||
ase_sll_t* sll /* a singly linked list */,
|
||||
void* dptr,
|
||||
ase_size_t dlen
|
||||
);
|
||||
|
||||
ase_sll_node_t* ase_sll_pushtail (
|
||||
ase_sll_t* sll /* a singly linked list */,
|
||||
void* dptr,
|
||||
ase_size_t dlen
|
||||
);
|
||||
|
||||
void ase_sll_delete (
|
||||
ase_sll_t* sll,
|
||||
ase_sll_node_t* pos
|
||||
);
|
||||
|
||||
void ase_sll_pophead (
|
||||
ase_sll_t* sll
|
||||
);
|
||||
|
||||
void ase_sll_poptail (
|
||||
ase_sll_t* sll
|
||||
);
|
||||
|
||||
/*
|
||||
* NAME Traverses s singly linked list
|
||||
*
|
||||
* DESCRIPTION
|
||||
* A singly linked list allows uni-directional in-order traversal.
|
||||
* The ase_sll_walk() function traverses a singly linkked list from its
|
||||
* head node down to its tail node as long as the walker function returns
|
||||
* ASE_SLL_WALK_FORWARD. A walker can return ASE_SLL_WALK_STOP to cause
|
||||
* immediate stop of traversal.
|
||||
* For each node, the walker function is called and it is passed three
|
||||
* parameters: the singly linked list, the visiting node, and the
|
||||
* user-defined data passed as the third parameter in a call to the
|
||||
* ase_sll_walk() function.
|
||||
*/
|
||||
void ase_sll_walk (
|
||||
ase_sll_t* sll /* a singly linked list */,
|
||||
ase_sll_walker_t walker /* a user-defined walker function */,
|
||||
void* arg /* pointer to user-defined data */
|
||||
);
|
||||
|
||||
/*
|
||||
* Causes a singly linked list to copy in data to a node.
|
||||
* Use ASE_SLL_COPIER_INLINE instead.
|
||||
*/
|
||||
void* ase_sll_copyinline (ase_sll_t* sll, void* data, ase_size_t len);
|
||||
void* ase_sll_copyinline (
|
||||
ase_sll_t* sll /* a singly linked list */,
|
||||
void* data /* pointer to data to copy */ ,
|
||||
ase_size_t len /* length of data in bytes */
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -88,11 +88,21 @@ ase_sll_node_t* ase_sll_gettail (ase_sll_t* sll)
|
||||
return sll->tail;
|
||||
}
|
||||
|
||||
ase_sll_copier_t ase_sll_getcopier (ase_sll_t* sll)
|
||||
{
|
||||
return sll->copier;
|
||||
}
|
||||
|
||||
void ass_sll_setcopier (ase_sll_t* sll, ase_sll_copier_t copier)
|
||||
{
|
||||
sll->copier = copier;
|
||||
}
|
||||
|
||||
ase_sll_freeer_t ase_sll_getfreeer (ase_sll_t* sll)
|
||||
{
|
||||
return sll->freeer;
|
||||
}
|
||||
|
||||
void ase_sll_setfreeer (ase_sll_t* sll, ase_sll_freeer_t freeer)
|
||||
{
|
||||
sll->freeer = freeer;
|
||||
@ -154,6 +164,7 @@ ase_sll_node_t* ase_sll_insert (
|
||||
if (pos == sll->head) sll->head = n;
|
||||
else
|
||||
{
|
||||
/* take note of performance penalty */
|
||||
ase_sll_node_t* n2 = sll->head;
|
||||
while (n2->next != pos) n2 = n2->next;
|
||||
n2->next = n;
|
||||
@ -164,23 +175,54 @@ ase_sll_node_t* ase_sll_insert (
|
||||
return n;
|
||||
}
|
||||
|
||||
ase_sll_node_t* ase_sll_prepend (ase_sll_t* sll, void* data, ase_size_t size)
|
||||
ase_sll_node_t* ase_sll_pushhead (ase_sll_t* sll, void* data, ase_size_t size)
|
||||
{
|
||||
return ase_sll_insert (sll, sll->head, data, size);
|
||||
}
|
||||
|
||||
ase_sll_node_t* ase_sll_append (ase_sll_t* sll, void* data, ase_size_t size)
|
||||
ase_sll_node_t* ase_sll_pushtail (ase_sll_t* sll, void* data, ase_size_t size)
|
||||
{
|
||||
return ase_sll_insert (sll, ASE_NULL, data, size);
|
||||
}
|
||||
|
||||
void ase_sll_delete (ase_sll_t* sll, ase_sll_node_t* pos)
|
||||
{
|
||||
ASE_ASSERT (pos != ASE_NULL);
|
||||
|
||||
if (pos == sll->head)
|
||||
{
|
||||
sll->head = pos->next;
|
||||
if (sll->head == ASE_NULL) sll->tail = ASE_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* take note of performance penalty */
|
||||
ase_sll_node_t* n2 = sll->head;
|
||||
while (n2->next != pos) n2 = n2->next;
|
||||
n2->next = pos->next;
|
||||
if (pos == sll->tail) sll->tail = n2;
|
||||
}
|
||||
|
||||
sll->size--;
|
||||
}
|
||||
|
||||
void ase_sll_pophead (ase_sll_t* sll)
|
||||
{
|
||||
ase_sll_delete (sll, sll->head);
|
||||
}
|
||||
|
||||
void ase_sll_poptail (ase_sll_t* sll)
|
||||
{
|
||||
ase_sll_delete (sll, sll->tail);
|
||||
}
|
||||
|
||||
void ase_sll_walk (ase_sll_t* sll, ase_sll_walker_t walker, void* arg)
|
||||
{
|
||||
ase_sll_node_t* n = sll->head;
|
||||
|
||||
while (n != ASE_NULL)
|
||||
{
|
||||
walker (sll, n, arg);
|
||||
if (walker(sll,n,arg) == ASE_SLL_WALK_STOP) return;
|
||||
n = n->next;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user