OpenStructure
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
dispatch.hh
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
2 // This file is part of the OpenStructure project <www.openstructure.org>
3 //
4 // Copyright (C) 2008-2011 by the OpenStructure authors
5 // Copyright (C) 2003-2010 by the IPLT authors
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License as published by the Free
9 // Software Foundation; either version 3.0 of the License, or (at your option)
10 // any later version.
11 // This library is distributed in the hope that it will be useful, but WITHOUT
12 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14 // details.
15 //
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with this library; if not, write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 //------------------------------------------------------------------------------
20 
21 /*
22  Author: Ansgar Philippsen
23 */
24 
25 #ifndef IMG_IMAGE_STATE_DISPATCH_HH
26 #define IMG_IMAGE_STATE_DISPATCH_HH
27 
28 #include <ost/message.hh>
29 #include <string>
30 
31 #include <ost/message.hh>
32 
33 #include "image_state_impl.hh"
34 #include "image_state_def.hh"
35 
36 namespace ost { namespace img { namespace image_state {
37 
38 class DLLEXPORT DispatchException: public Error {
39 public:
41  Error(m)
42  {}
43 };
44 
45 template <typename T, class D>
46 class ImageStateImpl;
47 
48 namespace dispatch {
49 
51 // unary RTTI dispatch
52 // used instead of visitor pattern
53 
55 
66 template <template <typename T, class D> class FNC>
68 
69 #define ISI_UNARY_DISPATCH_IP_CALL(TYPE,fnc,isb) \
70  else if(TYPE * is = dynamic_cast<TYPE *>(isb)) fnc(is)
71 
73  if(false);
80  else throw DispatchException("unknown image state in unary_dispatch_ip");
81  }
82 
83 #undef ISI_UNARY_DISPATCH_IP_CALL
84 
85  template <typename T, class D>
87  static FNC<T,D> fnc;
88  fnc(isi);
89  }
90 
91 };
92 
93 
95 
106 template <template <typename T, class D> class FNC>
108 
109 #define ISI_UNARY_DISPATCH_OP_CALL(TYPE,fnc,isb) \
110  else if(const TYPE * is = dynamic_cast<const TYPE *>(isb)) return fnc(is)
111 
113  if(false);
120  else throw DispatchException("unknown image state in unary_dispatch_op");
121  }
122 
123 #undef ISI_UNARY_DISPATCH_OP_CALL
124 
125  template <typename T, class D>
127  static FNC<T,D> fnc;
128  return fnc(isi);
129  }
130 };
131 
133 // binary RTTI dispatch
134 
136 
150 template <template <typename T1, class D1, typename T2, class D2> class FNC>
152 
153 #define ISI_BINARY_DISPATCH_IP_CALL_LEFT(TYPE,fnc,lhs,rhs) \
154  else if(TYPE * is = dynamic_cast<TYPE *>(lhs)) fnc(is,rhs)
155 
156  void operator()(ImageStateBase* lhs, const ImageStateBase* rhs) {
157  if(false);
164  else {
165  throw DispatchException("unknown lhs image state in binary_dispatch_ip");
166  }
167  }
168 
169 #undef ISI_BINARY_DISPATCH_IP_CALL_LEFT
170 
171 #define ISI_BINARY_DISPATCH_IP_CALL_RIGHT(TYPE,fnc,lhs,rhs) \
172  else if(const TYPE * is = dynamic_cast<const TYPE *>(rhs)) fnc(lhs,is)
173 
174  template <typename T1, class D1>
175  void left(ImageStateImpl<T1,D1>* lhs, const ImageStateBase* rhs) {
176  if(false);
183  else {
184  throw DispatchException("unknown rhs image state in binary_dispatch_ip");
185  }
186  }
187 
188 #undef ISI_BINARY_DISPATCH_IP_CALL_RIGHT
189 
190  template <typename T1, class D1, typename T2, class D2>
192  static FNC<T1,D1,T2,D2> fnc;
193  fnc(lhs,rhs);
194  }
195 };
196 
197 
198 
200 
213 template <template <typename T1, class D1, typename T2, class D2> class FNC>
215 
216 #define ISI_BINARY_DISPATCH_OP_CALL_LEFT(TYPE,fnc,lhs,rhs) \
217  else if(const TYPE * is = dynamic_cast<const TYPE *>(lhs)) return fnc(is,rhs)
218 
220  if(false);
227  else throw DispatchException("unknown lhs image state in binary_dispatch_op");
228  }
229 
230 #undef ISI_BINARY_DISPATCH_OP_CALL_LEFT
231 
232 #define ISI_BINARY_DISPATCH_OP_CALL_RIGHT(TYPE,fnc,lhs,rhs) \
233  else if(const TYPE * is = dynamic_cast<const TYPE *>(rhs)) return fnc(lhs,is)
234 
235  template <typename T1, class D1>
237  if(false);
244  else throw DispatchException("unknown rhs image state in binary_dispatch_op");
245  }
246 
247 #undef ISI_BINARY_DISPATCH_OP_CALL_RIGHT
248 
249  template <typename T1, class D1, typename T2, class D2>
251  static FNC<T1,D1,T2,D2> fnc;
252  return fnc(lhs,rhs);
253  }
254 
255 
256 };
257 
258 
259 
260 /*
261  application of dispatch code
262 
263  template<typename T1, class D1, typename T2, class D2>
264  struct fnc_add_ip {
265  void operator()(ImageStateImpl<T1,D1>* lhs, const ImageStateImpl<T2,D2>* rhs);
266  };
267 
268  // specialization possible, such as
269  template<typename T1, typename T2, class D>
270  struct fnc_add_ip<T1,D,T2,D> {
271  void operator()(ImageStateImpl<T1,D>* lhs, const ImageStateImpl<T2,D>* rhs)
272  {
273  // same domain!
274  }
275  };
276 
277  typedef binary_dispatch_ip<add_ip> dispatch_add_ip;
278 
279  void f()
280  {
281  ImageStateBase *is1,*is2;
282  dispatch_add_ip(is1,is2);
283  }
284 
285 */
286 
287 }}}} // ns
288 
289 #endif