Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing 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 84.7 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
96
97

#include <tbb/compat/condition_variable>
#include <tbb/concurrent_queue.h>
98
#include <tbb/spin_rw_mutex.h>
schultezub's avatar
schultezub committed
99

100
101
102
#include "ext/tgt/runnable.h"
#include "ext/tgt/singleton.h"

schultezub's avatar
schultezub committed
103
104
105
106
107
108
109
110
111
112
#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 {

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
    class _signal_handle_base {
    public:
        virtual ~_signal_handle_base() {};
        virtual void emitSignal() const = 0;
    };

    class signal_manager : public tgt::Singleton<signal_manager>, public tgt::Runnable {
        friend class tgt::Singleton<signal_manager>;

    public:
        /**
         * Directly dispatches the signal \a signal to all currently registered listeners.
         * \note    For using threaded signal dispatching use queueSignal()
         * \param   signal   signal to dispatch
         */
        void triggerSignal(_signal_handle_base* signal) const;

        /**
         * Enqueue \a signal into the list of signals to be dispatched.
         * \note    Dispatch will be perfomed in signal_mananger thread. For direct dispatch in
         *          caller thread use triggerSignal().
         * \param   signal   signal to dispatch
         * \return  True, if \a signal was successfully enqueued to signal queue.
         */
        bool queueSignal(_signal_handle_base* signal);

        /// \see Runnable:run
        virtual void run();
        /// \see Runnable:stop
        virtual void stop();

    private:
        /// Private constructor only for singleton
        signal_manager();
        /// Private destructor only for singleton
        ~signal_manager();

        typedef tbb::concurrent_queue<_signal_handle_base*> SignalQueue;

        SignalQueue _signalQueue;   ///< Queue for signals to be dispatched

        std::condition_variable _evaluationCondition; ///< conditional wait to be used when there are currently no jobs to process
        tbb::mutex _ecMutex; ///< Mutex for protecting _evaluationCondition

        static const std::string loggerCat_;
    };

160
    typedef tbb::spin_rw_mutex tbb_mutex;
schultezub's avatar
schultezub committed
161
162
163
164
165
166
167

    // The multi threading policies only get compiled in if they are enabled.
    class multi_threaded_global
    {
    public:
        multi_threaded_global()
        {
168
            ;
schultezub's avatar
schultezub committed
169
170
171
172
173
174
175
176
177
178
179
180
        }

        multi_threaded_global(const multi_threaded_global&)
        {
            ;
        }

        virtual ~multi_threaded_global()
        {
            ;
        }

181
        tbb_mutex& get_mutex()
schultezub's avatar
schultezub committed
182
        {
183
184
            static tbb_mutex g_mutex;
            return g_mutex;
schultezub's avatar
schultezub committed
185
186
187
188
189
190
191
192
        }
    };

    class multi_threaded_local
    {
    public:
        multi_threaded_local()
        {
193
            ;
schultezub's avatar
schultezub committed
194
195
196
197
198
199
200
        }

        multi_threaded_local(const multi_threaded_local&)
        {
            ;
        }

201
        virtual ~multi_threaded_local()
schultezub's avatar
schultezub committed
202
203
204
205
        {
            ;
        }

206
        tbb_mutex& get_mutex() { return m_mutex; }
schultezub's avatar
schultezub committed
207
208

    private:
209
        tbb_mutex m_mutex;
schultezub's avatar
schultezub committed
210
    };
211
212
213
    
    template<class mt_policy>
    class lock_block_write : tbb_mutex::scoped_lock
schultezub's avatar
schultezub committed
214
215
    {
    public:
216
        lock_block_write(mt_policy *mtx) : tbb_mutex::scoped_lock(mtx->get_mutex(), true)
schultezub's avatar
schultezub committed
217
218
        {
        }
219
220
        
        ~lock_block_write()
schultezub's avatar
schultezub committed
221
222
223
224
        {
        }
    };

225
226
    template<class mt_policy>
    class lock_block_read : tbb_mutex::scoped_lock
schultezub's avatar
schultezub committed
227
228
    {
    public:
229
        lock_block_read(mt_policy *mtx) : tbb_mutex::scoped_lock(mtx->get_mutex(), false)
schultezub's avatar
schultezub committed
230
231
232
        {
        }

233
        ~lock_block_read()
schultezub's avatar
schultezub committed
234
235
236
237
        {
        }
    };

