]> git.donarmstrong.com Git - lilypond.git/blob - flower/include/std-vector.hh
* lily/spanner.cc (find_broken_piece):
[lilypond.git] / flower / include / std-vector.hh
1 /*
2   std-vector.hh -- declare vector
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2006 Jan Nieuwenhuizen <janneke@gnu.org>
7 */
8
9 #ifndef STD_VECTOR_HH
10 #define STD_VECTOR_HH
11
12 #include <algorithm>   /* find, reverse, sort */
13 #include <functional>  /* unary_function */
14 #include <cassert>
15
16 using namespace std;
17
18 #if HAVE_BOOST_LAMBDA
19 #include <boost/lambda/lambda.hpp>
20 #endif
21
22 template<typename T>
23 int default_compare (T const &a, T const &b)
24 {
25   if (a < b)
26     return -1;
27   else if (b < a)
28     return 1;
29   else
30     return 0;
31 }
32
33 template<typename T>
34 int default_compare (T *const &a, T *const &b)
35 {
36   if (a < b)
37     return -1;
38   else if (a > b)
39     return 1;
40   else
41     return 0;
42 }
43
44 #include "compare.hh"
45
46 #ifndef VSIZE
47 #define VSIZE
48 typedef size_t vsize;
49 #define VPOS ((vsize) -1)
50 #endif
51
52 #if HAVE_STL_DATA_METHOD
53 #include <vector>
54 #else /* !HAVE_STL_DATA_METHOD */
55 #define vector __vector
56 #include <vector>
57 #undef vector
58
59 namespace std {
60
61   /* Interface without pointer arithmetic (iterator) semantics.  */
62   template<typename T, typename A=std::allocator<T> >
63   class vector : public __vector<T, A>
64   {
65   public:
66     typedef typename __vector<T>::iterator iterator;
67     typedef typename __vector<T>::const_iterator const_iterator;
68
69     vector<T, A> () : __vector<T, A> ()
70     {
71     }
72
73     vector<T, A> (vector<T, A> const& v) : __vector<T, A> (v)
74     {
75     }
76
77     vector<T, A> (const_iterator b, const_iterator e) : __vector<T, A> (b, e)
78     {
79     }
80
81     T*
82     data ()
83     {
84       return &(*this)[0];
85     }
86
87     T const*
88     data () const
89     {
90       return &(*this)[0];
91     }
92   };
93
94 } /* namespace std */
95
96 #endif /* !HAVE_STL_DATA_METHOD */
97
98 template<typename T>
99 T const &
100 boundary (vector<T> const &v, int dir, vsize i)
101 {
102   assert (dir);
103   return v[dir == -1 ? i : v.size () - 1 - i];
104 }
105
106 template<typename T>
107 T &
108 boundary (vector<T> &v, int dir, vsize i)
109 {
110   assert (dir);
111   return v[dir == -1 ? i : v.size () - 1 - i];
112 }
113
114 template<typename T>
115 T const &
116 back (vector<T> const &v, vsize i)
117 {
118   return v[v.size () - i - 1];
119 }
120
121 template<typename T>
122 T&
123 back (vector<T> &v, vsize i)
124 {
125   return v[v.size () - i - 1];
126 }
127
128 template<typename T>
129 void
130 concat (vector<T> &v, vector<T> const& w)
131 {
132   v.insert (v.end (), w.begin (), w.end ());
133 }
134
135 template<typename T, typename Compare>
136 vsize
137 lower_bound (vector<T> const &v,
138              T const &key,
139              Compare less,
140              vsize b=0, vsize e=VPOS)
141 {
142   if (e == VPOS)
143     e = v.size ();
144   typename vector<T>::const_iterator i = lower_bound (v.begin () + b,
145                                                       v.begin () + e,
146                                                       key,
147                                                       less);
148
149   return i - v.begin ();
150 }
151
152 template<typename T, typename Compare>
153 vsize
154 upper_bound (vector<T> const &v,
155              T const &key,
156              Compare less,
157              vsize b=0, vsize e=VPOS)
158 {
159   if (e == VPOS)
160     e = v.size ();
161
162   typename vector<T>::const_iterator i = upper_bound (v.begin () + b,
163                                                       v.begin () + e,
164                                                       key,
165                                                       less);
166
167   return i - v.begin ();
168 }
169
170 template<typename T, typename Compare>
171 vsize
172 binary_search (vector<T> const &v,
173                T const &key,
174                Compare less=less<T> (),
175                vsize b=0, vsize e=VPOS)
176 {
177   vsize lb = lower_bound (v, key, less, b, e);
178
179   if (lb == v.size () || less (key, v[lb]))
180     return VPOS;
181   return lb;
182 }
183
184 #if 0
185 /* FIXME: the COMPARE functionality is broken?  */
186 template<typename T>
187 void
188 vector_sort (vector<T> &v, int (*compare) (T const &, T const &),
189              vsize lower=VPOS, vsize upper=VPOS)
190 {
191   typename vector<T>::iterator b = v.begin ();
192   typename vector<T>::iterator e = v.begin ();
193   if (lower == VPOS)
194     {
195       lower = 0;
196       upper = v.size ();
197     }
198   sort (b + lower, e + upper, compare);
199 }
200 #else
201
202 // ugh, c&p
203 template<typename T> void
204 vector_sort (vector<T> &v, int (*compare) (T const &, T const &),
205              vsize lower=VPOS, vsize upper=VPOS)
206 {
207   if (lower == VPOS)
208     {
209       lower = 0;
210       upper = v.size () - 1;
211     }
212   if (upper == VPOS || lower >= upper)
213     return;
214   swap (v[lower], v[(lower + upper) / 2]);
215   vsize last = lower;
216   for (vsize i = lower +1; i <= upper; i++)
217     if (compare (v[i], v[lower]) < 0)
218       swap (v[++last], v[i]);
219   swap (v[lower], v[last]);
220   vector_sort (v, compare, lower, last - 1);
221   vector_sort (v, compare, last + 1, upper);
222 }
223 #endif
224
225 template<typename T>
226 void
227 reverse (vector<T> &v)
228 {
229   // CHECKME: for a simple vector, like vector<int>, this should
230   // expand to memrev.
231   reverse (v.begin (), v.end ());
232 }
233
234 template<typename T>
235 void
236 uniq (vector<T> &v)
237 {
238   v.erase (unique (v.begin (), v.end ()), v.end ());
239 }
240
241 template<typename T>
242 typename vector<T>::const_iterator
243 find (vector<T> const &v, T const &key)
244 {
245   return find (v.begin (), v.end (), key);
246 }
247
248 #if HAVE_BOOST_LAMBDA
249 #include <boost/lambda/lambda.hpp>
250 using namespace boost::lambda;
251 template<typename T>
252 void
253 junk_pointers (vector<T> &v)
254 {
255   for_each (v.begin (), v.end (), (delete _1, _1 = 0));
256   v.clear ();
257 }
258 #else
259
260 template<typename T> struct del : public unary_function<T, void>
261 {
262   void operator() (T x)
263   {
264     delete x;
265     x = 0;
266   }
267 };
268
269 template<typename T>
270 void
271 junk_pointers (vector<T> &v)
272 {
273   // Hmm.
274   for_each (v.begin (), v.end (), del<T> ());
275   v.clear ();
276 }
277 #endif /* HAVE_BOOST_LAMBDA */
278
279 vector<string> string_split (string str, char c);
280
281 #define iterof(i,s) typeof((s).begin()) i((s).begin())
282
283 #endif /* STD_VECTOR_HH */