ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtutil.h
Revision: 1.28
Committed: Tue Jun 26 10:46:28 2007 UTC (16 years, 11 months ago) by ayin
Content type: text/plain
Branch: MAIN
CVS Tags: rel-8_4, rel-8_3
Changes since 1.27: +1 -2 lines
Log Message:
gcc-3.4 has __builtin_{ctz,popcount}.

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