Skip to content
Snippets Groups Projects
ValueOperationAbstractionImpl.hpp 5.14 KiB
Newer Older
/*
 * ValueOperationAbstractionImpl.hpp
 *
 *  Created on: 11. 7. 2017
 *	  Author: Jan Travnicek
 */

#ifndef _VALUE_OPERATION_ABSTRACTION_IMPL_HPP_
#define _VALUE_OPERATION_ABSTRACTION_IMPL_HPP_

#include <alib/memory>
#include <abstraction/ValueInterface.hpp>
#include <common/AbstractionHelpers.hpp>

namespace abstraction {

template < class ReturnType >
class ValueOperationAbstractionImpl : virtual public ValueInterface < ReturnType > {
	mutable std::optional < ReturnType > m_data;

protected:
	void setData ( ReturnType && data ) {
		m_data = std::move ( data );
	}

	ReturnType && getValue ( ) const override {
		return std::move ( m_data.value ( ) );
	}

public:
	template < typename ... ParamTypes, typename Callable >
	inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( ParamTypes ) > & inputs ) {
		if ( ! evaluated ( ) )
			setData ( abstraction::apply < ParamTypes ... > ( callback, inputs ) );
	}

	bool evaluated ( ) const override {
		return ( bool ) m_data;
	}
};

template < class ReturnType >
class ValueOperationAbstractionImpl < const ReturnType > : virtual public ValueInterface < ReturnType > {
	mutable std::optional < ReturnType > m_data;

protected:
	void setData ( ReturnType && data ) {
		m_data = std::move ( data );
	}

	ReturnType && getValue ( ) const override {
		return std::move ( m_data.value ( ) );
	}

public:
	template < typename ... ParamTypes, typename Callable >
	inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( ParamTypes ) > & inputs ) {
		if ( ! evaluated ( ) )
			setData ( abstraction::apply < ParamTypes ... > ( callback, inputs ) );
	}

	bool evaluated ( ) const override {
		return ( bool ) m_data;
	}
};

template < class ReturnType >
class ValueOperationAbstractionImpl < ReturnType & > : virtual public ValueInterface < ReturnType > {
	mutable std::optional < std::reference_wrapper < ReturnType > > m_data;

protected:
	void setData ( ReturnType & data ) {
		m_data = std::reference_wrapper < ReturnType > ( data );
	}

	ReturnType && getValue ( ) const override {
		return std::move ( m_data->get ( ) );
	}

public:
	template < typename ... ParamTypes, typename Callable >
	inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( ParamTypes ) > & inputs ) {
		if ( ! evaluated ( ) )
			setData ( abstraction::apply < ParamTypes ... > ( callback, inputs ) );
	}

	bool evaluated ( ) const override {
		return ( bool ) m_data;
	}
};

template < class ReturnType >
class ValueOperationAbstractionImpl < const ReturnType & > : virtual public ValueInterface < ReturnType > {
	mutable std::optional < std::reference_wrapper < ReturnType > > m_data;

protected:
	void setData ( const ReturnType & data ) {
		m_data = std::reference_wrapper < ReturnType > ( const_cast < ReturnType & > ( data ) );
	}

	ReturnType && getValue ( ) const override {
		return std::move ( m_data->get ( ) );
	}

public:
	template < typename ... ParamTypes, typename Callable >
	inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( ParamTypes ) > & inputs ) {
		if ( ! evaluated ( ) )
			setData ( abstraction::apply < ParamTypes ... > ( callback, inputs ) );
	}

	bool evaluated ( ) const override {
		return ( bool ) m_data;
	}
};

template < class ReturnType >
class ValueOperationAbstractionImpl < ReturnType && > : virtual public ValueInterface < ReturnType > {
	mutable std::optional < std::reference_wrapper < ReturnType > > m_data;

protected:
	void setData ( ReturnType && data ) {
		m_data = std::reference_wrapper < ReturnType > ( data );
	}

	ReturnType && getValue ( ) const override {
		return std::move ( m_data->get ( ) );
	}

public:
	template < typename ... ParamTypes, typename Callable >
	inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( ParamTypes ) > & inputs ) {
		if ( ! evaluated ( ) )
			setData ( abstraction::apply < ParamTypes ... > ( callback, inputs ) );
	}

	bool evaluated ( ) const override {
		return ( bool ) m_data;
	}
};

template < class ReturnType >
class ValueOperationAbstractionImpl < const ReturnType && > : virtual public ValueInterface < ReturnType > {
	mutable std::optional < std::reference_wrapper < ReturnType > > m_data;

protected:
	void setData ( const ReturnType && data ) {
		m_data = std::reference_wrapper < ReturnType > ( const_cast < ReturnType & > ( data ) );
	}

	ReturnType && getValue ( ) const override {
		return std::move ( m_data->get ( ) );
	}

public:
	template < typename ... ParamTypes, typename Callable >
	inline void run_helper ( Callable callback, const ext::array < std::pair < std::shared_ptr < OperationAbstraction >, bool >, sizeof ... ( ParamTypes ) > & inputs ) {
		if ( ! evaluated ( ) )
			setData ( abstraction::apply < ParamTypes ... > ( callback, inputs ) );
	}

	bool evaluated ( ) const override {
		return ( bool ) m_data;
	}
};

} /* namespace abstraction */

#endif /* _VALUE_OPERATION_ABSTRACTION_IMPL_HPP_ */