#ifndef EOLIAN_CXX_QUALIFIER_DEF_HH #define EOLIAN_CXX_QUALIFIER_DEF_HH #include "grammar/type_traits.hpp" #include namespace efl { namespace eolian { namespace grammar { namespace attributes { enum class qualifier_info { is_none , is_own = 1 , is_const = 2 , is_optional = 4 , is_ref = 8 }; struct qualifier_bool { qualifier_info v; qualifier_bool(qualifier_info v) : v(v) {} typedef qualifier_info(qualifier_bool::*unspecified_bool_type)() const; operator unspecified_bool_type() const { return v != qualifier_info::is_none ? &qualifier_bool::operator qualifier_info : nullptr; } operator qualifier_info() const { return v; } }; inline qualifier_bool operator|(qualifier_info lhs, qualifier_info rhs) { return static_cast(static_cast(lhs) | static_cast(rhs)); } inline qualifier_bool operator&(qualifier_info lhs, qualifier_info rhs) { return static_cast(static_cast(lhs) & static_cast(rhs)); } inline qualifier_info operator^(qualifier_info lhs, qualifier_info rhs) { return static_cast(static_cast(lhs) & ~static_cast(rhs)); } inline qualifier_info& operator|=(qualifier_info& lhs, qualifier_info rhs) { lhs = static_cast(static_cast(lhs) | static_cast(rhs)); return lhs; } inline qualifier_info& operator&=(qualifier_info& lhs, qualifier_info rhs) { lhs = static_cast(static_cast(lhs) & static_cast(rhs)); return lhs; } inline qualifier_info& operator^=(qualifier_info& lhs, qualifier_info rhs) { lhs = static_cast(static_cast(lhs) & ~static_cast(rhs)); return lhs; } inline qualifier_bool operator|(qualifier_bool lhs, qualifier_info rhs) { lhs.v |= rhs; return lhs; } inline qualifier_bool operator&(qualifier_bool lhs, qualifier_info rhs) { lhs.v &= rhs; return lhs; } inline qualifier_bool operator^(qualifier_bool lhs, qualifier_info rhs) { lhs.v ^= rhs; return lhs; } inline qualifier_info qualifiers(Eolian_Type const* type) { qualifier_info is_own = ::eolian_type_is_owned(type) ? qualifier_info::is_own : qualifier_info::is_none; qualifier_info is_const = ::eolian_type_is_const(type) ? qualifier_info::is_const : qualifier_info::is_none; qualifier_info is_ref = ::eolian_type_is_ptr(type) ? qualifier_info::is_ref : qualifier_info::is_none; return is_own | is_const | is_ref; } struct qualifier_def { qualifier_info qualifier; std::string free_function; qualifier_def() : qualifier(qualifier_info::is_none) {} qualifier_def(qualifier_info info, std::string free_function) : qualifier(info), free_function(std::move(free_function)) {} typedef qualifier_info(qualifier_bool::*unspecified_bool_type)() const; operator unspecified_bool_type() const { return qualifier != qualifier_info::is_none ? &qualifier_bool::operator qualifier_info : nullptr; } }; inline qualifier_def operator|(qualifier_def lhs, qualifier_info rhs) { lhs.qualifier = lhs.qualifier | rhs; return lhs; } inline qualifier_def operator&(qualifier_def lhs, qualifier_info rhs) { lhs.qualifier = lhs.qualifier & rhs; return lhs; } inline qualifier_def operator^(qualifier_def lhs, qualifier_info rhs) { lhs.qualifier = lhs.qualifier ^ rhs; return lhs; } inline bool operator<(qualifier_def const& lhs, qualifier_def const& rhs) { return lhs.qualifier < rhs.qualifier || (!(rhs.qualifier < lhs.qualifier) && lhs.free_function < rhs.free_function); } inline bool operator>(qualifier_def const& lhs, qualifier_def const& rhs) { return rhs < lhs; } inline bool operator==(qualifier_def const& lhs, qualifier_def const& rhs) { return rhs.qualifier == lhs.qualifier && rhs.free_function == lhs.free_function; } inline bool operator!=(qualifier_def const& lhs, qualifier_def const& rhs) { return !(rhs == lhs); } } using attributes::qualifier_info; } } } #endif