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/Exceptions.hpp>
00034 #include <Thor/Tools/ForEach.hpp>
00035 #include <Thor/Tools/Rtti.hpp>
00036 #include <Thor/SmartPtr/CopiedPtr.hpp>
00037 #include <Thor/Detail/BinaryFunction.hpp>
00038 #include <Thor/Detail/AssociativeHelpers.hpp>
00039 #include <Thor/Detail/Metaprogramming.hpp>
00040 #include <Thor/Detail/TypeInfo.hpp>
00041 #include <Thor/Config.hpp>
00042
00043 #include <vector>
00044 #include <algorithm>
00045 #include <cassert>
00046
00047
00048 namespace thor
00049 {
00050
00053
00064 template <class B, typename R = void>
00065 class DoubleDispatcher : private NonCopyable
00066 {
00067
00068
00069
00070
00071 THOR_STATIC_ASSERT(
00072 std::tr1::is_pointer<B>::value && std::tr1::is_polymorphic< typename std::tr1::remove_pointer<B>::type >::value
00073 || std::tr1::is_reference<B>::value && std::tr1::is_polymorphic< typename std::tr1::remove_reference<B>::type >::value )
00074
00075
00076
00077
00078 public:
00087 explicit DoubleDispatcher(bool symmetric = true, bool supportDerivedToBase = false);
00088
00108 template <class D1, class D2>
00109 void Register(R (*globalFunction)( THOR_REPLICATE(B,D1), THOR_REPLICATE(B,D2) ));
00110
00135 template <class D1, class D2, class C>
00136 void Register(R (C::*memberFunction)( THOR_REPLICATE(B,D1), THOR_REPLICATE(B,D2) ), C& object);
00137
00159 template <class D1, class D2, typename Fn>
00160 void Register(const Fn& functionObject);
00161
00171 R Call(B arg1, B arg2) const;
00172
00173
00174
00175
00176 private:
00177 typedef detail::TypeInfo TypeInfo;
00178 typedef std::pair<TypeInfo, TypeInfo> Key;
00179 typedef CopiedPtr<detail::BinaryFunctionBase<B, R>, DynamicCopy> Value;
00180 typedef detail::KeyValuePair<Key, Value> Pair;
00181 typedef std::vector<Pair> FnMap;
00182
00183
00184
00185
00186 private:
00187
00188 void InternalRegister(FnMap& fnMap, TypeInfo key1, TypeInfo key2, Value value) const;
00189
00190
00191 typename FnMap::const_iterator Find(TypeInfo key1, TypeInfo key2, bool useCache = false) const;
00192
00193
00194 void EnsureCacheUpdate() const;
00195
00196
00197 Key MakeArgumentPair(TypeInfo key1, TypeInfo key2) const;
00198
00199
00200
00201
00202 private:
00203 FnMap mMap;
00204 mutable FnMap mCachedMap;
00205 mutable bool mNeedsCacheUpdate;
00206 bool mSymmetric;
00207 bool mDerivedToBase;
00208 };
00209
00233
00235
00236 }
00237
00238 #include <Thor/Detail/DoubleDispatcher.inl>
00239 #endif // THOR_DOUBLEDISPATCHER_HPP