238

schultezub's avatar
schultezub committed
239
240
    template<class mt_policy>
    class has_slots;
schultezub's avatar
schultezub committed
241
    
schultezub's avatar
schultezub committed
242
243
244
245
    template<class mt_policy>
    class _connection_base0
    {
    public:
schultezub's avatar
schultezub committed
246
        virtual ~_connection_base0() {}
schultezub's avatar
schultezub committed
247
248
249
250
251
        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
252
    
schultezub's avatar
schultezub committed
253
254
255
256
    template<class arg1_type, class mt_policy>
    class _connection_base1
    {
    public:
schultezub's avatar
schultezub committed
257
        virtual ~_connection_base1() {}
schultezub's avatar
schultezub committed
258
259
260
261
262
        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
263
    
schultezub's avatar
schultezub committed
264
265
266
267
    template<class arg1_type, class arg2_type, class mt_policy>
    class _connection_base2
    {
    public:
schultezub's avatar
schultezub committed
268
        virtual ~_connection_base2() {}
schultezub's avatar
schultezub committed
269
270
271
272
273
        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
274
    
schultezub's avatar
schultezub committed
275
276
277
278
    template<class arg1_type, class arg2_type, class arg3_type, class mt_policy>
    class _connection_base3
    {
    public:
schultezub's avatar
schultezub committed
279
        virtual ~_connection_base3() {}
schultezub's avatar
schultezub committed
280
281
282
283
284
        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
285
    
schultezub's avatar
schultezub committed
286
287
288
289
    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
290
        virtual ~_connection_base4() {}
schultezub's avatar
schultezub committed
291
292
293
294
295
        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
296
    
schultezub's avatar
schultezub committed
297
298
299
300
301
    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
302
        virtual ~_connection_base5() {}
schultezub's avatar
schultezub committed
303
304
        virtual has_slots<mt_policy>* getdest() const = 0;
        virtual void emitSignal(arg1_type, arg2_type, arg3_type, arg4_type, 
schultezub's avatar
schultezub committed
305
                          arg5_type) = 0;
schultezub's avatar
schultezub committed
306
        virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
307
        arg5_type, mt_policy>* clone() = 0;
schultezub's avatar
schultezub committed
308
        virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
309
        arg5_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
schultezub's avatar
schultezub committed
310
    };
schultezub's avatar
schultezub committed
311
    
schultezub's avatar
schultezub committed
312
313
314
315
316
    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
317
        virtual ~_connection_base6() {}
schultezub's avatar
schultezub committed
318
319
        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
320
                          arg6_type) = 0;
schultezub's avatar
schultezub committed
321
        virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
322
        arg5_type, arg6_type, mt_policy>* clone() = 0;
schultezub's avatar
schultezub committed
323
        virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
324
        arg5_type, arg6_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
schultezub's avatar
schultezub committed
325
    };
schultezub's avatar
schultezub committed
326
    
schultezub's avatar
schultezub committed
327
328
329
330
331
    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
332
        virtual ~_connection_base7() {}
schultezub's avatar
schultezub committed
333
334
        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
335
                          arg6_type, arg7_type) = 0;
schultezub's avatar
schultezub committed
336
        virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
337
        arg5_type, arg6_type, arg7_type, mt_policy>* clone() = 0;
schultezub's avatar
schultezub committed
338
        virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
339
        arg5_type, arg6_type, arg7_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
schultezub's avatar
schultezub committed
340
    };
schultezub's avatar
schultezub committed
341
    
schultezub's avatar
schultezub committed
342
343
344
345
346
    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
347
        virtual ~_connection_base8() {}
schultezub's avatar
schultezub committed
348
349
        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
350
                          arg6_type, arg7_type, arg8_type) = 0;
schultezub's avatar
schultezub committed
351
        virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
352
        arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* clone() = 0;
schultezub's avatar
schultezub committed
353
        virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
354
        arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
schultezub's avatar
schultezub committed
355
    };
schultezub's avatar
schultezub committed
356
    
schultezub's avatar
schultezub committed
357
358
359
360
361
    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
362
        virtual void slot_duplicate(has_slots<mt_policy> const* poldslot, has_slots<mt_policy>* pnewslot) = 0;
schultezub's avatar
schultezub committed
363
    };
