-
Jan Trávníček authoredJan Trávníček authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ValueHolder.hpp 4.92 KiB
/*
* ValueHolder.hpp
*
* Created on: 11. 7. 2017
* Author: Jan Travnicek
*/
#ifndef _VALUE_HOLDER_HPP_
#define _VALUE_HOLDER_HPP_
#include <alib/memory>
#include <alib/typeindex>
#include <alib/typeinfo>
#include <abstraction/ValueHolderInterface.hpp>
namespace abstraction {
template < class Type >
class ValueHolderImpl : public ValueHolderInterface < Type > {
mutable std::optional < Type > m_data;
public:
using ValueHolderInterface < Type >::ValueHolderInterface;
Type && getValue ( ) const override {
return std::move ( m_data.value ( ) );
}
void setData ( Type && data ) {
m_data = std::move ( data );
}
bool evaluated ( ) const override {
return ( bool ) m_data;
}
};
template < class Type >
class ValueHolderImpl < const Type > : public ValueHolderInterface < Type > {
mutable std::optional < Type > m_data;
public:
using ValueHolderInterface < Type >::ValueHolderInterface;
void setData ( Type && data ) {
m_data = std::move ( data );
}
Type && getValue ( ) const override {
return std::move ( m_data.value ( ) );
}
bool evaluated ( ) const override {
return ( bool ) m_data;
}
};
template < class Type >
class ValueHolderImpl < Type & > : public ValueHolderInterface < Type > {
mutable std::optional < std::reference_wrapper < Type > > m_data;
public:
using ValueHolderInterface < Type >::ValueHolderInterface;
void setData ( Type & data ) {
m_data = std::reference_wrapper < Type > ( data );
}
Type && getValue ( ) const override {
return std::move ( m_data->get ( ) );
}
bool evaluated ( ) const override {
return ( bool ) m_data;
}
};
template < class Type >
class ValueHolderImpl < const Type & > : public ValueHolderInterface < Type > {
mutable std::optional < std::reference_wrapper < Type > > m_data;
public:
using ValueHolderInterface < Type >::ValueHolderInterface;
void setData ( const Type & data ) {
m_data = std::reference_wrapper < Type > ( const_cast < Type & > ( data ) );
}
Type && getValue ( ) const override {
return std::move ( m_data->get ( ) );
}
bool evaluated ( ) const override {
return ( bool ) m_data;
}
};
template < class Type >
class ValueHolderImpl < Type && > : public ValueHolderInterface < Type > {
mutable std::optional < std::reference_wrapper < Type > > m_data;
public:
using ValueHolderInterface < Type >::ValueHolderInterface;
void setData ( Type && data ) {
m_data = std::reference_wrapper < Type > ( data );
}
Type && getValue ( ) const override {
return std::move ( m_data->get ( ) );
}
bool evaluated ( ) const override {
return ( bool ) m_data;
}
};
template < class Type >
class ValueHolderImpl < const Type && > : public ValueHolderInterface < Type > {
mutable std::optional < std::reference_wrapper < Type > > m_data;
public:
using ValueHolderInterface < Type >::ValueHolderInterface;
void setData ( const Type && data ) {
m_data = std::reference_wrapper < Type > ( const_cast < Type & > ( data ) );
}
Type && getValue ( ) const override {
return std::move ( m_data->get ( ) );
}
bool evaluated ( ) const override {
return ( bool ) m_data;
}
};
template < class Type >
class ValueHolder : public ValueHolderImpl < Type > {
public:
ValueHolder ( std::shared_ptr < abstraction::OperationAbstraction > ref ) : ValueHolderImpl < Type > ( ref, std::is_const_v < std::remove_reference_t < Type > >, std::is_rvalue_reference_v < Type >, std::is_lvalue_reference_v < Type >, true ) {
}
ValueHolder ( std::shared_ptr < abstraction::OperationAbstraction > ref, Type && value ) : ValueHolderImpl < Type > ( ref, std::is_const_v < std::remove_reference_t < Type > >, std::is_rvalue_reference_v < Type >, std::is_lvalue_reference_v < Type >, true ) {
this->setData ( std::forward < Type > ( value ) );
}
using ValueHolderImpl < Type >::ValueHolderImpl;
std::shared_ptr < abstraction::Value > cloneAsVariable ( bool isConst, bool isRvalueRef, bool isLvalueRef, bool move ) override {
std::shared_ptr < abstraction::ValueHolder < Type > > res = std::make_shared < abstraction::ValueHolder < Type > > ( this->getLifeReference ( ), isConst, isRvalueRef, isLvalueRef, false );
res->setData ( retrieveValue < Type > ( this->getProxyAbstraction ( ), move ) );
return res;
}
std::shared_ptr < abstraction::Value > cloneAsValue ( bool isConst, bool isRvalueRef, bool isLvalueRef, bool move ) override {
std::shared_ptr < abstraction::ValueHolder < Type > > res = std::make_shared < abstraction::ValueHolder < Type > > ( this->getLifeReference ( ), isConst, isRvalueRef, isLvalueRef, true );
res->setData ( retrieveValue < Type > ( this->getProxyAbstraction ( ), move ) );
return res;
}
ext::set < abstraction::ParamQualifiers::ParamQualifier > getTypeQualifiers ( ) const override {
return abstraction::ParamQualifiers::paramQualifiers < Type > ( );
}
ext::type_index getTypeIndex ( ) const override {
return ext::type_index ( typeid ( std::decay_t < Type > ) );
}
};
} /* namespace abstraction */
#endif /* _VALUE_HOLDER_HPP_ */