]> git.donarmstrong.com Git - lilypond.git/blob - flower/include/cons.hh
release: 1.1.37
[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 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #ifndef CONS_HH
11 #define CONS_HH
12
13
14 template<class T>
15 class Cons
16 {
17 public:
18   T * car_;
19   Cons * next_;
20   Cons ()
21     {
22       car_=0;
23       next_ =0;
24     }
25   Cons (T*t, Cons<T>*c)
26     {
27       car_ = t;
28       next_ = c;
29     }
30  virtual ~Cons ()
31     {
32       delete next_;
33     }
34 };
35
36 template<class T>
37 class Killing_cons : public Cons<T>
38 {
39 public:
40   Killing_cons (T *t, Cons<T> *p)
41     : Cons<T>( t,p)
42     {
43     }
44   virtual ~Killing_cons ();
45 };
46
47
48 /// remove the link pointed to by *p.
49 template<class T>
50 Cons<T> *remove_cons (Cons<T> **pp)
51 {
52   Cons<T> *knip = *pp;
53   *pp = (*pp)->next_;
54   knip->next_ = 0;
55   return knip;
56 }
57
58 /**
59
60    Invariants:
61
62    (*tail_) is either the head_ pointer, or a next_ pointer from the list.
63    
64    **tail_ == NULL
65  */
66
67 template<class T>
68 class Cons_list
69 {
70 public:
71   Cons<T> * head_;
72   Cons<T> ** tail_;
73   Cons_list () { init_list (); }
74   void init_list () {head_ =0; tail_ = &head_; }
75   void append (Cons<T> *c)
76     {
77       assert (!c->next_);
78       *tail_ = c;
79       while (*tail_)
80         tail_ = &(*tail_)->next_;
81     }
82   /**
83      PRE: *pp should either be the head_ pointer, or the next_ pointer
84      from a list cell.
85   */
86   Cons<T> *remove_cons (Cons<T> **pp)
87     {
88       if (&(*pp)->next_ == tail_)
89         tail_ = pp;
90
91       return ::remove_cons (pp);
92     }
93   void junk ()
94     {
95       delete head_;
96       head_ =0;
97     }
98   ~Cons_list () { junk (); }
99 };
100
101
102 template<class T>
103 void  copy_killing_cons_list (Cons_list<T>&, Cons<T> *src);
104 template<class T>
105 void
106 clone_killing_cons_list (Cons_list<T>&, Cons<T> *src);
107
108 template<class T> int cons_list_size_i (Cons<T> *l)
109 {
110   int i=0;
111   while  (l)
112     {
113       l = l->next_;
114         i++;
115     }
116   return i;
117 }
118
119
120
121
122 #endif /* CONS_HH */
123