DoubleDispatcher.hpp
Go to the documentation of this file.
1 //
3 // Aurora C++ Library
4 // Copyright (c) 2012-2016 Jan Haller
5 //
6 // This software is provided 'as-is', without any express or implied
7 // warranty. In no event will the authors be held liable for any damages
8 // arising from the use of this software.
9 //
10 // Permission is granted to anyone to use this software for any purpose,
11 // including commercial applications, and to alter it and redistribute it
12 // freely, subject to the following restrictions:
13 //
14 // 1. The origin of this software must not be misrepresented; you must not
15 // claim that you wrote the original software. If you use this software
16 // in a product, an acknowledgment in the product documentation would be
17 // appreciated but is not required.
18 //
19 // 2. Altered source versions must be plainly marked as such, and must not be
20 // misrepresented as being the original software.
21 //
22 // 3. This notice may not be removed or altered from any source distribution.
23 //
25 
28 
29 #ifndef AURORA_DOUBLEDISPATCHER_HPP
30 #define AURORA_DOUBLEDISPATCHER_HPP
31 
35 #include <Aurora/Tools/Hash.hpp>
37 #include <Aurora/Config.hpp>
38 
39 #include <unordered_map>
40 #include <functional>
41 #include <algorithm>
42 #include <cassert>
43 
44 
45 namespace aurora
46 {
47 
50 
118 template <typename Signature, class Traits = RttiDispatchTraits<Signature, 2>>
120 {
121  // ---------------------------------------------------------------------------------------------------------------------------
122  // Public types
123  public:
126  typedef typename FunctionResult<Signature>::Type Result;
127 
130  typedef typename FunctionParam<Signature, 0>::Type Parameter;
131 
134  typedef typename FunctionParam<Signature, 2>::Type UserData;
135 
136 
137  // ---------------------------------------------------------------------------------------------------------------------------
138  // Static assertions
139 
140  // Make sure that B is either T* or T&
141  static_assert(std::is_pointer<Parameter>::value || std::is_lvalue_reference<Parameter>::value,
142  "Function parameter must be a pointer or reference.");
143 
144  // For signature R(X, Y), ensure that X == Y
145  static_assert(std::is_same<typename FunctionParam<Signature, 0>::Type, typename FunctionParam<Signature, 1>::Type>::value,
146  "The two function parameters must have the same type.");
147 
148 
149  // ---------------------------------------------------------------------------------------------------------------------------
150  // Public member functions
151  public:
156  explicit DoubleDispatcher(bool symmetric = true);
157 
160 
163 
166 
177  template <typename Id1, typename Id2, typename Fn>
178  void bind(const Id1& identifier1, const Id2& identifier2, Fn function);
179 
190  Result call(Parameter arg1, Parameter arg2) const;
191 
204  Result call(Parameter arg1, Parameter arg2, UserData data) const;
205 
211  void fallback(std::function<Signature> function);
212 
213 
214  // ---------------------------------------------------------------------------------------------------------------------------
215  // Private types
216  private:
217  typedef typename Traits::Key SingleKey;
218  typedef std::function<Signature> BaseFunction;
219 
220  struct Key
221  {
222  Key(const SingleKey& key1, const SingleKey& key2, bool swapped);
223  bool operator== (const Key& rhs) const;
224 
225  std::pair<SingleKey, SingleKey> keyPair;
226  bool swapped;
227  };
228 
229  struct Hasher
230  {
231  std::size_t operator() (const Key& k) const;
232  };
233 
234  typedef std::unordered_map<Key, BaseFunction, Hasher> FnMap;
235 
236 
237  // ---------------------------------------------------------------------------------------------------------------------------
238  // Private member functions
239  private:
240  // Makes sure that the keys are sorted in case we use symmetric argument dispatching.
241  Key makeKey(SingleKey key1, SingleKey key2) const;
242 
243 
244  // ---------------------------------------------------------------------------------------------------------------------------
245  // Private variables
246  private:
247  FnMap mMap;
248  BaseFunction mFallback;
249  bool mSymmetric;
250 };
251 
253 
254 } // namespace aurora
255 
256 #include <Aurora/Dispatch/Detail/DoubleDispatcher.inl>
257 #endif // AURORA_DOUBLEDISPATCHER_HPP
Extensions to std::hash.
Utilities for template metaprogramming.
Definition of Aurora exception classes.
DoubleDispatcher(bool symmetric=true)
Constructor.
Result call(Parameter arg1, Parameter arg2) const
Dispatches the key of arg1 and arg2 and invokes the corresponding function.
~DoubleDispatcher()
Destructor.
void bind(const Id1 &identifier1, const Id2 &identifier2, Fn function)
Registers a function bound to a specific key.
Non-copyable base class.
Definition: NonCopyable.hpp:42
Class that is able to perform dynamic dispatch on multiple functions with two parameters.
Definition: DoubleDispatcher.hpp:119
Configuration header of the library.
FunctionParam< Signature, 0 >::Type Parameter
Function parameter type denoting the object used for the dispatch.
Definition: DoubleDispatcher.hpp:130
Class template aurora::DispatchTraits.
DoubleDispatcher & operator=(DoubleDispatcher &&source)
Move assignment operator.
FunctionParam< Signature, 2 >::Type UserData
Addition parameter for user data, only useful if Signature contains more than 2 parameters.
Definition: DoubleDispatcher.hpp:134
Class aurora::NonCopyable.
void fallback(std::function< Signature > function)
Registers a fallback function.
FunctionResult< Signature >::Type Result
Function return type.
Definition: DoubleDispatcher.hpp:126
Definition: DispatchTraits.hpp:39