schultezub's avatar
schultezub committed
364
    
schultezub's avatar
schultezub committed
365
366
367
368
    template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
    class has_slots : public mt_policy 
    {
    private:
schultezub's avatar
schultezub committed
369
        typedef typename std::set<_signal_base<mt_policy> *> sender_set;
schultezub's avatar
schultezub committed
370
        typedef typename sender_set::const_iterator const_iterator;
schultezub's avatar
schultezub committed
371
        
schultezub's avatar
schultezub committed
372
    public:
schultezub's avatar
schultezub committed
373
374
375
        has_slots() {}
        
        has_slots(has_slots const& hs) : mt_policy(hs)
schultezub's avatar
schultezub committed
376
        {
377
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
378
379
            const_iterator it = hs.m_senders.begin();
            const_iterator itEnd = hs.m_senders.end();
schultezub's avatar
schultezub committed
380
381
            
            while (it != itEnd) {
schultezub's avatar
schultezub committed
382
383
384
385
386
                (*it)->slot_duplicate(&hs, this);
                m_senders.insert(*it);
                ++it;
            }
        } 
schultezub's avatar
schultezub committed
387
        
schultezub's avatar
schultezub committed
388
389
        void signal_connect(_signal_base<mt_policy>* sender)
        {
390
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
391
392
            m_senders.insert(sender);
        }
schultezub's avatar
schultezub committed
393
        
schultezub's avatar
schultezub committed
394
395
        void signal_disconnect(_signal_base<mt_policy>* sender)
        {
396
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
397
398
            m_senders.erase(sender);
        }
schultezub's avatar
schultezub committed
399
        
schultezub's avatar
schultezub committed
400
401
402
403
        virtual ~has_slots()
        {
            disconnect_all();
        }
schultezub's avatar
schultezub committed
404
        
schultezub's avatar
schultezub committed
405
406
        void disconnect_all()
        {
407
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
408
409
            const_iterator it = m_senders.begin();
            const_iterator itEnd = m_senders.end();
schultezub's avatar
schultezub committed
410
411
            
            while (it != itEnd) {
schultezub's avatar
schultezub committed
412
413
414
                (*it)->slot_disconnect(this);
                ++it;
            }
schultezub's avatar
schultezub committed
415
            
schultezub's avatar
schultezub committed
416
417
            m_senders.erase(m_senders.begin(), m_senders.end());
        }
schultezub's avatar
schultezub committed
418
        
schultezub's avatar
schultezub committed
419
420
421
    private:
        sender_set m_senders;
    };
schultezub's avatar
schultezub committed
422
    
schultezub's avatar
schultezub committed
423
424
425
426
427
    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
428
429
430
431
        
        _signal_base0() {}
        
        _signal_base0(_signal_base0 const& s) : _signal_base<mt_policy>(s)
schultezub's avatar
schultezub committed
432
        {
433
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
434
435
436
437
            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
438
439
440
441
442
                (*it)->getdest()->signal_connect(this);
                m_connected_slots.push_back((*it)->clone());
                ++it;
            }
        }
schultezub's avatar
schultezub committed
443
        
schultezub's avatar
schultezub committed
444
445
446
447
        ~_signal_base0()
        {
            disconnect_all();
        }
schultezub's avatar
schultezub committed
448
        
schultezub's avatar
schultezub committed
449
450
        void disconnect_all()
        {
451
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
452
453
454
455
            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
456
457
458
459
                (*it)->getdest()->signal_disconnect(this);
                delete *it;
                ++it;
            }
schultezub's avatar
schultezub committed
460
            
schultezub's avatar
schultezub committed
461
462
            m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
        }
schultezub's avatar
schultezub committed
463
        
schultezub's avatar
schultezub committed
464
465
        void disconnect(has_slots<mt_policy>* pclass)
        {
466
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
467
468
469
470
471
            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
472
473
474
475
476
                    delete *it;
                    m_connected_slots.erase(it);
                    pclass->signal_disconnect(this);
                    return;
                }
schultezub's avatar
schultezub committed
477
                
schultezub's avatar
schultezub committed
478
479
480
                ++it;
            }
        }
schultezub's avatar
schultezub committed
481
        
