Skip to content
Snippets Groups Projects
Commit 2b313227 authored by Jan Trávníček's avatar Jan Trávníček
Browse files

add another dispatch algorithm

parent 7fb6ea1e
No related branches found
No related tags found
No related merge requests found
......@@ -440,6 +440,65 @@ public:
 
};
 
template < class Algorithm, class ReturnType, class FirstParameterType, class SecondParameterType, class StaticParamType >
class DoubleDispatchLastStaticParam {
public:
class RegistratorWrapperBase {
public:
virtual ReturnType eval ( const FirstParameterType &, const SecondParameterType &, StaticParamType ) = 0;
};
private:
std::map < std::pair < std::type_index, std::type_index >, RegistratorWrapperBase * > registeredFunctions;
static DoubleDispatchLastStaticParam < Algorithm, ReturnType, FirstParameterType, SecondParameterType, StaticParamType > & getInstance ( ) {
static DoubleDispatchLastStaticParam < Algorithm, ReturnType, FirstParameterType, SecondParameterType, StaticParamType > res;
return res;
}
public:
template < class RealReturnType, class RealFirstParameterType, class RealSecondParameterType >
class RegistratorWrapper : public RegistratorWrapperBase {
std::function < RealReturnType ( const RealFirstParameterType &, const RealSecondParameterType &, StaticParamType ) > callback;
public:
ReturnType eval ( const FirstParameterType & first, const SecondParameterType & second, StaticParamType res ) {
return ReturnType ( callback ( ( const RealFirstParameterType & ) first, ( const RealSecondParameterType & ) second, res ) );
}
RegistratorWrapper ( RealReturnType ( * callback ) ( const RealFirstParameterType &, const RealSecondParameterType &, StaticParamType ) ) : callback ( callback ) {
if ( !getInstance ( ).registeredFunctions.insert ( std::make_pair ( std::make_pair ( std::type_index ( typeid ( RealFirstParameterType ) ), std::type_index ( typeid ( RealSecondParameterType ) ) ), this ) ).second ) {
std::string firstType = std::cstringToString ( std::type_name < RealFirstParameterType > ( ) );
std::string secondType = std::cstringToString ( std::type_name < RealSecondParameterType > ( ) );
std::string classType = std::cstringToString ( std::type_name < Algorithm > ( ) );
throw::exception::CommonException ( "Callback for (" + firstType + ", " + secondType + ") already registered on " + classType + "." );
}
}
};
static ReturnType dispatch ( const FirstParameterType & first, const SecondParameterType & second, StaticParamType res ) {
typename std::map < std::pair < std::type_index, std::type_index >, RegistratorWrapperBase * >::iterator callback = getInstance ( ).registeredFunctions.find ( std::make_pair ( std::type_index ( typeid ( first ) ), std::type_index ( typeid ( second ) ) ) );
if ( callback == getInstance ( ).registeredFunctions.end ( ) ) {
std::string firstType = std::cstringToString ( std::type_name ( typeid ( first ) ) );
std::string secondType = std::cstringToString ( std::type_name ( typeid ( second ) ) );
std::string classType = std::cstringToString ( std::type_name < Algorithm > ( ) );
throw::exception::CommonException ( "Callback for (" + firstType + ", " + secondType + ") not registered on " + classType + "." );
}
return callback->second->eval ( first, second, res );
}
};
} /* namespace std */
 
#endif /* MULTIPLE_DISPATCH_H_ */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment