VTK
/Users/kitware/Dashboards/MyTests/VTK_BLD_Release_docs/Utilities/Doxygen/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   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