/* * PackingAbstraction.hpp * * Created on: 29. 5. 2018 * Author: Jan Travnicek */ #ifndef _PACKING_ABSTRACTION_HPP_ #define _PACKING_ABSTRACTION_HPP_ #include <alib/memory> #include <alib/array> #include <abstraction/ValueOperationAbstraction.hpp> #include <registry/Registry.h> namespace abstraction { template < size_t NumberOfParams > class PackingAbstraction : public OperationAbstraction { struct ConnectionTarget { size_t targetId; size_t paramPosition; }; ext::vector < std::shared_ptr < abstraction::OperationAbstraction > > m_abstractions; ext::array < ext::vector < ConnectionTarget >, NumberOfParams > m_connections; size_t m_resultId; public: PackingAbstraction ( ext::vector < std::shared_ptr < abstraction::OperationAbstraction > > abstractions, size_t resultId ) : m_abstractions ( std::move ( abstractions ) ), m_resultId ( resultId ) { } bool setInnerConnection ( size_t sourceId, size_t targetId, size_t paramPosition, bool move ) { return m_abstractions [ targetId ]->attachInput ( m_abstractions [ sourceId ], paramPosition, move, true ); } bool clearInnerConnection ( size_t targetId, size_t paramPosition ) { return m_abstractions [ targetId ]->detachInput ( paramPosition ); } void setOuterConnection ( size_t sourceId, size_t targetId, size_t paramPosition ) { m_connections [ sourceId ].push_back ( ConnectionTarget { targetId, paramPosition } ); } private: bool attachInput ( const std::shared_ptr < OperationAbstraction > & input, size_t index, bool move, bool checkInput ) override { bool res = true; for ( const ConnectionTarget & target : m_connections [ index ] ) res &= m_abstractions [ target.targetId ]->attachInput ( input, target.paramPosition, move, checkInput ); if ( ! res ) this->detachInput ( index ); return res; } bool detachInput ( size_t index ) override { bool res = true; for ( const ConnectionTarget & target : m_connections [ index ] ) res &= m_abstractions [ target.targetId ]->detachInput ( target.paramPosition ); return res; } bool checkInput ( const std::shared_ptr < OperationAbstraction > & input, size_t index ) const override { for ( const ConnectionTarget & target : m_connections [ index ] ) if ( ! m_abstractions [ target.targetId ]->checkInput ( input, target.paramPosition ) ) return false; return true; } public: bool inputsAttached ( ) const override { for ( const std::shared_ptr < abstraction::OperationAbstraction > & operation : m_abstractions ) if ( ! operation->inputsAttached ( ) ) return false; return true; } bool run ( ) override { return m_abstractions [ m_resultId ]->eval ( ); } bool eval ( ) override { if ( ! inputsAttached ( ) ) return false; if ( this->evaluated ( ) ) return true; return this->run ( ); } size_t numberOfParams ( ) const override { return NumberOfParams; } bool evaluated ( ) const override { return m_abstractions [ m_resultId ]->evaluated ( ); } ext::type_index getParamTypeIndex ( size_t index ) const override { return m_abstractions [ m_connections.at ( index ) [ 0 ].targetId ]->getParamTypeIndex ( m_connections.at ( index ) [ 0 ].paramPosition ); } ext::set < abstraction::ParamQualifiers::ParamQualifier > getParamTypeQualifiers ( size_t index ) const override { return m_abstractions [ m_connections.at ( index ) [ 0 ].targetId ]->getParamTypeQualifiers ( m_connections.at ( index ) [ 0 ].paramPosition ); } ext::type_index getReturnTypeIndex ( ) const override { return m_abstractions [ m_resultId ]->getReturnTypeIndex ( ); } ext::set < abstraction::ParamQualifiers::ParamQualifier > getReturnTypeQualifiers ( ) const override { return m_abstractions [ m_resultId ]->getReturnTypeQualifiers ( ); } std::shared_ptr < abstraction::OperationAbstraction > getProxyAbstraction ( ) override { return m_abstractions [ m_resultId ]->getProxyAbstraction ( ); } std::shared_ptr < abstraction::OperationAbstraction > getVariableOperationAbstraction ( ) override { return m_abstractions [ m_resultId ]->getProxyAbstraction ( )->getVariableOperationAbstraction ( ); } }; } /* namespace abstraction */ #endif /* _PACKING_ABSTRACTION_HPP_ */