39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync/** @file
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * IPRT - Generic Doubly Linked List.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync */
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync/*
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2010-2011 Oracle Corporation
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync *
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * available from http://www.virtualbox.org. This file is free software;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * you can redistribute it and/or modify it under the terms of the GNU
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * General Public License (GPL) as published by the Free Software
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync *
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * The contents of this file may alternatively be used under the terms
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * of the Common Development and Distribution License Version 1.0
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * VirtualBox OSE distribution, in which case the provisions of the
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * CDDL are applicable instead of those of the GPL.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync *
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * You may elect to license modified versions of this file under the
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * terms and conditions of either the GPL or the CDDL or both.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync */
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync#ifndef ___iprt_list_h
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync#define ___iprt_list_h
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync#include <iprt/types.h>
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync/** @defgroup grp_rt_list RTList - Generic Doubly Linked List
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * @ingroup grp_rt
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * The list implementation is circular without any type wise distintion between
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * the list and its nodes. This can be confusing since the list head usually
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * resides in a different structure than the nodes, so care must be taken when
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * walking the list.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync *
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * @{
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync */
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsyncRT_C_DECLS_BEGIN
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync/**
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * A list node of a doubly linked list.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync */
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsynctypedef struct RTLISTNODE
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync{
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync /** Pointer to the next list node. */
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync struct RTLISTNODE *pNext;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync /** Pointer to the previous list node. */
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync struct RTLISTNODE *pPrev;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync} RTLISTNODE;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync/** Pointer to a list node. */
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsynctypedef RTLISTNODE *PRTLISTNODE;
3ad6e8aa4524ee7c68c5c623f1a5874d4d00d672vboxsync/** Pointer to a const list node. */
3ad6e8aa4524ee7c68c5c623f1a5874d4d00d672vboxsynctypedef RTLISTNODE const *PCRTLISTNODE;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync/** Pointer to a list node pointer. */
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsynctypedef PRTLISTNODE *PPRTLISTNODE;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
a5379812e95dfb90e15c9b44b45c7b1dffc61376vboxsync/** The anchor (head/tail) of a doubly linked list.
a5379812e95dfb90e15c9b44b45c7b1dffc61376vboxsync *
a5379812e95dfb90e15c9b44b45c7b1dffc61376vboxsync * @remarks Please use this instead of RTLISTNODE to indicate a list
a5379812e95dfb90e15c9b44b45c7b1dffc61376vboxsync * head/tail. It makes the code so much easier to read. Also,
a5379812e95dfb90e15c9b44b45c7b1dffc61376vboxsync * always mention the actual list node type(s) in the comment. */
a5379812e95dfb90e15c9b44b45c7b1dffc61376vboxsynctypedef RTLISTNODE RTLISTANCHOR;
a5379812e95dfb90e15c9b44b45c7b1dffc61376vboxsync/** Pointer to a doubly linked list anchor. */
a5379812e95dfb90e15c9b44b45c7b1dffc61376vboxsynctypedef RTLISTANCHOR *PRTLISTANCHOR;
3ad6e8aa4524ee7c68c5c623f1a5874d4d00d672vboxsync/** Pointer to a const doubly linked list anchor. */
3ad6e8aa4524ee7c68c5c623f1a5874d4d00d672vboxsynctypedef RTLISTANCHOR const *PCRTLISTANCHOR;
a5379812e95dfb90e15c9b44b45c7b1dffc61376vboxsync
a5379812e95dfb90e15c9b44b45c7b1dffc61376vboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync/**
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * Initialize a list.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param pList Pointer to an unitialised list.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync */
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsyncDECLINLINE(void) RTListInit(PRTLISTNODE pList)
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync{
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync pList->pNext = pList;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync pList->pPrev = pList;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync}
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync/**
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * Append a node to the end of the list.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param pList The list to append the node to.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param pNode The node to append.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync */
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsyncDECLINLINE(void) RTListAppend(PRTLISTNODE pList, PRTLISTNODE pNode)
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync{
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync pList->pPrev->pNext = pNode;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync pNode->pPrev = pList->pPrev;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync pNode->pNext = pList;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync pList->pPrev = pNode;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync}
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync/**
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * Add a node as the first element of the list.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param pList The list to prepend the node to.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param pNode The node to prepend.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync */
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsyncDECLINLINE(void) RTListPrepend(PRTLISTNODE pList, PRTLISTNODE pNode)
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync{
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync pList->pNext->pPrev = pNode;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync pNode->pNext = pList->pNext;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync pNode->pPrev = pList;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync pList->pNext = pNode;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync}
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
c80170800394cbf2746e3136b41886c2d11617aevboxsync/**
c80170800394cbf2746e3136b41886c2d11617aevboxsync * Inserts a node after the specified one.
c80170800394cbf2746e3136b41886c2d11617aevboxsync *
c80170800394cbf2746e3136b41886c2d11617aevboxsync * @param pCurNode The current node.
c80170800394cbf2746e3136b41886c2d11617aevboxsync * @param pNewNode The node to insert.
c80170800394cbf2746e3136b41886c2d11617aevboxsync */
c80170800394cbf2746e3136b41886c2d11617aevboxsyncDECLINLINE(void) RTListNodeInsertAfter(PRTLISTNODE pCurNode, PRTLISTNODE pNewNode)
c80170800394cbf2746e3136b41886c2d11617aevboxsync{
c80170800394cbf2746e3136b41886c2d11617aevboxsync RTListPrepend(pCurNode, pNewNode);
c80170800394cbf2746e3136b41886c2d11617aevboxsync}
c80170800394cbf2746e3136b41886c2d11617aevboxsync
c80170800394cbf2746e3136b41886c2d11617aevboxsync/**
c80170800394cbf2746e3136b41886c2d11617aevboxsync * Inserts a node before the specified one.
c80170800394cbf2746e3136b41886c2d11617aevboxsync *
c80170800394cbf2746e3136b41886c2d11617aevboxsync * @param pCurNode The current node.
c80170800394cbf2746e3136b41886c2d11617aevboxsync * @param pNewNode The node to insert.
c80170800394cbf2746e3136b41886c2d11617aevboxsync */
c80170800394cbf2746e3136b41886c2d11617aevboxsyncDECLINLINE(void) RTListNodeInsertBefore(PRTLISTNODE pCurNode, PRTLISTNODE pNewNode)
c80170800394cbf2746e3136b41886c2d11617aevboxsync{
c80170800394cbf2746e3136b41886c2d11617aevboxsync RTListAppend(pCurNode, pNewNode);
c80170800394cbf2746e3136b41886c2d11617aevboxsync}
c80170800394cbf2746e3136b41886c2d11617aevboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync/**
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * Remove a node from a list.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param pNode The node to remove.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync */
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsyncDECLINLINE(void) RTListNodeRemove(PRTLISTNODE pNode)
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync{
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync PRTLISTNODE pPrev = pNode->pPrev;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync PRTLISTNODE pNext = pNode->pNext;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync pPrev->pNext = pNext;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync pNext->pPrev = pPrev;
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync /* poison */
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync pNode->pNext = NULL;
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync pNode->pPrev = NULL;
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync}
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync/**
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * Checks if a node is the last element in the list.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @retval @c true if the node is the last element in the list.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @retval @c false otherwise
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param pList The list.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param pNode The node to check.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync */
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync#define RTListNodeIsLast(pList, pNode) ((pNode)->pNext == (pList))
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync/**
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * Checks if a node is the first element in the list.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @retval @c true if the node is the first element in the list.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @retval @c false otherwise.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param pList The list.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param pNode The node to check.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync */
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync#define RTListNodeIsFirst(pList, pNode) ((pNode)->pPrev == (pList))
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync/**
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync * Checks if a type converted node is actually the dummy element (@a pList).
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync *
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync * @retval @c true if the node is the dummy element in the list.
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync * @retval @c false otherwise.
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync *
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync * @param pList The list.
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync * @param pNodeStruct The node structure to check. Typically
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync * something obtained from RTListNodeGetNext() or
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync * RTListNodeGetPrev(). This is NOT a PRTLISTNODE
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync * but something that contains a RTLISTNODE member!
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync * @param Type Structure the list node is a member of.
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync * @param Member The list node member.
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync */
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync#define RTListNodeIsDummy(pList, pNode, Type, Member) \
99dfe084aaa87733b2e26f5f9a86054d0461ff60vboxsync ( (pNode) == RT_FROM_MEMBER((pList), Type, Member) )
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync/** @copydoc RTListNodeIsDummy */
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync#define RTListNodeIsDummyCpp(pList, pNode, Type, Member) \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync ( (pNode) == RT_FROM_CPP_MEMBER((pList), Type, Member) )
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync/**
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * Checks if a list is empty.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @retval @c true if the list is empty.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @retval @c false otherwise.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param pList The list to check.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync */
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync#define RTListIsEmpty(pList) ((pList)->pPrev == (pList))
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync/**
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * Returns the next node in the list.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @returns The next node.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param pCurNode The current node.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param Type Structure the list node is a member of.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param Member The list node member.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync */
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync#define RTListNodeGetNext(pCurNode, Type, Member) \
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync RT_FROM_MEMBER((pCurNode)->pNext, Type, Member)
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync/** @copydoc RTListNodeGetNext */
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync#define RTListNodeGetNextCpp(pCurNode, Type, Member) \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync RT_FROM_CPP_MEMBER((pCurNode)->pNext, Type, Member)
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync/**
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync * Returns the previous node in the list.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @returns The previous node.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param pCurNode The current node.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param Type Structure the list node is a member of.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param Member The list node member.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync */
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync#define RTListNodeGetPrev(pCurNode, Type, Member) \
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync RT_FROM_MEMBER((pCurNode)->pPrev, Type, Member)
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync/** @copydoc RTListNodeGetPrev */
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync#define RTListNodeGetPrevCpp(pCurNode, Type, Member) \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync RT_FROM_CPP_MEMBER((pCurNode)->pPrev, Type, Member)
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync/**
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * Returns the first element in the list (checks for empty list).
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @retval Pointer to the first list element.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @retval NULL if the list is empty.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param pList List to get the first element from.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param Type Structure the list node is a member of.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param Member The list node member.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync */
c80170800394cbf2746e3136b41886c2d11617aevboxsync#define RTListGetFirst(pList, Type, Member) \
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync (!RTListIsEmpty(pList) ? RTListNodeGetNext(pList, Type, Member) : NULL)
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync/** @copydoc RTListGetFirst */
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync#define RTListGetFirstCpp(pList, Type, Member) \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync (!RTListIsEmpty(pList) ? RTListNodeGetNextCpp(pList, Type, Member) : NULL)
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync/**
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * Returns the last element in the list (checks for empty list).
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @retval Pointer to the last list element.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @retval NULL if the list is empty.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync *
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param pList List to get the last element from.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param Type Structure the list node is a member of.
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync * @param Member The list node member.
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync */
c80170800394cbf2746e3136b41886c2d11617aevboxsync#define RTListGetLast(pList, Type, Member) \
46060a4bc5ef66ad6fb489730c6cfc34a414cfbfvboxsync (!RTListIsEmpty(pList) ? RTListNodeGetPrev(pList, Type, Member) : NULL)
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync/** @copydoc RTListGetLast */
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync#define RTListGetLastCpp(pList, Type, Member) \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync (!RTListIsEmpty(pList) ? RTListNodeGetPrevCpp(pList, Type, Member) : NULL)
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
c80170800394cbf2746e3136b41886c2d11617aevboxsync/**
c80170800394cbf2746e3136b41886c2d11617aevboxsync * Returns the next node in the list or NULL if the end has been reached.
c80170800394cbf2746e3136b41886c2d11617aevboxsync *
c80170800394cbf2746e3136b41886c2d11617aevboxsync * @returns The next node or NULL.
c80170800394cbf2746e3136b41886c2d11617aevboxsync *
c80170800394cbf2746e3136b41886c2d11617aevboxsync * @param pList The list @a pCurNode is linked on.
c80170800394cbf2746e3136b41886c2d11617aevboxsync * @param pCurNode The current node, of type @a Type.
c80170800394cbf2746e3136b41886c2d11617aevboxsync * @param Type Structure the list node is a member of.
c80170800394cbf2746e3136b41886c2d11617aevboxsync * @param Member The list node member.
c80170800394cbf2746e3136b41886c2d11617aevboxsync */
c80170800394cbf2746e3136b41886c2d11617aevboxsync#define RTListGetNext(pList, pCurNode, Type, Member) \
c80170800394cbf2746e3136b41886c2d11617aevboxsync ( (pCurNode)->Member.pNext != (pList) ? RT_FROM_MEMBER((pCurNode)->Member.pNext, Type, Member) : NULL )
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync/** @copydoc RTListGetNext */
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync#define RTListGetNextCpp(pList, pCurNode, Type, Member) \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync ( (pCurNode)->Member.pNext != (pList) ? RT_FROM_CPP_MEMBER((pCurNode)->Member.pNext, Type, Member) : NULL )
c80170800394cbf2746e3136b41886c2d11617aevboxsync
c80170800394cbf2746e3136b41886c2d11617aevboxsync/**
c80170800394cbf2746e3136b41886c2d11617aevboxsync * Returns the previous node in the list or NULL if the start has been reached.
c80170800394cbf2746e3136b41886c2d11617aevboxsync *
c80170800394cbf2746e3136b41886c2d11617aevboxsync * @returns The previous node or NULL.
c80170800394cbf2746e3136b41886c2d11617aevboxsync *
c80170800394cbf2746e3136b41886c2d11617aevboxsync * @param pList The list @a pCurNode is linked on.
c80170800394cbf2746e3136b41886c2d11617aevboxsync * @param pCurNode The current node, of type @a Type.
c80170800394cbf2746e3136b41886c2d11617aevboxsync * @param Type Structure the list node is a member of.
c80170800394cbf2746e3136b41886c2d11617aevboxsync * @param Member The list node member.
c80170800394cbf2746e3136b41886c2d11617aevboxsync */
c80170800394cbf2746e3136b41886c2d11617aevboxsync#define RTListGetPrev(pList, pCurNode, Type, Member) \
c80170800394cbf2746e3136b41886c2d11617aevboxsync ( (pCurNode)->Member.pPrev != (pList) ? RT_FROM_MEMBER((pCurNode)->Member.pPrev, Type, Member) : NULL )
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync/** @copydoc RTListGetPrev */
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync#define RTListGetPrevCpp(pList, pCurNode, Type, Member) \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync ( (pCurNode)->Member.pPrev != (pList) ? RT_FROM_CPP_MEMBER((pCurNode)->Member.pPrev, Type, Member) : NULL )
c80170800394cbf2746e3136b41886c2d11617aevboxsync
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync/**
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync * Enumerate the list in head to tail order.
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync *
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync * @param pList List to enumerate.
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync * @param pIterator The iterator variable name.
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync * @param Type Structure the list node is a member of.
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync * @param Member The list node member name.
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync */
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync#define RTListForEach(pList, pIterator, Type, Member) \
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync for (pIterator = RTListNodeGetNext(pList, Type, Member); \
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync !RTListNodeIsDummy(pList, pIterator, Type, Member); \
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync pIterator = RT_FROM_MEMBER((pIterator)->Member.pNext, Type, Member) )
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync/** @copydoc RTListForEach */
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync#define RTListForEachCpp(pList, pIterator, Type, Member) \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync for (pIterator = RTListNodeGetNextCpp(pList, Type, Member); \
9669a82ff71031b9586ec3afe066db7fb88c07fcvboxsync !RTListNodeIsDummyCpp(pList, pIterator, Type, Member); \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync pIterator = RT_FROM_CPP_MEMBER((pIterator)->Member.pNext, Type, Member) )
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync
f428528fc897b81a4b60f63128bb1b2067497f51vboxsync
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync/**
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync * Enumerate the list in head to tail order, safe against removal of the
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync * current node.
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync *
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync * @param pList List to enumerate.
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync * @param pIterator The iterator variable name.
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync * @param pIterNext The name of the variable saving the pointer to
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync * the next element.
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync * @param Type Structure the list node is a member of.
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync * @param Member The list node member name.
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync */
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync#define RTListForEachSafe(pList, pIterator, pIterNext, Type, Member) \
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync for (pIterator = RTListNodeGetNext(pList, Type, Member), \
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync pIterNext = RT_FROM_MEMBER((pIterator)->Member.pNext, Type, Member); \
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync !RTListNodeIsDummy(pList, pIterator, Type, Member); \
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync pIterator = pIterNext, \
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync pIterNext = RT_FROM_MEMBER((pIterator)->Member.pNext, Type, Member) )
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync/** @copydoc RTListForEachSafe */
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync#define RTListForEachSafeCpp(pList, pIterator, pIterNext, Type, Member) \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync for (pIterator = RTListNodeGetNextCpp(pList, Type, Member), \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync pIterNext = RT_FROM_CPP_MEMBER((pIterator)->Member.pNext, Type, Member); \
9669a82ff71031b9586ec3afe066db7fb88c07fcvboxsync !RTListNodeIsDummyCpp(pList, pIterator, Type, Member); \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync pIterator = pIterNext, \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync pIterNext = RT_FROM_CPP_MEMBER((pIterator)->Member.pNext, Type, Member) )
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync
99dfe084aaa87733b2e26f5f9a86054d0461ff60vboxsync/**
99dfe084aaa87733b2e26f5f9a86054d0461ff60vboxsync * Enumerate the list in reverse order (tail to head).
99dfe084aaa87733b2e26f5f9a86054d0461ff60vboxsync *
99dfe084aaa87733b2e26f5f9a86054d0461ff60vboxsync * @param pList List to enumerate.
99dfe084aaa87733b2e26f5f9a86054d0461ff60vboxsync * @param pIterator The iterator variable name.
99dfe084aaa87733b2e26f5f9a86054d0461ff60vboxsync * @param Type Structure the list node is a member of.
99dfe084aaa87733b2e26f5f9a86054d0461ff60vboxsync * @param Member The list node member name.
99dfe084aaa87733b2e26f5f9a86054d0461ff60vboxsync */
99dfe084aaa87733b2e26f5f9a86054d0461ff60vboxsync#define RTListForEachReverse(pList, pIterator, Type, Member) \
031810467d35a9c73b0a60263ea1b6e21fa3b7e4vboxsync for (pIterator = RTListNodeGetPrev(pList, Type, Member); \
99dfe084aaa87733b2e26f5f9a86054d0461ff60vboxsync !RTListNodeIsDummy(pList, pIterator, Type, Member); \
99dfe084aaa87733b2e26f5f9a86054d0461ff60vboxsync pIterator = RT_FROM_MEMBER((pIterator)->Member.pPrev, Type, Member) )
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync/** @copydoc RTListForEachReverse */
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync#define RTListForEachReverseCpp(pList, pIterator, Type, Member) \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync for (pIterator = RTListNodeGetPrevCpp(pList, Type, Member); \
9669a82ff71031b9586ec3afe066db7fb88c07fcvboxsync !RTListNodeIsDummyCpp(pList, pIterator, Type, Member); \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync pIterator = RT_FROM_CPP_MEMBER((pIterator)->Member.pPrev, Type, Member) )
99dfe084aaa87733b2e26f5f9a86054d0461ff60vboxsync
99dfe084aaa87733b2e26f5f9a86054d0461ff60vboxsync
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync/**
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync * Enumerate the list in reverse order (tail to head).
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync *
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync * @param pList List to enumerate.
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync * @param pIterator The iterator variable name.
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync * @param pIterPrev The name of the variable saving the pointer to
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync * the previous element.
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync * @param Type Structure the list node is a member of.
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync * @param Member The list node member name.
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync */
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync#define RTListForEachReverseSafe(pList, pIterator, pIterPrev, Type, Member) \
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync for (pIterator = RTListNodeGetPrev(pList, Type, Member), \
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync pIterPrev = RT_FROM_MEMBER((pIterator)->Member.pPrev, Type, Member); \
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync !RTListNodeIsDummy(pList, pIterator, Type, Member); \
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync pIterator = pIterPrev, \
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync pIterPrev = RT_FROM_MEMBER((pIterator)->Member.pPrev, Type, Member) )
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync/** @copydoc RTListForEachReverseSafe */
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync#define RTListForEachReverseSafeCpp(pList, pIterator, pIterPrev, Type, Member) \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync for (pIterator = RTListNodeGetPrevCpp(pList, Type, Member), \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync pIterPrev = RT_FROM_CPP_MEMBER((pIterator)->Member.pPrev, Type, Member); \
9669a82ff71031b9586ec3afe066db7fb88c07fcvboxsync !RTListNodeIsDummyCpp(pList, pIterator, Type, Member); \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync pIterator = pIterPrev, \
9033fe9eb36bf5df4f899338743e1259042c71a6vboxsync pIterPrev = RT_FROM_CPP_MEMBER((pIterator)->Member.pPrev, Type, Member) )
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync
f5df6e1305059bc0b3b08812aa23279103114ab8vboxsync
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync/**
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync * Move the given list to a new list header.
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync *
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync * @param pListDst The new list.
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync * @param pListSrc The list to move.
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync */
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsyncDECLINLINE(void) RTListMove(PRTLISTNODE pListDst, PRTLISTNODE pListSrc)
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync{
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync if (!RTListIsEmpty(pListSrc))
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync {
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync pListDst->pNext = pListSrc->pNext;
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync pListDst->pPrev = pListSrc->pPrev;
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync /* Adjust the first and last element links */
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync pListDst->pNext->pPrev = pListDst;
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync pListDst->pPrev->pNext = pListDst;
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync /* Finally remove the elements from the source list */
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync RTListInit(pListSrc);
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync }
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync}
c5245f029ba21b3152e4ba59394838bb5c09126bvboxsync
097af7772652819eddadc27c46ab4a8f830ab96avboxsync/**
097af7772652819eddadc27c46ab4a8f830ab96avboxsync * List concatenation.
097af7772652819eddadc27c46ab4a8f830ab96avboxsync *
097af7772652819eddadc27c46ab4a8f830ab96avboxsync * @returns nothing.
097af7772652819eddadc27c46ab4a8f830ab96avboxsync * @param pListDst The destination list.
097af7772652819eddadc27c46ab4a8f830ab96avboxsync * @param pListSrc The source list to concatenate.
097af7772652819eddadc27c46ab4a8f830ab96avboxsync */
097af7772652819eddadc27c46ab4a8f830ab96avboxsyncDECLINLINE(void) RTListConcatenate(PRTLISTANCHOR pListDst, PRTLISTANCHOR pListSrc)
097af7772652819eddadc27c46ab4a8f830ab96avboxsync{
097af7772652819eddadc27c46ab4a8f830ab96avboxsync if (!RTListIsEmpty(pListSrc))
097af7772652819eddadc27c46ab4a8f830ab96avboxsync {
097af7772652819eddadc27c46ab4a8f830ab96avboxsync PRTLISTNODE pFirst = pListSrc->pNext;
097af7772652819eddadc27c46ab4a8f830ab96avboxsync PRTLISTNODE pLast = pListSrc->pPrev;
097af7772652819eddadc27c46ab4a8f830ab96avboxsync
097af7772652819eddadc27c46ab4a8f830ab96avboxsync pListDst->pPrev->pNext = pFirst;
097af7772652819eddadc27c46ab4a8f830ab96avboxsync pFirst->pPrev = pListDst->pPrev;
097af7772652819eddadc27c46ab4a8f830ab96avboxsync pLast->pNext = pListDst;
097af7772652819eddadc27c46ab4a8f830ab96avboxsync pListDst->pPrev = pLast;
097af7772652819eddadc27c46ab4a8f830ab96avboxsync
097af7772652819eddadc27c46ab4a8f830ab96avboxsync /* Finally remove the elements from the source list */
097af7772652819eddadc27c46ab4a8f830ab96avboxsync RTListInit(pListSrc);
097af7772652819eddadc27c46ab4a8f830ab96avboxsync }
097af7772652819eddadc27c46ab4a8f830ab96avboxsync}
097af7772652819eddadc27c46ab4a8f830ab96avboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsyncRT_C_DECLS_END
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync/** @} */
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync
39c2e57acd25ad706e24d3eed2cba74905506db0vboxsync#endif