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 protected: 00110 FunctorImpl() {} 00111 FunctorImpl(const FunctorImpl&) {} 00112 private: 00113 // not implemented 00114 FunctorImpl& operator =(const FunctorImpl&); 00115 }; 00116 00118 // Impl functor that calls a user functor 00120 template <class ParentFunctor,typename Fun> 00121 class FunctorHandler: public ParentFunctor::Impl 00122 { 00123 typedef typename ParentFunctor::Impl Base; 00124 public: 00125 typedef typename Base::ResultType ResultType; 00126 typedef typename Base::Parm1 Parm1; 00127 00128 FunctorHandler(Fun& fun) : f_(fun) {} 00129 virtual ~FunctorHandler() {} 00130 00131 ResultType operator()(Parm1& p1) 00132 { return f_(p1); } 00133 virtual FunctorHandler* DoClone() const { return new FunctorHandler(*this); } 00134 00135 private: 00136 Fun f_; 00137 FunctorHandler(const FunctorHandler &b) : ParentFunctor::Impl(b), f_(b.f_) {} 00138 // not implemented 00139 FunctorHandler& operator =(const FunctorHandler& b); 00140 }; 00141 00142 00144 // Functor wrapper class 00146 template <typename R,typename Parm1> 00147 class Functor 00148 { 00149 public: 00150 typedef FunctorImpl<R, Parm1> Impl; 00151 typedef R ResultType; 00152 00153 Functor() : spImpl_(0) 00154 {} 00155 00156 Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get())) 00157 {} 00158 00159 template <typename Fun> 00160 Functor(Fun fun) 00161 : spImpl_(new FunctorHandler<Functor,Fun>(fun)) 00162 {} 00163 00164 Functor& operator=(const Functor& rhs) 00165 { 00166 Functor copy(rhs); 00167 // swap auto_ptrs by hand 00168 Impl* p = spImpl_.release(); 00169 spImpl_.reset(copy.spImpl_.release()); 00170 copy.spImpl_.reset(p); 00171 return *this; 00172 } 00173 00174 00175 ResultType operator()(Parm1& p1) 00176 { return (*spImpl_)(p1); } 00177 private: 00178 std::auto_ptr<Impl> spImpl_; 00179 }; 00180 00181 } 00182 00183 00184 namespace vtkDoubleDispatcherPrivate 00185 { 00186 00188 // Dispatch helper 00190 template <class BaseLhs, class BaseRhs, 00191 class SomeLhs, class SomeRhs, 00192 typename RT, 00193 class CastLhs, class CastRhs, 00194 class Fun> 00195 class FunctorRefDispatcherHelper 00196 { 00197 Fun& fun_; 00198 public: 00199 typedef RT ResultType; 00200 FunctorRefDispatcherHelper(const FunctorRefDispatcherHelper& rhs) : fun_(rhs.fun_) {} 00201 FunctorRefDispatcherHelper(Fun& fun) : fun_(fun) {} 00202 00203 ResultType operator()(BaseLhs& lhs, BaseRhs& rhs) 00204 { 00205 return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs)); 00206 } 00207 private: 00208 FunctorRefDispatcherHelper& operator =(const FunctorRefDispatcherHelper& b); 00209 }; 00210 00211 template <class BaseLhs, class BaseRhs, 00212 class SomeLhs, class SomeRhs, 00213 typename RT, 00214 class CastLhs, class CastRhs, 00215 class Fun> 00216 class FunctorDoubleDispatcherHelper 00217 { 00218 Fun fun_; 00219 public: 00220 typedef RT ResultType; 00221 FunctorDoubleDispatcherHelper(const FunctorDoubleDispatcherHelper& rhs) : fun_(rhs.fun_) {} 00222 FunctorDoubleDispatcherHelper(Fun fun) : fun_(fun) {} 00223 00224 ResultType operator()(BaseLhs& lhs, BaseRhs& rhs) 00225 { 00226 return fun_(CastLhs::Cast(lhs), CastRhs::Cast(rhs)); 00227 } 00228 00229 }; 00230 00232 // Parent class for all FunctorImpl, helps hide functor template args 00234 template <typename R, typename P1, typename P2> 00235 class FunctorImpl{ 00236 public: 00237 typedef R ResultType; 00238 typedef P1 Parm1; 00239 typedef P2 Parm2; 00240 00241 virtual ~FunctorImpl() {} 00242 virtual R operator()(P1&,P2&) = 0; 00243 virtual FunctorImpl* DoClone() const = 0; 00244 00245 template <class U> 00246 static U* Clone(U* pObj) 00247 { 00248 if (!pObj) return 0; 00249 U* pClone = static_cast<U*>(pObj->DoClone()); 00250 assert(typeid(*pClone) == typeid(*pObj)); 00251 return pClone; 00252 } 00253 protected: 00254 FunctorImpl() {} 00255 FunctorImpl(const FunctorImpl&) {} 00256 private: 00257 // not implemented 00258 FunctorImpl& operator =(const FunctorImpl&); 00259 }; 00260 00262 // Impl functor that calls a user functor 00264 template <class ParentFunctor,typename Fun> 00265 class FunctorHandler: public ParentFunctor::Impl 00266 { 00267 typedef typename ParentFunctor::Impl Base; 00268 public: 00269 typedef typename Base::ResultType ResultType; 00270 typedef typename Base::Parm1 Parm1; 00271 typedef typename Base::Parm2 Parm2; 00272 00273 FunctorHandler(const Fun& fun) : f_(fun) {} 00274 virtual ~FunctorHandler() {} 00275 00276 ResultType operator()(Parm1& p1,Parm2& p2) 00277 { return f_(p1,p2); } 00278 00279 virtual FunctorHandler* DoClone() const { return new FunctorHandler(*this); } 00280 00281 private: 00282 Fun f_; 00283 FunctorHandler(const FunctorHandler &b) : ParentFunctor::Impl(b), f_(b.f_) {} 00284 // not implemented 00285 FunctorHandler& operator =(const FunctorHandler& b); 00286 }; 00287 00289 // Functor wrapper class 00291 template <typename R,typename Parm1, typename Parm2> 00292 class Functor 00293 { 00294 public: 00295 typedef FunctorImpl<R, Parm1,Parm2> Impl; 00296 typedef R ResultType; 00297 00298 Functor() : spImpl_(0) 00299 {} 00300 00301 Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get())) 00302 {} 00303 00304 template <typename Fun> 00305 Functor(const Fun& fun) 00306 : spImpl_(new FunctorHandler<Functor,Fun>(fun)) 00307 {} 00308 00309 Functor& operator=(const Functor& rhs) 00310 { 00311 Functor copy(rhs); 00312 // swap auto_ptrs by hand 00313 Impl* p = spImpl_.release(); 00314 spImpl_.reset(copy.spImpl_.release()); 00315 copy.spImpl_.reset(p); 00316 return *this; 00317 } 00318 00319 ResultType operator()(Parm1& p1,Parm2& p2) 00320 { return (*spImpl_)(p1,p2); } 00321 private: 00322 std::auto_ptr<Impl> spImpl_; 00323 }; 00324 } 00325 00326 namespace vtkDispatcherCommon 00327 { 00328 00329 template <class To, class From> 00330 struct DynamicCaster 00331 { 00332 static To& Cast(From& obj) 00333 { 00334 return dynamic_cast<To&>(obj); 00335 } 00336 00337 static To* Cast(From* obj) 00338 { 00339 return dynamic_cast<To*>(obj); 00340 } 00341 }; 00342 00343 template <class To, class From> 00344 struct vtkCaster 00345 { 00346 static To& Cast(From& obj) 00347 { 00348 return *(To::SafeDownCast(&obj)); 00349 } 00350 00351 static To* Cast(From* obj) 00352 { 00353 return To::SafeDownCast(obj); 00354 } 00355 }; 00356 00357 class TypeInfo 00358 { 00359 public: 00360 // Constructors 00361 TypeInfo(); // needed for containers 00362 TypeInfo(const std::type_info&); // non-explicit 00363 00364 // Access for the wrapped std::type_info 00365 const std::type_info& Get() const; 00366 // Compatibility functions 00367 bool before(const TypeInfo& rhs) const; 00368 const char* name() const; 00369 00370 private: 00371 const std::type_info* pInfo_; 00372 }; 00373 00374 // Implementation 00375 00376 inline TypeInfo::TypeInfo() 00377 { 00378 class Nil {}; 00379 pInfo_ = &typeid(Nil); 00380 assert(pInfo_); 00381 } 00382 00383 inline TypeInfo::TypeInfo(const std::type_info& ti) 00384 : pInfo_(&ti) 00385 { assert(pInfo_); } 00386 00387 inline bool TypeInfo::before(const TypeInfo& rhs) const 00388 { 00389 assert(pInfo_); 00390 // type_info::before return type is int in some VC libraries 00391 return pInfo_->before(*rhs.pInfo_) != 0; 00392 } 00393 00394 inline const std::type_info& TypeInfo::Get() const 00395 { 00396 assert(pInfo_); 00397 return *pInfo_; 00398 } 00399 00400 inline const char* TypeInfo::name() const 00401 { 00402 assert(pInfo_); 00403 return pInfo_->name(); 00404 } 00405 00406 // Comparison operators 00407 00408 inline bool operator==(const TypeInfo& lhs, const TypeInfo& rhs) 00409 // type_info::operator== return type is int in some VC libraries 00410 { return (lhs.Get() == rhs.Get()) != 0; } 00411 00412 inline bool operator<(const TypeInfo& lhs, const TypeInfo& rhs) 00413 { return lhs.before(rhs); } 00414 00415 inline bool operator!=(const TypeInfo& lhs, const TypeInfo& rhs) 00416 { return !(lhs == rhs); } 00417 00418 inline bool operator>(const TypeInfo& lhs, const TypeInfo& rhs) 00419 { return rhs < lhs; } 00420 00421 inline bool operator<=(const TypeInfo& lhs, const TypeInfo& rhs) 00422 { return !(lhs > rhs); } 00423 00424 inline bool operator>=(const TypeInfo& lhs, const TypeInfo& rhs) 00425 { return !(lhs < rhs); } 00426 00427 } 00428 00429 #endif // vtkDispatcherPrivate_h 00430 // VTK-HeaderTest-Exclude: vtkDispatcher_Private.h