utlist

Basic linked list operation definitions.

LDECLTYPE( x)
1
__typeof(x)
_SV( elt, list)
_NEXT( elt, list, next)
1
((elt)->next)
_NEXTASGN( elt, list, to, next)
1
((elt)->next)=(to)
_PREVASGN( elt, list, to, prev)
1
((elt)->prev)=(to)
_RS( list)
_CASTASGN( a, b)
1
(a)=(b)
LL_SORT( list, cmp)
1
LL_SORT2(list, cmp, next)
LL_SORT2( list, cmp, next)
DL_SORT( list, cmp)
1
DL_SORT2(list, cmp, prev, next)
DL_SORT2( list, cmp, prev, next)
CDL_SORT( list, cmp)
1
CDL_SORT2(list, cmp, prev, next)
CDL_SORT2( list, cmp, prev, next)
LL_PREPEND( head, add)

LL prepend element ‘add’ to list.

1
LL_PREPEND2(head,add,next)
LL_PREPEND2( head, add, next)

LL prepend to list with alternative next ptr name ‘next’.

1
2
3
4
do {                                                                                           \
  (add)->next = head;                                                                          \
  head = add;                                                                                  \
} while (0)
LL_CONCAT( head1, head2)

LL concat to append second list to first.

1
LL_CONCAT2(head1,head2,next)
LL_CONCAT2( head1, head2, next)

LL concat with alternative next ptr name ‘next’.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
do {                                                                                           \
  LDECLTYPE(head1) _tmp;                                                                       \
  if (head1) {                                                                                 \
    _tmp = head1;                                                                              \
    while (_tmp->next) { _tmp = _tmp->next; }                                                  \
    _tmp->next=(head2);                                                                        \
  } else {                                                                                     \
    (head1)=(head2);                                                                           \
  }                                                                                            \
} while (0)
LL_APPEND( head, add)

LL append to append element ‘add’ to list.

1
LL_APPEND2(head,add,next)
LL_APPEND2( head, add, next)

LL append with alternative next ptr name ‘next’.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
do {                                                                                           \
  LDECLTYPE(head) _tmp;                                                                        \
  (add)->next=NULL;                                                                            \
  if (head) {                                                                                  \
    _tmp = head;                                                                               \
    while (_tmp->next) { _tmp = _tmp->next; }                                                  \
    _tmp->next=(add);                                                                          \
  } else {                                                                                     \
    (head)=(add);                                                                              \
  }                                                                                            \
} while (0)
LL_DELETE( head, del)

LL delete element ‘del’ from list.

1
LL_DELETE2(head,del,next)
LL_DELETE2( head, del, next)

LL delete with alternative next ptr name ‘name’.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
do {                                                                                           \
  LDECLTYPE(head) _tmp;                                                                        \
  if ((head) == (del)) {                                                                       \
    (head)=(head)->next;                                                                       \
  } else {                                                                                     \
    _tmp = head;                                                                               \
    while (_tmp->next && (_tmp->next != (del))) {                                              \
      _tmp = _tmp->next;                                                                       \
    }                                                                                          \
    if (_tmp->next) {                                                                          \
      _tmp->next = ((del)->next);                                                              \
    }                                                                                          \
  }                                                                                            \
} while (0)
LL_APPEND_VS2008( head, add)
1
LL_APPEND2_VS2008(head,add,next)
LL_APPEND2_VS2008( head, add, next)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
do {                                                                                           \
  if (head) {                                                                                  \
    (add)->next = head;     /* use add->next as a temp variable */                             \
    while ((add)->next->next) { (add)->next = (add)->next->next; }                             \
    (add)->next->next=(add);                                                                   \
  } else {                                                                                     \
    (head)=(add);                                                                              \
  }                                                                                            \
  (add)->next=NULL;                                                                            \
} while (0)
LL_DELETE_VS2008( head, del)
1
LL_DELETE2_VS2008(head,del,next)
LL_DELETE2_VS2008( head, del, next)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
do {                                                                                           \
  if ((head) == (del)) {                                                                       \
    (head)=(head)->next;                                                                       \
  } else {                                                                                     \
    char *_tmp = (char*)(head);                                                                \
    while ((head)->next && ((head)->next != (del))) {                                          \
      head = (head)->next;                                                                     \
    }                                                                                          \
    if ((head)->next) {                                                                        \
      (head)->next = ((del)->next);                                                            \
    }                                                                                          \
    {                                                                                          \
      char **_head_alias = (char**)&(head);                                                    \
      *_head_alias = _tmp;                                                                     \
    }                                                                                          \
  }                                                                                            \
} while (0)
LL_COUNT( head, el, counter)

