VTK
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 
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  protected:
112  private:
113  FunctorImpl& operator =(const FunctorImpl&) VTK_DELETE_FUNCTION;
114 };
115 
117 // Impl functor that calls a user functor
119 template <class ParentFunctor,typename Fun>
120 class FunctorHandler: public ParentFunctor::Impl
121 {
122  typedef typename ParentFunctor::Impl Base;
123 public:
124  typedef typename Base::ResultType ResultType;
125  typedef typename Base::Parm1 Parm1;
126 
127  FunctorHandler(Fun& fun) : f_(fun) {}
128  virtual ~FunctorHandler() {}
129 
130  ResultType operator()(Parm1& p1)
131  { return f_(p1); }
132  virtual FunctorHandler* DoClone() const { return new FunctorHandler(*this); }
133 
134 private:
135  Fun f_;
136  FunctorHandler(const FunctorHandler &b) : ParentFunctor::Impl(b), f_(b.f_) {}
137  FunctorHandler& operator =(const FunctorHandler& b) VTK_DELETE_FUNCTION;
138 };
139 
140 
142 // Functor wrapper class
144 template <typename R,typename Parm1>
145 class Functor
146 {
147 public:
149  typedef R ResultType;
150 
151 #if defined(VTK_HAS_STD_UNIQUE_PTR)
152  Functor() : spImpl_()
153 #else
154  Functor() : spImpl_(0)
155 #endif
156  {}
157 
158  Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get()))
159  {}
160 
161  template <typename Fun>
162  Functor(Fun fun)
163  : spImpl_(new FunctorHandler<Functor,Fun>(fun))
164  {}
165 
166  Functor& operator=(const Functor& rhs)
167  {
168  Functor copy(rhs);
169 #if defined(VTK_HAS_STD_UNIQUE_PTR)
170  spImpl_.swap(copy.spImpl_);
171 #else
172  // swap auto_ptrs by hand
173  Impl* p = spImpl_.release();
174  spImpl_.reset(copy.spImpl_.release());
175  copy.spImpl_.reset(p);
176 #endif
177  return *this;
178  }
179 
180 
181  ResultType operator()(Parm1& p1)
182  { return (*spImpl_)(p1); }
183 private:
184 #if defined(VTK_HAS_STD_UNIQUE_PTR)
185  std::unique_ptr<Impl> spImpl_;
186 #else
187  std::auto_ptr<Impl> spImpl_;
188 #endif
189 
190 };
191 
192 }
193 
194 
196 {
197 
199 // Dispatch helper
201 template <class BaseLhs, class BaseRhs,
202  class SomeLhs, class SomeRhs,
203  typename RT,
204  class CastLhs, class CastRhs,
205  class Fun>
207 {
208  Fun& fun_;
209 public:
210  typedef RT ResultType;
212  FunctorRefDispatcherHelper(Fun& fun) : fun_(fun) {}
213 
214  ResultType operator()(BaseLhs& lhs, BaseRhs& rhs)
215  {
216  return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
217  }
218 private:
220 };
221 
222 template <class BaseLhs, class BaseRhs,
223  class SomeLhs, class SomeRhs,
224  typename RT,
225  class CastLhs, class CastRhs,
226  class Fun>
228 {
229  Fun fun_;
230 public:
231  typedef RT ResultType;
233  FunctorDoubleDispatcherHelper(Fun fun) : fun_(fun) {}
234 
235  ResultType operator()(BaseLhs& lhs, BaseRhs& rhs)
236  {
237  return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
238  }
239 
240 };
241 
243 // Parent class for all FunctorImpl, helps hide functor template args
245 template <typename R, typename P1, typename P2>
247  public:
248  typedef R ResultType;
249  typedef P1 Parm1;
250  typedef P2 Parm2;
251 
252  virtual ~FunctorImpl() {}
253  virtual R operator()(P1&,P2&) = 0;
254  virtual FunctorImpl* DoClone() const = 0;
255 
256  template <class U>
257  static U* Clone(U* pObj)
258  {
259  if (!pObj) return 0;
260  U* pClone = static_cast<U*>(pObj->DoClone());
261  assert(typeid(*pClone) == typeid(*pObj));
262  return pClone;
263  }
264  protected:
267  private:
268  FunctorImpl& operator =(const FunctorImpl&) VTK_DELETE_FUNCTION;
269 };
270 
272 // Impl functor that calls a user functor
274 template <class ParentFunctor,typename Fun>
275 class FunctorHandler: public ParentFunctor::Impl
276 {
277  typedef typename ParentFunctor::Impl Base;
278 public:
279  typedef typename Base::ResultType ResultType;
280  typedef typename Base::Parm1 Parm1;
281  typedef typename Base::Parm2 Parm2;
282 
283  FunctorHandler(const Fun& fun) : f_(fun) {}
284  virtual ~FunctorHandler() {}
285 
286  ResultType operator()(Parm1& p1,Parm2& p2)
287  { return f_(p1,p2); }
288 
289  virtual FunctorHandler* DoClone() const { return new FunctorHandler(*this); }
290 
291 private:
292  Fun f_;
293  FunctorHandler(const FunctorHandler &b) : ParentFunctor::Impl(b), f_(b.f_) {}
294  FunctorHandler& operator =(const FunctorHandler& b) VTK_DELETE_FUNCTION;
295 };
296 
298 // Functor wrapper class
300 template <typename R,typename Parm1, typename Parm2>
301 class Functor
302 {
303 public:
305  typedef R ResultType;
306 
307 #if defined(VTK_HAS_STD_UNIQUE_PTR)
308  Functor() : spImpl_()
309 #else
310  Functor() : spImpl_(0)
311 #endif
312  {}
313 
314  Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get()))
315  {}
316 
317  template <typename Fun>
318  Functor(const Fun& fun)
319  : spImpl_(new FunctorHandler<Functor,Fun>(fun))
320  {}
321 
322  Functor& operator=(const Functor& rhs)
323  {
324  Functor copy(rhs);
325 #if defined(VTK_HAS_STD_UNIQUE_PTR)
326  spImpl_.swap(copy.spImpl_);
327 #else // swap auto_ptrs by hand
328  Impl* p = spImpl_.release();
329  spImpl_.reset(copy.spImpl_.release());
330  copy.spImpl_.reset(p);
331 #endif
332  return *this;
333  }
334 
335  ResultType operator()(Parm1& p1,Parm2& p2)
336  { return (*spImpl_)(p1,p2); }
337 private:
338 #if defined(VTK_HAS_STD_UNIQUE_PTR)
339  std::unique_ptr<Impl> spImpl_;
340 #else
341  std::auto_ptr<Impl> spImpl_;
342 #endif
343 };
344 }
345 
347 {
348 
349 template <class To, class From>
351 {
352  static To& Cast(From& obj)
353  {
354  return dynamic_cast<To&>(obj);
355  }
356 
357  static To* Cast(From* obj)
358  {
359  return dynamic_cast<To*>(obj);
360  }
361 };
362 
363 template <class To, class From>
364 struct vtkCaster
365 {
366  static To& Cast(From& obj)
367  {
368  return *(To::SafeDownCast(&obj));
369  }
370 
371  static To* Cast(From* obj)
372  {
373  return To::SafeDownCast(obj);
374  }
375 };
376 
377 class TypeInfo
378 {
379 public:
380  // Constructors
381  TypeInfo(); // needed for containers
382  TypeInfo(const std::type_info&); // non-explicit
383 
384  // Access for the wrapped std::type_info
385  const std::type_info& Get() const;
386  // Compatibility functions
387  bool before(const TypeInfo& rhs) const;
388  const char* name() const;
389 
390 private:
391  const std::type_info* pInfo_;
392 };
393 
394 // Implementation
395 
396 inline TypeInfo::TypeInfo()
397 {
398  class Nil {};
399  pInfo_ = &typeid(Nil);
400  assert(pInfo_);
401 }
402 
403 inline TypeInfo::TypeInfo(const std::type_info& ti)
404  : pInfo_(&ti)
405  { assert(pInfo_); }
406 
407 inline bool TypeInfo::before(const TypeInfo& rhs) const
408 {
409  assert(pInfo_);
410  // type_info::before return type is int in some VC libraries
411  return pInfo_->before(*rhs.pInfo_) != 0;
412 }
413 
414 inline const std::type_info& TypeInfo::Get() const
415 {
416  assert(pInfo_);
417  return *pInfo_;
418 }
419 
420 inline const char* TypeInfo::name() const
421 {
422  assert(pInfo_);
423  return pInfo_->name();
424 }
425 
426 // Comparison operators
427 
428 inline bool operator==(const TypeInfo& lhs, const TypeInfo& rhs)
429 // type_info::operator== return type is int in some VC libraries
430  { return (lhs.Get() == rhs.Get()) != 0; }
431 
432 inline bool operator<(const TypeInfo& lhs, const TypeInfo& rhs)
433  { return lhs.before(rhs); }
434 
435 inline bool operator!=(const TypeInfo& lhs, const TypeInfo& rhs)
436  { return !(lhs == rhs); }
437 
438 inline bool operator>(const TypeInfo& lhs, const TypeInfo& rhs)
439  { return rhs < lhs; }
440 
441 inline bool operator<=(const TypeInfo& lhs, const TypeInfo& rhs)
442  { return !(lhs > rhs); }
443 
444 inline bool operator>=(const TypeInfo& lhs, const TypeInfo& rhs)
445  { return !(lhs < rhs); }
446 
447 }
448 
449 #endif // vtkDispatcherPrivate_h
450 // 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)
FunctorImpl< R, Parm1, Parm2 > Impl
FunctorDoubleDispatcherHelper(const FunctorDoubleDispatcherHelper &rhs)
virtual FunctorImpl * DoClone() const =0
#define P1
Functor & operator=(const Functor &rhs)
else
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)
bool operator<=(const TypeInfo &lhs, const TypeInfo &rhs)
ResultType operator()(Parm1 &p1, Parm2 &p2)
FunctorDispatcherHelper(const FunctorDispatcherHelper &rhs)