~ubuntu-branches/ubuntu/wily/cxxtools/wily-proposed

« back to all changes in this revision

Viewing changes to include/cxxtools/signals.tpp

  • Committer: Bazaar Package Importer
  • Author(s): Kari Pahula
  • Date: 2008-06-16 12:24:28 UTC
  • mfrom: (3.1.3 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080616122428-7bllgyt1358u779r
Tags: 1.4.8-2
Made libcxxtools-dev depend on libcxxtools6, not libcxxtools5.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// BEGIN_Signal 10
 
2
    /** Multicast Signal
 
3
 
 
4
        A Signal can be connected to multiple targets. The return
 
5
        value of the target(s) is/are ignored.
 
6
    */
 
7
    template <class A1 = Void, class A2 = Void, class A3 = Void, class A4 = Void, class A5 = Void, class A6 = Void, class A7 = Void, class A8 = Void, class A9 = Void, class A10 = Void>
 
8
    class Signal : public SignalBase {
 
9
        public:
 
10
            typedef Invokable<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10> _Invokable;
 
11
 
 
12
        public:
 
13
            /** Does nothing. */
 
14
            Signal()
 
15
            { }
 
16
 
 
17
            /** Deeply copies rhs. */
 
18
            Signal(const Signal& rhs)
 
19
            {
 
20
                Signal::operator=(rhs);
 
21
            }
 
22
 
 
23
            /**
 
24
            Connects slot to this signal, such that firing this signal
 
25
            will invoke slot.
 
26
            */
 
27
            template <typename R>
 
28
            Connection connect(const BasicSlot<R, A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>& slot)
 
29
            {
 
30
                return Connection(*this, slot.clone() );
 
31
            }
 
32
 
 
33
            /**
 
34
            Invokes all slots connected to this signal, in an undefined
 
35
            order. Their return values are ignored. Calling of connected slots will
 
36
            be interrupted if a slot deletes this Signal object or throws an exception.
 
37
            */
 
38
            inline void send(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) const
 
39
            {
 
40
                // The sentry will set the Signal to the sending state and
 
41
                // reset it to not-sending upon destruction. In the sending
 
42
                // state, removing connection will leave invalid connections
 
43
                // in the connection list to keep the iterator valid, but mark
 
44
                // the Signal dirty. If the Signal is dirty, all invalid
 
45
                // connections will be removed by the Sentry when it destructs..
 
46
                SignalBase::Sentry sentry(this);
 
47
 
 
48
                std::list<Connection>::const_iterator it = Connectable::connections().begin();
 
49
                std::list<Connection>::const_iterator end = Connectable::connections().end();
 
50
 
 
51
                for(; it != end; ++it)
 
52
                {
 
53
                    if( false == it->valid() || &( it->sender() ) != this  )
 
54
                        continue;
 
55
 
 
56
                    // The following scenarios must be considered when the
 
57
                    // slot is called:
 
58
                    // - The slot might get deleted and thus disconnected from
 
59
                    //   this signal
 
60
                    // - The slot might delete this signal and we must end
 
61
                    //   calling any slots immediately
 
62
                    // - A new Connection might get added to this Signal in
 
63
                    //   the slot
 
64
                    const _Invokable* invokable = static_cast<const _Invokable*>( it->slot().callable() );
 
65
                    invokable->invoke(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10);
 
66
 
 
67
                    // if this signal gets deleted by the slot, the Sentry
 
68
                    // will be detached. In this case we bail out immediately
 
69
                    if( !sentry )
 
70
                        return;
 
71
                }
 
72
            }
 
73
 
 
74
            /** Same as send(...). */
 
75
            inline void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) const
 
76
            { this->send(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10); }
 
77
    };
 
78
 
 
79
// END_Signal 10
 
80
// BEGIN_SignalSlot 10
 
81
    /**
 
82
      SignalSlot is a "slot wrapper" for Signal objects. That is, it
 
83
      effectively converts a Signal object into a Slot object, so that it
 
84
      can be used as the target of another Signal. This allows chaining of
 
85
      Signals.
 
86
    */
 
87
    template <class A1 = Void, class A2 = Void, class A3 = Void, class A4 = Void, class A5 = Void, class A6 = Void, class A7 = Void, class A8 = Void, class A9 = Void, class A10 = Void>
 
88
    class SignalSlot : public BasicSlot<void,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>
 
89
    {
 
90
        public:
 
91
            /** Wraps signal. */
 
92
            SignalSlot(Signal<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>& signal)
 
93
            : _method( signal, &Signal<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>::send )
 
94
            {}
 
95
 
 
96
            /** Creates a clone of this object and returns it. Caller owns
 
97
            the returned object. */
 
98
            BasicSlot<void,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>* clone() const
 
99
            { return new SignalSlot(*this); }
 
100
 
 
101
            /** Returns a pointer to this object's internal Callable object. */
 
102
            virtual const void* callable() const
 
103
            {
 
104
                return &_method;
 
105
            }
 
106
 
 
107
            /** ??? */
 
108
            virtual bool opened(const Connection& c)
 
109
            {
 
110
                Connectable& connectable = _method.object();
 
111
                return connectable.opened(c);
 
112
            }
 
113
 
 
114
            /** ??? */
 
115
            virtual void closed(const Connection& c)
 
116
            {
 
117
                Connectable& connectable = _method.object();
 
118
                connectable.closed(c);
 
119
            }
 
120
 
 
121
        private:
 
122
            mutable ConstMethod<void, Signal<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10 > _method;
 
123
    };
 
124
 
 
125
    /** Creates a SignalSlot object from an equivalent Signal. */
 
126
    template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
 
127
    SignalSlot<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10> slot( Signal<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10> & signal )
 
128
    { return SignalSlot<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>( signal ); }
 
129
 
 
130
 
 
131
    /** Connects the given signal and slot objects and returns that Connection
 
132
    object (which can normally be ignored). */
 
133
    template <typename R,class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
 
134
    Connection connect(Signal<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>& signal, const BasicSlot<R,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>& slot)
 
135
    {
 
136
        return Connection(signal, slot.clone() );
 
137
    }
 
138
 
 
139
 
 
140
    //! Connects a Signal to a function.
 
141
    template <typename R,class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
 
142
    Connection connect(Signal<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>& signal, R(*func)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10))
 
143
    {
 
144
        return connect( signal, slot(func) );
 
145
    }
 
146
 
 
147
    //! Connects a Signal to a member function.
 
148
    template <typename R, class BaseT, class ClassT,class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
 
149
    Connection connect(Signal<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>& signal, BaseT& object, R(ClassT::*memFunc)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10))
 
150
    {
 
151
        return connect( signal, slot(object, memFunc) );
 
152
    }
 
153
 
 
154
    //! Connects a Signal to a const member function.
 
155
    template <typename R, class ClassT,class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
 
156
    Connection connect(Signal<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>& signal, ClassT& object, R(ClassT::*memFunc)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const)
 
