eolian-cxx: Add workaround for function pointer types

This commit is contained in:
Felipe Magno de Almeida 2017-08-22 22:31:55 -03:00
parent 2f53bdfe60
commit a7649a7897
3 changed files with 71 additions and 7 deletions

View File

@ -22,6 +22,11 @@ template <typename T>
struct in_traits<T, typename std::enable_if<eo::is_eolian_object<T>::value>::type> { typedef T type; };
template <typename T>
struct in_traits<T, typename std::enable_if<std::is_fundamental<T>::value>::type> { typedef T type; };
template <typename R, typename...Args>
struct in_traits<R(*)(Args...)>
{
typedef std::function<R(Args...)> type;
};
template <>
struct in_traits<eina::string_view> { typedef eina::string_view type; };
template <>
@ -285,7 +290,25 @@ auto convert_inout(V& object) -> decltype(impl::convert_inout_impl(object, impl:
template <typename T, typename U, bool Own = false, typename V>
T convert_to_c(V&& object);
template <typename F, typename T>
void* data_function_ptr_to_c(T function)
{
return nullptr;
}
template <typename F, typename T>
F function_ptr_to_c()
{
return nullptr;
}
template <typename F, typename T>
Eina_Free_Cb free_function_ptr_to_c()
{
return nullptr;
}
namespace impl {
template <typename U, typename T, typename V>
@ -549,6 +572,17 @@ T* convert_to_c_impl(T const* p, tag<T*, T const*>) // needed for property_get
{
return const_cast<T*>(p);
}
template <typename R, typename...Args>
typename std::add_pointer<R(Args...)>::type
convert_to_c_impl(std::function<R(Args...)>
, tag
<
typename std::add_pointer<R(Args...)>::type
, std::function<R(Args...)>
>) // needed for property_get
{
return nullptr; // not implemented naked functions
}
}
template <typename T, typename U, bool Own, typename V>

View File

@ -19,11 +19,40 @@ namespace efl { namespace eolian { namespace grammar {
struct converting_argument_generator
{
struct
{
typedef bool result_type;
template <typename T>
bool operator()(T const&) const { return false;}
bool operator()(attributes::regular_type_def const& r) const
{
return r.is_function_ptr;
}
} static const is_function_ptr;
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& ctx) const
{
attributes::qualifier_def qualifier = param.type.original_type.visit(attributes::get_qualifier_visitor{});
return as_generator
bool is_function_ptr = param.type.original_type.visit(this->is_function_ptr);
if(is_function_ptr)
return as_generator
(
attribute_reorder<-1, -1, 2, -1, -1, -1, -1>
(
" ::efl::eolian::data_function_ptr_to_c<" << c_type
<< ", " << parameter_type
<< ">(" << string << ")"
", ::efl::eolian::function_ptr_to_c<" << c_type
<< ", " << parameter_type
<< ">()"
", ::efl::eolian::free_function_ptr_to_c<" << c_type
<< ", " << parameter_type
<< ">()"
)
).generate(sink, param, ctx);
else
return as_generator
(
attribute_reorder<-1, -1, 2>
(

View File

@ -171,16 +171,16 @@ get(klass_name const& klass)
struct regular_type_def
{
regular_type_def() : is_undefined(false) {}
regular_type_def() : is_undefined(false), is_function_ptr(false) {}
regular_type_def(std::string base_type, qualifier_def qual, std::vector<std::string> namespaces
, bool is_undefined = false)
, bool is_undefined = false, bool is_function_ptr = false)
: base_type(std::move(base_type)), base_qualifier(qual), namespaces(std::move(namespaces))
, is_undefined(is_undefined) {}
, is_undefined(is_undefined), is_function_ptr(is_function_ptr) {}
std::string base_type;
qualifier_def base_qualifier;
std::vector<std::string> namespaces;
bool is_undefined;
bool is_undefined, is_function_ptr;
};
inline bool operator==(regular_type_def const& rhs, regular_type_def const& lhs)
@ -262,6 +262,7 @@ inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* uni
{
bool is_undefined = false;
Eolian_Typedecl const* decl = eolian_type_typedecl_get(eolian_type);
bool is_function_ptr = decl && eolian_typedecl_type_get(decl) == EOLIAN_TYPEDECL_FUNCTION_POINTER;
if(decl && eolian_typedecl_type_get(decl) == EOLIAN_TYPEDECL_ALIAS)
{
Eolian_Type const* aliased = eolian_typedecl_base_type_get(decl);
@ -277,7 +278,7 @@ inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* uni
for(efl::eina::iterator<const char> namespace_iterator( ::eolian_type_namespaces_get(eolian_type))
, namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
namespaces.push_back(&*namespace_iterator);
original_type = {regular_type_def{ ::eolian_type_name_get(eolian_type), {qualifiers(eolian_type), {}}, namespaces, is_undefined}};
original_type = {regular_type_def{ ::eolian_type_name_get(eolian_type), {qualifiers(eolian_type), {}}, namespaces, is_undefined, is_function_ptr}};
}
break;
case EOLIAN_TYPE_CLASS: