Skip to content
Snippets Groups Projects
NaryOperationAbstractionImpl.hpp 2.43 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
     * NaryOperationAbstractionImpl.hpp
     *
     *  Created on: 20. 8. 2017
     *	  Author: Jan Travnicek
     */
    
    #ifndef _NARY_OPERATION_ABSTRACTION_IMPL_HPP_
    #define _NARY_OPERATION_ABSTRACTION_IMPL_HPP_
    
    #include <alib/memory>
    #include <alib/array>
    
    #include <abstraction/OperationAbstraction.hpp>
    
    namespace abstraction {
    
    template < size_t N >
    class NaryOperationAbstractionImpl : virtual public OperationAbstraction {
    	ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, N > m_params;
    
    protected:
    	ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, N > & getParams ( ) {
    		return m_params;
    	}
    
    private:
    	bool attachInput ( const std::shared_ptr < OperationAbstraction > & input, size_t index, bool move, bool checkInput ) override {
    		if ( index >= m_params.size ( ) )
    			throw std::invalid_argument ( "Parameter index " + ext::to_string ( index ) + " out of bounds.");
    
    		if ( input == nullptr )
    			return false;
    
    		if ( checkInput && ! this->checkInput ( input, index ) )
    			return false;
    
    		m_params [ index ].first = input;
    		m_params [ index ].second = move;
    
    		return true;
    	}
    
    	bool detachInput ( size_t index ) override {
    		if ( index >= m_params.size ( ) )
    			throw std::invalid_argument ( "Parameter index " + ext::to_string ( index ) + " out of bounds.");
    
    		m_params [ index ].first = nullptr;
    		m_params [ index ].second = false;
    
    		return true;
    	}
    
    public:
    	NaryOperationAbstractionImpl ( ) {
    		for ( size_t i = 0; i < N; ++ i ) {
    			m_params [ i ].first = nullptr;
    			m_params [ i ].second = false;
    		}
    	}
    
    	bool inputsAttached ( ) const override {
    		for ( const std::pair < std::shared_ptr < OperationAbstraction >, bool > & param : m_params )
    			if ( ! param.first )
    				return false;
    
    		return true;
    	}
    
    	bool eval ( ) override {
    		if ( ! inputsAttached ( ) )
    			return false;
    
    		if ( this->evaluated ( ) )
    			return true;
    
    		for ( const std::pair < std::shared_ptr < OperationAbstraction >, bool > & param : m_params )
    			if ( ! param.first->eval ( ) )
    				return false;
    
    		return this->run ( );
    	}
    
    	size_t numberOfParams ( ) const override {
    		return N;
    	}
    
    };
    
    } /* namespace abstraction */
    
    extern template class abstraction::NaryOperationAbstractionImpl < 0 >;
    extern template class abstraction::NaryOperationAbstractionImpl < 1 >;
    extern template class abstraction::NaryOperationAbstractionImpl < 2 >;
    extern template class abstraction::NaryOperationAbstractionImpl < 3 >;
    
    #endif /* _NARY_OPERATION_ABSTRACTION_IMPL_HPP_ */