The expiration time for new job artifacts in CI/CD pipelines is now 30 days (GitLab default). Previously generated artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

sigslot.h 81.3 KB
Newer Older
schultezub's avatar
schultezub committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*
 
 sigslot.h: Signal/Slot classes
 
 Written by Sarah Thompson (sarah@telergy.com) 2002.
 
 License: Public domain. You are free to use this code however you like,
          with the proviso that the author takes on no responsibility or
          liability for any use.
 
 QUICK DOCUMENTATION
 
 (see also the full documentation at http://sigslot.sourceforge.net/)
 
 1. #define switches

    SIGSLOT_PURE_ISO:
    Define this to force ISO C++ compliance. This also disables
    all of the thread safety support on platforms where it is 
    available.
 
    SIGSLOT_USE_POSIX_THREADS:
    Force use of Posix threads when using a C++ compiler other than
    gcc on a platform that supports Posix threads. (When using gcc,
    this is the default - use SIGSLOT_PURE_ISO to disable this if 
    necessary)
 
    SIGSLOT_DEFAULT_MT_POLICY:
    Where thread support is enabled, this defaults to multi_threaded_global.
    Otherwise, the default is single_threaded. #define this yourself to
    override the default. In pure ISO mode, anything other than
    single_threaded will cause a compiler error.

 2. PLATFORM NOTES
 
    Win32:
    On Win32, the WIN32 symbol must be #defined. Most mainstream
    compilers do this by default, but you may need to define it
    yourself if your build environment is less standard. This causes
    the Win32 thread support to be compiled in and used automatically.
 
    Unix/Linux/BSD, etc:
    If you're using gcc, it is assumed that you have Posix threads
    available, so they are used automatically. You can override this
    (as under Windows) with the SIGSLOT_PURE_ISO switch. If you're using
    something other than gcc but still want to use Posix threads, you
    need to #define SIGSLOT_USE_POSIX_THREADS.
 
    ISO C++:
    If none of the supported platforms are detected, or if
    SIGSLOT_PURE_ISO is defined, all multithreading support is turned off,
    along with any code that might cause a pure ISO C++ environment to
    complain. Before you ask, gcc -ansi -pedantic won't compile this 
    library, but gcc -ansi is fine. Pedantic mode seems to throw a lot of
    errors that aren't really there. If you feel like investigating this,
    please contact the author.
      
 THREADING MODES
 
    single_threaded:
    Your program is assumed to be single threaded from the point of view
    of signal/slot usage (i.e. all objects using signals and slots are
    created and destroyed from a single thread). Behaviour if objects are
    destroyed concurrently is undefined (i.e. you'll get the occasional
    segmentation fault/memory exception).
 
    multi_threaded_global:
    Your program is assumed to be multi threaded. Objects using signals and
    slots can be safely created and destroyed from any thread, even when
    connections exist. In multi_threaded_global mode, this is achieved by a
    single global mutex (actually a critical section on Windows because they
    are faster). This option uses less OS resources, but results in more
    opportunities for contention, possibly resulting in more context switches
    than are strictly necessary.
 
    multi_threaded_local:
    Behaviour in this mode is essentially the same as multi_threaded_global,
    except that each signal, and each object that inherits has_slots, all 
    have their own mutex/critical section. In practice, this means that
    mutex collisions (and hence context switches) only happen if they are
    absolutely essential. However, on some platforms, creating a lot of 
    mutexes can slow down the whole OS, so use this option with care.
 
 USING THE LIBRARY
 
 See the full documentation at http://sigslot.sourceforge.net/
 
*/
schultezub's avatar
schultezub committed
89

schultezub's avatar
schultezub committed
90
91
#ifndef SIGSLOT_H
#define SIGSLOT_H
schultezub's avatar
schultezub committed
92
93
94

#include <set>
#include <list>
95
#include <tbb/spin_rw_mutex.h>
schultezub's avatar
schultezub committed
96
97
98
99
100
101
102
103
104
105
106

#ifndef SIGSLOT_DEFAULT_MT_POLICY
#	ifdef _SIGSLOT_SINGLE_THREADED
#		define SIGSLOT_DEFAULT_MT_POLICY single_threaded
#	else
#		define SIGSLOT_DEFAULT_MT_POLICY multi_threaded_local
#	endif
#endif

namespace sigslot {

107
    typedef tbb::spin_rw_mutex tbb_mutex;
schultezub's avatar
schultezub committed
108
109
110
111
112
113
114

    // The multi threading policies only get compiled in if they are enabled.
    class multi_threaded_global
    {
    public:
        multi_threaded_global()
        {
115
            ;
schultezub's avatar
schultezub committed
116
117
118
119
120
121
122
123
124
125
126
127
        }

        multi_threaded_global(const multi_threaded_global&)
        {
            ;
        }

        virtual ~multi_threaded_global()
        {
            ;
        }

128
        tbb_mutex& get_mutex()
schultezub's avatar
schultezub committed
129
        {
130
131
            static tbb_mutex g_mutex;
            return g_mutex;
schultezub's avatar
schultezub committed
132
133
134
135
136
137
138
139
        }
    };

    class multi_threaded_local
    {
    public:
        multi_threaded_local()
        {
140
            ;
schultezub's avatar
schultezub committed
141
142
143
144
145
146
147
        }

        multi_threaded_local(const multi_threaded_local&)
        {
            ;
        }

148
        virtual ~multi_threaded_local()
schultezub's avatar
schultezub committed
149
150
151
152
        {
            ;
        }

153
        tbb_mutex& get_mutex() { return m_mutex; }
schultezub's avatar
schultezub committed
154
155

    private:
156
        tbb_mutex m_mutex;
schultezub's avatar
schultezub committed
157
    };
158
159
160
    
    template<class mt_policy>
    class lock_block_write : tbb_mutex::scoped_lock
schultezub's avatar
schultezub committed
161
162
    {
    public:
163
        lock_block_write(mt_policy *mtx) : tbb_mutex::scoped_lock(mtx->get_mutex(), true)
schultezub's avatar
schultezub committed
164
165
        {
        }
166
167
        
        ~lock_block_write()
schultezub's avatar
schultezub committed
168
169
170
171
        {
        }
    };

172
173
    template<class mt_policy>
    class lock_block_read : tbb_mutex::scoped_lock
schultezub's avatar
schultezub committed
174
175
    {
    public:
176
        lock_block_read(mt_policy *mtx) : tbb_mutex::scoped_lock(mtx->get_mutex(), false)
schultezub's avatar
schultezub committed
177
178
179
        {
        }

180
        ~lock_block_read()
schultezub's avatar
schultezub committed
181
182
183
184
185
186
        {
        }
    };

    template<class mt_policy>
    class has_slots;
schultezub's avatar
schultezub committed
187
    
schultezub's avatar
schultezub committed
188
189
190
191
    template<class mt_policy>
    class _connection_base0
    {
    public:
schultezub's avatar
schultezub committed
192
        virtual ~_connection_base0() {}
schultezub's avatar
schultezub committed
193
194
195
196
197
        virtual has_slots<mt_policy>* getdest() const = 0;
        virtual void emitSignal() = 0;
        virtual _connection_base0* clone() = 0;
        virtual _connection_base0* duplicate(has_slots<mt_policy>* pnewdest) = 0;
    };
schultezub's avatar
schultezub committed
198
    
schultezub's avatar
schultezub committed
199
200
201
202
    template<class arg1_type, class mt_policy>
    class _connection_base1
    {
    public:
schultezub's avatar
schultezub committed
203
        virtual ~_connection_base1() {}
schultezub's avatar
schultezub committed
204
205
206
207
208
        virtual has_slots<mt_policy>* getdest() const = 0;
        virtual void emitSignal(arg1_type) = 0;
        virtual _connection_base1<arg1_type, mt_policy>* clone() = 0;
        virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
    };
schultezub's avatar
schultezub committed
209
    
schultezub's avatar
schultezub committed
210
211
212
213
    template<class arg1_type, class arg2_type, class mt_policy>
    class _connection_base2
    {
    public:
schultezub's avatar
schultezub committed
214
        virtual ~_connection_base2() {}
schultezub's avatar
schultezub committed
215
216
217
218
219
        virtual has_slots<mt_policy>* getdest() const = 0;
        virtual void emitSignal(arg1_type, arg2_type) = 0;
        virtual _connection_base2<arg1_type, arg2_type, mt_policy>* clone() = 0;
        virtual _connection_base2<arg1_type, arg2_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
    };
schultezub's avatar
schultezub committed
220
    
schultezub's avatar
schultezub committed
221
222
223
224
    template<class arg1_type, class arg2_type, class arg3_type, class mt_policy>
    class _connection_base3
    {
    public:
schultezub's avatar
schultezub committed
225
        virtual ~_connection_base3() {}
schultezub's avatar
schultezub committed
226
227
228
229
230
        virtual has_slots<mt_policy>* getdest() const = 0;
        virtual void emitSignal(arg1_type, arg2_type, arg3_type) = 0;
        virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* clone() = 0;
        virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
    };
schultezub's avatar
schultezub committed
231
    
schultezub's avatar
schultezub committed
232
233
234
235
    template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, class mt_policy>
    class _connection_base4
    {
    public:
schultezub's avatar
schultezub committed
236
        virtual ~_connection_base4() {}
schultezub's avatar
schultezub committed
237
238
239
240
241
        virtual has_slots<mt_policy>* getdest() const = 0;
        virtual void emitSignal(arg1_type, arg2_type, arg3_type, arg4_type) = 0;
        virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* clone() = 0;
        virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
    };
schultezub's avatar
schultezub committed
242
    
schultezub's avatar
schultezub committed
243
244
245
246
247
    template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
    class arg5_type, class mt_policy>
    class _connection_base5
    {
    public:
schultezub's avatar
schultezub committed
248
        virtual ~_connection_base5() {}
schultezub's avatar
schultezub committed
249
250
        virtual has_slots<mt_policy>* getdest() const = 0;
        virtual void emitSignal(arg1_type, arg2_type, arg3_type, arg4_type, 
schultezub's avatar
schultezub committed
251
                          arg5_type) = 0;
schultezub's avatar
schultezub committed
252
        virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
253
        arg5_type, mt_policy>* clone() = 0;
schultezub's avatar
schultezub committed
254
        virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
255
        arg5_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
schultezub's avatar
schultezub committed
256
    };
schultezub's avatar
schultezub committed
257
    
schultezub's avatar
schultezub committed
258
259
260
261
262
    template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
    class arg5_type, class arg6_type, class mt_policy>
    class _connection_base6
    {
    public:
schultezub's avatar
schultezub committed
263
        virtual ~_connection_base6() {}
schultezub's avatar
schultezub committed
264
265
        virtual has_slots<mt_policy>* getdest() const = 0;
        virtual void emitSignal(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type,
schultezub's avatar
schultezub committed
266
                          arg6_type) = 0;
schultezub's avatar
schultezub committed
267
        virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
268
        arg5_type, arg6_type, mt_policy>* clone() = 0;
schultezub's avatar
schultezub committed
269
        virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
270
        arg5_type, arg6_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
schultezub's avatar
schultezub committed
271
    };
schultezub's avatar
schultezub committed
272
    
schultezub's avatar
schultezub committed
273
274
275
276
277
    template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
    class arg5_type, class arg6_type, class arg7_type, class mt_policy>
    class _connection_base7
    {
    public:
schultezub's avatar
schultezub committed
278
        virtual ~_connection_base7() {}
schultezub's avatar
schultezub committed
279
280
        virtual has_slots<mt_policy>* getdest() const = 0;
        virtual void emitSignal(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type,
schultezub's avatar
schultezub committed
281
                          arg6_type, arg7_type) = 0;
schultezub's avatar
schultezub committed
282
        virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
283
        arg5_type, arg6_type, arg7_type, mt_policy>* clone() = 0;
schultezub's avatar
schultezub committed
284
        virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
285
        arg5_type, arg6_type, arg7_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
schultezub's avatar
schultezub committed
286
    };
schultezub's avatar
schultezub committed
287
    
schultezub's avatar
schultezub committed
288
289
290
291
292
    template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
    class arg5_type, class arg6_type, class arg7_type, class arg8_type, class mt_policy>
    class _connection_base8
    {
    public:
schultezub's avatar
schultezub committed
293
        virtual ~_connection_base8() {}
schultezub's avatar
schultezub committed
294
295
        virtual has_slots<mt_policy>* getdest() const = 0;
        virtual void emitSignal(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type,
schultezub's avatar
schultezub committed
296
                          arg6_type, arg7_type, arg8_type) = 0;
schultezub's avatar
schultezub committed
297
        virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
298
        arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* clone() = 0;
schultezub's avatar
schultezub committed
299
        virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
300
        arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
schultezub's avatar
schultezub committed
301
    };
schultezub's avatar
schultezub committed
302
    
schultezub's avatar
schultezub committed
303
304
305
306
307
    template<class mt_policy>
    class _signal_base : public mt_policy
    {
    public:
        virtual void slot_disconnect(has_slots<mt_policy>* pslot) = 0;
schultezub's avatar
schultezub committed
308
        virtual void slot_duplicate(has_slots<mt_policy> const* poldslot, has_slots<mt_policy>* pnewslot) = 0;
schultezub's avatar
schultezub committed
309
    };
schultezub's avatar
schultezub committed
310
    
schultezub's avatar
schultezub committed
311
312
313
314
    template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
    class has_slots : public mt_policy 
    {
    private:
schultezub's avatar
schultezub committed
315
        typedef typename std::set<_signal_base<mt_policy> *> sender_set;
schultezub's avatar
schultezub committed
316
        typedef typename sender_set::const_iterator const_iterator;
schultezub's avatar
schultezub committed
317
        
schultezub's avatar
schultezub committed
318
    public:
schultezub's avatar
schultezub committed
319
320
321
        has_slots() {}
        
        has_slots(has_slots const& hs) : mt_policy(hs)
schultezub's avatar
schultezub committed
322
        {
323
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
324
325
            const_iterator it = hs.m_senders.begin();
            const_iterator itEnd = hs.m_senders.end();
schultezub's avatar
schultezub committed
326
327
            
            while (it != itEnd) {
schultezub's avatar
schultezub committed
328
329
330
331
332
                (*it)->slot_duplicate(&hs, this);
                m_senders.insert(*it);
                ++it;
            }
        } 
schultezub's avatar
schultezub committed
333
        
schultezub's avatar
schultezub committed
334
335
        void signal_connect(_signal_base<mt_policy>* sender)
        {
336
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
337
338
            m_senders.insert(sender);
        }
schultezub's avatar
schultezub committed
339
        
schultezub's avatar
schultezub committed
340
341
        void signal_disconnect(_signal_base<mt_policy>* sender)
        {
342
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
343
344
            m_senders.erase(sender);
        }
schultezub's avatar
schultezub committed
345
        
schultezub's avatar
schultezub committed
346
347
348
349
        virtual ~has_slots()
        {
            disconnect_all();
        }
schultezub's avatar
schultezub committed
350
        
schultezub's avatar
schultezub committed
351
352
        void disconnect_all()
        {
353
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
354
355
            const_iterator it = m_senders.begin();
            const_iterator itEnd = m_senders.end();
schultezub's avatar
schultezub committed
356
357
            
            while (it != itEnd) {
schultezub's avatar
schultezub committed
358
359
360
                (*it)->slot_disconnect(this);
                ++it;
            }
schultezub's avatar
schultezub committed
361
            
schultezub's avatar
schultezub committed
362
363
            m_senders.erase(m_senders.begin(), m_senders.end());
        }
schultezub's avatar
schultezub committed
364
        
schultezub's avatar
schultezub committed
365
366
367
    private:
        sender_set m_senders;
    };
schultezub's avatar
schultezub committed
368
    
schultezub's avatar
schultezub committed
369
370
371
372
373
    template<class mt_policy>
    class _signal_base0 : public _signal_base<mt_policy>
    {
    public:
        typedef std::list<_connection_base0<mt_policy> *>  connections_list;
schultezub's avatar
schultezub committed
374
375
376
377
        
        _signal_base0() {}
        
        _signal_base0(_signal_base0 const& s) : _signal_base<mt_policy>(s)
schultezub's avatar
schultezub committed
378
        {
379
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
380
381
382
383
            typename connections_list::const_iterator it = s.m_connected_slots.begin();
            typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
            
            while (it != itEnd) {
schultezub's avatar
schultezub committed
384
385
386
387
388
                (*it)->getdest()->signal_connect(this);
                m_connected_slots.push_back((*it)->clone());
                ++it;
            }
        }
schultezub's avatar
schultezub committed
389
        
schultezub's avatar
schultezub committed
390
391
392
393
        ~_signal_base0()
        {
            disconnect_all();
        }
schultezub's avatar
schultezub committed
394
        
schultezub's avatar
schultezub committed
395
396
        void disconnect_all()
        {
397
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
398
399
400
401
            typename connections_list::const_iterator it = m_connected_slots.begin();
            typename connections_list::const_iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
schultezub's avatar
schultezub committed
402
403
404
405
                (*it)->getdest()->signal_disconnect(this);
                delete *it;
                ++it;
            }
schultezub's avatar
schultezub committed
406
            
schultezub's avatar
schultezub committed
407
408
            m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
        }
schultezub's avatar
schultezub committed
409
        
schultezub's avatar
schultezub committed
410
411
        void disconnect(has_slots<mt_policy>* pclass)
        {
412
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
413
414
415
416
417
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                if ((*it)->getdest() == pclass) {
schultezub's avatar
schultezub committed
418
419
420
421
422
                    delete *it;
                    m_connected_slots.erase(it);
                    pclass->signal_disconnect(this);
                    return;
                }
schultezub's avatar
schultezub committed
423
                
schultezub's avatar
schultezub committed
424
425
426
                ++it;
            }
        }
schultezub's avatar
schultezub committed
427
        
schultezub's avatar
schultezub committed
428
429
        void slot_disconnect(has_slots<mt_policy>* pslot)
        {
430
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
431
432
433
434
435
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                typename connections_list::iterator itNext = it;
schultezub's avatar
schultezub committed
436
                ++itNext;
schultezub's avatar
schultezub committed
437
438
                
                if ((*it)->getdest() == pslot) {
schultezub's avatar
schultezub committed
439
                    m_connected_slots.erase(it);
schultezub's avatar
schultezub committed
440
                    //          delete *it;
schultezub's avatar
schultezub committed
441
                }
schultezub's avatar
schultezub committed
442
                
schultezub's avatar
schultezub committed
443
444
445
                it = itNext;
            }
        }
