CSTLは、C++のSTLコンテナに似たインターフェイスを持つC/C++用のコンテナライブラリである。 マクロを使うことにより、任意の型の要素を格納することが可能なコンテナを提供する。
手動でコピーする方法
SourceForge.jpからtarballをダウンロードし、展開する。 cstlディレクトリには以下のファイルが含まれている。
vector.h deque.h list.h rbtree.h set.h map.h string.h
cstlディレクトリをインクルードパスの通ったディレクトリにコピーする。
SVNリポジトリからチェックアウトする方法
インクルードパスの通ったディレクトリに移動し、以下のコマンドを実行する。
最新スナップショットをチェックアウト > svn checkout http://svn.sourceforge.jp/svnroot/cstl/trunk/cstl ./cstl 特定のバージョンをチェックアウト(x.x.xはバージョン番号) > svn checkout http://svn.sourceforge.jp/svnroot/cstl/tags/rel-x.x.x/cstl ./cstl
CSTLは以下のコンテナを提供する。
可変長配列。許容量を超えた要素の追加をした場合、自動的に拡張する。 末尾での要素の挿入・削除が高速であり、それ以外の位置の要素の挿入・削除と要素の検索は遅い。 インデックスによる要素のランダムアクセスが可能。
両端キュー。動的な拡張はサポートしない。 先頭と末尾での要素の挿入・削除が高速であり、それ以外の位置の要素の挿入・削除と要素の検索は遅い。 インデックスによる要素のランダムアクセスが可能。
双方向リンクリスト。 要素の挿入・削除が高速であり、要素の検索は遅い。
要素が値によって自動的にソートされるコンテナ。要素は定数となる。 要素の重複は許されない。 要素の挿入・削除・検索が速い。
要素の重複が許されることを除き、setと同じである。
キーと値のペアを要素とするコンテナ。要素はキーによって自動的にソートされる。キーは定数となる。 キーの重複は許されない。 要素の挿入・削除が速い。キーの検索は速く、値の検索は遅い。 キーによる要素のランダムアクセスが可能。 連想配列として使用可能。
キーの重複が許されることと、キーによる要素のランダムアクセスが不可能であることを除き、mapと同じである。 辞書として使用可能。
可変長文字列。許容量を超えた文字の追加をした場合、自動的に拡張する。
vectorを使うには、vector.hというヘッダファイルをインクルードする。
#include <cstl/vector.h>
以下のマクロを用いてコードを展開する必要がある。
/* インターフェイスを展開 */ #define VECTOR_INTERFACE(Name, Type) /* 実装を展開 */ #define VECTOR_IMPLEMENT(Name, Type)
Nameに既存の型と重複しない任意の名前を、Typeに任意の要素の型を指定する。
VECTOR_INTERFACEの引数のNameにVector, TypeにTを指定した場合、 以下のインターフェイスを提供する。
Vector
コンテナの型。抽象データ型となっており、以下の関数によってのみアクセスできる。
Vector *Vector_new(void);
Vector *Vector_new_copy(Vector *x);
void Vector_delete(Vector *self);
size_t Vector_size(Vector *self);
int Vector_empty(Vector *self);
size_t Vector_capacity(Vector *self);
int Vector_reserve(Vector *self, size_t n);
void Vector_shrink(Vector *self, size_t n);
int Vector_assign(Vector *self, T *elems, size_t n);
T *Vector_at(Vector *self, size_t idx);
T Vector_front(Vector *self);
T Vector_back(Vector *self);
int Vector_insert(Vector *self, size_t idx, T elem);
int Vector_insert_n(Vector *self, size_t idx, T *elems, size_t n);
int Vector_push_back(Vector *self, T elem);
void Vector_erase(Vector *self, size_t idx);
void Vector_erase_n(Vector *self, size_t idx, size_t n);
T Vector_pop_back(Vector *self);
void Vector_clear(Vector *self);
int Vector_resize(Vector *self, size_t n, T elem);
dequeを使うには、deque.hというヘッダファイルをインクルードする。
#include <cstl/deque.h>
以下のマクロを用いてコードを展開する必要がある。
/* インターフェイスを展開 */ #define DEQUE_INTERFACE(Name, Type) /* 実装を展開 */ #define DEQUE_IMPLEMENT(Name, Type)
Nameに既存の型と重複しない任意の名前を、Typeに任意の要素の型を指定する。
malloc/freeが使用できない環境の場合は、DEQUE_IMPLEMENTマクロを展開する前に以下のマクロを定義する。
#define malloc(s) 0 #define free(p)
DEQUE_INTERFACEの引数のNameにDeque, TypeにTを指定した場合、 以下のインターフェイスを提供する。
Deque
コンテナの型。抽象データ型となっており、以下の関数によってのみアクセスできる。
Deque *Deque_new(size_t n);
Deque *Deque_new_copy(Deque *x);
void Deque_delete(Deque *self);
void Deque_init(Deque *self, T *buf, size_t n);
size_t Deque_size(Deque *self);
size_t Deque_max_size(Deque *self);
int Deque_empty(Deque *self);
int Deque_full(Deque *self);
int Deque_assign(Deque *self, T *elems, size_t n);
T *Deque_at(Deque *self, size_t idx);
T Deque_front(Deque *self);
T Deque_back(Deque *self);
int Deque_insert(Deque *self, size_t idx, T elem);
int Deque_insert_n(Deque *self, size_t idx, T *elems, size_t n);
int Deque_push_back(Deque *self, T elem);
int Deque_push_front(Deque *self, T elem);
void Deque_erase(Deque *self, size_t idx);
void Deque_erase_n(Deque *self, size_t idx, size_t n);
T Deque_pop_front(Deque *self);
T Deque_pop_back(Deque *self);
void Deque_clear(Deque *self);
int Deque_resize(Deque *self, size_t n, T elem);
listを使うには、list.hというヘッダファイルをインクルードする。
#include <cstl/list.h>
以下のマクロを用いてコードを展開する必要がある。
/* インターフェイスを展開 */ #define LIST_INTERFACE(Name, Type) /* 実装を展開 */ #define LIST_IMPLEMENT(Name, Type)
Nameに既存の型と重複しない任意の名前を、Typeに任意の要素の型を指定する。
LIST_INTERFACEの引数のNameにList, TypeにTを指定した場合、 以下のインターフェイスを提供する。
List
コンテナの型。抽象データ型となっており、以下の関数によってのみアクセスできる。
ListIterator
イテレータの型。要素の位置を示す。
List *List_new(void);
List *List_new_copy(List *x);
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);
int List_assign(List *self, T *elems, size_t n);
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_push_back(List *self, T elem);
int List_push_front(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);
set/multisetを使うには、set.hというヘッダファイルをインクルードする。
#include <cstl/set.h>
以下のマクロを用いてコードを展開する必要がある。
setの場合
/* インターフェイスを展開 */ #define SET_INTERFACE(Name, Type) /* 実装を展開 */ #define SET_IMPLEMENT(Name, Type, Compare, Order)
multisetの場合
/* インターフェイスを展開 */ #define MULTISET_INTERFACE(Name, Type) /* 実装を展開 */ #define MULTISET_IMPLEMENT(Name, Type, Compare, Order)
Nameに既存の型と重複しない任意の名前を、Typeに任意の要素の型を指定する。
Compareに要素の比較ルーチンを指定する。
Typeが整数型、小数型、ポインタ型など、2つの値を単純に比較できる型の場合、 SIMPLE_CMPマクロを指定する。SIMPLE_CMPマクロはヘッダで以下のように定義されている。
#define SIMPLE_CMP(x, y) ((x) - (y) == 0 ? 0 : (x) - (y) > 0 ? 1 : -1)
Typeがその他の型の場合、以下のような引数と戻り値を持ち、 xとyが一致なら0を不一致なら正または負の整数を返す比較ルーチンを用意して指定する。 尚、Typeが文字列型(char*)ならば、C標準関数のstrcmpが指定可能である。
int Compare(Type x, Type y);
Orderにソートの順序を以下から選択して指定する。
ASC /* 昇順 */ DESC /* 降順 */
SET_INTERFACE/MULTISET_INTERFACEの引数のNameにSet, TypeにTを指定した場合、 以下のインターフェイスを提供する。
Set
コンテナの型。抽象データ型となっており、以下の関数によってのみアクセスできる。
SetIterator
イテレータの型。要素の位置を示す。
Set *Set_new(void);
Set *Set_new_copy(Set *x);
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);
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);
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);
map/multimapを使うには、map.hというヘッダファイルをインクルードする。
#include <cstl/map.h>
以下のマクロを用いてコードを展開する必要がある。
mapの場合
/* インターフェイスを展開 */ #define MAP_INTERFACE(Name, KeyType, ValueType) /* 実装を展開 */ #define MAP_IMPLEMENT(Name, KeyType, ValueType, Compare, Order)
multimapの場合
/* インターフェイスを展開 */ #define MULTIMAP_INTERFACE(Name, KeyType, ValueType) /* 実装を展開 */ #define MULTIMAP_IMPLEMENT(Name, KeyType, ValueType, Compare, Order)
Nameに既存の型と重複しない任意の名前を、KeyTypeに任意の要素のキーの型を、ValueTypeに任意の要素の値の型を指定する。
Compareに要素の比較ルーチンを指定する。
KeyTypeが整数型、小数型、ポインタ型など、2つの値を単純に比較できる型の場合、 SIMPLE_CMPマクロを指定する。SIMPLE_CMPマクロはヘッダで以下のように定義されている。
#define SIMPLE_CMP(x, y) ((x) - (y) == 0 ? 0 : (x) - (y) > 0 ? 1 : -1)
KeyTypeがその他の型の場合、以下のような引数と戻り値を持ち、 xとyが一致なら0を不一致なら正または負の整数を返す比較ルーチンを用意して指定する。 尚、KeyTypeが文字列型(char*)ならば、C標準関数のstrcmpが指定可能である。
int Compare(KeyType x, KeyType y);
Orderにソートの順序を以下から選択して指定する。
ASC /* 昇順 */ DESC /* 降順 */
MAP_INTERFACE/MULTIMAP_INTERFACEの引数のNameにMap, KeyTypeにKeyT, ValueTypeにValueTを指定した場合、 以下のインターフェイスを提供する。
Map
コンテナの型。抽象データ型となっており、以下の関数によってのみアクセスできる。
MapIterator
イテレータの型。要素の位置を示す。
Map *Map_new(void);
Map *Map_new_copy(Map *x);
void Map_delete(Map *self);
size_t Map_size(Map *self);
int Map_empty(Map *self);
MapIterator Map_begin(Map *self);
MapIterator Map_end(Map *self);
MapIterator Map_rbegin(Map *self);
MapIterator Map_rend(Map *self);
MapIterator Map_next(MapIterator pos);
MapIterator Map_prev(MapIterator pos);
KeyT Map_key(MapIterator pos);
ValueT *Map_value(MapIterator pos);
ValueT *Map_lookup(Map *self, KeyT key);
MapIterator Map_insert(Map *self, KeyT key, ValueT value, int *success);
MapIterator Map_insert(Map *self, KeyT key, ValueT value);
MapIterator Map_erase(Map *self, MapIterator pos);
MapIterator Map_erase_range(Map *self, MapIterator first, MapIterator last);
size_t Map_erase_key(Map *self, KeyT key);
void Map_clear(Map *self);
size_t Map_count(Map *self, KeyT key);
MapIterator Map_find(Map *self, KeyT key);
MapIterator Map_lower_bound(Map *self, KeyT key);
MapIterator Map_upper_bound(Map *self, KeyT key);
stringを使うには、string.hというヘッダファイルをインクルードする。
#include <cstl/string.h>
以下のマクロを用いてコードを展開する必要がある。
/* インターフェイスを展開 */ #define STRING_INTERFACE(Name, Type) /* 実装を展開 */ #define STRING_IMPLEMENT(Name, Type)
Nameに既存の型と重複しない任意の名前を、Typeに任意の文字の型を指定する。
STRING_INTERFACEの引数のNameにString, TypeにCharTを指定した場合、 以下のインターフェイスを提供する。
#define NPOS ((size_t)-1)
String
コンテナの型。抽象データ型となっており、以下の関数によってのみアクセスできる。
String *String_new(void);
String *String_new_cstr(CharT *cstr, size_t cstr_len);
String *String_new_c(size_t n, CharT c);
String *String_new_copy(String *x);
void String_delete(String *self);
size_t String_size(String *self);
size_t String_length(String *self);
int String_empty(String *self);
size_t String_capacity(String *self);
int String_reserve(String *self, size_t n);
void String_shrink(String *self, size_t n);
int String_compare(String *x, String *y);
CharT *String_at(String *self, size_t idx);
CharT *String_c_str(String *self);
int String_assign(String *self, CharT *cstr, size_t cstr_len);
int String_assign_c(String *self, size_t n, CharT c);
int String_append(String *self, CharT *cstr, size_t cstr_len);
int String_append_c(String *self, size_t n, CharT c);
int String_push_back(String *self, CharT c);
int String_insert(String *self, size_t idx, CharT *cstr, size_t cstr_len);
int String_insert_c(String *self, size_t idx, size_t n, CharT c);
int String_replace(String *self, size_t idx, size_t len, CharT *cstr, size_t cstr_len);
int String_replace_c(String *self, size_t idx, size_t len, size_t n, CharT c);
void String_erase(String *self, size_t idx, size_t len);
void String_clear(String *self);
int String_resize(String *self, size_t n, CharT c);
size_t String_find(CharT *x, CharT *cstr, size_t idx, size_t cstr_len);
size_t String_find_c(CharT *x, CharT c, size_t idx);
size_t String_rfind(CharT *x, CharT *cstr, size_t idx, size_t cstr_len);
size_t String_rfind_c(CharT *x, CharT c, size_t idx);
size_t String_find_first_of(CharT *x, CharT *cstr, size_t idx, size_t cstr_len);
size_t String_find_first_of_c(CharT *x, CharT c, size_t idx);
size_t String_find_last_of(CharT *x, CharT *cstr, size_t idx, size_t cstr_len);
size_t String_find_last_of_c(CharT *x, CharT c, size_t idx);
size_t String_find_first_not_of(CharT *x, CharT *cstr, size_t idx, size_t cstr_len);
size_t String_find_first_not_of_c(CharT *x, CharT c, size_t idx);
size_t String_find_last_not_of(CharT *x, CharT *cstr, size_t idx, size_t cstr_len);
size_t String_find_last_not_of_c(CharT *x, CharT c, size_t idx);
本ソフトウェアのライセンスは、修正BSDライセンスに従う。
Copyright (c) 2006, KATO Noriaki All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Copyright (c) 2006, KATO Noriaki All rights reserved. ソースコード形式かバイナリ形式か、変更するかしないかを問わず、以下の条件を満た す場合に限り、再頒布および使用が許可されます。 1. ソースコードを再頒布する場合、上記の著作権表示、本条件一覧、および下記免責 条項を含めること。 2. バイナリ形式で再頒布する場合、頒布物に付属のドキュメント等の資料に、上記の 著作権表示、本条件一覧、および下記免責条項を含めること。 本ソフトウェアは、著作権者によって「現状のまま」提供されており、明示黙示を問わ ず、商業的な使用可能性、および特定の目的に対する適合性に関する暗黙の保証も含 め、またそれに限定されない、いかなる保証もありません。著作権者は、事由のいかん を問わず、損害発生の原因いかんを問わず、かつ責任の根拠が契約であるか厳格責任で あるか(過失その他の)不法行為であるかを問わず、仮にそのような損害が発生する可 能性を知らされていたとしても、本ソフトウェアの使用によって発生した(代替品また は代用サービスの調達、使用の喪失、データの喪失、利益の喪失、業務の中断も含め、 またそれに限定されない)直接損害、間接損害、偶発的な損害、特別損害、懲罰的損 害、または結果損害について、一切責任を負わないものとします。