LL count list elements using ‘counter’.

1
LL_COUNT2(head,el,counter,next)                                                            \
LL_COUNT2( head, el, counter, next)

LL count with alternative next ptr name ‘next’.

1
2
3
4
{                                                                                              \
    counter = 0;                                                                               \
    LL_FOREACH2(head,el,next){ ++counter; }                                                    \
}
LL_FOREACH( head, el)

LL list iteration.

1
LL_FOREACH2(head,el,next)
LL_FOREACH2( head, el, next)

LL list iteration with alternative next ptr name ‘next’.

1
for(el=head;el;el=(el)->next)
LL_FOREACH_SAFE( head, el, tmp)

LL safe list iteration Use if list elements might be deleted while iterating.

1
LL_FOREACH_SAFE2(head,el,tmp,next)
LL_FOREACH_SAFE2( head, el, tmp, next)

LL safe list iteration with alternative ptr names.

1
for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp)
LL_SEARCH_SCALAR( head, out, field, val)

LL scalar search for element with value ‘val’ for member ‘field’.

1
LL_SEARCH_SCALAR2(head,out,field,val,next)
LL_SEARCH_SCALAR2( head, out, field, val, next)

LL scalar search with alternative next ptr name ‘next’.

1
2
3
4
5
do {                                                                                           \
    LL_FOREACH2(head,out,next) {                                                               \
      if ((out)->field == (val)) break;                                                        \
    }                                                                                          \
} while(0)
LL_SEARCH( head, out, elt, cmp)

LL search element ‘elt’ in list using function ‘cmp’.

1
LL_SEARCH2(head,out,elt,cmp,next)
LL_SEARCH2( head, out, elt, cmp, next)

LL search with alternative next ptr name ‘next’.

1
2
3
4
5
do {                                                                                           \
    LL_FOREACH2(head,out,next) {                                                               \
      if ((cmp(out,elt))==0) break;                                                            \
    }                                                                                          \
} while(0)
LL_REPLACE_ELEM( head, el, add)

LL replace element ‘el’ with element ‘add’ in list.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
do {                                                                                           \
 LDECLTYPE(head) _tmp;                                                                         \
 assert(head != NULL);                                                                         \
 assert(el != NULL);                                                                           \
 assert(add != NULL);                                                                          \
 (add)->next = (el)->next;                                                                     \
 if ((head) == (el)) {                                                                         \
  (head) = (add);                                                                              \
 } else {                                                                                      \
  _tmp = head;                                                                                 \
  while (_tmp->next && (_tmp->next != (el))) {                                                 \
   _tmp = _tmp->next;                                                                          \
  }                                                                                            \
  if (_tmp->next) {                                                                            \
    _tmp->next = (add);                                                                        \
  }                                                                                            \
 }                                                                                             \
} while (0)
LL_PREPEND_ELEM( head, el, add)

