Xplace_for_ICCAD/thirdparty/flute/dl.h
2022-10-20 22:46:17 +08:00

185 lines
4.1 KiB
C++

#ifndef DL_H
#define DL_H
#include <string.h>
#include <stdlib.h>
namespace Flute {
typedef struct dl_el_s {
struct dl_el_s *prev, *next;
} dl_el;
typedef struct {
dl_el *first, *last;
unsigned int count;
} dl_s, *dl_t;
dl_t dl_alloc(void);
void dl_delete(dl_t dl, dl_el *el);
void dl_clear(dl_t dl);
void dl_concat(dl_t list1, dl_t list2);
void dl_sort(dl_t dl, size_t el_size, int(*compar)(void *, void *));
#define dl_length(dl) (dl)->count
#define dl_empty(dl) ((dl)->count <= 0)
#define dl_data(type, el) \
*(type*)(((dl_el*)(el))+1)
#define dl_data_p(type, el) \
((type*)(((dl_el*)(el))+1))
#define dl_forall(type, dl, data) \
{ \
dl_el *_el, *_next; \
dl_t _curr_dl = (dl); \
for (_el=_curr_dl->first; _el; _el=_next) { \
_next = _el->next; \
(data) = dl_data(type, _el);
#define dl_forall_p(type, dl, data_p) \
{ \
dl_el *_el, *_next; \
dl_t _curr_dl = (dl); \
for (_el=_curr_dl->first; _el; _el=_next) { \
_next = _el->next; \
(data_p) = dl_data_p(type, _el);
#define dl_current() _el
#define dl_delete_current() dl_delete(_curr_dl, _el)
#define dl_endfor \
} \
}
#define dl_forall_reverse(type, dl, data) \
{ \
dl_el *_el, *_next; \
dl_t _curr_dl = (dl); \
for (_el=_curr_dl->last; _el; _el=_next) { \
_next = _el->prev; \
(data) = dl_data(type, _el);
#define dl_forall_reverse_p(type, dl, data_p) \
{ \
dl_el *_el, *_next; \
dl_t _curr_dl = (dl); \
for (_el=_curr_dl->last; _el; _el=_next) { \
_next = _el->prev; \
(data_p) = dl_data_p(type, _el);
#define dl_first(type, dl) \
dl_data(type, (dl)->first)
#define dl_first_element(dl) (dl)->first
#define dl_last(type, dl) \
dl_data(type, (dl)->last)
#define dl_pop_first(type, dl, data) \
{ \
(data) = dl_first(type, dl); \
dl_delete((dl), (dl)->first); \
}
#define dl_pop_last(type, dl, data) \
{ (data) = dl_last(type, dl); dl_delete((dl), (dl)->last); }
#define dl_insert_before(type, dl, element, data) \
{ \
if ((element) == (dl)->first) { \
dl_prepend(type, dl, data); \
} else { \
dl_el *_el = (dl_el*) malloc(sizeof(dl_el)+sizeof(type)); \
if (!_el) { \
printf("Out of memory!!\n"); \
} else { \
memcpy(_el+1, &(data), sizeof(type)); \
_el->prev = (element)->prev; _el->next = (element); \
(element)->prev->next = _el; (element)->prev = _el; \
(dl)->count++; \
} \
} \
}
#define dl_insert_after(type, dl, element, data) \
{ \
if ((element) == (dl)->last) { \
dl_append(type, dl, data); \
} else { \
dl_el *_el = (dl_el*) malloc(sizeof(dl_el)+sizeof(type)); \
if (!_el) { \
printf("Out of memory!!\n"); \
} else { \
memcpy(_el+1, &(data), sizeof(type)); \
_el->next = (element)->next; _el->prev = (element); \
(element)->next->prev = _el; (element)->next = _el; \
(dl)->count++; \
} \
} \
}
#define dl_append(type, dl, data) \
{ \
dl_el *_el = (dl_el*) malloc(sizeof(dl_el)+sizeof(type)); \
if (!_el) { \
printf("Out of memory!!\n"); \
} else { \
memcpy(_el+1, &(data), sizeof(type)); \
_el->next = 0; \
if ((dl)->count <= 0) { \
_el->prev = 0; \
(dl)->first = (dl)->last = _el; \
(dl)->count = 1; \
} else { \
_el->prev = (dl)->last; \
(dl)->last->next = _el; \
(dl)->last = _el; \
(dl)->count++; \
} \
} \
}
#define dl_prepend(type, dl, data) \
{ \
dl_el *_el = (dl_el*) malloc(sizeof(dl_el)+sizeof(type)); \
if (!_el) { \
printf("Out of memory!!\n"); \
} else { \
memcpy(_el+1, &(data), sizeof(type)); \
_el->prev = 0; \
if ((dl)->count <= 0) { \
_el->next = 0; \
(dl)->first = (dl)->last = _el; \
(dl)->count = 1; \
} else { \
_el->next = (dl)->first; \
(dl)->first->prev = _el; \
(dl)->first = _el; \
(dl)->count++; \
} \
} \
}
#define dl_free(dl) \
{ \
dl_clear(dl); free(dl); dl = 0; \
}
#define dl_duplicate(dest, src, type) \
{ \
dest = dl_alloc(); \
type _data_el; \
dl_forall(type, src, _data_el) { \
dl_append(type, dest, _data_el); \
} dl_endfor; \
}
} // namespace Flute
#endif