#ifndef EFL_EOLIAN_INTEROP_HH #define EFL_EOLIAN_INTEROP_HH #include #include #include #include #include namespace efl { namespace eolian { //// From C++ to C inline const char* to_c(std::string const& x) { return x.c_str(); } inline const char* to_c(efl::eina::stringshare const& x) { return x.c_str(); } inline Eina_Bool to_c(bool x) { return x ? EINA_TRUE : EINA_FALSE; } inline Eina_Bool* to_c(bool* x) { static_assert(sizeof(bool) == sizeof(Eina_Bool), ""); return reinterpret_cast(x); } template T to_c(T const& v, typename std::enable_if::value>::type* = 0) { return v; } template Eo* to_c(T const& v, typename std::enable_if::value>::type* = 0) { return v._eo_ptr(); } template Eo** to_c(T* v, typename std::enable_if::value>::type* = 0) { static_assert(sizeof(T) == sizeof(Eo*), ""); return static_cast(static_cast(v)); } template R to_native(T const& v) { static_assert(sizeof(T) == sizeof(R), ""); return v.native_handle(); } template R to_native(T* v) { static_assert(sizeof(T) == sizeof(typename std::remove_pointer::type), ""); return static_cast(static_cast(v)); } //// From C to C++ template struct tag {}; template T to_cxx(U object, O o); // XXX inline void* to_cxx(void *x, std::tuple, tag) { return x; } // XXX inline const void* to_cxx(const void *x, std::tuple, tag) { return x; } template inline T to_cxx(Eo* x, std::tuple, tag) { return T(x); } template inline T to_cxx(Eo* x, std::tuple, tag) { return T(::eo_ref(x)); } #ifdef _EVAS_H template Evas_Object_Textblock_Node_Format * to_cxx(Evas_Object_Textblock_Node_Format* x, std::tuple, tag) { return x; // XXX } #endif inline bool to_cxx(Eina_Bool x, std::tuple, tag) { return !!x; } inline std::string to_cxx(const char* x, std::tuple, tag) { return std::string(x); } template struct traits { typedef T type; }; template struct traits ::value>::type> { typedef Eo* type; }; template struct traits , T>::value>::type> { typedef const char* type; }; template inline efl::eina::range_list to_cxx(const Eina_List* x, std::tuple, tag< efl::eina::range_list >) { return efl::eina::range_list {x}; } template inline efl::eina::range_list to_cxx(Eina_List* x, std::tuple, tag< efl::eina::range_list >) { return efl::eina::range_list{x}; } template inline efl::eina::list to_cxx(Eina_List* x, std::tuple, tag< efl::eina::list >) { return efl::eina::list {x}; } inline eina::stringshare to_cxx(Eina_Stringshare const* x, const std::false_type, tag) { return ::eina_stringshare_ref(x); } template inline efl::eina::accessor to_cxx(Eina_Accessor* x, std::tuple, tag< efl::eina::accessor >) { return efl::eina::accessor(x); } template inline efl::eina::iterator to_cxx(Eina_Iterator* x, std::tuple, tag< efl::eina::iterator >) { return efl::eina::iterator(x); } template T to_cxx(Eo const* x, std::tuple, tag< T > , typename std::enable_if::value>* = 0) { // Workaround for erroneous constness return T{ ::eo_ref(const_cast(x))}; } template T to_cxx(Eo const* x, std::tuple, tag< T > , typename std::enable_if::value>* = 0) { // Workaround for erroneous constness return T{const_cast(x)}; } template T to_cxx(U object, O o) { return to_cxx(object, o, tag()); } //// Callbacks template R funcall(V* data, Args... args) { F const* f = static_cast(data); return (*f)(args...); } template struct callback_result_type; template struct callback_result_type { typedef R type; }; template struct callback_args_type; template struct callback_args_type { typedef std::tuple type; }; template C get_callback_impl(tag >) { static_assert(std::is_same::type>::value, "First argument of callback should be void* or const void*"); return static_cast(&eolian::funcall); } template C get_callback() { return get_callback_impl::type> (tag::type>()); } template 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