Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00025
00028
00029 #ifndef THOR_DOUBLEDISPATCHER_HPP
00030 #define THOR_DOUBLEDISPATCHER_HPP
00031
00032 #include <Thor/Tools/NonCopyable.hpp>
00033 #include <Thor/Tools/ForEach.hpp>
00034 #include <Thor/Tools/Exceptions.hpp>
00035 #include <Thor/Detail/BinaryFunction.hpp>
00036 #include <Thor/Detail/AssociativeHelpers.hpp>
00037 #include <Thor/Detail/Metaprogramming.hpp>
00038 #include <Thor/Detail/TypeInfo.hpp>
00039 #include <Thor/Config.hpp>
00040
00041 #include <vector>
00042 #include <algorithm>
00043 #include <cassert>
00044
00045
00046 namespace thor
00047 {
00048
00051
00062 template <class B, typename R = void>
00063 class DoubleDispatcher : private NonCopyable
00064 {
00065
00066
00067
00068
00069 THOR_STATIC_ASSERT(
00070 std::tr1::is_pointer<B>::value && std::tr1::is_polymorphic< typename std::tr1::remove_pointer<B>::type >::value
00071 || std::tr1::is_reference<B>::value && std::tr1::is_polymorphic< typename std::tr1::remove_reference<B>::type >::value )
00072
00073
00074
00075
00076 public:
00081 explicit DoubleDispatcher(bool symmetric = true);
00082
00085 ~DoubleDispatcher();
00086
00106 template <class D1, class D2>
00107 void Register(R (*globalFunction)( THOR_REPLICATE(B,D1), THOR_REPLICATE(B,D2) ));
00108
00133 template <class D1, class D2, class C>
00134 void Register(R (C::*memberFunction)( THOR_REPLICATE(B,D1), THOR_REPLICATE(B,D2) ), C& object);
00135
00157 template <class D1, class D2, typename Fn>
00158 void Register(const Fn& functionObject);
00159
00167 R Call(B arg1, B arg2) const;
00168
00169
00170
00171
00172 private:
00173 typedef std::pair<detail::TypeInfo, detail::TypeInfo> Key;
00174 typedef detail::BinaryFunctionBase<B, R>* Value;
00175 typedef detail::KeyValuePair<Key, Value> Pair;
00176 typedef std::vector<Pair> FnMap;
00177
00178
00179
00180
00181 private:
00182
00183 void InternalRegister(detail::TypeInfo key1, detail::TypeInfo key2, Value value);
00184
00185
00186 typename FnMap::const_iterator Find(detail::TypeInfo key1, detail::TypeInfo key2) const;
00187
00188
00189 Key MakeArgumentPair(detail::TypeInfo key1, detail::TypeInfo key2) const;
00190
00191
00192
00193
00194 private:
00195 FnMap mMap;
00196 bool mSymmetric;
00197 };
00198
00222
00224
00225 }
00226
00227 #include <Thor/Detail/DoubleDispatcher.inl>
00228 #endif // THOR_DOUBLEDISPATCHER_HPP