]> git.donarmstrong.com Git - lilypond.git/blob - flower/include/list.tcc
release: 0.1.11
[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 LIST_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     {
35         assert (lp);
36         lp->OK();
37         lp = lp->next();
38     }
39   assert (!lp);
40    i = size_;
41   lp = bottom_;
42   while (i--) 
43     {
44         assert (lp);
45         lp->OK();
46         lp = lp->previous();
47     }
48   assert (!lp);
49 }
50
51 template<class T>
52 void
53 List<T>::junk_links()
54 {
55   Cursor<T> c (*this);
56   while (c.ok())
57         c.del();
58 }
59
60 template<class T>
61 List<T>::~List()
62 {
63   junk_links();
64 }
65
66 /** 
67
68   add after after_me.
69
70   Procedure:
71   \begin{itemize}
72   \item if #after_me# is #ok()#, add after #after_me#, else
73   \item if list !empty simply add to bottom, else
74   \item list is empty: create first \Ref{Link} and initialize 
75   #bottom_# and #top_#.
76   \end{itemize}
77 */
78 template<class T>
79 void
80 List<T>::add (T const & thing, Cursor<T> &after_me)
81 {
82   if (!size_) {         // not much choice if list is empty
83       bottom_ = top_ = new Link<T>( thing);
84         if (!after_me.ok())
85             after_me = bottom();
86     }
87   else {                        // add at aprioprate place
88         if (!after_me.ok())
89             after_me = bottom();
90         Link<T> *p =after_me.pointer();
91         p->add (thing);
92         if (p == bottom_)       // adjust bottom_ if necessary.
93             bottom_ = p->next();
94     }
95
96   size_++;
97 }
98
99 template<class T>
100 void
101 List<T>::insert (T const & thing, Cursor<T> &before_me)
102 {
103   if (!size_) 
104     {
105         bottom_ = top_ = new Link<T>( thing);
106         if (!before_me.ok())
107             before_me = top();
108         
109     }
110   else 
111     {
112         if (!before_me.ok())
113             before_me = top();
114         
115         Link<T> *p = before_me.pointer() ;
116
117         p->insert (thing);
118         if (p == top_)
119             top_ = p->previous();
120     }
121
122   size_++;
123 }
124
125
126 template<class T>
127 void
128 List<T>::concatenate (List<T> const&s)
129 {
130   Cursor<T> b (bottom());
131   for (Cursor<T> c (s); c.ok(); c++) 
132     {
133         b.add (c);
134         b++;
135     }
136 }
137 #endif