ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtutil.h
Revision: 1.42
Committed: Mon Jan 3 03:05:47 2011 UTC (13 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.41: +12 -9 lines
Log Message:
*** empty log message ***

File Contents

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