schultezub's avatar
schultezub committed
446
447
        
        void slot_duplicate(has_slots<mt_policy> const* oldtarget, has_slots<mt_policy>* newtarget)
schultezub's avatar
schultezub committed
448
        {
449
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
450
451
452
453
454
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                if ((*it)->getdest() == oldtarget) {
schultezub's avatar
schultezub committed
455
456
                    m_connected_slots.push_back((*it)->duplicate(newtarget));
                }
schultezub's avatar
schultezub committed
457
                
schultezub's avatar
schultezub committed
458
459
460
                ++it;
            }
        }
schultezub's avatar
schultezub committed
461
        
schultezub's avatar
schultezub committed
462
463
464
    protected:
        connections_list m_connected_slots;   
    };
schultezub's avatar
schultezub committed
465
    
schultezub's avatar
schultezub committed
466
467
468
469
470
    template<class arg1_type, class mt_policy>
    class _signal_base1 : public _signal_base<mt_policy>
    {
    public:
        typedef std::list<_connection_base1<arg1_type, mt_policy> *>  connections_list;
schultezub's avatar
schultezub committed
471
472
473
474
        
        _signal_base1() {}
        
        _signal_base1(_signal_base1<arg1_type, mt_policy> const& s) : _signal_base<mt_policy>(s)
schultezub's avatar
schultezub committed
475
        {
476
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
477
478
479
480
            typename connections_list::const_iterator it = s.m_connected_slots.begin();
            typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
            
            while (it != itEnd) {
schultezub's avatar
schultezub committed
481
482
483
484
485
                (*it)->getdest()->signal_connect(this);
                m_connected_slots.push_back((*it)->clone());
                ++it;
            }
        }
schultezub's avatar
schultezub committed
486
487
        
        void slot_duplicate(has_slots<mt_policy> const* oldtarget, has_slots<mt_policy>* newtarget)
schultezub's avatar
schultezub committed
488
        {
489
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
490
491
492
493
494
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                if ((*it)->getdest() == oldtarget) {
schultezub's avatar
schultezub committed
495
496
                    m_connected_slots.push_back((*it)->duplicate(newtarget));
                }
schultezub's avatar
schultezub committed
497
                
schultezub's avatar
schultezub committed
498
499
500
                ++it;
            }
        }
