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  Functor() : spImpl_()
153  {}
154 
155  Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get()))
156  {}
157 
158  template <typename Fun>
159  Functor(Fun fun)
160  : spImpl_(new FunctorHandler<Functor,Fun>(fun))
161  {}
162 
163  Functor& operator=(const Functor& rhs)
164  {
165  Functor copy(rhs);
166  spImpl_.swap(copy.spImpl_);
167  return *this;
168  }
169 
170 
171  ResultType operator()(Parm1& p1)
172  { return (*spImpl_)(p1); }
173 private:
174  std::unique_ptr<Impl> spImpl_;
175 };
176 
177 }
178 
179 
181 {
182 
184 // Dispatch helper
186 template <class BaseLhs, class BaseRhs,
187  class SomeLhs, class SomeRhs,
188  typename RT,
189  class CastLhs, class CastRhs,
190  class Fun>
192 {
193  Fun& fun_;
194 public:
195  typedef RT ResultType;
197  FunctorRefDispatcherHelper(Fun& fun) : fun_(fun) {}
198 
199  ResultType operator()(BaseLhs& lhs, BaseRhs& rhs)
200  {
201  return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
202  }
203 private:
205 };
206 
207 template <class BaseLhs, class BaseRhs,
208  class SomeLhs, class SomeRhs,
209  typename RT,
210  class CastLhs, class CastRhs,
211  class Fun>
213 {
214  Fun fun_;
215 public:
216  typedef RT ResultType;
218  FunctorDoubleDispatcherHelper(Fun fun) : fun_(fun) {}
219 
220  ResultType operator()(BaseLhs& lhs, BaseRhs& rhs)
221  {
222  return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
223  }
224 
225 };
226 
228 // Parent class for all FunctorImpl, helps hide functor template args
230 template <typename R, typename P1, typename P2>
232  public:
233  typedef R ResultType;
234  typedef P1 Parm1;
235  typedef P2 Parm2;
236 
237  virtual ~FunctorImpl() {}
238  virtual R operator()(P1&,P2&) = 0;
239  virtual FunctorImpl* DoClone() const = 0;
240 
241  template <class U>
242  static U* Clone(U* pObj)
243  {
244  if (!pObj) return nullptr;
245  U* pClone = static_cast<U*>(pObj->DoClone());
246  assert(typeid(*pClone) == typeid(*pObj));
247  return pClone;
248  }
249  protected:
252  private:
253  FunctorImpl& operator =(const FunctorImpl&) = delete;
254 };
255 
257 // Impl functor that calls a user functor
259 template <class ParentFunctor,typename Fun>
260 class FunctorHandler: public ParentFunctor::Impl
261 {
262  typedef typename ParentFunctor::Impl Base;
263 public:
264  typedef typename Base::ResultType ResultType;
265  typedef typename Base::Parm1 Parm1;
266  typedef typename Base::Parm2 Parm2;
267 
268  FunctorHandler(const Fun& fun) : f_(fun) {}
269  ~FunctorHandler() override {}
270 
271  ResultType operator()(Parm1& p1,Parm2& p2) override
272  { return f_(p1,p2); }
273 
274  FunctorHandler* DoClone() const override { return new FunctorHandler(*this); }
275 
276 private:
277  Fun f_;
278  FunctorHandler(const FunctorHandler &b) : ParentFunctor::Impl(b), f_(b.f_) {}
279  FunctorHandler& operator =(const FunctorHandler& b) = delete;
280 };
281 
283 // Functor wrapper class
285 template <typename R,typename Parm1, typename Parm2>
286 class Functor
287 {
288 public:
290  typedef R ResultType;
291 
292  Functor() : spImpl_()
293  {}
294 
295  Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get()))
296  {}
297 
298  template <typename Fun>
299  Functor(const Fun& fun)
300  : spImpl_(new FunctorHandler<Functor,Fun>(fun))
301  {}
302 
303  Functor& operator=(const Functor& rhs)
304  {
305  Functor copy(rhs);
306  spImpl_.swap(copy.spImpl_);
307  return *this;
308  }
309 
310  ResultType operator()(Parm1& p1,Parm2& p2)
311  { return (*spImpl_)(p1,p2); }
312 private:
313  std::unique_ptr<Impl> spImpl_;
314 };
315 }
316 
318 {
319 
320 template <class To, class From>
322 {
323  static To& Cast(From& obj)
324  {
325  return dynamic_cast<To&>(obj);
326  }
327 
328  static To* Cast(From* obj)
329  {
330  return dynamic_cast<To*>(obj);
331  }
332 };
333 
334 template <class To, class From>
335 struct vtkCaster
336 {
337  static To& Cast(From& obj)
338  {
339  return *(To::SafeDownCast(&obj));
340  }
341 
342  static To* Cast(From* obj)
343  {
344  return To::SafeDownCast(obj);
345  }
346 };
347 
348 class TypeInfo
349 {
350 public:
351  // Constructors
352  TypeInfo(); // needed for containers
353  TypeInfo(const std::type_info&); // non-explicit
354 
355  // Access for the wrapped std::type_info
356  const std::type_info& Get() const;
357  // Compatibility functions
358  bool before(const TypeInfo& rhs) const;
359  const char* name() const;
360 
361 private:
362  const std::type_info* pInfo_;
363 };
364 
365 // Implementation
366 
367 inline TypeInfo::TypeInfo()
368 {
369  class Nil {};
370  pInfo_ = &typeid(Nil);
371  assert(pInfo_);
372 }
373 
374 inline TypeInfo::TypeInfo(const std::type_info& ti)
375  : pInfo_(&ti)
376  { assert(pInfo_); }
377 
378 inline bool TypeInfo::before(const TypeInfo& rhs) const
379 {
380  assert(pInfo_);
381  // type_info::before return type is int in some VC libraries
382  return pInfo_->before(*rhs.pInfo_) != 0;
383 }
384 
385 inline const std::type_info& TypeInfo::Get() const
386 {
387  assert(pInfo_);
388  return *pInfo_;
389 }
390 
391 inline const char* TypeInfo::name() const
392 {
393  assert(pInfo_);
394  return pInfo_->name();
395 }
396 
397 // Comparison operators
398 
399 inline bool operator==(const TypeInfo& lhs, const TypeInfo& rhs)
400 // type_info::operator== return type is int in some VC libraries
401  { return (lhs.Get() == rhs.Get()) != 0; }
402 
403 inline bool operator<(const TypeInfo& lhs, const TypeInfo& rhs)
404  { return lhs.before(rhs); }
405 
406 inline bool operator!=(const TypeInfo& lhs, const TypeInfo& rhs)
407  { return !(lhs == rhs); }
408 
409 inline bool operator>(const TypeInfo& lhs, const TypeInfo& rhs)
410  { return rhs < lhs; }
411 
412 inline bool operator<=(const TypeInfo& lhs, const TypeInfo& rhs)
413  { return !(lhs > rhs); }
414 
415 inline bool operator>=(const TypeInfo& lhs, const TypeInfo& rhs)
416  { return !(lhs < rhs); }
417 
418 }
419 
420 #endif
421 #endif // vtkDispatcherPrivate_h
422 // 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)