forked from enlightenment/efl
eolian_cxx: Fix: Using binding type for @out parameter instead of native type
No longer reverting to the native type when the parameter has "@out" direction. Added "is_out" member variable to eolian_type class. With that, generators can keep track of the direction of the parameters. Also added helper functions "type_is_out" and "type_is_complex". Created "to_native" functions in eo_cxx_interop.hh to convert binding types from C++ arguments to the actual C function arguments. Added static assertions in these functions to enforce compatibility between the binding and the native type (Required by @out parameters). Reworked the overload of the "to_c" function for eo::base derivated objects. Now there is a overload that rely in the compatibility between the native type and the wrapper, enabling a wrapper to be used as an output parameter.
This commit is contained in:
parent
890ce1f9cf
commit
d5ec6c41d9
|
@ -348,7 +348,9 @@ parameter_type(Eolian_Function_Parameter const& parameter,
|
|||
assert(!type.empty());
|
||||
if (parameter_is_out(parameter))
|
||||
{
|
||||
type = { efl::eolian::type_to_native(type) };
|
||||
if (type.front().native == "char *")
|
||||
type = { efl::eolian::type_to_native(type) };
|
||||
type.front().is_out = true;
|
||||
type.front().native += "*";
|
||||
}
|
||||
if (parameter_is_const(parameter, func_type))
|
||||
|
|
|
@ -13,12 +13,6 @@ namespace efl { namespace eolian {
|
|||
|
||||
//// From C++ to C
|
||||
|
||||
inline Eo*
|
||||
to_c(efl::eo::base const& x)
|
||||
{
|
||||
return x._eo_ptr();
|
||||
}
|
||||
|
||||
inline const char*
|
||||
to_c(std::string const& x)
|
||||
{
|
||||
|
@ -45,10 +39,38 @@ to_c(bool* x)
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
T to_c(T const& v, typename std::enable_if<!std::is_base_of<efl::eo::base, T>::value>::type* = 0)
|
||||
T to_c(T const& v, typename std::enable_if<!std::is_convertible<T*, efl::eo::base*>::value>::type* = 0)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Eo* to_c(T const& v, typename std::enable_if<std::is_convertible<T*, efl::eo::base*>::value>::type* = 0)
|
||||
{
|
||||
return v._eo_ptr();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Eo** to_c(T* v, typename std::enable_if<std::is_convertible<T*, efl::eo::base*>::value>::type* = 0)
|
||||
{
|
||||
static_assert(sizeof(T) == sizeof(Eo*), "");
|
||||
return static_cast<Eo**>(static_cast<void*>(v));
|
||||
}
|
||||
|
||||
template <typename R, typename T>
|
||||
R to_native(T const& v)
|
||||
{
|
||||
static_assert(sizeof(T) == sizeof(R), "");
|
||||
return v.native_handle();
|
||||
}
|
||||
|
||||
template <typename R, typename T>
|
||||
R to_native(T* v)
|
||||
{
|
||||
static_assert(sizeof(T) == sizeof(typename std::remove_pointer<R>::type), "");
|
||||
return static_cast<R>(static_cast<void*>(v));
|
||||
}
|
||||
|
||||
|
||||
//// From C to C++
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ struct eolian_type
|
|||
, category(unknown_)
|
||||
, is_const(false)
|
||||
, is_own(false)
|
||||
, is_out(false)
|
||||
, binding()
|
||||
, includes()
|
||||
{}
|
||||
|
@ -47,6 +48,7 @@ struct eolian_type
|
|||
, category(category_)
|
||||
, is_const(is_const_)
|
||||
, is_own(is_own_)
|
||||
, is_out(false)
|
||||
, binding(binding_)
|
||||
, includes(includes_)
|
||||
{
|
||||
|
@ -66,6 +68,7 @@ struct eolian_type
|
|||
category_type category;
|
||||
bool is_const;
|
||||
bool is_own;
|
||||
bool is_out;
|
||||
std::string binding;
|
||||
includes_container_type includes;
|
||||
};
|
||||
|
@ -94,6 +97,19 @@ type_is_binding(eolian_type_instance const& type)
|
|||
return type_is_binding(type.front());
|
||||
}
|
||||
|
||||
inline bool
|
||||
type_is_out(eolian_type const& type)
|
||||
{
|
||||
return type.is_out;
|
||||
}
|
||||
|
||||
inline bool
|
||||
type_is_out(eolian_type_instance const& type)
|
||||
{
|
||||
assert(!type.empty());
|
||||
return type_is_out(type.front());
|
||||
}
|
||||
|
||||
inline eolian_type
|
||||
type_to_native(eolian_type const& type)
|
||||
{
|
||||
|
@ -122,6 +138,13 @@ type_is_complex(eolian_type const& type)
|
|||
return type.category == eolian_type::complex_;
|
||||
}
|
||||
|
||||
inline bool
|
||||
type_is_complex(eolian_type_instance const& type_ins)
|
||||
{
|
||||
assert(!type_ins.empty());
|
||||
return type_is_complex(type_ins.front());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool
|
||||
type_is_callback(T const&);
|
||||
|
|
|
@ -47,10 +47,12 @@ operator<<(std::ostream& out, efl::eolian::grammar::reinterpret_type const& x)
|
|||
std::string res;
|
||||
for (auto rit = x._list.rbegin(), last = x._list.rend(); rit != last; ++rit)
|
||||
{
|
||||
if (type_is_complex(*rit))
|
||||
res = (*rit).binding + "< " + res + " >";
|
||||
eolian_type const& t = *rit;
|
||||
if (type_is_complex(t))
|
||||
res = t.binding + "< " + res + " >" + (t.is_out ? "*" : "");
|
||||
else
|
||||
res = type_is_binding(*rit) ? (*rit).binding : (*rit).native;
|
||||
res = type_is_binding(t) ? t.binding + (t.is_out ? "*" : "")
|
||||
: t.native;
|
||||
}
|
||||
assert(!res.empty());
|
||||
return out << res;
|
||||
|
@ -191,6 +193,8 @@ operator<<(std::ostream& out, to_c const& x)
|
|||
if (type_is_callback(x._type))
|
||||
out << "efl::eolian::get_callback<" << type_to_native_str(x._type)
|
||||
<< ", " << parameter_no_ref_type(x._type, x._varname) << " >()";
|
||||
else if (type_is_complex(x._type) && type_is_binding(x._type))
|
||||
out << "efl::eolian::to_native<" << c_type(x._type) << ">(" << x._varname << ")";
|
||||
else if (type_is_binding(x._type))
|
||||
out << "efl::eolian::to_c(" << x._varname << ")";
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue