-
Jan Trávníček authored
Explicit constructors, transform, and any_of
Jan Trávníček authoredExplicit constructors, transform, and any_of
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
CastRegistry.cpp 3.85 KiB
/*
* CastRegistry.cpp
*
* Created on: 21. 7. 2017
* Author: Jan Travnicek
*/
#include <registry/CastRegistry.hpp>
#include <alib/algorithm>
#include <exception>
namespace abstraction {
ext::map < ext::pair < std::string, std::string >, std::unique_ptr < CastRegistry::Entry > > & CastRegistry::getEntries ( ) {
static ext::map < ext::pair < std::string, std::string >, std::unique_ptr < Entry > > casts;
return casts;
}
void CastRegistry::unregisterCast ( const std::string & target, const std::string & param ) {
if ( getEntries ( ).erase ( ext::tie ( target, param ) ) == 0u )
throw std::invalid_argument ( "Entry from " + param + " to " + target + " not registered." );
}
void CastRegistry::registerCast ( std::string target, std::string param, std::unique_ptr < Entry > entry ) {
auto iter = getEntries ( ).insert ( std::make_pair ( ext::make_pair ( std::move ( target ), std::move ( param ) ), std::move ( entry ) ) );
if ( ! iter.second )
throw std::invalid_argument ( "Entry from " + iter.first->first.second + " to " + iter.first->first.first + " already registered." );
}
std::shared_ptr < abstraction::OperationAbstraction > CastRegistry::getAbstraction ( const std::string & target, const std::string & param ) {
auto entry = getEntries ( ).end ( );
for ( auto iter = getEntries ( ).begin ( ); iter != getEntries ( ).end ( ); ++ iter )
if ( iter->first.second == param && ext::is_same_type ( target, ext::erase_template_info ( iter->first.first ) ) ) {
if ( entry == getEntries ( ).end ( ) )
entry = iter;
else
throw std::invalid_argument ( "Entry from " + param + " to " + target + " is ambigous." );
}
if ( entry == getEntries ( ).end ( ) )
throw std::invalid_argument ( "Entry from " + param + " to " + target + " not available." );
return entry->second->getAbstraction ( );
}
bool CastRegistry::isNoOp ( const std::string & target, const std::string & param ) {
return ext::is_same_type ( ext::erase_template_info ( target ), ext::erase_template_info ( param ) );
}
bool CastRegistry::castAvailable ( const std::string & target, const std::string & param, bool implicitOnly ) {
for ( const std::pair < const ext::pair < std::string, std::string >, std::unique_ptr < Entry > > & entry : getEntries ( ) )
if ( ( entry.first.second == param && ext::is_same_type ( target, ext::erase_template_info ( entry.first.first ) ) )
&& ( ! implicitOnly || ! entry.second->isExplicit ( ) ) )
return true;
return false;
}
ext::list < ext::pair < std::string, bool > > CastRegistry::listFrom ( const std::string & type ) {
ext::list < ext::pair < std::string, bool > > res;
for ( const std::pair < const ext::pair < std::string, std::string >, std::unique_ptr < Entry > > & entry : getEntries ( ) )
if ( ext::is_same_type ( type, ext::erase_template_info ( entry.first.second ) ) )
res.push_back ( ext::make_pair ( entry.first.first, entry.second->isExplicit ( ) ) );
return res;
}
ext::list < ext::pair < std::string, bool > > CastRegistry::listTo ( const std::string & type ) {
ext::list < ext::pair < std::string, bool > > res;
for ( const std::pair < const ext::pair < std::string, std::string >, std::unique_ptr < Entry > > & entry : getEntries ( ) )
if ( ext::is_same_type ( type, ext::erase_template_info ( entry.first.first ) ) )
res.push_back ( ext::make_pair ( entry.first.second, entry.second->isExplicit ( ) ) );
return res;
}
ext::list < ext::tuple < std::string, std::string, bool > > CastRegistry::list ( ) {
ext::list < ext::tuple < std::string, std::string, bool > > res;
std::transform ( getEntries ( ).begin ( ), getEntries ( ).end ( ), std::back_inserter ( res ), [ ] ( const std::pair < const ext::pair < std::string, std::string >, std::unique_ptr < Entry > > & entry ) {
return ext::make_tuple ( entry.first.first, entry.first.second, entry.second->isExplicit ( ) );
} );
return res;
}
} /* namespace abstraction */