1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 /*[]---------------------------------------------------[]*/
22 /*| list.c - bidirectional list class |*/
25 /*| Author: Alexander Gelfenbain |*/
26 /*[]---------------------------------------------------[]*/
28 #include <rtl/alloc.h>
33 /*- private data types */
43 lnode
*head
, *tail
, *cptr
;
45 list_destructor eDtor
;
48 /*- private methods */
50 static lnode
*newNode(void *el
)
52 lnode
*ptr
= static_cast<lnode
*>(rtl_allocateMemory(sizeof(lnode
)));
53 assert(ptr
!= nullptr);
60 static lnode
*appendPrim(list pThis
, void *el
)
62 lnode
*ptr
= newNode(el
);
63 lnode
**flink
, *blink
;
65 if (pThis
->tail
!= nullptr) {
66 flink
= &(pThis
->tail
->next
);
71 pThis
->cptr
= ptr
; /*- list was empty - set current to this element */
85 list
listNewEmpty() /*- default ctor */
87 list pThis
= static_cast<list
>(rtl_allocateMemory(sizeof(struct list_
)));
88 assert(pThis
!= nullptr);
91 pThis
->eDtor
= nullptr;
92 pThis
->head
= pThis
->tail
= pThis
->cptr
= nullptr;
97 void listDispose(list pThis
) /*- dtor */
99 assert(pThis
!= nullptr);
101 rtl_freeMemory(pThis
);
104 void listSetElementDtor(list pThis
, list_destructor f
)
106 assert(pThis
!= nullptr);
110 /* calling this function on an empty list is a run-time error */
111 void *listCurrent(list pThis
)
113 assert(pThis
!= nullptr);
114 assert(pThis
->cptr
!= nullptr);
115 return pThis
->cptr
->value
;
118 int listCount(list pThis
)
120 assert(pThis
!= nullptr);
121 return pThis
->aCount
;
124 int listIsEmpty(list pThis
)
126 assert(pThis
!= nullptr);
127 return pThis
->aCount
== 0;
130 int listNext(list pThis
)
132 return listSkipForward(pThis
, 1);
135 int listSkipForward(list pThis
, int n
)
138 assert(pThis
!= nullptr);
140 if (pThis
->cptr
== nullptr) return 0;
143 if (pThis
->cptr
->next
== nullptr) break;
144 pThis
->cptr
= pThis
->cptr
->next
;
151 int listToFirst(list pThis
)
153 assert(pThis
!= nullptr);
155 if (pThis
->cptr
!= pThis
->head
) {
156 pThis
->cptr
= pThis
->head
;
162 int listToLast(list pThis
)
164 assert(pThis
!= nullptr);
166 if (pThis
->cptr
!= pThis
->tail
) {
167 pThis
->cptr
= pThis
->tail
;
173 list
listAppend(list pThis
, void *el
)
175 assert(pThis
!= nullptr);
177 appendPrim(pThis
, el
);
181 list
listRemove(list pThis
)
183 lnode
*ptr
= nullptr;
184 if (pThis
->cptr
== nullptr) return pThis
;
186 if (pThis
->cptr
->next
!= nullptr) {
187 ptr
= pThis
->cptr
->next
;
188 pThis
->cptr
->next
->prev
= pThis
->cptr
->prev
;
190 pThis
->tail
= pThis
->cptr
->prev
;
193 if (pThis
->cptr
->prev
!= nullptr) {
194 if (ptr
== nullptr) ptr
= pThis
->cptr
->prev
;
195 pThis
->cptr
->prev
->next
= pThis
->cptr
->next
;
197 pThis
->head
= pThis
->cptr
->next
;
200 if (pThis
->eDtor
) pThis
->eDtor(pThis
->cptr
->value
); /* call the dtor callback */
202 rtl_freeMemory(pThis
->cptr
);
208 list
listClear(list pThis
)
210 lnode
*node
= pThis
->head
, *ptr
;
214 if (pThis
->eDtor
) pThis
->eDtor(node
->value
); /* call the dtor callback */
215 rtl_freeMemory(node
);
220 pThis
->head
= pThis
->tail
= pThis
->cptr
= nullptr;
221 assert(pThis
->aCount
== 0);
225 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */