*** empty log message ***
[dana/urxvt.git] / src / rxvtutil.h
1 #ifndef RXVT_UTIL_H
2 #define RXVT_UTIL_H
3
4 #include <cstring>
5
6 extern class byteorder {
7   static unsigned int e; // at least 32 bits
8 public:
9   byteorder ();
10
11   static bool big_endian    () { return e == 0x11223344; };
12   static bool network       () { return e == 0x11223344; };
13   static bool little_endian () { return e == 0x44332211; };
14   static bool vax           () { return e == 0x44332211; };
15 } byteorder;
16
17 template<typename T, typename U>
18 static inline T min (T a, U b) { return a < b ? a : (T)b; }
19 template<typename T, typename U>
20 static inline T max (T a, U b) { return a > b ? a : (T)b; }
21 template<typename T>
22 static inline void swap (T& a, T& b) { T t=a; a=b; b=t; }
23
24
25 struct zero_initialized {
26   void *operator new (size_t s);
27   void operator delete (void *p, size_t s);
28 };
29
30 /* simplevec taken (and heavily modified), from:
31  * 
32  *  MICO --- a free CORBA implementation
33  *  Copyright (C) 1997-98 Kay Roemer & Arno Puder
34  */
35 template<class T>
36 struct simplevec {
37     typedef T* iterator;
38     typedef const T* const_iterator;
39     typedef unsigned long size_type;
40
41 private:
42     size_type _last, _size;
43     T *_buf;
44
45 public:
46     const_iterator begin () const
47     {
48         return &_buf[0];
49     }
50     iterator begin ()
51     {
52         return &_buf[0];
53     }
54     const_iterator end () const
55     {
56         return &_buf[_last];
57     }
58     iterator end ()
59     {
60         return &_buf[_last];
61     }
62     size_type capacity () const
63     {
64         return _size;
65     }
66     size_type size () const
67     {
68         return _last;
69     }
70
71 private:
72     static T *alloc (size_type n)
73     {
74         return (T *)::operator new ((size_t) (n * sizeof (T)));
75     }
76     static void dealloc (T *buf)
77     {
78         if (buf)
79             ::operator delete (buf);
80     }
81
82     void reserve (iterator where, size_type n)
83     {
84         if (_last + n <= _size) {
85             memmove (where+n, where, (end ()-where)*sizeof (T));
86         } else {
87             size_type sz = _last+n;
88             sz = (_size == 0) ? max (sz, 5) : max (sz, 2*_size);
89             T *nbuf = alloc (sz);
90             if (_buf) {
91                 memcpy (nbuf, begin (), (where-begin ())*sizeof (T));
92                 memcpy (nbuf + (where-begin ()) + n, where,
93                         (end ()-where)*sizeof (T));
94                 dealloc (_buf);
95             }
96             _buf = nbuf;
97             _size = sz;
98         }
99     }
100
101 public:
102     void reserve (size_type sz)
103     {
104         if (_size < sz) {
105             sz = (_size == 0) ? max (sz, 5) : max (sz, 2*_size);
106             T *nbuf = alloc (sz);
107             if (_buf) {
108                 memcpy (nbuf, begin (), size ()*sizeof (T));
109                 dealloc (_buf);
110             }
111             _buf = nbuf;
112             _size = sz;
113         }
114     }
115     simplevec ()
116     : _last(0), _size(0), _buf(0)
117     {
118     }
119     simplevec (size_type n, const T& t = T ())
120     : _last(0), _size(0), _buf(0)
121     {
122         insert (begin (), n, t);
123     }
124     simplevec (const_iterator first, const_iterator last)
125     : _last(0), _size(0), _buf(0)
126     {
127         insert (begin (), first, last);
128     }
129     simplevec (const simplevec<T> &v)
130     : _last(0), _size(0), _buf(0)
131     {
132         reserve (v._last);
133         memcpy (_buf, v.begin (), v.size ()*sizeof (T));
134         _last = v._last;
135     }
136     simplevec<T> &operator= (const simplevec<T> &v)
137     {
138         if (this != &v) {
139             _last = 0;
140             reserve (v._last);
141             memcpy (_buf, v.begin (), v.size ()*sizeof (T));
142             _last = v._last;
143         }
144         return *this;
145     }
146     ~simplevec ()
147     {
148         dealloc (_buf);
149     }
150     const T &front () const
151     {
152         //ministl_assert (size () > 0);
153         return _buf[0];
154     }
155     T &front ()
156     {
157         //ministl_assert (size () > 0);
158         return _buf[0];
159     }
160     const T &back () const
161     {
162         //ministl_assert (size () > 0);
163         return _buf[_last-1];
164     }
165     T &back ()
166     {
167         //ministl_assert (size () > 0);
168         return _buf[_last-1];
169     }
170     bool empty () const
171     {
172         return _last == 0;
173     }
174     void clear ()
175     {
176         _last = 0;
177     }
178     void push_back (const T &t)
179     {
180         reserve (_last+1);
181         *end () = t;
182         ++_last;
183     }
184     void push_back (T &t)
185     {
186         reserve (_last+1);
187         *end () = t;
188         ++_last;
189     }
190     void pop_back ()
191     {
192         //ministl_assert (size () > 0);
193         --_last;
194     }
195     const T &operator[] (size_type idx) const
196     {
197         //ministl_assert (idx < size ());
198         return _buf[idx];
199     }
200     T &operator[] (size_type idx)
201     {
202         //ministl_assert (idx < size ());
203         return _buf[idx];
204     }
205     iterator insert (iterator pos, const T &t)
206     {
207         //ministl_assert (pos <= end ());
208         long at = pos - begin ();
209         reserve (pos, 1);
210         pos = begin ()+at;
211         *pos = t;
212         ++_last;
213         return pos;
214     }
215     iterator insert (iterator pos, const_iterator first, const_iterator last)
216     {
217         //ministl_assert (pos <= end ());
218         long n = last - first;
219         long at = pos - begin ();
220         if (n > 0) {
221             reserve (pos, n);
222             pos = begin ()+at;
223             memcpy (pos, first, (last-first)*sizeof (T));
224             _last += n;
225         }
226         return pos;
227     }
228     iterator insert (iterator pos, size_type n, const T &t)
229     {
230         //ministl_assert (pos <= end ());
231         long at = pos - begin ();
232         if (n > 0) {
233             reserve (pos, n);
234             pos = begin ()+at;
235             for (int i = 0; i < n; ++i)
236                 pos[i] = t;
237             _last += n;
238         }
239         return pos;
240     }
241     void erase (iterator first, iterator last)
242     {
243         if (last != first) {
244             memmove (first, last, (end ()-last)*sizeof (T));
245             _last -= last - first;
246         }
247     }
248     void erase (iterator pos)
249     {
250         if (pos != end ()) {
251             memmove (pos, pos+1, (end ()- (pos+1))*sizeof (T));
252             --_last;
253         }
254     }
255     void swap (simplevec<T> &t)
256     {
257         ::swap(_last, t._last);
258         ::swap(_size, t._size);
259         ::swap(_buf, t._buf);
260     }
261 };
262
263 template<class T>
264 bool operator== (const simplevec<T> &v1, const simplevec<T> &v2)
265 {
266     if (v1.size () != v2.size ())
267         return false;
268     return !v1.size () || !memcmp (&v1[0], &v2[0], v1.size ()*sizeof (T));
269 }
270
271 template<class T>
272 bool operator< (const simplevec<T> &v1, const simplevec<T> &v2)
273 {
274     unsigned long minlast = min (v1.size (), v2.size ());
275     for (unsigned long i = 0; i < minlast; ++i) {
276         if (v1[i] < v2[i])
277             return true;
278         if (v2[i] < v1[i])
279             return false;
280     }
281     return v1.size () < v2.size ();
282 }
283
284
285 template<typename T>
286 struct vector : simplevec<T>
287 { };
288
289 #if 0
290 template<typename T>
291 struct rxvt_vec : simplevec<void *> {
292   typedef T *iterator;
293
294   void push_back (T d) { simplevec<void *>::push_back ((void *)d); }
295   T pop_back () { return (T*)simplevec<void *>::pop_back (); }
296   void erase (int i) { erase (begin () + i); }
297   void erase (iterator i) { simplevec<void *>::erase ((void **)i); }
298   iterator begin () const { return (iterator)simplevec<void *>::begin (); }
299   iterator end () const { return (iterator)simplevec<void *>::end (); }
300   T &operator [] (int i) { return * (T *) (& ((* (simplevec<void *> *)this)[i])); }
301   const T &operator [] (int i) const { return * (const T *) (& ((* (const simplevec<void *> *)this)[i])); }
302 };
303 #endif
304
305 template <typename I, typename T>
306 I find (I first, I last, const T& value)
307 {
308   while (first != last && *first != value)
309     ++first;
310
311   return first;
312 }
313
314 template<typename T>
315 struct auto_ptr {
316   T *p;
317
318   auto_ptr () : p (0) { }
319   auto_ptr (T *a) : p (a) { }
320
321   auto_ptr (auto_ptr<T> &a)
322   {
323     p = a.p;
324     a.p = 0;
325   }
326
327   template<typename A>
328   auto_ptr (auto_ptr<A> &a)
329   {
330     p = a.p;
331     a.p = 0;
332   }
333
334   ~auto_ptr ()
335   {
336     delete p;
337   }
338
339   // void because it makes sense in our context
340   void operator = (T *a)
341   {
342     delete p;
343     p = a;
344   }
345
346   void operator = (auto_ptr &a)
347   {
348     *this = a.p;
349     a.p = 0;
350   }
351
352   template<typename A>
353   void operator = (auto_ptr<A> &a)
354   {
355     *this = a.p;
356     a.p = 0;
357   }
358
359   operator T * () const { return p; }
360
361   T *operator -> () const { return p; }
362   T &operator * () const { return *p; }
363
364   T *get ()
365   {
366     T *r = p;
367     p = 0;
368     return r;
369   }
370 };
371
372 typedef auto_ptr<char> auto_str;
373
374 struct stringvec : simplevec<char *>
375 {
376   ~stringvec ()
377   {
378     for (char **c = begin (); c != end (); c++)
379       delete [] *c;
380   }
381 };
382
383 #endif
384