schultezub's avatar
schultezub committed
501
        
schultezub's avatar
schultezub committed
502
503
504
505
        ~_signal_base1()
        {
            disconnect_all();
        }
schultezub's avatar
schultezub committed
506
        
schultezub's avatar
schultezub committed
507
508
        void disconnect_all()
        {
509
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
510
511
512
513
            typename connections_list::const_iterator it = m_connected_slots.begin();
            typename connections_list::const_iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
schultezub's avatar
schultezub committed
514
515
516
517
                (*it)->getdest()->signal_disconnect(this);
                delete *it;
                ++it;
            }
schultezub's avatar
schultezub committed
518
            
schultezub's avatar
schultezub committed
519
520
            m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
        }
schultezub's avatar
schultezub committed
521
        
schultezub's avatar
schultezub committed
522
523
        void disconnect(has_slots<mt_policy>* pclass)
        {
524
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
525
526
527
528
529
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                if ((*it)->getdest() == pclass) {
schultezub's avatar
schultezub committed
530
531
532
533
534
                    delete *it;
                    m_connected_slots.erase(it);
                    pclass->signal_disconnect(this);
                    return;
                }
schultezub's avatar
schultezub committed
535
                
schultezub's avatar
schultezub committed
536
537
538
                ++it;
            }
        }
