Do not link rxvtc to ev_cpp.o, it does not use libev.
[dana/urxvt.git] / src / rxvtutil.h
1 #ifndef RXVT_UTIL_H
2 #define RXVT_UTIL_H
3
4 #include <cstdlib>
5 #include <cstring>
6
7 using namespace std;
8
9 #define PP_CONCAT_(a, b) a ## b
10 #define PP_CONCAT(a, b) PP_CONCAT_(a, b)
11 #define PP_STRINGIFY_(a) #a
12 #define PP_STRINGIFY(a) PP_STRINGIFY_(a)
13
14 #define HAVE_GCC_BUILTINS (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ == 4))
15
16 #if __GNUC__ >= 4
17 # define rxvt_attribute(x) __attribute__(x)
18 # define expect(expr,value)         __builtin_expect ((expr),(value))
19 #else
20 # define rxvt_attribute(x)
21 # define expect(expr,value)         (expr)
22 #endif
23
24 // put into ifs if you are very sure that the expression
25 // is mostly true or mosty false. note that these return
26 // booleans, not the expression.
27 #define expect_false(expr) expect ((expr) != 0, 0)
28 #define expect_true(expr)  expect ((expr) != 0, 1)
29
30 #define NORETURN rxvt_attribute ((noreturn))
31 #define UNUSED   rxvt_attribute ((unused))
32 #define CONST    rxvt_attribute ((const))
33
34 // increases code size unless -fno-enforce-eh-specs
35 #if __GNUC__
36 # define NOTHROW
37 # define THROW(x)
38 #else
39 # define NOTHROW  throw()
40 # define THROW(x) throw x
41 #endif
42
43 extern class byteorder {
44   static unsigned int e; // at least 32 bits
45 public:
46   byteorder ();
47
48   static bool big_endian    () { return e == 0x11223344; };
49   static bool network       () { return e == 0x11223344; };
50   static bool little_endian () { return e == 0x44332211; };
51   static bool vax           () { return e == 0x44332211; };
52 } byteorder;
53
54 // various utility functions
55 template<typename T, typename U> static inline T    min    (T  a, U b) { return a < (T)b ? a : (T)b; }
56 template<typename T, typename U> static inline void min_it (T &a, U b) {    a = a < (T)b ? a : (T)b; }
57 template<typename T, typename U> static inline T    max    (T  a, U b) { return a > (T)b ? a : (T)b; }
58 template<typename T, typename U> static inline void max_it (T &a, U b) {    a = a > (T)b ? a : (T)b; }
59
60 template<typename T, typename U, typename V> static inline T    clamp    (T  v, U a, V b) { return v < (T)a ? a : v >(T)b ? b : v; }
61 template<typename T, typename U, typename V> static inline void clamp_it (T &v, U a, V b) {    v = v < (T)a ? a : v >(T)b ? b : v; }
62
63 template<typename T, typename U> static inline void swap (T& a, U& b) { T t=a; a=(T)b; b=(U)t; }
64
65 template<typename T> static inline T squared_diff (T a, T b) { return (a-b)*(a-b); }
66
67 // linear interpolation
68 template<typename T, typename U, typename P>
69 static inline
70 T lerp (T a, U b, P p)
71 {
72   return (long(a) * long(100 - p) + long(b) * long(p) + 50) / 100;
73 }
74
75 template <typename I, typename T>
76 I find (I first, I last, const T& value)
77 {
78   while (first != last && *first != value)
79     ++first;
80
81   return first;
82 }
83
84 // return a very temporary (and never deallocated) buffer. keep small.
85 void *rxvt_temp_buf (int len);
86
87 template<typename T>
88 static inline T *
89 rxvt_temp_buf (int len)
90 {
91   return (T *)rxvt_temp_buf (len * sizeof (T));
92 }
93
94 // some bit functions, xft fuck me plenty
95 #if HAVE_GCC_BUILTINS
96 /* netbsd stupidly defines popcount itself and puts it into string.h */
97 static inline int rxvt_ctz      (unsigned int x) { return __builtin_ctz      (x); }
98 static inline int rxvt_popcount (unsigned int x) { return __builtin_popcount (x); }
99 #else
100 // count trailing zero bits and count # of one bits
101 int rxvt_ctz      (unsigned int x) CONST;
102 int rxvt_popcount (unsigned int x) CONST;
103 #endif
104
105 // in range including end
106 #define IN_RANGE_INC(val,beg,end) \
107   ((unsigned int)(val) - (unsigned int)(beg) <= (unsigned int)(end) - (unsigned int)(beg))
108
109 // in range excluding end
110 #define IN_RANGE_EXC(val,beg,end) \
111   ((unsigned int)(val) - (unsigned int)(beg) <  (unsigned int)(end) - (unsigned int)(beg))
112
113 // for m >= -n, ensure remainder lies between 0..n-1
114 #define MOD(m,n) (((m) + (n)) % (n))
115
116 // makes dynamically allocated objects zero-initialised
117 struct zero_initialized
118 {
119   void *operator new (size_t s);
120   void operator delete (void *p, size_t s);
121 };
122
123 /* simplevec taken (and heavily modified), from:
124  *
125  *  MICO --- a free CORBA implementation
126  *  Copyright (C) 1997-98 Kay Roemer & Arno Puder
127  */
128 template<class T>
129 struct simplevec
130 {
131     typedef T* iterator;
132     typedef const T* const_iterator;
133     typedef unsigned long size_type;
134
135 private:
136     size_type _last, _size;
137     T *_buf;
138
139 public:
140     const_iterator begin () const
141     {
142         return &_buf[0];
143     }
144     iterator begin ()
145     {
146         return &_buf[0];
147     }
148     const_iterator end () const
149     {
150         return &_buf[_last];
151     }
152     iterator end ()
153     {
154         return &_buf[_last];
155     }
156     size_type capacity () const
157     {
158         return _size;
159     }
160     size_type size () const
161     {
162         return _last;
163     }
164
165 private:
166     static T *alloc (size_type n)
167     {
168         return (T *)::operator new ((size_t) (n * sizeof (T)));
169     }
170     static void dealloc (T *buf)
171     {
172         if (buf)
173             ::operator delete (buf);
174     }
175
176     void reserve (iterator where, size_type n)
177     {
178         if (_last + n <= _size) {
179             memmove (where+n, where, (end ()-where)*sizeof (T));
180         } else {
181             size_type sz = _last+n;
182             sz = (_size == 0) ? max (sz, 5) : max (sz, 2*_size);
183             T *nbuf = alloc (sz);
184             if (_buf) {
185                 memcpy (nbuf, begin (), (where-begin ())*sizeof (T));
186                 memcpy (nbuf + (where-begin ()) + n, where,
187                         (end ()-where)*sizeof (T));
188                 dealloc (_buf);
189             }
190             _buf = nbuf;
191             _size = sz;
192         }
193     }
194
195 public:
196     void reserve (size_type sz)
197     {
198         if (_size < sz) {
199             sz = (_size == 0) ? max (sz, 5) : max (sz, 2*_size);
200             T *nbuf = alloc (sz);
201             if (_buf) {
202                 memcpy (nbuf, begin (), size ()*sizeof (T));
203                 dealloc (_buf);
204             }
205             _buf = nbuf;
206             _size = sz;
207         }
208     }
209     simplevec ()
210     : _last(0), _size(0), _buf(0)
211     {
212     }
213     simplevec (size_type n, const T& t = T ())
214     : _last(0), _size(0), _buf(0)
215     {
216         insert (begin (), n, t);
217     }
218     simplevec (const_iterator first, const_iterator last)
219     : _last(0), _size(0), _buf(0)
220     {
221         insert (begin (), first, last);
222     }
223     simplevec (const simplevec<T> &v)
224     : _last(0), _size(0), _buf(0)
225     {
226         reserve (v._last);
227         memcpy (_buf, v.begin (), v.size ()*sizeof (T));
228         _last = v._last;
229     }
230     simplevec<T> &operator= (const simplevec<T> &v)
231     {
232         if (this != &v) {
233             _last = 0;
234             reserve (v._last);
235             memcpy (_buf, v.begin (), v.size ()*sizeof (T));
236             _last = v._last;
237         }
238         return *this;
239     }
240     ~simplevec ()
241     {
242         dealloc (_buf);
243     }
244     const T &front () const
245     {
246         //ministl_assert (size () > 0);
247         return _buf[0];
248     }
249     T &front ()
250     {
251         //ministl_assert (size () > 0);
252         return _buf[0];
253     }
254     const T &back () const
255     {
256         //ministl_assert (size () > 0);
257         return _buf[_last-1];
258     }
259     T &back ()
260     {
261         //ministl_assert (size () > 0);
262         return _buf[_last-1];
263     }
264     bool empty () const
265     {
266         return _last == 0;
267     }
268     void clear ()
269     {
270         _last = 0;
271     }
272     void push_back (const T &t)
273     {
274         reserve (_last+1);
275         *end () = t;
276         ++_last;
277     }
278     void push_back (T &t)
279     {
280         reserve (_last+1);
281         *end () = t;
282         ++_last;
283     }
284     void pop_back ()
285     {
286         //ministl_assert (size () > 0);
287         --_last;
288     }
289     const T &operator[] (size_type idx) const
290     {
291         //ministl_assert (idx < size ());
292         return _buf[idx];
293     }
294     T &operator[] (size_type idx)
295     {
296         //ministl_assert (idx < size ());
297         return _buf[idx];
298     }
299     iterator insert (iterator pos, const T &t)
300     {
301         //ministl_assert (pos <= end ());
302         long at = pos - begin ();
303         reserve (pos, 1);
304         pos = begin ()+at;
305         *pos = t;
306         ++_last;
307         return pos;
308     }
309     iterator insert (iterator pos, const_iterator first, const_iterator last)
310     {
311         //ministl_assert (pos <= end ());
312         long n = last - first;
313         long at = pos - begin ();
314         if (n > 0) {
315             reserve (pos, n);
316             pos = begin ()+at;
317             memcpy (pos, first, (last-first)*sizeof (T));
318             _last += n;
319         }
320         return pos;
321     }
322     iterator insert (iterator pos, size_type n, const T &t)
323     {
324         //ministl_assert (pos <= end ());
325         long at = pos - begin ();
326         if (n > 0) {
327             reserve (pos, n);
328             pos = begin ()+at;
329             for (int i = 0; i < n; ++i)
330                 pos[i] = t;
331             _last += n;
332         }
333         return pos;
334     }
335     void erase (iterator first, iterator last)
336     {
337         if (last != first) {
338             memmove (first, last, (end () - last) * sizeof (T));
339             _last -= last - first;
340         }
341     }
342     void erase (iterator pos)
343     {
344         if (pos != end ()) {
345             memmove (pos, pos+1, (end () - (pos+1)) * sizeof (T));
346             --_last;
347         }
348     }
349     void swap (simplevec<T> &t)
350     {
351         ::swap(_last, t._last);
352         ::swap(_size, t._size);
353         ::swap(_buf, t._buf);
354     }
355 };
356
357 template<class T>
358 bool operator== (const simplevec<T> &v1, const simplevec<T> &v2)
359 {
360     if (v1.size () != v2.size ())
361         return false;
362     return !v1.size () || !memcmp (&v1[0], &v2[0], v1.size ()*sizeof (T));
363 }
364
365 template<class T>
366 bool operator< (const simplevec<T> &v1, const simplevec<T> &v2)
367 {
368     unsigned long minlast = min (v1.size (), v2.size ());
369     for (unsigned long i = 0; i < minlast; ++i) {
370         if (v1[i] < v2[i])
371             return true;
372         if (v2[i] < v1[i])
373             return false;
374     }
375     return v1.size () < v2.size ();
376 }
377
378
379 template<typename T>
380 struct vector : simplevec<T>
381 {
382 };
383
384 struct stringvec : simplevec<char *>
385 {
386   ~stringvec ()
387   {
388     for (char **c = begin (); c != end (); c++)
389       free (*c);
390   }
391 };
392
393 #if 0
394 template<typename T>
395 struct rxvt_vec : simplevec<void *>
396 {
397   typedef T *iterator;
398
399   void push_back (T d) { simplevec<void *>::push_back ((void *)d); }
400   T pop_back () { return (T*)simplevec<void *>::pop_back (); }
401   void erase (int i) { erase (begin () + i); }
402   void erase (iterator i) { simplevec<void *>::erase ((void **)i); }
403   iterator begin () const { return (iterator)simplevec<void *>::begin (); }
404   iterator end () const { return (iterator)simplevec<void *>::end (); }
405   T &operator [] (int i) { return * (T *) (& ((* (simplevec<void *> *)this)[i])); }
406   const T &operator [] (int i) const { return * (const T *) (& ((* (const simplevec<void *> *)this)[i])); }
407 };
408 #endif
409
410 template<typename T>
411 struct auto_ptr
412 {
413   T *p;
414
415   auto_ptr () : p (0) { }
416   auto_ptr (T *a) : p (a) { }
417
418   auto_ptr (auto_ptr<T> &a)
419   {
420     p = a.p;
421     a.p = 0;
422   }
423
424   template<typename A>
425   auto_ptr (auto_ptr<A> &a)
426   {
427     p = a.p;
428     a.p = 0;
429   }
430
431   ~auto_ptr ()
432   {
433     delete p;
434   }
435
436   // void because it makes sense in our context
437   void operator = (T *a)
438   {
439     delete p;
440     p = a;
441   }
442
443   void operator = (auto_ptr &a)
444   {
445     *this = a.p;
446     a.p = 0;
447   }
448
449   template<typename A>
450   void operator = (auto_ptr<A> &a)
451   {
452     *this = a.p;
453     a.p = 0;
454   }
455
456   operator T * () const { return p; }
457
458   T *operator -> () const { return p; }
459   T &operator * () const { return *p; }
460
461   T *get ()
462   {
463     T *r = p;
464     p = 0;
465     return r;
466   }
467 };
468
469 typedef auto_ptr<char> auto_str;
470
471 #endif
472