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