]> git.lyx.org Git - lyx.git/blob - sigc++/macros/slot.h.m4
visual support for \displaystyle
[lyx.git] / sigc++ / macros / slot.h.m4
1 dnl 
2 dnl Abstract Slot templates
3 dnl 
4 dnl  Copyright (C) 1998 Karl Nelson <kenelson@ece.ucdavis.edu>
5 dnl 
6 dnl  This library is free software; you can redistribute it and/or
7 dnl  modify it under the terms of the GNU Library General Public
8 dnl  License as published by the Free Software Foundation; either
9 dnl  version 2 of the License, or (at your option) any later version.
10 dnl 
11 dnl  This library is distributed in the hope that it will be useful,
12 dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 dnl  Library General Public License for more details.
15 dnl 
16 dnl  You should have received a copy of the GNU Library General Public
17 dnl  License along with this library; if not, write to the Free
18 dnl  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 dnl 
20 // -*- c++ -*-
21 dnl Ignore the next line
22 /* This is a generated file, do not edit.  Generated from __file__ */
23 include(template.macros.m4)
24
25 #ifndef __header__
26 #define __header__
27
28 /*
29
30 This file just gives the basic definition of Slots. 
31
32 Callback# is the 4 byte data necessary for representing all
33 callback types.
34
35 CallData is a specific interpretation of the Callback data.
36
37 Slot_ is a pimple on SlotData containing an Object for
38 holding its referencees, a Dependency that removes the slot
39 when its caller or receiver die, and a Callback.
40
41 Slot is a handle to a Slot_.
42
43 */
44
45 #include <sigc++/sigc++config.h>
46 #include <sigc++/type.h>
47 #include <sigc++/object.h>
48 #include <sigc++/handle.h>
49
50 #ifdef SIGC_CXX_NAMESPACES
51 namespace SigC
52 {
53 #endif
54
55 // Base node for a polymorphic list of "extra" data needed
56 // by various slots. 
57 struct LIBSIGC_API SlotNode
58   {
59    void *next_;
60    SlotNode();
61    virtual ~SlotNode()=0;
62   };
63
64 struct LIBSIGC_API SlotIterator_
65   {
66         typedef SlotNode NodeType;
67    typedef SlotIterator_ Iterator;
68    NodeType *node_;
69
70    NodeType* node()             {return node_;}
71    const NodeType* node() const {return node_;}
72
73    NodeType& operator*()
74      {return *node_;
75      }
76    const NodeType& operator*() const
77      {return *node_;
78      }
79
80    bool operator==(const Iterator& i) const
81      {return node_==i.node_;
82      }
83    bool operator!=(const Iterator& i) const
84      {return node_!=i.node_;
85      }
86
87    Iterator& operator++()
88      {
89       if (node_)
90         node_=(NodeType*)node_->next_;
91       return *this;
92      }
93
94    Iterator operator++(int)
95      {Iterator tmp=*this;
96       ++*this;
97       return tmp;
98      }
99
100    Iterator& operator= (const Iterator& i)
101      {
102       node_=i.node_;
103       return *this;
104      }
105
106    SlotIterator_():node_(0) {}
107    SlotIterator_(NodeType *node):node_(node) {}
108   };
109
110 // This is a list for storing internal data for slots
111 struct LIBSIGC_API SlotList_
112   {
113    typedef SlotNode NodeType;
114    typedef SlotIterator_ Iterator;
115    NodeType* head_;
116
117    Iterator begin()             {return ((NodeType*)head_);}
118    Iterator end()               {return Iterator();}
119    const Iterator begin() const {return ((NodeType*)head_);}
120    const Iterator end()   const {return Iterator();}
121
122    // this is best used at the begining of list.
123    Iterator insert_direct(Iterator pos,NodeType *n);
124
125    void clear();
126    bool empty() const {return head_==0;}
127
128    SlotList_():head_(0)
129      {}
130    ~SlotList_()
131      {clear();}
132
133    private:
134      SlotList_(const SlotList_&);
135   };
136
137
138 struct SlotData;
139
140 // SlotDependent is an internal of SlotData used to unreference the
141 // Slot when either the sender or receiver have gone away
142 struct LIBSIGC_API SlotDependent:public ScopeNode
143   {
144    struct LIBSIGC_API Dep: public ScopeNode
145      {
146       SlotData *parent;
147       virtual void erase();
148       Dep() {}
149       virtual ~Dep();
150      } dep;
151
152    ScopeNode* receiver() {return &dep;}
153    ScopeNode* sender()   {return this;}
154    SlotData*  parent()   {return dep.parent;}
155
156    bool connected()
157      {return (next_!=this);}
158
159    virtual void erase();
160
161    void set_parent(SlotData *s)
162      {dep.parent=s;}
163
164    SlotDependent(SlotData &s)
165      {dep.parent=&s;}
166
167    SlotDependent()
168      {}
169
170    virtual ~SlotDependent();
171   };
172
173 // common data to all callbacks.  
174 struct Callback_
175   {
176    // callback function
177    void* (*func_)(void*);
178
179    struct O;
180    struct C1
181      {
182       void* (*f1)(void*);
183      };
184    struct C2
185      {
186       O* o;
187       void (O::*v)(void);
188      };
189
190    // Object pointer or function pointer
191    union {C1 a1; C2 a2;};
192   };
193
194 // All slots have the same base 
195 struct LIBSIGC_API SlotData:public ObjectScoped
196   {
197    typedef SlotList_ List;
198
199    SlotDependent dep_;
200
201    ScopeNode* receiver() {return dep_.receiver();}
202    ScopeNode* sender()   {return dep_.sender();}
203
204    // Called from signals to tell slot object it is connected
205    // invalidates list and sets weak reference
206    void connect();
207
208    List list_;
209    Callback_ data_;
210
211    Callback_& callback() {return data_;}
212
213    SlotData()
214      {dep_.set_parent(this);}
215    virtual ~SlotData();
216   };
217
218
219 typedef Scopes::Extend SlotExtend;
220 #ifdef LIBSIGC_MSC
221 #pragma warning(disable: 4231)
222 LIBSIGC_TMPL template class LIBSIGC_API Handle<SlotData,SlotExtend>;
223 #endif
224 class LIBSIGC_API Connection:protected Handle<SlotData,SlotExtend>
225   {
226    typedef Handle<SlotData,SlotExtend> Base;
227    public:
228      // hides virtual method
229      void disconnect() {if (obj()) obj()->invalid();}
230      bool connected() {return Base::connected ();}
231
232      Connection():Base() {}
233      Connection(SlotData *s):Base(s) {}
234      Connection(const Connection& s):Base(s) {}
235   };
236
237 // possible casts of Callback
238 template <class C,class F>
239 struct CallDataFunc
240   {
241    C callback;
242    F func;
243   };
244
245 template <class C,class O>
246 struct CallDataObj2
247   {
248    C callback;
249    O *obj;
250   };
251
252 template <class C,class O,class F>
253 struct CallDataObj3
254   { 
255    C   callback;
256    O*  obj;
257    F   func;
258   };
259
260 // from Abstract_Slots we build abstract slots
261 // with various lengths of arguments
262 //   A slot is not concrete til it has a call
263
264 dnl
265 dnl SLOT([P1,P2,...])
266 dnl
267 define([SLOT],[dnl
268 /****************************************************************
269 ***** Abstract Slot NUM($1)
270 ****************************************************************/
271 SLOT_IMPL(R,[$1])
272
273 #ifndef SIGC_CXX_VOID_RETURN
274 #ifdef SIGC_CXX_PARTIAL_SPEC
275 SLOT_IMPL(void,[$1])
276 #endif
277 #endif
278
279 ])dnl  end SLOT
280
281 dnl
282 dnl SLOT_IMPL(R,[P1,P2,...])
283 dnl
284 define([SLOT_IMPL],[dnl
285 LINE(]__line__[)dnl
286
287 ifelse($1,void,[dnl
288 template <ARG_CLASS($2)>
289 struct [Callback]NUM($2)<LIST(void,1,ARG_TYPE($2),[$2])>:public Callback_
290   {
291    typedef void RType;
292    typedef RType (*Func)(LIST([void*],1,ARG_TYPE($2),[$2]));
293    inline RType call(ARG_REF($2))
294      {((Func)(func_))(LIST([(void*)this],1,ARG_NAME($2),[$2]));}
295    inline RType operator()(ARG_REF($2))
296      {((Func)(func_))(LIST([(void*)this],1,ARG_NAME($2),[$2]));}
297   };
298 ],[dnl
299 template <LIST(class R,1,ARG_CLASS($2),[$2])>
300 struct [Callback]NUM($2):public Callback_
301   {
302 #ifdef SIGC_CXX_PARTIAL_SPEC
303    typedef R RType;
304 #else
305    typedef Trait<R>::type RType;
306 #endif
307    typedef RType (*Func)(LIST([void*],1,ARG_TYPE($2),[$2]));
308    inline RType call(ARG_REF($2))
309      {return ((Func)(func_))(LIST([(void*)this],1,ARG_NAME($2),[$2]));}
310    inline RType operator()(ARG_REF($2))
311      {return ((Func)(func_))(LIST([(void*)this],1,ARG_NAME($2),[$2]));}
312   };
313 ])dnl
314
315 ifelse($1,void,[dnl
316 template <ARG_CLASS($2)>
317 class __SLOT__(void,[$2])
318 ],[dnl
319 template <LIST(class R,1,ARG_CLASS($2),[$2])>
320 class [Slot]NUM($2)
321 ])dnl
322    :public Handle<SlotData,SlotExtend>
323   {
324    public:
325      typedef Handle<SlotData,SlotExtend> Base;
326      typedef [Callback]NUM($2)<LIST($1,1,ARG_TYPE($2),[$2])> Callback;
327      typedef ifelse([$1$2],void,,typename) Callback::RType RType;
328      typedef RType (*Func)(LIST([void*],1,ARG_TYPE($2),[$2]));
329
330      SlotData* data()     const {return (SlotData*)(scope_.object());}
331
332      [Slot]NUM($2)() {}
333      [Slot]NUM($2)(SlotData *s):Base(s)    {}
334      [Slot]NUM($2)(const [Slot]NUM($2)& s):Base(s.obj()) {}
335
336      inline RType call(ARG_REF($2)) 
337         {
338          if (connected()) 
339 ifelse($1,void,[
340            ((Callback&)(data()->callback())).call(ARG_NAME($2));
341 ],[dnl
342            return ((Callback&)(data()->callback())).call(ARG_NAME($2));
343          return RType();
344 ])dnl
345         }
346      inline RType operator()(ARG_REF($2)) 
347         {
348          if (connected()) 
349 ifelse($1,void,[
350            ((Callback&)(data()->callback())).call(ARG_NAME($2));
351 ],[dnl
352            return ((Callback&)(data()->callback())).call(ARG_NAME($2));
353          return RType();
354 ])dnl
355         }
356   };
357 ])dnl  end SLOT_IMPL
358
359 SLOT(ARGS(P,0))
360 SLOT(ARGS(P,1))
361 SLOT(ARGS(P,2))
362 SLOT(ARGS(P,3))
363 SLOT(ARGS(P,4))
364 SLOT(ARGS(P,5))
365
366 #ifdef SIGC_CXX_NAMESPACES
367 } // namespace
368 #endif
369
370 #endif // __header__