ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/include/util.h
Revision: 1.31
Committed: Mon Jan 15 02:39:41 2007 UTC (17 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.30: +2 -0 lines
Log Message:
- fix crash bug
- better fork & abort (untested)

File Contents

# User Rev Content
1 root 1.1 #ifndef UTIL_H__
2     #define UTIL_H__
3    
4 root 1.2 #if __GNUC__ >= 3
5     # define is_constant(c) __builtin_constant_p (c)
6     #else
7     # define is_constant(c) 0
8     #endif
9    
10 root 1.11 #include <cstddef>
11 root 1.28 #include <cmath>
12 root 1.25 #include <new>
13     #include <vector>
14 root 1.11
15     #include <glib.h>
16    
17 root 1.25 #include <shstr.h>
18     #include <traits.h>
19    
20 root 1.14 // use a gcc extension for auto declarations until ISO C++ sanctifies them
21     #define AUTODECL(var,expr) typeof(expr) var = (expr)
22    
23 root 1.26 // very ugly macro that basicaly declares and initialises a variable
24     // that is in scope for the next statement only
25     // works only for stuff that can be assigned 0 and converts to false
26     // (note: works great for pointers)
27     // most ugly macro I ever wrote
28     #define declvar(type, name, value) if (type name = 0) { } else if (((name) = (value)), 1)
29    
30 root 1.27 // in range including end
31     #define IN_RANGE_INC(val,beg,end) \
32     ((unsigned int)(val) - (unsigned int)(beg) <= (unsigned int)(end) - (unsigned int)(beg))
33    
34     // in range excluding end
35     #define IN_RANGE_EXC(val,beg,end) \
36     ((unsigned int)(val) - (unsigned int)(beg) < (unsigned int)(end) - (unsigned int)(beg))
37    
38 root 1.31 void fork_abort (const char *msg);
39    
40 root 1.28 // this is much faster than crossfires original algorithm
41     // on modern cpus
42     inline int
43     isqrt (int n)
44     {
45     return (int)sqrtf ((float)n);
46     }
47    
48     // this is only twice as fast as naive sqrtf (dx*dy+dy*dy)
49     #if 0
50     // and has a max. error of 6 in the range -100..+100.
51     #else
52     // and has a max. error of 9 in the range -100..+100.
53     #endif
54     inline int
55     idistance (int dx, int dy)
56     {
57     unsigned int dx_ = abs (dx);
58     unsigned int dy_ = abs (dy);
59    
60     #if 0
61     return dx_ > dy_
62     ? (dx_ * 61685 + dy_ * 26870) >> 16
63     : (dy_ * 61685 + dx_ * 26870) >> 16;
64     #else
65 root 1.30 return dx_ + dy_ - min (dx_, dy_) * 5 / 8;
66 root 1.28 #endif
67     }
68    
69 root 1.29 /*
70     * absdir(int): Returns a number between 1 and 8, which represent
71     * the "absolute" direction of a number (it actually takes care of
72     * "overflow" in previous calculations of a direction).
73     */
74     inline int
75     absdir (int d)
76     {
77     return ((d - 1) & 7) + 1;
78     }
79 root 1.28
80 root 1.1 // makes dynamically allocated objects zero-initialised
81     struct zero_initialised
82     {
83 root 1.11 void *operator new (size_t s, void *p)
84     {
85     memset (p, 0, s);
86     return p;
87     }
88    
89     void *operator new (size_t s)
90     {
91     return g_slice_alloc0 (s);
92     }
93    
94     void *operator new[] (size_t s)
95     {
96     return g_slice_alloc0 (s);
97     }
98    
99     void operator delete (void *p, size_t s)
100     {
101     g_slice_free1 (s, p);
102     }
103    
104     void operator delete[] (void *p, size_t s)
105     {
106     g_slice_free1 (s, p);
107     }
108     };
109    
110 root 1.20 void *salloc_ (int n) throw (std::bad_alloc);
111     void *salloc_ (int n, void *src) throw (std::bad_alloc);
112    
113 root 1.12 // strictly the same as g_slice_alloc, but never returns 0
114 root 1.20 template<typename T>
115     inline T *salloc (int n = 1) throw (std::bad_alloc) { return (T *)salloc_ (n * sizeof (T)); }
116    
117 root 1.17 // also copies src into the new area, like "memdup"
118 root 1.18 // if src is 0, clears the memory
119     template<typename T>
120 root 1.20 inline T *salloc (int n, T *src) throw (std::bad_alloc) { return (T *)salloc_ (n * sizeof (T), (void *)src); }
121 root 1.18
122 root 1.21 // clears the memory
123     template<typename T>
124     inline T *salloc0(int n = 1) throw (std::bad_alloc) { return (T *)salloc_ (n * sizeof (T), 0); }
125    
126 root 1.12 // for symmetry
127 root 1.18 template<typename T>
128 root 1.20 inline void sfree (T *ptr, int n = 1) throw ()
129 root 1.12 {
130 root 1.20 g_slice_free1 (n * sizeof (T), (void *)ptr);
131 root 1.12 }
132 root 1.11
133     // a STL-compatible allocator that uses g_slice
134     // boy, this is verbose
135     template<typename Tp>
136     struct slice_allocator
137     {
138     typedef size_t size_type;
139     typedef ptrdiff_t difference_type;
140     typedef Tp *pointer;
141     typedef const Tp *const_pointer;
142     typedef Tp &reference;
143     typedef const Tp &const_reference;
144     typedef Tp value_type;
145    
146     template <class U>
147     struct rebind
148     {
149     typedef slice_allocator<U> other;
150     };
151    
152     slice_allocator () throw () { }
153     slice_allocator (const slice_allocator &o) throw () { }
154     template<typename Tp2>
155     slice_allocator (const slice_allocator<Tp2> &) throw () { }
156    
157     ~slice_allocator () { }
158    
159     pointer address (reference x) const { return &x; }
160     const_pointer address (const_reference x) const { return &x; }
161    
162     pointer allocate (size_type n, const_pointer = 0)
163     {
164 root 1.18 return salloc<Tp> (n);
165 root 1.11 }
166    
167     void deallocate (pointer p, size_type n)
168     {
169 root 1.19 sfree<Tp> (p, n);
170 root 1.11 }
171    
172     size_type max_size ()const throw ()
173     {
174     return size_t (-1) / sizeof (Tp);
175     }
176    
177     void construct (pointer p, const Tp &val)
178     {
179     ::new (p) Tp (val);
180     }
181    
182     void destroy (pointer p)
183     {
184     p->~Tp ();
185     }
186 root 1.1 };
187    
188 root 1.7 template<class T>
189     struct refptr
190     {
191     T *p;
192    
193     refptr () : p(0) { }
194     refptr (const refptr<T> &p) : p(p.p) { if (p) p->refcnt_inc (); }
195     refptr (T *p) : p(p) { if (p) p->refcnt_inc (); }
196     ~refptr () { if (p) p->refcnt_dec (); }
197    
198     const refptr<T> &operator =(T *o)
199     {
200     if (p) p->refcnt_dec ();
201     p = o;
202     if (p) p->refcnt_inc ();
203    
204     return *this;
205     }
206    
207     const refptr<T> &operator =(const refptr<T> o)
208     {
209     *this = o.p;
210     return *this;
211     }
212    
213     T &operator * () const { return *p; }
214     T *operator ->() const { return p; }
215    
216     operator T *() const { return p; }
217     };
218    
219 root 1.24 typedef refptr<maptile> maptile_ptr;
220 root 1.22 typedef refptr<object> object_ptr;
221     typedef refptr<archetype> arch_ptr;
222 root 1.24 typedef refptr<client> client_ptr;
223     typedef refptr<player> player_ptr;
224 root 1.22
225 root 1.4 struct str_hash
226     {
227     std::size_t operator ()(const char *s) const
228     {
229     unsigned long hash = 0;
230    
231     /* use the one-at-a-time hash function, which supposedly is
232     * better than the djb2-like one used by perl5.005, but
233     * certainly is better then the bug used here before.
234     * see http://burtleburtle.net/bob/hash/doobs.html
235     */
236     while (*s)
237     {
238     hash += *s++;
239     hash += hash << 10;
240     hash ^= hash >> 6;
241     }
242    
243     hash += hash << 3;
244     hash ^= hash >> 11;
245     hash += hash << 15;
246    
247     return hash;
248     }
249     };
250    
251     struct str_equal
252     {
253     bool operator ()(const char *a, const char *b) const
254     {
255     return !strcmp (a, b);
256     }
257     };
258    
259 root 1.26 template<class T>
260     struct unordered_vector : std::vector<T, slice_allocator<T> >
261 root 1.6 {
262 root 1.11 typedef typename unordered_vector::iterator iterator;
263 root 1.6
264     void erase (unsigned int pos)
265     {
266     if (pos < this->size () - 1)
267     (*this)[pos] = (*this)[this->size () - 1];
268    
269     this->pop_back ();
270     }
271    
272     void erase (iterator i)
273     {
274     erase ((unsigned int )(i - this->begin ()));
275     }
276     };
277    
278 root 1.26 template<class T, int T::* index>
279     struct object_vector : std::vector<T *, slice_allocator<T *> >
280     {
281     void insert (T *obj)
282     {
283     assert (!(obj->*index));
284     push_back (obj);
285     obj->*index = this->size ();
286     }
287    
288     void insert (T &obj)
289     {
290     insert (&obj);
291     }
292    
293     void erase (T *obj)
294     {
295     assert (obj->*index);
296     int pos = obj->*index;
297     obj->*index = 0;
298    
299     if (pos < this->size ())
300     {
301     (*this)[pos - 1] = (*this)[this->size () - 1];
302     (*this)[pos - 1]->*index = pos;
303     }
304    
305     this->pop_back ();
306     }
307    
308     void erase (T &obj)
309     {
310     errase (&obj);
311     }
312     };
313    
314 root 1.8 template<typename T, typename U> static inline T min (T a, U b) { return a < (T)b ? a : (T)b; }
315     template<typename T, typename U> static inline T max (T a, U b) { return a > (T)b ? a : (T)b; }
316     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; }
317    
318     template<typename T, typename U> static inline void swap (T& a, U& b) { T t=a; a=(T)b; b=(U)t; }
319    
320 root 1.10 // basically does what strncpy should do, but appends "..." to strings exceeding length
321     void assign (char *dst, const char *src, int maxlen);
322    
323     // type-safe version of assign
324 root 1.9 template<int N>
325     inline void assign (char (&dst)[N], const char *src)
326     {
327 root 1.10 assign ((char *)&dst, src, N);
328 root 1.9 }
329    
330 root 1.17 typedef double tstamp;
331    
332     // return current time as timestampe
333     tstamp now ();
334    
335 root 1.25 int similar_direction (int a, int b);
336    
337 root 1.1 #endif
338