schultezub's avatar
schultezub committed
482
483
        void slot_disconnect(has_slots<mt_policy>* pslot)
        {
484
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
485
486
487
488
489
            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
490
                ++itNext;
schultezub's avatar
schultezub committed
491
492
                
                if ((*it)->getdest() == pslot) {
schultezub's avatar
schultezub committed
493
                    m_connected_slots.erase(it);
schultezub's avatar
schultezub committed
494
                    //          delete *it;
schultezub's avatar
schultezub committed
495
                }
schultezub's avatar
schultezub committed
496
                
schultezub's avatar
schultezub committed
497
498
499
                it = itNext;
            }
        }
schultezub's avatar
schultezub committed
500
501
        
        void slot_duplicate(has_slots<mt_policy> const* oldtarget, has_slots<mt_policy>* newtarget)
schultezub's avatar
schultezub committed
502
        {
503
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
504
505
506
507
508
            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
509
510
                    m_connected_slots.push_back((*it)->duplicate(newtarget));
                }
schultezub's avatar
schultezub committed
511
                
schultezub's avatar
schultezub committed
512
513
514
                ++it;
            }
        }
515
516
517
518
519

        bool has_connections() const
        {
            return !m_connected_slots.empty();
        }
schultezub's avatar
schultezub committed
520
        
schultezub's avatar
schultezub committed
521
522
523
    protected:
        connections_list m_connected_slots;   
    };
schultezub's avatar
schultezub committed
524
    
schultezub's avatar
schultezub committed
525
526
527
528
529
    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
530
531
532
533
        
        _signal_base1() {}
        
        _signal_base1(_signal_base1<arg1_type, mt_policy> const& s) : _signal_base<mt_policy>(s)
schultezub's avatar
schultezub committed
534
        {
535
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
536
537
538
539
            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
540
541
542
543
544
                (*it)->getdest()->signal_connect(this);
                m_connected_slots.push_back((*it)->clone());
                ++it;
            }
        }
schultezub's avatar
schultezub committed
545
546
        
        void slot_duplicate(has_slots<mt_policy> const* oldtarget, has_slots<mt_policy>* newtarget)
schultezub's avatar
schultezub committed
547
        {
548
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
549
550
551
552
553
            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
554
555
                    m_connected_slots.push_back((*it)->duplicate(newtarget));
                }
schultezub's avatar
schultezub committed
556
                
schultezub's avatar
schultezub committed
557
558
559
                ++it;
            }
        }
schultezub's avatar
schultezub committed
560
        
schultezub's avatar
schultezub committed
561
562
563
564
        ~_signal_base1()
        {
            disconnect_all();
        }
schultezub's avatar
schultezub committed
565
        
schultezub's avatar
schultezub committed
566
567
        void disconnect_all()
        {
568
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
569
570
571
572
            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
573
574
575
576
                (*it)->getdest()->signal_disconnect(this);
                delete *it;
                ++it;
            }
schultezub's avatar
schultezub committed
577
            
schultezub's avatar
schultezub committed
578
579
            m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
        }
schultezub's avatar
schultezub committed
580
        
schultezub's avatar
schultezub committed
581
582
        void disconnect(has_slots<mt_policy>* pclass)
        {
583
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
584
585
586
587
588
            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
589
590
591
592
593
                    delete *it;
                    m_connected_slots.erase(it);
                    pclass->signal_disconnect(this);
                    return;
                }
schultezub's avatar
schultezub committed
594
                
schultezub's avatar
schultezub committed
595
596
597
                ++it;
            }
        }
schultezub's avatar
schultezub committed
598
        
schultezub's avatar
schultezub committed
599
600
        void slot_disconnect(has_slots<mt_policy>* pslot)
        {
601
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
602
603
604
605
606
            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
607
                ++itNext;
schultezub's avatar
schultezub committed
608
609
                
                if ((*it)->getdest() == pslot) {
schultezub's avatar
schultezub committed
610
                    m_connected_slots.erase(it);
schultezub's avatar
schultezub committed
611
                    //          delete *it;
schultezub's avatar
schultezub committed
612
                }
schultezub's avatar
schultezub committed
613
                
schultezub's avatar
schultezub committed
614
615
616
                it = itNext;
            }
        }
617
618
619
620
621

        bool has_connections() const
        {
            return !m_connected_slots.empty();
        }
schultezub's avatar
schultezub committed
622
623
        
        
schultezub's avatar
schultezub committed
624
625
626
    protected:
        connections_list m_connected_slots;   
    };
