1 /*
2 *
3 * kkconsui linkedlist class
4 * $Id: linkedlist.cc,v 1.2 2001/06/03 21:12:05 konst Exp $
5 *
6 * Copyright (C) 1999-2001 by Konstantin Klyagin <k@thekonst.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 * USA
22 *
23 */
24 
25 #include "linkedlist.h"
26 
linkedlist()27 linkedlist::linkedlist(): count(0), flist(0), freeitem(0) {
28 }
29 
~linkedlist()30 linkedlist::~linkedlist() {
31     empty();
32 //    if(flist) delete flist;
33 }
34 
add(void * p)35 void linkedlist::add(void *p) {
36     flinkedlist *l = flist, *k = new flinkedlist;
37 
38     k->data = p;
39     k->next = 0;
40 
41     if(!count) flist = k; else {
42 	for(i = 0; i < count-1; i++, l = l->next);
43 	l->next = k;
44     }
45 
46     count++;
47 }
48 
insert(int n,void * p)49 void linkedlist::insert(int n, void *p) {
50     if(n <= count) {
51         flinkedlist *l = flist, *k = new flinkedlist;
52 
53 	for(i = 0; i < n-1; i++, l = l->next);
54 	k->data = l->data;
55 	l->data = p;
56 	k->next = l->next;
57 	l->next = k;
58 	count++;
59     }
60     else{
61       add(p);
62     }
63 }
64 
remove(int n)65 void linkedlist::remove(int n) {
66     flinkedlist *l = flist, *pr;
67 
68     if((n < count) && (n >= 0)) {
69 	if(!n) {
70 	    flist = l->next;
71 	    if(freeitem) freeitem(l->data); else free(l->data);
72 	    delete l;
73 	} else {
74 	    for(pr = 0, i = 0; i < n; i++, l = l->next) {
75 		if(i == n-1) pr = l;
76 	    }
77 
78 	    if(pr) {
79 		pr->next = l->next;
80 		if(freeitem) freeitem(l->data); else free(l->data);
81 		delete l;
82 	    }
83 	}
84 
85 	count--;
86     }
87 }
88 
empty()89 void linkedlist::empty() {
90     flinkedlist *l, *p;
91 
92     for(i = 0, l = flist; i < count && l; i++) {
93 	p = l;
94 	l = l->next;
95 	if(freeitem) freeitem(p->data); else free(p->data);
96 	delete p;
97     }
98 
99     count = 0;
100 }
101 
at(int n)102 void* linkedlist::at(int n) {
103     flinkedlist *l = flist;
104 
105     if((n < count) && (n >= 0) && l) {
106 	for(i = 0; i < n; i++, l = l->next);
107 	return l->data;
108     } else {
109 	return 0;
110     }
111 }
112 
find(void * p,listcompare * compare)113 void* linkedlist::find(void *p, listcompare *compare) {
114     void *l;
115 
116     for(i = 0; i < count; i++) {
117 	l = at(i);
118 	if(!compare(p, l)) return l;
119     }
120 
121     return 0;
122 }
123 
findnum(void * p,listcompare * compare)124 int linkedlist::findnum(void *p, listcompare *compare) {
125     void *l;
126 
127     for(i = 0; i < count; i++) {
128 	l = at(i);
129 	if(!compare(p, l)) return i;
130     }
131 
132     return -1;
133 }
134 
sort(listcompare * compare)135 void linkedlist::sort(listcompare *compare) {
136     int i;
137     flinkedlist *f;
138     void *tempdata;
139 
140     for(i = 0; i < count; i++)
141     for(f = flist; f && f->next; f = f->next) {
142 	if(compare(f->next->data, f->data) > 0) {
143 	    tempdata = f->data;
144 	    f->data = f->next->data;
145 	    f->next->data = tempdata;
146 	}
147     }
148 }
149 
replace(int n,void * p)150 void linkedlist::replace(int n, void *p) {
151     flinkedlist *l = flist;
152 
153     if(n < count) {
154 	for(i = 0; i < n; i++, l = l->next);
155 	if(l->data != p) {
156 	    if(freeitem) freeitem(l->data); else free(l->data);
157 	    l->data = p;
158 	}
159     } else add(p);
160 }
161 
foreach(listforeachfunc * exec,void * arg)162 void *linkedlist::foreach(listforeachfunc *exec, void *arg) {
163     flinkedlist *l = flist;
164     void *ret = 0;
165 
166     for(; !ret && l; l = l->next) {
167 	ret = exec(l->data, arg);
168     }
169 
170     return ret;
171 }
172