LL prepend new element ‘add’ to element ‘el’ in list.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
do {                                                                                           \
 LDECLTYPE(head) _tmp;                                                                         \
 assert(head != NULL);                                                                         \
 assert(el != NULL);                                                                           \
 assert(add != NULL);                                                                          \
 (add)->next = (el);                                                                           \
 if ((head) == (el)) {                                                                         \
  (head) = (add);                                                                              \
 } else {                                                                                      \
  _tmp = head;                                                                                 \
  while (_tmp->next && (_tmp->next != (el))) {                                                 \
   _tmp = _tmp->next;                                                                          \
  }                                                                                            \
  if (_tmp->next) {                                                                            \
    _tmp->next = (add);                                                                        \
  }                                                                                            \
 }                                                                                             \
} while (0)
DL_PREPEND( head, add)

DL prepend element ‘add’ to list.

1
DL_PREPEND2(head,add,prev,next)
DL_PREPEND2( head, add, prev, next)

DL prepend to list with alternative ptr names.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
do {                                                                                           \
 (add)->next = head;                                                                           \
 if (head) {                                                                                   \
   (add)->prev = (head)->prev;                                                                 \
   (head)->prev = (add);                                                                       \
 } else {                                                                                      \
   (add)->prev = (add);                                                                        \
 }                                                                                             \
 (head) = (add);                                                                               \
} while (0)
DL_APPEND( head, add)

DL append to append element ‘add’ to list.

1
DL_APPEND2(head,add,prev,next)
DL_APPEND2( head, add, prev, next)

DL append with alternative next ptr name ‘next’.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
do {                                                                                           \
  if (head) {                                                                                  \
      (add)->prev = (head)->prev;                                                              \
      (head)->prev->next = (add);                                                              \
      (head)->prev = (add);                                                                    \
      (add)->next = NULL;                                                                      \
  } else {                                                                                     \
      (head)=(add);                                                                            \
      (head)->prev = (head);                                                                   \
      (head)->next = NULL;                                                                     \
  }                                                                                            \
} while (0)
DL_CONCAT( head1, head2)

DL concat to append second list to first.

1
DL_CONCAT2(head1,head2,prev,next)
DL_CONCAT2( head1, head2, prev, next)

DL concat with alternative next ptr name ‘next’.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
do {                                                                                           \
  LDECLTYPE(head1) _tmp;                                                                       \
  if (head2) {                                                                                 \
    if (head1) {                                                                               \
        _tmp = (head2)->prev;                                                                  \
        (head2)->prev = (head1)->prev;                                                         \
        (head1)->prev->next = (head2);                                                         \
        (head1)->prev = _tmp;                                                                  \
    } else {                                                                                   \
        (head1)=(head2);                                                                       \
    }                                                                                          \
  }                                                                                            \
} while (0)
DL_DELETE( head, del)

DL delete element ‘del’ from list.

1
DL_DELETE2(head,del,prev,next)
DL_DELETE2( head, del, prev, next)

DL delete with alternative ptr names.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
do {                                                                                           \
  assert((del)->prev != NULL);                                                                 \
  if ((del)->prev == (del)) {                                                                  \
      (head)=NULL;                                                                             \
  } else if ((del)==(head)) {                                                                  \
      (del)->next->prev = (del)->prev;                                                         \
      (head) = (del)->next;                                                                    \
  } else {                                                                                     \
      (del)->prev->next = (del)->next;                                                         \
      if ((del)->next) {                                                                       \
          (del)->next->prev = (del)->prev;                                                     \
      } else {                                                                                 \
          (head)->prev = (del)->prev;                                                          \
      }                                                                                        \
  }                                                                                            \
} while (0)
DL_COUNT( head, el, counter)

DL count list elements using ‘counter’.

1
DL_COUNT2(head,el,counter,next)                                                            \
DL_COUNT2( head, el, counter, next)

DL count with alternative next ptr name ‘next’.

1
2
3
4
{                                                                                              \
    counter = 0;                                                                               \
    DL_FOREACH2(head,el,next){ ++counter; }                                                    \
}
DL_FOREACH( head, el)

DL list iteration.

1
DL_FOREACH2(head,el,next)
DL_FOREACH2( head, el, next)

DL list iteration with alternative next ptr name ‘next’.

