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 #ifndef __VTK_WRAP__
33 
34 #include <typeinfo>
35 #include <cassert>
36 #include <memory>
37 
39 {
41 // Dispatch helper for reference functors
43 template <class BaseLhs,
44  class SomeLhs,
45  typename RT,
46  class CastLhs,
47  class Fun>
49 {
50  Fun& fun_;
51 public:
52  typedef RT ResultType;
53 
55  FunctorRefDispatcherHelper(Fun& f) : fun_(f) {}
56 
57  ResultType operator()(BaseLhs& lhs)
58  {
59  return fun_(CastLhs::Cast(lhs));
60  }
61 private:
63 };
64 
66 // Dispatch helper
68 template <class BaseLhs,
69  class SomeLhs,
70  typename RT,
71  class CastLhs,
72  class Fun>
74 {
75  Fun fun_;
76 public:
77  typedef RT ResultType;
78 
79  FunctorDispatcherHelper(const FunctorDispatcherHelper& rhs) : fun_(rhs.fun_) {}
80  FunctorDispatcherHelper(Fun fun) : fun_(fun) {}
81 
82  ResultType operator()(BaseLhs& lhs)
83  {
84  return fun_(CastLhs::Cast(lhs));
85  }
86 };
87 
88 
90 // Parent class for all FunctorImpl, helps hide functor template args
92 template <typename R, typename P1>
94  public:
95  typedef R ResultType;
96  typedef P1 Parm1;
97 
98  virtual ~FunctorImpl() {}
99  virtual R operator()(P1&) = 0;
100  virtual FunctorImpl* DoClone() const = 0;
101 
102  template <class U>
103  static U* Clone(U* pObj)
104  {
105  if (!pObj) return nullptr;
106  U* pClone = static_cast<U*>(pObj->DoClone());
107  assert(typeid(*pClone) == typeid(*pObj));
108  return pClone;
109  }
110  protected:
113  private:
114  FunctorImpl& operator =(const FunctorImpl&) = delete;
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  ~FunctorHandler() override {}
130 
131  ResultType operator()(Parm1& p1) override
132  { return f_(p1); }
133  FunctorHandler* DoClone() const override { return new FunctorHandler(*this); }
134 
135 private:
136  Fun f_;
137  FunctorHandler(const FunctorHandler &b) : ParentFunctor::Impl(b), f_(b.f_) {}
138  FunctorHandler& operator =(const FunctorHandler& b) = delete;
139 };
140 
141 
143 // Functor wrapper class
145 template <typename R,typename Parm1>
146 class Functor
147 {
148 public:
150  typedef R ResultType;
151 
152 #if defined(VTK_HAS_STD_UNIQUE_PTR)
153  Functor() : spImpl_()
154 #else
155  Functor() : spImpl_(0)
156 #endif
157  {}
158 
159  Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get()))
160  {}
161 
162  template <typename Fun>
163  Functor(Fun fun)
164  : spImpl_(new FunctorHandler<Functor,Fun>(fun))
165  {}
166 
167  Functor& operator=(const Functor& rhs)
168  {
169  Functor copy(rhs);
170 #if defined(VTK_HAS_STD_UNIQUE_PTR)
171  spImpl_.swap(copy.spImpl_);
172 #else
173  // swap auto_ptrs by hand
174  Impl* p = spImpl_.release();
175  spImpl_.reset(copy.spImpl_.release());
176  copy.spImpl_.reset(p);
177 #endif
178  return *this;
179  }
180 
181 
182  ResultType operator()(Parm1& p1)
183  { return (*spImpl_)(p1); }
184 private:
185 #if defined(VTK_HAS_STD_UNIQUE_PTR)
186  std::unique_ptr<Impl> spImpl_;
187 #else
188  std::auto_ptr<Impl> spImpl_;
189 #endif
190 
191 };
192 
193 }
194 
195 
197 {
198 
200 // Dispatch helper
202 template <class BaseLhs, class BaseRhs,
203  class SomeLhs, class SomeRhs,
204  typename RT,
205  class CastLhs, class CastRhs,
206  class Fun>
208 {
209  Fun& fun_;
210 public:
211  typedef RT ResultType;
213  FunctorRefDispatcherHelper(Fun& fun) : fun_(fun) {}
214 
215  ResultType operator()(BaseLhs& lhs, BaseRhs& rhs)
216  {
217  return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
218  }
219 private:
221 };
222 
223 template <class BaseLhs, class BaseRhs,
224  class SomeLhs, class SomeRhs,
225  typename RT,
226  class CastLhs, class CastRhs,
227  class Fun>
229 {
230  Fun fun_;
231 public:
232  typedef RT ResultType;
234  FunctorDoubleDispatcherHelper(Fun fun) : fun_(fun) {}
235 
236  ResultType operator()(BaseLhs& lhs, BaseRhs& rhs)
237  {
238  return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
239  }
240 
241 };
242 
244 // Parent class for all FunctorImpl, helps hide functor template args
246 template <typename R, typename P1, typename P2>
248  public:
249  typedef R ResultType;
250  typedef P1 Parm1;
251  typedef P2 Parm2;
252 
253  virtual ~FunctorImpl() {}
254  virtual R operator()(P1&,P2&) = 0;
255  virtual FunctorImpl* DoClone() const = 0;
256 
257  template <class U>
258  static U* Clone(U* pObj)
259  {
260  if (!pObj) return nullptr;
261  U* pClone = static_cast<U*>(pObj->DoClone());
262  assert(typeid(*pClone) == typeid(*pObj));
263  return pClone;
264  }
265  protected:
268  private:
269  FunctorImpl& operator =(const FunctorImpl&) = delete;
270 };
271 
273 // Impl functor that calls a user functor
275 template <class ParentFunctor,typename Fun>
276 class FunctorHandler: public ParentFunctor::Impl
277 {
278  typedef typename ParentFunctor::Impl Base;
279 public:
280  typedef typename Base::ResultType ResultType;
281  typedef typename Base::Parm1 Parm1;
282  typedef typename Base::Parm2 Parm2;
283 
284  FunctorHandler(const Fun& fun) : f_(fun) {}
285  ~FunctorHandler() override {}
286 
287  ResultType operator()(Parm1& p1,Parm2& p2) override
288  { return f_(p1,p2); }
289 
290  FunctorHandler* DoClone() const override { return new FunctorHandler(*this); }
291 
292 private:
293  Fun f_;
294  FunctorHandler(const FunctorHandler &b) : ParentFunctor::Impl(b), f_(b.f_) {}
295  FunctorHandler& operator =(const FunctorHandler& b) = delete;
296 };
297 
299 // Functor wrapper class
301 template <typename R,typename Parm1, typename Parm2>
302 class Functor
303 {
304 public:
306  typedef R ResultType;
307 
308 #if defined(VTK_HAS_STD_UNIQUE_PTR)
309  Functor() : spImpl_()
310 #else
311  Functor() : spImpl_(0)
312 #endif
313  {}
314 
315  Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get()))
316  {}
317 
318  template <typename Fun>
319  Functor(const Fun& fun)
320  : spImpl_(new FunctorHandler<Functor,Fun>(fun))
321  {}
322 
323  Functor& operator=(const Functor& rhs)
324  {
325  Functor copy(rhs);
326 #if defined(VTK_HAS_STD_UNIQUE_PTR)
327  spImpl_.swap(copy.spImpl_);
328 #else // swap auto_ptrs by hand
329  Impl* p = spImpl_.release();
330  spImpl_.reset(copy.spImpl_.release());
331  copy.spImpl_.reset(p);
332 #endif
333  return *this;
334  }
335 
336  ResultType operator()(Parm1& p1,Parm2& p2)
337  { return (*spImpl_)(p1,p2); }
338 private:
339 #if defined(VTK_HAS_STD_UNIQUE_PTR)
340  std::unique_ptr<Impl> spImpl_;
341 #else
342  std::auto_ptr<Impl> spImpl_;
343 #endif
344 };
345 }
346 
348 {
349 
350 template <class To, class From>
352 {
353  static To& Cast(From& obj)
354  {
355  return dynamic_cast<To&>(obj);
356  }
357 
358  static To* Cast(From* obj)
359  {
360  return dynamic_cast<To*>(obj);
361  }
362 };
363 
364 template <class To, class From>
365 struct vtkCaster
366 {
367  static To& Cast(From& obj)
368  {
369  return *(To::SafeDownCast(&obj));
370  }
371 
372  static To* Cast(From* obj)
373  {
374  return To::SafeDownCast(obj);
375  }
376 };
377 
378 class TypeInfo
379 {
380 public:
381  // Constructors
382  TypeInfo(); // needed for containers
383  TypeInfo(const std::type_info&); // non-explicit
384 
385  // Access for the wrapped std::type_info
386  const std::type_info& Get() const;
387  // Compatibility functions
388  bool before(const TypeInfo& rhs) const;
389  const char* name() const;
390 
391 private:
392  const std::type_info* pInfo_;
393 };
394 
395 // Implementation
396 
397 inline TypeInfo::TypeInfo()
398 {
399  class Nil {};
400  pInfo_ = &typeid(Nil);
401  assert(pInfo_);
402 }
403 
404 inline TypeInfo::TypeInfo(const std::type_info& ti)
405  : pInfo_(&ti)
406  { assert(pInfo_); }
407 
408 inline bool TypeInfo::before(const TypeInfo& rhs) const
409 {
410  assert(pInfo_);
411  // type_info::before return type is int in some VC libraries
412  return pInfo_->before(*rhs.pInfo_) != 0;
413 }
414 
415 inline const std::type_info& TypeInfo::Get() const
416 {
417  assert(pInfo_);
418  return *pInfo_;
419 }
420 
421 inline const char* TypeInfo::name() const
422 {
423  assert(pInfo_);
424  return pInfo_->name();
425 }
426 
427 // Comparison operators
428 
429 inline bool operator==(const TypeInfo& lhs, const TypeInfo& rhs)
430 // type_info::operator== return type is int in some VC libraries
431  { return (lhs.Get() == rhs.Get()) != 0; }
432 
433 inline bool operator<(const TypeInfo& lhs, const TypeInfo& rhs)
434  { return lhs.before(rhs); }
435 
436 inline bool operator!=(const TypeInfo& lhs, const TypeInfo& rhs)
437  { return !(lhs == rhs); }
438 
439 inline bool operator>(const TypeInfo& lhs, const TypeInfo& rhs)
440  { return rhs < lhs; }
441 
442 inline bool operator<=(const TypeInfo& lhs, const TypeInfo& rhs)
443  { return !(lhs > rhs); }
444 
445 inline bool operator>=(const TypeInfo& lhs, const TypeInfo& rhs)
446  { return !(lhs < rhs); }
447 
448 }
449 
450 #endif
451 #endif // vtkDispatcherPrivate_h
452 // 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)
ResultType operator()(Parm1 &p1, Parm2 &p2) override
const std::type_info & Get() 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)
FunctorHandler * DoClone() const override
#define P1
Functor & operator=(const Functor &rhs)
FunctorHandler * DoClone() const override
ResultType operator()(Parm1 &p1) override
#define P2
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)