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 
72 #ifndef vtkDoubleDispatcher_h
73 #define vtkDoubleDispatcher_h
74 
75 #include "vtkDispatcher_Private.h" //needed for Functor,CastingPolicy,TypeInfo
76 #include <map> //Required for the storage of template params to runtime params
77 
78 template
79 <
80  class BaseLhs,
81  class BaseRhs = BaseLhs,
82  typename ReturnType = void,
83  template <class, class> class CastingPolicy = vtkDispatcherCommon::vtkCaster
84  >
86 {
87 public:
89 
98  template <class SomeLhs, class SomeRhs, class Functor>
99  void Add(Functor fun) { this->AddInternal<SomeLhs,SomeRhs>(fun, 1); }
101 
103 
105  template <class SomeLhs, class SomeRhs>
106  bool Remove() { return DoRemove(typeid(SomeLhs), typeid(SomeRhs)); }
108 
120  ReturnType Go(BaseLhs* lhs, BaseRhs* rhs);
121 
122 protected:
126 
127  void DoAddFunctor(TypeInfo lhs,TypeInfo rhs, MappedType fun);
128  bool DoRemove(TypeInfo lhs, TypeInfo rhs);
129 
130  typedef std::pair<TypeInfo,TypeInfo> KeyType;
131  typedef std::map<KeyType, MappedType > MapType;
132  MapType FunctorMap;
133 private:
134  template <class SomeLhs, class SomeRhs, class Functor>
135  void AddInternal(const Functor& fun, long);
136  template <class SomeLhs, class SomeRhs, class Functor>
137  void AddInternal(Functor* fun, int);
138 };
139 
140 //We are making all these method non-inline to reduce compile time overhead
141 //----------------------------------------------------------------------------
142 template<class BaseLhs, class BaseRhs, typename ReturnType,
143  template <class, class> class CastingPolicy>
144 template <class SomeLhs, class SomeRhs, class Functor>
146 ::AddInternal(const Functor& fun, long)
147  {
149  BaseLhs, BaseRhs,
150  SomeLhs, SomeRhs,
151  ReturnType,
152  CastingPolicy<SomeLhs, BaseLhs>,
153  CastingPolicy<SomeRhs, BaseRhs>,
154  Functor> Adapter;
155  Adapter ada(fun);
156  MappedType mt(ada);
157  DoAddFunctor(typeid(SomeLhs), typeid(SomeRhs),mt);
158  }
159 
160 //----------------------------------------------------------------------------
161 template<class BaseLhs, class BaseRhs, typename ReturnType,
162  template <class, class> class CastingPolicy>
163 template <class SomeLhs, class SomeRhs, class Functor>
165 ::AddInternal(Functor* fun, int)
166  {
168  BaseLhs, BaseRhs,
169  SomeLhs, SomeRhs,
170  ReturnType,
171  CastingPolicy<SomeLhs, BaseLhs>,
172  CastingPolicy<SomeRhs, BaseRhs>,
173  Functor> Adapter;
174  Adapter ada(*fun);
175  MappedType mt(ada);
176  DoAddFunctor(typeid(SomeLhs), typeid(SomeRhs),mt);
177  }
178 
179 //----------------------------------------------------------------------------
180 template<class BaseLhs, class BaseRhs, typename ReturnType,
181  template <class, class> class CastingPolicy>
184  {
185  FunctorMap[KeyType(lhs, rhs)] = fun;
186  }
187 
188 //----------------------------------------------------------------------------
189 template <class BaseLhs, class BaseRhs, typename ReturnType,
190  template <class, class> class CastingPolicy>
193  {
194  return FunctorMap.erase(KeyType(lhs, rhs)) == 1;
195  }
196 
197 //----------------------------------------------------------------------------
198 template <class BaseLhs, class BaseRhs, typename ReturnType,
199  template <class, class> class CastingPolicy>
201 ::Go(BaseLhs* lhs, BaseRhs* rhs)
202  {
203  typename MapType::key_type k(typeid(*lhs),typeid(*rhs));
204  typename MapType::iterator i = FunctorMap.find(k);
205  if (i == FunctorMap.end())
206  {
207  //we don't want to throw exceptions so we have two options.
208  //we can return the default, or make a lightweight struct for return value
209  return ReturnType();
210  }
211  return (i->second)(*lhs,*rhs);
212  }
213 
214 #endif // vtkDoubleDispatcher_h
215 // VTK-HeaderTest-Exclude: vtkDoubleDispatcher.h
ReturnType Go(BaseLhs *lhs, BaseRhs *rhs)
std::map< KeyType, MappedType > MapType
void DoAddFunctor(TypeInfo lhs, TypeInfo rhs, MappedType fun)
void Add(Functor fun)
vtkDispatcherCommon::TypeInfo TypeInfo
Dispatch to functor based on two pointer types.
bool DoRemove(TypeInfo lhs, TypeInfo rhs)
std::pair< TypeInfo, TypeInfo > KeyType
vtkDoubleDispatcherPrivate::Functor< ReturnType, BaseLhs, BaseRhs > MappedType