schultezub's avatar
schultezub committed
539
        
schultezub's avatar
schultezub committed
540
541
        void slot_disconnect(has_slots<mt_policy>* pslot)
        {
542
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
543
544
545
546
547
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                typename connections_list::iterator itNext = it;
schultezub's avatar
schultezub committed
548
                ++itNext;
schultezub's avatar
schultezub committed
549
550
                
                if ((*it)->getdest() == pslot) {
schultezub's avatar
schultezub committed
551
                    m_connected_slots.erase(it);
schultezub's avatar
schultezub committed
552
                    //          delete *it;
schultezub's avatar
schultezub committed
553
                }
schultezub's avatar
schultezub committed
554
                
schultezub's avatar
schultezub committed
555
556
557
                it = itNext;
            }
        }
schultezub's avatar
schultezub committed
558
559
        
        
schultezub's avatar
schultezub committed
560
561
562
    protected:
        connections_list m_connected_slots;   
    };
schultezub's avatar
schultezub committed
563
    
schultezub's avatar
schultezub committed
564
565
566
567
568
    template<class arg1_type, class arg2_type, class mt_policy>
    class _signal_base2 : public _signal_base<mt_policy>
    {
    public:
        typedef std::list<_connection_base2<arg1_type, arg2_type, mt_policy> *>
schultezub's avatar
schultezub committed
569
570
571
572
573
        connections_list;
        
        _signal_base2() {}
        
        _signal_base2(_signal_base2<arg1_type, arg2_type, mt_policy> const& s) : _signal_base<mt_policy>(s)
schultezub's avatar
schultezub committed
574
        {
575
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
576
577
578
579
            typename connections_list::const_iterator it = s.m_connected_slots.begin();
            typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
            
            while (it != itEnd) {
schultezub's avatar
schultezub committed
580
581
582
583
584
                (*it)->getdest()->signal_connect(this);
                m_connected_slots.push_back((*it)->clone());
                ++it;
            }
        }
schultezub's avatar
schultezub committed
585
586
        
        void slot_duplicate(has_slots<mt_policy> const* oldtarget, has_slots<mt_policy>* newtarget)
schultezub's avatar
schultezub committed
587
        {
588
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
589
590
591
592
593
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                if ((*it)->getdest() == oldtarget) {
schultezub's avatar
schultezub committed
594
595
                    m_connected_slots.push_back((*it)->duplicate(newtarget));
                }
schultezub's avatar
schultezub committed
596
                
schultezub's avatar
schultezub committed
597
598
599
                ++it;
            }
        }
