ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/include/util.h
Revision: 1.30
Committed: Mon Jan 15 01:50:33 2007 UTC (17 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.29: +1 -1 lines
Log Message:
testing helps

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