]> git.saurik.com Git - wxWidgets.git/blob - samples/richedit/kbList.cpp
8d6d0327495b001dbdbc6ac41145495ffa2ee28d
[wxWidgets.git] / samples / richedit / kbList.cpp
1 /*-*- c++ -*-********************************************************
2 * kbList.cc : a double linked list *
3 * *
4 * (C) 1998 by Karsten Ballüder (Ballueder@usa.net) *
5 * *
6 * $Id$ *
7 * *
8 * $Log$
9 * Revision 1.4 2005/05/31 09:19:38 JS
10 * Typo correction patch [ 1208110 ] Lots of typo corrections
11 * Olly Betts
12 *
13 * Revision 1.3 2004/08/06 17:27:18 ABX
14 * Deleting void is undefined.
15 *
16 * Revision 1.2 2002/01/16 13:39:50 GT
17 * Added checks for wxUSE_IOSTREAMH to determine which iostream(.h) to use
18 *
19 * Revision 1.1 1999/06/07 09:57:12 KB
20 * Formerly known as wxLayout.
21 *
22 * Revision 1.3 1998/11/19 20:34:50 KB
23 * fixes
24 *
25 * Revision 1.8 1998/09/23 08:57:27 KB
26 * changed deletion behaviour
27 *
28 * Revision 1.7 1998/08/16 21:21:29 VZ
29 *
30 * 1) fixed config file bug: it was never created (attempt to create ~/.M/config
31 * always failed, must mkdir("~/.M") first)
32 * 2) "redesign" of "Folder properties" dialog and bug corrected, small change to
33 * MInputBox (it was too wide)
34 * 3) bug in ProvFC when it didn't recognize the books as being in the correct
35 * format (=> messages "can't reopen book") corrected
36 * 4) I tried to enhance MDialog_About(), but it didn't really work... oh well,
37 * I've never said I was an artist
38 *
39 * Revision 1.6 1998/07/08 11:56:56 KB
40 * M compiles and runs on Solaris 2.5/gcc 2.8/c-client gso
41 *
42 * Revision 1.5 1998/06/27 20:07:18 KB
43 * several bug fixes for kbList
44 * started adding my layout stuff
45 *
46 * Revision 1.1.1.1 1998/06/13 21:51:12 karsten
47 * initial code
48 *
49 * Revision 1.4 1998/05/24 14:48:00 KB
50 * lots of progress on Python, but cannot call functions yet
51 * kbList fixes again?
52 *
53 * Revision 1.3 1998/05/18 17:48:34 KB
54 * more list<>->kbList changes, fixes for wxXt, improved makefiles
55 *
56 * Revision 1.2 1998/05/14 16:39:31 VZ
57 *
58 * fixed SIGSEGV in ~kbList if the list is empty
59 *
60 * Revision 1.1 1998/05/13 19:02:11 KB
61 * added kbList, adapted MimeTypes for it, more python, new icons
62 *
63 *******************************************************************/
64
65 #ifdef __GNUG__
66 # pragma implementation "kbList.h"
67 #endif
68
69 #include "wx/wxprec.h"
70
71 #ifdef __BORLANDC__
72 # pragma hdrstop
73 #endif
74
75 #include "wx/wx.h"
76
77 #include "kbList.h"
78
79
80 kbListNode::kbListNode( void *ielement,
81 kbListNode *iprev,
82 kbListNode *inext)
83 {
84 next = inext;
85 prev = iprev;
86 if(prev)
87 prev->next = this;
88 if(next)
89 next->prev = this;
90 element = ielement;
91 }
92
93 kbListNode::~kbListNode()
94 {
95 if(prev)
96 prev->next = next;
97 if(next)
98 next->prev = prev;
99 }
100
101
102 kbList::iterator::iterator(kbListNode *n)
103 {
104 node = n;
105 }
106
107 void *
108 kbList::iterator::operator*()
109 {
110 return node->element;
111 }
112
113 kbList::iterator &
114 kbList::iterator::operator++()
115 {
116 node = node ? node->next : NULL;
117 return *this;
118 }
119
120 kbList::iterator &
121 kbList::iterator::operator--()
122 {
123 node = node ? node->prev : NULL;
124 return *this;
125 }
126 kbList::iterator &
127 kbList::iterator::operator++(int /* foo */)
128 {
129 return operator++();
130 }
131
132 kbList::iterator &
133 kbList::iterator::operator--(int /* bar */)
134 {
135 return operator--();
136 }
137
138
139 bool
140 kbList::iterator::operator !=(kbList::iterator const & i) const
141 {
142 return node != i.node;
143 }
144
145 bool
146 kbList::iterator::operator ==(kbList::iterator const & i) const
147 {
148 return node == i.node;
149 }
150
151 kbList::kbList(bool ownsEntriesFlag)
152 {
153 first = NULL;
154 last = NULL;
155 ownsEntries = ownsEntriesFlag;
156 }
157
158 void
159 kbList::push_back(void *element)
160 {
161 if(! first) // special case of empty list
162 {
163 first = new kbListNode(element);
164 last = first;
165 return;
166 }
167 else
168 last = new kbListNode(element, last);
169 }
170
171 void
172 kbList::push_front(void *element)
173 {
174 if(! first) // special case of empty list
175 {
176 push_back(element);
177 return;
178 }
179 else
180 first = new kbListNode(element, NULL, first);
181 }
182
183 void *
184 kbList::pop_back(void)
185 {
186 iterator i;
187 void *data;
188 bool ownsFlagBak = ownsEntries;
189 i = tail();
190 data = *i;
191 ownsEntries = false;
192 erase(i);
193 ownsEntries = ownsFlagBak;
194 return data;
195 }
196
197 void *
198 kbList::pop_front(void)
199 {
200 iterator i;
201 void *data;
202 bool ownsFlagBak = ownsEntries;
203
204 i = begin();
205 data = *i;
206 ownsEntries = false;
207 erase(i);
208 ownsEntries = ownsFlagBak;
209 return data;
210
211 }
212
213 void
214 kbList::insert(kbList::iterator & i, void *element)
215 {
216 if(! i.Node())
217 return;
218 else if(i.Node() == first)
219 {
220 push_front(element);
221 i = first;
222 return;
223 }
224 i = kbList::iterator(new kbListNode(element, i.Node()->prev, i.Node()));
225 }
226
227 void
228 kbList::doErase(kbList::iterator & i)
229 {
230 kbListNode
231 *node = i.Node(),
232 *prev, *next;
233
234 if(! node) // illegal iterator
235 return;
236
237 prev = node->prev;
238 next = node->next;
239
240 // correct first/last:
241 if(node == first)
242 first = node->next;
243 if(node == last) // don't put else here!
244 last = node->prev;
245
246 // build new links:
247 if(prev)
248 prev->next = next;
249 if(next)
250 next->prev = prev;
251
252 // delete this node and contents:
253 // now done separately
254 //if(ownsEntries)
255 //delete *i;
256 delete i.Node();
257
258 // change the iterator to next element:
259 i = kbList::iterator(next);
260 }
261
262 kbList::~kbList()
263 {
264 kbListNode *next;
265
266 while ( first != NULL )
267 {
268 next = first->next;
269 if(ownsEntries)
270 {
271 #if 0
272 delete first->element;
273 #else
274 wxLogError(wxT("Deleting `void*' is undefined."));
275 wxLogError(wxT("Entries of kbList should be deleted by destructors of derived classes."));
276 #endif
277 }
278 delete first;
279 first = next;
280 }
281 }
282
283 kbList::iterator
284 kbList::begin(void) const
285 {
286 return kbList::iterator(first);
287 }
288
289 kbList::iterator
290 kbList::tail(void) const
291 {
292 return kbList::iterator(last);
293 }
294
295 kbList::iterator
296 kbList::end(void) const
297 {
298 return kbList::iterator(NULL); // the one after the last
299 }
300
301 unsigned
302 kbList::size(void) const // inefficient
303 {
304 unsigned count = 0;
305 kbList::iterator i;
306 for(i = begin(); i != end(); i++, count++)
307 ;
308 return count;
309 }
310
311
312
313
314
315
316
317 #ifdef KBLIST_TEST
318
319 #if wxUSE_IOSTREAMH
320 #include <iostream.h>
321 #else
322 #include <iostream>
323 #endif
324
325 KBLIST_DEFINE(kbListInt,int);
326
327 int main(void)
328 {
329 int
330 n, *ptr;
331 kbListInt
332 l;
333 kbListInt::iterator
334 i;
335
336 for(n = 0; n < 10; n++)
337 {
338 ptr = new int;
339 *ptr = n*n;
340 l.push_back(ptr);
341 }
342
343 i = l.begin(); // first element
344 i++; // 2nd
345 i++; // 3rd
346 i++; // 4th, insert here:
347 ptr = new int;
348 *ptr = 4444;
349 l.insert(i,ptr);
350
351 // this cannot work, because l.end() returns NULL:
352 i = l.end(); // behind last
353 i--; // still behind last
354 l.erase(i); // doesn't do anything
355
356 // this works:
357 i = l.tail(); // last element
358 i--;
359 --i;
360 l.erase(i); // erase 3rd last element (49)
361
362 for(i = l.begin(); i != l.end(); i++)
363 cout << *i << '\t' << *((int *)*i) << endl;
364
365
366 return 0;
367 }
368 #endif