schultezub's avatar
schultezub committed
600
        
schultezub's avatar
schultezub committed
601
602
603
604
        ~_signal_base2()
        {
            disconnect_all();
        }
schultezub's avatar
schultezub committed
605
        
schultezub's avatar
schultezub committed
606
607
        void disconnect_all()
        {
608
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
609
610
611
612
            typename connections_list::const_iterator it = m_connected_slots.begin();
            typename connections_list::const_iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
schultezub's avatar
schultezub committed
613
614
615
616
                (*it)->getdest()->signal_disconnect(this);
                delete *it;
                ++it;
            }
schultezub's avatar
schultezub committed
617
            
schultezub's avatar
schultezub committed
618
619
            m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
        }
schultezub's avatar
schultezub committed
620
        
schultezub's avatar
schultezub committed
621
622
        void disconnect(has_slots<mt_policy>* pclass)
        {
623
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
624
625
626
627
628
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                if ((*it)->getdest() == pclass) {
schultezub's avatar
schultezub committed
629
630
631
632
633
                    delete *it;
                    m_connected_slots.erase(it);
                    pclass->signal_disconnect(this);
                    return;
                }
schultezub's avatar
schultezub committed
634
                
schultezub's avatar
schultezub committed
635
636
637
                ++it;
            }
        }
