VTK
|
00001 /*========================================================================= 00002 00003 Program: Visualization Toolkit 00004 Module: vtkDispatcher.h 00005 00006 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 00007 All rights reserved. 00008 See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 00009 00010 This software is distributed WITHOUT ANY WARRANTY; without even 00011 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00012 PURPOSE. See the above copyright notice for more information. 00013 00014 =========================================================================*/ 00015 00017 // The Loki Library 00018 // Copyright (c) 2001 by Andrei Alexandrescu 00019 // This code accompanies the book: 00020 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 00021 // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 00022 // Permission to use, copy, modify, distribute and sell this software for any 00023 // purpose is hereby granted without fee, provided that the above copyright 00024 // notice appear in all copies and that both that copyright notice and this 00025 // permission notice appear in supporting documentation. 00026 // The author or Addison-Wesley Longman make no representations about the 00027 // suitability of this software for any purpose. It is provided "as is" 00028 // without express or implied warranty. 00030 #ifndef __vtkDispatcher_Private_h 00031 #define __vtkDispatcher_Private_h 00032 00033 #include <typeinfo> 00034 #include <cassert> 00035 #include <memory> 00036 00037 namespace vtkDispatcherPrivate 00038 { 00040 // Dispatch helper for reference functors 00042 template <class BaseLhs, 00043 class SomeLhs, 00044 typename RT, 00045 class CastLhs, 00046 class Fun> 00047 class FunctorRefDispatcherHelper 00048 { 00049 Fun& fun_; 00050 public: 00051 typedef RT ResultType; 00052 00053 FunctorRefDispatcherHelper(const FunctorRefDispatcherHelper& rhs) : fun_(rhs.fun_) {} 00054 FunctorRefDispatcherHelper(Fun& f) : fun_(f) {} 00055 00056 ResultType operator()(BaseLhs& lhs) 00057 { 00058 return fun_(CastLhs::Cast(lhs)); 00059 } 00060 private: 00061 FunctorRefDispatcherHelper& operator =(const FunctorRefDispatcherHelper& b); 00062 }; 00063 00065 // Dispatch helper 00067 template <class BaseLhs, 00068 class SomeLhs, 00069 typename RT, 00070 class CastLhs, 00071 class Fun> 00072 class FunctorDispatcherHelper 00073 { 00074 Fun fun_; 00075 public: 00076 typedef RT ResultType; 00077 00078 FunctorDispatcherHelper(const FunctorDispatcherHelper& rhs) : fun_(rhs.fun_) {} 00079 FunctorDispatcherHelper(Fun fun) : fun_(fun) {} 00080 00081 ResultType operator()(BaseLhs& lhs) 00082 { 00083 return fun_(CastLhs::Cast(lhs)); 00084 } 00085 }; 00086 00087 00089 // Parent class for all FunctorImpl, helps hide functor template args 00091 template <typename R, typename P1> 00092 class FunctorImpl{ 00093 public: 00094 typedef R ResultType; 00095 typedef P1 Parm1; 00096 00097 virtual ~FunctorImpl() {}; 00098 virtual R operator()(P1&) = 0; 00099 virtual FunctorImpl* DoClone() const = 0; 00100 00101 template <class U> 00102 static U* Clone(U* pObj) 00103 { 00104 if (!pObj) return 0; 00105 U* pClone = static_cast<U*>(pObj->DoClone()); 00106 assert(typeid(*pClone) == typeid(*pObj)); 00107 return pClone; 00108 } 00109 }; 00110 00112 // Impl functor that calls a user functor 00114 template <class ParentFunctor,typename Fun> 00115 class FunctorHandler: public ParentFunctor::Impl 00116 { 00117 typedef typename ParentFunctor::Impl Base; 00118 public: 00119 typedef typename Base::ResultType ResultType; 00120 typedef typename Base::Parm1 Parm1; 00121 00122 FunctorHandler(Fun& fun) : f_(fun) {} 00123 virtual ~FunctorHandler(){} 00124 00125 ResultType operator()(Parm1& p1) 00126 { return f_(p1); } 00127 virtual FunctorHandler* DoClone() const { return new FunctorHandler(*this); } 00128 00129 private: 00130 Fun f_; 00131 FunctorHandler& operator =(const FunctorHandler& b); 00132 }; 00133 00134 00136 // Functor wrapper class 00138 template <typename R,typename Parm1> 00139 class Functor 00140 { 00141 public: 00142 typedef FunctorImpl<R, Parm1> Impl; 00143 typedef R ResultType; 00144 00145 Functor() : spImpl_(0) 00146 {} 00147 00148 Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get())) 00149 {} 00150 00151 template <typename Fun> 00152 Functor(Fun fun) 00153 : spImpl_(new FunctorHandler<Functor,Fun>(fun)) 00154 {} 00155 00156 Functor& operator=(const Functor& rhs) 00157 { 00158 Functor copy(rhs); 00159 // swap auto_ptrs by hand 00160 Impl* p = spImpl_.release(); 00161 spImpl_.reset(copy.spImpl_.release()); 00162 copy.spImpl_.reset(p); 00163 return *this; 00164 } 00165 00166 00167 ResultType operator()(Parm1& p1) 00168 { return (*spImpl_)(p1); } 00169 private: 00170 std::auto_ptr<Impl> spImpl_; 00171 }; 00172 00173 } 00174 00175 00176 namespace vtkDoubleDispatcherPrivate 00177 { 00178 00180 // Dispatch helper 00182 template <class BaseLhs, class BaseRhs, 00183 class SomeLhs, class SomeRhs, 00184 typename RT, 00185 class CastLhs, class CastRhs, 00186 class Fun> 00187 class FunctorRefDispatcherHelper 00188 { 00189 Fun& fun_; 00190 public: 00191 typedef RT ResultType; 00192 FunctorRefDispatcherHelper(const FunctorRefDispatcherHelper& rhs) : fun_(rhs.fun_) {} 00193 FunctorRefDispatcherHelper(Fun& fun) : fun_(fun) {} 00194 00195 ResultType operator()(BaseLhs& lhs, BaseRhs& rhs) 00196 { 00197 return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs)); 00198 } 00199 private: 00200 FunctorRefDispatcherHelper& operator =(const FunctorRefDispatcherHelper& b); 00201 }; 00202 00203 template <class BaseLhs, class BaseRhs, 00204 class SomeLhs, class SomeRhs, 00205 typename RT, 00206 class CastLhs, class CastRhs, 00207 class Fun> 00208 class FunctorDoubleDispatcherHelper 00209 { 00210 Fun fun_; 00211 public: 00212 typedef RT ResultType; 00213 FunctorDoubleDispatcherHelper(const FunctorDoubleDispatcherHelper& rhs) : fun_(rhs.fun_) {} 00214 FunctorDoubleDispatcherHelper(Fun fun) : fun_(fun) {} 00215 00216 ResultType operator()(BaseLhs& lhs, BaseRhs& rhs) 00217 { 00218 return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs)); 00219 } 00220 00221 }; 00222 00224 // Parent class for all FunctorImpl, helps hide functor template args 00226 template <typename R, typename P1, typename P2> 00227 class FunctorImpl{ 00228 public: 00229 typedef R ResultType; 00230 typedef P1 Parm1; 00231 typedef P2 Parm2; 00232 00233 virtual ~FunctorImpl() {}; 00234 virtual R operator()(P1&,P2&) = 0; 00235 virtual FunctorImpl* DoClone() const = 0; 00236 00237 template <class U> 00238 static U* Clone(U* pObj) 00239 { 00240 if (!pObj) return 0; 00241 U* pClone = static_cast<U*>(pObj->DoClone()); 00242 assert(typeid(*pClone) == typeid(*pObj)); 00243 return pClone; 00244 } 00245 }; 00246 00248 // Impl functor that calls a user functor 00250 template <class ParentFunctor,typename Fun> 00251 class FunctorHandler: public ParentFunctor::Impl 00252 { 00253 typedef typename ParentFunctor::Impl Base; 00254 public: 00255 typedef typename Base::ResultType ResultType; 00256 typedef typename Base::Parm1 Parm1; 00257 typedef typename Base::Parm2 Parm2; 00258 00259 FunctorHandler(const Fun& fun) : f_(fun) {} 00260 virtual ~FunctorHandler(){} 00261 00262 ResultType operator()(Parm1& p1,Parm2& p2) 00263 { return f_(p1,p2); } 00264 00265 virtual FunctorHandler* DoClone() const { return new FunctorHandler(*this); } 00266 00267 private: 00268 Fun f_; 00269 FunctorHandler& operator =(const FunctorHandler& b); 00270 }; 00271 00273 // Functor wrapper class 00275 template <typename R,typename Parm1, typename Parm2> 00276 class Functor 00277 { 00278 public: 00279 typedef FunctorImpl<R, Parm1,Parm2> Impl; 00280 typedef R ResultType; 00281 00282 Functor() : spImpl_(0) 00283 {} 00284 00285 Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get())) 00286 {} 00287 00288 template <typename Fun> 00289 Functor(const Fun& fun) 00290 : spImpl_(new FunctorHandler<Functor,Fun>(fun)) 00291 {} 00292 00293 Functor& operator=(const Functor& rhs) 00294 { 00295 Functor copy(rhs); 00296 // swap auto_ptrs by hand 00297 Impl* p = spImpl_.release(); 00298 spImpl_.reset(copy.spImpl_.release()); 00299 copy.spImpl_.reset(p); 00300 return *this; 00301 } 00302 00303 ResultType operator()(Parm1& p1,Parm2& p2) 00304 { return (*spImpl_)(p1,p2); } 00305 private: 00306 std::auto_ptr<Impl> spImpl_; 00307 }; 00308 } 00309 00310 namespace vtkDispatcherCommon 00311 { 00312 00313 template <class To, class From> 00314 struct DynamicCaster 00315 { 00316 static To& Cast(From& obj) 00317 { 00318 return dynamic_cast<To&>(obj); 00319 } 00320 00321 static To* Cast(From* obj) 00322 { 00323 return dynamic_cast<To*>(obj); 00324 } 00325 }; 00326 00327 template <class To, class From> 00328 struct vtkCaster 00329 { 00330 static To& Cast(From& obj) 00331 { 00332 return *(To::SafeDownCast(&obj)); 00333 } 00334 00335 static To* Cast(From* obj) 00336 { 00337 return To::SafeDownCast(obj); 00338 } 00339 }; 00340 00341 class TypeInfo 00342 { 00343 public: 00344 // Constructors 00345 TypeInfo(); // needed for containers 00346 TypeInfo(const std::type_info&); // non-explicit 00347 00348 // Access for the wrapped std::type_info 00349 const std::type_info& Get() const; 00350 // Compatibility functions 00351 bool before(const TypeInfo& rhs) const; 00352 const char* name() const; 00353 00354 private: 00355 const std::type_info* pInfo_; 00356 }; 00357 00358 // Implementation 00359 00360 inline TypeInfo::TypeInfo() 00361 { 00362 class Nil {}; 00363 pInfo_ = &typeid(Nil); 00364 assert(pInfo_); 00365 } 00366 00367 inline TypeInfo::TypeInfo(const std::type_info& ti) 00368 : pInfo_(&ti) 00369 { assert(pInfo_); } 00370 00371 inline bool TypeInfo::before(const TypeInfo& rhs) const 00372 { 00373 assert(pInfo_); 00374 // type_info::before return type is int in some VC libraries 00375 return pInfo_->before(*rhs.pInfo_) != 0; 00376 } 00377 00378 inline const std::type_info& TypeInfo::Get() const 00379 { 00380 assert(pInfo_); 00381 return *pInfo_; 00382 } 00383 00384 inline const char* TypeInfo::name() const 00385 { 00386 assert(pInfo_); 00387 return pInfo_->name(); 00388 } 00389 00390 // Comparison operators 00391 00392 inline bool operator==(const TypeInfo& lhs, const TypeInfo& rhs) 00393 // type_info::operator== return type is int in some VC libraries 00394 { return (lhs.Get() == rhs.Get()) != 0; } 00395 00396 inline bool operator<(const TypeInfo& lhs, const TypeInfo& rhs) 00397 { return lhs.before(rhs); } 00398 00399 inline bool operator!=(const TypeInfo& lhs, const TypeInfo& rhs) 00400 { return !(lhs == rhs); } 00401 00402 inline bool operator>(const TypeInfo& lhs, const TypeInfo& rhs) 00403 { return rhs < lhs; } 00404 00405 inline bool operator<=(const TypeInfo& lhs, const TypeInfo& rhs) 00406 { return !(lhs > rhs); } 00407 00408 inline bool operator>=(const TypeInfo& lhs, const TypeInfo& rhs) 00409 { return !(lhs < rhs); } 00410 00411 } 00412 00413 #endif // __vtkDispatcherPrivate_h 00414 // VTK-HeaderTest-Exclude: vtkDispatcher_Private.h