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 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