-
Jan Trávníček authoredJan Trávníček authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ValueOperationAbstraction.hpp 13.25 KiB
/*
* ValueOperationAbstraction.hpp
*
* Created on: 11. 7. 2017
* Author: Jan Travnicek
*/
#ifndef _VALUE_OPERATION_ABSTRACTION_HPP_
#define _VALUE_OPERATION_ABSTRACTION_HPP_
#include <abstraction/OperationAbstraction.hpp>
#include <tuple>
#include <memory>
#include <typeindex>
#include <variant>
#include <abstraction/ValueProvider.hpp>
namespace abstraction {
template < class ReturnType >
class ValueOperationAbstraction : public OperationAbstraction, public ValueProvider < ReturnType >, public ValueProvider < ReturnType & >, public ValueProvider < const ReturnType & >, public ValueProvider < ReturnType && >, public ValueProvider < const ReturnType && > {
protected:
virtual ReturnType & getData ( ) const override {
return m_data.template get < ReturnType > ( );
}
virtual const ReturnType & getConstData ( ) const override {
return m_data.template get < ReturnType > ( );
}
mutable ext::variant < void, ReturnType > m_data;
public:
template < typename Callable, typename Object, typename ... Ts, size_t ... Indexes >
inline void member_run_helper ( Callable callback, const ext::tuple < Object, Ts ... > & inputs, const std::array < bool, 1 + sizeof ... ( Indexes ) > moves, std::index_sequence < Indexes ... > ) {
/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
( void ) inputs;
( void ) moves;
if ( ! isReady ( ) )
m_data = callback ( & std::get < 0 > ( inputs )->getValue ( false ), std::get < Indexes + 1 > ( inputs )->getValue ( std::get < Indexes + 1 > ( moves ) ) ... );
}
template < typename Callable, typename ... Ts, size_t ... Indexes >
inline void run_helper ( Callable callback, const ext::tuple < Ts ... > & inputs, const std::array < bool, sizeof ... ( Indexes ) > moves, std::index_sequence < Indexes ... > ) {
/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
( void ) inputs;
( void ) moves;
if ( ! isReady ( ) )
m_data = callback ( std::get < Indexes > ( inputs )->getValue ( std::get < Indexes > ( moves ) ) ... );
}
virtual bool isReady ( ) const override {
return m_data.template is < ReturnType > ( );
}
virtual ext::type_index getReturnTypeIndex ( ) const override {
return ext::type_index ( typeid ( ReturnType ) );
}
virtual ext::type_index getRuntimeReturnTypeIndex ( ) const override {
if ( isReady ( ) )
return ext::type_index ( typeid ( getData ( ) ) );
else
throw exception::CommonException ( "Runtime type unknown before evaluation." );
}
virtual bool cached ( ) const override {
return isReady ( );
}
};
template < class ReturnType >
class ValueOperationAbstraction < ReturnType & > : public OperationAbstraction, public ValueProvider < ReturnType & >, public ValueProvider < const ReturnType & >, public ValueProvider < ReturnType && >, public ValueProvider < const ReturnType && > {
protected:
virtual ReturnType & getData ( ) const override {
return m_data.template get < std::reference_wrapper < ReturnType > > ( ).get ( );
}
virtual const ReturnType & getConstData ( ) const override {
return m_data.template get < std::reference_wrapper < ReturnType > > ( ).get ( );
}
mutable ext::variant < void, std::reference_wrapper < ReturnType > > m_data;
public:
template < typename Callable, typename Object, typename ... Ts, size_t ... Indexes >
inline void member_run_helper ( Callable callback, const ext::tuple < Object, Ts ... > & inputs, const std::array < bool, 1 + sizeof ... ( Indexes ) > moves, std::index_sequence < Indexes ... > ) {
/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
( void ) inputs;
( void ) moves;
if ( ! isReady ( ) )
m_data = std::reference_wrapper < ReturnType > ( callback ( & std::get < 0 > ( inputs )->getValue ( false ), std::get < Indexes + 1 > ( inputs )->getValue ( std::get < Indexes + 1 > ( moves ) ) ... ) );
}
template < typename Callable, typename ... Ts, size_t ... Indexes >
inline void run_helper ( Callable callback, const ext::tuple < Ts ... > & inputs, const std::array < bool, sizeof ... ( Indexes ) > moves, std::index_sequence < Indexes ... > ) {
/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
( void ) inputs;
( void ) moves;
if ( ! isReady ( ) )
m_data = std::reference_wrapper < ReturnType > ( callback ( std::get < Indexes > ( inputs )->getValue ( std::get < Indexes > ( moves ) ) ... ) );
}
virtual bool isReady ( ) const override {
return m_data.template is < std::reference_wrapper < ReturnType > > ( );
}
virtual ext::type_index getReturnTypeIndex ( ) const override {
return ext::type_index ( typeid ( ReturnType ) );
}
virtual ext::type_index getRuntimeReturnTypeIndex ( ) const override {
if ( isReady ( ) )
return ext::type_index ( typeid ( getData ( ) ) );
else
throw exception::CommonException ( "Runtime type unknown before evaluation." );
}
virtual bool cached ( ) const override {
return isReady ( );
}
};
template < class ReturnType >
class ValueOperationAbstraction < const ReturnType & > : public OperationAbstraction, public ValueProvider < const ReturnType & >, public ValueProvider < const ReturnType && > {
protected:
virtual const ReturnType & getConstData ( ) const override {
return m_data.template get < std::reference_wrapper < const ReturnType > > ( ).get ( );
}
mutable ext::variant < void, std::reference_wrapper < const ReturnType > > m_data;
public:
template < typename Callable, typename Object, typename ... Ts, size_t ... Indexes >
inline void member_run_helper ( Callable callback, const ext::tuple < Object, Ts ... > & inputs, const std::array < bool, 1 + sizeof ... ( Indexes ) > moves, std::index_sequence < Indexes ... > ) {
/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
( void ) inputs;
( void ) moves;
if ( ! isReady ( ) )
m_data = std::reference_wrapper < const ReturnType > ( callback ( & std::get < 0 > ( inputs )->getValue ( false ), std::get < Indexes + 1 > ( inputs )->getValue ( std::get < Indexes + 1 > ( moves ) ) ... ) );
}
template < typename Callable, typename ... Ts, size_t ... Indexes >
inline void run_helper ( Callable callback, const ext::tuple < Ts ... > & inputs, const std::array < bool, sizeof ... ( Indexes ) > moves, std::index_sequence < Indexes ... > ) {
/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
( void ) inputs;
( void ) moves;
if ( ! isReady ( ) )
m_data = std::reference_wrapper < const ReturnType > ( callback ( std::get < Indexes > ( inputs )->getValue ( std::get < Indexes > ( moves ) ) ... ) );
}
virtual bool isReady ( ) const override {
return m_data.template is < std::reference_wrapper < const ReturnType > > ( );
}
virtual ext::type_index getReturnTypeIndex ( ) const override {
return ext::type_index ( typeid ( ReturnType ) );
}
virtual ext::type_index getRuntimeReturnTypeIndex ( ) const override {
if ( isReady ( ) )
return ext::type_index ( typeid ( getConstData ( ) ) );
else
throw exception::CommonException ( "Runtime type unknown before evaluation." );
}
virtual bool cached ( ) const override {
return isReady ( );
}
};
template < class ReturnType >
class ValueOperationAbstraction < ReturnType && > : public OperationAbstraction, public ValueProvider < ReturnType & >, public ValueProvider < const ReturnType & >, public ValueProvider < ReturnType && >, public ValueProvider < const ReturnType && > {
protected:
virtual ReturnType & getData ( ) const override {
return m_data.template get < std::reference_wrapper < ReturnType > > ( ).get ( );
}
virtual const ReturnType & getConstData ( ) const override {
return m_data.template get < std::reference_wrapper < ReturnType > > ( ).get ( );
}
mutable ext::variant < void, std::reference_wrapper < ReturnType > > m_data;
public:
template < typename Callable, typename Object, typename ... Ts, size_t ... Indexes >
inline void member_run_helper ( Callable callback, const ext::tuple < Object, Ts ... > & inputs, const std::array < bool, 1 + sizeof ... ( Indexes ) > moves, std::index_sequence < Indexes ... > ) {
/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
( void ) inputs;
( void ) moves;
if ( ! isReady ( ) ) {
ReturnType && res = callback ( & std::get < 0 > ( inputs )->getValue ( false ), std::get < Indexes + 1 > ( inputs )->getValue ( std::get < Indexes + 1 > ( moves ) ) ... );
m_data = std::reference_wrapper < ReturnType > ( res );
}
}
template < typename Callable, typename ... Ts, size_t ... Indexes >
inline void run_helper ( Callable callback, const ext::tuple < Ts ... > & inputs, const std::array < bool, sizeof ... ( Indexes ) > moves, std::index_sequence < Indexes ... > ) {
/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
( void ) inputs;
( void ) moves;
if ( ! isReady ( ) ) {
ReturnType && res = callback ( std::get < Indexes > ( inputs )->getValue ( std::get < Indexes > ( moves ) ) ... );
m_data = std::reference_wrapper < ReturnType > ( res );
}
}
virtual bool isReady ( ) const override {
return m_data.template is < std::reference_wrapper < ReturnType > > ( );
}
virtual ext::type_index getReturnTypeIndex ( ) const override {
return ext::type_index ( typeid ( ReturnType ) );
}
virtual ext::type_index getRuntimeReturnTypeIndex ( ) const override {
if ( isReady ( ) )
return ext::type_index ( typeid ( getData ( ) ) );
else
throw exception::CommonException ( "Runtime type unknown before evaluation." );
}
virtual bool cached ( ) const override {
return isReady ( );
}
};
template < class ReturnType >
class ValueOperationAbstraction < const ReturnType && > : public OperationAbstraction, public ValueProvider < const ReturnType & >, public ValueProvider < const ReturnType && > {
protected:
virtual const ReturnType & getConstData ( ) const override {
return m_data.template get < std::reference_wrapper < const ReturnType > > ( ).get ( );
}
mutable ext::variant < void, std::reference_wrapper < const ReturnType > > m_data;
public:
template < typename Callable, typename Object, typename ... Ts, size_t ... Indexes >
inline void member_run_helper ( Callable callback, const ext::tuple < Object, Ts ... > & inputs, const std::array < bool, 1 + sizeof ... ( Indexes ) > moves, std::index_sequence < Indexes ... > ) {
/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
( void ) inputs;
( void ) moves;
if ( ! isReady ( ) ) {
const ReturnType && res = callback ( & std::get < 0 > ( inputs )->getValue ( false ), std::get < Indexes + 1 > ( inputs )->getValue ( std::get < Indexes + 1 > ( moves ) ) ... );
m_data = std::reference_wrapper < const ReturnType > ( res );
}
}
template < typename Callable, typename ... Ts, size_t ... Indexes >
inline void run_helper ( Callable callback, const ext::tuple < Ts ... > & inputs, const std::array < bool, sizeof ... ( Indexes ) > moves, std::index_sequence < Indexes ... > ) {
/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
( void ) inputs;
( void ) moves;
if ( ! isReady ( ) ) {
const ReturnType && res = callback ( std::get < Indexes > ( inputs )->getValue ( std::get < Indexes > ( moves ) ) ... );
m_data = std::reference_wrapper < const ReturnType > ( res );
}
}
virtual bool isReady ( ) const override {
return m_data.template is < std::reference_wrapper < const ReturnType > > ( );
}
virtual ext::type_index getReturnTypeIndex ( ) const override {
return ext::type_index ( typeid ( ReturnType ) );
}
virtual ext::type_index getRuntimeReturnTypeIndex ( ) const override {
if ( isReady ( ) )
return ext::type_index ( typeid ( getConstData ( ) ) );
else
throw exception::CommonException ( "Runtime type unknown before evaluation." );
}
virtual bool cached ( ) const override {
return isReady ( );
}
};
template < >
class ValueOperationAbstraction < void > : public OperationAbstraction {
public:
template < typename Callable, typename Object, typename ... Ts, size_t ... Indexes >
inline void member_run_helper ( Callable callback, const ext::tuple < Object, Ts ... > & inputs, const std::array < bool, 1 + sizeof ... ( Indexes ) > moves, std::index_sequence < Indexes ... > ) {
/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
( void ) inputs;
( void ) moves;
callback ( & std::get < 0 > ( inputs )->getValue ( false ), std::get < Indexes + 1 > ( inputs )->getValue ( std::get < Indexes + 1 > ( moves ) ) ... );
}
template < typename Callable, typename ... Ts, size_t ... Indexes >
inline void run_helper ( Callable callback, const ext::tuple < Ts ... > & inputs, const std::array < bool, sizeof ... ( Indexes ) > moves, std::index_sequence < Indexes ... > ) const {
/* make unused parameter warning go away in case of sizeof ... ( Ts ) == 0 */
( void ) inputs;
( void ) moves;
callback ( std::get < Indexes > ( inputs )->getValue ( std::get < Indexes > ( moves ) ) ... );
}
virtual bool isReady ( ) const override {
return true;
}
virtual ext::type_index getReturnTypeIndex ( ) const override {
return ext::type_index ( typeid ( void ) );
}
virtual ext::type_index getRuntimeReturnTypeIndex ( ) const override {
return ext::type_index ( typeid ( void ) );
}
virtual bool cached ( ) const override {
return false;
}
};
} /* namespace abstraction */
#endif /* _VALUE_OPERATION_ABSTRACTION_HPP_ */