ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtutil.h
Revision: 1.37
Committed: Mon Jul 21 16:51:31 2008 UTC (15 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.36: +8 -0 lines
Log Message:
*** empty log message ***

File Contents

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