schultezub's avatar
schultezub committed
638
        
schultezub's avatar
schultezub committed
639
640
        void slot_disconnect(has_slots<mt_policy>* pslot)
        {
641
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
642
643
644
645
646
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                typename connections_list::iterator itNext = it;
schultezub's avatar
schultezub committed
647
                ++itNext;
schultezub's avatar
schultezub committed
648
649
                
                if ((*it)->getdest() == pslot) {
schultezub's avatar
schultezub committed
650
                    m_connected_slots.erase(it);
schultezub's avatar
schultezub committed
651
                    //          delete *it;
schultezub's avatar
schultezub committed
652
                }
schultezub's avatar
schultezub committed
653
                
schultezub's avatar
schultezub committed
654
655
656
                it = itNext;
            }
        }
schultezub's avatar
schultezub committed
657
        
schultezub's avatar
schultezub committed
658
659
660
    protected:
        connections_list m_connected_slots;   
    };
schultezub's avatar
schultezub committed
661
    
schultezub's avatar
schultezub committed
662
663
664
665
666
    template<class arg1_type, class arg2_type, class arg3_type, class mt_policy>
    class _signal_base3 : public _signal_base<mt_policy>
    {
    public:
        typedef std::list<_connection_base3<arg1_type, arg2_type, arg3_type, mt_policy> *>
schultezub's avatar
schultezub committed
667
668
669
670
671
672
673
        connections_list;
        
        _signal_base3() {}
        
        _signal_base3(_signal_base3<arg1_type, arg2_type, arg3_type, mt_policy> const& s)
        : _signal_base<mt_policy>(s)
        {
674
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
675
676
677
678
            typename connections_list::const_iterator it = s.m_connected_slots.begin();
            typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
            
            while (it != itEnd) {
schultezub's avatar
schultezub committed
679
680
681
682
683
                (*it)->getdest()->signal_connect(this);
                m_connected_slots.push_back((*it)->clone());
                ++it;
            }
        }
schultezub's avatar
schultezub committed
684
685
        
        void slot_duplicate(has_slots<mt_policy> const* oldtarget, has_slots<mt_policy>* newtarget)
schultezub's avatar
schultezub committed
686
        {
687
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
688
689
690
691
692
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                if ((*it)->getdest() == oldtarget) {
schultezub's avatar
schultezub committed
693
694
                    m_connected_slots.push_back((*it)->duplicate(newtarget));
                }
schultezub's avatar
schultezub committed
695
                
schultezub's avatar
schultezub committed
696
697
698
                ++it;
            }
        }
schultezub's avatar
schultezub committed
699
        
schultezub's avatar
schultezub committed
700
701
702
703
        ~_signal_base3()
        {
            disconnect_all();
        }
schultezub's avatar
schultezub committed
704
        
schultezub's avatar
schultezub committed
705
706
        void disconnect_all()
        {
707
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
708
709
710
711
            typename connections_list::const_iterator it = m_connected_slots.begin();
            typename connections_list::const_iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
schultezub's avatar
schultezub committed
712
713
714
715
                (*it)->getdest()->signal_disconnect(this);
                delete *it;
                ++it;
            }
schultezub's avatar
schultezub committed
716
            
schultezub's avatar
schultezub committed
717
718
            m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
        }
schultezub's avatar
schultezub committed
719
        
schultezub's avatar
schultezub committed
720
721
        void disconnect(has_slots<mt_policy>* pclass)
        {
722
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
723
724
725
726
727
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                if ((*it)->getdest() == pclass) {
schultezub's avatar
schultezub committed
728
729
730
731
732
                    delete *it;
                    m_connected_slots.erase(it);
                    pclass->signal_disconnect(this);
                    return;
                }
schultezub's avatar
schultezub committed
733
                
schultezub's avatar
schultezub committed
734
735
736
                ++it;
            }
        }
schultezub's avatar
schultezub committed
737
        
schultezub's avatar
schultezub committed
738
739
        void slot_disconnect(has_slots<mt_policy>* pslot)
        {
740
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
741
742
743
744
745
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                typename connections_list::iterator itNext = it;
schultezub's avatar
schultezub committed
746
                ++itNext;
schultezub's avatar
schultezub committed
747
748
                
                if ((*it)->getdest() == pslot) {
schultezub's avatar
schultezub committed
749
                    m_connected_slots.erase(it);
schultezub's avatar
schultezub committed
750
                    //          delete *it;
schultezub's avatar
schultezub committed
751
                }
schultezub's avatar
schultezub committed
752
                
schultezub's avatar
schultezub committed
753
754
755
                it = itNext;
            }
        }