schultezub's avatar
schultezub committed
627
    
schultezub's avatar
schultezub committed
628
629
630
631
632
    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
633
634
635
636
637
        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
638
        {
639
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
640
641
642
643
            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
644
645
646
647
648
                (*it)->getdest()->signal_connect(this);
                m_connected_slots.push_back((*it)->clone());
                ++it;
            }
        }
schultezub's avatar
schultezub committed
649
650
        
        void slot_duplicate(has_slots<mt_policy> const* oldtarget, has_slots<mt_policy>* newtarget)
schultezub's avatar
schultezub committed
651
        {
652
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
653
654
655
656
657
            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
658
659
                    m_connected_slots.push_back((*it)->duplicate(newtarget));
                }
schultezub's avatar
schultezub committed
660
                
schultezub's avatar
schultezub committed
661
662
663
                ++it;
            }
        }
schultezub's avatar
schultezub committed
664
        
schultezub's avatar
schultezub committed
665
666
667
668
        ~_signal_base2()
        {
            disconnect_all();
        }
schultezub's avatar
schultezub committed
669
        
schultezub's avatar
schultezub committed
670
671
        void disconnect_all()
        {
672
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
673
674
675
676
            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
677
678
679
680
                (*it)->getdest()->signal_disconnect(this);
                delete *it;
                ++it;
            }
schultezub's avatar
schultezub committed
681
            
schultezub's avatar
schultezub committed
682
683
            m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
        }
schultezub's avatar
schultezub committed
684
        
schultezub's avatar
schultezub committed
685
686
        void disconnect(has_slots<mt_policy>* pclass)
        {
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() == pclass) {
schultezub's avatar
schultezub committed
693
694
695
696
697
                    delete *it;
                    m_connected_slots.erase(it);
                    pclass->signal_disconnect(this);
                    return;
                }
schultezub's avatar
schultezub committed
698
                
schultezub's avatar
schultezub committed
699
700
701
                ++it;
            }
        }
schultezub's avatar
schultezub committed
702
        
schultezub's avatar
schultezub committed
703
704
        void slot_disconnect(has_slots<mt_policy>* pslot)
        {
705
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
706
707
708
709
710
            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
711
                ++itNext;
schultezub's avatar
schultezub committed
712
713
                
                if ((*it)->getdest() == pslot) {
schultezub's avatar
schultezub committed
714
                    m_connected_slots.erase(it);
schultezub's avatar
schultezub committed
715
                    //          delete *it;
schultezub's avatar
schultezub committed
716
                }
schultezub's avatar
schultezub committed
717
                
schultezub's avatar
schultezub committed
718
719
720
                it = itNext;
            }
        }
721
722
723
724
725

        bool has_connections() const
        {
            return !m_connected_slots.empty();
        }
schultezub's avatar
schultezub committed
726
        
schultezub's avatar
schultezub committed
727
728
729
    protected:
        connections_list m_connected_slots;   
    };
schultezub's avatar
schultezub committed
730
    
schultezub's avatar
schultezub committed
731
732
733
734
735
    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
736
737
738
739
740
741
742
        connections_list;
        
        _signal_base3() {}
        
        _signal_base3(_signal_base3<arg1_type, arg2_type, arg3_type, mt_policy> const& s)
        : _signal_base<mt_policy>(s)
        {
743
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
744
745
746
747
            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
748
749
750
751
752
                (*it)->getdest()->signal_connect(this);
                m_connected_slots.push_back((*it)->clone());
                ++it;
            }
        }
schultezub's avatar
schultezub committed
753
754
        
        void slot_duplicate(has_slots<mt_policy> const* oldtarget, has_slots<mt_policy>* newtarget)
schultezub's avatar
schultezub committed
755
        {
756
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
757
758
759
760
761
            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
762
763
                    m_connected_slots.push_back((*it)->duplicate(newtarget));
                }
schultezub's avatar
schultezub committed
764
                
schultezub's avatar
schultezub committed
765
766
767
                ++it;
            }
        }
schultezub's avatar
schultezub committed
768
        
schultezub's avatar
schultezub committed
769
770
771
772
        ~_signal_base3()
        {
            disconnect_all();
        }
schultezub's avatar
schultezub committed
773
        