157
    {
 
158
        return connect( signal, slot(object, memFunc) );
 
159
    }
 
160
 
 
161
    /** Connects a Signal to another Signal. */
 
162
    template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
 
163
    Connection connect(Signal<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>& sender, Signal<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>& receiver)
 
164
    {
 
165
        return connect( sender, slot(receiver) );
 
166
    }
 
167
// END_SignalSlot 10
 
168
// BEGIN_Signal 9
 
169
    // specialization
 
170
    template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
 
171
    class Signal<A1,A2,A3,A4,A5,A6,A7,A8,A9,Void> : public SignalBase {
 
172
        public:
 
173
            typedef Invokable<A1,A2,A3,A4,A5,A6,A7,A8,A9,Void> _Invokable;
 
174
 
 
175
        public:
 
176
            /** Does nothing. */
 
177
            Signal()
 
178
            { }
 
179
 
 
180
            /** Deeply copies rhs. */
 
181
            Signal(const Signal& rhs)
 
182
            {
 
183
                Signal::operator=(rhs);
 
184
            }
 
185
 
 
186
            /**
 
187
            Connects slot to this signal, such that firing this signal
 
188
            will invoke slot.
 
189
            */
 
190
            template <typename R>
 
191
            Connection connect(const BasicSlot<R, A1,A2,A3,A4,A5,A6,A7,A8,A9,Void>& slot)
 
192
            {
 
193
                return Connection(*this, slot.clone() );
 
194
            }
 
195
 
 
196
            /**
 
197
            Invokes all slots connected to this signal, in an undefined
 
198
            order. Their return values are ignored. Calling of connected slots will
 
199
            be interrupted if a slot deletes this Signal object or throws an exception.
 
200
            */
 
201
            inline void send(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) const
 
202
            {
 
203
                // The sentry will set the Signal to the sending state and
 
204
                // reset it to not-sending upon destruction. In the sending
 
205
                // state, removing connection will leave invalid connections
 
206
                // in the connection list to keep the iterator valid, but mark
 
207
                // the Signal dirty. If the Signal is dirty, all invalid
 
208
                // connections will be removed by the Sentry when it destructs..
 
209
                SignalBase::Sentry sentry(this);
 
210
 
 
211
                std::list<Connection>::const_iterator it = Connectable::connections().begin();
 
212
                std::list<Connection>::const_iterator end = Connectable::connections().end();
 
213
 
 
214
                for(; it != end; ++it)
 
215
                {
 
216
                    if( false == it->valid() || &( it->sender() ) != this  )
 
217
                        continue;
 
218
 
 
219
                    // The following scenarios must be considered when the
 
220
                    // slot is called:
 
221
                    // - The slot might get deleted and thus disconnected from
 
222
                    //   this signal
 
223
                    // - The slot might delete this signal and we must end
 
224
                    //   calling any slots immediately
 
225
                    // - A new Connection might get added to this Signal in
 
226
                    //   the slot
 
227
                    const _Invokable* invokable = static_cast<const _Invokable*>( it->slot().callable() );
 
228
                    invokable->invoke(a1,a2,a3,a4,a5,a6,a7,a8,a9);
 
229
 
 
230
                    // if this signal gets deleted by the slot, the Sentry
 
231
                    // will be detached. In this case we bail out immediately
 
232
                    if( !sentry )
 
233
                        return;
 
234
                }
 
235
            }
 
236
 
 
237
            /** Same as send(...). */
 
238
            inline void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) const
 
239
            { this->send(a1,a2,a3,a4,a5,a6,a7,a8,a9); }
 
240
    };
 
241
 
 
242
// END_Signal 9
 
243
// BEGIN_SignalSlot 9
 
244
 
 
245
    //! Connects a Signal to a function.
 
246
    template <typename R,class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
 
247
    Connection connect(Signal<A1,A2,A3,A4,A5,A6,A7,A8,A9>& signal, R(*func)(A1,A2,A3,A4,A5,A6,A7,A8,A9))
 
248
    {
 
249
        return connect( signal, slot(func) );
 
250
    }
 
251
 
 
252
    //! Connects a Signal to a member function.
 
253
    template <typename R, class BaseT, class ClassT,class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
 
254
    Connection connect(Signal<A1,A2,A3,A4,A5,A6,A7,A8,A9>& signal, BaseT& object, R(ClassT::*memFunc)(A1,A2,A3,A4,A5,A6,A7,A8,A9))
 
255
    {
 
256
        return connect( signal, slot(object, memFunc) );
 
257
    }
 
258
 
 
259
    //! Connects a Signal to a const member function.
 
260
    template <typename R, class ClassT,class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
 
261
    Connection connect(Signal<A1,A2,A3,A4,A5,A6,A7,A8,A9>& signal, ClassT& object, R(ClassT::*memFunc)(A1,A2,A3,A4,A5,A6,A7,A8,A9) const)
 
262
    {
 
263
        return connect( signal, slot(object, memFunc) );
 
264
    }
 
265
 
 
266
    /** Connects a Signal to another Signal. */
 
267
    template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
 
268
    Connection connect(Signal<A1,A2,A3,A4,A5,A6,A7,A8,A9>& sender, Signal<A1,A2,A3,A4,A5,A6,A7,A8,A9>& receiver)
 
269
    {
 
270
        return connect( sender, slot(receiver) );
 
271
    }
 
272
// END_SignalSlot 9
 
273
// BEGIN_Signal 8
 
274
    // specialization
 
275
    template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
 
