source: git/factory/templates/ftmpl_list.cc @ ddbd52

spielwiese
Last change on this file since ddbd52 was ddbd52, checked in by Jens Schmidt <schmidt@…>, 27 years ago
stream-io wrapped by NOSTREAMIO error check changed to ASSERT git-svn-id: file:///usr/local/Singular/svn/trunk@111 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 9.7 KB
Line 
1// emacs edit mode for this file is -*- C++ -*-
2// $Id: ftmpl_list.cc,v 1.1 1997-03-27 10:31:57 schmidt Exp $
3
4/*
5$Log: not supported by cvs2svn $
6Revision 1.0  1996/05/17 11:06:32  stobbe
7Initial revision
8
9*/
10
11#include <templates/assert.h>
12
13#include <templates/list.h>
14
15template <class T>
16ListItem<T>::ListItem( const ListItem<T>& i )
17{
18    next = i.next;
19    prev = i.prev;
20    item = i.item;
21}
22
23
24template <class T>
25ListItem<T>::ListItem( const T& t, ListItem<T>* n, ListItem<T>* p )
26{
27    next = n;
28    prev = p;
29    item = new T( t );
30}
31
32
33template <class T>
34ListItem<T>::ListItem( T* t, ListItem<T>* n, ListItem<T>* p )
35{
36    next = n;
37    prev = p;
38    item = t;
39}
40
41
42template <class T>
43ListItem<T>::~ListItem()
44{
45    delete item;
46}
47
48
49template <class T>
50ListItem<T>& ListItem<T>::operator=( const ListItem<T>& i )
51{
52    if ( this != &i ) {
53        next = i.next;
54        prev = i.prev;
55        item = i.item;
56    }
57    return *this;
58}
59
60
61template <class T>
62ListItem<T>* ListItem<T>::getNext()
63{
64    return next;
65}
66
67
68template <class T>
69ListItem<T>* ListItem<T>::getPrev()
70{
71    return prev;
72}
73
74
75template <class T>
76T& ListItem<T>::getItem()
77{
78    return *item;
79}
80
81#ifndef NOSTREAMIO
82template <class T>
83void ListItem<T>::print( ostream & os )
84{
85    if ( item )
86        os << *item;
87    else
88        os << "(no item)";
89}
90#endif /* NOSTREAMIO */
91
92
93
94template <class T>
95List<T>::List()
96{
97    first = last = 0;
98    _length = 0;
99}
100
101
102template <class T>
103List<T>::List( const List<T>& l )
104{
105    ListItem<T>* cur = l.last;
106    if ( cur ) {
107        first = new ListItem<T>( *(cur->item), 0, 0 );
108        last = first;
109        cur = cur->prev;
110        while ( cur ) {
111            first = new ListItem<T>( *(cur->item), first, 0 );
112            first->next->prev = first;
113            cur = cur->prev;
114        }
115        _length = l._length;
116    }
117    else {
118        first = last = 0;
119        _length = 0;
120    }
121}
122
123
124template <class T>
125List<T>::List( const T& t )
126{
127    first = last = new ListItem<T>( t, 0, 0 );
128    _length = 1;
129}
130
131
132template <class T>
133List<T>::~List()
134{
135    ListItem<T> *dummy;
136    while ( first ) {
137        dummy = first;
138        first = first->next;
139        delete dummy;
140    }
141}
142
143
144template <class T>
145List<T>& List<T>::operator=( const List<T>& l )
146{
147    if ( this != &l ) {
148        ListItem<T> *dummy;
149        while ( first ) {
150            dummy = first;
151            first = first->next;
152            delete dummy;
153        }
154        ListItem<T>* cur = l.last;
155        if ( cur ) {
156            first = new ListItem<T>( *(cur->item), 0, 0 );
157            last = first;
158            cur = cur->prev;
159            while ( cur ) {
160                first = new ListItem<T>( *(cur->item), first, 0 );
161                first->next->prev = first;
162                cur = cur->prev;
163            }
164            _length = l._length;
165        }
166        else {
167            first = last = 0;
168            _length = 0;
169        }
170        _length = l._length;
171    }
172    return *this;
173}
174
175
176template <class T>
177void List<T>::insert ( const T& t )
178{
179    first = new ListItem<T>( t, first, 0 );
180    if ( last )
181        first->next->prev = first;
182    last = ( last ) ? last : first;
183    _length++;
184}
185
186
187template <class T>
188void List<T>::insert ( const T& t, int (*cmpf)( const T&, const T& ) )
189{
190    if ( ! first || cmpf( *first->item, t ) > 0 )
191        insert( t );
192    else if ( cmpf( *last->item, t ) < 0 )
193        append( t );
194    else {
195        ListItem<T> * cursor = first;
196        int c;
197        while ( (c = cmpf( *cursor->item, t )) < 0 )
198            cursor = cursor->next;
199        if ( c == 0 )
200            *cursor->item = t;
201        else {
202            cursor = cursor->prev;
203            cursor->next = new ListItem<T>( t, cursor->next, cursor );
204            cursor->next->next->prev = cursor->next;
205            _length++;
206        }
207    }
208}
209
210
211template <class T>
212void List<T>::insert ( const T& t, int (*cmpf)( const T&, const T& ), void (*insf)( T&, const T& ) )
213{
214    if ( ! first || cmpf( *first->item, t ) > 0 )
215        insert( t );
216    else if ( cmpf( *last->item, t ) < 0 )
217        append( t );
218    else {
219        ListItem<T> * cursor = first;
220        int c;
221        while ( (c = cmpf( *cursor->item, t )) < 0 )
222            cursor = cursor->next;
223        if ( c == 0 )
224            insf( *cursor->item, t );
225        else {
226            cursor = cursor->prev;
227            cursor->next = new ListItem<T>( t, cursor->next, cursor );
228            cursor->next->next->prev = cursor->next;
229            _length++;
230        }
231    }
232}
233
234
235template <class T>
236void List<T>::append ( const T& t )
237{
238    last = new ListItem<T>( t, 0, last );
239    if ( first )
240        last->prev->next = last;
241    first = ( first ) ? first : last;
242    _length++;
243}
244
245
246template <class T>
247int List<T>::isEmpty() const
248{
249    return ( first == 0 );
250}
251
252template <class T>
253int List<T>::length() const
254{
255    return _length;
256}
257
258template <class T>
259T List<T>::getFirst() const
260{
261    ASSERT( first, "List: no item available" );
262    return first->getItem();
263}
264
265
266template <class T>
267void List<T>::removeFirst()
268{
269    if ( first ) {
270        _length--;
271        if ( first == last ) {
272            delete first;
273            first = last = 0;
274        }
275        else {
276            ListItem<T> *dummy = first;
277            first->next->prev = 0;
278            first = first->next;
279            delete dummy;
280        }
281    }
282}
283
284
285template <class T>
286T List<T>::getLast() const
287{
288    ASSERT( first, "List: no item available" );
289    return last->getItem();
290}
291
292
293template <class T>
294void List<T>::removeLast()
295{
296    if ( last ) {
297        _length--;
298        if ( first == last ) {
299            delete last;
300            first = last = 0;
301        }
302        else {
303            ListItem<T> *dummy = last;
304            last->prev->next = 0;
305            last = last->prev;
306            delete dummy;
307        }
308    }
309}
310
311
312template <class T>
313void List<T>::sort( int (*swapit) ( const T&, const T& ) )
314{
315    if ( first != last ) {
316        int swap = 1;
317        while ( swap ) {
318            swap = 0;
319            ListItem<T> *cur = first;
320            while ( cur->next ) {
321                if ( swapit( *(cur->item), *(cur->next->item) ) ) {
322                    T* dummy = cur->item;
323                    cur->item = cur->next->item;
324                    cur->next->item = dummy;
325                    swap = 1;
326                }
327                cur = cur->next;
328            }
329        }
330    }
331}
332
333
334#ifndef NOSTREAMIO
335template <class T>
336void List<T>::print ( ostream & os ) const
337{
338    ListItem<T> *cur = first;
339    os << "( ";
340    while ( cur ) {
341        cur->print( os );
342        if ( (cur = cur->getNext()) )
343            os << ", ";
344    }
345    os << " )";
346}
347#endif /* NOSTREAMIO */
348
349
350template <class T>
351ListIterator<T>::ListIterator()
352{
353    theList = 0;
354    current = 0;
355}
356
357
358template <class T>
359ListIterator<T>::ListIterator ( const ListIterator<T> & i )
360{
361    theList = i.theList;
362    current = i.current;
363}
364
365
366template <class T>
367ListIterator<T>::ListIterator ( const List<T> & l )
368{
369    theList = (List<T>*)&l;
370    current = l.first;
371}
372
373
374template <class T>
375ListIterator<T>::~ListIterator() { }
376
377
378template <class T>
379ListIterator<T>& ListIterator<T>::operator= ( const ListIterator<T> & I )
380{
381    if ( this != &I ) {
382        theList = I.theList;
383        current = I.current;
384    }
385    return *this;
386}
387
388
389template <class T>
390ListIterator<T>& ListIterator<T>::operator= ( const List<T> & l )
391{
392    theList = (List<T>*)&l;
393    current = l.first;
394    return *this;
395}
396
397
398template <class T>
399T& ListIterator<T>::getItem () const
400{
401    ASSERT( current, "ListIterator: no item available" );
402    return current->getItem();
403}
404
405
406template <class T>
407int ListIterator<T>::hasItem ()
408{
409    return current != 0;
410}
411
412
413template <class T>
414void ListIterator<T>::operator++ ()
415{
416    if ( current )
417        current = current->next;
418}
419
420
421template <class T>
422void ListIterator<T>::operator-- ()
423{
424    if ( current )
425        current = current->prev;
426}
427
428
429template <class T>
430void ListIterator<T>::operator++ ( int )
431{
432    if ( current )
433        current = current->next;
434}
435
436
437template <class T>
438void ListIterator<T>::operator-- ( int )
439{
440    if ( current )
441        current = current->prev;
442}
443
444
445template <class T>
446void ListIterator<T>::firstItem ()
447{
448    current = theList->first;
449}
450
451
452template <class T>
453void ListIterator<T>::lastItem ()
454{
455    current = theList->last;
456}
457
458
459template <class T>
460void ListIterator<T>::insert ( const T & t )
461{
462    if ( current ) {
463        if ( ! current->prev )
464            theList->insert( t );
465        else {
466            current->prev = new ListItem<T>( t, current, current->prev );
467            current->prev->prev->next = current->prev;
468            theList->_length++;
469        }
470    }
471}
472
473
474template <class T>
475void ListIterator<T>::append ( const T & t )
476{
477    if ( current ) {
478        if ( ! current->next )
479            theList->append( t );
480        else {
481            current->next = new ListItem<T>( t, current->next, current );
482            current->next->next->prev = current->next;
483            theList->_length++;
484        }
485    }
486}
487
488
489template <class T>
490void ListIterator<T>::remove ( int moveright )
491{
492    if ( current ) {
493        ListItem <T>*dummynext = current->next, *dummyprev = current->prev;
494        if ( current->prev ) {
495            current->prev->next = current->next;
496            if ( current->next )
497                current->next->prev = current->prev;
498            else
499                theList->last = current->prev;
500            delete current;
501            current = ( moveright ) ? dummynext : dummyprev;
502        }
503        else {
504            if ( current->next )
505                current->next->prev = 0;
506            theList->first = current->next;
507            delete current;
508            current = ( moveright ) ? dummynext : dummyprev;
509        }
510    }
511}
512
513#ifndef NOSTREAMIO
514template <class T>
515ostream& operator<<( ostream & os, const List<T> & l )
516{
517    l.print( os );
518    return os;
519}
520#endif /* NOSTREAMIO */
521
522template <class T>
523List<T> Union ( const List<T> & F, const List<T> & G )
524{
525    List<T> L = G;
526    ListIterator<T> i, j;
527    T f;
528    bool iselt;
529
530    for ( i = F; i.hasItem(); i++ ) {
531        f = i.getItem();
532        iselt = false;
533        j = G;
534        while ( ( ! iselt ) && j.hasItem() ) {
535            iselt =  f == j.getItem();
536            j++;
537        }
538        if ( ! iselt )
539            L.append( f );
540    }
541    return L;
542}
543
544template <class T>
545List<T> Union ( const List<T> & F, const List<T> & G, int (*cmpf)( const T&, const T& ), void (*insf)( T&, const T& ) )
546{
547    List<T> L = G;
548    ListIterator<T> i;
549
550    for ( i = F; i.hasItem(); ++i )
551        L.insert( i.getItem(), cmpf, insf );
552    return L;
553}
554
555template <class T>
556List<T> Difference ( const List<T> & F, const List<T> & G )
557{
558    List<T> L;
559    ListIterator<T> i, j;
560    T f;
561    int found;
562    for ( i = F; i.hasItem(); ++i ) {
563        f = i.getItem();
564        found = 0;
565        for ( j = G; j.hasItem() && (!found); ++j )
566            found = f == j.getItem();
567        if ( ! found )
568            L.append( f );
569    }
570    return L;
571}
572
573template <class T>
574T prod ( const List<T> & F )
575{
576    ListIterator<T> i;
577    T p = 1;
578    for ( i = F; i.hasItem(); i++ )
579        p = p * i.getItem();
580    return p;
581}
Note: See TracBrowser for help on using the repository browser.