ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/include/common/util.h
Revision: 1.3
Committed: Tue Aug 28 17:08:07 2007 UTC (19 years, 1 month ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.2: +54 -34 lines
Log Message:
- changed name
- updated the example config to the new system
- added more documentation
- enhanced documentation generators
- added a link to the pdf to the website
- added an RSS feed generator
- transitioned hooks to c++ callbacks
- did various merges with upstream along the way
- added const where appropriate
- removed the old block allocator
- fixed most memory leaks
- transitioned some dictionaries to std::map
- transitioned some lists to std::vector
- made some free functions members where appropriate
- renamed string to dynstr and added a static string ststr
- use NOW instead of time (NULL) if possible
- completely reworked database backends, crypto handlers and protocol handlers
  to use an object factory
- removed the old module system. ermyth does not do any dynamic loading anymore
- fixed most of the build system
- reworked how protocol commands work

File Contents

# User Rev Content
1 pippijn 1.2 /*
2     * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team
3     * Rights to this code are as documented in doc/pod/gplicense.pod.
4     *
5     * Various utility functions.
6     *
7 pippijn 1.3 * $Id: util.h,v 1.2 2007-07-25 01:05:17 pippijn Exp $
8 pippijn 1.2 */
9    
10 pippijn 1.1 #ifndef UTIL_H
11     #define UTIL_H
12    
13     #include <climits>
14     #include <cstddef>
15     #include <vector>
16    
17 pippijn 1.3 #include <ermyth/exception.h>
18 pippijn 1.1
19     /**
20     * Mostly the same as std::vector, but erase can reorder
21     * the elements, making insert/remove O(1) instead of O(n).
22     *
23     * NOTE: only some forms of erase are available
24     * (Taken from Crossfire TRT http://cf.schmorp.de/)
25     */
26     template<typename T, typename Alloc = std::allocator<T> >
27     struct unordered_vector : std::vector<T, Alloc>
28     {
29     typedef typename unordered_vector::iterator iterator;
30    
31     void erase (unsigned pos)
32     {
33     if (pos < this->size () - 1)
34     (*this)[pos] = (*this)[this->size () - 1];
35    
36     this->pop_back ();
37     }
38    
39     void erase (iterator pos)
40     {
41     erase ((unsigned)(pos - this->begin ()));
42     }
43    
44     void insert (T const &val)
45     {
46     push_back (val);
47     }
48     };
49    
50     /**
51     * The following templates find a sufficiently large integer type to contain
52     * the given number of bits.
53     *
54     * Usage:
55     *
56     * unsigned_type<16>::type a; // 16-bit unsigned if available (probably unsigned short)
57     * signed_type<8>::type a; // 8-bit signed if available (probably char)
58     */
59    
60     // Empty class if everything failed
61     struct empty_base
62     {
63     };
64    
65     // To allow inheritance from this and get the integer type out
66     template<typename T>
67     struct identity
68     {
69     typedef T type;
70     };
71    
72     /**
73     * The following two templates are a compile-time if-statement.
74     */
75     template<bool Cond, class Then, class Else>
76     struct If
77     {
78     typedef Then ret;
79     };
80    
81     template<class Then, class Else>
82     struct If<false, Then, Else>
83     {
84     typedef Else ret;
85     };
86    
87     // Looks whether the desired type exists
88     template<typename T, std::size_t bits, typename Else>
89     struct type_if_size
90     : If<sizeof (T) * CHAR_BIT >= bits, identity<T>, Else>::ret
91     {
92     };
93    
94     template<std::size_t bits>
95     struct unsigned_type
96     : type_if_size<unsigned char, bits,
97     type_if_size<unsigned short, bits,
98     type_if_size<unsigned int, bits,
99     type_if_size<unsigned long, bits,
100     empty_base // No such type
101     >
102     >
103     >
104     >
105     {
106     };
107    
108     template<std::size_t bits>
109     struct signed_type
110     : type_if_size<signed char, bits
111     , type_if_size<signed short, bits
112     , type_if_size<signed int, bits
113     , type_if_size<signed long, bits
114     , empty_base // No such type
115     >
116     >
117     >
118     >
119     {
120     };
121    
122 pippijn 1.3 // This is a vector that stores each element's index in the object.
123     // This only works for pointers to objects.
124     //
125     // Based on the object_vector from Crossfire TRT
126 pippijn 1.1 template<class T, int T::*index = &T::index, class Alloc = std::allocator<T *> >
127     struct indexing_vector : std::vector<T *, Alloc>
128     {
129     typedef typename indexing_vector::size_type size_type;
130     typedef typename indexing_vector::iterator iterator;
131    
132 pippijn 1.3 iterator find (const T *obj)
133     {
134     return obj->*index
135     ? this->begin () + obj->*index - 1
136     : this->end ();
137     }
138    
139     iterator find (const T &obj)
140     {
141     return find (&obj);
142     }
143    
144 pippijn 1.1 void erase (T *obj)
145     {
146 pippijn 1.3 unsigned int pos = obj->*index;
147 pippijn 1.1 obj->*index = 0;
148    
149 pippijn 1.3 if (pos < this->size ())
150 pippijn 1.1 {
151 pippijn 1.3 (*this)[pos - 1] = (*this)[this->size () - 1];
152     (*this)[pos - 1]->*index = pos;
153 pippijn 1.1 }
154    
155     this->pop_back ();
156     }
157    
158 pippijn 1.3 void erase (T &obj)
159     {
160     erase (&obj);
161     }
162    
163 pippijn 1.1 void insert (T *obj)
164     {
165     this->push_back (obj);
166     obj->*index = this->size ();
167     }
168     };
169    
170     struct str_hash
171     {
172     std::size_t operator () (char const *s) const
173     {
174     unsigned long hash = 0;
175    
176     // use the one-at-a-time hash function.
177     // see http://burtleburtle.net/bob/hash/doobs.html
178     while (*s)
179     {
180     hash += *s++;
181     hash += hash << 10;
182     hash ^= hash >> 6;
183     }
184    
185     hash += hash << 3;
186     hash ^= hash >> 11;
187     hash += hash << 15;
188    
189     return hash;
190     }
191     };
192    
193     struct str_eq
194     {
195     bool operator () (char const * const s1, char const * const s2) const
196     {
197     if (s1 == NULL || s2 == NULL)
198     throw nullpointer_exception ();
199     return !strcmp (s1, s2);
200     }
201     };
202    
203     struct str_lt
204     {
205     bool operator () (char const * const s1, char const * const s2) const
206     {
207     if (s1 == NULL || s2 == NULL)
208     throw nullpointer_exception ();
209     return strcmp (s1, s2) < 0;
210     }
211     };
212    
213 pippijn 1.3 E int irccasecmp (char const * const s1, char const * const s2);
214     E int ircncasecmp (char const * const s1, char const * const s2, int maxlen);
215    
216     struct irccase_lt
217     {
218     bool operator () (char const * const s1, char const * const s2) const
219     {
220     if (s1 == NULL || s2 == NULL)
221     throw nullpointer_exception ();
222     return irccasecmp (s1, s2) < 0;
223     }
224     };
225    
226     inline double
227     now ()
228     {
229     #ifdef HAVE_GETTIMEOFDAY
230     struct timeval tv;
231    
232     gettimeofday (&tv, 0);
233     return double (tv.tv_sec) + double (tv.tv_usec) * double (1e-6);
234     #else
235     return double (time (NULL));
236     #endif
237     }
238    
239    
240 pippijn 1.1 #endif