276
    class Signal<A1,A2,A3,A4,A5,A6,A7,A8,Void,Void> : public SignalBase {
 
277
        public:
 
278
            typedef Invokable<A1,A2,A3,A4,A5,A6,A7,A8,Void,Void> _Invokable;
 
279
 
 
280
        public:
 
281
            /** Does nothing. */
 
282
            Signal()
 
283
            { }
 
284
 
 
285
            /** Deeply copies rhs. */
 
286
            Signal(const Signal& rhs)
 
287
            {
 
288
                Signal::operator=(rhs);
 
289
            }
 
290
 
 
291
            /**
 
292
            Connects slot to this signal, such that firing this signal
 
293
            will invoke slot.
 
294
            */
 
295
            template <typename R>
 
296
            Connection connect(const BasicSlot<R, A1,A2,A3,A4,A5,A6,A7,A8,Void,Void>& slot)
 
297
            {
 
298
                return Connection(*this, slot.clone() );
 
299
            }
 
300
 
 
301
            /**
 
302
            Invokes all slots connected to this signal, in an undefined
 
303
            order. Their return values are ignored. Calling of connected slots will
 
304
            be interrupted if a slot deletes this Signal object or throws an exception.
 
305
            */
 
306
            inline void send(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
 
307
            {
 
308
                // The sentry will set the Signal to the sending state and
 
309
                // reset it to not-sending upon destruction. In the sending
 
310
                // state, removing connection will leave invalid connections
 
311
                // in the connection list to keep the iterator valid, but mark
 
312
                // the Signal dirty. If the Signal is dirty, all invalid
 
313
                // connections will be removed by the Sentry when it destructs..
 
314
                SignalBase::Sentry sentry(this);
 
315
 
 
316
                std::list<Connection>::const_iterator it = Connectable::connections().begin();
 
317
                std::list<Connection>::const_iterator end = Connectable::connections().end();
 
318
 
 
319
                for(; it != end; ++it)
 
320
                {
 
321
                    if( false == it->valid() || &( it->sender() ) != this  )
 
322
                        continue;
 
323
 
 
324
                    // The following scenarios must be considered when the
 
325
                    // slot is called:
 
326
                    // - The slot might get deleted and thus disconnected from
 
327
                    //   this signal
 
328
                    // - The slot might delete this signal and we must end
 
329
                    //   calling any slots immediately
 
330
                    // - A new Connection might get added to this Signal in
 
331
                    //   the slot
 
332
                    const _Invokable* invokable = static_cast<const _Invokable*>( it->slot().callable() );
 
333
                    invokable->invoke(a1,a2,a3,a4,a5,a6,a7,a8);
 
334
 
 
335
                    // if this signal gets deleted by the slot, the Sentry
 
336
                    // will be detached. In this case we bail out immediately
 
337
                    if( !sentry )
 
338
                        return;
 
339
                }
 
340
            }
 
341
 
 
342
            /** Same as send(...). */
 
343
            inline void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
 
344
            { this->send(a1,a2,a3,a4,a5,a6,a7,a8); }
 
345
    };
 
346
 
 
347
// END_Signal 8
 
348
// BEGIN_SignalSlot 8
 
349
 
 
350
    //! Connects a Signal to a function.
 
351
    template <typename R,class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
 
352
    Connection connect(Signal<A1,A2,A3,A4,A5,A6,A7,A8>& signal, R(*func)(A1,A2,A3,A4,A5,A6,A7,A8))
 
353
    {
 
354
        return connect( signal, slot(func) );
 
355
    }
 
356
 
 
357
    //! Connects a Signal to a member function.
 
358
    template <typename R, class BaseT, class ClassT,class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
 
359
    Connection connect(Signal<A1,A2,A3,A4,A5,A6,A7,A8>& signal, BaseT& object, R(ClassT::*memFunc)(A1,A2,A3,A4,A5,A6,A7,A8))
 
360
    {
 
361
        return connect( signal, slot(object, memFunc) );
 
362
    }
 
363
 
 
364
    //! Connects a Signal to a const member function.
 
365
    template <typename R, class ClassT,class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
 
366
    Connection connect(Signal<A1,A2,A3,A4,A5,A6,A7,A8>& signal, ClassT& object, R(ClassT::*memFunc)(A1,A2,A3,A4,A5,A6,A7,A8) const)
 
367
    {
 
368
        return connect( signal, slot(object, memFunc) );
 
369
    }
 
370
 
 
371
    /** Connects a Signal to another Signal. */
 
372
    template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
 
373
    Connection connect(Signal<A1,A2,A3,A4,A5,A6,A7,A8>& sender, Signal<A1,A2,A3,A4,A5,A6,A7,A8>& receiver)
 
374
    {
 
375
        return connect( sender, slot(receiver) );
 
376
    }
 
377
// END_SignalSlot 8
 
378
// BEGIN_Signal 7
 
379
    // specialization
 
380
    template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
 
381
    class Signal<A1,A2,A3,A4,A5,A6,A7,Void,Void,Void> : public SignalBase {
 
382
        public:
 
383
            typedef Invokable<A1,A2,A3,A4,A5,A6,A7,Void,Void,Void> _Invokable;
 
384
 
 
385
        public:
 
386
            /** Does nothing. */
 
387
            Signal()
 
388
            { }
 
389
 
 
390
            /** Deeply copies rhs. */
 
391
            Signal(const Signal& rhs)
 
392
            {
 
393
                Signal::operator=(rhs);
 
394
            }
 
395
 
 
396
            /**
 
397
            Connects slot to this signal, such that firing this signal
 
398
            will invoke slot.
 
399
            */
 
400
            template <typename R>
 
401
            Connection connect(const BasicSlot<R, A1,A2,A3,A4,A5,A6,A7,Void,Void,Void>& slot)
 
402
            {
 
403
                return Connection(*this, slot.clone() );
 
404
            }
 
405
 
 
406
            /**
 
407
            Invokes all slots connected to this signal, in an undefined
 
408
            order. Their return values are ignored. Calling of connected slots will
 
409
            be interrupted if a slot deletes this Signal object or throws an exception.
 
410
            */
 
411
            inline void send(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
 
412
            {
 
413
                // The sentry will set the Signal to the sending state and
 
414
                // reset it to not-sending upon destruction. In the sending
 
415
                // state, removing connection will leave invalid connections
 
416
                // in the connection list to keep the iterator valid, but mark
 
417
                // the Signal dirty. If the Signal is dirty, all invalid
 
418
                // connections will be removed by the Sentry when it destructs..
 
419
                SignalBase::Sentry sentry(this);
 
420
 
 
421
                std::list<Connection>::const_iterator it = Connectable::connections().begin();
 
422
                std::list<Connection>::const_iterator end = Connectable::connections().end();
 
423
 
 
424
                for(; it != end; ++it)
 
425
                {
 
426
                    if( false == it->valid() || &( it->sender() ) != this  )
 
427
                        continue;
 
428
 
 
429
                    // The following scenarios must be considered when the
 
430
                    // slot is called:
 
431
                    // - The slot might get deleted and thus disconnected from
 
432
                    //   this signal
 
433
                    // - The slot might delete this signal and we must end
 
434
                    //   calling any slots immediately
 
435
                    // - A new Connection might get added to this Signal in
 
436
                    //   the slot
 
437
                    const _Invokable* invokable = static_cast<const _Invokable*>( it->slot().callable() );
 
438
                    invokable->invoke(a1,a2,a3,a4,a5,a6,a7);
 
439
 
 
440
                    // if this signal gets deleted by the slot, the Sentry
 
441
                    // will be detached. In this case we bail out immediately
 
442
                    if( !sentry )
 
443
                        return;
 
444
                }
 
445
            }
 
446
 
 
447
            /** Same as send(...). */
 
448
            inline void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
 
449
            { this->send(a1,a2,a3,a4,a5,a6,a7); }
 
450
    };
 
451
 
 
452
// END_Signal 7
 
453
// BEGIN_SignalSlot 7
 
454
 
 
455
    //! Connects a Signal to a function.
 
456
    template <typename R,class A1, class A2, class A3, class A4, class A5, class A6, class A7>
 
457
    Connection connect(Signal<A1,A2,A3,A4,A5,A6,A7>& signal, R(*func)(A1,A2,A3,A4,A5,A6,A7))
 
458
    {
 
459
        return connect( signal, slot(func) );
 
460
    }
 
461
 
 
462
    //! Connects a Signal to a member function.
 
463
    template <typename R, class BaseT, class ClassT,class A1, class A2, class A3, class A4, class A5, class A6, class A7>
 
464
    Connection connect(Signal<A1,A2,A3,A4,A5,A6,A7>& signal, BaseT& object, R(ClassT::*memFunc)(A1,A2,A3,A4,A5,A6,A7))
 
465
    {
 
466
        return connect( signal, slot(object, memFunc) );
 
467
    }
 
468
 
 
469
    //! Connects a Signal to a const member function.
 
470
    template <typename R, class ClassT,class A1, class A2, class A3, class A4, class A5, class A6, class A7>
 
471
    Connection connect(Signal<A1,A2,A3,A4,A5,A6,A7>& signal, ClassT& object, R(ClassT::*memFunc)(A1,A2,A3,A4,A5,A6,A7) const)
 
472
    {
 
473
        return connect( signal, slot(object, memFunc) );
 
474
    }
 
475
 
 
476
    /** Connects a Signal to another Signal. */
 
477
    template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
 
478
    Connection connect(Signal<A1,A2,A3,A4,A5,A6,A7>& sender, Signal<A1,A2,A3,A4,A5,A6,A7>& receiver)
 
479
    {
 
480
        return connect( sender, slot(receiver) );
 
481
    }
 
482
// END_SignalSlot 7
 
483
// BEGIN_Signal 6
 
484
    // specialization
 
485
    template <class A1, class A2, class A3, class A4, class A5, class A6>
 
486
    class Signal<A1,A2,A3,A4,A5,A6,Void,Void,Void,Void> : public SignalBase {
 
487
        public:
 
488
            typedef Invokable<A1,A2,A3,A4,A5,A6,Void,Void,Void,Void> _Invokable;
 
489
 
 
490
        public:
 
491
            /** Does nothing. */
 
492
            Signal()
 
493
            { }
 
494
 
 
495
            /** Deeply copies rhs. */
 
496
            Signal(const Signal& rhs)
 
497
            {
 
498
                Signal::operator=(rhs);
 
499
            }
 
500
 
 
501
            /**
 
502
            Connects slot to this signal, such that firing this signal
 
503
            will invoke slot.
 
504
            */
 
505
            template <typename R>
 
506
            Connection connect(const BasicSlot<R, A1,A2,A3,A4,A5,A6,Void,Void,Void,Void>& slot)
 
507
            {
 
508
                return Connection(*this, slot.clone() );
 
509
            }
 
510
 
 
511
            /**
 
512
            Invokes all slots connected to this signal, in an undefined
 
513
            order. Their return values are ignored. Calling of connected slots will
 
514
            be interrupted if a slot deletes this Signal object or throws an exception.
 
515
            */
 
516
            inline void send(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
 
517
            {
 
518
                // The sentry will set the Signal to the sending state and
 
519
                // reset it to not-sending upon destruction. In the sending
 
520
                // state, removing connection will leave invalid connections
 
521
                // in the connection list to keep the iterator valid, but mark
 
522
                // the Signal dirty. If the Signal is dirty, all invalid
 
523
                // connections will be removed by the Sentry when it destructs..
 
524
                SignalBase::Sentry sentry(this);
 
525
 
 
526
                std::list<Connection>::const_iterator it = Connectable::connections().begin();
 
527
                std::list<Connection>::const_iterator end = Connectable::connections().end();
 
528
 
 
529
                for(; it != end; ++it)
 
530
                {
 
531
                    if( false == it->valid() || &( it->sender() ) != this  )
 
532
                        continue;
 
533
 
 
534
                    // The following scenarios must be considered when the
 
535
                    // slot is called:
 
536
                    // - The slot might get deleted and thus disconnected from
 
537
                    //   this signal
 
538
                    // - The slot might delete this signal and we must end
 
539
                    //   calling any slots immediately
 
540
                    // - A new Connection might get added to this Signal in
 
541
                    //   the slot
 
542
                    const _Invokable* invokable = static_cast<const _Invokable*>( it->slot().callable() );
 
543
                    invokable->invoke(a1,a2,a3,a4,a5,a6);
 
544
 
 
545
                    // if this signal gets deleted by the slot, the Sentry
 
546
                    // will be detached. In this case we bail out immediately
 
547
                    if( !sentry )
 
548
                        return;
 
549
                }
 
550
            }
 
551
 
 
552
            /** Same as send(...). */
 
553
            inline void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
 
554
            { this->send(a1,a2,a3,a4,a5,a6); }
 
555
    };
 
556
 
 
557
// END_Signal 6
 
558
// BEGIN_SignalSlot 6
 
559
 
 
560
    //! Connects a Signal to a function.
 
561
    template <typename R,class A1, class A2, class A3, class A4, class A5, class A6>
 
562
    Connection connect(Signal<A1,A2,A3,A4,A5,A6>& signal, R(*func)(A1,A2,A3,A4,A5,A6))
 
563
    {
 
564
        return connect( signal, slot(func) );
 
565
    }
 
566
 
 
567
    //! Connects a Signal to a member function.
 
568
    template <typename R, class BaseT, class ClassT,class A1, class A2, class A3, class A4, class A5, class A6>
 
569
    Connection connect(Signal<A1,A2,A3,A4,A5,A6>& signal, BaseT& object, R(ClassT::*memFunc)(A1,A2,A3,A4,A5,A6))
 
570
    {
 
571
        return connect( signal, slot(object, memFunc) );
 
572
    }
 
573
 
 
574
    //! Connects a Signal to a const member function.
 
575
    template <typename R, class ClassT,class A1, class A2, class A3, class A4, class A5, class A6>
 
576
    Connection connect(Signal<A1,A2,A3,A4,A5,A6>& signal, ClassT& object, R(ClassT::*memFunc)(A1,A2,A3,A4,A5,A6) const)
 
577
    {
 
578
        return connect( signal, slot(object, memFunc) );
 
579
    }
 
580
 
 
581
    /** Connects a Signal to another Signal. */
 
582
    template <class A1, class A2, class A3, class A4, class A5, class A6>
 
583
    Connection connect(Signal<A1,A2,A3,A4,A5,A6>& sender, Signal<A1,A2,A3,A4,A5,A6>& receiver)
 
584
    {
 
585
        return connect( sender, slot(receiver) );
 
586
    }
 
587
// END_SignalSlot 6
 
588
// BEGIN_Signal 5
 
589
    // specialization
 
590
    template <class A1, class A2, class A3, class A4, class A5>
 
591
    class Signal<A1,A2,A3,A4,A5,Void,Void,Void,Void,Void> : public SignalBase {
 
592
        public:
 
593
            typedef Invokable<A1,A2,A3,A4,A5,Void,Void,Void,Void,Void> _Invokable;
 
594
 
 
595
        public:
 
596
            /** Does nothing. */
 
597
            Signal()
 
598
            { }
 
599
 
 
600
            /** Deeply copies rhs. */
 
601
            Signal(const Signal& rhs)
 
602
            {
 
603
                Signal::operator=(rhs);
 
604
            }
 
605
 
 
606
            /**
 
607
            Connects slot to this signal, such that firing this signal
 
608
            will invoke slot.
 
609
            */
 
610
            template <typename R>
 
611
            Connection connect(const BasicSlot<R, A1,A2,A3,A4,A5,Void,Void,Void,Void,Void>& slot)
 
612
            {
 
613
                return Connection(*this, slot.clone() );
 
614
            }
 
615
 
 
616
            /**
 
617
            Invokes all slots connected to this signal, in an undefined
 
618
            order. Their return values are ignored. Calling of connected slots will
 
619
            be interrupted if a slot deletes this Signal object or throws an exception.
 
620
            */
 
621
            inline void send(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
 
622
            {
 
623
                // The sentry will set the Signal to the sending state and
 
624
                // reset it to not-sending upon destruction. In the sending
 
625
                // state, removing connection will leave invalid connections
 
626
                // in the connection list to keep the iterator valid, but mark
 
627
                // the Signal dirty. If the Signal is dirty, all invalid
 
628
                // connections will be removed by the Sentry when it destructs..
 
629
                SignalBase::Sentry sentry(this);
 
630
 
 
631
                std::list<Connection>::const_iterator it = Connectable::connections().begin();
 
632
                std::list<Connection>::const_iterator end = Connectable::connections().end();
 
633
 
 
634
                for(; it != end; ++it)
 
635
                {
 
636
                    if( false == it->valid() || &( it->sender() ) != this  )
 
637
                        continue;
 
638
 
 
639
                    // The following scenarios must be considered when the
 
640
                    // slot is called:
 
641
                    // - The slot might get deleted and thus disconnected from
 
642
                    //   this signal
 
643
                    // - The slot might delete this signal and we must end
 
644
                    //   calling any slots immediately
 
645
                    // - A new Connection might get added to this Signal in
 
646
                    //   the slot
 
647
                    const _Invokable* invokable = static_cast<const _Invokable*>( it->slot().callable() );
 
648
                    invokable->invoke(a1,a2,a3,a4,a5);
 
649
 
 
650
                    // if this signal gets deleted by the slot, the Sentry
 
651
                    // will be detached. In this case we bail out immediately
 
652
                    if( !sentry )
 
653
                        return;
 
654
                }
 
655
            }
 
656
 
 
657
            /** Same as send(...). */
 
658
            inline void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
 
659
            { this->send(a1,a2,a3,a4,a5); }
 
660
    };
 
661
 
 
662
// END_Signal 5
 
663
// BEGIN_SignalSlot 5
 
664
 
 
665
    //! Connects a Signal to a function.
 
666
    template <typename R,class A1, class A2, class A3, class A4, class A5>
 
667
    Connection connect(Signal<A1,A2,A3,A4,A5>& signal, R(*func)(A1,A2,A3,A4,A5))
 
668
    {
 
669
        return connect( signal, slot(func) );
 
670
    }
 
671
 
 
672
    //! Connects a Signal to a member function.
 
673
    template <typename R, class BaseT, class ClassT,class A1, class A2, class A3, class A4, class A5>
 
674
    Connection connect(Signal<A1,A2,A3,A4,A5>& signal, BaseT& object, R(ClassT::*memFunc)(A1,A2,A3,A4,A5))
 
675
    {
 
676
        return connect( signal, slot(object, memFunc) );
 
677
    }
 
678
 
 
679
    //! Connects a Signal to a const member function.
 
680
    template <typename R, class ClassT,class A1, class A2, class A3, class A4, class A5>
 
681
    Connection connect(Signal<A1,A2,A3,A4,A5>& signal, ClassT& object, R(ClassT::*memFunc)(A1,A2,A3,A4,A5) const)
 
682
    {
 
683
        return connect( signal, slot(object, memFunc) );
 
684
    }
 
685
 
 
686
    /** Connects a Signal to another Signal. */
 
687
    template <class A1, class A2, class A3, class A4, class A5>
 
688
    Connection connect(Signal<A1,A2,A3,A4,A5>& sender, Signal<A1,A2,A3,A4,A5>& receiver)
 
689
    {
 
690
        return connect( sender, slot(receiver) );
 
691
    }
 
692
// END_SignalSlot 5
 
693
// BEGIN_Signal 4
 
694
    // specialization
 
695
    template <class A1, class A2, class A3, class A4>
 
696
    class Signal<A1,A2,A3,A4,Void,Void,Void,Void,Void,Void> : public SignalBase {
 
697
        public:
 
698
            typedef Invokable<A1,A2,A3,A4,Void,Void,Void,Void,Void,Void> _Invokable;
 
699
 
 
700
        public:
 
701
            /** Does nothing. */
 
702
            Signal()
 
703
            { }
 
704
 
 
705
            /** Deeply copies rhs. */
 
706
            Signal(const Signal& rhs)
 
707
            {
 
708
                Signal::operator=(rhs);
 
709
            }
 
710
 
 
711
            /**
 
712
            Connects slot to this signal, such that firing this signal
 
713
            will invoke slot.
 
714
            */
 
715
            template <typename R>
 
716
            Connection connect(const BasicSlot<R, A1,A2,A3,A4,Void,Void,Void,Void,Void,Void>& slot)
 
717
            {
 
718
                return Connection(*this, slot.clone() );
 
719
            }
 
720
 
 
721
            /**
 
722
            Invokes all slots connected to this signal, in an undefined
 
723
            order. Their return values are ignored. Calling of connected slots will
 
724
            be interrupted if a slot deletes this Signal object or throws an exception.
 
725
            */
 
726
            inline void send(A1 a1, A2 a2, A3 a3, A4 a4) const
 
727
            {
 
728
                // The sentry will set the Signal to the sending state and
 
729
                // reset it to not-sending upon destruction. In the sending
 
730
                // state, removing connection will leave invalid connections
 
731
                // in the connection list to keep the iterator valid, but mark
 
732
                // the Signal dirty. If the Signal is dirty, all invalid
 
733
                // connections will be removed by the Sentry when it destructs..
 
734
                SignalBase::Sentry sentry(this);
 
735
 
 
736
                std::list<Connection>::const_iterator it = Connectable::connections().begin();
 
737
                std::list<Connection>::const_iterator end = Connectable::connections().end();
 
738
 
 
739
                for(; it != end; ++it)
 
740
                {
 
741
                    if( false == it->valid() || &( it->sender() ) != this  )
 
742
                        continue;
 
743
 
 
744
                    // The following scenarios must be considered when the
 
745
                    // slot is called:
 
746
                    // - The slot might get deleted and thus disconnected from
 
747
                    //   this signal
 
748
                    // - The slot might delete this signal and we must end
 
749
                    //   calling any slots immediately
 
750
                    // - A new Connection might get added to this Signal in
 
751
                    //   the slot
 
752
                    const _Invokable* invokable = static_cast<const _Invokable*>( it->slot().callable() );
 
753
                    invokable->invoke(a1,a2,a3,a4);
 
754
 
 
755
                    // if this signal gets deleted by the slot, the Sentry
 
756
                    // will be detached. In this case we bail out immediately
 
757
                    if( !sentry )
 
758
                        return;
 
759
                }
 
760
            }
 
761
 
 
762
            /** Same as send(...). */
 
763
            inline void operator()(A1 a1, A2 a2, A3 a3, A4 a4) const
 
764
            { this->send(a1,a2,a3,a4); }
 
765
    };
 
766
 
 
767
// END_Signal 4
 
768
// BEGIN_SignalSlot 4
 
769
 
 
770
    //! Connects a Signal to a function.
 
771
    template <typename R,class A1, class A2, class A3, class A4>
 
772
    Connection connect(Signal<A1,A2,A3,A4>& signal, R(*func)(A1,A2,A3,A4))
 
773
    {
 
774
        return connect( signal, slot(func) );
 
775
    }
 
776
 
 
777
    //! Connects a Signal to a member function.
 
778
    template <typename R, class BaseT, class ClassT,class A1, class A2, class A3, class A4>
 
779
    Connection connect(Signal<A1,A2,A3,A4>& signal, BaseT& object, R(ClassT::*memFunc)(A1,A2,A3,A4))
 
780
    {
 
781
        return connect( signal, slot(object, memFunc) );
 
782
    }
 
783
 
 
784
    //! Connects a Signal to a const member function.
 
785
    template <typename R, class ClassT,class A1, class A2, class A3, class A4>
 
786
    Connection connect(Signal<A1,A2,A3,A4>& signal, ClassT& object, R(ClassT::*memFunc)(A1,A2,A3,A4) const)
 
787
    {
 
788
        return connect( signal, slot(object, memFunc) );
 
789
    }
 
790
 
 
791
    /** Connects a Signal to another Signal. */
 
792
    template <class A1, class A2, class A3, class A4>
 
793
    Connection connect(Signal<A1,A2,A3,A4>& sender, Signal<A1,A2,A3,A4>& receiver)
 
794
    {
 
795
        return connect( sender, slot(receiver) );
 
796
    }
 
797
// END_SignalSlot 4
 
798
// BEGIN_Signal 3
 
799
    // specialization
 
800
    template <class A1, class A2, class A3>
 
801
    class Signal<A1,A2,A3,Void,Void,Void,Void,Void,Void,Void> : public SignalBase {
 
802
        public:
 
803
            typedef Invokable<A1,A2,A3,Void,Void,Void,Void,Void,Void,Void> _Invokable;
 
804
 
 
805
        public:
 
806
            /** Does nothing. */
 
807
            Signal()
 
808
            { }
 
809
 
 
810
            /** Deeply copies rhs. */
 
811
            Signal(const Signal& rhs)
 
812
            {
 
813
                Signal::operator=(rhs);
 
814
            }
 
815
 
 
816
            /**
 
817
            Connects slot to this signal, such that firing this signal
 
818
            will invoke slot.
 
819
            */
 
820
            template <typename R>
 
821
            Connection connect(const BasicSlot<R, A1,A2,A3,Void,Void,Void,Void,Void,Void,Void>& slot)
 
822
            {
 
823
                return Connection(*this, slot.clone() );
 
824
            }
 
825
 
 
826
            /**
 
827
            Invokes all slots connected to this signal, in an undefined
 
828
            order. Their return values are ignored. Calling of connected slots will
 
829
            be interrupted if a slot deletes this Signal object or throws an exception.
 
830
            */
 
831
            inline void send(A1 a1, A2 a2, A3 a3) const
 
832
            {
 
833
                // The sentry will set the Signal to the sending state and
 
834
                // reset it to not-sending upon destruction. In the sending
 
835
                // state, removing connection will leave invalid connections
 
836
                // in the connection list to keep the iterator valid, but mark
 
837
                // the Signal dirty. If the Signal is dirty, all invalid
 
838
                // connections will be removed by the Sentry when it destructs..
 
839
                SignalBase::Sentry sentry(this);
 
840
 
 
841
                std::list<Connection>::const_iterator it = Connectable::connections().begin();
 
842
                std::list<Connection>::const_iterator end = Connectable::connections().end();
 
843
 
 
844
                for(; it != end; ++it)
 
845
                {
 
846
                    if( false == it->valid() || &( it->sender() ) != this  )
 
847
                        continue;
 
848
 
 
849
                    // The following scenarios must be considered when the
 
850
                    // slot is called:
 
851
                    // - The slot might get deleted and thus disconnected from
 
852
                    //   this signal
 
853
                    // - The slot might delete this signal and we must end
 
854
                    //   calling any slots immediately
 
855
                    // - A new Connection might get added to this Signal in
 
856
                    //   the slot
 
857
                    const _Invokable* invokable = static_cast<const _Invokable*>( it->slot().callable() );
 
858
                    invokable->invoke(a1,a2,a3);
 
859
 
 
860
                    // if this signal gets deleted by the slot, the Sentry
 
861
                    // will be detached. In this case we bail out immediately
 
862
                    if( !sentry )
 
863
                        return;
 
864
                }
 
865
            }
 
866
 
 
867
            /** Same as send(...). */
 
868
            inline void operator()(A1 a1, A2 a2, A3 a3) const
 
869
            { this->send(a1,a2,a3); }
 
870
    };
 
871
 
 
872
// END_Signal 3
 
873
// BEGIN_SignalSlot 3
 
874
 
 
875
    //! Connects a Signal to a function.
 
876
    template <typename R,class A1, class A2, class A3>
 
877
    Connection connect(Signal<A1,A2,A3>& signal, R(*func)(A1,A2,A3))
 
878
    {
 
879
        return connect( signal, slot(func) );
 
880
    }
 
881
 
 
882
    //! Connects a Signal to a member function.
 
883
    template <typename R, class BaseT, class ClassT,class A1, class A2, class A3>
 
884
    Connection connect(Signal<A1,A2,A3>& signal, BaseT& object, R(ClassT::*memFunc)(A1,A2,A3))
 
885
    {
 
886
        return connect( signal, slot(object, memFunc) );
 
887
    }
 
888
 
 
889
    //! Connects a Signal to a const member function.
 
890
    template <typename R, class ClassT,class A1, class A2, class A3>
 
891
    Connection connect(Signal<A1,A2,A3>& signal, ClassT& object, R(ClassT::*memFunc)(A1,A2,A3) const)
 
892
    {
 
893
        return connect( signal, slot(object, memFunc) );
 
894
    }
 
895
 
 
896
    /** Connects a Signal to another Signal. */
 
897
    template <class A1, class A2, class A3>
 
898
    Connection connect(Signal<A1,A2,A3>& sender, Signal<A1,A2,A3>& receiver)
 
899
    {
 
900
        return connect( sender, slot(receiver) );
 
901
    }
 
902
// END_SignalSlot 3
 
903
// BEGIN_Signal 2
 
904
    // specialization
 
905
    template <class A1, class A2>
 
906
    class Signal<A1,A2,Void,Void,Void,Void,Void,Void,Void,Void> : public SignalBase {
 
907
        public:
 
908
            typedef Invokable<A1,A2,Void,Void,Void,Void,Void,Void,Void,Void> _Invokable;
 
909
 
 
910
        public:
 
911
            /** Does nothing. */
 
912
            Signal()
 
913
            { }
 
914
 
 
915
            /** Deeply copies rhs. */
 
916
            Signal(const Signal& rhs)
 
917
            {
 
918
                Signal::operator=(rhs);
 
919
            }
 
920
 
 
921
            /**
 
922
            Connects slot to this signal, such that firing this signal
 
923
            will invoke slot.
 
924
            */
 
925
            template <typename R>
 
926
            Connection connect(const BasicSlot<R, A1,A2,Void,Void,Void,Void,Void,Void,Void,Void>& slot)
 
927
            {
 
928
                return Connection(*this, slot.clone() );
 
929
            }
 
930
 
 
931
            /**
 
932
            Invokes all slots connected to this signal, in an undefined
 
933
            order. Their return values are ignored. Calling of connected slots will
 
934
            be interrupted if a slot deletes this Signal object or throws an exception.
 
935
            */
 
936
            inline void send(A1 a1, A2 a2) const
 
937
            {
 
938
                // The sentry will set the Signal to the sending state and
 
939
                // reset it to not-sending upon destruction. In the sending
 
940
                // state, removing connection will leave invalid connections
 
941
                // in the connection list to keep the iterator valid, but mark
 
942
                // the Signal dirty. If the Signal is dirty, all invalid
 
943
                // connections will be removed by the Sentry when it destructs..
 
944
                SignalBase::Sentry sentry(this);
 
945
 
 
946
                std::list<Connection>::const_iterator it = Connectable::connections().begin();
 
947
                std::list<Connection>::const_iterator end = Connectable::connections().end();
 
948
 
 
949
                for(; it != end; ++it)
 
950
                {
 
951
                    if( false == it->valid() || &( it->sender() ) != this  )
 
952
                        continue;
 
953
 
 
954
                    // The following scenarios must be considered when the
 
955
                    // slot is called:
 
956
                    // - The slot might get deleted and thus disconnected from
 
957
                    //   this signal
 
958
                    // - The slot might delete this signal and we must end
 
959
                    //   calling any slots immediately
 
960
                    // - A new Connection might get added to this Signal in
 
961
                    //   the slot
 
962
                    const _Invokable* invokable = static_cast<const _Invokable*>( it->slot().callable() );
 
963
                    invokable->invoke(a1,a2);
 
964
 
 
965
                    // if this signal gets deleted by the slot, the Sentry
 
966
                    // will be detached. In this case we bail out immediately
 
967
                    if( !sentry )
 
968
                        return;
 
969
                }
 
970
            }
 
971
 
 
972
            /** Same as send(...). */
 
973
            inline void operator()(A1 a1, A2 a2) const
 
974
            { this->send(a1,a2); }
 
975
    };
 
976
 
 
977
// END_Signal 2
 
978
// BEGIN_SignalSlot 2
 
979
 
 
980
    //! Connects a Signal to a function.
 
981
    template <typename R,class A1, class A2>
 
982
    Connection connect(Signal<A1,A2>& signal, R(*func)(A1,A2))
 
983
    {
 
984
        return connect( signal, slot(func) );
 
985
    }
 
986
 
 
987
    //! Connects a Signal to a member function.
 
988
    template <typename R, class BaseT, class ClassT,class A1, class A2>
 
989
    Connection connect(Signal<A1,A2>& signal, BaseT& object, R(ClassT::*memFunc)(A1,A2))
 
990
    {
 
991
        return connect( signal, slot(object, memFunc) );
 
992
    }
 
993
 
 
994
    //! Connects a Signal to a const member function.
 
995
    template <typename R, class ClassT,class A1, class A2>
 
996
    Connection connect(Signal<A1,A2>& signal, ClassT& object, R(ClassT::*memFunc)(A1,A2) const)
 
997
    {
 
998
        return connect( signal, slot(object, memFunc) );
 
999
    }
 
1000
 
 
1001
    /** Connects a Signal to another Signal. */
 
1002
    template <class A1, class A2>
 
1003
    Connection connect(Signal<A1,A2>& sender, Signal<A1,A2>& receiver)
 
1004
    {
 
1005
        return connect( sender, slot(receiver) );
 
1006
    }
 
1007
// END_SignalSlot 2
 
1008
// BEGIN_Signal 1
 
1009
    // specialization
 
1010
    template <class A1>
 
1011
    class Signal<A1,Void,Void,Void,Void,Void,Void,Void,Void,Void> : public SignalBase {
 
1012
        public:
 
1013
            typedef Invokable<A1,Void,Void,Void,Void,Void,Void,Void,Void,Void> _Invokable;
 
1014
 
 
1015
        public:
 
1016
            /** Does nothing. */
 
1017
            Signal()
 
1018
            { }
 
1019
 
 
1020
            /** Deeply copies rhs. */
 
1021
            Signal(const Signal& rhs)
 
1022
            {
 
1023
                Signal::operator=(rhs);
 
1024
            }
 
1025
 
 
1026
            /**
 
1027
            Connects slot to this signal, such that firing this signal
 
1028
            will invoke slot.
 
1029
            */
 
1030
            template <typename R>
 
1031
            Connection connect(const BasicSlot<R, A1,Void,Void,Void,Void,Void,Void,Void,Void,Void>& slot)
 
1032
            {
 
1033
                return Connection(*this, slot.clone() );
 
1034
            }
 
1035
 
 
1036
            /**
 
1037
            Invokes all slots connected to this signal, in an undefined
 
1038
            order. Their return values are ignored. Calling of connected slots will
 
1039
            be interrupted if a slot deletes this Signal object or throws an exception.
 
1040
            */
 
1041
            inline void send(A1 a1) const
 
1042
            {
 
1043
                // The sentry will set the Signal to the sending state and
 
1044
                // reset it to not-sending upon destruction. In the sending
 
1045
                // state, removing connection will leave invalid connections
 
1046
                // in the connection list to keep the iterator valid, but mark
 
1047
                // the Signal dirty. If the Signal is dirty, all invalid
 
1048
                // connections will be removed by the Sentry when it destructs..
 
1049
                SignalBase::Sentry sentry(this);
 
1050
 
 
1051
                std::list<Connection>::const_iterator it = Connectable::connections().begin();
 
1052
                std::list<Connection>::const_iterator end = Connectable::connections().end();
 
1053
 
 
1054
                for(; it != end; ++it)
 
1055
                {
 
1056
                    if( false == it->valid() || &( it->sender() ) != this  )
 
1057
                        continue;
 
1058
 
 
1059
                    // The following scenarios must be considered when the
 
1060
                    // slot is called:
 
1061
                    // - The slot might get deleted and thus disconnected from
 
1062
                    //   this signal
 
1063
                    // - The slot might delete this signal and we must end
 
1064
                    //   calling any slots immediately
 
1065
                    // - A new Connection might get added to this Signal in
 
1066
                    //   the slot
 
1067
                    const _Invokable* invokable = static_cast<const _Invokable*>( it->slot().callable() );
 
1068
                    invokable->invoke(a1);
 
1069
 
 
1070
                    // if this signal gets deleted by the slot, the Sentry
 
1071
                    // will be detached. In this case we bail out immediately
 
1072
                    if( !sentry )
 
1073
                        return;
 
1074
                }
 
1075
            }
 
1076
 
 
1077
            /** Same as send(...). */
 
1078
            inline void operator()(A1 a1) const
 
1079
            { this->send(a1); }
 
1080
    };
 
1081
 
 
1082
// END_Signal 1
 
1083
// BEGIN_SignalSlot 1
 
1084
 
 
1085
    //! Connects a Signal to a function.
 
1086
    template <typename R,class A1>
 
1087
    Connection connect(Signal<A1>& signal, R(*func)(A1))
 
1088
    {
 
1089
        return connect( signal, slot(func) );
 
1090
    }
 
1091
 
 
1092
    //! Connects a Signal to a member function.
 
1093
    template <typename R, class BaseT, class ClassT,class A1>
 
1094
    Connection connect(Signal<A1>& signal, BaseT& object, R(ClassT::*memFunc)(A1))
 
1095
    {
 
1096
        return connect( signal, slot(object, memFunc) );
 
1097
    }
 
1098
 
 
1099
    //! Connects a Signal to a const member function.
 
1100
    template <typename R, class ClassT,class A1>
 
1101
    Connection connect(Signal<A1>& signal, ClassT& object, R(ClassT::*memFunc)(A1) const)
 
1102
    {
 
1103
        return connect( signal, slot(object, memFunc) );
 
1104
    }
 
1105
 
 
1106
    /** Connects a Signal to another Signal. */
 
1107
    template <class A1>
 
1108
    Connection connect(Signal<A1>& sender, Signal<A1>& receiver)
 
1109
    {
 
1110
        return connect( sender, slot(receiver) );
 
1111
    }
 
1112
// END_SignalSlot 1
 
1113
// BEGIN_Signal 0
 
1114
    // specialization
 
1115
    template <>
 
1116
    class Signal<Void,Void,Void,Void,Void,Void,Void,Void,Void,Void> : public SignalBase {
 
1117
        public:
 
1118
            typedef Invokable<Void,Void,Void,Void,Void,Void,Void,Void,Void,Void> _Invokable;
 
1119
 
 
1120
        public:
 
1121
            /** Does nothing. */
 
1122
            Signal()
 
1123
            { }
 
1124
 
 
1125
            /** Deeply copies rhs. */
 
1126
            Signal(const Signal& rhs)
 
1127
            {
 
1128
                Signal::operator=(rhs);
 
1129
            }
 
1130
 
 
1131
            /**
 
1132
            Connects slot to this signal, such that firing this signal
 
1133
            will invoke slot.
 
1134
            */
 
1135
            template <typename R>
 
1136
            Connection connect(const BasicSlot<R, Void,Void,Void,Void,Void,Void,Void,Void,Void,Void>& slot)
 
1137
            {
 
1138
                return Connection(*this, slot.clone() );
 
1139
            }
 
1140
 
 
1141
            /**
 
1142
            Invokes all slots connected to this signal, in an undefined
 
1143
            order. Their return values are ignored. Calling of connected slots will
 
1144
            be interrupted if a slot deletes this Signal object or throws an exception.
 
1145
            */
 
1146
            inline void send() const
 
1147
            {
 
1148
                // The sentry will set the Signal to the sending state and
 
1149
                // reset it to not-sending upon destruction. In the sending
 
1150
                // state, removing connection will leave invalid connections
 
1151
                // in the connection list to keep the iterator valid, but mark
 
1152
                // the Signal dirty. If the Signal is dirty, all invalid
 
1153
                // connections will be removed by the Sentry when it destructs..
 
1154
                SignalBase::Sentry sentry(this);
 
1155
 
 
1156
                std::list<Connection>::const_iterator it = Connectable::connections().begin();
 
1157
                std::list<Connection>::const_iterator end = Connectable::connections().end();
 
1158
 
 
1159
                for(; it != end; ++it)
 
1160
                {
 
1161
                    if( false == it->valid() || &( it->sender() ) != this  )
 
1162
                        continue;
 
1163
 
 
1164
                    // The following scenarios must be considered when the
 
1165
                    // slot is called:
 
1166
                    // - The slot might get deleted and thus disconnected from
 
1167
                    //   this signal
 
1168
                    // - The slot might delete this signal and we must end
 
1169
                    //   calling any slots immediately
 
1170
                    // - A new Connection might get added to this Signal in
 
1171
                    //   the slot
 
1172
                    const _Invokable* invokable = static_cast<const _Invokable*>( it->slot().callable() );
 
1173
                    invokable->invoke();
 
1174
 
 
1175
                    // if this signal gets deleted by the slot, the Sentry
 
1176
                    // will be detached. In this case we bail out immediately
 
1177
                    if( !sentry )
 
1178
                        return;
 
1179
                }
 
1180
            }
 
1181
 
 
1182
            /** Same as send(...). */
 
1183
            inline void operator()() const
 
1184
            { this->send(); }
 
1185
    };
 
1186
 
 
1187
// END_Signal 0
 
1188
// BEGIN_SignalSlot 0
 
1189
 
 
1190
    //! Connects a Signal to a function.
 
1191
    template <typename R>
 
1192
    Connection connect(Signal<>& signal, R(*func)())
 
1193
    {
 
1194
        return connect( signal, slot(func) );
 
1195
    }
 
1196
 
 
1197
    //! Connects a Signal to a member function.
 
1198
    template <typename R, class BaseT, class ClassT>
 
1199
    Connection connect(Signal<>& signal, BaseT& object, R(ClassT::*memFunc)())
 
1200
    {
 
1201
        return connect( signal, slot(object, memFunc) );
 
1202
    }
 
1203
 
 
1204
    //! Connects a Signal to a const member function.
 
1205
    template <typename R, class ClassT>
 
1206
    Connection connect(Signal<>& signal, ClassT& object, R(ClassT::*memFunc)() const)
 
1207
    {
 
1208
        return connect( signal, slot(object, memFunc) );
 
1209
    }
 
1210
 
 
1211
    /** Connects a Signal to another Signal. */
 
1212
    inline Connection connect(Signal<>& sender, Signal<>& receiver)
 
1213
    {
 
1214
        return connect( sender, slot(receiver) );
 
1215
    }
 
1216
// END_SignalSlot 0