source: tags/ms_r16q3/MULTI_PROBE/SoTl.hxx

Last change on this file was 7623, checked in by westram, 13 years ago
  • merge from dev [7450] [7452] [7456] [7457] [7458] [7459] [7460] [7461] [7464] [7465] [7466] [7467] [7468] [7469] [7482]
    • tweaked compiler options
      • activated -Weffc++
        • postfilter warnings where Scott Meyers' advices are too general.
          • base classes should not always have virtual destructors, since that renders tiny classes useless and
          • members should not always be initialized via initialization list, since that often violates the DRY principle
        • fix gcc's inability to detect that Noncopyable implements a private copy-ctor and op=
        • this slows down complete ARB recompilation by ~5%
    • added -Wold-style-cast (inactive)
    • removed -Wno-non-template-friend added in [7447]
  • postcompile.pl
    • added option —original to show unmodified compiler output
  • declared op= for classes which had a copy-ctor
  • moved op= macros to arbtools.h
  • derived classes containing pointers from Noncopyable (use Noncopyable virtually) or
  • made them copyable if needed (awt_mask_item, KnownDB, Code, AWT_registered_itemtype, GEN_gene, PosGene, PartialSequence, PlugIn, Range, Convaln_exception)
  • other related changes
    • user mask destruction working now
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 29.8 KB
Line 
1#ifndef SOTL_HXX
2#define SOTL_HXX
3
4// SOTL = SelfOrganising TemplateList
5
6/*
7  Copyright by Andrej Konkow 1996
8
9  User has to take care by his own on calling update_pos_no, when inserting
10  elements somewhere in the middle. If elements are inserted only at the last
11  position the pos is incremented correctly. By default the first element in the list
12  has position 1.
13  no_of_members is counted and updated automatically.
14
15  Caution:
16  This List by default is NOT a selforganizing list. This means that by default an element
17  that is being asked for is NOT put at front of the list. This only will be done while the
18  flag sotl is set to false(this is default). You can change this flag with the methods
19  sotl_list() (sets the flag true) and no_sotl_list() (sets the flag false).
20
21  The List is created by
22  List<Typename> *instance_variable = new List<Typename>(sotl_flag);
23  ^^^^^^^
24  sotl_flag is optional.
25  For a normal double linked list
26  this flag has not to be set. For
27  a selforganizing list : true
28
29  Afterwards the elements can be inserted.
30  The User of this list has to delete the elements which are inserted to the list by
31  its own.
32  The User has only have to work with the List class.
33*/
34
35#ifndef _GLIBCXX_CSTDIO
36#include <cstdio>
37#endif
38#ifndef ARBTOOLS_H
39#include <arbtools.h>
40#endif
41
42typedef unsigned long positiontype;
43
44#define RELATION_GREATER 1
45#define RELATION_LESS    2
46
47
48template <class Type>
49class list_elem : virtual Noncopyable {
50    positiontype pos;
51
52public:
53    list_elem<Type> *next;
54    list_elem<Type> *prev;
55    Type            *elem;
56    bool             isolate_list_elem();                       // set next and prev links to NULL
57    // true if isolation has taken place,
58    // else false(for example if we're the
59    // only element
60
61    Type                        *get_elem()                     { return elem; };
62    void                        set_elem(Type *el)              { elem = el; };
63    positiontype                get_pos()                       { return pos; };
64    void                        set_pos(positiontype p)         { pos = p; };
65    list_elem<Type>             *get_next()                     { return next; };
66    void                        set_next(list_elem<Type> *n)    { next = n; };
67    list_elem<Type>             *get_prev()                     { return prev; };
68    void                        set_prev(list_elem<Type> *p)    { prev = p; };
69
70    list_elem();
71    list_elem(Type *el);
72    ~list_elem();
73};
74
75
76template <class Type>
77class List : virtual Noncopyable {
78    list_elem<Type>     *first;
79    list_elem<Type>     *last;
80    list_elem<Type>     *last_asked_list_elem;
81    list_elem<Type>     *remembered_elem;
82
83    positiontype        no_of_members;
84    bool                sotl;
85
86
87    list_elem<Type>     *get_list_elem_with_member      (Type *object);
88    list_elem<Type>     *get_list_elem_at_pos           (positiontype pos);
89    list_elem<Type>     *get_list_elem_at_pos_simple    (positiontype pos);
90public:
91    // general List functions
92
93
94    // only use these functions if you know what you are doing !!!  BEGINNING
95    list_elem<Type>     *get_first_list_elem()  { return first; };      // do not use !!!
96    list_elem<Type>     *get_last_list_elem()   { return last; };       // do not use !!!
97    list_elem<Type>     *get_current_list_elem() { return last_asked_list_elem; }; // do not use !!!
98    void                remember_current()      { remembered_elem = last_asked_list_elem; };
99    void                set_current_ARC(list_elem<Type> *t);            // ARC = and remember current
100    void                set_remembered_as_current_ARC();                // ARC = and remember current
101    // only use these functions if you know what you are doing !!!  END
102
103    void                sotl_list()             { sotl = true; };
104    void                no_sotl_list()          { sotl = false; };
105    positiontype        get_no_of_members()     { return no_of_members; };
106
107    positiontype        insert_as_first         (Type *object);
108    positiontype        insert_as_last          (Type *object);         // returns pos_no
109    positiontype        insert_after_current    (Type *object);
110    positiontype        insert_before_current   (Type *object);
111    positiontype        insert                  (Type *object);         // returns pos_no
112    Type                *get_first              ();
113    Type                *get_last               ();
114    Type                *get_prev               ();
115    Type                *get_next               ();
116
117    void                remove_member_from_list (Type *object);         // object won't be deleted
118    void                remove_first();
119    void                remove_last();
120    List<Type>  *duplicate_list         (Type *object);         // the list is duplicated
121    // from the element given til the end.
122    // For duplicating the whole list
123    // object = get_first(). Only the list is
124    // duplicated, not the elems. Caution:
125    // In a sotl list the asked element is put
126    // to the front. So first make a no_sotl_list()
127    // ask and duplicate the list, and then make a
128    // sotl_list() again.
129
130    bool                exchange_members        (Type *ex, Type *change);
131
132    /*  following functions only make sense if our list is sorted by the address of
133        our item inserted to the list.
134        Caution:
135        The list is only sorted if it's NOT a sotl list. So take care to
136        create or set it to a no_sotl_list().
137    */
138
139    // Comment to insert_sorted_by_address_of_object:
140    // The function returns the no_of_members in the list.
141    // By default an object(the meaning here is that one object equals another,
142    // if the address of both objects matches) can be inserted to the list
143    // several times. If there is the need to insert an object only once
144    // in the list, the flag duplicates has to be set to false.
145    // Finally the relation has to be set, by which the list is sorted.
146    // The possibilities are : RELATION_GREATER and RELATION_LESS
147    positiontype        insert_sorted_by_address_of_object(Type *object,
148                                                                int relation=RELATION_LESS,
149                                                                bool duplicates=true);
150
151    // Comment to sort_list_join:
152    // if an object found in List l is found in this list it won't be inserted
153    // a second time.
154    void                sort_list_join          (List<Type> *l,
155                                                        int relation=RELATION_LESS);    // Lists given as parameter
156    // won't be affected
157    // Comment to sort_list_subtract:
158    // this function call only makes sense if the same element can be found
159    // in both lists. The flag relation tells the method how this list(not list l)
160    // is sorted. Both lists have to be sorted by the same relation.
161    void                sort_list_subtract      (List<Type> *l,
162                                                        int relation=RELATION_LESS);
163
164
165
166    positiontype        insert_at_pos_simple    (Type *object, positiontype pos);       // returns pos inserted to
167    // doesn't refer to get_pos()
168    Type                *get_member_at_pos_simple(positiontype pos);
169
170    /*
171      Following functions only make sense if the user takes care of the list as
172      a numbered list.
173    */
174    // Comment to insert_at_pos :
175    // user does not have to call update_pos_no after insert_at_pos()
176    positiontype        insert_at_pos           (Type *object, positiontype pos);       // returns pos inserted to
177    positiontype        get_pos_of_member       (Type *object);
178    Type                *get_member_at_pos      (positiontype pos);
179    bool                remove_pos_from_list    (positiontype pos);             // element won't be deleted
180    bool                exchange_positions      (positiontype ex, positiontype change);         // exchange elems in list
181    void                update_pos_no(list_elem<Type> *elem, positiontype nr);  // updates no from
182    // the given elem with nr til last
183    void                update_pos_no();                // updates pos number from first to last
184
185    List(bool so=false);
186    ~List();
187};
188
189// ------------------
190//      list_elem
191
192template <class Type> inline list_elem<Type>::list_elem()
193{
194    pos = 0;
195    next = NULL;
196    prev = NULL;
197    elem = NULL;
198}
199
200template <class Type> inline list_elem<Type>::list_elem(Type *el)
201{
202    pos = 0;
203    next = NULL;
204    prev = NULL;
205    elem = el;
206}
207
208template <class Type> inline list_elem<Type>::~list_elem()
209{
210    isolate_list_elem();
211}
212
213template <class Type> inline  bool list_elem<Type>::isolate_list_elem()
214{
215    if (prev && next)               // somewhere in the middle
216    {
217        prev->next      = next;
218        next->prev      = prev;
219        next            = NULL;
220        prev            = NULL;
221    }
222    else if (prev)                  // we're the last
223    {
224        prev->next      = NULL;
225        prev            = NULL;
226    }
227    else if (next)                  // we're the first
228    {
229        next->prev      = NULL;
230        next            = NULL;
231    }
232    else
233        return false;
234
235    return true;
236}
237
238// -------------
239//      List
240
241template <class Type> inline List<Type>::List(bool so)
242{
243    first = last = last_asked_list_elem = remembered_elem = NULL;
244    no_of_members = 0;
245    sotl = so;
246}
247
248template <class Type> inline List<Type>::~List()
249{
250    list_elem<Type> *elem, *help;
251
252    elem = first;
253    while (elem)                            // delete every object in list
254    {
255        help = elem->next;
256        delete elem;
257        elem = help;
258    }
259}
260
261template <class Type> inline void List<Type>::set_current_ARC(list_elem<Type> *t)       // ARC = and remember current
262{
263    remembered_elem = last_asked_list_elem;
264    last_asked_list_elem = t;
265}
266
267template <class Type> inline void List<Type>::set_remembered_as_current_ARC()   // ARC = and remember current
268{
269    list_elem<Type> *mark;
270
271    mark = last_asked_list_elem;
272    last_asked_list_elem = remembered_elem;
273    remembered_elem = mark;
274}
275
276template <class Type> inline list_elem<Type> *List<Type>::get_list_elem_with_member(Type *object)
277{
278    list_elem<Type> *loc_elem;
279
280    loc_elem = first;
281    while (loc_elem && loc_elem->elem!=object)
282        loc_elem = loc_elem->next;
283
284    return loc_elem;
285}
286
287template <class Type> inline list_elem<Type> *List<Type>::get_list_elem_at_pos(positiontype pos)
288{
289    list_elem<Type> *elem;
290
291    if (pos < 1 || pos > no_of_members)
292        return NULL;
293
294    if (! last_asked_list_elem)
295    {
296        if (pos > no_of_members/2)
297        {
298            elem = last;
299            while (elem && elem->get_pos() != pos)
300                elem = elem->get_prev();
301        }
302        else
303        {
304            elem = first;
305            while (elem && elem->get_pos() != pos)
306                elem = elem->next;
307        }
308    }
309    else
310    {
311        elem = last_asked_list_elem;
312
313        if (pos >= last_asked_list_elem->get_pos())
314        {
315            while (elem && elem->get_pos() != pos)
316                elem = elem->next;
317        }
318        else    // pos < last_asked_list_elem->pos
319        {
320            while (elem && elem->get_pos() != pos)
321                elem = elem->get_prev();
322        }
323    }
324
325    return elem;
326}
327
328template <class Type> inline list_elem<Type> *List<Type>::get_list_elem_at_pos_simple(positiontype pos)
329{
330    list_elem<Type>         *elem;
331    positiontype    counter = 1;
332
333    if (pos < 1 || pos > no_of_members)
334        return NULL;
335
336    if (pos > no_of_members/2)
337    {
338        elem = last;
339        counter = no_of_members;
340        while (elem && counter != pos)
341        {
342            elem = elem->get_prev();
343            counter --;
344        }
345    }
346    else
347    {
348        elem = first;
349        while (elem && counter != pos)
350        {
351            elem = elem->next;
352            counter ++;
353        }
354    }
355
356    return elem;
357}
358
359template <class Type> inline Type *List<Type>::get_first()
360{
361    if (first)
362    {
363        last_asked_list_elem = first;
364        return first->elem;
365    }
366    else
367        return NULL;
368}
369
370template <class Type> inline Type *List<Type>::get_last()
371{
372    if (last && ! sotl)                     // behavior of a normal linked list
373    {
374        last_asked_list_elem = last;
375        return last->elem;
376    }
377    else if (last && sotl)
378    {
379        last_asked_list_elem = last->get_prev();
380        insert_as_first(last->elem);
381        remove_last();
382        return first->elem;
383    }
384    else
385        return NULL;
386}
387
388template <class Type> inline Type *List<Type>::get_prev()
389{
390    Type            *result = NULL;
391    list_elem<Type> *mark_prev;
392
393    if (last_asked_list_elem) {
394
395        if (!sotl)              // behavior of a normal linked list
396        {
397            last_asked_list_elem = last_asked_list_elem->get_prev();
398
399            if (last_asked_list_elem)
400                result = last_asked_list_elem->elem;
401        }
402        else if (sotl)
403        {
404            if (last_asked_list_elem)
405            {
406                result          = last_asked_list_elem->elem;
407                mark_prev       = last_asked_list_elem->get_prev();
408
409                remove_member_from_list(result);
410                insert_as_first(result);
411                last_asked_list_elem = mark_prev;
412            }
413        }
414    }
415    return result;
416}
417
418template <class Type> inline Type *List<Type>::get_next()
419{
420    Type            *result = NULL;
421    list_elem<Type> *mark_next;
422
423    if (last_asked_list_elem) {
424
425        if (!sotl)              // behavior of a normal linked list
426        {
427            last_asked_list_elem = last_asked_list_elem->next;
428
429            if (last_asked_list_elem)
430                result = last_asked_list_elem->elem;
431        }
432        else if (sotl)
433        {
434            if (last_asked_list_elem)
435            {
436                result          = last_asked_list_elem->elem;
437                mark_next       = last_asked_list_elem->next;
438
439                remove_member_from_list(result);
440                insert_as_first(result);
441                last_asked_list_elem = mark_next;
442            }
443        }
444    }
445
446    return result;
447}
448
449
450template <class Type> inline positiontype List<Type>::insert_as_first(Type *object)
451{
452    list_elem<Type> *help = NULL;
453
454    if (! first)                                    // create first element
455    {                                               // in list
456        first = new list_elem<Type>(object);
457        first->set_pos(1);
458        last = first;
459    }
460    else
461    {
462        help = new list_elem<Type>(object);
463        help->set_pos(1);                               // update by USER !!!
464        help->set_next(first);
465        first->set_prev(help);
466        first = help;
467    }
468
469    no_of_members ++;
470    return 1;
471}
472
473template <class Type> inline  positiontype List<Type>::insert_as_last(Type *object)
474{
475    list_elem<Type> *help = NULL;
476
477    if (! first)                                    // create first element
478    {                                               // in list
479        first = new list_elem<Type>(object);
480        first->set_pos(1);
481        last = first;
482    }
483    else
484    {
485        help = new list_elem<Type>(object);
486        help->set_pos(no_of_members+1);
487        help->set_prev(last);
488        last->set_next(help);
489        last = help;
490    }
491
492    no_of_members ++;
493    return no_of_members;
494}
495
496template <class Type> inline positiontype List<Type>::insert_after_current(Type *object)
497{
498    list_elem<Type>     *help = NULL;
499    positiontype result = 0;
500
501    if (last_asked_list_elem) {
502
503        if (!last_asked_list_elem->get_next()) {
504            result = insert_as_last(object);
505        }
506        else {
507            help = new list_elem<Type>(object);
508            help->set_pos(last_asked_list_elem->get_pos() + 1);
509            help->set_prev(last_asked_list_elem);
510            help->set_next(last_asked_list_elem->get_next());
511            help->get_next()->set_prev(help);
512            last_asked_list_elem->set_next(help);
513            last_asked_list_elem = help;
514
515            no_of_members ++;
516            result =  no_of_members;
517        }
518    }
519    return result;
520}
521
522template <class Type> inline positiontype List<Type>::insert_before_current(Type *object)
523{
524    list_elem<Type>     *help = NULL;
525    positiontype result = 0;
526    if (last_asked_list_elem) {
527
528        if (!last_asked_list_elem->get_prev()) {
529            result = insert_as_first(object);
530        }
531        else {
532            help = new list_elem<Type>(object);
533            help->set_pos(last_asked_list_elem->get_pos() - 1);
534            help->set_next(last_asked_list_elem);
535            help->set_prev(last_asked_list_elem->get_prev());
536            help->get_prev()->set_next(help);
537            last_asked_list_elem->set_prev(help);
538            last_asked_list_elem = help;
539
540            no_of_members ++;
541            result = no_of_members;
542        }
543    }
544    return result;
545}
546
547template <class Type> inline  positiontype List<Type>::insert(Type *object)
548{
549    return insert_as_first(object);
550}
551
552template <class Type> inline positiontype List<Type>::insert_at_pos_simple(Type *object, positiontype temp_pos)         // returns pos inserted to
553{
554    list_elem<Type> *elem,
555        *new_elem;
556
557    if (temp_pos<=1)
558    {
559        insert_as_first(object);
560        return 1;
561    }
562    else if (temp_pos>no_of_members)
563    {
564        insert_as_last(object);
565        return no_of_members;
566    }
567    else
568    {
569        elem = get_list_elem_at_pos_simple(temp_pos);
570
571        new_elem = new list_elem<Type>;
572        new_elem->elem = object;
573        new_elem->set_pos(temp_pos);
574        new_elem->prev = elem->prev;
575        new_elem->next = elem;
576        elem->prev->next = new_elem;
577        elem->prev = new_elem;
578
579        no_of_members ++;
580        return temp_pos;
581    }
582}
583
584template <class Type> inline void List<Type>::remove_member_from_list(Type *object)
585{
586    list_elem<Type> *loc_elem;
587
588    if (last_asked_list_elem &&
589        last_asked_list_elem->elem==object)
590    {
591        if (! last_asked_list_elem->next)       // we're the last
592            last = last_asked_list_elem->get_prev();
593
594        if (! last_asked_list_elem->get_prev())         // we're the first
595            first = last_asked_list_elem->next;
596
597        delete last_asked_list_elem;
598
599        if (no_of_members == 1)
600            first = last = NULL;
601
602        last_asked_list_elem = NULL;
603    }
604    else
605    {
606        if (last_asked_list_elem &&
607            last_asked_list_elem->next &&
608            last_asked_list_elem->next->elem == object)
609            loc_elem = last_asked_list_elem->next;
610        else if (last_asked_list_elem &&
611                 last_asked_list_elem->get_prev() &&
612                 last_asked_list_elem->get_prev()->elem == object)
613            loc_elem = last_asked_list_elem->get_prev();
614        else
615            loc_elem = get_list_elem_with_member(object);
616
617        if (! loc_elem)
618            return;
619
620        if (! loc_elem->next)   // we're the last
621            last = loc_elem->get_prev();
622
623        if (! loc_elem->get_prev())     // we're the first
624            first = loc_elem->next;
625
626        delete loc_elem;
627    }
628
629    no_of_members --;
630}
631
632template <class Type> inline void List<Type>::remove_first()
633{
634    list_elem<Type> *new_first;
635
636    if (no_of_members <= 1)                 // case 0 or 1
637    {
638        delete first;
639        first = last = last_asked_list_elem = NULL;
640        no_of_members = 0;
641    }
642    else
643    {
644        new_first = first->next;
645        delete first;
646        first = new_first;
647        no_of_members --;
648    }
649}
650
651template <class Type> inline void List<Type>::remove_last()
652{
653    list_elem<Type> *new_last;
654
655    if (no_of_members <= 1)                 // case 0 or 1
656    {
657        delete last;
658        first = last = last_asked_list_elem = NULL;
659        no_of_members = 0;
660    }
661    else
662    {
663        new_last = last->get_prev();
664        delete last;
665        last = new_last;
666        no_of_members --;
667    }
668}
669
670template <class Type> inline positiontype List<Type>::insert_sorted_by_address_of_object(Type *object,
671                                                                                          int relation,
672                                                                                          bool duplicates)              // falls object schon vorhanden, dann
673{
674    list_elem<Type> *help = NULL,
675        *l_help;
676
677    if (! first)                            // create first element
678    {                                       // in list
679        first = new list_elem<Type>(object);
680        first->set_pos(1);
681        last = first;
682    }
683    else
684    {
685        if (relation == RELATION_GREATER)       // search for a place to insert to
686        {                                       // objects which are created later,
687            l_help = first;                 // have a greater address !!!
688            while (l_help && object < l_help->elem)
689                l_help = l_help->next;
690        }
691        else            // RELATION_LESS
692        {
693            l_help = last;
694            while (l_help && object < l_help->elem)
695                l_help = l_help->get_prev();
696        }
697
698        if (l_help && object == l_help->elem && ! duplicates)   // Element already is in the list
699            return no_of_members;
700
701        help = new list_elem<Type>(object);     // generate new element
702
703        if (! l_help)                           // new element in front/at end
704        {
705            if (relation == RELATION_GREATER)
706            {
707                last->set_next(help);
708                help->set_prev(last);
709                last = help;
710            }
711            else            // RELATION_LESS
712            {
713                first->set_prev(help);
714                help->set_next(first);
715                first = help;
716            }
717        }
718        else
719        {
720            if (relation == RELATION_GREATER)
721            {
722                if (first == l_help)
723                    first = help;
724
725                help->set_next(l_help);
726                help->set_prev(l_help->get_prev());
727            }
728            else            // RELATION_LESS
729            {
730                if (last == l_help)
731                    last = help;
732
733                help->set_prev(l_help);
734                help->set_next(l_help->next);
735            }
736
737            if (help->next)
738                help->next->set_prev(help);
739
740            if (help->get_prev())
741                help->get_prev()->set_next(help);
742        }
743
744    }
745
746    no_of_members ++;
747
748    return no_of_members;
749}
750
751template <class Type> inline void List<Type>::sort_list_join(List<Type> *l,
752                                                              int relation)
753{
754    list_elem<Type> *this_list = first,
755        *join_list,
756        *new_elem;
757
758    if (! l || ! l->get_no_of_members())
759        return;
760
761    join_list = l->get_first_list_elem();
762
763    while (this_list && join_list)
764    {
765        if (this_list->elem == join_list->elem)
766        {
767            this_list = this_list->next;
768            join_list = join_list->next;
769        }
770        else
771        {
772            if ((relation == RELATION_GREATER && this_list->elem > join_list->elem) ||
773                    (relation == RELATION_LESS    && this_list->elem < join_list->elem))
774                this_list = this_list->next;
775            else
776            {
777                new_elem = new list_elem<Type>(join_list->elem);
778                new_elem->set_prev(this_list->get_prev());
779                new_elem->set_next(this_list);
780                this_list->set_prev(new_elem);
781
782                if (new_elem->get_prev())
783                    new_elem->get_prev()->set_next(new_elem);
784                else
785                    first = new_elem;
786
787                join_list = join_list->next;
788
789                no_of_members ++;
790            }
791        }
792    }
793
794    if (! join_list || (!this_list && !join_list))
795        return;
796
797    if (!this_list)
798    {
799        while (join_list)
800        {
801            new_elem = new list_elem<Type>(join_list->elem);
802            new_elem->set_prev(last);
803
804            if (last)
805                last->set_next(new_elem);
806
807            if (!first)
808                first = new_elem;
809
810            last = new_elem;
811            no_of_members ++;
812            join_list = join_list->next;
813        }
814    }
815}
816
817template <class Type> inline  void List<Type>::sort_list_subtract(List<Type> *l, int relation)
818{
819    list_elem<Type> *this_list = first,
820        *join_list = l->get_first_list_elem(),
821        *mark;
822
823    while (this_list && join_list)
824    {
825        if ((relation == RELATION_GREATER && this_list->elem > join_list->elem) ||
826             (relation == RELATION_LESS    && this_list->elem < join_list->elem))
827            this_list = this_list->next;
828        else if ((relation == RELATION_GREATER && this_list->elem < join_list->elem) ||
829                  (relation == RELATION_LESS    && this_list->elem > join_list->elem))
830            join_list = join_list->next;
831        else if (this_list->elem == join_list->elem) // same element => delete from this_list
832        {
833            if (this_list == first)
834                first = this_list->next;
835
836            if (this_list == last)
837                last = this_list->get_prev();
838
839            mark = this_list->next;
840            delete this_list;
841            this_list = mark;
842
843            join_list = join_list->next;
844            no_of_members --;
845
846            if (! no_of_members)
847            {
848                last_asked_list_elem = NULL;
849                return;
850            }
851        }
852    }
853}
854
855template <class Type> inline List<Type> *List<Type>::duplicate_list(Type *object)
856{
857    list_elem<Type> *help_l = first;
858    List<Type>      *new_list = NULL;
859
860    if (last_asked_list_elem->elem == object)
861        help_l = last_asked_list_elem;
862    else
863        help_l = get_list_elem_with_member(object);
864
865    if (help_l)
866        new_list = new List<Type>;
867
868    while (help_l)
869    {
870        new_list->insert_as_last(help_l->elem);
871
872        help_l = help_l->next;
873    }
874
875    return new_list;
876}
877
878template <class Type>  inline void List<Type>::update_pos_no(list_elem<Type> *elem, positiontype nr)
879{
880    list_elem<Type> *mark;
881
882    if (!elem)
883        return;
884
885    elem->set_pos(nr++);
886    mark = elem->next;
887    while (mark)
888    {
889        mark->set_pos(nr++);
890        mark = mark->next;
891    }
892}
893
894template <class Type> inline void List<Type>::update_pos_no()
895{
896    update_pos_no(first, 1);
897}
898
899template <class Type> inline bool List<Type>::exchange_members(Type *ex, Type *change)
900{
901    list_elem<Type> *one, *two;
902    bool result = false;
903    while (1) {
904        if (!ex || !change)
905            break;
906
907        if (last_asked_list_elem && last_asked_list_elem->elem == ex)
908            one = last_asked_list_elem;
909        else
910            one = get_list_elem_with_member(ex);
911
912        if (! one)
913            break;
914
915        if (last_asked_list_elem && last_asked_list_elem->elem == change)
916            two = last_asked_list_elem;
917        else
918            two = get_list_elem_with_member(change);
919
920        if (!two)
921            break;
922
923        one->set_elem(change);
924        two->set_elem(ex);
925        result = true;
926        break;
927    }
928
929    return result;
930}
931
932template <class Type> inline bool List<Type>::exchange_positions(positiontype ex, positiontype change)
933{
934    list_elem<Type> *one, *two;
935    Type            *dummy;
936    bool    result = false;
937    while (1) {
938        if (ex < 1 || ex > no_of_members ||
939                change < 1 || change > no_of_members)
940            break;
941
942        one = get_list_elem_at_pos(ex);
943        if (! one)
944            break;
945
946        two = get_list_elem_at_pos(change);
947        if (!two)
948            break;
949
950        dummy = one->elem;
951        one->elem = two->elem;
952        two->elem = dummy;
953        result = true;
954        break;
955    }
956    return result;
957}
958
959template <class Type> inline positiontype List<Type>::get_pos_of_member(Type *object)
960{
961    list_elem<Type> *elem;
962
963    if (!object)
964        return 0;
965
966    if (last_asked_list_elem && last_asked_list_elem->elem == object)
967        return last_asked_list_elem->get_pos();
968    else
969    {
970        elem = first;
971        while (elem && elem->elem != object)
972            elem = elem->next;
973
974        if (elem)
975            return elem->get_pos();
976        else
977            return 0;
978    }
979}
980
981
982template <class Type> inline positiontype List<Type>::insert_at_pos(Type *object, positiontype pos)     // returns pos inserted to
983{
984    list_elem<Type> *elem,
985        *new_elem;
986    positiontype result;
987
988    elem = get_list_elem_at_pos(pos);
989
990    if (! elem)
991    {
992        insert_as_last(object);
993        result = last->get_pos();
994    }
995    else
996    {
997        new_elem = new list_elem<Type>(object);
998        new_elem->set_prev(elem->get_prev());
999        new_elem->set_next(elem);
1000
1001        if (elem->get_prev())
1002            elem->get_prev()->set_next(new_elem);
1003
1004        elem->set_prev(new_elem);
1005
1006        if (first == elem)
1007            first = new_elem;
1008
1009        update_pos_no (new_elem, pos);
1010
1011        result =  pos;
1012    }
1013    return result;
1014}
1015
1016template <class Type> inline Type *List<Type>::get_member_at_pos(positiontype pos)
1017{
1018    list_elem<Type> *elem;
1019
1020    elem = get_list_elem_at_pos(pos);
1021
1022    if (elem)
1023    {
1024        last_asked_list_elem = elem;
1025        return elem->elem;
1026    }
1027    else
1028        return NULL;
1029}
1030
1031template <class Type> inline Type *List<Type>::get_member_at_pos_simple(positiontype pos)
1032{
1033    list_elem<Type> *elem;
1034
1035    elem = get_list_elem_at_pos_simple(pos);
1036
1037    if (elem)
1038    {
1039        last_asked_list_elem = elem;
1040        return elem->elem;
1041    }
1042    else
1043        return NULL;
1044}
1045
1046template <class Type> inline bool List<Type>::remove_pos_from_list(positiontype pos)
1047{
1048    list_elem<Type> *loc_elem;
1049    bool result = false;
1050    while (1) {
1051        if (pos < 1 || pos > no_of_members)
1052            break;
1053
1054        loc_elem = last_asked_list_elem;
1055
1056        if (loc_elem && loc_elem->get_pos() == pos)
1057            last_asked_list_elem = NULL;
1058        else
1059        {
1060            if (! (loc_elem = get_list_elem_at_pos(pos)))
1061                break;
1062        }
1063
1064        if (last == loc_elem)
1065            last = last->get_prev();
1066
1067        if (first == loc_elem)
1068
1069
1070            first = first->next;
1071
1072        delete loc_elem;
1073        no_of_members --;
1074        result = true;
1075        break;
1076    }
1077
1078    return result;
1079}
1080
1081#else
1082#error SoTl.hxx included twice
1083#endif
Note: See TracBrowser for help on using the repository browser.