schultezub's avatar
schultezub committed
756
        
schultezub's avatar
schultezub committed
757
758
759
    protected:
        connections_list m_connected_slots;   
    };
schultezub's avatar
schultezub committed
760
    
schultezub's avatar
schultezub committed
761
762
763
764
765
    template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, class mt_policy>
    class _signal_base4 : public _signal_base<mt_policy>
    {
    public:
        typedef std::list<_connection_base4<arg1_type, arg2_type, arg3_type,
schultezub's avatar
schultezub committed
766
767
768
769
        arg4_type, mt_policy> *>  connections_list;
        
        _signal_base4() {}
        
schultezub's avatar
schultezub committed
770
        _signal_base4(const _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>& s)
schultezub's avatar
schultezub committed
771
        : _signal_base<mt_policy>(s)
schultezub's avatar
schultezub committed
772
        {
773
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
774
775
776
777
            typename connections_list::const_iterator it = s.m_connected_slots.begin();
            typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
            
            while (it != itEnd) {
schultezub's avatar
schultezub committed
778
779
                (*it)->getdest()->signal_connect(this);
                m_connected_slots.push_back((*it)->clone());
schultezub's avatar
schultezub committed
780
                
schultezub's avatar
schultezub committed
781
782
783
                ++it;
            }
        }
schultezub's avatar
schultezub committed
784
        
schultezub's avatar
schultezub committed
785
786
        void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
        {
787
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
788
789
790
791
792
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                if ((*it)->getdest() == oldtarget) {
schultezub's avatar
schultezub committed
793
794
                    m_connected_slots.push_back((*it)->duplicate(newtarget));
                }
schultezub's avatar
schultezub committed
795
                
schultezub's avatar
schultezub committed
796
797
798
                ++it;
            }
        }
schultezub's avatar
schultezub committed
799
        
schultezub's avatar
schultezub committed
800
801
802
803
        ~_signal_base4()
        {
            disconnect_all();
        }
schultezub's avatar
schultezub committed
804
        
schultezub's avatar
schultezub committed
805
806
        void disconnect_all()
        {
807
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
808
809
810
811
            typename connections_list::const_iterator it = m_connected_slots.begin();
            typename connections_list::const_iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
schultezub's avatar
schultezub committed
812
813
                (*it)->getdest()->signal_disconnect(this);
                delete *it;
schultezub's avatar
schultezub committed
814
                
schultezub's avatar
schultezub committed
815
816
                ++it;
            }
schultezub's avatar
schultezub committed
817
            
schultezub's avatar
schultezub committed
818
819
            m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
        }
schultezub's avatar
schultezub committed
820
        
schultezub's avatar
schultezub committed
821
822
        void disconnect(has_slots<mt_policy>* pclass)
        {
823
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
824
825
826
827
828
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                if ((*it)->getdest() == pclass) {
schultezub's avatar
schultezub committed
829
830
831
832
833
                    delete *it;
                    m_connected_slots.erase(it);
                    pclass->signal_disconnect(this);
                    return;
                }
schultezub's avatar
schultezub committed
834
                
schultezub's avatar
schultezub committed
835
836
837
                ++it;
            }
        }
schultezub's avatar
schultezub committed
838
        
schultezub's avatar
schultezub committed
839
840
        void slot_disconnect(has_slots<mt_policy>* pslot)
        {
841
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
842
843
844
845
846
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                typename connections_list::iterator itNext = it;
schultezub's avatar
schultezub committed
847
                ++itNext;
schultezub's avatar
schultezub committed
848
849
                
                if ((*it)->getdest() == pslot) {
schultezub's avatar
schultezub committed
850
                    m_connected_slots.erase(it);
schultezub's avatar
schultezub committed
851
                    //          delete *it;
schultezub's avatar
schultezub committed
852
                }
schultezub's avatar
schultezub committed
853
                
schultezub's avatar
schultezub committed
854
855
856
                it = itNext;
            }
        }
schultezub's avatar
schultezub committed
857
        
schultezub's avatar
schultezub committed
858
859
860
    protected:
        connections_list m_connected_slots;   
    };
schultezub's avatar
schultezub committed
861
    
schultezub's avatar
schultezub committed
862
863
864
865
866
867
    template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
    class arg5_type, class mt_policy>
    class _signal_base5 : public _signal_base<mt_policy>
    {
    public:
        typedef std::list<_connection_base5<arg1_type, arg2_type, arg3_type,
schultezub's avatar
schultezub committed
868
869
870
871
        arg4_type, arg5_type, mt_policy> *>  connections_list;
        
        _signal_base5() {}
        
schultezub's avatar
schultezub committed
872
        _signal_base5(const _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
873
874
                      arg5_type, mt_policy>& s)
        : _signal_base<mt_policy>(s)
schultezub's avatar
schultezub committed
875
        {
876
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
877
878
879
880
            typename connections_list::const_iterator it = s.m_connected_slots.begin();
            typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
            
            while (it != itEnd) {
schultezub's avatar
schultezub committed
881
882
                (*it)->getdest()->signal_connect(this);
                m_connected_slots.push_back((*it)->clone());
schultezub's avatar
schultezub committed
883
                
schultezub's avatar
schultezub committed
884
885
886
                ++it;
            }
        }
schultezub's avatar
schultezub committed
887
        
schultezub's avatar
schultezub committed
888
889
        void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
        {
890
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
891
892
893
894
895
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                if ((*it)->getdest() == oldtarget) {
schultezub's avatar
schultezub committed
896
897
                    m_connected_slots.push_back((*it)->duplicate(newtarget));
                }
schultezub's avatar
schultezub committed
898
                
schultezub's avatar
schultezub committed
899
900
901
                ++it;
            }
        }
