Add operations to qlist to allow it to be used as a stack

This makes lists no longer invariant. It's a very useful bit of functionality
though.

To deal with the fact that lists are no longer invariant, introduce a deep
copy mechanism for lists.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Anthony Liguori 2009-11-11 10:48:51 -06:00
parent c99ca93142
commit 033815fe14
2 changed files with 60 additions and 0 deletions

56
qlist.c
View file

@ -37,6 +37,23 @@ QList *qlist_new(void)
return qlist;
}
static void qlist_copy_elem(QObject *obj, void *opaque)
{
QList *dst = opaque;
qobject_incref(obj);
qlist_append_obj(dst, obj);
}
QList *qlist_copy(QList *src)
{
QList *dst = qlist_new();
qlist_iter(src, qlist_copy_elem, dst);
return dst;
}
/**
* qlist_append_obj(): Append an QObject into QList
*
@ -67,6 +84,45 @@ void qlist_iter(const QList *qlist,
iter(entry->value, opaque);
}
QObject *qlist_pop(QList *qlist)
{
QListEntry *entry;
QObject *ret;
if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) {
return NULL;
}
entry = QTAILQ_FIRST(&qlist->head);
QTAILQ_REMOVE(&qlist->head, entry, next);
ret = entry->value;
qemu_free(entry);
return ret;
}
QObject *qlist_peek(QList *qlist)
{
QListEntry *entry;
QObject *ret;
if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) {
return NULL;
}
entry = QTAILQ_FIRST(&qlist->head);
ret = entry->value;
return ret;
}
int qlist_empty(const QList *qlist)
{
return QTAILQ_EMPTY(&qlist->head);
}
/**
* qobject_to_qlist(): Convert a QObject into a QList
*/

View file

@ -30,9 +30,13 @@ typedef struct QList {
qlist_append_obj(qlist, QOBJECT(obj))
QList *qlist_new(void);
QList *qlist_copy(QList *src);
void qlist_append_obj(QList *qlist, QObject *obj);
void qlist_iter(const QList *qlist,
void (*iter)(QObject *obj, void *opaque), void *opaque);
QObject *qlist_pop(QList *qlist);
QObject *qlist_peek(QList *qlist);
int qlist_empty(const QList *qlist);
QList *qobject_to_qlist(const QObject *obj);
#endif /* QLIST_H */