リスト処理をマクロで書いてみた
C言語でリスト処理を作るときに、普通の関数で作ると引数の型に柔軟性を持たせにくくなって、セルになる構造体のデータ毎に関数をつくらざるをえないようなことになったりもする。
C++であればtemplateなんかでもよいのだろうけど、C言語だけで書くには困ってしまう。
そこで、マクロでリストの処理を書いてみた。
リスト処理はしょっちゅう必要になるので(何に?)ここにまとめておくとよいかなーと思った。
Macでeditすると¥が?に置き換わる。。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #define init_cell(cell) { ? (cell)->prev = (cell)->next = NULL; ? } #define init_list(list) { ? (list)->head = (list)->tail = NULL; ? pthread_mutex_init(&((list)->mutex), NULL); ? } #define push_list(list, cell) { ? (cell)->next = NULL; ? pthread_mutex_lock(&((list)->mutex)); ? if((list)->head != NULL) { ? (cell)->prev = (list)->tail; ? (list)->tail->next = cell; ? (list)->tail = cell; ? } else { ? (cell)->prev = NULL; ? (list)->head = (list)->tail = cell; ? } ? pthread_mutex_unlock(&((list)->mutex)); ? } #define pop_list(list, cell) ? { ? pthread_mutex_lock(&((list)->mutex)); ? *(cell) = (list)->head; ? if((list)->head != NULL) { ? (list)->head = (list)->head->next; ? if((list)->head != NULL) { ? (list)->head->prev = NULL; ? } ? (*(cell))->next = NULL; ? } ? pthread_mutex_unlock(&((list)->mutex)); ? }
ここより下は上記マクロの動作確認用。同じファイルにくっつけるなり、上のコードをヘッダに書いておいてincludeするなりしてください。
struct sample_cell_a { struct sample_cell_a *prev; struct sample_cell_a *next; int data; }; struct sample_list_a { struct sample_cell_a *head; struct sample_cell_a *tail; pthread_mutex_t mutex; }; #define CELLNUM (5) void show_list(const char *str, struct sample_list_a *list) { struct sample_cell_a *tmp = list->head; printf("-- %s --?n", str); while(tmp != NULL) { printf("prev=%016p cell=%016p next=%016p data=%d?n", tmp->prev, tmp, tmp->next, tmp->data); tmp = tmp->next; } } int main(int argc, char **argv) { struct sample_cell_a *tmp; struct sample_cell_a cell[CELLNUM]; struct sample_list_a list; int i; for(i=0;i<CELLNUM;i++ ) { init_cell(&cell[i]); cell[i].data = i; } init_list(&list); for(i=0;i<CELLNUM;i++ ) { push_list(&list, &cell[i]); show_list("pushed", &list); } while(1) { pop_list(&list, &tmp); if(tmp == NULL) { break; } show_list("popped", &list); } return 0; }
listをロックするように修正しました。
次はqueueかな。そのあとhashでそのあとTimerかなぁ。