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