File es_list.h¶
File List > cubrid > src > storage > es_list.h
Go to the documentation of this file
/*
* Copyright 2008 Search Solution Corporation
* Copyright 2016 CUBRID Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* es_list.h -
*
* Simple doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
#ifndef _ES_LIST_H_
#define _ES_LIST_H_
#ifdef __cplusplus
extern "C"
{
#endif
struct es_list_head
{
struct es_list_head *next, *prev;
};
typedef struct es_list_head es_list_head_t;
#define ES_LIST_HEAD_INIT(name) { &(name), &(name) }
#define ES_LIST_HEAD(name) \
struct es_list_head name = ES_LIST_HEAD_INIT(name)
#define ES_INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
#define ES_LIST_FIRST(name) (name)->next
#define ES_LIST_LAST(name) (name)->prev
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add (struct es_list_head *new_item, struct es_list_head *prev, struct es_list_head *next)
{
next->prev = new_item;
new_item->next = next;
new_item->prev = prev;
prev->next = new_item;
}
static inline void es_list_add (struct es_list_head *new_item, struct es_list_head *head)
{
__list_add (new_item, head, head->next);
}
static inline void es_list_add_tail (struct es_list_head *new_item, struct es_list_head *head)
{
__list_add (new_item, head->prev, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del (struct es_list_head *prev, struct es_list_head *next)
{
next->prev = prev;
prev->next = next;
}
static inline void es_list_del (struct es_list_head *entry)
{
__list_del (entry->prev, entry->next);
entry->next = entry->prev = 0;
}
static inline void es_list_del_init (struct es_list_head *entry)
{
__list_del (entry->prev, entry->next);
ES_INIT_LIST_HEAD (entry);
}
static inline int es_list_empty (struct es_list_head *head)
{
return head->next == head;
}
static inline void es_list_splice (struct es_list_head *list, struct es_list_head *head)
{
struct es_list_head *first = list->next;
if (first != list)
{
struct es_list_head *last = list->prev;
struct es_list_head *at = head->next;
first->prev = head;
head->next = first;
last->next = at;
at->prev = last;
}
}
#define ES_LIST_ENTRY(ptr, type, member) \
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
#define ES_LIST_FOR_EACH(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
#define ES_LIST_FOR_REVERSE_EACH(pos, head) \
for (pos = (head)->prev; pos != (head); pos = pos->prev)
#define ES_LIST_FOR_EACH_SAFE(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
#ifdef __cplusplus
}
#endif
#endif /* _ES_LIST_H_ */