eolian_cxx: Fix callback handling on generated wrappers

Added callbacks to the event EO_EV_DEL for deleting heap-allocated
function objects. This will enforce that the allocated memory,
necessary for maintaining these callable objects alive, is freed at
least when the underlaying Eo object is destroyed.

Functions and constructor methods are now able to have multiple
callback types.

Removed some unused generators, since they become inconsistent now that
functions are required to handle multiple callback types.

Allocating callback objects in the constructor methods instead of
delaying it until the final constructor is called.

Created some generators to avoid code repetition.

Now the generator parameters_forward_to_c replicate the behavior of the
generator parameters_list. The generator parameters_list was, then,
removed since it have a less intuitive name.

Added a TODO comment regarding the behaviour of simple not translating
callbacks that are not followed by a user data pointer.

The generator parameter_type was moved from "parameters_generator.hh" to
"type_generator.hh" for more consistency and convenience.
This commit is contained in:
Vitor Sousa 2014-11-19 13:59:21 -02:00
parent 2b94d874fe
commit 64dede1cf1
6 changed files with 375 additions and 242 deletions

View File

@ -234,6 +234,15 @@ C get_callback()
(tag<typename callback_args_type<C>::type>());
}
template <typename F>
Eina_Bool free_callback_calback(void* data, Eo* obj EINA_UNUSED
, Eo_Event_Description const* e EINA_UNUSED
, void* event_info EINA_UNUSED)
{
delete (F*) data;
return EO_CALLBACK_CONTINUE;
}
} } // namespace efl { namespace eolian {
#endif // EFL_EOLIAN_INTEROP_HH

View File

