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

# 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 // actually, some gcc-3.x versions work, too
15 #define HAVE_GCC_BUILTINS (__GNUC__ >= 4)
16
17 #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 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 // various utility functions
51 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 template<typename T, typename U> static inline void swap (T& a, U& b) { T t=a; a=(T)b; b=(U)t; }
60
61 template<typename T> static inline T squared_diff (T a, T b) { return (a-b)*(a-b); }
62
63 // linear interpolation
64 template<typename T, typename U, typename P>
65 static inline
66 T lerp (T a, U b, P p)
67 {
68 return (long(a) * long(100 - p) + long(b) * long(p) + 50) / 100;
69 }
70
71 // some bit functions, xft fuck me plenty
72 #if HAVE_GCC_BUILTINS
73 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 #else
76 // count trailing zero bits and count # of one bits
77 int ctz (unsigned int x) CONST;
78 int popcount (unsigned int x) CONST;
79 #endif
80
81 // in range including end
82 #define IN_RANGE_INC(val,beg,end) \
83 ((unsigned int)(val) - (unsigned int)(beg) <= (unsigned int)(end) - (unsigned int)(beg))
84
85 // 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 // makes dynamically allocated objects zero-initialised
90 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 return &_buf[0];
114 }
115 iterator begin ()
116 {
117 return &_buf[0];
118 }
119 const_iterator end () const
120 {
121 return &_buf[_last];
122 }
123 iterator end ()
124 {
125 return &_buf[_last];
126 }
127 size_type capacity () const
128 {
129 return _size;
130 }
131 size_type size () const
132 {
133 return _last;
134 }
135
136 private:
137 static T *alloc (size_type n)
138 {
139 return (T *)::operator new ((size_t) (n * sizeof (T)));
140 }
141 static void dealloc (T *buf)
142 {
143 if (buf)
144 ::operator delete (buf);
145 }
146
147 void reserve (iterator where, size_type n)
148 {
149 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 }
165
166 public:
167 void reserve (size_type sz)
168 {
169 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 }
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 insert (begin (), n, t);
188 }
189 simplevec (const_iterator first, const_iterator last)
190 : _last(0), _size(0), _buf(0)
191 {
192 insert (begin (), first, last);
193 }
194 simplevec (const simplevec<T> &v)
195 : _last(0), _size(0), _buf(0)
196 {
197 reserve (v._last);
198 memcpy (_buf, v.begin (), v.size ()*sizeof (T));
199 _last = v._last;
200 }
201 simplevec<T> &operator= (const simplevec<T> &v)
202 {
203 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 return *this;
210 }
211 ~simplevec ()
212 {
213 dealloc (_buf);
214 }
215 const T &front () const
216 {
217 //ministl_assert (size () > 0);
218 return _buf[0];
219 }
220 T &front ()
221 {
222 //ministl_assert (size () > 0);
223 return _buf[0];
224 }
225 const T &back () const
226 {
227 //ministl_assert (size () > 0);
228 return _buf[_last-1];
229 }
230 T &back ()
231 {
232 //ministl_assert (size () > 0);
233 return _buf[_last-1];
234 }
235 bool empty () const
236 {
237 return _last == 0;
238 }
239 void clear ()
240 {
241 _last = 0;
242 }
243 void push_back (const T &t)
244 {
245 reserve (_last+1);
246 *end () = t;
247 ++_last;
248 }
249 void push_back (T &t)
250 {
251 reserve (_last+1);
252 *end () = t;
253 ++_last;
254 }
255 void pop_back ()
256 {
257 //ministl_assert (size () > 0);
258 --_last;
259 }
260 const T &operator[] (size_type idx) const
261 {
262 //ministl_assert (idx < size ());
263 return _buf[idx];
264 }
265 T &operator[] (size_type idx)
266 {
267 //ministl_assert (idx < size ());
268 return _buf[idx];
269 }
270 iterator insert (iterator pos, const T &t)
271 {
272 //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 }
280 iterator insert (iterator pos, const_iterator first, const_iterator last)
281 {
282 //ministl_assert (pos <= end ());
283 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 }
293 iterator insert (iterator pos, size_type n, const T &t)
294 {
295 //ministl_assert (pos <= end ());
296 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 }
306 void erase (iterator first, iterator last)
307 {
308 if (last != first) {
309 memmove (first, last, (end () - last) * sizeof (T));
310 _last -= last - first;
311 }
312 }
313 void erase (iterator pos)
314 {
315 if (pos != end ()) {
316 memmove (pos, pos+1, (end () - (pos+1)) * sizeof (T));
317 --_last;
318 }
319 }
320 void swap (simplevec<T> &t)
321 {
322 ::swap(_last, t._last);
323 ::swap(_size, t._size);
324 ::swap(_buf, t._buf);
325 }
326 };
327
328 template<class T>
329 bool operator== (const simplevec<T> &v1, const simplevec<T> &v2)
330 {
331 if (v1.size () != v2.size ())
332 return false;
333 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 return true;
343 if (v2[i] < v1[i])
344 return false;
345 }
346 return v1.size () < v2.size ();
347 }
348
349
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 free (*c);
445 }
446 };
447
448 // return a very temporary (and never deallocated) buffer. keep small.
449 void *rxvt_temp_buf (int len);
450
451 template<typename T>
452 static inline T *
453 rxvt_temp_buf (int len)
454 {
455 return (T *)rxvt_temp_buf (len * sizeof (T));
456 }
457
458 #endif
459