diff --git a/alib2common/src/abstraction/AnyaryOperationAbstraction.hpp b/alib2common/src/abstraction/AnyaryOperationAbstraction.hpp new file mode 100644 index 0000000000000000000000000000000000000000..180363e540df8871031b4c2f002a6afe552f9d85 --- /dev/null +++ b/alib2common/src/abstraction/AnyaryOperationAbstraction.hpp @@ -0,0 +1,93 @@ +/* + * AnyaryOperationAbstraction.hpp + * + * Created on: 20. 8. 2017 + * Author: Jan Travnicek + */ + +#ifndef _ANYARY_OPERATION_ABSTRACTION_HPP_ +#define _ANYARY_OPERATION_ABSTRACTION_HPP_ + +#include <abstraction/ValueOperationAbstraction.hpp> +#include <tuple> +#include <memory> +#include <abstraction/Registry.h> + +namespace abstraction { + +template < class ReturnType, class ParamType > +class AnyaryOperationAbstraction : public ValueOperationAbstraction < ReturnType > { +protected: + ext::vector < std::pair < std::shared_ptr < ValueProvider < ParamType > >, bool > > m_params; + +private: + virtual bool attachInput ( const std::shared_ptr < OperationAbstraction > & input, unsigned index, bool move ) override { + std::shared_ptr < ValueProvider < ParamType > > validData = std::dynamic_pointer_cast < ValueProvider < ParamType > > ( input ); + if ( validData ) { + if ( m_params.size ( ) < index + 1 ) + m_params.resize ( index + 1 ); + + m_params [ index ] = std::make_pair ( validData, move ); + return true; + } else { + return false; + } + } + + virtual bool detachInput ( unsigned index ) override { + if ( index >= m_params.size ( ) ) + throw exception::CommonException ( "Parameter index out of bounds."); + + m_params [ index ].first = nullptr; + m_params [ index ].second = false; + + return true; + } + +public: + AnyaryOperationAbstraction ( ) { + } + + virtual bool inputsReady ( ) const override { + for ( const auto & param : m_params ) + if ( ! ( bool ) param.first || ! param.first->isReady ( ) ) + return false; + + return true; + } + + virtual bool inputsAttached ( ) const override { + for ( const auto & param : m_params ) + if ( ! ( bool ) param.first ) + return false; + + return true; + } + + virtual bool eval ( ) override { + if ( ! inputsAttached ( ) ) + return false; + + if ( this->cached ( ) ) + return true; + + for ( const std::pair < std::shared_ptr < ValueProvider < ParamType > >, bool > & param : m_params ) + if ( ! param.first->eval ( ) ) + return false; + + return this->run ( ); + } + + virtual unsigned numberOfParams ( ) const override { + return m_params.size ( ); + } + + virtual ext::type_index getParamTypeIndex ( unsigned ) const override { + return ext::type_index ( typeid ( ParamType ) ); + } + +}; + +} /* namespace abstraction */ + +#endif /* _ANYARY_OPERATION_ABSTRACTION_HPP_ */ diff --git a/alib2common/src/abstraction/ContainerRegistry.cpp b/alib2common/src/abstraction/ContainerRegistry.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5703a9e579bcec66edc4ac0ea6ef2a806a53a55d --- /dev/null +++ b/alib2common/src/abstraction/ContainerRegistry.cpp @@ -0,0 +1,56 @@ +/* + * ContainerRegistry.cpp + * + * Created on: 19. 8. 2017 + * Author: Jan Travnicek + */ + +#include <abstraction/ContainerRegistry.hpp> +#include <foreach> + +namespace abstraction { + +bool ContainerRegistry::hasAbstraction ( const std::string & container ) { + return getEntries ( ).count ( container ); +} + +std::shared_ptr < abstraction::OperationAbstraction > ContainerRegistry::getAbstraction ( const std::string & container, const std::string & paramType ) { + std::set < std::string > paramTypes; + if ( alib::namingApi::hasTypes ( paramType ) ) + paramTypes = ext::transform < std::string > ( alib::namingApi::getTypes ( paramType ), [ ] ( const ext::type_index & type ) { return ext::to_string ( type ); } ); + else + paramTypes.insert ( paramType ); + + auto group = getEntries ( ).find ( container ); + if ( group == getEntries ( ).end ( ) ) + throw exception::CommonException ( "Entry " + container + " not available" ); + + for ( const ext::pair < std::string, std::shared_ptr < Entry > > & entry : group->second ) + if ( paramTypes.count ( entry.first ) ) + return entry.second->getAbstraction ( ); + + throw exception::CommonException ( "Entry for " + container + " parametrized with " + paramType + " not available." ); +} + +ext::set < std::string > ContainerRegistry::listOverloads ( const std::string & container ) { + auto group = getEntries ( ).find ( container ); + if ( group == getEntries ( ).end ( ) ) + throw exception::CommonException ( "Entry " + container + " not available" ); + + ext::set < std::string > res; + for ( const ext::pair < std::string, std::shared_ptr < Entry > > & entry : group->second ) + res.insert ( entry.first ); + + return res; +} + +ext::set < std::string > ContainerRegistry::list ( ) { + ext::set < std::string > res; + + for ( const std::pair < const std::string, ext::vector < ext::pair < std::string, std::shared_ptr < Entry > > > > & groups : getEntries ( ) ) + res.insert ( groups.first ); + + return res; +} + +} /* namespace abstraction */ diff --git a/alib2common/src/abstraction/ContainerRegistry.hpp b/alib2common/src/abstraction/ContainerRegistry.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6b3b75093c07676ab9933a81260e7678cfd580bc --- /dev/null +++ b/alib2common/src/abstraction/ContainerRegistry.hpp @@ -0,0 +1,78 @@ +/* + * ContainerRegistry.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _CONTAINER_REGISTRY_HPP_ +#define _CONTAINER_REGISTRY_HPP_ + +#include <functional> +#include <memory> +#include <vector> +#include <string> +#include <set> + +#include <exception/CommonException.h> +#include <abstraction/OperationAbstraction.hpp> + +#include <core/namingApi.hpp> + +namespace abstraction { + +class ContainerRegistry { + class Entry { + public: + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const = 0; + }; + + template < class Params > + class SetEntryImpl : public Entry { + public: + virtual std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override; + }; + + static ext::map < std::string, ext::vector < ext::pair < std::string, std::shared_ptr < Entry > > > > & getEntries ( ) { + static ext::map < std::string, ext::vector < ext::pair < std::string, std::shared_ptr < Entry > > > > containerGroups; + return containerGroups; + }; +public: + template < class ParamTypes > + static void registerSet ( ) { + std::string container = "Set"; + + std::string paramName = ext::to_string < typename std::decay < ParamTypes >::type > ( ); + + auto & group = getEntries ( ) [ container ]; + for ( const ext::pair < std::string, std::shared_ptr < Entry > > & entry : group ) + if ( entry.first == paramName ) + throw exception::CommonException ( "Callback for " + container + " already registered." ); + + std::shared_ptr < Entry > entryValue = std::make_shared < SetEntryImpl < ParamTypes > > ( ); + group.push_back ( ext::make_pair ( paramName, entryValue ) ); + } + + static bool hasAbstraction ( const std::string & container ); + + static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( const std::string & container, const std::string & paramType ); + + static ext::set < std::string > listOverloads ( const std::string & algorithm ); + + static ext::set < std::string > list ( ); +}; + +} /* namespace abstraction */ + +#include <abstraction/SetAbstraction.hpp> + +namespace abstraction { + +template < class Param > +std::shared_ptr < abstraction::OperationAbstraction > ContainerRegistry::SetEntryImpl < Param >::getAbstraction ( ) const { + return std::make_shared < abstraction::SetAbstraction < Param > > ( ); +} + +} /* namespace abstraction */ + +#endif /* _CONTAINER_REGISTRY_HPP_ */ diff --git a/alib2common/src/abstraction/PrimitiveRegistrator.cpp b/alib2common/src/abstraction/PrimitiveRegistrator.cpp index ad4be3902dd059aec097ff277d57478e18d32e30..de686e144c3d342282ce7f3b3a8beef7b389bd70 100644 --- a/alib2common/src/abstraction/PrimitiveRegistrator.cpp +++ b/alib2common/src/abstraction/PrimitiveRegistrator.cpp @@ -17,6 +17,8 @@ #include <primitive/UnsignedLong.h> #include <primitive/String.h> +#include "SetAbstraction.hpp" + namespace abstraction { class PrimitiveCasts { diff --git a/alib2common/src/abstraction/Registry.cpp b/alib2common/src/abstraction/Registry.cpp index dde8c227eac9bf629ee8a249a2a7a6da141ac6c6..0b874f96c8c04e9b2b128201c98aa95ac9a00814 100644 --- a/alib2common/src/abstraction/Registry.cpp +++ b/alib2common/src/abstraction/Registry.cpp @@ -16,6 +16,7 @@ #include <abstraction/CastRegistry.hpp> #include <abstraction/NormalizeRegistry.hpp> #include <abstraction/DowncastRegistry.hpp> +#include <abstraction/ContainerRegistry.hpp> #include <core/namingApi.hpp> @@ -57,6 +58,10 @@ ext::set < ext::pair < ext::pair < std::string, ext::set < abstraction::ParamQua return AlgorithmRegistry::listOverloads ( algorithm ); } +std::shared_ptr < abstraction::OperationAbstraction > Registry::getContainerAbstraction ( const std::string & container, const std::string & type ) { + return ContainerRegistry::getAbstraction ( container, type ); +} + std::shared_ptr < abstraction::OperationAbstraction > Registry::getAlgorithmAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes ) { return AlgorithmRegistry::getAbstraction ( name, paramTypes ); } diff --git a/alib2common/src/abstraction/Registry.h b/alib2common/src/abstraction/Registry.h index 027c0fd5e6f6aa287f91aef2f8e262a6526964f9..8af926b16a7aa65fd726c78a12bc7eef91a3d85a 100644 --- a/alib2common/src/abstraction/Registry.h +++ b/alib2common/src/abstraction/Registry.h @@ -10,6 +10,7 @@ #include <abstraction/OperationAbstraction.hpp> #include <abstraction/common/ParamQualifiers.hpp> +#include <abstraction/common/AlgorithmCategories.hpp> namespace abstraction { @@ -29,6 +30,7 @@ public: static ext::set < ext::pair < std::string, ext::set < std::string > > > listNames ( ); + static std::shared_ptr < abstraction::OperationAbstraction > getContainerAbstraction ( const std::string & container, const std::string & type ); static std::shared_ptr < abstraction::OperationAbstraction > getAlgorithmAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes ); static std::shared_ptr < abstraction::OperationAbstraction > getAlgorithmAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes, bool & unwrap, bool & normalize ); static std::shared_ptr < abstraction::OperationAbstraction > getCastAbstraction ( const std::string & target, const std::string & param, bool & normalize ); diff --git a/alib2common/src/abstraction/SetAbstraction.hpp b/alib2common/src/abstraction/SetAbstraction.hpp new file mode 100644 index 0000000000000000000000000000000000000000..cf1395b7880d7d75ecdd73a77f8074c0ce9d1801 --- /dev/null +++ b/alib2common/src/abstraction/SetAbstraction.hpp @@ -0,0 +1,47 @@ +/* + * SetAbstraction.hpp + * + * Created on: 11. 7. 2017 + * Author: Jan Travnicek + */ + +#ifndef _SET_ABSTRACTION_HPP_ +#define _SET_ABSTRACTION_HPP_ + +#include <abstraction/AnyaryOperationAbstraction.hpp> +#include <tuple> +#include <memory> +#include <abstraction/Registry.h> +#include <foreach> + +namespace abstraction { + +template < class ParamType > +class SetAbstraction : public AnyaryOperationAbstraction < ext::set < ParamType >, ParamType > { + +public: + SetAbstraction ( ) { + } + + virtual bool run ( ) override { + if ( ! this->inputsReady ( ) ) + return false; + + if ( this->cached ( ) ) + return true; + + ext::set < ParamType > theSet; + for ( const std::pair < std::shared_ptr < ValueProvider < ParamType > >, bool > & param : this->m_params ) { + theSet.insert ( param.first->getValue ( param.second ) ); + } + + this->m_data = theSet; + + return true; + } + +}; + +} /* namespace abstraction */ + +#endif /* _SET_ABSTRACTION_HPP_ */