VTK  9.1.0
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#ifndef __VTK_WRAP__
34
35#include "vtkDeprecation.h" // for VTK_DEPRECATED_IN_9_0_0
36
37#include <cassert>
38#include <memory>
39#include <typeinfo>
40
42{
44// Dispatch helper for reference functors
46template <class BaseLhs, class SomeLhs, typename RT, class CastLhs, class Fun>
48{
49 Fun& fun_;
50
51public:
52 typedef RT ResultType;
53
55 : fun_(rhs.fun_)
56 {
57 }
59 : fun_(f)
60 {
61 }
62
63 ResultType operator()(BaseLhs& lhs) { return fun_(CastLhs::Cast(lhs)); }
64
65private:
66 FunctorRefDispatcherHelper& operator=(const FunctorRefDispatcherHelper& b) = delete;
67};
68
70// Dispatch helper
72template <class BaseLhs, class SomeLhs, typename RT, class CastLhs, class Fun>
74{
75 Fun fun_;
76
77public:
78 typedef RT ResultType;
79
81 : fun_(rhs.fun_)
82 {
83 }
85 : fun_(fun)
86 {
87 }
88
89 ResultType operator()(BaseLhs& lhs) { return fun_(CastLhs::Cast(lhs)); }
90};
91
93// Parent class for all FunctorImpl, helps hide functor template args
95template <typename R, typename P1>
97{
98public:
99 typedef R ResultType;
100 typedef P1 Parm1;
101
102 virtual ~FunctorImpl() = default;
103 virtual R operator()(P1&) = 0;
104 virtual FunctorImpl* DoClone() const = 0;
105
106 template <class U>
107 static U* Clone(U* pObj)
108 {
109 if (!pObj)
110 return nullptr;
111 U* pClone = static_cast<U*>(pObj->DoClone());
112 assert(typeid(*pClone) == typeid(*pObj));
113 return pClone;
114 }
115
116protected:
117 FunctorImpl() = default;
118 FunctorImpl(const FunctorImpl&) = default;
119
120private:
121 FunctorImpl& operator=(const FunctorImpl&) = delete;
122};
123
125// Impl functor that calls a user functor
127template <class ParentFunctor, typename Fun>
128class FunctorHandler : public ParentFunctor::Impl
129{
130 typedef typename ParentFunctor::Impl Base;
131
132public:
133 typedef typename Base::ResultType ResultType;
134 typedef typename Base::Parm1 Parm1;
135
137 : f_(fun)
138 {
139 }
140 ~FunctorHandler() override = default;
141
142 ResultType operator()(Parm1& p1) override { return f_(p1); }
143 FunctorHandler* DoClone() const override { return new FunctorHandler(*this); }
144
145private:
146 Fun f_;
148 : ParentFunctor::Impl(b)
149 , f_(b.f_)
150 {
151 }
152 FunctorHandler& operator=(const FunctorHandler& b) = delete;
153};
154
156// Functor wrapper class
158template <typename R, typename Parm1>
160{
161public:
163 typedef R ResultType;
164
166 : spImpl_()
167 {
168 }
169
170 Functor(const Functor& rhs)
171 : spImpl_(Impl::Clone(rhs.spImpl_.get()))
172 {
173 }
174
175 template <typename Fun>
176 Functor(Fun fun)
177 : spImpl_(new FunctorHandler<Functor, Fun>(fun))
178 {
179 }
180
182 {
183 Functor copy(rhs);
184 spImpl_.swap(copy.spImpl_);
185 return *this;
186 }
187
188 ResultType operator()(Parm1& p1) { return (*spImpl_)(p1); }
189
190private:
191 std::unique_ptr<Impl> spImpl_;
192};
193
194}
195
197{
198
200// Dispatch helper
202template <class BaseLhs, class BaseRhs, class SomeLhs, class SomeRhs, typename RT, class CastLhs,
203 class CastRhs, class Fun>
205{
206 Fun& fun_;
207
208public:
209 typedef RT ResultType;
211 : fun_(rhs.fun_)
212 {
213 }
215 : fun_(fun)
216 {
217 }
218
219 ResultType operator()(BaseLhs& lhs, BaseRhs& rhs)
220 {
221 return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
222 }
223
224private:
225 FunctorRefDispatcherHelper& operator=(const FunctorRefDispatcherHelper& b) = delete;
226};
227
228template <class BaseLhs, class BaseRhs, class SomeLhs, class SomeRhs, typename RT, class CastLhs,
229 class CastRhs, class Fun>
231{
232 Fun fun_;
233
234public:
235 typedef RT ResultType;
237 : fun_(rhs.fun_)
238 {
239 }
241 : fun_(fun)
242 {
243 }
244
245 ResultType operator()(BaseLhs& lhs, BaseRhs& rhs)
246 {
247 return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs));
248 }
249};
250
252// Parent class for all FunctorImpl, helps hide functor template args
254template <typename R, typename P1, typename P2>
256{
257public:
258 typedef R ResultType;
259 typedef P1 Parm1;
260 typedef P2 Parm2;
261
262 virtual ~FunctorImpl() = default;
263 virtual R operator()(P1&, P2&) = 0;
264 virtual FunctorImpl* DoClone() const = 0;
265
266 template <class U>
267 static U* Clone(U* pObj)
268 {
269 if (!pObj)
270 return nullptr;
271 U* pClone = static_cast<U*>(pObj->DoClone());
272 assert(typeid(*pClone) == typeid(*pObj));
273 return pClone;
274 }
275
276protected:
277 FunctorImpl() = default;
278 FunctorImpl(const FunctorImpl&) = default;
279
280private:
281 FunctorImpl& operator=(const FunctorImpl&) = delete;
282};
283
285// Impl functor that calls a user functor
287template <class ParentFunctor, typename Fun>
288class FunctorHandler : public ParentFunctor::Impl
289{
290 typedef typename ParentFunctor::Impl Base;
291
292public:
293 typedef typename Base::ResultType ResultType;
294 typedef typename Base::Parm1 Parm1;
295 typedef typename Base::Parm2 Parm2;
296
297 FunctorHandler(const Fun& fun)
298 : f_(fun)
299 {
300 }
301 ~FunctorHandler() override = default;
302
303 ResultType operator()(Parm1& p1, Parm2& p2) override { return f_(p1, p2); }
304
305 FunctorHandler* DoClone() const override { return new FunctorHandler(*this); }
306
307private:
308 Fun f_;
310 : ParentFunctor::Impl(b)
311 , f_(b.f_)
312 {
313 }
314 FunctorHandler& operator=(const FunctorHandler& b) = delete;
315};
316
318// Functor wrapper class
320template <typename R, typename Parm1, typename Parm2>
322{
323public:
325 typedef R ResultType;
326
328 : spImpl_()
329 {
330 }
331
332 Functor(const Functor& rhs)
333 : spImpl_(Impl::Clone(rhs.spImpl_.get()))
334 {
335 }
336
337 template <typename Fun>
338 Functor(const Fun& fun)
339 : spImpl_(new FunctorHandler<Functor, Fun>(fun))
340 {
341 }
342
344 {
345 Functor copy(rhs);
346 spImpl_.swap(copy.spImpl_);
347 return *this;
348 }
349
350 ResultType operator()(Parm1& p1, Parm2& p2) { return (*spImpl_)(p1, p2); }
351
352private:
353 std::unique_ptr<Impl> spImpl_;
354};
355}
356
358{
359
360template <class To, class From>
362{
363 static To& Cast(From& obj) { return dynamic_cast<To&>(obj); }
364
365 static To* Cast(From* obj) { return dynamic_cast<To*>(obj); }
366};
367
368template <class To, class From>
370{
371 static To& Cast(From& obj) { return *(To::SafeDownCast(&obj)); }
372
373 static To* Cast(From* obj) { return To::SafeDownCast(obj); }
374};
375
377{
378public:
379 // Constructors
380 TypeInfo(); // needed for containers
381 TypeInfo(const std::type_info&); // non-explicit
382
383 // Access for the wrapped std::type_info
384 const std::type_info& Get() const;
385 // Compatibility functions
386 bool before(const TypeInfo& rhs) const;
387 const char* name() const;
388
389private:
390 const std::type_info* pInfo_;
391};
392
393// Implementation
394
396{
397 class Nil
398 {
399 };
400 pInfo_ = &typeid(Nil);
401 assert(pInfo_);
402}
403
404inline TypeInfo::TypeInfo(const std::type_info& ti)
405 : pInfo_(&ti)
406{
407 assert(pInfo_);
408}
409
410inline bool TypeInfo::before(const TypeInfo& rhs) const
411{
412 assert(pInfo_);
413 // type_info::before return type is int in some VC libraries
414 return pInfo_->before(*rhs.pInfo_) != 0;
415}
416
417inline const std::type_info& TypeInfo::Get() const
418{
419 assert(pInfo_);
420 return *pInfo_;
421}
422
423inline const char* TypeInfo::name() const
424{
425 assert(pInfo_);
426 return pInfo_->name();
427}
428
429// Comparison operators
430
431inline bool operator==(const TypeInfo& lhs, const TypeInfo& rhs)
432// type_info::operator== return type is int in some VC libraries
433{
434 return (lhs.Get() == rhs.Get()) != 0;
435}
436
437inline bool operator<(const TypeInfo& lhs, const TypeInfo& rhs)
438{
439 return lhs.before(rhs);
440}
441
442inline bool operator!=(const TypeInfo& lhs, const TypeInfo& rhs)
443{
444 return !(lhs == rhs);
445}
446
447inline bool operator>(const TypeInfo& lhs, const TypeInfo& rhs)
448{
449 return rhs < lhs;
450}
451
452inline bool operator<=(const TypeInfo& lhs, const TypeInfo& rhs)
453{
454 return !(lhs > rhs);
455}
456
457inline bool operator>=(const TypeInfo& lhs, const TypeInfo& rhs)
458{
459 return !(lhs < rhs);
460}
461
462}
463
464#endif // wrapping
465#endif // vtkDispatcherPrivate_h
466// VTK-HeaderTest-Exclude: vtkDispatcher_Private.h
bool before(const TypeInfo &rhs) const
const std::type_info & Get() const
FunctorDispatcherHelper(const FunctorDispatcherHelper &rhs)
ResultType operator()(Parm1 &p1) override
FunctorHandler * DoClone() const override
FunctorImpl(const FunctorImpl &)=default
virtual FunctorImpl * DoClone() const =0
FunctorRefDispatcherHelper(const FunctorRefDispatcherHelper &rhs)
Functor & operator=(const Functor &rhs)
FunctorDoubleDispatcherHelper(const FunctorDoubleDispatcherHelper &rhs)
ResultType operator()(Parm1 &p1, Parm2 &p2) override
FunctorHandler * DoClone() const override
FunctorImpl(const FunctorImpl &)=default
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
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)