VTK
dox/Common/DataModel/vtkDispatcher_Private.h
Go to the documentation of this file.
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