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 /*[]---------------------------------------------------[]*/
35 /*- private data types */
47 lnode
*head
, *tail
, *cptr
;
49 list_destructor eDtor
;
52 /*- private methods */
54 static lnode
*newNode(void *el
)
56 lnode
*ptr
= static_cast<lnode
*>(std::malloc(sizeof(lnode
)));
57 assert(ptr
!= nullptr);
64 static lnode
*appendPrim(list pThis
, void *el
)
66 lnode
*ptr
= newNode(el
);
67 lnode
**flink
, *blink
;
69 if (pThis
->tail
!= nullptr) {
70 flink
= &(pThis
->tail
->next
);
75 pThis
->cptr
= ptr
; /*- list was empty - set current to this element */
89 list
listNewEmpty() /*- default ctor */
91 list pThis
= static_cast<list
>(std::malloc(sizeof(struct list_
)));
92 assert(pThis
!= nullptr);
95 pThis
->eDtor
= nullptr;
96 pThis
->head
= pThis
->tail
= pThis
->cptr
= nullptr;
101 void listDispose(list pThis
) /*- dtor */
103 assert(pThis
!= nullptr);
108 void listSetElementDtor(list pThis
, list_destructor f
)
110 assert(pThis
!= nullptr);
114 /* calling this function on an empty list is a run-time error */
115 void *listCurrent(list pThis
)
117 assert(pThis
!= nullptr);
118 assert(pThis
->cptr
!= nullptr);
119 return pThis
->cptr
->value
;
122 int listCount(list pThis
)
124 assert(pThis
!= nullptr);
125 return pThis
->aCount
;
128 int listIsEmpty(list pThis
)
130 assert(pThis
!= nullptr);
131 return pThis
->aCount
== 0;
134 int listNext(list pThis
)
136 return listSkipForward(pThis
, 1);
139 int listSkipForward(list pThis
, int n
)
142 assert(pThis
!= nullptr);
144 if (pThis
->cptr
== nullptr) return 0;
147 if (pThis
->cptr
->next
== nullptr) break;
148 pThis
->cptr
= pThis
->cptr
->next
;
155 int listToFirst(list pThis
)
157 assert(pThis
!= nullptr);
159 if (pThis
->cptr
!= pThis
->head
) {
160 pThis
->cptr
= pThis
->head
;
166 int listToLast(list pThis
)
168 assert(pThis
!= nullptr);
170 if (pThis
->cptr
!= pThis
->tail
) {
171 pThis
->cptr
= pThis
->tail
;
177 list
listAppend(list pThis
, void *el
)
179 assert(pThis
!= nullptr);
181 appendPrim(pThis
, el
);
185 list
listRemove(list pThis
)
187 lnode
*ptr
= nullptr;
188 if (pThis
->cptr
== nullptr) return pThis
;
190 if (pThis
->cptr
->next
!= nullptr) {
191 ptr
= pThis
->cptr
->next
;
192 pThis
->cptr
->next
->prev
= pThis
->cptr
->prev
;
194 pThis
->tail
= pThis
->cptr
->prev
;
197 if (pThis
->cptr
->prev
!= nullptr) {
198 if (ptr
== nullptr) ptr
= pThis
->cptr
->prev
;
199 pThis
->cptr
->prev
->next
= pThis
->cptr
->next
;
201 pThis
->head
= pThis
->cptr
->next
;
204 if (pThis
->eDtor
) pThis
->eDtor(pThis
->cptr
->value
); /* call the dtor callback */
206 std::free(pThis
->cptr
);
212 list
listClear(list pThis
)
214 lnode
*node
= pThis
->head
, *ptr
;
218 if (pThis
->eDtor
) pThis
->eDtor(node
->value
); /* call the dtor callback */
224 pThis
->head
= pThis
->tail
= pThis
->cptr
= nullptr;
225 assert(pThis
->aCount
== 0);
229 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */