ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/include/util.h
Revision: 1.17
Committed: Sat Dec 16 03:08:26 2006 UTC (17 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.16: +12 -5 lines
Log Message:
- socket i/o is completely asynchronous now
- some command sare handled immediately
- others (most palying related commands) are queued
  for later (as of now synchronous) processing
- specifying a max queue length (in seconds) is possible, but disabled
- also add some syntax sugar for network code

File Contents

# Content
1 #ifndef UTIL_H__
2 #define UTIL_H__
3
4 #if __GNUC__ >= 3
5 # define is_constant(c) __builtin_constant_p (c)
6 #else
7 # define is_constant(c) 0
8 #endif
9
10 #include <cstddef>
11
12 #include <glib.h>
13
14 // use a gcc extension for auto declarations until ISO C++ sanctifies them
15 #define AUTODECL(var,expr) typeof(expr) var = (expr)
16
17 // makes dynamically allocated objects zero-initialised
18 struct zero_initialised
19 {
20 void *operator new (size_t s, void *p)
21 {
22 memset (p, 0, s);
23 return p;
24 }
25
26 void *operator new (size_t s)
27 {
28 return g_slice_alloc0 (s);
29 }
30
31 void *operator new[] (size_t s)
32 {
33 return g_slice_alloc0 (s);
34 }
35
36 void operator delete (void *p, size_t s)
37 {
38 g_slice_free1 (s, p);
39 }
40
41 void operator delete[] (void *p, size_t s)
42 {
43 g_slice_free1 (s, p);
44 }
45 };
46
47 // strictly the same as g_slice_alloc, but never returns 0
48 void *salloc (int size) throw (std::bad_alloc);
49 // also copies src into the new area, like "memdup"
50 void *salloc (int size, void *src) throw (std::bad_alloc);
51 // for symmetry
52 inline void sfree (void *ptr, int size) throw ()
53 {
54 g_slice_free1 (size, ptr);
55 }
56
57 // a STL-compatible allocator that uses g_slice
58 // boy, this is verbose
59 template<typename Tp>
60 struct slice_allocator
61 {
62 typedef size_t size_type;
63 typedef ptrdiff_t difference_type;
64 typedef Tp *pointer;
65 typedef const Tp *const_pointer;
66 typedef Tp &reference;
67 typedef const Tp &const_reference;
68 typedef Tp value_type;
69
70 template <class U>
71 struct rebind
72 {
73 typedef slice_allocator<U> other;
74 };
75
76 slice_allocator () throw () { }
77 slice_allocator (const slice_allocator &o) throw () { }
78 template<typename Tp2>
79 slice_allocator (const slice_allocator<Tp2> &) throw () { }
80
81 ~slice_allocator () { }
82
83 pointer address (reference x) const { return &x; }
84 const_pointer address (const_reference x) const { return &x; }
85
86 pointer allocate (size_type n, const_pointer = 0)
87 {
88 return static_cast<pointer>(salloc (n * sizeof (Tp)));
89 }
90
91 void deallocate (pointer p, size_type n)
92 {
93 sfree (static_cast<void *>(p), n * sizeof (Tp));
94 }
95
96 size_type max_size ()const throw ()
97 {
98 return size_t (-1) / sizeof (Tp);
99 }
100
101 void construct (pointer p, const Tp &val)
102 {
103 ::new (p) Tp (val);
104 }
105
106 void destroy (pointer p)
107 {
108 p->~Tp ();
109 }
110 };
111
112 struct refcounted
113 {
114 refcounted () : refcnt (0) { }
115 // virtual ~refcounted ();
116 void refcnt_inc () { ++refcnt; }
117 void refcnt_dec () { --refcnt; }
118 bool dead () { return refcnt == 0; }
119 mutable int refcnt;
120 #if 0
121 private:
122 static refcounted *rc_first;
123 refcounted *rc_next;
124 #endif
125 };
126
127 template<class T>
128 struct refptr
129 {
130 T *p;
131
132 refptr () : p(0) { }
133 refptr (const refptr<T> &p) : p(p.p) { if (p) p->refcnt_inc (); }
134 refptr (T *p) : p(p) { if (p) p->refcnt_inc (); }
135 ~refptr () { if (p) p->refcnt_dec (); }
136
137 const refptr<T> &operator =(T *o)
138 {
139 if (p) p->refcnt_dec ();
140 p = o;
141 if (p) p->refcnt_inc ();
142
143 return *this;
144 }
145
146 const refptr<T> &operator =(const refptr<T> o)
147 {
148 *this = o.p;
149 return *this;
150 }
151
152 T &operator * () const { return *p; }
153 T *operator ->() const { return p; }
154
155 operator T *() const { return p; }
156 };
157
158 struct str_hash
159 {
160 std::size_t operator ()(const char *s) const
161 {
162 unsigned long hash = 0;
163
164 /* use the one-at-a-time hash function, which supposedly is
165 * better than the djb2-like one used by perl5.005, but
166 * certainly is better then the bug used here before.
167 * see http://burtleburtle.net/bob/hash/doobs.html
168 */
169 while (*s)
170 {
171 hash += *s++;
172 hash += hash << 10;
173 hash ^= hash >> 6;
174 }
175
176 hash += hash << 3;
177 hash ^= hash >> 11;
178 hash += hash << 15;
179
180 return hash;
181 }
182 };
183
184 struct str_equal
185 {
186 bool operator ()(const char *a, const char *b) const
187 {
188 return !strcmp (a, b);
189 }
190 };
191
192 #include <vector>
193
194 template<class obj>
195 struct unordered_vector : std::vector<obj, slice_allocator<obj> >
196 {
197 typedef typename unordered_vector::iterator iterator;
198
199 void erase (unsigned int pos)
200 {
201 if (pos < this->size () - 1)
202 (*this)[pos] = (*this)[this->size () - 1];
203
204 this->pop_back ();
205 }
206
207 void erase (iterator i)
208 {
209 erase ((unsigned int )(i - this->begin ()));
210 }
211 };
212
213 template<typename T, typename U> static inline T min (T a, U b) { return a < (T)b ? a : (T)b; }
214 template<typename T, typename U> static inline T max (T a, U b) { return a > (T)b ? a : (T)b; }
215 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; }
216
217 template<typename T, typename U> static inline void swap (T& a, U& b) { T t=a; a=(T)b; b=(U)t; }
218
219 // basically does what strncpy should do, but appends "..." to strings exceeding length
220 void assign (char *dst, const char *src, int maxlen);
221
222 // type-safe version of assign
223 template<int N>
224 inline void assign (char (&dst)[N], const char *src)
225 {
226 assign ((char *)&dst, src, N);
227 }
228
229 typedef double tstamp;
230
231 // return current time as timestampe
232 tstamp now ();
233
234 #endif
235