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_t ase_sll_t;
|
||||||
typedef struct ase_sll_node_t ase_sll_node_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
|
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_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 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
|
#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 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
|
* 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 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 (
|
void* ase_sll_getextension (
|
||||||
ase_sll_t* sll /* a singly linked list */
|
ase_sll_t* sll /* a singly linked list */
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Gets the number of elements held in a singly linked list
|
* NAME Gets the number of elements held in a singly linked list
|
||||||
* RETURNS the number of elements the list holds
|
* RETURN the number of elements the list holds
|
||||||
*/
|
*/
|
||||||
ase_size_t ase_sll_getsize (
|
ase_size_t ase_sll_getsize (
|
||||||
ase_sll_t* sll /* a singly linked list */
|
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_node_t* ase_sll_gethead (
|
||||||
ase_sll_t* sll /* a singly linked list */
|
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_node_t* ase_sll_gettail (
|
||||||
ase_sll_t* sll /* a singly linked list */
|
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_node_t* ase_sll_insert (
|
||||||
ase_sll_t* sll /* a singly linked list */,
|
ase_sll_t* sll /* a singly linked list */,
|
||||||
ase_sll_node_t* pos /* a node before which a new node is inserted */,
|
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 */
|
ase_size_t dlen /* the length of the data in bytes */
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Traverses s singly linked list */
|
ase_sll_node_t* ase_sll_pushhead (
|
||||||
void ase_sll_walk (ase_sll_t* sll, ase_sll_walker_t walker, void* arg);
|
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.
|
* Causes a singly linked list to copy in data to a node.
|
||||||
* Use ASE_SLL_COPIER_INLINE instead.
|
* 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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -88,11 +88,21 @@ ase_sll_node_t* ase_sll_gettail (ase_sll_t* sll)
|
|||||||
return sll->tail;
|
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)
|
void ass_sll_setcopier (ase_sll_t* sll, ase_sll_copier_t copier)
|
||||||
{
|
{
|
||||||
sll->copier = 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)
|
void ase_sll_setfreeer (ase_sll_t* sll, ase_sll_freeer_t freeer)
|
||||||
{
|
{
|
||||||
sll->freeer = freeer;
|
sll->freeer = freeer;
|
||||||
@ -154,6 +164,7 @@ ase_sll_node_t* ase_sll_insert (
|
|||||||
if (pos == sll->head) sll->head = n;
|
if (pos == sll->head) sll->head = n;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* take note of performance penalty */
|
||||||
ase_sll_node_t* n2 = sll->head;
|
ase_sll_node_t* n2 = sll->head;
|
||||||
while (n2->next != pos) n2 = n2->next;
|
while (n2->next != pos) n2 = n2->next;
|
||||||
n2->next = n;
|
n2->next = n;
|
||||||
@ -164,23 +175,54 @@ ase_sll_node_t* ase_sll_insert (
|
|||||||
return n;
|
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);
|
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);
|
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)
|
void ase_sll_walk (ase_sll_t* sll, ase_sll_walker_t walker, void* arg)
|
||||||
{
|
{
|
||||||
ase_sll_node_t* n = sll->head;
|
ase_sll_node_t* n = sll->head;
|
||||||
|
|
||||||
while (n != ASE_NULL)
|
while (n != ASE_NULL)
|
||||||
{
|
{
|
||||||
walker (sll, n, arg);
|
if (walker(sll,n,arg) == ASE_SLL_WALK_STOP) return;
|
||||||
n = n->next;
|
n = n->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user