]> git.llucax.com Git - software/libev.git/blob - ev++.h
fix some aliasing issues again
[software/libev.git] / ev++.h
1 #ifndef EVPP_H__
2 #define EVPP_H__
3
4 #include "ev.h"
5
6 namespace ev {
7
8   template<class ev_watcher, class watcher>
9   struct base : ev_watcher
10   {
11     #if EV_MULTIPLICITY
12       EV_P;
13
14       void set (EV_P)
15       {
16         this->EV_A = EV_A;
17       }
18     #endif
19
20     base ()
21     {
22       ev_init (this, 0);
23     }
24
25     void set_ (void *data, void (*cb)(EV_P_ ev_watcher *w, int revents))
26     {
27       this->data = data;
28       ev_set_cb (static_cast<ev_watcher *>(this), cb);
29     }
30
31     template<class K, void (K::*method)(watcher &w, int)>
32     void set (K *object)
33     {
34       set_ (object, method_thunk<K, method>);
35     }
36
37     template<class K, void (K::*method)(watcher &w, int)>
38     static void method_thunk (EV_P_ ev_watcher *w, int revents)
39     {
40       K *obj = static_cast<K *>(w->data);
41       (obj->*method) (*static_cast<watcher *>(w), revents);
42     }
43
44     template<class K, void (K::*method)(watcher &w, int) const>
45     void set (const K *object)
46     {
47       set_ (object, const_method_thunk<K, method>);
48     }
49
50     template<class K, void (K::*method)(watcher &w, int) const>
51     static void const_method_thunk (EV_P_ ev_watcher *w, int revents)
52     {
53       K *obj = static_cast<K *>(w->data);
54       (static_cast<K *>(w->data)->*method) (*static_cast<watcher *>(w), revents);
55     }
56
57     template<void (*function)(watcher &w, int)>
58     void set (void *data = 0)
59     {
60       set_ (data, function_thunk<function>);
61     }
62
63     template<void (*function)(watcher &w, int)>
64     static void function_thunk (EV_P_ ev_watcher *w, int revents)
65     {
66       function (*static_cast<watcher *>(w), revents);
67     }
68
69     void operator ()(int events = EV_UNDEF)
70     {
71       return ev_cb (static_cast<ev_watcher *>(this))
72         (static_cast<ev_watcher *>(this), events);
73     }
74
75     bool is_active () const
76     {
77       return ev_is_active (static_cast<const ev_watcher *>(this));
78     }
79
80     bool is_pending () const
81     {
82       return ev_is_pending (static_cast<const ev_watcher *>(this));
83     }
84   };
85
86   enum {
87     UNDEF    = EV_UNDEF,
88     NONE     = EV_NONE,
89     READ     = EV_READ,
90     WRITE    = EV_WRITE,
91     TIMEOUT  = EV_TIMEOUT,
92     PERIODIC = EV_PERIODIC,
93     SIGNAL   = EV_SIGNAL,
94     CHILD    = EV_CHILD,
95     STAT     = EV_STAT,
96     IDLE     = EV_IDLE,
97     CHECK    = EV_CHECK,
98     PREPARE  = EV_PREPARE,
99     FORK     = EV_FORK,
100     EMBED    = EV_EMBED,
101     ERROR    = EV_ERROR,
102   };
103
104   typedef ev_tstamp tstamp;
105
106   inline ev_tstamp now (EV_P)
107   {
108     return ev_now (EV_A);
109   }
110
111   #if EV_MULTIPLICITY
112     #define EV_CONSTRUCT                                                                \
113       (EV_P = EV_DEFAULT)                                                               \
114       {                                                                                 \
115         set (EV_A);                                                                     \
116       }
117   #else
118     #define EV_CONSTRUCT                                                                \
119       ()                                                                                \
120       {                                                                                 \
121       }
122   #endif
123
124   /* using a template here would require quite a bit more lines,
125    * so a macro solution was chosen */
126   #define EV_BEGIN_WATCHER(cppstem,cstem)                                               \
127                                                                                         \
128   struct cppstem : base<ev_ ## cstem, cppstem>                                          \
129   {                                                                                     \
130     void start ()                                                                       \
131     {                                                                                   \
132       ev_ ## cstem ## _start (EV_A_ static_cast<ev_ ## cstem *>(this));                 \
133     }                                                                                   \
134                                                                                         \
135     void stop ()                                                                        \
136     {                                                                                   \
137       ev_ ## cstem ## _stop (EV_A_ static_cast<ev_ ## cstem *>(this));                  \
138     }                                                                                   \
139                                                                                         \
140     cppstem EV_CONSTRUCT                                                                \
141                                                                                         \
142     ~cppstem ()                                                                         \
143     {                                                                                   \
144       stop ();                                                                          \
145     }                                                                                   \
146                                                                                         \
147     using base<ev_ ## cstem, cppstem>::set;                                             \
148                                                                                         \
149   private:                                                                              \
150                                                                                         \
151     cppstem (const cppstem &o)                                                          \
152     { /* disabled */ }                                                                  \
153                                                                                         \
154     void operator =(const cppstem &o) { /* disabled */ }                                \
155                                                                                         \
156   public:
157
158   #define EV_END_WATCHER(cppstem,cstem)                                                 \
159   };
160
161   EV_BEGIN_WATCHER (io, io)
162     void set (int fd, int events)
163     {
164       int active = is_active ();
165       if (active) stop ();
166       ev_io_set (static_cast<ev_io *>(this), fd, events);
167       if (active) start ();
168     }
169
170     void set (int events)
171     {
172       int active = is_active ();
173       if (active) stop ();
174       ev_io_set (static_cast<ev_io *>(this), fd, events);
175       if (active) start ();
176     }
177
178     void start (int fd, int events)
179     {
180       set (fd, events);
181       start ();
182     }
183   EV_END_WATCHER (io, io)
184
185   EV_BEGIN_WATCHER (timer, timer)
186     void set (ev_tstamp after, ev_tstamp repeat = 0.)
187     {
188       int active = is_active ();
189       if (active) stop ();
190       ev_timer_set (static_cast<ev_timer *>(this), after, repeat);
191       if (active) start ();
192     }
193
194     void start (ev_tstamp after, ev_tstamp repeat = 0.)
195     {
196       set (after, repeat);
197       start ();
198     }
199
200     void again ()
201     {
202       ev_timer_again (EV_A_ static_cast<ev_timer *>(this));
203     }
204   EV_END_WATCHER (timer, timer)
205
206   #if EV_PERIODIC_ENABLE
207   EV_BEGIN_WATCHER (periodic, periodic)
208     void set (ev_tstamp at, ev_tstamp interval = 0.)
209     {
210       int active = is_active ();
211       if (active) stop ();
212       ev_periodic_set (static_cast<ev_periodic *>(this), at, interval, 0);
213       if (active) start ();
214     }
215
216     void start (ev_tstamp at, ev_tstamp interval = 0.)
217     {
218       set (at, interval);
219       start ();
220     }
221
222     void again ()
223     {
224       ev_periodic_again (EV_A_ static_cast<ev_periodic *>(this));
225     }
226   EV_END_WATCHER (periodic, periodic)
227   #endif
228
229   EV_BEGIN_WATCHER (sig, signal)
230     void set (int signum)
231     {
232       int active = is_active ();
233       if (active) stop ();
234       ev_signal_set (static_cast<ev_signal *>(this), signum);
235       if (active) start ();
236     }
237
238     void start (int signum)
239     {
240       set (signum);
241       start ();
242     }
243   EV_END_WATCHER (sig, signal)
244
245   EV_BEGIN_WATCHER (child, child)
246     void set (int pid)
247     {
248       int active = is_active ();
249       if (active) stop ();
250       ev_child_set (static_cast<ev_child *>(this), pid);
251       if (active) start ();
252     }
253
254     void start (int pid)
255     {
256       set (pid);
257       start ();
258     }
259   EV_END_WATCHER (child, child)
260
261   #if EV_STAT_ENABLE
262   EV_BEGIN_WATCHER (stat, stat)
263     void set (const char *path, ev_tstamp interval = 0.)
264     {
265       int active = is_active ();
266       if (active) stop ();
267       ev_stat_set (static_cast<ev_stat *>(this), path, interval);
268       if (active) start ();
269     }
270
271     void start (const char *path, ev_tstamp interval = 0.)
272     {
273       stop ();
274       set (path, interval);
275       start ();
276     }
277
278     void update ()
279     {
280       ev_stat_stat (EV_A_ static_cast<ev_stat *>(this));
281     }
282   EV_END_WATCHER (stat, stat)
283   #endif
284
285   EV_BEGIN_WATCHER (idle, idle)
286     void set () { }
287   EV_END_WATCHER (idle, idle)
288
289   EV_BEGIN_WATCHER (prepare, prepare)
290     void set () { }
291   EV_END_WATCHER (prepare, prepare)
292
293   EV_BEGIN_WATCHER (check, check)
294     void set () { }
295   EV_END_WATCHER (check, check)
296
297   #if EV_EMBED_ENABLE
298   EV_BEGIN_WATCHER (embed, embed)
299     void start (struct ev_loop *embedded_loop)
300     {
301       stop ();
302       ev_embed_set (static_cast<ev_embed *>(this), embedded_loop);
303       start ();
304     }
305
306     void sweep ()
307     {
308       ev_embed_sweep (EV_A_ static_cast<ev_embed *>(this));
309     }
310   EV_END_WATCHER (embed, embed)
311   #endif
312
313   #if EV_FORK_ENABLE
314   EV_BEGIN_WATCHER (fork, fork)
315     void set () { }
316   EV_END_WATCHER (fork, fork)
317   #endif
318
319   #undef EV_CONSTRUCT
320   #undef EV_BEGIN_WATCHER
321   #undef EV_END_WATCHER
322 }
323
324 #endif
325