summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorBardur Arantsson <bardur@scientician.net>2014-12-18 00:00:35 +0100
committerBardur Arantsson <bardur@scientician.net>2014-12-18 00:00:35 +0100
commit76d1d3f63fef965ba0a2d5ccea3408ad36e9ce4c (patch)
tree08b7758fc22456584b6fb3477c30bf569e79d500 /src/include
parentd34f472970e6a9fa2257a63ed40d021fc2c6f045 (diff)
Remove all uses of sglib
Diffstat (limited to 'src/include')
-rw-r--r--src/include/sglib.h1952
1 files changed, 0 insertions, 1952 deletions
diff --git a/src/include/sglib.h b/src/include/sglib.h
deleted file mode 100644
index 1a4780fa..00000000
--- a/src/include/sglib.h
+++ /dev/null
@@ -1,1952 +0,0 @@
-/*
-
- This is SGLIB version 1.0.3
-
- (C) by Marian Vittek, Bratislava, http://www.xref-tech.com/sglib, 2003-5
-
- License Conditions: You can use a verbatim copy (including this
- copyright notice) of sglib freely in any project, commercial or not.
- You can also use derivative forms freely under terms of Open Source
- Software license or under terms of GNU Public License. If you need
- to use a derivative form in a commercial project, or you need sglib
- under any other license conditions, contact the author.
-
-
-
-*/
-
-
-#ifndef _SGLIB__h_
-#define _SGLIB__h_
-
-/* the assert is used exclusively to write unexpected error messages */
-#include <assert.h>
-
-
-/* ---------------------------------------------------------------------------- */
-/* ---------------------------------------------------------------------------- */
-/* - LEVEL - 0 INTERFACE - */
-/* ---------------------------------------------------------------------------- */
-/* ---------------------------------------------------------------------------- */
-
-
-/* ---------------------------------------------------------------------------- */
-/* ------------------------------ STATIC ARRAYS ------------------------------- */
-/* ---------------------------------------------------------------------------- */
-
-/*
-
- Basic algorithms for sorting arrays. Multiple depending arrays can
- be rearranged using user defined 'elem_exchangers'
-
-*/
-
-/* HEAP - SORT (level 0) */
-
-#define SGLIB_ARRAY_SINGLE_HEAP_SORT(type, a, max, comparator) {\
- SGLIB_ARRAY_HEAP_SORT(type, a, max, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\
-}
-
-#define SGLIB_ARRAY_HEAP_SORT(type, a, max, comparator, elem_exchanger) {\
- int _k_;\
- for(_k_=(max)/2; _k_>=0; _k_--) {\
- SGLIB___ARRAY_HEAP_DOWN(type, a, _k_, max, comparator, elem_exchanger);\
- }\
- for(_k_=(max)-1; _k_>=0; _k_--) {\
- elem_exchanger(type, a, 0, _k_);\
- SGLIB___ARRAY_HEAP_DOWN(type, a, 0, _k_, comparator, elem_exchanger);\
- }\
-}
-
-#define SGLIB___ARRAY_HEAP_DOWN(type, a, ind, max, comparator, elem_exchanger) {\
- type _t_;\
- int _m_, _l_, _r_, _i_;\
- _i_ = (ind);\
- _m_ = _i_;\
- do {\
- _i_ = _m_; \
- _l_ = 2*_i_+1;\
- _r_ = _l_+1;\
- if (_l_ < (max)){\
- if (comparator(((a)[_m_]), ((a)[_l_])) < 0) _m_ = _l_;\
- if (_r_ < (max)) {\
- if (comparator(((a)[_m_]), ((a)[_r_])) < 0) _m_ = _r_;\
- }\
- }\
- if (_m_ != _i_) {\
- elem_exchanger(type, a, _i_, _m_);\
- }\
- } while (_m_ != _i_);\
-}
-
-
-/* QUICK - SORT (level 0) */
-
-#define SGLIB_ARRAY_SINGLE_QUICK_SORT(type, a, max, comparator) {\
- SGLIB_ARRAY_QUICK_SORT(type, a, max, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\
-}
-
-#define SGLIB_ARRAY_QUICK_SORT(type, a, max, comparator, elem_exchanger) {\
- int _i_, _j_, _p_, _stacki_, _start_, _end_;\
- /* can sort up to 2^64 elements */\
- int _startStack_[64]; \
- int _endStack_[64];\
- type _tmp_;\
- _startStack_[0] = 0;\
- _endStack_[0] = (max);\
- _stacki_ = 1;\
- while (_stacki_ > 0) {\
- _stacki_ --;\
- _start_ = _startStack_[_stacki_];\
- _end_ = _endStack_[_stacki_];\
- while (_end_ - _start_ > 2) {\
- _p_ = _start_;\
- _i_ = _start_ + 1;\
- _j_ = _end_ - 1;\
- while (_i_<_j_) {\
- for(; _i_<=_j_ && comparator(((a)[_i_]),((a)[_p_]))<=0; _i_++) ;\
- if (_i_ > _j_) {\
- /* all remaining elements lesseq than pivot */\
- elem_exchanger(type, a, _j_, _p_);\
- _i_ = _j_;\
- } else {\
- for(; _i_<=_j_ && comparator(((a)[_j_]),((a)[_p_]))>=0; _j_--) ;\
- if (_i_ > _j_) {\
- /* all remaining elements greater than pivot */\
- elem_exchanger(type, a, _j_, _p_);\
- _i_ = _j_;\
- } else if (_i_ < _j_) {\
- elem_exchanger(type, a, _i_, _j_);\
- if (_i_+2 < _j_) {_i_++; _j_--;}\
- else if (_i_+1 < _j_) _i_++;\
- }\
- }\
- }\
- /* O.K. i==j and pivot is on a[i] == a[j] */\
- /* handle recursive calls without recursion */\
- if (_i_-_start_ > 1 && _end_-_j_ > 1) {\
- /* two recursive calls, use array-stack */\
- if (_i_-_start_ < _end_-_j_-1) {\
- _startStack_[_stacki_] = _j_+1;\
- _endStack_[_stacki_] = _end_;\
- _stacki_ ++;\
- _end_ = _i_;\
- } else {\
- _startStack_[_stacki_] = _start_;\
- _endStack_[_stacki_] = _i_;\
- _stacki_ ++;\
- _start_ = _j_+1;\
- }\
- } else {\
- if (_i_-_start_ > 1) {\
- _end_ = _i_;\
- } else {\
- _start_ = _j_+1;\
- }\
- }\
- }\
- if (_end_ - _start_ == 2) {\
- if (comparator(((a)[_start_]),((a)[_end_-1])) > 0) {\
- elem_exchanger(type, a, _start_, _end_-1);\
- }\
- }\
- }\
-}
-
-/* BINARY SEARCH (level 0) */
-
-#define SGLIB_ARRAY_BINARY_SEARCH(type, a, start_index, end_index, key, comparator, found, result_index) {\
- int _kk_, _cc_, _ii_, _jj_, _ff_;\
- _ii_ = (start_index); \
- _jj_ = (end_index);\
- _ff_ = 0;\
- while (_ii_ <= _jj_ && _ff_==0) {\
- _kk_ = (_jj_+_ii_)/2;\
- _cc_ = comparator(((a)[_kk_]), (key));\
- if (_cc_ == 0) {\
- (result_index) = _kk_; \
- _ff_ = 1;\
- } else if (_cc_ < 0) {\
- _ii_ = _kk_+1;\
- } else {\
- _jj_ = _kk_-1;\
- }\
- }\
- if (_ff_ == 0) {\
- /* not found, but set its resulting place in the array */\
- (result_index) = _jj_+1;\
- }\
- (found) = _ff_;\
-}
-
-/* -------------------------------- queue (in an array) ------------------ */
-/* queue is a quadruple (a,i,j,dim) such that: */
-/* a is the array storing values */
-/* i is the index of the first used element in the array */
-/* j is the index of the first free element in the array */
-/* dim is the size of the array a */
-/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */
-
-#define SGLIB_QUEUE_INIT(type, a, i, j) { i = j = 0; }
-#define SGLIB_QUEUE_IS_EMPTY(type, a, i, j) ((i)==(j))
-#define SGLIB_QUEUE_IS_FULL(type, a, i, j, dim) ((i)==((j)+1)%(dim))
-#define SGLIB_QUEUE_FIRST_ELEMENT(type, a, i, j) (a[i])
-#define SGLIB_QUEUE_ADD_NEXT(type, a, i, j, dim) {\
- if (SGLIB_QUEUE_IS_FULL(type, a, i, j, dim)) assert(0 && "the queue is full");\
- (j) = ((j)+1) % (dim);\
-}
-#define SGLIB_QUEUE_ADD(type, a, elem, i, j, dim) {\
- a[j] = (elem);\
- SGLIB_QUEUE_ADD_NEXT(type, a, i, j, dim);\
-}
-#define SGLIB_QUEUE_DELETE_FIRST(type, a, i, j, dim) {\
- if (SGLIB_QUEUE_IS_EMPTY(type, a, i, j)) assert(0 && "the queue is empty");\
- (i) = ((i)+1) % (dim);\
-}
-#define SGLIB_QUEUE_DELETE(type, a, i, j, dim) {\
- SGLIB_QUEUE_DELETE_FIRST(type, a, i, j, dim);\
-}
-
-/* ----------------- priority queue (heap) (in an array) -------------------- */
-/* heap is a triple (a,i,dim) such that: */
-/* a is the array storing values */
-/* i is the index of the first free element in the array */
-/* dim is the size of the array a */
-/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */
-
-#define SGLIB_HEAP_INIT(type, a, i) { i = 0; }
-#define SGLIB_HEAP_IS_EMPTY(type, a, i) ((i)==0)
-#define SGLIB_HEAP_IS_FULL(type, a, i, dim) ((i)==(dim))
-#define SGLIB_HEAP_FIRST_ELEMENT(type, a, i) (a[0])
-#define SGLIB_HEAP_ADD_NEXT(type, a, i, dim, comparator, elem_exchanger) {\
- int _i_;\
- if (SGLIB_HEAP_IS_FULL(type, a, i, dim)) assert(0 && "the heap is full");\
- _i_ = (i)++;\
- while (_i_ > 0 && comparator(a[_i_/2], a[_i_]) < 0) {\
- elem_exchanger(type, a, (_i_/2), _i_);\
- _i_ = _i_/2;\
- }\
-}
-#define SGLIB_HEAP_ADD(type, a, elem, i, dim, comparator) {\
- if (SGLIB_HEAP_IS_FULL(type, a, i, dim)) assert(0 && "the heap is full");\
- a[i] = (elem);\
- SGLIB_HEAP_ADD_NEXT(type, a, i, dim, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\
-}
-#define SGLIB_HEAP_DELETE_FIRST(type, a, i, dim, comparator, elem_exchanger) {\
- if (SGLIB_HEAP_IS_EMPTY(type, a, i)) assert(0 && "the heap is empty");\
- (i)--;\
- a[0] = a[i];\
- SGLIB___ARRAY_HEAP_DOWN(type, a, 0, i, comparator, elem_exchanger);\
-}
-#define SGLIB_HEAP_DELETE(type, a, i, dim, comparator) {\
- SGLIB_HEAP_DELETE_FIRST(type, a, i, dim, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\
-}
-
-
-/* ----------------- hashed table of pointers (in an array) -------------------- */
-
-/*
-
- This hashed table is storing pointers to objects (not containers).
- In this table there is a one-to-one mapping between 'objects' stored
- in the table and indexes where they are placed. Each index is
- pointing to exactly one 'object' and each 'object' stored in the
- table occurs on exactly one index. Once an object is stored in the
- table, it can be represented via its index.
-
- In case of collision while adding an object the index shifted
- by SGLIB_HASH_TAB_SHIFT_CONSTANT (constant can be redefined)
-
- You can NOT delete an element from such hash table. The only
- justification (I can see) for this data structure is an exchange
- file format, having an index table at the beginning and then
- refering objects via indexes.
-
- !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!!
-
-*/
-
-#define SGLIB_HASH_TAB_INIT(type, table, dim) {\
- int _i_;\
- for(_i_ = 0; _i_ < (dim); _i_++) (table)[_i_] = NULL;\
-}
-
-#define SGLIB_HASH_TAB_ADD_IF_NOT_MEMBER(type, table, dim, elem, hash_function, comparator, member){\
- unsigned _pos_;\
- type *_elem_;\
- SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, _pos_, _elem_);\
- (member) = (table)[_pos_];\
- if (_elem_ == NULL) {\
- if ((table)[_pos_] != NULL) assert(0 && "the hash table is full");\
- (table)[_pos_] = (elem);\
- }\
-}
-
-#define SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, hash_function, comparator, resultIndex, resultMember) {\
- unsigned _i_;\
- int _count_;\
- type *_e_;\
- _count = 0;\
- _i_ = hash_function(elem);\
- _i_ %= (dim);\
- while ((_e_=(table)[_i_])!=NULL && comparator(_e_, (elem))!=0 && _count_<(dim)) {\
- _count_ ++;\
- _i_ = (_i_ + SGLIB_HASH_TAB_SHIFT_CONSTANT) % (dim);\
- }\
- (resultIndex) = _i_;\
- if (_count_ < (dim)) (resultMember) = _e_;\
- else (resultMember) = NULL;\
-}
-
-#define SGLIB_HASH_TAB_IS_MEMBER(type, table, dim, elem, hash_function, resultIndex) {\
- unsigned _i_;\
- int _c_;\
- type *_e_;\
- _count = 0;\
- _i_ = hash_function(elem);\
- _i_ %= (dim);\
- while ((_e_=(table)[_i_])!=NULL && _e_!=(elem) && _c_<(dim)) {\
- _c_ ++;\
- _i_ = (_i_ + SGLIB_HASH_TAB_SHIFT_CONSTANT) % (dim);\
- }\
- if (_e_==(elem)) (resultIndex) = _i_;\
- else (resultIndex) = -1;\
-}
-
-#define SGLIB_HASH_TAB_MAP_ON_ELEMENTS(type, table, dim, iteratedIndex, iteratedVariable, command) {\
- unsigned iteratedIndex;\
- type *iteratedVariable;\
- for(iteratedIndex=0; iteratedIndex < (dim); iteratedIndex++) {\
- iteratedVariable = (table)[iteratedIndex];\
- if (iteratedVariable != NULL) {command;}\
- }\
-}
-
-
-/* ---------------------------------------------------------------------------- */
-/* ------------------------- DYNAMIC DATA STRUCTURES -------------------------- */
-/* ---------------------------------------------------------------------------- */
-
-/* ------------------------------------ lists (level 0) --------------------- */
-
-#define SGLIB_LIST_ADD(type, list, elem, next) {\
- (elem)->next = (list);\
- (list) = (elem);\
-}
-
-#define SGLIB_LIST_CONCAT(type, first, second, next) {\
- if ((first)==NULL) {\
- (first) = (second);\
- } else {\
- type *_p_;\
- for(_p_ = (first); _p_->next!=NULL; _p_=_p_->next) ;\
- _p_->next = (second);\
- }\
-}
-
-#define SGLIB_LIST_DELETE(type, list, elem, next) {\
- type **_p_;\
- for(_p_ = &(list); *_p_!=NULL && *_p_!=(elem); _p_= &(*_p_)->next) ;\
- assert(*_p_!=NULL && "element is not member of the container, use DELETE_IF_MEMBER instead"!=NULL);\
- *_p_ = (*_p_)->next;\
-}
-
-#define SGLIB_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, next, member) {\
- type *_p_;\
- for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) != 0; _p_= _p_->next) ;\
- (member) = _p_;\
- if (_p_ == NULL) {\
- SGLIB_LIST_ADD(type, list, elem, next);\
- }\
-}
-
-#define SGLIB_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, next, member) {\
- type **_p_;\
- for(_p_ = &(list); *_p_!=NULL && comparator((*_p_), (elem)) != 0; _p_= &(*_p_)->next) ;\
- (member) = *_p_;\
- if (*_p_ != NULL) {\
- *_p_ = (*_p_)->next;\
- }\
-}
-
-#define SGLIB_LIST_IS_MEMBER(type, list, elem, next, result) {\
- type *_p_;\
- for(_p_ = (list); _p_!=NULL && _p_ != (elem); _p_= _p_->next) ;\
- (result) = (_p_!=NULL);\
-}
-
-#define SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, next, member) {\
- type *_p_;\
- for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) != 0; _p_= _p_->next) ;\
- (member) = _p_;\
-}
-
-#define SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command) {\
- type *_ne_;\
- type *iteratedVariable;\
- (iteratedVariable) = (list); \
- while ((iteratedVariable)!=NULL) {\
- _ne_ = (iteratedVariable)->next;\
- {command;};\
- (iteratedVariable) = _ne_;\
- }\
-}
-
-#define SGLIB_LIST_LEN(type, list, next, result) {\
- type *_ce_;\
- (result) = 0;\
- SGLIB_LIST_MAP_ON_ELEMENTS(type, list, _ce_, next, (result)++);\
-}
-
-#define SGLIB_LIST_REVERSE(type, list, next) {\
- type *_list_,*_tmp_,*_res_;\
- _list_ = (list);\
- _res_ = NULL;\
- while (_list_!=NULL) {\
- _tmp_ = _list_->next; _list_->next = _res_;\
- _res_ = _list_; _list_ = _tmp_;\
- }\
- (list) = _res_;\
-}
-
-#define SGLIB_LIST_SORT(type, list, comparator, next) {\
- /* a non-recursive merge sort on lists */\
- type *_r_;\
- type *_a_, *_b_, *_todo_, *_t_, **_restail_;\
- int _i_, _n_, _contFlag_;\
- _r_ = (list);\
- _contFlag_ = 1;\
- for(_n_ = 1; _contFlag_; _n_ = _n_+_n_) {\
- _todo_ = _r_; _r_ = NULL; _restail_ = &_r_; _contFlag_ =0;\
- while (_todo_!=NULL) {\
- _a_ = _todo_;\
- for(_i_ = 1, _t_ = _a_; _i_ < _n_ && _t_!=NULL; _i_++, _t_ = _t_->next) ;\
- if (_t_ ==NULL) {\
- *_restail_ = _a_;\
- break;\
- }\
- _b_ = _t_->next; _t_->next=NULL;\
- for(_i_ =1, _t_ = _b_; _i_<_n_ && _t_!=NULL; _i_++, _t_ = _t_->next) ;\
- if (_t_ ==NULL) {\
- _todo_ =NULL;\
- } else {\
- _todo_ = _t_->next; _t_->next=NULL;\
- }\
- /* merge */\
- while (_a_!=NULL && _b_!=NULL) {\
- if (comparator(_a_, _b_) < 0) {\
- *_restail_ = _a_; _restail_ = &(_a_->next); _a_ = _a_->next;\
- } else {\
- *_restail_ = _b_; _restail_ = &(_b_->next); _b_ = _b_->next;\
- }\
- }\
- if (_a_!=NULL) *_restail_ = _a_;\
- else *_restail_ = _b_;\
- while (*_restail_!=NULL) _restail_ = &((*_restail_)->next);\
- _contFlag_ =1;\
- }\
- }\
- (list) = _r_;\
-}
-
-/* --------------------------------- sorted list (level 0) --------------------- */
-/*
- All operations suppose that the list is sorted and they preserve
- this property.
-*/
-
-
-#define SGLIB_SORTED_LIST_ADD(type, list, elem, comparator, next) {\
- type **_e_;\
- int _cmpres_;\
- SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmpres_, _e_);\
- (elem)->next = *_e_;\
- *_e_ = (elem);\
-}
-
-#define SGLIB_SORTED_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, next, member) {\
- type **_e_;\
- int _cmp_res_;\
- SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmp_res_, _e_);\
- if (_cmp_res_ != 0) {\
- (elem)->next = *_e_;\
- *_e_ = (elem);\
- (member) = NULL;\
- } else {\
- (member) = *_e_;\
- }\
-}
-
-#define SGLIB_SORTED_LIST_DELETE(type, list, elem, next) {\
- SGLIB_LIST_DELETE(type, list, elem, next);\
-}
-
-#define SGLIB_SORTED_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, next, member) {\
- type **_e_;\
- int _cmp_res_;\
- SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmp_res_, _e_);\
- if (_cmp_res_ == 0) {\
- (member) = *_e_;\
- *_e_ = (*_e_)->next;\
- } else {\
- (member) = NULL;\
- }\
-}
-
-#define SGLIB_SORTED_LIST_FIND_MEMBER(type, list, elem, comparator, next, member) {\
- type *_p_;\
- int _cmpres_ = 1;\
- for(_p_ = (list); _p_!=NULL && (_cmpres_=comparator(_p_, (elem))) < 0; _p_=_p_->next) ;\
- if (_cmpres_ != 0) (member) = NULL;\
- else (member) = _p_;\
-}
-
-#define SGLIB_SORTED_LIST_IS_MEMBER(type, list, elem, comparator, next, result) {\
- type *_p_;\
- for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) < 0; _p_=_p_->next) ;\
- while (_p_ != NULL && _p_ != (elem) && comparator(_p_, (elem)) == 0) _p_=_p_->next;\
- (result) = (_p_ == (elem));\
-}
-
-#define SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, comparator_result, member_ptr) {\
- (comparator_result) = -1;\
- for((member_ptr) = &(list); \
- *(member_ptr)!=NULL && ((comparator_result)=comparator((*member_ptr), (elem))) < 0; \
- (member_ptr) = &(*(member_ptr))->next) ;\
-}
-
-#define SGLIB_SORTED_LIST_LEN(type, list, next, result) {\
- SGLIB_LIST_LEN(type, list, next, result);\
-}
-
-#define SGLIB_SORTED_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command) {\
- SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command);\
-}
-
-
-/* ------------------------------- double linked list (level 0) ------------------------- */
-/*
- Lists with back pointer to previous element. Those lists implements deletion
- of an element in a constant time.
-*/
-
-#define SGLIB___DL_LIST_CREATE_SINGLETON(type, list, elem, previous, next) {\
- (list) = (elem);\
- (list)->next = (list)->previous = NULL;\
-}
-
-#define SGLIB_DL_LIST_ADD_AFTER(type, place, elem, previous, next) {\
- if ((place) == NULL) {\
- SGLIB___DL_LIST_CREATE_SINGLETON(type, place, elem, previous, next);\
- } else {\
- (elem)->next = (place)->next;\
- (elem)->previous = (place);\
- (place)->next = (elem);\
- if ((elem)->next != NULL) (elem)->next->previous = (elem);\
- }\
-}
-
-#define SGLIB_DL_LIST_ADD_BEFORE(type, place, elem, previous, next) {\
- if ((place) == NULL) {\
- SGLIB___DL_LIST_CREATE_SINGLETON(type, place, elem, previous, next);\
- } else {\
- (elem)->next = (place);\
- (elem)->previous = (place)->previous;\
- (place)->previous = (elem);\
- if ((elem)->previous != NULL) (elem)->previous->next = (elem);\
- }\
-}
-
-#define SGLIB_DL_LIST_ADD(type, list, elem, previous, next) {\
- SGLIB_DL_LIST_ADD_BEFORE(type, list, elem, previous, next)\
-}
-
-#define SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, the_add_operation) {\
- type *_dlp_;\
- for(_dlp_ = (list); _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->previous) ;\
- if (_dlp_ == NULL && (list) != NULL) {\
- for(_dlp_ = (list)->next; _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->next) ;\
- }\
- (member) = _dlp_;\
- if (_dlp_ == NULL) {\
- the_add_operation(type, list, elem, previous, next);\
- }\
-}
-
-#define SGLIB_DL_LIST_ADD_BEFORE_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\
- SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD_BEFORE);\
-}
-
-#define SGLIB_DL_LIST_ADD_AFTER_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\
- SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD_AFTER);\
-}
-
-#define SGLIB_DL_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\
- SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD);\
-}
-
-#define SGLIB_DL_LIST_CONCAT(type, first, second, previous, next) {\
- if ((first)==NULL) {\
- (first) = (second);\
- } else if ((second)!=NULL) {\
- type *_dlp_;\
- for(_dlp_ = (first); _dlp_->next!=NULL; _dlp_=_dlp_->next) ;\
- SGLIB_DL_LIST_ADD_AFTER(type, _dlp_, second, previous, next);\
- }\
-}
-
-#define SGLIB_DL_LIST_DELETE(type, list, elem, previous, next) {\
- type *_l_;\
- _l_ = (list);\
- if (_l_ == (elem)) {\
- if ((elem)->previous != NULL) _l_ = (elem)->previous;\
- else _l_ = (elem)->next;\
- }\
- if ((elem)->next != NULL) (elem)->next->previous = (elem)->previous;\
- if ((elem)->previous != NULL) (elem)->previous->next = (elem)->next;\
- (list) = _l_;\
-}
-
-#define SGLIB_DL_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, previous, next, member) {\
- type *_dlp_;\
- for(_dlp_ = (list); _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->previous) ;\
- if (_dlp_ == NULL && (list) != NULL) {\
- for(_dlp_ = (list)->next; _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->next) ;\
- }\
- (member) = _dlp_;\
- if (_dlp_ != NULL) {\
- SGLIB_DL_LIST_DELETE(type, list, _dlp_, previous, next);\
- }\
-}
-
-#define SGLIB_DL_LIST_IS_MEMBER(type, list, elem, previous, next, result) {\
- type *_dlp_;\
- SGLIB_LIST_IS_MEMBER(type, list, elem, previous, result);\
- if (result == 0 && (list) != NULL) {\
- _dlp_ = (list)->next;\
- SGLIB_LIST_IS_MEMBER(type, _dlp_, elem, next, result);\
- }\
-}
-
-#define SGLIB_DL_LIST_FIND_MEMBER(type, list, elem, comparator, previous, next, member) {\
- type *_dlp_;\
- SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, previous, member);\
- if ((member) == NULL && (list) != NULL) {\
- _dlp_ = (list)->next;\
- SGLIB_LIST_FIND_MEMBER(type, _dlp_, elem, comparator, next, member);\
- }\
-}
-
-#define SGLIB_DL_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, previous, next, command) {\
- type *_dl_;\
- type *iteratedVariable;\
- if ((list)!=NULL) {\
- _dl_ = (list)->next;\
- SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, previous, command);\
- SGLIB_LIST_MAP_ON_ELEMENTS(type, _dl_, iteratedVariable, next, command);\
- }\
-}
-
-#define SGLIB_DL_LIST_SORT(type, list, comparator, previous, next) {\
- type *_dll_, *_dlp_, *_dlt_;\
- _dll_ = (list);\
- if (_dll_ != NULL) {\
- for(; _dll_->previous!=NULL; _dll_=_dll_->previous) ;\
- SGLIB_LIST_SORT(type, _dll_, comparator, next);\
- SGLIB___DL_LIST_CREATE_FROM_LIST(type, _dll_, previous, next);\
- (list) = _dll_;\
- }\
-}
-
-#define SGLIB_DL_LIST_GET_FIRST(type, list, previous, next, result) {\
- type *_dll_;\
- _dll_ = (list);\
- if (_dll_ != NULL) {\
- for(; _dll_->previous!=NULL; _dll_=_dll_->previous) ;\
- }\
- (result) = _dll_;\
-}
-
-#define SGLIB_DL_LIST_GET_LAST(type, list, previous, next, result) {\
- type *_dll_;\
- _dll_ = (list);\
- if (_dll_ != NULL) {\
- for(; _dll_->next!=NULL; _dll_=_dll_->next) ;\
- }\
- (result) = _dll_;\
-}
-
-#define SGLIB_DL_LIST_LEN(type, list, previous, next, result) {\
- type *_dl_;\
- int _r1_, _r2_;\
- if ((list)==NULL) {\
- (result) = 0;\
- } else {\
- SGLIB_LIST_LEN(type, list, previous, _r1_);\
- _dl_ = (list)->next;\
- SGLIB_LIST_LEN(type, _dl_, next, _r2_);\
- (result) = _r1_ + _r2_;\
- }\
-}
-
-#define SGLIB_DL_LIST_REVERSE(type, list, previous, next) {\
- type *_list_,*_nlist_,*_dlp_,*_dln_;\
- _list_ = (list);\
- if (_list_!=NULL) {\
- _nlist_ = _list_->next;\
- while (_list_!=NULL) {\
- _dln_ = _list_->next; \
- _dlp_ = _list_->previous; \
- _list_->next = _dlp_;\
- _list_->previous = _dln_;\
- _list_ = _dlp_;\
- }\
- while (_nlist_!=NULL) {\
- _dln_ = _nlist_->next; \
- _dlp_ = _nlist_->previous; \
- _nlist_->next = _dlp_;\
- _nlist_->previous = _dln_;\
- _nlist_ = _dln_;\
- }\
- }\
-}
-
-#define SGLIB___DL_LIST_CREATE_FROM_LIST(type, list, previous, next) {\
- type *_dlp_, *_dlt_;\
- _dlp_ = NULL;\
- for(_dlt_ = (list); _dlt_!=NULL; _dlt_ = _dlt_->next) {\
- _dlt_->previous = _dlp_;\
- _dlp_ = _dlt_;\
- }\
-}
-
-
-/* ------------------------------- binary tree traversal (level 0) -------------------- */
-
-
-#define SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, iteratedVariable, order, left, right, command) {\
- /* this is non-recursive implementation of tree traversal */\
- /* it maintains the path to the current node in the array '_path_' */\
- /* the _path_[0] contains the root of the tree; */\
- /* the _path_[_pathi_] contains the _current_element_ */\
- /* the macro does not use the _current_element_ after execution of command */\
- /* command can destroy it, it can free the element for example */\
- type *_path_[SGLIB_MAX_TREE_DEEP];\
- type *_right_[SGLIB_MAX_TREE_DEEP];\
- char _pass_[SGLIB_MAX_TREE_DEEP];\
- type *_cn_;\
- int _pathi_;\
- type *iteratedVariable;\
- _cn_ = (tree);\
- _pathi_ = 0;\
- while (_cn_!=NULL) {\
- /* push down to leftmost innermost element */\
- while(_cn_!=NULL) {\
- _path_[_pathi_] = _cn_;\
- _right_[_pathi_] = _cn_->right;\
- _pass_[_pathi_] = 0;\
- _cn_ = _cn_->left;\
- if (order == 0) {\
- iteratedVariable = _path_[_pathi_];\
- {command;}\
- }\
- _pathi_ ++;\
- if (_pathi_ >= SGLIB_MAX_TREE_DEEP) assert(0 && "the binary_tree is too deep");\
- }\
- do {\
- _pathi_ --;\
- if ((order==1 && _pass_[_pathi_] == 0)\
- || (order == 2 && (_pass_[_pathi_] == 1 || _right_[_pathi_]==NULL))) {\
- iteratedVariable = _path_[_pathi_];\
- {command;}\
- }\
- _pass_[_pathi_] ++;\
- } while (_pathi_>0 && _right_[_pathi_]==NULL) ;\
- _cn_ = _right_[_pathi_];\
- _right_[_pathi_] = NULL;\
- _pathi_ ++;\
- }\
-}
-
-#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, left, right, command) {\
- SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 1, left, right, command);\
-}
-
-#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS_PREORDER(type, tree, _current_element_, left, right, command) {\
- SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 0, left, right, command);\
-}
-
-#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS_POSTORDER(type, tree, _current_element_, left, right, command) {\
- SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 2, left, right, command);\
-}
-
-#define SGLIB___BIN_TREE_FIND_MEMBER(type, tree, elem, left, right, comparator, res) {\
- type *_s_;\
- int _c_;\
- _s_ = (tree);\
- while (_s_!=NULL) {\
- _c_ = comparator((elem), _s_);\
- if (_c_ < 0) _s_ = _s_->left;\
- else if (_c_ > 0) _s_ = _s_->right;\
- else break;\
- }\
- (res) = _s_;\
-}
-
-/* ---------------------------------------------------------------------------- */
-/* ---------------------------------------------------------------------------- */
-/* - LEVEL - 1 INTERFACE - */
-/* ---------------------------------------------------------------------------- */
-/* ---------------------------------------------------------------------------- */
-
-
-
-/* ---------------------------------------------------------------------------- */
-/* ------------------------------ STATIC ARRAYS ------------------------------- */
-/* ---------------------------------------------------------------------------- */
-
-/* ----------------------------- array sorting (level 1) ---------------------- */
-
-#define SGLIB_DEFINE_ARRAY_SORTING_PROTOTYPES(type, comparator) \
- extern void sglib_##type##_array_quick_sort(type *a, int max);\
- extern void sglib_##type##_array_heap_sort(type *a, int max);\
-
-
-#define SGLIB_DEFINE_ARRAY_SORTING_FUNCTIONS(type, comparator) \
- void sglib_##type##_array_quick_sort(type *a, int max) {\
- SGLIB_ARRAY_SINGLE_QUICK_SORT(type, a, max, comparator);\
- }\
- void sglib_##type##_array_heap_sort(type *a, int max) {\
- SGLIB_ARRAY_SINGLE_HEAP_SORT(type, a, max, comparator);\
- }\
-
-
-/* ----------------------------- array queue (level 1) ------------------- */
-/* sglib's queue is stored in a fixed sized array */
-/* queue_type MUST be a structure containing fields: */
-/* afield is the array storing elem_type */
-/* ifield is the index of the first element in the queue */
-/* jfield is the index of the first free element after the queue */
-/* dim is the size of the array afield */
-/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */
-
-
-#define SGLIB_DEFINE_QUEUE_PROTOTYPES(queue_type, elem_type, afield, ifield, jfield, dim) \
- extern void sglib_##queue_type##_init(queue_type *q); \
- extern int sglib_##queue_type##_is_empty(queue_type *q); \
- extern int sglib_##queue_type##_is_full(queue_type *q); \
- extern elem_type sglib_##queue_type##_first_element(queue_type *q); \
- extern elem_type *sglib_##queue_type##_first_element_ptr(queue_type *q); \
- extern void sglib_##queue_type##_add_next(queue_type *q); \
- extern void sglib_##queue_type##_add(queue_type *q, elem_type elem); \
- extern void sglib_##queue_type##_delete_first(queue_type *q); \
- extern void sglib_##queue_type##_delete(queue_type *q);
-
-
-#define SGLIB_DEFINE_QUEUE_FUNCTIONS(queue_type, elem_type, afield, ifield, jfield, dim) \
- void sglib_##queue_type##_init(queue_type *q) {\
- SGLIB_QUEUE_INIT(elem_type, q->afield, q->ifield, q->jfield);\
- }\
- int sglib_##queue_type##_is_empty(queue_type *q) {\
- return(SGLIB_QUEUE_IS_EMPTY(elem_type, q->afield, q->ifield, q->jfield));\
- }\
- int sglib_##queue_type##_is_full(queue_type *q) {\
- return(SGLIB_QUEUE_IS_FULL(elem_type, q->afield, q->ifield, q->jfield));\
- }\
- elem_type sglib_##queue_type##_first_element(queue_type *q) {\
- return(SGLIB_QUEUE_FIRST_ELEMENT(elem_type, q->afield, q->ifield, q->jfield));\
- }\
- elem_type *sglib_##queue_type##_first_element_ptr(queue_type *q) {\
- return(& SGLIB_QUEUE_FIRST_ELEMENT(elem_type, q->afield, q->ifield, q->jfield));\
- }\
- void sglib_##queue_type##_add_next(queue_type *q) {\
- SGLIB_QUEUE_ADD_NEXT(elem_type, q->afield, q->ifield, q->jfield, dim);\
- }\
- void sglib_##queue_type##_add(queue_type *q, elem_type elem) {\
- SGLIB_QUEUE_ADD(elem_type, q->afield, elem, q->ifield, q->jfield, dim);\
- }\
- void sglib_##queue_type##_delete_first(queue_type *q) {\
- SGLIB_QUEUE_DELETE_FIRST(elem_type, q->afield, q->ifield, q->jfield, dim);\
- }\
- void sglib_##queue_type##_delete(queue_type *q) {\
- SGLIB_QUEUE_DELETE_FIRST(elem_type, q->afield, q->ifield, q->jfield, dim);\
- }
-
-
-/* ------------------------ array heap (level 1) ------------------------- */
-/* sglib's heap is a priority queue implemented in a fixed sized array */
-/* heap_type MUST be a structure containing fields: */
-/* afield is the array of size dim storing elem_type */
-/* ifield is the index of the first free element after the queue */
-/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */
-
-
-#define SGLIB_DEFINE_HEAP_PROTOTYPES(heap_type, elem_type, afield, ifield, dim, comparator, elem_exchanger) \
- extern void sglib_##heap_type##_init(heap_type *q); \
- extern int sglib_##heap_type##_is_empty(heap_type *q); \
- extern int sglib_##heap_type##_is_full(heap_type *q); \
- extern elem_type sglib_##heap_type##_first_element(heap_type *q); \
- extern elem_type *sglib_##heap_type##_first_element_ptr(heap_type *q); \
- extern void sglib_##heap_type##_add_next(heap_type *q); \
- extern void sglib_##heap_type##_add(heap_type *q, elem_type elem); \
- extern void sglib_##heap_type##_delete_first(heap_type *q); \
- extern void sglib_##heap_type##_delete(heap_type *q)
-
-#define SGLIB_DEFINE_HEAP_FUNCTIONS(heap_type, elem_type, afield, ifield, dim, comparator, elem_exchanger) \
- void sglib_##heap_type##_init(heap_type *q) {\
- SGLIB_HEAP_INIT(elem_type, q->afield, q->ifield);\
- }\
- int sglib_##heap_type##_is_empty(heap_type *q) {\
- return(SGLIB_HEAP_IS_EMPTY(elem_type, q->afield, q->ifield));\
- }\
- int sglib_##heap_type##_is_full(heap_type *q) {\
- return(SGLIB_HEAP_IS_FULL(elem_type, q->afield, q->ifield));\
- }\
- elem_type sglib_##heap_type##_first_element(heap_type *q) {\
- return(SGLIB_HEAP_FIRST_ELEMENT(elem_type, q->afield, q->ifield));\
- }\
- elem_type *sglib_##heap_type##_first_element_ptr(heap_type *q) {\
- return(& SGLIB_HEAP_FIRST_ELEMENT(elem_type, q->afield, q->ifield));\
- }\
- void sglib_##heap_type##_add_next(heap_type *q) {\
- SGLIB_HEAP_ADD_NEXT(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\
- }\
- void sglib_##heap_type##_add(heap_type *q, elem_type elem) {\
- SGLIB_HEAP_ADD(elem_type, q->afield, elem, q->ifield, dim, comparator, elem_exchanger);\
- }\
- void sglib_##heap_type##_delete_first(heap_type *q) {\
- SGLIB_HEAP_DELETE_FIRST(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\
- }\
- void sglib_##heap_type##_delete(heap_type *q) {\
- SGLIB_HEAP_DELETE_FIRST(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\
- }
-
-
-/* ------------------------ hashed table (level 1) ------------------------- */
-/*
-
- sglib's hash table is an array storing directly pointers to objects (not containers).
- In this table there is a one-to-one mapping between 'objects' stored
- in the table and indexes where they are placed. Each index is
- pointing to exactly one 'object' and each 'object' stored in the
- table occurs on exactly one index. Once an object is stored in the
- table, it can be represented via its index.
-
- type - is the type of elements
- dim - is the size of the hash array
- hash_function - is a hashing function mapping type* to unsigned
- comparator - is a comparator on elements
-
- !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!!
-*/
-
-#define SGLIB_DEFINE_HASHED_TABLE_PROTOTYPES(type, dim, hash_function, comparator) \
- struct sglib_hashed_##type##_iterator {\
- int currentIndex;\
- int (*subcomparator)(type *, type *);\
- type *equalto;\
- };\
- extern void sglib_hashed_##type##_init(type *table[dim]);\
- extern int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member);\
- extern int sglib_hashed_##type##_is_member(type *table[dim], type *elem);\
- extern type * sglib_hashed_##type##_find_member(type *table[dim], type *elem);\
- extern type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]); \
- extern type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto); \
- extern type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it); \
- extern type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it);
-
-#define SGLIB_DEFINE_HASHED_TABLE_FUNCTIONS(type, dim, hash_function, comparator) \
- struct sglib_hashed_##type##_iterator {\
- int currentIndex;\
- type **table;\
- int (*subcomparator)(type *, type *);\
- type *equalto;\
- };\
- void sglib_hashed_##type##_init(type *table[dim]) {\
- SGLIB_HASH_TAB_INIT(type, table, dim);\
- }\
- int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member) {\
- SGLIB_HASH_TAB_ADD_IF_NOT_MEMBER(type, table, dim, elem, hash_function, comparator, *member);\
- }\
- int sglib_hashed_##type##_is_member(type *table[dim], type *elem) {\
- int ind;\
- SGLIB_HASH_TAB_IS_MEMBER(type, table, dim, elem, hash_function, ind);\
- return(ind != -1);\
- }\
- type * sglib_hashed_##type##_find_member(type *table[dim], type *elem) {\
- type *mmb;\
- int ind;\
- SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, hash_function, comparator, ind, mmb);\
- return(mmb);\
- }\
- type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto) {\
- int i;\
- it->table = table;\
- it->subcomparator = subcomparator;\
- it->equalto = equalto;\
- for(i=0; i<(dim) && table[i]==NULL; i++) ;\
- it->currentIndex = i;\
- if (i<(dim)) return(table[i]);\
- return(NULL);\
- }\
- type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]) {\
- sglib_hashed_##type##_it_init_on_equal(it, table, NULL, NULL);\
- }\
- type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it) {\
- return(table[it->currentIndex]);\
- }\
- type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it) {\
- i=it->currentIndex;\
- if (i<(dim)) {\
- for(i++; i<(dim) && table[i]==NULL; i++) ;\
- }\
- it->currentIndex = i;\
- if (i<(dim)) return(table[i]);\
- return(NULL);\
- }
-
-
-/* ------------------- hashed container (only for level 1) -------------------- */
-/*
- hashed container is a table of given fixed size containing another
- (dynamic) base container in each cell. Once an object should be
- inserted into the hashed container, a hash function is used to
- determine the cell where the object belongs and the object is
- inserted into the base container stored in this cell. Usually the
- base container is simply a list or a sorted list, but it can be a
- red-black tree as well.
-
- parameters:
- type - the type of the container stored in each cell.
- dim - the size of the hashed array
- hash_function - the hashing function hashing 'type *' to unsigned.
-
-*/
-
-#define SGLIB_DEFINE_HASHED_CONTAINER_PROTOTYPES(type, dim, hash_function) \
- struct sglib_hashed_##type##_iterator {\
- struct sglib_##type##_iterator containerIt;\
- type **table;\
- int currentIndex;\
- int (*subcomparator)(type *, type *);\
- type *equalto;\
- };\
- extern void sglib_hashed_##type##_init(type *table[dim]);\
- extern void sglib_hashed_##type##_add(type *table[dim], type *elem);\
- extern int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member);\
- extern void sglib_hashed_##type##_delete(type *table[dim], type *elem);\
- extern int sglib_hashed_##type##_delete_if_member(type *table[dim], type *elem, type **memb);\
- extern int sglib_hashed_##type##_is_member(type *table[dim], type *elem);\
- extern type * sglib_hashed_##type##_find_member(type *table[dim], type *elem);\
- extern type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]); \
- extern type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto); \
- extern type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it); \
- extern type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it);
-
-#define SGLIB_DEFINE_HASHED_CONTAINER_FUNCTIONS(type, dim, hash_function) \
- /*extern unsigned hash_function(type *elem);*/\
- void sglib_hashed_##type##_init(type *table[dim]) {\
- unsigned i;\
- for(i=0; i<(dim); i++) table[i] = NULL;\
- }\
- void sglib_hashed_##type##_add(type *table[dim], type *elem) {\
- unsigned i;\
- i = ((unsigned)hash_function(elem)) % (dim);\
- sglib_##type##_add(&(table)[i], elem);\
- }\
- int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member) {\
- unsigned i;\
- i = ((unsigned)hash_function(elem)) % (dim);\
- return(sglib_##type##_add_if_not_member(&(table)[i], elem, member));\
- }\
- void sglib_hashed_##type##_delete(type *table[dim], type *elem) {\
- unsigned i;\
- i = ((unsigned)hash_function(elem)) % (dim);\
- sglib_##type##_delete(&(table)[i], elem);\
- }\
- int sglib_hashed_##type##_delete_if_member(type *table[dim], type *elem, type **memb) {\
- unsigned i;\
- i = ((unsigned)hash_function(elem)) % (dim);\
- return(sglib_##type##_delete_if_member(&(table)[i], elem, memb));\
- }\
- int sglib_hashed_##type##_is_member(type *table[dim], type *elem) {\
- unsigned i;\
- i = ((unsigned)hash_function(elem)) % (dim);\
- return(sglib_##type##_is_member((table)[i], elem));\
- }\
- type * sglib_hashed_##type##_find_member(type *table[dim], type *elem) {\
- unsigned i;\
- i = ((unsigned)hash_function(elem)) % (dim);\
- return(sglib_##type##_find_member((table)[i], elem));\
- }\
- type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto) {\
- type *e;\
- it->table = table;\
- it->currentIndex = 0;\
- it->subcomparator = subcomparator;\
- it->equalto = equalto;\
- e = sglib_##type##_it_init_on_equal(&it->containerIt, table[it->currentIndex], it->subcomparator, it->equalto);\
- if (e==NULL) e = sglib_hashed_##type##_it_next(it);\
- return(e);\
- }\
- type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]) {\
- return(sglib_hashed_##type##_it_init_on_equal(it, table, NULL, NULL));\
- }\
- type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it) {\
- return(sglib_##type##_it_current(&it->containerIt));\
- }\
- type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it) {\
- type *e;\
- e = sglib_##type##_it_next(&it->containerIt);\
- while (e==NULL && (++(it->currentIndex))<(dim)) {\
- e = sglib_##type##_it_init_on_equal(&it->containerIt, it->table[it->currentIndex], it->subcomparator, it->equalto);\
- }\
- return(e);\
- }
-
-
-
-/* ---------------------------------------------------------------------------- */
-/* ------------------------- DYNAMIC DATA STRUCTURES -------------------------- */
-/* ---------------------------------------------------------------------------- */
-
-
-
-/* ------------------------------------ list (level 1) -------------------------------- */
-
-#define SGLIB_DEFINE_LIST_PROTOTYPES(type, comparator, next) \
- struct sglib_##type##_iterator {\
- type *currentelem;\
- type *nextelem;\
- int (*subcomparator)(type *, type *);\
- type *equalto;\
- };\
- extern void sglib_##type##_add(type **list, type *elem);\
- extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\
- extern void sglib_##type##_concat(type **first, type *second);\
- extern void sglib_##type##_delete(type **list, type *elem);\
- extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\
- extern int sglib_##type##_is_member(type *list, type *elem);\
- extern type *sglib_##type##_find_member(type *list, type *elem);\
- extern void sglib_##type##_sort(type **list);\
- extern int sglib_##type##_len(type *list);\
- extern void sglib_##type##_reverse(type **list);\
- extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \
- extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \
- extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \
- extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it);
-
-
-#define SGLIB_DEFINE_LIST_FUNCTIONS(type, comparator, next) \
- int sglib_##type##_is_member(type *list, type *elem) {\
- int result;\
- SGLIB_LIST_IS_MEMBER(type, list, elem, next, result);\
- return(result);\
- }\
- type *sglib_##type##_find_member(type *list, type *elem) {\
- type *result;\
- SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, next, result);\
- return(result);\
- }\
- int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\
- SGLIB_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, next, *member);\
- return(*member==NULL);\
- }\
- void sglib_##type##_add(type **list, type *elem) {\
- SGLIB_LIST_ADD(type, *list, elem, next);\
- }\
- void sglib_##type##_concat(type **first, type *second) {\
- SGLIB_LIST_CONCAT(type, *first, second, next);\
- }\
- void sglib_##type##_delete(type **list, type *elem) {\
- SGLIB_LIST_DELETE(type, *list, elem, next);\
- }\
- int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\
- SGLIB_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, next, *member);\
- return(*member!=NULL);\
- }\
- void sglib_##type##_sort(type **list) { \
- SGLIB_LIST_SORT(type, *list, comparator, next);\
- }\
- int sglib_##type##_len(type *list) {\
- int res;\
- SGLIB_LIST_LEN(type, list, next, res);\
- return(res);\
- }\
- void sglib_##type##_reverse(type **list) {\
- SGLIB_LIST_REVERSE(type, *list, next);\
- }\
- \
- type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\
- it->subcomparator = subcomparator;\
- it->equalto = equalto;\
- it->nextelem = list;\
- return(sglib_##type##_it_next(it));\
- }\
- type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\
- return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\
- }\
- type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\
- return(it->currentelem);\
- }\
- type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\
- type *ce, *eq;\
- int (*scp)(type *, type *);\
- ce = it->nextelem;\
- it->nextelem = NULL;\
- if (it->subcomparator != NULL) {\
- eq = it->equalto; \
- scp = it->subcomparator;\
- while (ce!=NULL && scp(ce, eq)!=0) ce = ce->next;\
- }\
- it->currentelem = ce;\
- if (ce != NULL) it->nextelem = ce->next;\
- return(ce);\
- }
-
-/* ----------------------------- sorted list (level 1) ----------------------------------- */
-
-
-#define SGLIB_DEFINE_SORTED_LIST_PROTOTYPES(type, comparator, next) \
- struct sglib_##type##_iterator {\
- type *currentelem;\
- type *nextelem;\
- int (*subcomparator)(type *, type *);\
- type *equalto;\
- };\
- extern void sglib_##type##_add(type **list, type *elem);\
- extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\
- extern void sglib_##type##_delete(type **list, type *elem);\
- extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\
- extern int sglib_##type##_is_member(type *list, type *elem);\
- extern type *sglib_##type##_find_member(type *list, type *elem);\
- extern int sglib_##type##_len(type *list);\
- extern void sglib_##type##_sort(type **list);\
- extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \
- extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \
- extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \
- extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it);
-
-
-#define SGLIB_DEFINE_SORTED_LIST_FUNCTIONS(type, comparator, next) \
- int sglib_##type##_is_member(type *list, type *elem) {\
- int result;\
- SGLIB_SORTED_LIST_IS_MEMBER(type, list, elem, comparator, next, result);\
- return(result);\
- }\
- type *sglib_##type##_find_member(type *list, type *elem) {\
- type *result;\
- SGLIB_SORTED_LIST_FIND_MEMBER(type, list, elem, comparator, next, result);\
- return(result);\
- }\
- int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\
- SGLIB_SORTED_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, next, *member);\
- return(*member==NULL);\
- }\
- void sglib_##type##_add(type **list, type *elem) {\
- SGLIB_SORTED_LIST_ADD(type, *list, elem, comparator, next);\
- }\
- void sglib_##type##_delete(type **list, type *elem) {\
- SGLIB_SORTED_LIST_DELETE(type, *list, elem, next);\
- }\
- int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\
- SGLIB_SORTED_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, next, *member);\
- return(*member!=NULL);\
- }\
- int sglib_##type##_len(type *list) {\
- int res;\
- SGLIB_SORTED_LIST_LEN(type, list, next, res);\
- return(res);\
- }\
- void sglib_##type##_sort(type **list) { \
- SGLIB_LIST_SORT(type, *list, comparator, next);\
- }\
- \
- type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\
- it->subcomparator = subcomparator;\
- it->equalto = equalto;\
- it->nextelem = list;\
- return(sglib_##type##_it_next(it));\
- }\
- type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\
- return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\
- }\
- type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\
- return(it->currentelem);\
- }\
- type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\
- type *ce, *eq;\
- int (*scp)(type *, type *);\
- int c;\
- ce = it->nextelem;\
- it->nextelem = NULL;\
- if (it->subcomparator != NULL) {\
- eq = it->equalto; \
- scp = it->subcomparator;\
- while (ce!=NULL && (c=scp(ce, eq)) < 0) ce = ce->next;\
- if (ce != NULL && c > 0) ce = NULL;\
- }\
- it->currentelem = ce;\
- if (ce != NULL) it->nextelem = ce->next;\
- return(ce);\
- }
-
-
-/* ----------------------------- double linked list (level 1) ------------------------------ */
-
-
-#define SGLIB_DEFINE_DL_LIST_PROTOTYPES(type, comparator, previous, next) \
- struct sglib_##type##_iterator {\
- type *currentelem;\
- type *prevelem;\
- type *nextelem;\
- int (*subcomparator)(type *, type *);\
- type *equalto;\
- };\
- extern void sglib_##type##_add(type **list, type *elem);\
- extern void sglib_##type##_add_before(type **list, type *elem);\
- extern void sglib_##type##_add_after(type **list, type *elem);\
- extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\
- extern int sglib_##type##_add_before_if_not_member(type **list, type *elem, type **member);\
- extern int sglib_##type##_add_after_if_not_member(type **list, type *elem, type **member);\
- extern void sglib_##type##_concat(type **first, type *second);\
- extern void sglib_##type##_delete(type **list, type *elem);\
- extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\
- extern int sglib_##type##_is_member(type *list, type *elem);\
- extern type *sglib_##type##_find_member(type *list, type *elem);\
- extern type *sglib_##type##_get_first(type *list);\
- extern type *sglib_##type##_get_last(type *list);\
- extern void sglib_##type##_sort(type **list);\
- extern int sglib_##type##_len(type *list);\
- extern void sglib_##type##_reverse(type **list);\
- extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \
- extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \
- extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \
- extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it);
-
-
-#define SGLIB_DEFINE_DL_LIST_FUNCTIONS(type, comparator, previous, next) \
- void sglib_##type##_add(type **list, type *elem) {\
- SGLIB_DL_LIST_ADD(type, *list, elem, previous, next);\
- }\
- void sglib_##type##_add_after(type **list, type *elem) {\
- SGLIB_DL_LIST_ADD_AFTER(type, *list, elem, previous, next);\
- }\
- void sglib_##type##_add_before(type **list, type *elem) {\
- SGLIB_DL_LIST_ADD_BEFORE(type, *list, elem, previous, next);\
- }\
- int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\
- SGLIB_DL_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\
- return(*member==NULL);\
- }\
- int sglib_##type##_add_after_if_not_member(type **list, type *elem, type **member) {\
- SGLIB_DL_LIST_ADD_AFTER_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\
- return(*member==NULL);\
- }\
- int sglib_##type##_add_before_if_not_member(type **list, type *elem, type **member) {\
- SGLIB_DL_LIST_ADD_BEFORE_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\
- return(*member==NULL);\
- }\
- void sglib_##type##_concat(type **first, type *second) {\
- SGLIB_DL_LIST_CONCAT(type, *first, second, previous, next);\
- }\
- void sglib_##type##_delete(type **list, type *elem) {\
- SGLIB_DL_LIST_DELETE(type, *list, elem, previous, next);\
- }\
- int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\
- SGLIB_DL_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, previous, next, *member);\
- return(*member!=NULL);\
- }\
- int sglib_##type##_is_member(type *list, type *elem) {\
- int result;\
- SGLIB_DL_LIST_IS_MEMBER(type, list, elem, previous, next, result);\
- return(result);\
- }\
- type *sglib_##type##_find_member(type *list, type *elem) {\
- type *result;\
- SGLIB_DL_LIST_FIND_MEMBER(type, list, elem, comparator, previous, next, result);\
- return(result);\
- }\
- type *sglib_##type##_get_first(type *list) {\
- type *result;\
- SGLIB_DL_LIST_GET_FIRST(type, list, previous, next, result);\
- return(result);\
- }\
- type *sglib_##type##_get_last(type *list) {\
- type *result;\
- SGLIB_DL_LIST_GET_LAST(type, list, previous, next, result);\
- return(result);\
- }\
- void sglib_##type##_sort(type **list) {\
- SGLIB_DL_LIST_SORT(type, *list, comparator, previous, next);\
- }\
- int sglib_##type##_len(type *list) {\
- int res;\
- SGLIB_DL_LIST_LEN(type, list, previous, next, res);\
- return(res);\
- }\
- void sglib_##type##_reverse(type **list) {\
- SGLIB_DL_LIST_REVERSE(type, *list, previous, next);\
- }\
- \
- type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\
- it->subcomparator = subcomparator;\
- it->equalto = equalto;\
- it->prevelem = list;\
- it->nextelem = list;\
- if (list != NULL) it->nextelem = list->next;\
- return(sglib_##type##_it_next(it));\
- }\
- type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\
- return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\
- }\
- type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\
- return(it->currentelem);\
- }\
- type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\
- type *ce, *eq;\
- int (*scp)(type *, type *);\
- ce = it->prevelem;\
- it->prevelem = NULL;\
- if (it->subcomparator != NULL) {\
- eq = it->equalto; \
- scp = it->subcomparator;\
- while (ce!=NULL && scp(eq, ce)!=0) ce = ce->previous;\
- }\
- if (ce != NULL) {\
- it->prevelem = ce->previous;\
- } else {\
- ce = it->nextelem;\
- it->nextelem = NULL;\
- if (it->subcomparator != NULL) {\
- eq = it->equalto; \
- scp = it->subcomparator;\
- while (ce!=NULL && scp(ce, eq)!=0) ce = ce->next;\
- }\
- if (ce != NULL) it->nextelem = ce->next;\
- }\
- it->currentelem = ce;\
- return(ce);\
- }
-
-
-/* --------------------------------- red-black trees (level 1) -------------------------------- */
-
-/*
-
-This implementation requires pointers to left and right sons (no
-parent pointer is needed) and one bit of additional information
-storing the color of the node. The implementation follows discrepancy
-fixing rules from:
-http://www.cis.ohio-state.edu/~gurari/course/cis680/cis680Ch11.html
-
-*/
-
-#define SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, leftt, rightt, bits, RED, BLACK) {\
- type *t, *tl, *a, *b, *c, *ar, *bl, *br, *cl, *cr;\
- t = *tree;\
- tl = t->leftt;\
- if (t->rightt!=NULL && SGLIB___GET_VALUE(t->rightt->bits)==RED) {\
- if (SGLIB___GET_VALUE(tl->bits)==RED) {\
- if ((tl->leftt!=NULL && SGLIB___GET_VALUE(tl->leftt->bits)==RED) \
- || (tl->rightt!=NULL && SGLIB___GET_VALUE(tl->rightt->bits)==RED)) {\
- SGLIB___SET_VALUE(t->leftt->bits,BLACK);\
- SGLIB___SET_VALUE(t->rightt->bits,BLACK);\
- SGLIB___SET_VALUE(t->bits,RED);\
- }\
- }\
- } else {\
- if (SGLIB___GET_VALUE(tl->bits)==RED) {\
- if (tl->leftt!=NULL && SGLIB___GET_VALUE(tl->leftt->bits)==RED) {\
- a = t; b = tl; c = tl->leftt;\
- br = b->rightt;\
- a->leftt = br;\
- b->leftt = c; b->rightt = a;\
- SGLIB___SET_VALUE(a->bits,RED);\
- SGLIB___SET_VALUE(b->bits,BLACK);\
- *tree = b;\
- } else if (tl->rightt!=NULL && SGLIB___GET_VALUE(tl->rightt->bits)==RED) {\
- a = t; b = tl; ar=a->rightt;\
- bl=b->leftt; c=b->rightt;\
- cl=c->leftt; cr=c->rightt;\
- b->rightt = cl;\
- a->leftt = cr;\
- c->leftt = b;\
- c->rightt = a;\
- SGLIB___SET_VALUE(c->bits,BLACK);\
- SGLIB___SET_VALUE(a->bits,RED);\
- *tree = c;\
- }\
- }\
- }\
-}
-
-#define SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, leftt, rightt, bits, RED, BLACK, res) {\
- type *t, *a, *b, *c, *d, *ar, *bl, *br, *cl, *cr, *dl, *dr;\
- t = a = *tree;\
- assert(t!=NULL);\
- ar = a->rightt;\
- b = t->leftt;\
- if (b==NULL) {\
- assert(SGLIB___GET_VALUE(t->bits)==RED);\
- SGLIB___SET_VALUE(t->bits,BLACK);\
- res = 0;\
- } else {\
- bl = b->leftt;\
- br = b->rightt;\
- if (SGLIB___GET_VALUE(b->bits)==RED) {\
- if (br==NULL) {\
- *tree = b;\
- SGLIB___SET_VALUE(b->bits,BLACK);\
- b->rightt = a;\
- a->leftt = br;\
- res = 0;\
- } else {\
- c = br;\
- assert(c!=NULL && SGLIB___GET_VALUE(c->bits)==BLACK);\
- cl = c->leftt;\
- cr = c->rightt;\
- if ((cl==NULL||SGLIB___GET_VALUE(cl->bits)==BLACK) && (cr==NULL||SGLIB___GET_VALUE(cr->bits)==BLACK)) {\
- *tree = b;\
- b->rightt = a;\
- SGLIB___SET_VALUE(b->bits,BLACK);\
- a->leftt = c;\
- SGLIB___SET_VALUE(c->bits,RED);\
- res = 0;\
- } else if (cl!=NULL && SGLIB___GET_VALUE(cl->bits)==RED) {\
- if (cr!=NULL && SGLIB___GET_VALUE(cr->bits)==RED) {\
- d = cr;\
- dl = d->leftt;\
- dr = d->rightt;\
- *tree = d;\
- SGLIB___SET_VALUE(d->bits,BLACK);\
- d->leftt = b;\
- c->rightt = dl;\
- d->rightt = a;\
- a->leftt = dr;\
- res = 0;\
- } else {\
- *tree = c;\
- c->leftt = b;\
- c->rightt = a;\
- b->leftt = bl;\
- b->rightt = cl;\
- a->leftt = cr;\
- SGLIB___SET_VALUE(cl->bits,BLACK);\
- res = 0;\
- }\
- } else if (cr!=NULL && SGLIB___GET_VALUE(cr->bits)==RED) {\
- assert(cl==NULL || SGLIB___GET_VALUE(cl->bits)==BLACK);\
- d = cr;\
- dl = d->leftt;\
- dr = d->rightt;\
- *tree = d;\
- SGLIB___SET_VALUE(d->bits,BLACK);\
- d->leftt = b;\
- c->rightt = dl;\
- d->rightt = a;\
- a->leftt = dr;\
- res = 0;\
- } else {\
- assert(0);\
- res = 0;\
- }\
- }\
- } else {\
- if ((bl==NULL || SGLIB___GET_VALUE(bl->bits)==BLACK) && (br==NULL || SGLIB___GET_VALUE(br->bits)==BLACK)) {\
- res = (SGLIB___GET_VALUE(a->bits)==BLACK);\
- SGLIB___SET_VALUE(a->bits,BLACK);\
- SGLIB___SET_VALUE(b->bits,RED);\
- } else if (bl!=NULL && SGLIB___GET_VALUE(bl->bits)==RED) {\
- if (br==NULL || SGLIB___GET_VALUE(br->bits)==BLACK) {\
- *tree = b;\
- SGLIB___SET_VALUE(b->bits,SGLIB___GET_VALUE(a->bits));\
- SGLIB___SET_VALUE(a->bits,BLACK);\
- b->rightt = a;\
- a->leftt = br;\
- SGLIB___SET_VALUE(bl->bits,BLACK);\
- res = 0;\
- } else {\
- assert(bl!=NULL);\
- assert(br!=NULL);\
- assert(SGLIB___GET_VALUE(bl->bits)==RED);\
- assert(SGLIB___GET_VALUE(br->bits)==RED);\
- c = br;\
- cl = c->leftt;\
- cr = c->rightt;\
- *tree = c;\
- SGLIB___SET_VALUE(c->bits,SGLIB___GET_VALUE(a->bits));\
- SGLIB___SET_VALUE(a->bits,BLACK);\
- c->leftt = b;\
- c->rightt = a;\
- b->rightt = cl;\
- a->leftt = cr;\
- res = 0;\
- }\
- } else {\
- assert(br!=NULL && SGLIB___GET_VALUE(br->bits)==RED);\
- c = br;\
- cl = c->leftt;\
- cr = c->rightt;\
- *tree = c;\
- SGLIB___SET_VALUE(c->bits,SGLIB___GET_VALUE(a->bits));\
- SGLIB___SET_VALUE(a->bits,BLACK);\
- c->leftt = b;\
- c->rightt = a;\
- b->rightt = cl;\
- a->leftt = cr;\
- res = 0;\
- }\
- }\
- }\
-}
-
-
-#define SGLIB_DEFINE_RBTREE_FUNCTIONS_GENERAL(type, left, right, bits, comparator, RED, BLACK) \
-static void sglib___##type##_fix_left_insertion_discrepancy(type **tree) {\
- SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, left, right, bits, RED, BLACK);\
-}\
-\
-static void sglib___##type##_fix_right_insertion_discrepancy(type **tree) {\
- SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, right, left, bits, RED, BLACK);\
-}\
-\
-static int sglib___##type##_fix_left_deletion_discrepancy(type **tree) {\
- int res;\
- SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, right, left, bits, RED, BLACK, res);\
- return(res);\
-}\
-\
-static int sglib___##type##_fix_right_deletion_discrepancy(type **tree) {\
- int res;\
- SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, left, right, bits, RED, BLACK, res);\
- return(res);\
-}\
-\
-static void sglib___##type##_add_recursive(type **tree, type *elem) {\
- int cmp;\
- type *t;\
- t = *tree;\
- if (t == NULL) {\
- SGLIB___SET_VALUE(elem->bits,RED);\
- *tree =elem;\
- } else {\
- cmp = comparator(elem, t);\
- if (cmp < 0 || (cmp==0 && elem<t)) {\
- sglib___##type##_add_recursive(&t->left, elem);\
- if (SGLIB___GET_VALUE(t->bits)==BLACK) sglib___##type##_fix_left_insertion_discrepancy(tree);\
- } else {\
- sglib___##type##_add_recursive(&t->right, elem);\
- if (SGLIB___GET_VALUE(t->bits)==BLACK) sglib___##type##_fix_right_insertion_discrepancy(tree);\
- }\
- }\
-}\
-\
-static int sglib___##type##_delete_rightmost_leaf(type **tree, type **theLeaf) {\
- type *t;\
- int res, deepDecreased;\
- t = *tree;\
- res = 0;\
- assert(t!=NULL);\
- if (t->right == NULL) {\
- *theLeaf = t;\
- if (t->left!=NULL) {\
- if (SGLIB___GET_VALUE(t->bits)==BLACK && SGLIB___GET_VALUE(t->left->bits)==BLACK) res = 1;\
- SGLIB___SET_VALUE(t->left->bits,BLACK);\
- *tree = t->left;\
- } else {\
- *tree = NULL;\
- res = (SGLIB___GET_VALUE(t->bits)==BLACK);\
- }\
- } else {\
- deepDecreased = sglib___##type##_delete_rightmost_leaf(&t->right, theLeaf);\
- if (deepDecreased) res = sglib___##type##_fix_right_deletion_discrepancy(tree);\
- }\
- return(res);\
-}\
-\
-int sglib___##type##_delete_recursive(type **tree, type *elem) {\
- type *t, *theLeaf;\
- int cmp, res, deepDecreased;\
- t = *tree;\
- res = 0;\
- if (t==NULL) {\
- assert(0 && "The element to delete not found in the tree, use 'delete_if_member'"!=NULL);\
- } else {\
- cmp = comparator(elem, t);\
- if (cmp < 0 || (cmp==0 && elem<t)) {\
- deepDecreased = sglib___##type##_delete_recursive(&t->left, elem);\
- if (deepDecreased) {\
- res = sglib___##type##_fix_left_deletion_discrepancy(tree);\
- }\
- } else if (cmp > 0 || (cmp==0 && elem>t)) {\
- deepDecreased = sglib___##type##_delete_recursive(&t->right, elem);\
- if (deepDecreased) {\
- res = sglib___##type##_fix_right_deletion_discrepancy(tree);\
- }\
- } else {\
- assert(elem==t && "Deleting an element which is non member of the tree, use 'delete_if_member'"!=NULL);\
- if (t->left == NULL) {\
- if (t->right == NULL) {\
- /* a leaf, delete, it; */\
- *tree = NULL;\
- res = (SGLIB___GET_VALUE(t->bits)==BLACK);\
- } else {\
- if (SGLIB___GET_VALUE(t->bits)==0 && SGLIB___GET_VALUE(t->right->bits)==0) res = 1;\
- SGLIB___SET_VALUE(t->right->bits,BLACK);\
- *tree = t->right;\
- }\
- } else {\
- /* propagate deletion until righmost leaf of left subtree */\
- deepDecreased = sglib___##type##_delete_rightmost_leaf(&t->left, &theLeaf);\
- theLeaf->left = t->left;\
- theLeaf->right = t->right;\
- SGLIB___SET_VALUE(theLeaf->bits,SGLIB___GET_VALUE(t->bits));\
- *tree = theLeaf;\
- if (deepDecreased) res = sglib___##type##_fix_left_deletion_discrepancy(tree);\
- }\
- }\
- }\
- return(res);\
-}\
-\
-void sglib_##type##_add(type **tree, type *elem) {\
- elem->left = elem->right = NULL;\
- sglib___##type##_add_recursive(tree, elem);\
- SGLIB___SET_VALUE((*tree)->bits,BLACK);\
-}\
-\
-void sglib_##type##_delete(type **tree, type *elem) {\
- sglib___##type##_delete_recursive(tree, elem);\
- if (*tree!=NULL) SGLIB___SET_VALUE((*tree)->bits,BLACK);\
-}\
-\
-type *sglib_##type##_find_member(type *t, type *elem) {\
- type *res;\
- SGLIB___BIN_TREE_FIND_MEMBER(type, t, elem, left, right, comparator, res);\
- return(res);\
-}\
-\
-int sglib_##type##_is_member(type *t, type *elem) {\
- int cmp;\
- while (t!=NULL) {\
- cmp = comparator(elem, t);\
- if (cmp < 0 || (cmp==0 && elem<t)) {\
- t = t->left;\
- } else if (cmp > 0 || (cmp==0 && elem>t)) {\
- t = t->right;\
- } else {\
- assert(t == elem);\
- return(1);\
- }\
- }\
- return(0);\
-}\
-\
-int sglib_##type##_delete_if_member(type **tree, type *elem, type **memb) {\
- if ((*memb=sglib_##type##_find_member(*tree, elem))!=NULL) {\
- sglib_##type##_delete(tree, *memb);\
- return(1);\
- } else {\
- return(0);\
- }\
-}\
-int sglib_##type##_add_if_not_member(type **tree, type *elem, type **memb) {\
- if ((*memb=sglib_##type##_find_member(*tree, elem))==NULL) {\
- sglib_##type##_add(tree, elem);\
- return(1);\
- } else {\
- return(0);\
- }\
-}\
-int sglib_##type##_len(type *t) {\
- int n;\
- type *e;\
- n = 0;\
- SGLIB_BIN_TREE_MAP_ON_ELEMENTS(type, t, e, left, right, n++);\
- return(n);\
-}\
-\
-void sglib__##type##_it_compute_current_elem(struct sglib_##type##_iterator *it) {\
- int i,j,cmp;\
- type *s, *eqt;\
- int (*subcomparator)(type *, type *);\
- eqt = it->equalto;\
- subcomparator = it->subcomparator;\
- it->currentelem = NULL;\
- while(it->pathi > 0 && it->currentelem==NULL) {\
- i = it->pathi-1;\
- if (i >= 0) {\
- if (it->pass[i] >= 2) {\
- /* goto up */\
- it->pathi --;\
- } else {\
- if (it->pass[i] == 0) {\
- /* goto left */\
- s = it->path[i]->left;\
- } else {\
- /* goto right */\
- s = it->path[i]->right;\
- }\
- if (eqt != NULL) {\
- if (subcomparator == NULL) {\
- SGLIB___BIN_TREE_FIND_MEMBER(type, s, eqt, left, right, comparator, s);\
- } else {\
- SGLIB___BIN_TREE_FIND_MEMBER(type, s, eqt, left, right, subcomparator, s);\
- }\
- }\
- if (s != NULL) {\
- j = i+1;\
- it->path[j] = s;\
- it->pass[j] = 0;\
- it->pathi ++;\
- }\
- it->pass[i] ++;\
- }\
- }\
- if (it->pathi>0 && it->order == it->pass[it->pathi-1]) {\
- it->currentelem = it->path[it->pathi-1];\
- }\
- }\
-}\
-type *sglib__##type##_it_init(struct sglib_##type##_iterator *it, type *tree, int order, int (*subcomparator)(type *, type *), type *equalto) {\
- type *t;\
- assert(it!=NULL);\
- it->order = order;\
- it->equalto = equalto;\
- it->subcomparator = subcomparator;\
- if (equalto == NULL) { \
- t = tree;\
- } else {\
- if (subcomparator == NULL) {\
- SGLIB___BIN_TREE_FIND_MEMBER(type, tree, equalto, left, right, comparator, t);\
- } else {\
- SGLIB___BIN_TREE_FIND_MEMBER(type, tree, equalto, left, right, subcomparator, t);\
- }\
- }\
- if (t == NULL) {\
- it->pathi = 0;\
- it->currentelem = NULL;\
- } else {\
- it->pathi = 1;\
- it->pass[0] = 0;\
- it->path[0] = t;\
- if (order == 0) {\
- it->currentelem = t;\
- } else {\
- sglib__##type##_it_compute_current_elem(it);\
- }\
- }\
- return(it->currentelem);\
-}\
-type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *tree) {\
- return(sglib__##type##_it_init(it, tree, 2, NULL, NULL));\
-}\
-type *sglib_##type##_it_init_preorder(struct sglib_##type##_iterator *it, type *tree) {\
- return(sglib__##type##_it_init(it, tree, 0, NULL, NULL));\
-}\
-type *sglib_##type##_it_init_inorder(struct sglib_##type##_iterator *it, type *tree) {\
- return(sglib__##type##_it_init(it, tree, 1, NULL, NULL));\
-}\
-type *sglib_##type##_it_init_postorder(struct sglib_##type##_iterator *it, type *tree) {\
- return(sglib__##type##_it_init(it, tree, 2, NULL, NULL));\
-}\
-type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *tree, int (*subcomparator)(type *, type *), type *equalto) {\
- return(sglib__##type##_it_init(it, tree, 1, subcomparator, equalto));\
-}\
-type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\
- return(it->currentelem);\
-}\
-type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\
- sglib__##type##_it_compute_current_elem(it);\
- return(it->currentelem);\
-}\
-\
-static void sglib___##type##_consistency_check_recursive(type *t, int *pathdeep, int cdeep) {\
- if (t==NULL) {\
- if (*pathdeep < 0) *pathdeep = cdeep;\
- else assert(*pathdeep == cdeep);\
- } else {\
- if (t->left!=NULL) assert(comparator(t->left, t) <= 0);\
- if (t->right!=NULL) assert(comparator(t, t->right) <= 0);\
- if (SGLIB___GET_VALUE(t->bits) == RED) {\
- assert(t->left == NULL || SGLIB___GET_VALUE(t->left->bits)==BLACK);\
- assert(t->right == NULL || SGLIB___GET_VALUE(t->right->bits)==BLACK);\
- sglib___##type##_consistency_check_recursive(t->left, pathdeep, cdeep);\
- sglib___##type##_consistency_check_recursive(t->right, pathdeep, cdeep);\
- } else {\
- sglib___##type##_consistency_check_recursive(t->left, pathdeep, cdeep+1);\
- sglib___##type##_consistency_check_recursive(t->right, pathdeep, cdeep+1);\
- }\
- }\
-}\
-\
-void sglib___##type##_consistency_check(type *t) {\
- int pathDeep;\
- assert(t==NULL || SGLIB___GET_VALUE(t->bits) == BLACK);\
- pathDeep = -1;\
- sglib___##type##_consistency_check_recursive(t, &pathDeep, 0);\
-}
-
-
-#define SGLIB_DEFINE_RBTREE_PROTOTYPES(type, left, right, colorbit, comparator) \
- struct sglib_##type##_iterator {\
- type *currentelem;\
- char pass[SGLIB_MAX_TREE_DEEP];\
- type *path[SGLIB_MAX_TREE_DEEP];\
- short int pathi;\
- short int order;\
- type *equalto;\
- int (*subcomparator)(type *, type *);\
- };\
- extern void sglib___##type##_consistency_check(type *t); \
- extern void sglib_##type##_add(type **tree, type *elem); \
- extern int sglib_##type##_add_if_not_member(type **tree, type *elem, type **memb); \
- extern void sglib_##type##_delete(type **tree, type *elem); \
- extern int sglib_##type##_delete_if_member(type **tree, type *elem, type **memb); \
- extern int sglib_##type##_is_member(type *t, type *elem); \
- extern type *sglib_##type##_find_member(type *t, type *elem); \
- extern int sglib_##type##_len(type *t); \
- extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *tree); \
- extern type *sglib_##type##_it_init_preorder(struct sglib_##type##_iterator *it, type *tree); \
- extern type *sglib_##type##_it_init_inorder(struct sglib_##type##_iterator *it, type *tree); \
- extern type *sglib_##type##_it_init_postorder(struct sglib_##type##_iterator *it, type *tree); \
- extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *tree, int (*subcomparator)(type *, type *), type *equalto); \
- extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \
- extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); \
-
-
-#define SGLIB_DEFINE_RBTREE_FUNCTIONS(type, left, right, colorbit, comparator) \
- SGLIB_DEFINE_RBTREE_FUNCTIONS_GENERAL(type, left, right, colorbit, comparator, 1, 0)
-
-
-
-/* ---------------------------------------------------------------------------- */
-/* ---------------------------------------------------------------------------- */
-/* - SUPPLEMENTARY DEFINITIONS - */
-/* ---------------------------------------------------------------------------- */
-/* ---------------------------------------------------------------------------- */
-
-
-#define SGLIB___GET_VALUE(x) (x)
-#define SGLIB___SET_VALUE(x, value) {(x) = (value);}
-#define SGLIB_ARRAY_ELEMENTS_EXCHANGER(type, a, i, j) {type _sgl_aee_tmp_; _sgl_aee_tmp_=(a)[(i)]; (a)[(i)]=(a)[(j)]; (a)[(j)]= _sgl_aee_tmp_;}
-
-
-#define SGLIB_SAFE_NUMERIC_COMPARATOR(x, y) (((x)>(y)?1:((x)<(y)?-1:0)))
-#define SGLIB_SAFE_REVERSE_NUMERIC_COMPARATOR(x, y) (((x)>(y)?-1:((x)<(y)?1:0)))
-#define SGLIB_FAST_NUMERIC_COMPARATOR(x, y) ((int)((x) - (y)))
-#define SGLIB_FAST_REVERSE_NUMERIC_COMPARATOR(x, y) ((int)((y) - (x)))
-#define SGLIB_NUMERIC_COMPARATOR(x, y) SGLIB_SAFE_NUMERIC_COMPARATOR(x, y)
-#define SGLIB_REVERSE_NUMERIC_COMPARATOR(x, y) SGLIB_SAFE_REVERSE_NUMERIC_COMPARATOR(x, y)
-
-#ifndef SGLIB_MAX_TREE_DEEP
-#define SGLIB_MAX_TREE_DEEP 128
-#endif
-
-#ifndef SGLIB_HASH_TAB_SHIFT_CONSTANT
-#define SGLIB_HASH_TAB_SHIFT_CONSTANT 16381 /* should be a prime */
-/* #define SGLIB_HASH_TAB_SHIFT_CONSTANT 536870912*/ /* for large tables :) */
-#endif
-
-#endif /* _SGLIB__h_ */