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));