]> git.donarmstrong.com Git - lilypond.git/blob - flower/include/list.tcc
release: 0.1.8
[lilypond.git] / flower / include / list.tcc
1 /*
2   list.tcc -- implement List<T>
3
4   source file of the Flower Library
5
6   (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8 #ifndef LIST_CC
9 #define LIST_CC
10
11
12 // instantiate a template:  explicit instantiation.
13 #define L_INSTANTIATE(a)   class List<a>; template class Cursor<a>; \
14   template class Link<a>
15
16 #include "list.hh"
17
18 template<class T>
19 List<T>::List (List const&src)
20 {
21     set_empty();
22     // probably el stupido
23     for (Cursor<T> c (src); c.ok(); c++)
24         bottom().add (c);
25 }
26
27 template<class T>
28 void
29 List<T>::OK() const
30 {
31     int i = size_;
32     Link<T> *lp = top_;
33     while (i--) {
34         assert (lp);
35         lp->OK();
36         lp = lp->next();
37     }
38     assert (!lp);
39      i = size_;
40     lp = bottom_;
41     while (i--) {
42         assert (lp);
43         lp->OK();
44         lp = lp->previous();
45     }
46     assert (!lp);
47 }
48
49 template<class T>
50 void
51 List<T>::junk_links()
52 {
53     Cursor<T> c (*this);
54     while (c.ok())
55         c.del();
56 }
57
58 template<class T>
59 List<T>::~List()
60 {
61     junk_links();
62 }
63
64 /** 
65
66   add after after_me.
67
68   Procedure:
69   \begin{itemize}
70   \item if #after_me# is #ok()#, add after #after_me#, else
71   \item if list !empty simply add to bottom, else
72   \item list is empty: create first \Ref{Link} and initialize 
73   #bottom_# and #top_#.
74   \end{itemize}
75 */
76 template<class T>
77 void
78 List<T>::add (T const & thing, Cursor<T> &after_me)
79 {
80     if (!size_) {               // not much choice if list is empty
81         bottom_ = top_ = new Link<T>( thing);
82         if (!after_me.ok())
83             after_me = bottom();
84     } else {                    // add at aprioprate place
85         if (!after_me.ok())
86             after_me = bottom();
87         Link<T> *p =after_me.pointer();
88         p->add (thing);
89         if (p == bottom_)       // adjust bottom_ if necessary.
90             bottom_ = p->next();
91     }
92
93     size_++;
94 }
95
96 template<class T>
97 void
98 List<T>::insert (T const & thing, Cursor<T> &before_me)
99 {
100     if (!size_) {
101         bottom_ = top_ = new Link<T>( thing);
102         if (!before_me.ok())
103             before_me = top();
104         
105     } else {
106         if (!before_me.ok())
107             before_me = top();
108         
109         Link<T> *p = before_me.pointer() ;
110
111         p->insert (thing);
112         if (p == top_)
113             top_ = p->previous();
114     }
115
116     size_++;
117 }
118
119
120 template<class T>
121 void
122 List<T>::concatenate (List<T> const&s)
123 {
124     Cursor<T> b (bottom());
125     for (Cursor<T> c (s); c.ok(); c++) {
126         b.add (c);
127         b++;
128     }
129 }
130 #endif