setは要素が値によって自動的にソートされるコンテナである。 同じ要素を2個以上挿入することはできない。 挿入した要素は読み出し専用となる。 要素の挿入・削除・検索の計算量はO(log N)である。
multisetは要素の重複が許されることを除き、setと同じである。
set/multisetを使うには、 以下のマクロを用いてコードを展開する必要がある。
#include <cstl/set.h> #define CSTL_SET_INTERFACE(Name, Type) #define CSTL_SET_IMPLEMENT(Name, Type, Compare) #define CSTL_MULTISET_INTERFACE(Name, Type) #define CSTL_MULTISET_IMPLEMENT(Name, Type, Compare)
CSTL_SET_INTERFACE()は任意の名前と要素の型のsetのインターフェイスを展開する。 CSTL_SET_IMPLEMENT()はその実装を展開する。 それぞれのマクロのCompare以外の引数は同じものを指定すること。
CSTL_MULTISET_INTERFACE()は任意の名前と要素の型のmultisetのインターフェイスを展開する。 CSTL_MULTISET_IMPLEMENT()はその実装を展開する。 それぞれのマクロのCompare以外の引数は同じものを指定すること。
Typeが整数型、小数型、ポインタ型など、2つの値を単純に比較できる型の場合、 要素のソートの順序を昇順にするならばCSTL_LESSを、降順にするならばCSTL_GREATERをCompareに指定する。 これらのマクロはヘッダで以下のように定義されている。
#define CSTL_LESS(x, y) ((x) == (y) ? 0 : (x) < (y) ? -1 : 1) #define CSTL_GREATER(x, y) ((x) == (y) ? 0 : (x) > (y) ? -1 : 1)
Typeがその他の型の場合、以下の関数のような引数と戻り値を持ち、 x == yならば0を、x < yならば正または負の整数を、x > yならばx < yの場合と逆の符号の整数を 返す比較関数またはマクロをCompareに指定する。 尚、Typeが文字列型(const char *)ならば、C標準関数のstrcmpが指定可能である。
int comp(Type x, Type y);
#include <stdio.h> #include <cstl/set.h> CSTL_SET_INTERFACE(IntSet, int) /* インターフェイスを展開 */ CSTL_SET_IMPLEMENT(IntSet, int, CSTL_LESS) /* 実装を展開 */ int main(void) { int i; /* イテレータ */ IntSetIterator pos; /* intのsetを生成 */ IntSet *set = IntSet_new(); /* 要素を挿入 */ for (i = 0; i < 64; i++) { IntSet_insert(set, i, NULL); } /* サイズ */ printf("size: %d\n", IntSet_size(set)); for (pos = IntSet_begin(set); pos != IntSet_end(set); pos = IntSet_next(pos)) { /* イテレータによる要素の読み出し */ printf("%d\n", IntSet_key(pos)); } /* 3以上の要素を削除 */ IntSet_erase_range(set, IntSet_find(set, 3), IntSet_end(set)); /* 使い終わったら破棄 */ IntSet_delete(set); return 0; }
※複数のソースファイルから同じ型のコンテナを使用する場合は、 マクロ展開用のヘッダファイルとソースファイルを用意し、適宜インクルードやリンクをすればよい。
CSTL_SET_INTERFACE(Name, Type) , CSTL_MULTISET_INTERFACE(Name, Type)の NameにSet, TypeにTを指定した場合、 以下のインターフェイスを提供する。
Set
コンテナの型。抽象データ型となっており、以下の関数によってのみアクセスできる。
SetIterator
イテレータの型。要素の位置を示す。 関数から返されたイテレータを有効なイテレータという。 宣言されただけのイテレータ、または削除された要素のイテレータを無効なイテレータという。
Set *Set_new(void);
void Set_delete(Set *self);
size_t Set_size(Set *self);
int Set_empty(Set *self);
SetIterator Set_begin(Set *self);
SetIterator Set_end(Set *self);
SetIterator Set_rbegin(Set *self);
SetIterator Set_rend(Set *self);
SetIterator Set_next(SetIterator pos);
SetIterator Set_prev(SetIterator pos);
T Set_key(SetIterator pos);
SetIterator Set_insert(Set *self, T elem, int *success);
SetIterator Set_insert(Set *self, T elem);
int Set_insert_range(Set *self, SetIterator first, SetIterator last);
SetIterator Set_erase(Set *self, SetIterator pos);
SetIterator Set_erase_range(Set *self, SetIterator first, SetIterator last);
size_t Set_erase_key(Set *self, T elem);
void Set_clear(Set *self);
void Set_swap(Set *self, Set *x);
size_t Set_count(Set *self, T elem);
SetIterator Set_find(Set *self, T elem);
SetIterator Set_lower_bound(Set *self, T elem);
SetIterator Set_upper_bound(Set *self, T elem);