VTK
vtkDoubleDispatcher.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkDoubleDispatcher.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
15 
17 // The Loki Library
18 // Copyright (c) 2001 by Andrei Alexandrescu
19 // This code accompanies the book:
20 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
21 // Patterns Applied". Copyright (c) 2001. Addison-Wesley.
22 // Permission to use, copy, modify, distribute and sell this software for any
23 // purpose is hereby granted without fee, provided that the above copyright
24 // notice appear in all copies and that both that copyright notice and this
25 // permission notice appear in supporting documentation.
26 // The author or Addison-Wesley Longman make no representations about the
27 // suitability of this software for any purpose. It is provided "as is"
28 // without express or implied warranty.
30 
73 #ifndef vtkDoubleDispatcher_h
74 #define vtkDoubleDispatcher_h
75 
76 #include "vtkDispatcher_Private.h" //needed for Functor,CastingPolicy,TypeInfo
77 #include <map> //Required for the storage of template params to runtime params
78 
79 template
80 <
81  class BaseLhs,
82  class BaseRhs = BaseLhs,
83  typename ReturnType = void,
84  template <class, class> class CastingPolicy = vtkDispatcherCommon::vtkCaster
85  >
87 {
88 public:
102  template <class SomeLhs, class SomeRhs, class Functor>
103  void Add(Functor fun) { this->AddInternal<SomeLhs,SomeRhs>(fun, 1); }
104 
109  template <class SomeLhs, class SomeRhs>
110  bool Remove() { return DoRemove(typeid(SomeLhs), typeid(SomeRhs)); }
111 
130  ReturnType Go(BaseLhs* lhs, BaseRhs* rhs);
131 
132 protected:
136 
137  void DoAddFunctor(TypeInfo lhs,TypeInfo rhs, MappedType fun);
138  bool DoRemove(TypeInfo lhs, TypeInfo rhs);
139 
140  typedef std::pair<TypeInfo,TypeInfo> KeyType;
141  typedef std::map<KeyType, MappedType > MapType;
142  MapType FunctorMap;
143 private:
144  template <class SomeLhs, class SomeRhs, class Functor>
145  void AddInternal(const Functor& fun, long);
146  template <class SomeLhs, class SomeRhs, class Functor>
147  void AddInternal(Functor* fun, int);
148 };
149 
150 //We are making all these method non-inline to reduce compile time overhead
151 //----------------------------------------------------------------------------
152 template<class BaseLhs, class BaseRhs, typename ReturnType,
153  template <class, class> class CastingPolicy>
154 template <class SomeLhs, class SomeRhs, class Functor>
156 ::AddInternal(const Functor& fun, long)
157 {
159  BaseLhs, BaseRhs,
160  SomeLhs, SomeRhs,
161  ReturnType,
162  CastingPolicy<SomeLhs, BaseLhs>,
163  CastingPolicy<SomeRhs, BaseRhs>,
164  Functor> Adapter;
165  Adapter ada(fun);
166  MappedType mt(ada);
167  DoAddFunctor(typeid(SomeLhs), typeid(SomeRhs),mt);
168 }
169 
170 //----------------------------------------------------------------------------
171 template<class BaseLhs, class BaseRhs, typename ReturnType,
172  template <class, class> class CastingPolicy>
173 template <class SomeLhs, class SomeRhs, class Functor>
175 ::AddInternal(Functor* fun, int)
176 {
178  BaseLhs, BaseRhs,
179  SomeLhs, SomeRhs,
180  ReturnType,
181  CastingPolicy<SomeLhs, BaseLhs>,
182  CastingPolicy<SomeRhs, BaseRhs>,
183  Functor> Adapter;
184  Adapter ada(*fun);
185  MappedType mt(ada);
186  DoAddFunctor(typeid(SomeLhs), typeid(SomeRhs),mt);
187 }
188 
189 //----------------------------------------------------------------------------
190 template<class BaseLhs, class BaseRhs, typename ReturnType,
191  template <class, class> class CastingPolicy>
194 {
195  FunctorMap[KeyType(lhs, rhs)] = fun;
196 }
197 
198 //----------------------------------------------------------------------------
199 template <class BaseLhs, class BaseRhs, typename ReturnType,
200  template <class, class> class CastingPolicy>
203 {
204  return FunctorMap.erase(KeyType(lhs, rhs)) == 1;
205 }
206 
207 //----------------------------------------------------------------------------
208 template <class BaseLhs, class BaseRhs, typename ReturnType,
209  template <class, class> class CastingPolicy>
211 ::Go(BaseLhs* lhs, BaseRhs* rhs)
212 {
213  typename MapType::key_type k(typeid(*lhs),typeid(*rhs));
214  typename MapType::iterator i = FunctorMap.find(k);
215  if (i == FunctorMap.end())
216  {
217  //we don't want to throw exceptions so we have two options.
218  //we can return the default, or make a lightweight struct for return value
219  return ReturnType();
220  }
221  return (i->second)(*lhs,*rhs);
222 }
223 
224 #endif // vtkDoubleDispatcher_h
225 // VTK-HeaderTest-Exclude: vtkDoubleDispatcher.h
ReturnType Go(BaseLhs *lhs, BaseRhs *rhs)
Given two pointers of objects that derive from the BaseLhs and BaseRhs we find the matching functor t...
std::map< KeyType, MappedType > MapType
void DoAddFunctor(TypeInfo lhs, TypeInfo rhs, MappedType fun)
void Add(Functor fun)
Add in a functor that is mapped to the combination of the two template parameters passed in...
vtkDispatcherCommon::TypeInfo TypeInfo
Dispatch to functor based on two pointer types.
bool Remove()
Remove a functor that is bound to the given parameter types.
bool DoRemove(TypeInfo lhs, TypeInfo rhs)
std::pair< TypeInfo, TypeInfo > KeyType
vtkDoubleDispatcherPrivate::Functor< ReturnType, BaseLhs, BaseRhs > MappedType