schultezub's avatar
schultezub committed
774
775
        void disconnect_all()
        {
776
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
777
778
779
780
            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
781
782
783
784
                (*it)->getdest()->signal_disconnect(this);
                delete *it;
                ++it;
            }
schultezub's avatar
schultezub committed
785
            
schultezub's avatar
schultezub committed
786
787
            m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
        }
schultezub's avatar
schultezub committed
788
        
schultezub's avatar
schultezub committed
789
790
        void disconnect(has_slots<mt_policy>* pclass)
        {
791
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
792
793
794
795
796
            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
797
798
799
800
801
                    delete *it;
                    m_connected_slots.erase(it);
                    pclass->signal_disconnect(this);
                    return;
                }
schultezub's avatar
schultezub committed
802
                
schultezub's avatar
schultezub committed
803
804
805
                ++it;
            }
        }
schultezub's avatar
schultezub committed
806
        
schultezub's avatar
schultezub committed
807
808
        void slot_disconnect(has_slots<mt_policy>* pslot)
        {
809
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
810
811
812
813
814
            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
815
                ++itNext;
schultezub's avatar
schultezub committed
816
817
                
                if ((*it)->getdest() == pslot) {
schultezub's avatar
schultezub committed
818
                    m_connected_slots.erase(it);
schultezub's avatar
schultezub committed
819
                    //          delete *it;
schultezub's avatar
schultezub committed
820
                }
schultezub's avatar
schultezub committed
821
                
schultezub's avatar
schultezub committed
822
823
824
                it = itNext;
            }
        }
825
826
827
828
829

        bool has_connections() const
        {
            return !m_connected_slots.empty();
        }
schultezub's avatar
schultezub committed
830
        
schultezub's avatar
schultezub committed
831
832
833
    protected:
        connections_list m_connected_slots;   
    };
schultezub's avatar
schultezub committed
834
    
schultezub's avatar
schultezub committed
835
836
837
838
839
    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
840
841
842
843
        arg4_type, mt_policy> *>  connections_list;
        
        _signal_base4() {}
        
schultezub's avatar
schultezub committed
844
        _signal_base4(const _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>& s)
schultezub's avatar
schultezub committed
845
        : _signal_base<mt_policy>(s)
schultezub's avatar
schultezub committed
846
        {
847
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
848
849
850
851
            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
852
853
                (*it)->getdest()->signal_connect(this);
                m_connected_slots.push_back((*it)->clone());
schultezub's avatar
schultezub committed
854
                
schultezub's avatar
schultezub committed
855
856
857
                ++it;
            }
        }
schultezub's avatar
schultezub committed
858
        
schultezub's avatar
schultezub committed
859
860
        void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
        {
861
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
862
863
864
865
866
            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
867
868
                    m_connected_slots.push_back((*it)->duplicate(newtarget));
                }
schultezub's avatar
schultezub committed
869
                
schultezub's avatar
schultezub committed
870
871
872
                ++it;
            }
        }
schultezub's avatar
schultezub committed
873
        
schultezub's avatar
schultezub committed
874
875
876
877
        ~_signal_base4()
        {
            disconnect_all();
        }
schultezub's avatar
schultezub committed
878
        
schultezub's avatar
schultezub committed
879
880
        void disconnect_all()
        {
881
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
882
883
884
885
            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
886
887
                (*it)->getdest()->signal_disconnect(this);
                delete *it;
schultezub's avatar
schultezub committed
888
                
schultezub's avatar
schultezub committed
889
890
                ++it;
            }
schultezub's avatar
schultezub committed
891
            
schultezub's avatar
schultezub committed
892
893
            m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
        }
schultezub's avatar
schultezub committed
894
        
schultezub's avatar
schultezub committed
895
896
        void disconnect(has_slots<mt_policy>* pclass)
        {
897
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
898
899
900
901
902
            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
903
904
905
906
907
                    delete *it;
                    m_connected_slots.erase(it);
                    pclass->signal_disconnect(this);
                    return;
                }
schultezub's avatar
schultezub committed
908
                
schultezub's avatar
schultezub committed
909
910
911
                ++it;
            }
        }
schultezub's avatar
schultezub committed
912
        
