]> git.donarmstrong.com Git - lilypond.git/blob - flower/include/array.hh
98e4d1f06050c48d16c93bbf59142e47b1ad51e5
[lilypond.git] / flower / include / array.hh
1 /*
2   (c) 1995--2006 Han-Wen Nienhuys
3
4   Distributed under GNU GPL
5 */
6 #ifndef ARRAY_H
7 #define ARRAY_H
8
9 #ifndef STD_VECTOR_HH
10 #error array.hh is obsolete, use std-vector.hh
11 #endif
12
13 #include <cassert>
14 using namespace std;
15
16 #ifndef INLINE
17 #define INLINE inline
18 #endif
19
20 #if !STD_VECTOR
21 #define index_assert(i) (assert (i >= 0 && i < size_));
22 #else
23 #define index_assert(i) (assert (i != VPOS && i < size_));
24 #endif
25
26 namespace std {
27 /// copy a bare (C-)array from #src# to #dest# sized  #count#
28 template<class T> void arrcpy (T *dest, T const *src, vsize count);
29
30 /**
31    Scaleable array/stack template, for a type T with default constructor.
32
33
34    This template implements a scaleable vector. With (or without) range
35    checking. The type T should have a default constructor. It is
36    best suited for simple types, such as int, double or String, it
37    provides a paranoidly safe replacement for the new T[int] construct.
38
39    You should \bf{never} store pointers to objects in an Array (since
40    the array may be relocated without the pointer knowing it).
41
42    It uses stack terminology, (push, pop, top), and  can be used as a stack.
43 */
44 template<class T>
45 class Array
46 {
47 public:
48
49   /// maximum length of array.
50   vsize max_;
51
52   /// the data itself
53   T *array_;
54
55   /// stretch or shrink  array.
56   void remax (vsize newmax)
57   {
58     T *newarr = new T[newmax];
59     size_ = (newmax < size_) ? newmax : size_;
60     arrcpy (newarr, array_, size_);
61
62     delete[] array_;
63     array_ = newarr;
64     max_ = newmax;
65   }
66   vsize size_;
67
68 public:
69   /* std::vector interface */
70   typedef T* iterator;
71   typedef T const* const_iterator;
72
73   Array ()
74   {
75     array_ = 0;
76     max_ = 0;
77     size_ = 0;
78   }
79
80   Array (Array const &src)
81   {
82     array_ = src.copys ();
83     max_ = size_ = src.size_;
84   }
85
86   Array (const_iterator begin, const_iterator end);
87     
88   T const &back () const
89   {
90     return (*this)[size_ - 1];
91   }
92
93   T &back ()
94   {
95     return (*this)[size_ - 1];
96   }
97
98   bool empty () const
99   {
100     return !size_;
101   }
102
103   void pop_back ()
104   {
105     assert (!empty ());
106     resize (size () - 1);
107   }
108
109   vsize size () const
110   {
111     return size_;
112   }
113
114   /** set the size_ to #s#.
115       POST: size () == s.
116       Warning: contents are unspecified */
117   void resize (vsize s)
118   {
119     if (s > max_)
120       remax (s);
121     size_ = s;
122   }
123
124   T*
125   data ()
126   {
127     return array_;
128   }
129
130   T const*
131   data () const
132   {
133     return array_;
134   }
135
136   iterator
137   begin ()
138   {
139     return data ();
140   }
141
142   const_iterator
143   begin () const
144   {
145     return data ();
146   }
147   
148   iterator
149   end ()
150   {
151     return data () + size_;
152   }
153
154   const_iterator
155   end () const
156   {
157     return data () + size_;
158   }
159
160   void clear ()
161   {
162     //resize (0);
163     size_ = 0;
164   }
165
166   T &
167   at (vsize i)
168   {
169     return (*this)[i];
170   }
171
172   T const &
173   at (vsize i) const
174   {
175     return (*this)[i];
176   }
177
178   T &operator [] (vsize i)
179   {
180     return array_[i];
181   }
182
183   T const &operator [] (vsize i) const
184   {
185     return array_[i];
186   }
187
188   iterator
189   erase (iterator p)
190   {
191     vsize i = p - data ();
192     index_assert (i);
193     arrcpy (array_ + i, array_ + i + 1, size_ - i - 1);
194     size_--;
195     return p;
196   }
197
198   void
199   insert (iterator b, T k)
200   {
201     vsize j = b - array_;
202     resize (size_ + 1);
203     index_assert (j);
204     for (vsize i = size_ - 1; i > j; i--)
205       array_[i] = array_[i - 1];
206     array_[j] = k;
207   }
208
209   void
210   insert (iterator pos, const_iterator b, const_iterator e)
211   {
212     vsize j = pos - array_;
213     vsize k = e - b;
214     resize (size_ + k);
215     for (vsize i = size_ - 1; i > j + k; i--)
216       array_[i] = array_[i - k];
217     for (vsize i = j; i < j + k; i++)
218       array_[i] = b[i - j];
219   }
220
221   /// add to the end of array
222   void push_back (T x)
223   {
224     if (size_ == max_)
225       remax (2 * max_ + 1);
226
227     // T::operator= (T &) is called here. Safe to use with automatic
228     // vars
229     array_[size_++] = x;
230   }
231
232
233   /* Flower intererface */
234
235   
236   /// check invariants
237   void OK () const;
238   /** report the size_.
239       @see
240       {setsize_}
241   */
242
243   Array (T *tp, vsize n)
244   {
245     array_ = new T[n];
246     max_ = size_ = n;
247     arrcpy (array_, tp, n);
248   }
249
250   // ugh, get around gcc 2.8.1 ice; see bezier.cc
251   Array (vsize i)
252   {
253     max_ = size_ = i;
254     array_ = new T[i];
255   }
256
257   /// tighten array size_.
258   void tighten_maxsize ()
259   {
260     remax (size_);
261   }
262
263   ~Array ()
264   {
265     delete[] array_;
266   }
267
268   /// return a  "new"ed copy of array 
269   T *copys () const
270   {
271     T *Tarray = new T[size_];
272     arrcpy (Tarray, array_, size_);
273     return Tarray;
274   }
275
276   T const *accesses () const
277   {
278     return array_;
279   }
280   void operator = (Array const &src)
281   {
282     resize (src.size_);
283     arrcpy (array_, src.array_, size_);
284   }
285
286   void unordered_del (vsize i)
287   {
288     at (i) = back ();
289     resize (size () -1);
290   }
291 };
292
293   template<typename T>
294   T const &
295   back (Array<T> const &v, vsize i)
296   {
297     return v[v.size () - i - 1];
298   }
299
300   template<typename T>
301   T&
302   back (Array<T> &v, vsize i)
303   {
304     return v[v.size () - i - 1];
305   }
306
307   template<typename T>
308   T const &
309   boundary (Array<T> const &v, int dir, vsize i)
310   {
311     assert (dir);
312     return v[dir == 1 ? i : v.size () - 1 - i];
313   }
314
315   template<typename T>
316   T &
317   boundary (Array<T> &v, int dir, vsize i)
318   {
319     assert (dir);
320     return v[dir == 1 ? i : v.size () - 1 - i];
321   }
322
323   template<class T>
324   void
325   reverse (Array<T> &v)
326   {
327     vsize h = v.size () / 2;
328     for (vsize i = 0, j = v.size () - 1; i < h; i++, j--)
329       swap (v[i], v[j]);
330   }
331
332 #include "array.icc"
333
334 }
335
336 #endif