ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtutil.h
Revision: 1.41
Committed: Sat Dec 18 18:17:39 2010 UTC (13 years, 5 months ago) by sf-exg
Content type: text/plain
Branch: MAIN
Changes since 1.40: +2 -0 lines
Log Message:
Add ARRAY_LENGTH macro with obvious meaning and use it.

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