1
for(el=head;el;el=(el)->next)
DL_FOREACH_SAFE( head, el, tmp)

DL safe list iteration Use if list elements might be deleted while iterating.

1
DL_FOREACH_SAFE2(head,el,tmp,next)
DL_FOREACH_SAFE2( head, el, tmp, next)

DL safe list iteration with alternative ptr names.

1
for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp)
DL_SEARCH_SCALAR

DL scalar search for element with value ‘val’ for member ‘field’ Identical to singly-linked counterpart.

1
LL_SEARCH_SCALAR
DL_SEARCH_SCALAR2

DL scalar search with alternative next ptr name ‘next’ Identical to singly-linked counterpart.

1
LL_SEARCH_SCALAR2
DL_SEARCH

DL search element ‘elt’ in list using function ‘cmp’ Identical to singly-linked counterpart.

1
LL_SEARCH
DL_SEARCH2

DL search with alternative next ptr name ‘next’ Identical to singly-linked counterpart.

1
LL_SEARCH2
DL_REPLACE_ELEM( head, el, add)

DL replace element ‘el’ with element ‘add’ in list.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
do {                                                                                           \
 assert(head != NULL);                                                                         \
 assert(el != NULL);                                                                           \
 assert(add != NULL);                                                                          \
 if ((head) == (el)) {                                                                         \
  (head) = (add);                                                                              \
  (add)->next = (el)->next;                                                                    \
  if ((el)->next == NULL) {                                                                    \
   (add)->prev = (add);                                                                        \
  } else {                                                                                     \
   (add)->prev = (el)->prev;                                                                   \
   (add)->next->prev = (add);                                                                  \
  }                                                                                            \
 } else {                                                                                      \
  (add)->next = (el)->next;                                                                    \
  (add)->prev = (el)->prev;                                                                    \
  (add)->prev->next = (add);                                                                   \
  if ((el)->next == NULL) {                                                                    \
   (head)->prev = (add);                                                                       \
  } else {                                                                                     \
   (add)->next->prev = (add);                                                                  \
  }                                                                                            \
 }                                                                                             \
} while (0)
DL_PREPEND_ELEM( head, el, add)

DL prepend new element ‘add’ to element ‘el’ in list.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
do {                                                                                           \
 assert(head != NULL);                                                                         \
 assert(el != NULL);                                                                           \
 assert(add != NULL);                                                                          \
 (add)->next = (el);                                                                           \
 (add)->prev = (el)->prev;                                                                     \
 (el)->prev = (add);                                                                           \
 if ((head) == (el)) {                                                                         \
  (head) = (add);                                                                              \
 } else {                                                                                      \
  (add)->prev->next = (add);                                                                   \
 }                                                                                             \
} while (0)
CDL_PREPEND( head, add)

CDL prepend element ‘add’ to list.

1
CDL_PREPEND2(head,add,prev,next)
CDL_PREPEND2( head, add, prev, next)

CDL prepend to list with alternative ptr names.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
do {                                                                                           \
 if (head) {                                                                                   \
   (add)->prev = (head)->prev;                                                                 \
   (add)->next = (head);                                                                       \
   (head)->prev = (add);                                                                       \
   (add)->prev->next = (add);                                                                  \
 } else {                                                                                      \
   (add)->prev = (add);                                                                        \
   (add)->next = (add);                                                                        \
 }                                                                                             \
(head)=(add);                                                                                  \
} while (0)
CDL_DELETE( head, del)

CDL delete element ‘del’ from list.

1
CDL_DELETE2(head,del,prev,next)
CDL_DELETE2( head, del, prev, next)

CDL delete with alternative ptr names.

1
2
3
4
5
6
7
8
9
do {                                                                                           \
  if ( ((head)==(del)) && ((head)->next == (head))) {                                          \
      (head) = 0L;                                                                             \
  } else {                                                                                     \
     (del)->next->prev = (del)->prev;                                                          \
     (del)->prev->next = (del)->next;                                                          \
     if ((del) == (head)) (head)=(del)->next;                                                  \
  }                                                                                            \
} while (0)
CDL_COUNT( head, el, counter)

