VTK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
vtkDispatcher_Private.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkDispatcher.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
15 
17 // The Loki Library
18 // Copyright (c) 2001 by Andrei Alexandrescu
19 // This code accompanies the book:
20 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
21 // Patterns Applied". Copyright (c) 2001. Addison-Wesley.
22 // Permission to use, copy, modify, distribute and sell this software for any
23 // purpose is hereby granted without fee, provided that the above copyright
24 // notice appear in all copies and that both that copyright notice and this
25 // permission notice appear in supporting documentation.
26 // The author or Addison-Wesley Longman make no representations about the
27 // suitability of this software for any purpose. It is provided "as is"
28 // without express or implied warranty.
30 #ifndef __vtkDispatcher_Private_h
31 #define __vtkDispatcher_Private_h
32 
33 #include <typeinfo>
34 #include <cassert>
35 #include <memory>
36 
37 namespace vtkDispatcherPrivate
38 {
40 // Dispatch helper for reference functors
42 template <class BaseLhs,
43  class SomeLhs,
44  typename RT,
45  class CastLhs,
46  class Fun>
48 {
49  Fun& fun_;
50 public:
51  typedef RT ResultType;
52 
54  FunctorRefDispatcherHelper(Fun& f) : fun_(f) {}
55 
56  ResultType operator()(BaseLhs& lhs)
57  {
58  return fun_(CastLhs::Cast(lhs));
59  }
60 private:
62 };
63 
65 // Dispatch helper
67 template <class BaseLhs,
68  class SomeLhs,
69  typename RT,
70  class CastLhs,
71  class Fun>
73 {
74  Fun fun_;
75 public:
76  typedef RT ResultType;
77 
78  FunctorDispatcherHelper(const FunctorDispatcherHelper& rhs) : fun_(rhs.fun_) {}
79  FunctorDispatcherHelper(Fun fun) : fun_(fun) {}
80 
81  ResultType operator()(BaseLhs& lhs)
82  {
83  return fun_(CastLhs::Cast(lhs));
84  }
85 };
86 
87 
89 // Parent class for all FunctorImpl, helps hide functor template args
91 template <typename R, typename P1>
93  public:
94  typedef R ResultType;
95  typedef P1 Parm1;
96 
97  virtual ~FunctorImpl() {};
98  virtual R operator()(P1&) = 0;
99  virtual FunctorImpl* DoClone() const = 0;
100 
101  template <class U>
102  static U* Clone(U* pObj)
103  {
104  if (!pObj) return 0;
105  U* pClone = static_cast<U*>(pObj->DoClone());
106  assert(typeid(*pClone) == typeid(*pObj));
107  return pClone;
108  }
109 };
110 
112 // Impl functor that calls a user functor
114 template <class ParentFunctor,typename Fun>
115 class FunctorHandler: public ParentFunctor::Impl
116 {
117  typedef typename ParentFunctor::Impl Base;
118 public:
119  typedef typename Base::ResultType ResultType;
120  typedef typename Base::Parm1 Parm1;
121 
122  FunctorHandler(Fun& fun) : f_(fun) {}
123  virtual ~FunctorHandler(){}
124 
126  { return f_(p1); }
127  virtual FunctorHandler* DoClone() const { return new FunctorHandler(*this); }
128 
129 private:
130  Fun f_;
131  FunctorHandler& operator =(const FunctorHandler& b);
132 };
133 
134 
136 // Functor wrapper class
138 template <typename R,typename Parm1>
139 class Functor
140 {
141 public:
143  typedef R ResultType;
144 
145  Functor() : spImpl_(0)
146  {}
147 
148  Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get()))
149  {}
150 
151  template <typename Fun>
152  Functor(Fun fun)
153  : spImpl_(new FunctorHandler<Functor,Fun>(fun))
154  {}
155 
156  Functor& operator=(const Functor& rhs)
157  {
158  Functor copy(rhs);
159  // swap auto_ptrs by hand
160  Impl* p = spImpl_.release();
161  spImpl_.reset(copy.spImpl_.release());
162  copy.spImpl_.reset(p);
163  return *this;
164  }
165 
166 
168  { return (*spImpl_)(p1); }
169 private:
170  std::auto_ptr<Impl> spImpl_;
171 };
172 
173 }
174 
175 
176 namespace vtkDoubleDispatcherPrivate
177 {
178 
180 // Dispatch helper
182 template <class BaseLhs, class BaseRhs,
183  class SomeLhs, class SomeRhs,
184  typename RT,
185  class CastLhs, class CastRhs,
186  class Fun>
188 {
189  Fun& fun_;
190 public:
191  typedef RT ResultType;
193  FunctorRefDispatcherHelper(Fun& fun) : fun_(fun) {}
194 
195  ResultType operator()(BaseLhs& lhs, BaseRhs& rhs)
196  {
197  return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
198  }
199 private:
201 };
202 
203 template <class BaseLhs, class BaseRhs,
204  class SomeLhs, class SomeRhs,
205  typename RT,
206  class CastLhs, class CastRhs,
207  class Fun>
209 {
210  Fun fun_;
211 public:
212  typedef RT ResultType;
214  FunctorDoubleDispatcherHelper(Fun fun) : fun_(fun) {}
215 
216  ResultType operator()(BaseLhs& lhs, BaseRhs& rhs)
217  {
218  return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
219  }
220 
221 };
222 
224 // Parent class for all FunctorImpl, helps hide functor template args
226 template <typename R, typename P1, typename P2>
228  public:
229  typedef R ResultType;
230  typedef P1 Parm1;
231  typedef P2 Parm2;
232 
233  virtual ~FunctorImpl() {};
234  virtual R operator()(P1&,P2&) = 0;
235  virtual FunctorImpl* DoClone() const = 0;
236 
237  template <class U>
238  static U* Clone(U* pObj)
239  {
240  if (!pObj) return 0;
241  U* pClone = static_cast<U*>(pObj->DoClone());
242  assert(typeid(*pClone) == typeid(*pObj));
243  return pClone;
244  }
245 };
246 
248 // Impl functor that calls a user functor
250 template <class ParentFunctor,typename Fun>
251 class FunctorHandler: public ParentFunctor::Impl
252 {
253  typedef typename ParentFunctor::Impl Base;
254 public:
255  typedef typename Base::ResultType ResultType;
256  typedef typename Base::Parm1 Parm1;
257  typedef typename Base::Parm2 Parm2;
258 
259  FunctorHandler(const Fun& fun) : f_(fun) {}
260  virtual ~FunctorHandler(){}
261 
263  { return f_(p1,p2); }
264 
265  virtual FunctorHandler* DoClone() const { return new FunctorHandler(*this); }
266 
267 private:
268  Fun f_;
269  FunctorHandler& operator =(const FunctorHandler& b);
270 };
271 
273 // Functor wrapper class
275 template <typename R,typename Parm1, typename Parm2>
276 class Functor
277 {
278 public:
280  typedef R ResultType;
281 
282  Functor() : spImpl_(0)
283  {}
284 
285  Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get()))
286  {}
287 
288  template <typename Fun>
289  Functor(const Fun& fun)
290  : spImpl_(new FunctorHandler<Functor,Fun>(fun))
291  {}
292 
293  Functor& operator=(const Functor& rhs)
294  {
295  Functor copy(rhs);
296  // swap auto_ptrs by hand
297  Impl* p = spImpl_.release();
298  spImpl_.reset(copy.spImpl_.release());
299  copy.spImpl_.reset(p);
300  return *this;
301  }
302 
303  ResultType operator()(Parm1& p1,Parm2& p2)
304  { return (*spImpl_)(p1,p2); }
305 private:
306  std::auto_ptr<Impl> spImpl_;
307 };
308 }
309 
310 namespace vtkDispatcherCommon
311 {
312 
313 template <class To, class From>
315 {
316  static To& Cast(From& obj)
317  {
318  return dynamic_cast<To&>(obj);
319  }
320 
321  static To* Cast(From* obj)
322  {
323  return dynamic_cast<To*>(obj);
324  }
325 };
326 
327 template <class To, class From>
328 struct vtkCaster
329 {
330  static To& Cast(From& obj)
331  {
332  return *(To::SafeDownCast(&obj));
333  }
334 
335  static To* Cast(From* obj)
336  {
337  return To::SafeDownCast(obj);
338  }
339 };
340 
341 class TypeInfo
342 {
343 public:
344  // Constructors
345  TypeInfo(); // needed for containers
346  TypeInfo(const std::type_info&); // non-explicit
347 
348  // Access for the wrapped std::type_info
349  const std::type_info& Get() const;
350  // Compatibility functions
351  bool before(const TypeInfo& rhs) const;
352  const char* name() const;
353 
354 private:
355  const std::type_info* pInfo_;
356 };
357 
358 // Implementation
359 
361  {
362  class Nil {};
363  pInfo_ = &typeid(Nil);
364  assert(pInfo_);
365  }
366 
367 inline TypeInfo::TypeInfo(const std::type_info& ti)
368  : pInfo_(&ti)
369  { assert(pInfo_); }
370 
371 inline bool TypeInfo::before(const TypeInfo& rhs) const
372  {
373  assert(pInfo_);
374  // type_info::before return type is int in some VC libraries
375  return pInfo_->before(*rhs.pInfo_) != 0;
376  }
377 
378 inline const std::type_info& TypeInfo::Get() const
379  {
380  assert(pInfo_);
381  return *pInfo_;
382  }
383 
384 inline const char* TypeInfo::name() const
385  {
386  assert(pInfo_);
387  return pInfo_->name();
388  }
389 
390 // Comparison operators
391 
392 inline bool operator==(const TypeInfo& lhs, const TypeInfo& rhs)
393 // type_info::operator== return type is int in some VC libraries
394  { return (lhs.Get() == rhs.Get()) != 0; }
395 
396 inline bool operator<(const TypeInfo& lhs, const TypeInfo& rhs)
397  { return lhs.before(rhs); }
398 
399 inline bool operator!=(const TypeInfo& lhs, const TypeInfo& rhs)
400  { return !(lhs == rhs); }
401 
402 inline bool operator>(const TypeInfo& lhs, const TypeInfo& rhs)
403  { return rhs < lhs; }
404 
405 inline bool operator<=(const TypeInfo& lhs, const TypeInfo& rhs)
406  { return !(lhs > rhs); }
407 
408 inline bool operator>=(const TypeInfo& lhs, const TypeInfo& rhs)
409  { return !(lhs < rhs); }
410 
411 }
412 
413 #endif // __vtkDispatcherPrivate_h
414 // VTK-HeaderTest-Exclude: vtkDispatcher_Private.h
FunctorRefDispatcherHelper(const FunctorRefDispatcherHelper &rhs)
bool before(const TypeInfo &rhs) const
bool operator<(const TypeInfo &lhs, const TypeInfo &rhs)
bool operator==(const TypeInfo &lhs, const TypeInfo &rhs)
FunctorRefDispatcherHelper(const FunctorRefDispatcherHelper &rhs)
double get(vtkDataArray *const &arr, vtkIdType key)
const std::type_info & Get() const
virtual FunctorHandler * DoClone() const
bool operator>(const TypeInfo &lhs, const TypeInfo &rhs)
bool operator>=(const TypeInfo &lhs, const TypeInfo &rhs)
virtual R operator()(P1 &, P2 &)=0
FunctorImpl< R, Parm1, Parm2 > Impl
FunctorDoubleDispatcherHelper(const FunctorDoubleDispatcherHelper &rhs)
virtual FunctorImpl * DoClone() const =0
#define P1
Functor & operator=(const Functor &rhs)
ResultType operator()(Parm1 &p1, Parm2 &p2)
#define P2
virtual FunctorHandler * DoClone() const
Functor & operator=(const Functor &rhs)
bool operator!=(const TypeInfo &lhs, const TypeInfo &rhs)
virtual FunctorImpl * DoClone() const =0
bool operator<=(const TypeInfo &lhs, const TypeInfo &rhs)
ResultType operator()(Parm1 &p1, Parm2 &p2)
FunctorDispatcherHelper(const FunctorDispatcherHelper &rhs)