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:
Vitor Sousa 2014-11-25 16:18:08 -02:00
parent 890ce1f9cf
commit d5ec6c41d9
4 changed files with 62 additions and 11 deletions

View File

@ -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))

View File

@ -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++

View File

@ -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&);

View File

@ -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