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
79template
80<
81 class BaseLhs,
82 class BaseRhs = BaseLhs,
83 typename ReturnType = void,
84 template <class, class> class CastingPolicy = vtkDispatcherCommon::vtkCaster
85 >
87{
88public:
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
132protected:
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;
143private:
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//----------------------------------------------------------------------------
152template<class BaseLhs, class BaseRhs, typename ReturnType,
153 template <class, class> class CastingPolicy>
154template <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//----------------------------------------------------------------------------
171template<class BaseLhs, class BaseRhs, typename ReturnType,
172 template <class, class> class CastingPolicy>
173template <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//----------------------------------------------------------------------------
190template<class BaseLhs, class BaseRhs, typename ReturnType,
191 template <class, class> class CastingPolicy>
194{
195 FunctorMap[KeyType(lhs, rhs)] = fun;
196}
197
198//----------------------------------------------------------------------------
199template <class BaseLhs, class BaseRhs, typename ReturnType,
200 template <class, class> class CastingPolicy>
203{
204 return FunctorMap.erase(KeyType(lhs, rhs)) == 1;
205}
206
207//----------------------------------------------------------------------------
208template <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
Dispatch to functor based on two pointer types.
bool DoRemove(TypeInfo lhs, TypeInfo rhs)
ReturnType Go(BaseLhs *lhs, BaseRhs *rhs)
Given two pointers of objects that derive from the BaseLhs and BaseRhs we find the matching functor t...
vtkDispatcherCommon::TypeInfo TypeInfo
std::map< KeyType, MappedType > MapType
void DoAddFunctor(TypeInfo lhs, TypeInfo rhs, MappedType fun)
bool Remove()
Remove a functor that is bound to the given parameter types.
void Add(Functor fun)
Add in a functor that is mapped to the combination of the two template parameters passed in.
vtkDoubleDispatcherPrivate::Functor< ReturnType, BaseLhs, BaseRhs > MappedType
std::pair< TypeInfo, TypeInfo > KeyType