]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/InGuiThread.h
Disambiguate std::bind, boost::bind, std::ref, boost::ref
[lyx.git] / src / frontends / qt4 / InGuiThread.h
1 // -*- C++ -*-
2 /**
3  * \file InGuiThread.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Peter Kümmel
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #ifndef INGUITHREAD_H
13 #define INGUITHREAD_H
14
15 #include <QMutex>
16 #include <QObject>
17 #include <QWaitCondition>
18
19 #include "support/bind.h"
20 #include "support/functional.h"
21
22 #if QT_VERSION < 0x040400
23 #define Q_EMIT
24 #endif
25
26 namespace lyx {
27 namespace frontend {
28
29
30 class IntoGuiThreadMover : public QObject
31 {
32         Q_OBJECT
33
34 protected:
35
36         IntoGuiThreadMover();
37
38         void callInGuiThread();
39
40 Q_SIGNALS:
41         void triggerFunctionCall();
42
43 private Q_SLOTS:
44         void doFunctionCall();
45
46 private:
47         virtual void synchronousFunctionCall() = 0;
48
49         QWaitCondition condition_;
50         QMutex sync_mutex_;
51 };
52
53
54 template<class R>
55 class InGuiThread : private IntoGuiThreadMover
56 {
57 public:
58
59         InGuiThread() {}
60
61         template<class F>
62         R call(F f)
63         {
64                 func_ = f;
65                 callInGuiThread();
66                 return return_value_;
67         }
68
69         template<class F, class P1>
70         R call(F f, P1& p1)
71         {
72                 return call(lyx::bind(f, lyx::ref(p1)));
73         }
74
75         template<class F, class P1, class P2>
76         R call(F f, P1& p1, P2& p2)
77         {
78                 return call(lyx::bind(f, lyx::ref(p1), lyx::ref(p2)));
79         }
80
81         template<class F, class P1, class P2, class P3>
82         R call(F f, P1& p1, P2& p2, P3& p3)
83         {
84                 return call(lyx::bind(f, lyx::ref(p1), lyx::ref(p2), lyx::ref(p3)));
85         }
86
87         template<class F, class P1, class P2, class P3, class P4>
88         R call(F f, P1& p1, P2& p2, P3& p3, P4& p4)
89         {
90                 return call(lyx::bind(f, lyx::ref(p1), lyx::ref(p2), lyx::ref(p3), lyx::ref(p4)));
91         }
92
93         /*
94           ...
95         */
96
97         template<class F, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
98         R call(F f, P1& p1, P2& p2, P3& p3, P4& p4, P5& p5, P6& p6, P7& p7, P8& p8)
99         {
100                 return call(lyx::bind(f, lyx::ref(p1), lyx::ref(p2), lyx::ref(p3), lyx::ref(p4), 
101                         lyx::ref(p5), lyx::ref(p6), lyx::ref(p7), lyx::ref(p8)));
102         }
103
104 private:
105
106         void synchronousFunctionCall()
107         {
108                 return_value_ = func_();
109         }
110
111 private:
112         R return_value_;
113         function<R()> func_;
114 };
115
116
117 // void specialisation
118 template<>
119 class InGuiThread<void> : private IntoGuiThreadMover
120 {
121 public:
122
123         InGuiThread() {}
124
125         template<class F>
126         void call(F f)
127         {
128                 func_ = f;
129                 callInGuiThread();
130         }
131
132         template<class F, class P1>
133         void call(F f, P1& p1)
134         {
135                 call(lyx::bind(f, lyx::ref(p1)));
136         }
137
138         template<class F, class P1, class P2>
139         void call(F f, P1& p1, P2& p2)
140         {
141                 call(lyx::bind(f, lyx::ref(p1), lyx::ref(p2)));
142         }
143
144         template<class F, class P1, class P2, class P3>
145         void call(F f, P1& p1, P2& p2, P3& p3)
146         {
147                 call(lyx::bind(f, lyx::ref(p1), lyx::ref(p2), lyx::ref(p3)));
148         }
149
150         template<class F, class P1, class P2, class P3, class P4>
151         void call(F f, P1& p1, P2& p2, P3& p3, P4& p4)
152         {
153                 call(lyx::bind(f, lyx::ref(p1), lyx::ref(p2), lyx::ref(p3), lyx::ref(p4)));
154         }
155
156         /*
157           ...
158         */
159
160         template<class F, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
161         void call(F f, P1& p1, P2& p2, P3& p3, P4& p4, P5& p5, P6& p6, P7& p7, P8& p8)
162         {
163                 call(bind(f, lyx::ref(p1), lyx::ref(p2), lyx::ref(p3), lyx::ref(p4), lyx::ref(p5),
164                         lyx::ref(p6), lyx::ref(p7), lyx::ref(p8)));
165         }
166
167 private:
168
169         void synchronousFunctionCall()
170         {
171                 func_();
172         }
173
174 private:
175         function<void()> func_;
176 };
177
178
179 } // namespace frontend
180 } // namespace lyx
181
182 #endif // INGUITHREAD_H