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