/** * @file kc_list.h * @brief List モジュールヘッダファイル * @copyright 2002 - 2023 Nomura Kei * @depends * kc.h * kc_macro.h */ #ifndef KC_LIST_H #define KC_LIST_H #include <kc.h> #include <kc_macro.h> typedef struct { } KcIterator; /** * 単一種類の要素を扱うことが可能なリスト。 */ typedef struct KcList_ { /** * 対象リスト内にある要素の数を返します。 * * @param list 対象リスト * @return 対象リスト内の要素数 */ int (*size)(struct KcList_* list); /** * 対象リストに要素がない場合に true を返します。 * * @param list 対象リスト * @return 対象リストに要素が含まれていない場合は true */ bool (*is_empty)(struct KcList_* list); /** * 指定の要素が対象リストに含まれている場合に true を返します。 * 要素サイズ固定のリストを扱う場合、size の値は無視されます。 * * @param list 対象リスト * @param element 対象リスト内にあるかどうか判定される要素 * @param size 要素のサイズ * @return 指定された要素が対象リスト内にある場合は true */ bool (*contains)(struct KcList_* list, const void* element, size_t size); /** * 対象リスト内の指定された位置に、指定された要素を挿入します。 * その位置の現在の要素(ある場合)とそれ以降の要素を右に移動します。(インデックスに1を加算)。 * 要素サイズ固定のリストを扱う場合、size の値は無視されます。 * * @param list 対象リスト * @param index 指定の要素が挿入される位置のインデックス * @param element 挿入される要素 * @param size 要素のサイズ * @return true/false (格納成功/失敗) */ bool (*add)(struct KcList_* list, int index, const void* element, size_t size); /** * 対象リスト内の指定された位置にある要素を削除します。 * 後続の要素を左に移動します(インデックスから1を減算)。 * element が NULL でない場合、削除された要素のコピーが格納されます。 * size が NULL でない場合、削除された要素のサイズが格納されます。 * * @param list 対象リスト * @param index 削除される要素のインデックス * @param element 削除された要素のコピーが格納されます。 * @param size 削除された要素のサイズが格納されます。 * @return true/false (削除成功/失敗) */ bool (*remove)(struct KcList_* list, int index, void* element, size_t* size); /** * 指定された comparator が示す順序に従って、対象リストをソートします。 * * @param list 対象リスト * @param comparator リスト要素を比較するために使用される comparator * @param args comparator の第5引数に渡すオブジェクト * @return true/false (ソート成功/ソート失敗) */ void (*sort)(struct KcList_* list, int (*comparator)(const void* element1, size_t size1, const void* element2, size_t size2, void* args), void* args); /** * すべての要素を対象リストから削除します。 * * @param list 対象リスト */ void (*clear)(struct KcList_* list); /** * 対象リスト内の指定された位置にある要素を返します。 * * @param list 対象リスト * @param index 取得する要素のインデックス * @param size 要素のサイズを格納するポインタ * @return 対象リスト内の指定された位置にある要素 */ void* (*get)(struct KcList_* list, int index, size_t* size); /** * 対象リスト内の指定された位置にある要素を、指定された要素に置き換えます。 * 要素サイズ固定のリストを扱う場合、size の値は無視されます。 * org_element が NULL でない場合、置き換え前の要素のコピーが格納されます。 * org_size が NULL でない場合、置き換え前の要素のサイズが格納されます。 * * @param list 対象リスト * @param index 置換される要素のインデックス * @param element 指定された位置に格納される要素 * @param size 指定された位置に格納される要素のサイズ * @param org_element 指定された位置に以前あった要素のコピーが格納されます。 * @param org_size 指定された位置に以前あった要素のサイズが格納されます。 * @return true/false (置換成功/失敗) */ bool (*set)(struct KcList_* list, int index, const void* element, size_t size, void* org_element, size_t* org_size); /** * 指定された要素がこのリスト内で最初に検出された位置のインデックスを返します。 * 指定された要素がこのリストにない場合は -1 を返します。 * 要素サイズ固定のリストを扱う場合、size の値は無視されます。 * * @param list 対象リスト * @param element 検索する要素 * @param size 検索する要素のサイズ * @return 指定された要素がこのリスト内で最初に検出された位置のインデックス */ int (*index_of)(struct KcList_* list, const void* element, size_t size); /** * 指定された要素がこのリスト内で最後に検出された位置のインデックスを返します。 * 指定された要素がこのリストにない場合は -1 を返します。 * 要素サイズ固定のリストを扱う場合、size の値は無視されます。 * * @param list 対象リスト * @param element 検索する要素 * @param size 検索する要素のサイズ * @return 指定された要素がこのリスト内で最後に検出された位置のインデックス */ int (*last_index_of)(struct KcList_* list, const void* element, size_t size); /** * このリスト内の指定された位置で始まる、リスト内の要素を反復するイテレータを返します。 * * @param list 対象リスト * @param index イテレータから返される最初の要素のインデックス * @return リスト内の指定された位置で始まる、リスト内の要素を反復するイテレータ */ KcIterator* (*iterator)(struct KcList_* list, int index); /** * リスト管理情報 * 本オブジェクトはリスト実装者が利用するための情報へのポインタとなります。 */ void* _info; } KcList; /** * サイズ固定の要素を管理する ArrayList を構築します。 * * @param element_size 要素のサイズ * @param capacity 初期容量 * @return ArrayList */ KcList* KcList_new_ArrayList(size_t element_size, int capacity); /** * LinkedList を構築します。 * * @return LinkedList */ KcList* KcList_new_LinkedList(void); /** * 渡されたポインタをそのまま要素として管理する LinkedList を構築します。 * * autofree が true の場合、 * 次のメソッド呼び出し時に、不要となった要素のメモリを解放します。 * - remove * - clear * - set * また、リストに渡す要素は、malloc 等で確保された要素とする必要があります。 * * autofree が false の場合、 * リスト内では要素のメモリ管理は実施せず、利用する側で管理する必要があります。 * * @param autofree true/false */ KcList* KcList_new_LinkedList_nocopy(bool autofree); /** * KcList を破棄します。 * * @param list 破棄するリスト */ void KcList_delete(KcList* list); #endif // KC_LIST_H