schultezub's avatar
schultezub committed
902
        
schultezub's avatar
schultezub committed
903
904
905
906
        ~_signal_base5()
        {
            disconnect_all();
        }
schultezub's avatar
schultezub committed
907
        
schultezub's avatar
schultezub committed
908
909
        void disconnect_all()
        {
910
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
911
912
913
914
            typename connections_list::const_iterator it = m_connected_slots.begin();
            typename connections_list::const_iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
schultezub's avatar
schultezub committed
915
916
                (*it)->getdest()->signal_disconnect(this);
                delete *it;
schultezub's avatar
schultezub committed
917
                
schultezub's avatar
schultezub committed
918
919
                ++it;
            }
schultezub's avatar
schultezub committed
920
            
schultezub's avatar
schultezub committed
921
922
            m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
        }
schultezub's avatar
schultezub committed
923
        
schultezub's avatar
schultezub committed
924
925
        void disconnect(has_slots<mt_policy>* pclass)
        {
926
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
927
928
929
930
931
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                if ((*it)->getdest() == pclass) {
schultezub's avatar
schultezub committed
932
933
934
935
936
                    delete *it;
                    m_connected_slots.erase(it);
                    pclass->signal_disconnect(this);
                    return;
                }
schultezub's avatar
schultezub committed
937
                
schultezub's avatar
schultezub committed
938
939
940
                ++it;
            }
        }
schultezub's avatar
schultezub committed
941
        
schultezub's avatar
schultezub committed
942
943
        void slot_disconnect(has_slots<mt_policy>* pslot)
        {
944
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
945
946
947
948
949
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                typename connections_list::iterator itNext = it;
schultezub's avatar
schultezub committed
950
                ++itNext;
schultezub's avatar
schultezub committed
951
952
                
                if ((*it)->getdest() == pslot) {
schultezub's avatar
schultezub committed
953
                    m_connected_slots.erase(it);
schultezub's avatar
schultezub committed
954
                    //          delete *it;
schultezub's avatar
schultezub committed
955
                }
schultezub's avatar
schultezub committed
956
                
schultezub's avatar
schultezub committed
957
958
959
                it = itNext;
            }
        }
schultezub's avatar
schultezub committed
960
        
schultezub's avatar
schultezub committed
961
962
963
    protected:
        connections_list m_connected_slots;   
    };
schultezub's avatar
schultezub committed
964
    
schultezub's avatar
schultezub committed
965
966
967
968
969
970
    template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
    class arg5_type, class arg6_type, class mt_policy>
    class _signal_base6 : public _signal_base<mt_policy>
    {
    public:
        typedef std::list<_connection_base6<arg1_type, arg2_type, arg3_type, 
schultezub's avatar
schultezub committed
971
972
973
974
        arg4_type, arg5_type, arg6_type, mt_policy> *>  connections_list;
        
        _signal_base6() {}
        
schultezub's avatar
schultezub committed
975
        _signal_base6(const _signal_base6<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
976
977
                      arg5_type, arg6_type, mt_policy>& s)
        : _signal_base<mt_policy>(s)
schultezub's avatar
schultezub committed
978
        {
979
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
980
981
982
983
            typename connections_list::const_iterator it = s.m_connected_slots.begin();
            typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
            
            while (it != itEnd) {
schultezub's avatar
schultezub committed
984
985
                (*it)->getdest()->signal_connect(this);
                m_connected_slots.push_back((*it)->clone());
schultezub's avatar
schultezub committed
986
                
schultezub's avatar
schultezub committed
987
988
989
                ++it;
            }
        }
schultezub's avatar
schultezub committed
990
        
schultezub's avatar
schultezub committed
991
992
        void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
        {
993
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
994
995
996
997
998
            typename connections_list::iterator it = m_connected_slots.begin();
            typename connections_list::iterator itEnd = m_connected_slots.end();
            
            while (it != itEnd) {
                if ((*it)->getdest() == oldtarget) {
schultezub's avatar
schultezub committed
999
1000
                    m_connected_slots.push_back((*it)->duplicate(newtarget));
                }
schultezub's avatar
schultezub committed
1001
                
schultezub's avatar
schultezub committed
1002
1003
1004
                ++it;
            }
        }
schultezub's avatar
schultezub committed
1005
        
schultezub's avatar
schultezub committed
1006
1007
1008
1009
        ~_signal_base6()
        {
            disconnect_all();
        }
schultezub's avatar
schultezub committed
1010