listは双方向リンクリストである。 任意の位置での要素の挿入・削除の計算量がO(1)であるが、要素のランダムアクセスはできない。
listを使うには、以下のマクロを用いてコードを展開する必要がある。
#include <cstl/list.h> #define CSTL_LIST_INTERFACE(Name, Type) #define CSTL_LIST_IMPLEMENT(Name, Type)
CSTL_LIST_INTERFACE()は任意の名前と要素の型のlistのインターフェイスを展開する。 CSTL_LIST_IMPLEMENT()はその実装を展開する。 それぞれのマクロの引数は同じものを指定すること。
#include <stdio.h> #include <cstl/list.h> CSTL_LIST_INTERFACE(IntList, int) /* インターフェイスを展開 */ CSTL_LIST_IMPLEMENT(IntList, int) /* 実装を展開 */ int main(void) { int i; /* イテレータ */ IntListIterator pos; /* intのlistを生成 */ IntList *lst = IntList_new(); for (i = 0; i < 32; i++) { /* 末尾から追加 */ IntList_push_back(lst, i); } for (i = 0; i < 32; i++) { /* 先頭から追加 */ IntList_push_front(lst, i); } /* サイズ */ printf("size: %d\n", IntList_size(lst)); for (pos = IntList_begin(lst); pos != IntList_end(lst); pos = IntList_next(pos)) { /* イテレータによる要素の読み書き */ printf("%d,", *IntList_at(pos)); *IntList_at(pos) += 1; printf("%d\n", *IntList_at(pos)); } /* 使い終わったら破棄 */ IntList_delete(lst); return 0; }
※複数のソースファイルから同じ型のコンテナを使用する場合は、 マクロ展開用のヘッダファイルとソースファイルを用意し、適宜インクルードやリンクをすればよい。
CSTL_LIST_INTERFACE(Name, Type)のNameにList, TypeにTを指定した場合、 以下のインターフェイスを提供する。
List
コンテナの型。抽象データ型となっており、以下の関数によってのみアクセスできる。
ListIterator
イテレータの型。要素の位置を示す。 関数から返されたイテレータを有効なイテレータという。 宣言されただけのイテレータ、または削除された要素のイテレータを無効なイテレータという。
List *List_new(void);
void List_delete(List *self);
size_t List_size(List *self);
int List_empty(List *self);
ListIterator List_begin(List *self);
ListIterator List_end(List *self);
ListIterator List_rbegin(List *self);
ListIterator List_rend(List *self);
ListIterator List_next(ListIterator pos);
ListIterator List_prev(ListIterator pos);
T *List_at(ListIterator pos);
T List_front(List *self);
T List_back(List *self);
ListIterator List_insert(List *self, ListIterator pos, T elem);
int List_insert_n(List *self, ListIterator pos, size_t n, T elem);
int List_insert_array(List *self, ListIterator pos, const T *elems, size_t n);
int List_insert_range(List *self, ListIterator pos, ListIterator first, ListIterator last);
int List_push_front(List *self, T elem);
int List_push_back(List *self, T elem);
ListIterator List_erase(List *self, ListIterator pos);
ListIterator List_erase_range(List *self, ListIterator first, ListIterator last);
T List_pop_front(List *self);
T List_pop_back(List *self);
void List_clear(List *self);
int List_resize(List *self, size_t n, T elem);
void List_swap(List *self, List *x);
void List_splice(List *self, ListIterator pos, List *x, ListIterator first, ListIterator last);
void List_sort(List *self, int (*comp)(const void *p1, const void *p2));
void List_reverse(List *self);
void List_merge(List *self, List *x, int (*comp)(const void *p1, const void *p2));