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
42template <class BaseLhs,
43 class SomeLhs,
44 typename RT,
45 class CastLhs,
46 class Fun>
48{
49 Fun& fun_;
50public:
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 }
60private:
62};
63
65// Dispatch helper
67template <class BaseLhs,
68 class SomeLhs,
69 typename RT,
70 class CastLhs,
71 class Fun>
73{
74 Fun fun_;
75public:
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
91template <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
119template <class ParentFunctor,typename Fun>
120class FunctorHandler: public ParentFunctor::Impl
121{
122 typedef typename ParentFunctor::Impl Base;
123public:
124 typedef typename Base::ResultType ResultType;
125 typedef typename Base::Parm1 Parm1;
126
127 FunctorHandler(Fun& fun) : f_(fun) {}
128 virtual ~FunctorHandler() {}
129
131 { return f_(p1); }
132 virtual FunctorHandler* DoClone() const { return new FunctorHandler(*this); }
133
134private:
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
144template <typename R,typename Parm1>
146{
147public:
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
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
182 { return (*spImpl_)(p1); }
183private:
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
201template <class BaseLhs, class BaseRhs,
202 class SomeLhs, class SomeRhs,
203 typename RT,
204 class CastLhs, class CastRhs,
205 class Fun>
207{
208 Fun& fun_;
209public:
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 }
218private:
220};
221
222template <class BaseLhs, class BaseRhs,
223 class SomeLhs, class SomeRhs,
224 typename RT,
225 class CastLhs, class CastRhs,
226 class Fun>
228{
229 Fun fun_;
230public:
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
245template <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
274template <class ParentFunctor,typename Fun>
275class FunctorHandler: public ParentFunctor::Impl
276{
277 typedef typename ParentFunctor::Impl Base;
278public:
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
287 { return f_(p1,p2); }
288
289 virtual FunctorHandler* DoClone() const { return new FunctorHandler(*this); }
290
291private:
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
300template <typename R,typename Parm1, typename Parm2>
302{
303public:
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
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); }
337private:
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
349template <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
363template <class To, class From>
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
378{
379public:
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
390private:
391 const std::type_info* pInfo_;
392};
393
394// Implementation
395
397{
398 class Nil {};
399 pInfo_ = &typeid(Nil);
400 assert(pInfo_);
401}
402
403inline TypeInfo::TypeInfo(const std::type_info& ti)
404 : pInfo_(&ti)
405 { assert(pInfo_); }
406
407inline 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
414inline const std::type_info& TypeInfo::Get() const
415{
416 assert(pInfo_);
417 return *pInfo_;
418}
419
420inline const char* TypeInfo::name() const
421{
422 assert(pInfo_);
423 return pInfo_->name();
424}
425
426// Comparison operators
427
428inline 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
432inline bool operator<(const TypeInfo& lhs, const TypeInfo& rhs)
433 { return lhs.before(rhs); }
434
435inline bool operator!=(const TypeInfo& lhs, const TypeInfo& rhs)
436 { return !(lhs == rhs); }
437
438inline bool operator>(const TypeInfo& lhs, const TypeInfo& rhs)
439 { return rhs < lhs; }
440
441inline bool operator<=(const TypeInfo& lhs, const TypeInfo& rhs)
442 { return !(lhs > rhs); }
443
444inline 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
bool before(const TypeInfo &rhs) const
const std::type_info & Get() const
FunctorDispatcherHelper(const FunctorDispatcherHelper &rhs)
virtual FunctorHandler * DoClone() const
virtual FunctorImpl * DoClone() const =0
FunctorRefDispatcherHelper(const FunctorRefDispatcherHelper &rhs)
Functor & operator=(const Functor &rhs)
FunctorDoubleDispatcherHelper(const FunctorDoubleDispatcherHelper &rhs)
ResultType operator()(Parm1 &p1, Parm2 &p2)
virtual FunctorHandler * DoClone() const
virtual FunctorImpl * DoClone() const =0
virtual R operator()(P1 &, P2 &)=0
FunctorRefDispatcherHelper(const FunctorRefDispatcherHelper &rhs)
ResultType operator()(Parm1 &p1, Parm2 &p2)
Functor & operator=(const Functor &rhs)
FunctorImpl< R, Parm1, Parm2 > Impl
double get(vtkDataArray *const &arr, vtkIdType key)
bool operator<=(const TypeInfo &lhs, const TypeInfo &rhs)
bool operator!=(const TypeInfo &lhs, const TypeInfo &rhs)
bool operator>=(const TypeInfo &lhs, const TypeInfo &rhs)
bool operator==(const TypeInfo &lhs, const TypeInfo &rhs)
bool operator<(const TypeInfo &lhs, const TypeInfo &rhs)
bool operator>(const TypeInfo &lhs, const TypeInfo &rhs)
#define P1
#define P2