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