]> git.donarmstrong.com Git - lilypond.git/blob - flower/include/cons.hh
2003 -> 2004
[lilypond.git] / flower / include / cons.hh
1 /*   
2   cons.hh -- declare LISP like datatypes
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1999--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #ifndef CONS_HH
11 #define CONS_HH
12
13
14 #include <assert.h>
15
16 template<class T>
17 class Cons
18 {
19 public:
20   T * car_;
21   Cons * next_;
22   Cons ()
23     {
24       car_=0;
25       next_ =0;
26     }
27   Cons (T*t, Cons<T>*c)
28     {
29       car_ = t;
30       next_ = c;
31     }
32  virtual ~Cons ()
33     {
34       delete next_;
35     }
36 };
37
38 template<class T>
39 class Killing_cons : public Cons<T>
40 {
41 public:
42   Killing_cons (T *t, Cons<T> *p)
43     : Cons<T> ( t,p)
44     {
45     }
46   virtual ~Killing_cons ();
47 };
48
49
50 /// remove the link pointed to by *p.
51 template<class T>
52 Cons<T> *remove_cons (Cons<T> **pp)
53 {
54   Cons<T> *knip = *pp;
55   *pp = (*pp)->next_;
56   knip->next_ = 0;
57   return knip;
58 }
59
60 template<class T> int cons_list_size (Cons<T> *l)
61 {
62   int i=0;
63   while (l)
64     {
65       l = l->next_;
66         i++;
67     }
68   return i;
69 }
70
71
72
73
74
75 template<class T>
76 Cons<T> * last_cons (Cons<T> * head)
77 {
78   while (head && head->next_)
79     {
80       head = head->next_;
81     }
82   return head;
83 }
84
85 /**
86
87    Invariants:
88
89  (*tail_) is either the head_ pointer, or a next_ pointer from the list.
90    
91    **tail_ == NULL
92  */
93
94 template<class T>
95 class Cons_list
96 {
97 public:
98   Cons<T> * head_;
99   Cons<T> ** nil_pointer_address_;
100   Cons_list ()
101     {
102       init ();
103     }
104   void init ()
105     {
106       head_ =0;
107       nil_pointer_address_ = &head_;
108     }
109   void append (T *c)
110     {
111       append (new Cons<T> (c,0));
112     }
113   void append (Cons<T> *c)
114     {
115       assert (!c->next_);
116       *nil_pointer_address_ = c;
117       while (*nil_pointer_address_)
118         nil_pointer_address_ = & (*nil_pointer_address_)->next_;
119     }
120   /**
121      PRE: *pp should either be the head_ pointer, or the next_ pointer
122      from a list cell.
123   */
124   Cons<T> *remove_cons (Cons<T> **pp)
125     {
126       if (& (*pp)->next_ == nil_pointer_address_)
127         nil_pointer_address_ = pp;
128
129       return ::remove_cons (pp);
130     }
131
132   /// junk everything after the  first I elements.
133   void truncate (int i)
134     {
135       Cons<T> **p  = &head_;
136       for (; *p && i;  p = & ((*p)->next_))
137         {
138           i--;
139         }
140
141       if (*p)
142         {
143           delete *p;
144           *p = 0;
145         }
146       nil_pointer_address_ = p;
147     }
148
149   void junk ()
150     {
151       delete head_;
152       head_ =0;
153     }
154   ~Cons_list ()
155     {
156       junk ();
157     }
158   int size ()
159     {
160       return cons_list_size (head_);
161     }
162 };
163
164
165 template<class T>
166 void  copy_killing_cons_list (Cons_list<T>&, Cons<T> *src);
167 template<class T>
168 void
169 clone_killing_cons_list (Cons_list<T>&, Cons<T> *src);
170
171 #endif /* CONS_HH */
172