schultezub's avatar
schultezub committed
913
914
        void slot_disconnect(has_slots<mt_policy>* pslot)
        {
915
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
916
917
918
919
920
            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
921
                ++itNext;
schultezub's avatar
schultezub committed
922
923
                
                if ((*it)->getdest() == pslot) {
schultezub's avatar
schultezub committed
924
                    m_connected_slots.erase(it);
schultezub's avatar
schultezub committed
925
                    //          delete *it;
schultezub's avatar
schultezub committed
926
                }
schultezub's avatar
schultezub committed
927
                
schultezub's avatar
schultezub committed
928
929
930
                it = itNext;
            }
        }
931
932
933
934
935

        bool has_connections() const
        {
            return !m_connected_slots.empty();
        }
schultezub's avatar
schultezub committed
936
        
schultezub's avatar
schultezub committed
937
938
939
    protected:
        connections_list m_connected_slots;   
    };
schultezub's avatar
schultezub committed
940
    
schultezub's avatar
schultezub committed
941
942
943
944
945
946
    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
947
948
949
950
        arg4_type, arg5_type, mt_policy> *>  connections_list;
        
        _signal_base5() {}
        
schultezub's avatar
schultezub committed
951
        _signal_base5(const _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type,
schultezub's avatar
schultezub committed
952
953
                      arg5_type, mt_policy>& s)
        : _signal_base<mt_policy>(s)
schultezub's avatar
schultezub committed
954
        {
955
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
956
957
958
959
            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
960
961
                (*it)->getdest()->signal_connect(this);
                m_connected_slots.push_back((*it)->clone());
schultezub's avatar
schultezub committed
962
                
schultezub's avatar
schultezub committed
963
964
965
                ++it;
            }
        }
schultezub's avatar
schultezub committed
966
        
schultezub's avatar
schultezub committed
967
968
        void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
        {
969
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
970
971
972
973
974
            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
975
976
                    m_connected_slots.push_back((*it)->duplicate(newtarget));
                }
schultezub's avatar
schultezub committed
977
                
schultezub's avatar
schultezub committed
978
979
980
                ++it;
            }
        }
schultezub's avatar
schultezub committed
981
        
schultezub's avatar
schultezub committed
982
983
984
985
        ~_signal_base5()
        {
            disconnect_all();
        }
schultezub's avatar
schultezub committed
986
        
schultezub's avatar
schultezub committed
987
988
        void disconnect_all()
        {
989
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
990
991
992
993
            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
994
995
                (*it)->getdest()->signal_disconnect(this);
                delete *it;
schultezub's avatar
schultezub committed
996
                
schultezub's avatar
schultezub committed
997
998
                ++it;
            }
schultezub's avatar
schultezub committed
999
            
schultezub's avatar
schultezub committed
1000
1001
            m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
        }
schultezub's avatar
schultezub committed
1002
        
schultezub's avatar
schultezub committed
1003
1004
        void disconnect(has_slots<mt_policy>* pclass)
        {
1005
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
1006
1007
1008
1009
1010
            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
1011
1012
1013
1014
1015
                    delete *it;
                    m_connected_slots.erase(it);
                    pclass->signal_disconnect(this);
                    return;
                }
schultezub's avatar
schultezub committed
1016
                
schultezub's avatar
schultezub committed
1017
1018
1019
                ++it;
            }
        }
schultezub's avatar
schultezub committed
1020
        
schultezub's avatar
schultezub committed
1021
1022
        void slot_disconnect(has_slots<mt_policy>* pslot)
        {
1023
            lock_block_write<mt_policy> lock(this);
schultezub's avatar
schultezub committed
1024
1025
1026
1027
1028
            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
1029
                ++itNext;
schultezub's avatar
schultezub committed
1030
1031
                
                if ((*it)->getdest() == pslot) {
schultezub's avatar
schultezub committed
1032
                    m_connected_slots.erase(it);
schultezub's avatar
schultezub committed
1033
                    //          delete *it;
schultezub's avatar
schultezub committed
1034
                }
schultezub's avatar
schultezub committed
1035
                
schultezub's avatar
schultezub committed
1036
1037
1038
                it = itNext;
            }
        }
1039
1040
1041
1042
1043

        bool has_connections() const
        {
            return !m_connected_slots.empty();
        }
schultezub's avatar
schultezub committed
1044
        
schultezub's avatar
schultezub committed
1045
1046
1047
    protected:
        connections_list m_connected_slots;   
    };
schultezub's avatar
schultezub committed
1048
    
schultezub's avatar
schultezub committed
1049
1050
1051
1052
1053
1054
    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