VTK
/Users/kitware/Dashboards/MyTests/VTK_BLD_Release_docs/Utilities/Doxygen/dox/Common/DataModel/vtkDispatcher.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 
00075 #ifndef vtkDispatcher_h
00076 #define vtkDispatcher_h
00077 
00078 #include "vtkDispatcher_Private.h" //needed for Functor,CastingPolicy,TypeInfo
00079 #include <map> //Required for the storage of template params to runtime params
00080 
00082 // class template FunctorDispatcher
00084 template
00085   <
00086     class BaseLhs,
00087     typename ReturnType = void,
00088     template <class, class> class CastingPolicy = vtkDispatcherCommon::vtkCaster
00089   >
00090 class vtkDispatcher
00091 {
00092 public:
00094 
00101   template <class SomeLhs, class Functor>
00102   void Add(Functor fun) { this->AddInternal<SomeLhs>(fun, 1); }
00104 
00106 
00108   template <class SomeLhs>
00109   bool Remove() { return DoRemove(typeid(SomeLhs)); }
00111 
00122   ReturnType Go(BaseLhs* lhs);
00123 
00124 protected:
00125   typedef vtkDispatcherCommon::TypeInfo TypeInfo;
00126   typedef vtkDispatcherPrivate::Functor<ReturnType,BaseLhs> MappedType;
00127 
00128   void DoAddFunctor(TypeInfo lhs, MappedType fun);
00129   bool DoRemove(TypeInfo lhs);
00130   typedef std::map<TypeInfo, MappedType > MapType;
00131   MapType FunctorMap;
00132 private:
00133   template <class SomeLhs, class Functor>
00134   void AddInternal(Functor const& fun, long);
00135   template <class SomeLhs, class Functor>
00136   void AddInternal(Functor* fun, int);
00137 };
00138 
00139 //We are making all these method non-inline to reduce compile time overhead
00140 //----------------------------------------------------------------------------
00141 template<class BaseLhs,typename ReturnType,
00142          template <class, class> class CastingPolicy>
00143 template <class SomeLhs, class Functor>
00144 void vtkDispatcher<BaseLhs,ReturnType,CastingPolicy>::AddInternal(const Functor& fun, long)
00145   {
00146   typedef vtkDispatcherPrivate::FunctorDispatcherHelper<
00147       BaseLhs,
00148       SomeLhs,
00149       ReturnType,
00150       CastingPolicy<SomeLhs, BaseLhs>,
00151       Functor> Adapter;
00152   Adapter ada(fun);
00153   MappedType mt(ada);
00154   DoAddFunctor(typeid(SomeLhs),mt);
00155   }
00156 
00157 
00158 //----------------------------------------------------------------------------
00159 template<class BaseLhs,typename ReturnType,
00160          template <class, class> class CastingPolicy>
00161 template <class SomeLhs, class Functor>
00162 void vtkDispatcher<BaseLhs,ReturnType,CastingPolicy>::AddInternal(Functor* fun, int)
00163   {
00164   typedef vtkDispatcherPrivate::FunctorRefDispatcherHelper<
00165       BaseLhs,
00166       SomeLhs,
00167       ReturnType,
00168       CastingPolicy<SomeLhs, BaseLhs>,
00169       Functor> Adapter;
00170   Adapter ada(*fun);
00171   MappedType mt(ada);
00172   DoAddFunctor(typeid(SomeLhs),mt);
00173   }
00174 
00175 //----------------------------------------------------------------------------
00176 template<class BaseLhs,typename ReturnType,
00177          template <class, class> class CastingPolicy>
00178 void vtkDispatcher<BaseLhs,ReturnType,CastingPolicy>
00179 ::DoAddFunctor(TypeInfo lhs, MappedType fun)
00180   {
00181   FunctorMap[TypeInfo(lhs)] = fun;
00182   }
00183 
00184 //----------------------------------------------------------------------------
00185 template <class BaseLhs, typename ReturnType,
00186           template <class, class> class CastingPolicy>
00187 bool vtkDispatcher<BaseLhs,ReturnType,CastingPolicy>
00188 ::DoRemove(TypeInfo lhs)
00189   {
00190   return FunctorMap.erase(TypeInfo(lhs)) == 1;
00191   }
00192 
00193 //----------------------------------------------------------------------------
00194 template <class BaseLhs,typename ReturnType,
00195           template <class, class> class CastingPolicy>
00196 ReturnType vtkDispatcher<BaseLhs,ReturnType,CastingPolicy>
00197 ::Go(BaseLhs* lhs)
00198   {
00199   typename MapType::key_type k(typeid(*lhs));
00200   typename MapType::iterator i = FunctorMap.find(k);
00201   if (i == FunctorMap.end())
00202     {
00203     //we return a default type, currently i don't want exceptions thrown
00204     return ReturnType();
00205     }
00206   return (i->second)(*lhs);
00207   }
00208 
00209 #endif // vtkDispatcher_h
00210 // VTK-HeaderTest-Exclude: vtkDispatcher.h