-
Jan Trávníček authoredJan Trávníček authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
AlgorithmRegistry.hpp 3.73 KiB
/*
* AlgorithmRegistry.hpp
*
* Created on: 11. 7. 2017
* Author: Jan Travnicek
*/
#ifndef _ALGORITHM_REGISTRY_HPP_
#define _ALGORITHM_REGISTRY_HPP_
#include <functional>
#include <memory>
#include <vector>
#include <string>
#include <exception/CommonException.h>
#include <abstraction/OperationAbstraction.hpp>
#include <abstraction/common/ParamQualifiers.hpp>
namespace abstraction {
class AlgorithmRegistry {
class Entry {
bool m_downcast;
bool m_normalize;
public:
Entry ( bool downcast, bool normalize ) : m_downcast ( downcast ), m_normalize ( normalize ) {
}
virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const = 0;
bool getDowncast ( ) const {
return m_downcast;
}
bool getNormalize ( ) const {
return m_normalize;
}
};
template < class Return, class ... Params >
class EntryImpl : public Entry {
std::function < Return ( Params ... ) > m_callback;
public:
EntryImpl ( std::function < Return ( Params ... ) > callback, bool downcast, bool normalize ) : Entry ( downcast, normalize ), m_callback ( callback ) {
}
virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override;
};
static ext::map < std::string, ext::vector < std::pair < ext::vector < std::pair < std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier > > >, std::shared_ptr < Entry > > > > & getEntries ( ) {
static ext::map < std::string, ext::vector < std::pair < ext::vector < std::pair < std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier > > >, std::shared_ptr < Entry > > > > algorithmGroups;
return algorithmGroups;
};
enum class MatchType {
EXACT,
CAST,
INCOMPATIBLE
};
public:
template < class Algo, class ReturnType, class ... ParamTypes >
static void registerAlgorithm ( ReturnType ( * callback ) ( ParamTypes ... ), bool downcast, bool normalize ) {
std::string algorithm = ext::to_string < Algo > ( );
ext::vector < std::pair < std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier > > > params;
( void ) std::initializer_list < int > { ( params.push_back ( std::make_pair ( ext::to_string < typename std::decay < ParamTypes >::type > ( ), abstraction::ParamQualifiers::paramQualifiers < ParamTypes > ( ) ) ), 0 ) ... };
auto & group = getEntries ( ) [ algorithm ];
for ( const std::pair < ext::vector < std::pair < std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier > > >, std::shared_ptr < Entry > > & entry : group )
if ( entry.first == params )
throw exception::CommonException ( "Callback for " + algorithm + " already registered." );
auto entryValue = std::make_pair ( params, std::shared_ptr < Entry > ( new EntryImpl < ReturnType, ParamTypes ... > ( callback, downcast, normalize ) ) );
group.push_back ( std::move ( entryValue ) );
}
static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes, bool & downcast, bool & normalize );
static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes );
static void listGroup ( const std::string & group );
static void listOverloads ( const std::string & algorithm );
static void list ( );
};
} /* namespace abstraction */
#include <abstraction/AlgorithmAbstraction.hpp>
namespace abstraction {
template < class Return, class ... Params >
std::shared_ptr < abstraction::OperationAbstraction > AlgorithmRegistry::EntryImpl < Return, Params ... >::getAbstraction ( ) const {
return std::make_shared < abstraction::AlgorithmAbstraction < Return, Params ... > > ( m_callback );
}
} /* namespace abstraction */
#endif /* _ALGORITHM_REGISTRY_HPP_ */