From a7649a7897218f3d66d72c15851aa566f00ca1f7 Mon Sep 17 00:00:00 2001 From: Felipe Magno de Almeida Date: Tue, 22 Aug 2017 22:31:55 -0300 Subject: [PATCH] eolian-cxx: Add workaround for function pointer types --- src/bindings/cxx/eo_cxx/eo_cxx_interop.hh | 36 ++++++++++++++++++- .../grammar/converting_argument.hpp | 31 +++++++++++++++- src/lib/eolian_cxx/grammar/klass_def.hpp | 11 +++--- 3 files changed, 71 insertions(+), 7 deletions(-) diff --git a/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh b/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh index e6b2780fe8..5a5e8f9535 100644 --- a/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh +++ b/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh @@ -22,6 +22,11 @@ template struct in_traits::value>::type> { typedef T type; }; template struct in_traits::value>::type> { typedef T type; }; +template +struct in_traits +{ + typedef std::function type; +}; template <> struct in_traits { typedef eina::string_view type; }; template <> @@ -285,7 +290,25 @@ auto convert_inout(V& object) -> decltype(impl::convert_inout_impl(object, impl: template T convert_to_c(V&& object); - + +template +void* data_function_ptr_to_c(T function) +{ + return nullptr; +} + +template +F function_ptr_to_c() +{ + return nullptr; +} + +template +Eina_Free_Cb free_function_ptr_to_c() +{ + return nullptr; +} + namespace impl { template @@ -549,6 +572,17 @@ T* convert_to_c_impl(T const* p, tag) // needed for property_get { return const_cast(p); } +template +typename std::add_pointer::type +convert_to_c_impl(std::function + , tag + < + typename std::add_pointer::type + , std::function + >) // needed for property_get +{ + return nullptr; // not implemented naked functions +} } template diff --git a/src/lib/eolian_cxx/grammar/converting_argument.hpp b/src/lib/eolian_cxx/grammar/converting_argument.hpp index cb3f750544..07255800ca 100644 --- a/src/lib/eolian_cxx/grammar/converting_argument.hpp +++ b/src/lib/eolian_cxx/grammar/converting_argument.hpp @@ -19,11 +19,40 @@ namespace efl { namespace eolian { namespace grammar { struct converting_argument_generator { + struct + { + typedef bool result_type; + template + 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 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> ( diff --git a/src/lib/eolian_cxx/grammar/klass_def.hpp b/src/lib/eolian_cxx/grammar/klass_def.hpp index 63d876f491..8bcbfc6b40 100644 --- a/src/lib/eolian_cxx/grammar/klass_def.hpp +++ b/src/lib/eolian_cxx/grammar/klass_def.hpp @@ -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 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 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 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: