ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtutil.h
Revision: 1.36
Committed: Fri Dec 14 11:11:31 2007 UTC (16 years, 6 months ago) by ayin
Content type: text/plain
Branch: MAIN
CVS Tags: rel-8_9, rel-8_8, rel-9_0, rel-9_02, rel-9_01, rel-9_05
Changes since 1.35: +3 -0 lines
Log Message:
Move MOD macro to rxvtutil.h.

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 ayin 1.36 // for m >= -n, ensure remainder lies between 0..n-1
105     #define MOD(m,n) (((m) + (n)) % (n))
106    
107 root 1.16 // makes dynamically allocated objects zero-initialised
108 root 1.4 struct zero_initialized {
109     void *operator new (size_t s);
110     void operator delete (void *p, size_t s);
111     };
112    
113     /* simplevec taken (and heavily modified), from:
114 ayin 1.29 *
115 root 1.4 * MICO --- a free CORBA implementation
116     * Copyright (C) 1997-98 Kay Roemer & Arno Puder
117     */
118     template<class T>
119     struct simplevec {
120     typedef T* iterator;
121     typedef const T* const_iterator;
122     typedef unsigned long size_type;
123    
124     private:
125     size_type _last, _size;
126     T *_buf;
127    
128     public:
129     const_iterator begin () const
130     {
131 root 1.8 return &_buf[0];
132 root 1.4 }
133     iterator begin ()
134     {
135 root 1.8 return &_buf[0];
136 root 1.4 }
137     const_iterator end () const
138     {
139 root 1.8 return &_buf[_last];
140 root 1.4 }
141     iterator end ()
142     {
143 root 1.8 return &_buf[_last];
144 root 1.4 }
145     size_type capacity () const
146     {
147 root 1.8 return _size;
148 root 1.4 }
149     size_type size () const
150     {
151 root 1.8 return _last;
152 root 1.4 }
153    
154     private:
155     static T *alloc (size_type n)
156     {
157 root 1.8 return (T *)::operator new ((size_t) (n * sizeof (T)));
158 root 1.4 }
159     static void dealloc (T *buf)
160     {
161 root 1.8 if (buf)
162     ::operator delete (buf);
163 root 1.4 }
164    
165     void reserve (iterator where, size_type n)
166     {
167 root 1.8 if (_last + n <= _size) {
168     memmove (where+n, where, (end ()-where)*sizeof (T));
169     } else {
170     size_type sz = _last+n;
171     sz = (_size == 0) ? max (sz, 5) : max (sz, 2*_size);
172     T *nbuf = alloc (sz);
173     if (_buf) {
174     memcpy (nbuf, begin (), (where-begin ())*sizeof (T));
175     memcpy (nbuf + (where-begin ()) + n, where,
176     (end ()-where)*sizeof (T));
177     dealloc (_buf);
178     }
179     _buf = nbuf;
180     _size = sz;
181     }
182 root 1.4 }
183    
184     public:
185     void reserve (size_type sz)
186     {
187 root 1.8 if (_size < sz) {
188     sz = (_size == 0) ? max (sz, 5) : max (sz, 2*_size);
189     T *nbuf = alloc (sz);
190     if (_buf) {
191     memcpy (nbuf, begin (), size ()*sizeof (T));
192     dealloc (_buf);
193     }
194     _buf = nbuf;
195     _size = sz;
196     }
197 root 1.4 }
198     simplevec ()
199     : _last(0), _size(0), _buf(0)
200     {
201     }
202     simplevec (size_type n, const T& t = T ())
203     : _last(0), _size(0), _buf(0)
204     {
205 root 1.8 insert (begin (), n, t);
206 root 1.4 }
207     simplevec (const_iterator first, const_iterator last)
208     : _last(0), _size(0), _buf(0)
209     {
210 root 1.8 insert (begin (), first, last);
211 root 1.4 }
212     simplevec (const simplevec<T> &v)
213     : _last(0), _size(0), _buf(0)
214     {
215 root 1.8 reserve (v._last);
216     memcpy (_buf, v.begin (), v.size ()*sizeof (T));
217     _last = v._last;
218 root 1.4 }
219     simplevec<T> &operator= (const simplevec<T> &v)
220     {
221 root 1.8 if (this != &v) {
222     _last = 0;
223     reserve (v._last);
224     memcpy (_buf, v.begin (), v.size ()*sizeof (T));
225     _last = v._last;
226     }
227 root 1.4 return *this;
228     }
229     ~simplevec ()
230     {
231 root 1.8 dealloc (_buf);
232 root 1.4 }
233     const T &front () const
234     {
235 root 1.8 //ministl_assert (size () > 0);
236     return _buf[0];
237 root 1.4 }
238     T &front ()
239     {
240 root 1.8 //ministl_assert (size () > 0);
241     return _buf[0];
242 root 1.4 }
243     const T &back () const
244     {
245 root 1.8 //ministl_assert (size () > 0);
246     return _buf[_last-1];
247 root 1.4 }
248     T &back ()
249     {
250 root 1.8 //ministl_assert (size () > 0);
251     return _buf[_last-1];
252 root 1.4 }
253     bool empty () const
254     {
255 root 1.8 return _last == 0;
256 root 1.4 }
257     void clear ()
258     {
259 root 1.8 _last = 0;
260 root 1.4 }
261     void push_back (const T &t)
262     {
263 root 1.8 reserve (_last+1);
264     *end () = t;
265     ++_last;
266 root 1.4 }
267     void push_back (T &t)
268     {
269 root 1.8 reserve (_last+1);
270     *end () = t;
271     ++_last;
272 root 1.4 }
273     void pop_back ()
274     {
275 root 1.8 //ministl_assert (size () > 0);
276     --_last;
277 root 1.4 }
278     const T &operator[] (size_type idx) const
279     {
280 root 1.8 //ministl_assert (idx < size ());
281     return _buf[idx];
282 root 1.4 }
283     T &operator[] (size_type idx)
284     {
285 root 1.8 //ministl_assert (idx < size ());
286     return _buf[idx];
287 root 1.4 }
288     iterator insert (iterator pos, const T &t)
289     {
290 root 1.8 //ministl_assert (pos <= end ());
291     long at = pos - begin ();
292     reserve (pos, 1);
293     pos = begin ()+at;
294     *pos = t;
295     ++_last;
296     return pos;
297 root 1.4 }
298     iterator insert (iterator pos, const_iterator first, const_iterator last)
299     {
300     //ministl_assert (pos <= end ());
301 root 1.8 long n = last - first;
302     long at = pos - begin ();
303     if (n > 0) {
304     reserve (pos, n);
305     pos = begin ()+at;
306     memcpy (pos, first, (last-first)*sizeof (T));
307     _last += n;
308     }
309     return pos;
310 root 1.4 }
311     iterator insert (iterator pos, size_type n, const T &t)
312     {
313     //ministl_assert (pos <= end ());
314 root 1.8 long at = pos - begin ();
315     if (n > 0) {
316     reserve (pos, n);
317     pos = begin ()+at;
318     for (int i = 0; i < n; ++i)
319     pos[i] = t;
320     _last += n;
321     }
322     return pos;
323 root 1.4 }
324     void erase (iterator first, iterator last)
325     {
326 root 1.8 if (last != first) {
327 root 1.18 memmove (first, last, (end () - last) * sizeof (T));
328 root 1.8 _last -= last - first;
329     }
330 root 1.4 }
331     void erase (iterator pos)
332     {
333     if (pos != end ()) {
334 root 1.18 memmove (pos, pos+1, (end () - (pos+1)) * sizeof (T));
335 root 1.4 --_last;
336     }
337     }
338 root 1.8 void swap (simplevec<T> &t)
339     {
340     ::swap(_last, t._last);
341     ::swap(_size, t._size);
342     ::swap(_buf, t._buf);
343     }
344 root 1.4 };
345    
346     template<class T>
347     bool operator== (const simplevec<T> &v1, const simplevec<T> &v2)
348     {
349     if (v1.size () != v2.size ())
350 root 1.8 return false;
351 root 1.4 return !v1.size () || !memcmp (&v1[0], &v2[0], v1.size ()*sizeof (T));
352     }
353    
354     template<class T>
355     bool operator< (const simplevec<T> &v1, const simplevec<T> &v2)
356     {
357     unsigned long minlast = min (v1.size (), v2.size ());
358     for (unsigned long i = 0; i < minlast; ++i) {
359     if (v1[i] < v2[i])
360 root 1.8 return true;
361     if (v2[i] < v1[i])
362     return false;
363 root 1.4 }
364     return v1.size () < v2.size ();
365     }
366    
367 root 1.1
368     template<typename T>
369     struct vector : simplevec<T>
370 root 1.35 {
371     };
372 root 1.1
373 ayin 1.32 struct stringvec : simplevec<char *>
374     {
375     ~stringvec ()
376     {
377     for (char **c = begin (); c != end (); c++)
378     free (*c);
379     }
380     };
381    
382 root 1.34 #if 0
383 root 1.1 template<typename T>
384     struct rxvt_vec : simplevec<void *> {
385     typedef T *iterator;
386    
387     void push_back (T d) { simplevec<void *>::push_back ((void *)d); }
388     T pop_back () { return (T*)simplevec<void *>::pop_back (); }
389     void erase (int i) { erase (begin () + i); }
390     void erase (iterator i) { simplevec<void *>::erase ((void **)i); }
391     iterator begin () const { return (iterator)simplevec<void *>::begin (); }
392     iterator end () const { return (iterator)simplevec<void *>::end (); }
393     T &operator [] (int i) { return * (T *) (& ((* (simplevec<void *> *)this)[i])); }
394     const T &operator [] (int i) const { return * (const T *) (& ((* (const simplevec<void *> *)this)[i])); }
395     };
396 root 1.34 #endif
397 root 1.1
398     template<typename T>
399     struct auto_ptr {
400     T *p;
401    
402     auto_ptr () : p (0) { }
403     auto_ptr (T *a) : p (a) { }
404    
405     auto_ptr (auto_ptr<T> &a)
406     {
407     p = a.p;
408     a.p = 0;
409     }
410    
411     template<typename A>
412     auto_ptr (auto_ptr<A> &a)
413     {
414     p = a.p;
415     a.p = 0;
416     }
417    
418     ~auto_ptr ()
419     {
420     delete p;
421     }
422    
423     // void because it makes sense in our context
424     void operator = (T *a)
425     {
426     delete p;
427     p = a;
428     }
429    
430     void operator = (auto_ptr &a)
431     {
432     *this = a.p;
433     a.p = 0;
434     }
435    
436     template<typename A>
437     void operator = (auto_ptr<A> &a)
438     {
439     *this = a.p;
440     a.p = 0;
441     }
442    
443     operator T * () const { return p; }
444    
445     T *operator -> () const { return p; }
446     T &operator * () const { return *p; }
447    
448     T *get ()
449     {
450     T *r = p;
451     p = 0;
452     return r;
453     }
454     };
455    
456     typedef auto_ptr<char> auto_str;
457 root 1.20
458 root 1.1 #endif
459