#ifndef EMPATHY_IR_VALUE_H
#define EMPATHY_IR_VALUE_H
namespace empathy::llr
{
class Element;
}
namespace empathy::ir
{
class Value;
class ValuePattern;
extern Term ValueToIRExpr( const Value& v );
extern optional< Value > ValueFromIRExpr( const Term& t );
extern Term ValueToIRExpr( const ValuePattern& v );
class Value
{
public:
template< typename T, typename VL >
Value( T&& type, VL&& valOrLLR ) :
m_type( forward< T >( type ) ),
m_valOrLLR( forward< VL >( valOrLLR ) )
{}
const auto& type() const { return m_type; }
const auto& val() const { return get< Term >( m_valOrLLR ); }
auto& val() { return get< Term >( m_valOrLLR ); }
auto llr() const
{
return get< ptr< llr::Element > >( m_valOrLLR );
}
bool isConstant() const { return holds_alternative< Term >( m_valOrLLR ); }
friend ostream& operator<<( ostream& out, const Value& val )
{
return out << ValueToIRExpr( val );
}
private:
Term m_type;
variant< Term, ptr< llr::Element > > m_valOrLLR;
};
class ValuePattern
{
public:
template< typename S, typename T, typename V >
ValuePattern( S&& sort, T&& type, V&& v ) :
m_sort( forward< T >( sort ) ),
m_type( forward< T >( type ) ),
m_val( forward< V >( v ) )
{}
template< typename T, typename V >
ValuePattern( T&& type, V&& v ) :
m_sort( TSID( constant ) ),
m_type( forward< T >( type ) ),
m_val( forward< V >( v ) )
{}
const auto& sort() const { return m_sort; }
const auto& type() const { return m_type; }
const auto& val() const { return m_val; }
private:
Term m_sort;
Term m_type;
Term m_val;
};
}
#endif