~ubuntu-branches/ubuntu/precise/stellarium/precise

« back to all changes in this revision

Viewing changes to src/stelutils/callback_helpers.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Cédric Delfosse
  • Date: 2008-05-19 21:28:23 UTC
  • mfrom: (3.1.5 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080519212823-m5nfiuntxstxzxj7
Tags: 0.9.1-4
Add libxcursor-dev, libxfixes-dev, libxinerama-dev, libqt4-opengl-dev to
build-deps (Closes: #479906)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//  boost CallbackHelpers.hpp  -------------------------------------------//
 
2
 
 
3
//  (C) Copyright Jesse Jones 2000. Permission to copy, use, modify, sell
 
4
//  and distribute this software is granted provided this copyright
 
5
//  notice appears in all copies. This software is provided "as is" without
 
6
//  express or implied warranty, and with no claim as to its suitability for
 
7
//  any purpose.
 
8
 
 
9
//  Revision History
 
10
//   20 Aug 2003 by Fabien Ch�reau
 
11
//                Changed a ARG1 into ARG2 which was causing weird bugs..!
 
12
//                Removed an implicitly typename warning that occured with gcc 3.2.2
 
13
//                and changed file names for consistency
 
14
//   22 Nov 2000  1) Introduced numbered base classes to get compile time errors with too few arguments
 
15
//              2) Sprinkled the code with typename keywords for gcc.
 
16
//              3) Renamed unused unused_arg.
 
17
//              4) Method ctors no longer require raw pointers.
 
18
//   21 Nov 2000  collapsed callback0, callback1, callback2 into one class
 
19
//              (this was inspired by Doug Gregor's callback classes)
 
20
//   18 Nov 2000  Initial version
 
21
 
 
22
#ifndef BOOST_CALLBACKHELPERS_HPP
 
23
#define BOOST_CALLBACKHELPERS_HPP
 
24
 
 
25
namespace boost {
 
26
namespace details {
 
27
 
 
28
typedef int atomic_int;   // $$$ use something from the thread library here
 
29
 
 
30
 
 
31
// ===============================================================================
 
32
//  struct unused_arg
 
33
// ===============================================================================
 
34
struct unused_arg{};
 
35
 
 
36
 
 
37
// ===============================================================================
 
38
//  class base_call_functor
 
39
// ===============================================================================
 
40
template <typename RETURN_TYPE, typename ARG1, typename ARG2>
 
41
class base_call_functor {
 
42
 
 
43
public:
 
44
   virtual        ~base_call_functor()         {}
 
45
                  base_call_functor()          {mRefCount = 1;}
 
46
 
 
47
         void     AddReference()               {++mRefCount;}
 
48
         void     RemoveReference()            {if (--mRefCount == 0) delete this;}
 
49
                  // $$$ cloning would be a bit safer for functors with mutable state...
 
50
 
 
51
private:
 
52
                  base_call_functor(const base_call_functor& rhs);   // $$$ use non_copyable
 
53
         base_call_functor& operator=(const base_call_functor& rhs);
 
54
private:
 
55
   atomic_int   mRefCount;
 
56
};
 
57
 
 
58
 
 
59
// ===============================================================================
 
60
//  0-arguments
 
61
// ===============================================================================
 
62
template <typename RETURN_TYPE>
 
63
class base_call_functor0 : public base_call_functor<RETURN_TYPE, unused_arg, unused_arg> {
 
64
 
 
65
public:
 
66
   virtual RETURN_TYPE Call() = 0;
 
67
};
 
68
 
 
69
 
 
70
template <typename FUNCTOR, typename RETURN_TYPE>
 
71
class call_functor0 : public base_call_functor0<RETURN_TYPE> {
 
72
 
 
73
public:
 
74
                  call_functor0(FUNCTOR functor)   : mFunctor(functor) {}
 
75
 
 
76
   virtual RETURN_TYPE Call()                      {return mFunctor();}
 
77
 
 
78
private:
 
79
   FUNCTOR      mFunctor;
 
80
};
 
81
 
 
82
 
 
83
// ===============================================================================
 
84
//  1-argument
 
85
// ===============================================================================
 
86
template <typename RETURN_TYPE, typename ARG1>
 
87
class base_call_functor1 : public base_call_functor<RETURN_TYPE, ARG1, unused_arg> {
 
88
 
 
89
public:
 
90
   virtual RETURN_TYPE Call(ARG1 arg1) = 0;
 
91
};
 
92
 
 
93
 
 
94
template <typename FUNCTOR, typename RETURN_TYPE, typename ARG1>
 
95
class call_functor1 : public base_call_functor1<RETURN_TYPE, ARG1> {
 
96
 
 
97
public:
 
98
                  call_functor1(FUNCTOR functor)   : mFunctor(functor) {}
 
99
 
 
100
   virtual RETURN_TYPE Call(ARG1 arg1)             {return mFunctor(arg1);}
 
101
 
 
102
private:
 
103
   FUNCTOR      mFunctor;
 
104
};
 
105
 
 
106
 
 
107
// ===============================================================================
 
108
//  2-arguments
 
109
// ===============================================================================
 
110
template <typename RETURN_TYPE, typename ARG1, typename ARG2>
 
111
class base_call_functor2 : public base_call_functor<RETURN_TYPE, ARG1, ARG2> {
 
112
 
 
113
public:
 
114
   virtual RETURN_TYPE Call(ARG1 arg1, ARG2 arg2) = 0;
 
115
};
 
116
 
 
117
 
 
118
template <typename FUNCTOR, typename RETURN_TYPE, typename ARG1, typename ARG2>
 
119
class call_functor2 : public base_call_functor2<RETURN_TYPE, ARG1, ARG2> {
 
120
 
 
121
public:
 
122
                  call_functor2(FUNCTOR functor)   : mFunctor(functor) {}
 
123
 
 
124
   virtual RETURN_TYPE Call(ARG1 arg1, ARG2 arg2) {return mFunctor(arg1, arg2);}
 
125
 
 
126
private:
 
127
   FUNCTOR      mFunctor;
 
128
};
 
129
 
 
130
// $$$ and call_functor3, call_functor4, etc
 
131
 
 
132
 
 
133
// ===============================================================================
 
134
//  Method Functors
 
135
//    $$$ note that the standard library only suffices for method_functor1
 
136
//    $$$ we can probably replace these with either the binder library or the
 
137
//    $$$ lambda library...
 
138
// ===============================================================================
 
139
template <typename RETURN_TYPE, typename OBJECT, typename METHOD>
 
140
class method_functor0 {
 
141
public:
 
142
                  method_functor0(OBJECT object, METHOD method) : mObject(object), mMethod(method) {}
 
143
 
 
144
         RETURN_TYPE operator()() const      {return (mObject->*mMethod)();}
 
145
private:
 
146
   OBJECT    mObject;
 
147
   METHOD    mMethod;
 
148
};
 
149
 
 
150
template <typename RETURN_TYPE, typename OBJECT, typename METHOD, typename ARG1>
 
151
class method_functor1 {
 
152
public:
 
153
                  method_functor1(OBJECT object, METHOD method) : mObject(object), mMethod(method) {}
 
154
 
 
155
         RETURN_TYPE operator()(ARG1 arg1) const      {return (mObject->*mMethod)(arg1);}
 
156
private:
 
157
   OBJECT    mObject;
 
158
   METHOD    mMethod;
 
159
};
 
160
 
 
161
template <typename RETURN_TYPE, typename OBJECT, typename METHOD, typename ARG1, typename ARG2>
 
162
class method_functor2 {
 
163
public:
 
164
                  method_functor2(OBJECT object, METHOD method) : mObject(object), mMethod(method) {}
 
165
 
 
166
         RETURN_TYPE operator()(ARG1 arg1, ARG2 arg2) const      {return (mObject->*mMethod)(arg1, arg2);}
 
167
private:
 
168
   OBJECT    mObject;
 
169
   METHOD    mMethod;
 
170
};
 
171
 
 
172
 
 
173
// ===============================================================================
 
174
//  struct IF
 
175
// ===============================================================================
 
176
struct SelectThen {
 
177
   template<class Then, class Else>
 
178
    struct Result {
 
179
      typedef Then RET;
 
180
    };
 
181
};
 
182
 
 
183
 
 
184
struct SelectElse {
 
185
   template<class Then, class Else>
 
186
    struct Result {
 
187
       typedef Else RET;
 
188
    };
 
189
};
 
190
 
 
191
 
 
192
template<bool Condition>
 
193
struct Selector {
 
194
   typedef SelectThen RET;
 
195
};
 
196
 
 
197
 
 
198
template<>
 
199
struct Selector<false> {
 
200
   typedef SelectElse RET;
 
201
};
 
202
 
 
203
 
 
204
template<bool Condition, class Then, class Else>
 
205
struct IF {
 
206
   typedef typename Selector<Condition>::RET select;
 
207
   typedef typename boost::details::Selector<Condition>::RET::template Result<Then,Else>::RET RET;
 
208
};
 
209
 
 
210
 
 
211
// ===============================================================================
 
212
//  struct SWITCH
 
213
// ===============================================================================
 
214
const int DEFAULT = -32767;
 
215
 
 
216
const int NilValue = -32768;
 
217
 
 
218
struct NilCase  {
 
219
    enum {tag = NilValue};
 
220
    typedef NilCase RET;
 
221
};
 
222
 
 
223
 
 
224
template <int Tag,class Statement,class Next = NilCase>
 
225
struct CASE {
 
226
       enum {tag = Tag};
 
227
      typedef Statement statement;
 
228
      typedef Next next;
 
229
};
 
230
 
 
231
 
 
232
template <int Tag,class aCase>      // non partial specialization version...
 
233
struct SWITCH {
 
234
   typedef typename aCase::next nextCase;
 
235
      enum {  tag = aCase::tag,               // VC++ 5.0 doesn't operate directly on aCase::value in IF<>
 
236
                      nextTag = nextCase::tag,// Thus we need a little cheat
 
237
                      found = (tag == Tag || tag == DEFAULT)
 
238
               };
 
239
      typedef typename IF<(nextTag == NilValue),
 
240
                              NilCase,
 
241
                              SWITCH<Tag,nextCase> >
 
242
                      ::RET nextSwitch;
 
243
      typedef typename IF<(found != 0),
 
244
                              typename aCase::statement,
 
245
                              typename nextSwitch::RET>
 
246
                      ::RET RET;
 
247
};
 
248
 
 
249
 
 
250
// ===============================================================================
 
251
//  struct generate_base_functor
 
252
// ===============================================================================
 
253
template <typename T>
 
254
struct is_used {
 
255
   enum {RET = 1};
 
256
};
 
257
 
 
258
template <>
 
259
struct is_used<unused_arg> {
 
260
   enum {RET = 0};
 
261
};
 
262
 
 
263
 
 
264
template <typename RETURN_TYPE, typename ARG1, typename ARG2>
 
265
struct generate_base_functor {
 
266
   enum {type = is_used<ARG1>::RET + is_used<ARG2>::RET};
 
267
 
 
268
   typedef base_call_functor0<RETURN_TYPE> f0;
 
269
   typedef base_call_functor1<RETURN_TYPE, ARG1> f1;
 
270
   typedef base_call_functor2<RETURN_TYPE, ARG1, ARG2> f2;
 
271
 
 
272
   typedef typename SWITCH<(type),
 
273
      CASE<0, f0,
 
274
      CASE<1, f1,
 
275
      CASE<2, f2> > > >::RET RET;
 
276
};
 
277
 
 
278
 
 
279
// ===============================================================================
 
280
//  struct generate_functor
 
281
// ===============================================================================
 
282
template <typename FUNCTOR, typename RETURN_TYPE, typename ARG1, typename ARG2>
 
283
struct generate_functor {
 
284
   enum {type = is_used<ARG1>::RET + is_used<ARG2>::RET};
 
285
 
 
286
   typedef call_functor0<FUNCTOR, RETURN_TYPE> f0;
 
287
   typedef call_functor1<FUNCTOR, RETURN_TYPE, ARG1> f1;
 
288
   typedef call_functor2<FUNCTOR, RETURN_TYPE, ARG1, ARG2> f2;
 
289
 
 
290
   typedef typename SWITCH<(type),
 
291
      CASE<0, f0,
 
292
      CASE<1, f1,
 
293
      CASE<2, f2> > > >::RET RET;
 
294
};
 
295
 
 
296
 
 
297
// ===============================================================================
 
298
//  struct generate_method
 
299
// ===============================================================================
 
300
template <typename RETURN_TYPE, typename OBJECT, typename METHOD, typename ARG1, typename ARG2>
 
301
struct generate_method {
 
302
   enum {type = is_used<ARG1>::RET + is_used<ARG2>::RET};
 
303
 
 
304
   typedef method_functor0<RETURN_TYPE, OBJECT, METHOD> f0;
 
305
   typedef method_functor1<RETURN_TYPE, OBJECT, METHOD, ARG1> f1;
 
306
   typedef method_functor2<RETURN_TYPE, OBJECT, METHOD, ARG1, ARG2> f2;
 
307
 
 
308
   typedef typename SWITCH<type,
 
309
      CASE<0, f0,
 
310
      CASE<1, f1,
 
311
      CASE<2, f2> > > >::RET RET;
 
312
};
 
313
 
 
314
 
 
315
}        // namespace details
 
316
}        // namespace boost
 
317
 
 
318
#endif   // BOOST_CALLBACKHELPERS_HPP
 
319