map/multimap

mapはキーと値のペアを要素とするコンテナである。 要素を挿入すると、キーによって自動的にソートされる。同じキーの要素を2個以上挿入することはできない。 挿入した要素のキーは読み出し専用となる。 キーによる要素のルックアップが可能。 要素の挿入・削除・キーの検索・ルックアップの計算量はO(log N)である。

multimapはキーの重複が許されることと、ルックアップが不可能であることを除き、mapと同じである。

map/multimapを使うには、以下のマクロを用いてコードを展開する必要がある。

#include <cstl/map.h>

#define CSTL_MAP_INTERFACE(Name, KeyType, ValueType)
#define CSTL_MAP_IMPLEMENT(Name, KeyType, ValueType, Compare)

#define CSTL_MULTIMAP_INTERFACE(Name, KeyType, ValueType)
#define CSTL_MULTIMAP_IMPLEMENT(Name, KeyType, ValueType, Compare)

CSTL_MAP_INTERFACE()は任意の名前と要素の型のmapのインターフェイスを展開する。 CSTL_MAP_IMPLEMENT()はその実装を展開する。 それぞれのマクロのCompare以外の引数は同じものを指定すること。

CSTL_MULTIMAP_INTERFACE()は任意の名前と要素の型のmultimapのインターフェイスを展開する。 CSTL_MULTIMAP_IMPLEMENT()はその実装を展開する。 それぞれのマクロのCompare以外の引数は同じものを指定すること。

Name
既存の型と重複しない任意の名前。コンテナの型名と関数のプレフィックスになる
KeyType
任意の要素のキーの型
ValueType
任意の要素の値の型
Compare
要素を比較する関数またはマクロ

使用例

#include <stdio.h>
#include <string.h>
#include <cstl/map.h>

CSTL_MAP_INTERFACE(StrIntMap, const char *, int)         /* インターフェイスを展開 */
CSTL_MAP_IMPLEMENT(StrIntMap, const char *, int, strcmp) /* 実装を展開 */

int main(void)
{
    /* イテレータ */
    StrIntMapIterator pos;
    /* キーが文字列、値がintのmapを生成 */
    StrIntMap *map = StrIntMap_new();

    /* 要素を挿入 */
    StrIntMap_insert(map, "aaa", 1, NULL);
    StrIntMap_insert(map, "bbb", 2, NULL);
    /* ルックアップによる要素の読み書き */
    printf("%d\n", *StrIntMap_lookup(map, "aaa"));
    *StrIntMap_lookup(map, "bbb") = 3;
    *StrIntMap_lookup(map, "ccc") = 4; /* 存在しないキーの要素は自動的に挿入 */
    /* サイズ */
    printf("size: %d\n", StrIntMap_size(map));
    for (pos = StrIntMap_begin(map); pos != StrIntMap_end(map); pos = StrIntMap_next(pos)) {
        /* イテレータによる要素の読み書き */
        printf("%s: %d,", StrIntMap_key(pos), *StrIntMap_value(pos));
        *StrIntMap_value(pos) += 1;
        printf("%d\n", *StrIntMap_value(pos));
    }

    /* 使い終わったら破棄 */
    StrIntMap_delete(map);
    return 0;
}

※複数のソースファイルから同じ型のコンテナを使用する場合は、 マクロ展開用のヘッダファイルとソースファイルを用意し、適宜インクルードやリンクをすればよい。


CSTL_MAP_INTERFACE(Name, KeyType, ValueType) , CSTL_MULTIMAP_INTERFACE(Name, KeyType, ValueType)の NameにMap, KeyTypeにKeyT, ValueTypeにValueTを指定した場合、 以下のインターフェイスを提供する。


Map

Map

コンテナの型。抽象データ型となっており、以下の関数によってのみアクセスできる。


MapIterator

MapIterator

イテレータの型。要素の位置を示す。 関数から返されたイテレータを有効なイテレータという。 宣言されただけのイテレータ、または削除された要素のイテレータを無効なイテレータという。


Map_new()

Map *Map_new(void);

Map_delete()

void Map_delete(Map *self);

Map_size()

size_t Map_size(Map *self);

Map_empty()

int Map_empty(Map *self);

Map_begin()

MapIterator Map_begin(Map *self);

Map_end()

MapIterator Map_end(Map *self);

Map_rbegin()

MapIterator Map_rbegin(Map *self);

Map_rend()

MapIterator Map_rend(Map *self);

Map_next()

MapIterator Map_next(MapIterator pos);

Map_prev()

MapIterator Map_prev(MapIterator pos);

Map_key()

KeyT Map_key(MapIterator pos);

Map_value()

ValueT *Map_value(MapIterator pos);

Map_lookup() map用

ValueT *Map_lookup(Map *self, KeyT key);

Map_insert() map用

MapIterator Map_insert(Map *self, KeyT key, ValueT value, int *success);

Map_insert() multimap用

MapIterator Map_insert(Map *self, KeyT key, ValueT value);

Map_insert_range()

int Map_insert_range(Map *self, MapIterator first, MapIterator last);

Map_erase()

MapIterator Map_erase(Map *self, MapIterator pos);

Map_erase_range()

MapIterator Map_erase_range(Map *self, MapIterator first, MapIterator last);

Map_erase_key()

size_t Map_erase_key(Map *self, KeyT key);

Map_clear()

void Map_clear(Map *self);

Map_swap()

void Map_swap(Map *self, Map *x);

Map_count()

size_t Map_count(Map *self, KeyT key);

Map_find()

MapIterator Map_find(Map *self, KeyT key);

Map_lower_bound()

MapIterator Map_lower_bound(Map *self, KeyT key);

Map_upper_bound()

MapIterator Map_upper_bound(Map *self, KeyT key);