/*
 * リストコンテナライブラリ
 */

#ifndef MINATO__LIST_H
#define MINATO__LIST_H

#define BOOL int
#define TRUE 1
#define FALSE 0

/* リストオブジェクト */
typedef struct _list_it {
   void* mItem;
   
   struct _list_it* mPrevIt;
   struct _list_it* mNextIt;
} list_it;

typedef struct {
   list_it* mEntryIt;
   list_it* mLastIt;
   int mCount;
} list_obj;

///////////////////////////////////////////////////////////////////////
// 関数宣言
///////////////////////////////////////////////////////////////////////
// 初期化
#ifdef MDEBUG

list_obj* list_new_debug(const char* fname, int line, const char* func_name);
#define LIST_NEW() list_new_debug(__FILE__, __LINE__, __FUNCTION__)

#else

list_obj* list_new();
#define LIST_NEW() list_new()

#endif

void list_delete(list_obj* self);       // 解放

int list_size(list_obj* self);                      // サイズ
BOOL list_empty(list_obj* self);                    // 空かどうか
int list_index_of(list_obj* self, void* item);      // アイテムのインデックス
void list_push_front(list_obj* self, void* item);   // アイテムを前から追加
void list_push_back(list_obj* self, void* item);    // アイテムを後ろから追加
void* list_pop_front(list_obj* self);               // 前からアイテムを取り出す
void* list_pop_back(list_obj* self);                // 後ろからアイテムを取り出す
void list_clear(list_obj* self);                    // アイテムをクリア

list_it* list_begin(list_obj* self);                // 先頭のリストイテレーターを取り出す
list_it* list_last(list_obj* self);                 // 最後のリストイテレーターを取り出す
list_it* list_at(list_obj* self, int index);        // 任意の場所のリストイテレーターを取りだす
list_it* list_find(list_obj* self, void* item);     // 引数のアイテムのイテレーターを取り出す
void* list_item(list_it* self);                     // イテレーターからアイテムを取り出す
list_it* list_next(list_it* self);                  // イテレーターから次のイテレーターを取り出す
list_it* list_prev(list_it* self);                  // イテレーターから前のイテレーターを取り出す
void list_replace(list_it* self, void* item);       // イテレーターのアイテムを置き換える
void list_erase(list_it* self, list_obj* owner);    // イテレーターのアイテムを削除する
void list_insert_front(list_it* self, void* item, list_obj* owner);     // イテレーターの前にアイテムを追加する
void list_insert_back(list_it* self, void* item, list_obj* owner);      // イテレーターの後ろにアイテムを追加する

/*
    全走査例
    
    for(list_it* i=list_begin(gList); i; i=list_next(i)) {
        sItem* item = (sItem*)list_item(i);
    }
*/

#endif