@ -104,12 +104,25 @@ inline std::ostream&
operator<<(std::ostream& out, constructor_functor_type_decl const& x)
{
out << constructor_functor_type_name(x._ctor);
auto cb_it = parameters_find_callback(x._ctor.params);
if(cb_it != x._ctor.params.cend())
if (parameters_count_callbacks(x._ctor.params) == 0)
return out;
bool comma = false;
out << "<";
auto first = x._ctor.params.cbegin(), last = x._ctor.params.cend();
for(auto it = first; it != last; ++it)
{
out << "<F>";
if (type_is_callback((*it).type) && it+1 != last)
{
if (comma)
out << ", ";
else
comma = true;
out << template_parameter_type((*it).type, (*it).name);
}
}
return out;
return out << ">";
}
struct functors_constructor_methods
@ -127,17 +140,24 @@ operator<<(std::ostream& out, functors_constructor_methods const& x)
for (it = first; it != last; ++it)
{
eo_constructor const& c = *it;
auto cb_it = parameters_find_callback(c.params);
bool has_callback = (cb_it != c.params.cend());
// Struct declaration
if(has_callback)
{
out << tab(1) << "template <typename F>" << endl;
}
out << tab(1) << "struct " << constructor_functor_type_name(c) << endl
out << template_parameters_declaration(c.params, 1)
<< tab(1) << "struct " << constructor_functor_type_name(c) << endl
<< tab(1) << "{" << endl;
// Callbacks typedefs
out << parameters_cxx_generic(c.params,
[](param_data d)
{
if (d.is_cb)
d.out << tab(2)
<< parameter_remove_reference_typedef(d.type, d.name)
<< endl;
}
)
<< endl;
// Struct constructor
out << tab(2) << constructor_functor_type_name(c) << "("
<< parameters_declaration(c.params) << ")"
@ -148,7 +168,13 @@ operator<<(std::ostream& out, functors_constructor_methods const& x)
d.out << endl << tab(3) << ": ";
else
d.out << ", ";
d.out << d.name << "(" << parameter_forward(d.type, d.name) << ")";
if (d.is_cb)
d.out << callback_tmp(d.name) << "(new "
<< template_parameter_type(d.type, d.name)
<< "(" << parameter_forward(d.type, d.name) << "))";
else
d.out << d.name << "(" << parameter_forward(d.type, d.name) << ")";
}
)
<< endl
@ -156,21 +182,22 @@ operator<<(std::ostream& out, functors_constructor_methods const& x)
// Struct operator()
out << tab(2) << "void operator()()" << endl
<< tab(2) << "{" << endl;
if (has_callback)
{
out << tab(3) << "typedef typename std::remove_reference<F>::type function_type;" << endl
<< tab(3) << "function_type* _tmp_f = new F(this->" << (*cb_it).name << ");" << endl;
}
out << tab(3) << "::" << c.name << "(" << parameters_forward_to_c(c.params) << ");" << endl
<< tab(2) << "{" << endl
<< tab(3) << "::" << c.name << "(" << parameters_forward_to_c(c.params) << ");" << endl
<< tab(2) << "}" << endl;
// Struct member variables
out << tab(1) << "private:" << endl
out << endl
<< parameters_cxx_generic(c.params,
[](param_data d)
{
d.out << tab(2) << parameter_type(d.type) << " " << d.name << ";" << endl;
d.out << tab(2);
if (d.is_cb)
d.out << parameter_no_ref_type(d.type, d.name) << "* "
<< callback_tmp(d.name);
else
d.out << parameter_type(d.type, d.name) << " " << d.name;
d.out << ";" << endl;
}
);
@ -197,12 +224,9 @@ operator<<(std::ostream& out, functions_constructor_methods const& x)
{
eo_constructor const& c = *it;
out << comment(c.comment, 1);
unsigned cb_count = parameters_count_callbacks(c.params);
if(cb_count)
out << tab(1) << "template <typename F>" << endl;
out << tab(1) << constructor_functor_type_decl(c) << " " << c.name << "("
out << comment(c.comment, 1)
<< template_parameters_declaration(c.params, 1)
<< tab(1) << constructor_functor_type_decl(c) << " " << c.name << "("
<< parameters_declaration(c.params) << ")" << endl
<< tab(1) << "{" << endl
<< tab(2) << "return " << constructor_functor_type_decl(c) << "("
@ -228,26 +252,50 @@ operator<<(std::ostream& out, constructor_with_constructor_methods const& x)
// TODO Require constructor methods of all base classes ?
//
unsigned cb_count = 0;
constructors_container_type::const_iterator it,
first = x._cls.constructors.cbegin(),
last = x._cls.constructors.cend();
for (it = first; it != last; ++it)
{
unsigned cb_count = parameters_count_callbacks((*it).params);
if(cb_count)
cb_count += parameters_count_callbacks((*it).params);
}
if (cb_count != 0)
{
out << tab(1) << "template <";
for (unsigned i = 0; i != cb_count; ++i)
{
out << tab(1) << "template <typename F>" << endl;
break;
if (i != 0)
out << ", ";
out << "typename F" << i;
}
out << ">" << endl;
}
out << tab(1) << x._cls.name << "(";
for (it = first; it != last; ++it)
{
out << constructor_functor_type_decl(*it)
<< " _c" << (it-first) << ", ";
}
{
unsigned cb_idx = 0;
for (it = first; it != last; ++it)
{
out << constructor_functor_type_name(*it);
if (cb_count != 0 && parameters_count_callbacks((*it).params) != 0)
{
out << "<"
<< parameters_cxx_generic((*it).params,
[&cb_idx](param_data d)
{
if (d.is_cb)
d.out << (d.cb_idx ? ", " : "") << "F" << cb_idx++;
})
<< ">";
}
out << " _c" << (it-first) << ", ";
}
assert(cb_idx == cb_count);
}
out << "efl::eo::parent_type _p = (efl::eo::parent = nullptr))" << endl
<< tab(2) << ": " << x._cls.name << "(_ctors_call(";
for (it = first; it != last; ++it)
@ -292,40 +340,6 @@ operator<<(std::ostream& out, constructor_eo const& x)
return out;
}
struct constructors
{
eo_class const& _cls;
constructors(eo_class const& cls)
: _cls(cls)
{}
};
inline std::ostream&
operator<<(std::ostream& out, constructors const& x)
{
constructors_container_type::const_iterator it,
first = x._cls.constructors.cbegin(),
last = x._cls.constructors.cend();
for (it = first; it != last; ++it)
{
eo_constructor const& ctor = *it;
out << comment(ctor.comment, 1);
if (parameters_count_callbacks(ctor.params))
out << tab(1) << "template <typename F>" << endl;
out << tab(1)
<< x._cls.name
<< '(' << parameters_declaration(ctor.params)
<< (ctor.params.size() > 0 ? ", " : "")
<< "efl::eo::parent_type _p = (efl::eo::parent = nullptr))" << endl
<< tab(2) << ": " << class_name(x._cls.name)
<< "(_c" << (it - first) << "(" << constructor_parameters_list(ctor.params)
<< (ctor.params.size() > 0 ? ", " : "")
<< "_p))" << endl
<< tab(1) << "{}" << endl << endl;
}
return out;
}
struct copy_constructor
{
eo_class const& _cls;
@ -363,48 +377,6 @@ operator<<(std::ostream& out, destructor const& x)
return out;
}
struct eo_class_constructors
{
eo_class const& _cls;
eo_class_constructors(eo_class const& cls) : _cls(cls) {}
};
inline std::ostream&
operator<<(std::ostream& out, eo_class_constructors const& x)
{
constructors_container_type::const_iterator it,
first = x._cls.constructors.begin(),
last = x._cls.constructors.end();
for (it = first; it != last; ++it)
{
if (parameters_count_callbacks((*it).params))
out << tab(1) << "template <typename F>" << endl;
out << tab(1)
<< "static Eo* _c" << (it - first) << "("
<< parameters_declaration((*it).params)
<< ((*it).params.size() > 0 ? ", " : "")
<< "efl::eo::parent_type _p"
<< ')' << endl
<< tab(1) << "{" << endl;
parameters_container_type::const_iterator callback_iter =
parameters_find_callback((*it).params);
if (callback_iter != (*it).params.cend())
{
out << tab(2)
<< "typedef typename std::remove_reference<F>::type function_type;" << endl
<< "function_type* _tmp_f = new F(std::forward<F>("
<< (*callback_iter).name << "));"
<< endl;
}
out << tab(2) << "return eo_add_ref("
<< x._cls.eo_name << ", _p._eo_raw, " << (*it).name
<< "(" << parameters_list((*it).params) << "));" << endl
<< tab(1) << "}" << endl << endl;
}
return out;
}
struct function_call_constructor_methods
{
eo_class const& _cls;
@ -414,31 +386,78 @@ struct function_call_constructor_methods
inline std::ostream&
operator<<(std::ostream& out, function_call_constructor_methods const& x)
{
unsigned cb_count = 0;
constructors_container_type::const_iterator it,
first = x._cls.constructors.cbegin(),
last = x._cls.constructors.cend();
for (it = first; it != last; ++it)
{
unsigned cb_count = parameters_count_callbacks((*it).params);
if (cb_count)
unsigned param_cb_count = parameters_count_callbacks((*it).params);
for (unsigned i = 0; i != param_cb_count; ++i)
{
out << tab(1) << "template <typename F>" << endl;
break;
if(cb_count == 0)
out << tab(1) << "template <";
else
out << ", ";
out << "typename F" << cb_count++;
}
}
if (cb_count != 0)
out << ">" << endl;
unsigned cb_idx = 0;
out << tab(1) << "static Eo* _ctors_call(";
for (it = first; it != last; ++it)
{
out << constructor_functor_type_decl(*it) << " _c" << (it-first) << ", ";
out << constructor_functor_type_name(*it);
if (cb_count != 0 && parameters_count_callbacks((*it).params) != 0)
{
out << "<"
<< parameters_cxx_generic((*it).params,
[&cb_idx](param_data d)
{
if (d.is_cb)
d.out << (d.cb_idx ? ", " : "") << "F" << cb_idx++;
})
<< ">";
}
out << " _c" << (it-first) << ", ";
}
assert(cb_idx == cb_count);
out << "efl::eo::parent_type _p)" << endl
<< tab(1) << "{" << endl
<< tab(2) << "return eo_add_ref(" << x._cls.eo_name << ", _p._eo_raw, ";
<< tab(2) << "Eo* _ret_eo = eo_add_ref(" << x._cls.eo_name << ", _p._eo_raw, ";
for (it = first; it != last; ++it)
{
out << "_c" << (it-first) << "(); ";
}
out << ");" << endl
out << ");" << endl << endl;
cb_idx = 0;
for (it = first; it != last; ++it)
{
if (parameters_count_callbacks((*it).params) == 0)
continue;
out << parameters_cxx_generic((*it).params,
[&it, &first, &cb_idx](param_data d)
{
if (d.is_cb)
d.out << tab(2)
<< "eo_do(_ret_eo," << endl
<< tab(3) << "eo_event_callback_add(EO_EV_DEL, "
<< "&efl::eolian::free_callback_calback<F" << cb_idx++
<< ">, _c" << (it-first) << "." << callback_tmp(d.name)
<< "));" << endl;
})
<< endl;
}
assert(cb_idx == cb_count);
out << tab(2) << "return _ret_eo;" << endl
<< tab(1) << "}" << endl << endl;
return out;

View File

@ -24,7 +24,7 @@ operator<<(std::ostream& out, function_call const& x)
bool is_void = function_is_void(x._func);
return out << (!is_void ? "_tmp_ret = " : "")
<< "::" << x._func.impl
<< "(" << parameters_list(x._func.params) << ")";
<< "(" << parameters_forward_to_c(x._func.params) << ")";
}
struct function
@ -39,8 +39,7 @@ operator<<(std::ostream& out, function const& x)
eo_function const& func = x._func;
out << comment(x._func.comment, 1);
if (parameters_count_callbacks(x._func.params) == 1)
out << tab(1) << "template <typename F>" << endl;
out << template_parameters_declaration(func.params, 1);
if (function_is_static(func))
out << tab(1) << "static ";
@ -55,16 +54,7 @@ operator<<(std::ostream& out, function const& x)
out << tab(2)
<< func.ret.front().native << " _tmp_ret;" << endl;
parameters_container_type::const_iterator callback_iter =
parameters_find_callback(func.params);
if (callback_iter != func.params.cend())
{
out << tab(2)
<< "typedef typename std::remove_reference<F>::type function_type;" << endl
<< tab(2) << "function_type* _tmp_f = new function_type(std::forward<F>("
<< (*callback_iter).name << "));"
<< endl;
}
out << callbacks_heap_alloc("_eo_ptr()", func.params, 2);
out << tab(2)
<< "eo_do(_eo_ptr(), " << function_call(x._func) << ");" << endl;

View File

@ -155,8 +155,8 @@ operator<<(std::ostream& out, inheritance_base_operations_function const& x)
eo_function const& func = x._func;
bool is_void = function_is_void(func);
if (parameters_count_callbacks(func.params) == 1)
out << tab(2) << "template <typename F>" << tab(2) << endl;
if (parameters_count_callbacks(func.params))
out << template_parameters_declaration(func.params, 2) << tab(2);
else
out << tab(2) << "virtual ";
@ -168,12 +168,8 @@ operator<<(std::ostream& out, inheritance_base_operations_function const& x)
if (!is_void)
out << tab(3) << func.ret.front().native << " _tmp_ret = {};" << endl;
parameters_container_type::const_iterator
callback_iter = parameters_find_callback(func.params);
if (callback_iter != func.params.cend())
out << tab(3) << "typedef typename std::remove_reference<F>::type function_type;" << endl
<< tab(3) << "function_type* _tmp_f = new function_type(std::forward<F>("
<< (*callback_iter).name << "));" << endl;
out << callbacks_heap_alloc("static_cast<T*>(this)->_eo_ptr()", func.params, 3)
<< endl;
out << tab(3)
<< "eo_do_super(static_cast<T*>(this)->_eo_ptr()," << endl
@ -291,8 +287,7 @@ struct inheritance_extension_function
inline std::ostream&
operator<<(std::ostream& out, inheritance_extension_function const& x)
{
if (parameters_count_callbacks(x._func.params) == 1)
out << tab(1) << "template <typename F>" << endl;
out << template_parameters_declaration(x._func.params, 1);
bool is_void = function_is_void(x._func);
out << tab(2)
@ -307,16 +302,8 @@ operator<<(std::ostream& out, inheritance_extension_function const& x)
out << tab(3) << x._func.ret.front().native << " _tmp_ret = {};" << endl;
}
parameters_container_type::const_iterator callback_iter =
parameters_find_callback(x._func.params);
if (callback_iter != x._func.params.cend())
{
out << tab(2)
<< "typedef typename std::remove_reference<F>::type function_type;" << endl
<< "function_type* _tmp_f = new function_type(std::forward<F>("
<< (*callback_iter).name << "));"
<< endl;
}
out << callbacks_heap_alloc("static_cast<U*>(this)->_eo_ptr()", x._func.params, 2)
<< endl;
out << tab(3) << "eo_do(static_cast<U*>(this)->_eo_ptr(), "
<< function_call(x._func) << ");" << endl;

View File

@ -10,25 +10,6 @@
namespace efl { namespace eolian { namespace grammar {
struct
parameter_type
{
eolian_type_instance const& _type;
parameter_type(eolian_type_instance const& t)
: _type(t)
{}
};
inline std::ostream&
operator<<(std::ostream& out, parameter_type const& x)
{
if(type_is_callback(x._type))
out << "F";
else
out << reinterpret_type(x._type);
return out;
}
struct
parameter_forward
{
@ -45,7 +26,7 @@ operator<<(std::ostream& out, parameter_forward const& x)
{
if (type_is_callback(x._type))
{
out << "std::forward<F>(" << x._name << ")";
out << "std::forward<" << template_parameter_type(x._type, x._name) << ">(" << x._name << ")";
}
else
out << x._name;
@ -109,6 +90,134 @@ parameters_cxx_generic(parameters_container_type const& params, T fparam)
return _parameters_cxx_generic<T>(params, fparam);
}
struct
callback_tmp
{
std::string const& _name;
callback_tmp(std::string const& name)
: _name(name)
{}
};
inline std::ostream&
operator<<(std::ostream& out, callback_tmp const& x)
{
return out << "_tmp_" << x._name;
}
struct
callback_parameter_heap_alloc
{
eolian_type_instance const& _type;
std::string const& _name;
int _tab;
callback_parameter_heap_alloc(eolian_type_instance const& type, std::string const& name, int tab)
: _type(type)
, _name(name)
, _tab(tab)
{}
};
inline std::ostream&
operator<<(std::ostream& out, callback_parameter_heap_alloc const& x)
{
out << tab(x._tab) << parameter_remove_reference_typedef(x._type, x._name) << endl
<< tab(x._tab) << parameter_no_ref_type(x._type, x._name) << "* "
<< callback_tmp(x._name) << " = new "
<< parameter_no_ref_type(x._type, x._name) << "(std::forward<"
<< template_parameter_type(x._type, x._name) << ">(" << x._name << "));" << endl;
return out;
}
struct
callback_parameter_free_ev_add
{
std::string const& _eo_raw_expr;
eolian_type_instance const& _type;
std::string const& _name;
callback_parameter_free_ev_add(std::string const& eo_raw_expr, eolian_type_instance const& type, std::string const& name)
: _eo_raw_expr(eo_raw_expr)
, _type(type)
, _name(name)
{}
};
inline std::ostream&
operator<<(std::ostream& out, callback_parameter_free_ev_add const& x)
{
out << "eo_do(" << x._eo_raw_expr
<< ", eo_event_callback_add(EO_EV_DEL, &efl::eolian::free_callback_calback<"
<< parameter_no_ref_type(x._type, x._name) << ">, "
<< callback_tmp(x._name) << "));";
return out;
}
struct
callbacks_heap_alloc
{
std::string const& _eo_raw_expr;
parameters_container_type const& _params;
int _tab;
callbacks_heap_alloc(std::string const& eo_raw_expr, parameters_container_type const& params, int tab)
: _eo_raw_expr(eo_raw_expr)
, _params(params)
, _tab(tab)
{}
};
inline std::ostream&
operator<<(std::ostream& out, callbacks_heap_alloc const& x)
{
auto first = x._params.cbegin(), last = x._params.cend();
for (auto it = first; it != last; ++it)
{
if (type_is_callback((*it).type) && it+1 != last)
{
out << callback_parameter_heap_alloc((*it).type, (*it).name, x._tab)
<< tab(x._tab)
<< callback_parameter_free_ev_add(x._eo_raw_expr, (*it).type, (*it).name)
<< endl << endl;
++it; // skip next.
}
}
return out;
}
struct
template_parameters_declaration
{
parameters_container_type const& _params;
int _tab;
template_parameters_declaration(parameters_container_type const& params, int tab)
: _params(params)
, _tab(tab)
{}
};
inline std::ostream&
operator<<(std::ostream& out, template_parameters_declaration const& x)
{
if (parameters_count_callbacks(x._params) == 0)
return out;
bool comma = false;
out << tab(x._tab) << "template <";
auto first = x._params.cbegin(), last = x._params.cend();
for (auto it = first; it != last; ++it)
{
if (type_is_callback((*it).type) && it+1 != last)
{
if (comma)
out << ", ";
else
comma = true;
out << "typename " << template_parameter_type((*it).type, (*it).name);
++it; // skip next.
}
}
return out << ">" << endl;
}
struct
parameters_declaration
{
@ -131,8 +240,7 @@ operator<<(std::ostream& out, parameters_declaration const& x)
// and does not have a following userdata pointer ?
if (type_is_callback((*it).type) && it+1 != last)
{
out << "F && " << (*it).name;
assert(it+1 != last);
out << template_parameter_type((*it).type, (*it).name) << " && " << (*it).name;
++it; // skip next.
}
else
@ -187,40 +295,6 @@ operator<<(std::ostream& out, parameters_types const& x)
return out;
}
struct
parameters_list
{
parameters_container_type const& _params;
parameters_list(parameters_container_type const& params)
: _params(params)
{}
};
inline std::ostream&
operator<<(std::ostream& out, parameters_list const& x)
{
auto first = x._params.cbegin(), last = x._params.cend();
for (auto it = first; it != last; ++it)
{
if (it != first)
out << ", ";
if (type_is_callback((*it).type))
{
if(it + 1 != last)
{
out << to_c((*it).type, (*it).name)
<< ", _tmp_f";
++it; // skip next
}
else
out << it->name;
}
else
out << to_c((*it).type, (*it).name);
}
return out;
}
struct
parameters_c_list
{
@ -265,35 +339,6 @@ operator<<(std::ostream& out, parameters_cxx_list const& x)
return out;
}
struct
constructor_parameters_list
{
parameters_container_type const& _params;
constructor_parameters_list(parameters_container_type const& params)
: _params(params)
{}
};
inline std::ostream&
operator<<(std::ostream& out, constructor_parameters_list const& x)
{
auto first = x._params.cbegin(),
last = x._params.cend();
for (auto it = first; it != last; ++it)
{
if (it != first)
out << ", ";
if (type_is_callback((*it).type) && it + 1 != last)
{
out << "std::forward<F>(" << (*it).name << ")";
++it; // skip next.
}
else
out << (*it).name;
}
return out;
}
struct
parameters_forward
{
@ -337,10 +382,17 @@ operator<<(std::ostream& out, parameters_forward_to_c const& x)
{
if (it != first)
out << ", ";
if (type_is_callback((*it).type) && it + 1 != last)
if (type_is_callback((*it).type))
{
out << to_c((*it).type, (*it).name) << ", _tmp_f";
++it; // skip next
// TODO: Is it correct to simple not translate the callback type
// when it is the last paramenter?
if(it + 1 != last)
{
out << to_c((*it).type, (*it).name) << ", " << callback_tmp((*it).name);
++it; // skip next
}
else
out << (*it).name;
}
else
out << to_c((*it).type, (*it).name);

View File

@ -77,6 +77,81 @@ operator<<(std::ostream& out, type_ownership const& x)
return out << ">()";
}
struct
template_parameter_type
{
eolian_type_instance const& _type;
std::string const& _name;
template_parameter_type(eolian_type_instance const& type, std::string const& name)
: _type(type)
, _name(name)
{}
};
inline std::ostream&
operator<<(std::ostream& out, template_parameter_type const& x)
{
return out << "F_" << x._name;
}
struct
parameter_type
{
eolian_type_instance const& _type;
std::string const& _name;
parameter_type(eolian_type_instance const& t, std::string const& name)
: _type(t)
, _name(name)
{}
};
inline std::ostream&
operator<<(std::ostream& out, parameter_type const& x)
{
if(type_is_callback(x._type))
out << template_parameter_type(x._type, x._name);
else
out << reinterpret_type(x._type);
return out;
}
struct
parameter_no_ref_type
{
eolian_type_instance const& _type;
std::string const& _name;
parameter_no_ref_type(eolian_type_instance const& type, std::string const& name)
: _type(type)
, _name(name)
{}
};
inline std::ostream&
operator<<(std::ostream& out, parameter_no_ref_type const& x)
{
return out << "_no_ref_" << parameter_type(x._type, x._name);
}
struct
parameter_remove_reference_typedef
{
eolian_type_instance const& _type;
std::string const& _name;
parameter_remove_reference_typedef(eolian_type_instance const& type, std::string const& name)
: _type(type)
, _name(name)
{}
};
inline std::ostream&
operator<<(std::ostream& out, parameter_remove_reference_typedef const& x)
{
out << "typedef typename std::remove_reference<"
<< parameter_type(x._type, x._name)
<< ">::type " << parameter_no_ref_type(x._type, x._name) << ";";
return out;
}
struct to_cxx
{
eolian_type_instance const& _type;
@ -114,7 +189,8 @@ inline std::ostream&
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) << ", function_type>()";
out << "efl::eolian::get_callback<" << type_to_native_str(x._type)
<< ", " << parameter_no_ref_type(x._type, x._varname) << " >()";
else if (type_is_binding(x._type))
out << "efl::eolian::to_c(" << x._varname << ")";
else