123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396 |
- /*****************************************************************************/
- /* Obj.c - A library for object list. */
- /* */
- /* Obj.c Copyright (c) 2000 Sakai Hiroaki. */
- /* All Rights Reserved. */
- /*****************************************************************************/
- #include "ObjP.h"
- /*****************************************************************************/
- /* ObjListData 型の操作 */
- /*****************************************************************************/
- static ObjListData ObjListData_Create(Obj obj, Obj (*destructor)())
- {
- ObjListData list_data;
- list_data = (ObjListData)malloc(sizeof(_ObjListData));
- list_data->obj = obj;
- list_data->destructor = destructor;
- return (list_data);
- }
- static ObjListData ObjListData_Destroy(ObjListData list_data)
- {
- if (list_data == NULL) return (NULL);
- /* デストラクタの実行 */
- if (list_data->destructor)
- (*(list_data->destructor))(list_data->obj);
- free(list_data);
- return (NULL);
- }
- /*****************************************************************************/
- /* ObjList 型オブジェクトの操作 */
- /*****************************************************************************/
- Obj ObjListData_GetObj(ObjListData data)
- {
- if (data == NULL) return (NULL);
- return (data->obj);
- }
- ObjListData ObjListData_GetPrev(ObjListData data)
- {
- if (data == NULL) return (NULL);
- return (data->prev);
- }
- ObjListData ObjListData_GetNext(ObjListData data)
- {
- if (data == NULL) return (NULL);
- return (data->next);
- }
- int ObjList_GetLength(ObjList list)
- {
- if (list == NULL) return (-1);
- return (list->length);
- }
- ObjListData ObjList_GetStartEdge(ObjList list)
- {
- if (list == NULL) return (NULL);
- return (list->start_edge);
- }
- ObjListData ObjList_GetEndEdge(ObjList list)
- {
- if (list == NULL) return (NULL);
- return (list->end_edge);
- }
- ObjListData ObjList_GetStart(ObjList list)
- {
- if (list == NULL) return (NULL);
- return (list->start_edge->next);
- }
- ObjListData ObjList_GetEnd(ObjList list)
- {
- if (list == NULL) return (NULL);
- return (list->end_edge->prev);
- }
- int ObjList_IsEmpty(ObjList list)
- {
- if (list == NULL) return (1);
- return (list->start_edge->next == list->end_edge);
- }
- int ObjList_IsStartEdge(ObjList list, ObjListData data)
- {
- if (list == NULL) return (0);
- return (data == list->start_edge);
- }
- int ObjList_IsEndEdge(ObjList list, ObjListData data)
- {
- if (list == NULL) return (0);
- return (data == list->end_edge);
- }
- int ObjList_IsStart(ObjList list, ObjListData data)
- {
- if (list == NULL) return (0);
- return (data == list->start_edge->next);
- }
- int ObjList_IsEnd(ObjList list, ObjListData data)
- {
- if (list == NULL) return (0);
- return (data == list->end_edge->prev);
- }
- ObjListData ObjList_InsertObjToPrev(ObjList list, ObjListData current,
- Obj obj, Obj (*destructor)())
- {
- ObjListData data;
- if (list == NULL) return (NULL);
- if (ObjList_IsStartEdge(list, current)) return (NULL);
- data = ObjListData_Create(obj, destructor);
- if (data == NULL) return (NULL);
- data->prev = current->prev;
- data->next = current;
- current->prev->next = data;
- current->prev = data;
- (list->length)++;
- return (data);
- }
- ObjListData ObjList_InsertObjToNext(ObjList list, ObjListData current,
- Obj obj, Obj (*destructor)())
- {
- ObjListData data;
- if (list == NULL) return (NULL);
- if (ObjList_IsEndEdge(list, current)) return (NULL);
- data = ObjListData_Create(obj, destructor);
- if (data == NULL) return (NULL);
- data->next = current->next;
- data->prev = current;
- current->next->prev = data;
- current->next = data;
- (list->length)++;
- return (data);
- }
- ObjListData ObjList_InsertObjToStart(ObjList list, Obj obj,
- Obj (*destructor)())
- {
- ObjListData current;
- current = ObjList_GetStart(list);
- return (ObjList_InsertObjToPrev(list, current, obj, destructor));
- }
- ObjListData ObjList_InsertObjToEnd(ObjList list, Obj obj,
- Obj (*destructor)())
- {
- ObjListData current;
- current = ObjList_GetEnd(list);
- return (ObjList_InsertObjToNext(list, current, obj, destructor));
- }
- ObjListData ObjList_DeleteObjToPrev(ObjList list, ObjListData current)
- {
- ObjListData ret;
- if (list == NULL) return (NULL);
- if (ObjList_IsStartEdge(list, current) || ObjList_IsEndEdge(list, current))
- return (NULL);
- current->prev->next = current->next;
- current->next->prev = current->prev;
- ret = current->prev;
- ObjListData_Destroy(current);
- (list->length)--;
- return (ret);
- }
- ObjListData ObjList_DeleteObjToNext(ObjList list, ObjListData current)
- {
- ObjListData ret;
- if (list == NULL) return (NULL);
- if (ObjList_IsStartEdge(list, current) || ObjList_IsEndEdge(list, current))
- return (NULL);
- current->prev->next = current->next;
- current->next->prev = current->prev;
- ret = current->next;
- ObjListData_Destroy(current);
- (list->length)--;
- return (ret);
- }
- ObjListData ObjList_DeleteObjFromStart(ObjList list)
- {
- ObjListData current;
- if (list == NULL) return (NULL);
- current = ObjList_GetStart(list);
- return (ObjList_DeleteObjToNext(list, current));
- }
- ObjListData ObjList_DeleteObjFromEnd(ObjList list)
- {
- ObjListData current;
- if (list == NULL) return (NULL);
- current = ObjList_GetEnd(list);
- return (ObjList_DeleteObjToPrev(list, current));
- }
- ObjListData ObjList_MoveObjToPrev(ObjList list,
- ObjListData current,
- ObjListData to)
- {
- if (list == NULL) return (NULL);
- return (ObjList_MoveObjToPrevOfOtherList(list, current, list, to));
- }
- ObjListData ObjList_MoveObjToNext(ObjList list,
- ObjListData current,
- ObjListData to)
- {
- if (list == NULL) return (NULL);
- return (ObjList_MoveObjToNextOfOtherList(list, current, list, to));
- }
- ObjListData ObjList_MoveObjToStart(ObjList list, ObjListData current)
- {
- if (list == NULL) return (NULL);
- return (ObjList_MoveObjToStartOfOtherList(list, current, list));
- }
- ObjListData ObjList_MoveObjToEnd(ObjList list, ObjListData current)
- {
- if (list == NULL) return (NULL);
- return (ObjList_MoveObjToEndOfOtherList(list, current, list));
- }
- ObjList ObjList_Create() /* ObjList 型オブジェクトを作成する */
- {
- ObjList list;
- list = (ObjList)malloc(sizeof(_ObjList));
- if (list == NULL) return (NULL);
- list->start_edge = ObjListData_Create(NULL, NULL);
- list->end_edge = ObjListData_Create(NULL, NULL);
- list->length = 0; /* 現在存在しているデータの数 */
- list->start_edge->prev = NULL;
- list->start_edge->next = list->end_edge;
- list->end_edge->prev = list->start_edge;
- list->end_edge->next = NULL;
- return (list);
- }
- ObjList ObjList_Destroy(ObjList list) /* */
- {
- if (list == NULL) return (NULL);
- while (!ObjList_IsEmpty(list))
- ObjList_DeleteObjFromStart(list);
- if (list->start_edge)
- list->start_edge = ObjListData_Destroy(list->start_edge);
- if (list->end_edge)
- list->end_edge = ObjListData_Destroy(list->end_edge);
- free(list);
- return (NULL);
- }
- /*===========================================================================*/
- /* 複数のリスト間での操作 */
- /*===========================================================================*/
- ObjListData ObjList_MoveObjToPrevOfOtherList(ObjList list, ObjListData current,
- ObjList to_list, ObjListData to)
- {
- if (list == NULL) return (NULL);
- if (to_list == NULL) return (NULL);
- if (ObjList_IsStartEdge(list, current) || ObjList_IsEndEdge(list, current))
- return (NULL);
- if (ObjList_IsStartEdge(to_list, to)) return (NULL);
- if ((list == to_list) && (current == to)) return (current);
- current->prev->next = current->next;
- current->next->prev = current->prev;
- current->prev = to->prev;
- current->next = to;
- to->prev->next = current;
- to->prev = current;
- (list->length)--;
- (to_list->length)++;
- return (current);
- }
- ObjListData ObjList_MoveObjToNextOfOtherList(ObjList list, ObjListData current,
- ObjList to_list, ObjListData to)
- {
- if (list == NULL) return (NULL);
- if (ObjList_IsStartEdge(list, current) || ObjList_IsEndEdge(list, current))
- return (NULL);
- if (ObjList_IsEndEdge(to_list, to)) return (NULL);
- if ((list == to_list) && (current == to)) return (current);
- current->prev->next = current->next;
- current->next->prev = current->prev;
- current->next = to->next;
- current->prev = to;
- to->next->prev = current;
- to->next = current;
- (list->length)--;
- (to_list->length)++;
- return (current);
- }
- ObjListData ObjList_MoveObjToStartOfOtherList(ObjList list,
- ObjListData current,
- ObjList to_list)
- {
- ObjListData to;
- if (list == NULL) return (NULL);
- if (to_list == NULL) return (NULL);
- to = ObjList_GetStart(to_list);
- return (ObjList_MoveObjToPrevOfOtherList(list, current, to_list, to));
- }
- ObjListData ObjList_MoveObjToEndOfOtherList(ObjList list,
- ObjListData current,
- ObjList to_list)
- {
- ObjListData to;
- if (list == NULL) return (NULL);
- if (to_list == NULL) return (NULL);
- to = ObjList_GetEnd(to_list);
- return (ObjList_MoveObjToNextOfOtherList(list, current, to_list, to));
- }
- ObjList ObjList_Concatenate(ObjList list1, ObjList list2)
- {
- ObjListData tmp;
- if (list1 == NULL) {
- list1 = list2;
- return (list1);
- }
- if (list2 == NULL) return (list1);
- list1->end_edge->prev->next = list2->start_edge->next;
- list2->start_edge->next->prev = list1->end_edge->prev;
- tmp = list1->end_edge;
- list1->end_edge = list2->end_edge;
- list2->end_edge = tmp;
- list2->start_edge->next = list2->end_edge;
- list2->end_edge->prev = list2->start_edge;
- list1->length += list2->length;
- list2->length = 0;
- ObjList_Destroy(list2);
- return (list1);
- }
- /* End of File. */
|