michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef jsclist_h michael@0: #define jsclist_h michael@0: michael@0: #include "jstypes.h" michael@0: michael@0: /* michael@0: ** Circular linked list michael@0: */ michael@0: typedef struct JSCListStr { michael@0: struct JSCListStr *next; michael@0: struct JSCListStr *prev; michael@0: } JSCList; michael@0: michael@0: /* michael@0: ** Insert element "_e" into the list, before "_l". michael@0: */ michael@0: #define JS_INSERT_BEFORE(_e,_l) \ michael@0: JS_BEGIN_MACRO \ michael@0: (_e)->next = (_l); \ michael@0: (_e)->prev = (_l)->prev; \ michael@0: (_l)->prev->next = (_e); \ michael@0: (_l)->prev = (_e); \ michael@0: JS_END_MACRO michael@0: michael@0: /* michael@0: ** Insert element "_e" into the list, after "_l". michael@0: */ michael@0: #define JS_INSERT_AFTER(_e,_l) \ michael@0: JS_BEGIN_MACRO \ michael@0: (_e)->next = (_l)->next; \ michael@0: (_e)->prev = (_l); \ michael@0: (_l)->next->prev = (_e); \ michael@0: (_l)->next = (_e); \ michael@0: JS_END_MACRO michael@0: michael@0: /* michael@0: ** Return the element following element "_e" michael@0: */ michael@0: #define JS_NEXT_LINK(_e) \ michael@0: ((_e)->next) michael@0: /* michael@0: ** Return the element preceding element "_e" michael@0: */ michael@0: #define JS_PREV_LINK(_e) \ michael@0: ((_e)->prev) michael@0: michael@0: /* michael@0: ** Append an element "_e" to the end of the list "_l" michael@0: */ michael@0: #define JS_APPEND_LINK(_e,_l) JS_INSERT_BEFORE(_e,_l) michael@0: michael@0: /* michael@0: ** Insert an element "_e" at the head of the list "_l" michael@0: */ michael@0: #define JS_INSERT_LINK(_e,_l) JS_INSERT_AFTER(_e,_l) michael@0: michael@0: /* Return the head/tail of the list */ michael@0: #define JS_LIST_HEAD(_l) (_l)->next michael@0: #define JS_LIST_TAIL(_l) (_l)->prev michael@0: michael@0: /* michael@0: ** Remove the element "_e" from it's circular list. michael@0: */ michael@0: #define JS_REMOVE_LINK(_e) \ michael@0: JS_BEGIN_MACRO \ michael@0: (_e)->prev->next = (_e)->next; \ michael@0: (_e)->next->prev = (_e)->prev; \ michael@0: JS_END_MACRO michael@0: michael@0: /* michael@0: ** Remove the element "_e" from it's circular list. Also initializes the michael@0: ** linkage. michael@0: */ michael@0: #define JS_REMOVE_AND_INIT_LINK(_e) \ michael@0: JS_BEGIN_MACRO \ michael@0: (_e)->prev->next = (_e)->next; \ michael@0: (_e)->next->prev = (_e)->prev; \ michael@0: (_e)->next = (_e); \ michael@0: (_e)->prev = (_e); \ michael@0: JS_END_MACRO michael@0: michael@0: /* michael@0: ** Return non-zero if the given circular list "_l" is empty, zero if the michael@0: ** circular list is not empty michael@0: */ michael@0: #define JS_CLIST_IS_EMPTY(_l) \ michael@0: ((_l)->next == (_l)) michael@0: michael@0: /* michael@0: ** Initialize a circular list michael@0: */ michael@0: #define JS_INIT_CLIST(_l) \ michael@0: JS_BEGIN_MACRO \ michael@0: (_l)->next = (_l); \ michael@0: (_l)->prev = (_l); \ michael@0: JS_END_MACRO michael@0: michael@0: #define JS_INIT_STATIC_CLIST(_l) \ michael@0: {(_l), (_l)} michael@0: michael@0: #endif /* jsclist_h */