CDL count list elements using ‘counter’.

1
CDL_COUNT2(head,el,counter,next)                                                           \
CDL_COUNT2( head, el, counter, next)

CDL count with alternative next ptr name ‘next’.

1
2
3
4
{                                                                                              \
    counter = 0;                                                                               \
    CDL_FOREACH2(head,el,next){ ++counter; }                                                   \
}
CDL_FOREACH( head, el)

CDL list iteration.

1
CDL_FOREACH2(head,el,next)
CDL_FOREACH2( head, el, next)

CDL list iteration with alternative next ptr name ‘next’.

1
for(el=head;el;el=((el)->next==head ? 0L : (el)->next))
CDL_FOREACH_SAFE( head, el, tmp1, tmp2)

CDL safe list iteration Use if list elements might be deleted while iterating.

1
CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next)
CDL_FOREACH_SAFE2( head, el, tmp1, tmp2, prev, next)

CDL safe list iteration with alternative ptr names.

1
2
3
for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL);                                        \
      (el) && ((tmp2)=(el)->next, 1);                                                          \
      ((el) = (((el)==(tmp1)) ? 0L : (tmp2))))
CDL_SEARCH_SCALAR( head, out, field, val)

CDL scalar search for element with value ‘val’ for member ‘field’.

1
CDL_SEARCH_SCALAR2(head,out,field,val,next)
CDL_SEARCH_SCALAR2( head, out, field, val, next)

CDL scalar search with alternative next ptr name ‘next’.

1
2
3
4
5
do {                                                                                           \
    CDL_FOREACH2(head,out,next) {                                                              \
      if ((out)->field == (val)) break;                                                        \
    }                                                                                          \
} while(0)
CDL_SEARCH( head, out, elt, cmp)

CDL search element ‘elt’ in list using function ‘cmp’.

1
CDL_SEARCH2(head,out,elt,cmp,next)
CDL_SEARCH2( head, out, elt, cmp, next)

CDL search with alternative next ptr name ‘next’.

1
2
3
4
5
do {                                                                                           \
    CDL_FOREACH2(head,out,next) {                                                              \
      if ((cmp(out,elt))==0) break;                                                            \
    }                                                                                          \
} while(0)
CDL_REPLACE_ELEM( head, el, add)

CDL replace element ‘el’ with element ‘add’ in list.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
do {                                                                                           \
 assert(head != NULL);                                                                         \
 assert(el != NULL);                                                                           \
 assert(add != NULL);                                                                          \
 if ((el)->next == (el)) {                                                                     \
  (add)->next = (add);                                                                         \
  (add)->prev = (add);                                                                         \
  (head) = (add);                                                                              \
 } else {                                                                                      \
  (add)->next = (el)->next;                                                                    \
  (add)->prev = (el)->prev;                                                                    \
  (add)->next->prev = (add);                                                                   \
  (add)->prev->next = (add);                                                                   \
  if ((head) == (el)) {                                                                        \
   (head) = (add);                                                                             \
  }                                                                                            \
 }                                                                                             \
} while (0)
CDL_PREPEND_ELEM( head, el, add)

CDL prepend new element ‘add’ to element ‘el’ in list.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
do {                                                                                           \
 assert(head != NULL);                                                                         \
 assert(el != NULL);                                                                           \
 assert(add != NULL);                                                                          \
 (add)->next = (el);                                                                           \
 (add)->prev = (el)->prev;                                                                     \
 (el)->prev = (add);                                                                           \
 (add)->prev->next = (add);                                                                    \
 if ((head) == (el)) {                                                                         \
  (head) = (add);                                                                              \
 }                                                                                             \
} while (0)
UTLIST_VERSION

Version number.

1
1.9.9