felipealmeida pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=8906998ef2821a237c4deba07dc8336afdc4c471
commit 8906998ef2821a237c4deba07dc8336afdc4c471 Author: Felipe Magno de Almeida <fel...@expertisesolutions.com.br> Date: Wed Jun 8 17:31:46 2016 -0300 eolian-cxx: Add support for ref parameters and correct ownership handling --- src/bindings/cxx/eina_cxx/Eina.hh | 1 + src/bindings/cxx/eina_cxx/eina_accessor.hh | 1 + src/bindings/cxx/eina_cxx/eina_deleter.hh | 23 ++ src/bindings/cxx/eina_cxx/eina_ptrarray.hh | 13 + src/bindings/cxx/eo_cxx/eo_cxx_interop.hh | 272 ++++++++++++++++----- .../eolian_cxx/grammar/attribute_conditional.hpp | 5 +- src/lib/eolian_cxx/grammar/c_type.hpp | 2 +- src/lib/eolian_cxx/grammar/container.hpp | 22 -- src/lib/eolian_cxx/grammar/converting_argument.hpp | 6 +- .../eolian_cxx/grammar/function_declaration.hpp | 2 +- src/lib/eolian_cxx/grammar/function_definition.hpp | 20 +- src/lib/eolian_cxx/grammar/klass_def.hpp | 145 +++++------ src/lib/eolian_cxx/grammar/parameter.hpp | 14 -- src/lib/eolian_cxx/grammar/qualifier_def.hpp | 217 +++++++--------- src/lib/eolian_cxx/grammar/type.hpp | 29 ++- src/lib/eolian_cxx/grammar/type_impl.hpp | 261 ++++++++------------ src/tests/eolian_cxx/complex.eo | 140 ++++++++++- src/tests/eolian_cxx/complex_cxx.cc | 15 +- src/tests/eolian_cxx/eolian_cxx_test_binding.cc | 136 +++++++---- src/tests/eolian_cxx/generic.eo | 2 +- src/tests/eolian_cxx/name1_name2_type_generation.c | 48 +++- .../eolian_cxx/name1_name2_type_generation.eo | 95 ++++--- 22 files changed, 881 insertions(+), 588 deletions(-) diff --git a/src/bindings/cxx/eina_cxx/Eina.hh b/src/bindings/cxx/eina_cxx/Eina.hh index c8717a6..c986815 100644 --- a/src/bindings/cxx/eina_cxx/Eina.hh +++ b/src/bindings/cxx/eina_cxx/Eina.hh @@ -25,6 +25,7 @@ #include <eina_pp.hh> #include <eina_workarounds.hh> #include <eina_future.hh> +#include <eina_deleter.hh> /** * @page eina_cxx_main Eina C++ (BETA) diff --git a/src/bindings/cxx/eina_cxx/eina_accessor.hh b/src/bindings/cxx/eina_cxx/eina_accessor.hh index 800c3fa..33046a3 100644 --- a/src/bindings/cxx/eina_cxx/eina_accessor.hh +++ b/src/bindings/cxx/eina_cxx/eina_accessor.hh @@ -215,6 +215,7 @@ struct accessor<T, typename std::enable_if< ! std::is_base_of<::efl::eo::concret _self_type& operator=(_self_type const& other) { _base_type::operator=(other); + return *this; } /** diff --git a/src/bindings/cxx/eina_cxx/eina_deleter.hh b/src/bindings/cxx/eina_cxx/eina_deleter.hh new file mode 100644 index 0000000..65f8da0 --- /dev/null +++ b/src/bindings/cxx/eina_cxx/eina_deleter.hh @@ -0,0 +1,23 @@ +#ifndef EINA_DELETERS_HH_ +#define EINA_DELETERS_HH_ + +#include <eina_workarounds.hh> + +namespace efl { namespace eina { + +struct malloc_deleter +{ + template <typename T> + void operator()(T* object) const + { + object->~T(); + free(object); + } +}; + +template <typename T> +using unique_malloc_ptr = std::unique_ptr<T, malloc_deleter>; + +} } + +#endif diff --git a/src/bindings/cxx/eina_cxx/eina_ptrarray.hh b/src/bindings/cxx/eina_cxx/eina_ptrarray.hh index f47202e..b5de9d7 100644 --- a/src/bindings/cxx/eina_cxx/eina_ptrarray.hh +++ b/src/bindings/cxx/eina_cxx/eina_ptrarray.hh @@ -516,6 +516,12 @@ public: insert(end(), other.begin(), other.end()); } + ptr_array(ptr_array<T, CloneAllocator>&& other) + : _base_type() + { + std::swap(other._impl._array, this->_impl._array); + } + /** * @brief Creates a copy of a @c ptr_array with a different clone allocator. * @param other Another @c ptr_array with a different clone allocator. @@ -554,6 +560,13 @@ public: return *this; } + ptr_array<T, CloneAllocator>& operator=(ptr_array<T, CloneAllocator>&& other) + { + clear(); + std::swap(other._impl._array, this->_impl._array); + return *this; + } + /** * @brief Remove all the elements of the array. */ diff --git a/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh b/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh index f90e4f7..bd7a883 100644 --- a/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh +++ b/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh @@ -39,35 +39,45 @@ template <typename T> struct in_traits<eina::range_array<T>> { typedef eina::range_array<T> type; }; template <typename T> -struct out_traits { typedef T type; }; +struct out_traits { typedef T& type; }; +template <typename T> +struct out_traits<T*> { typedef T* type; }; +template <> +struct out_traits<Eina_Hash*> { typedef Eina_Hash*& type; }; +template <typename T> +struct out_traits<eina::optional<T&>> { typedef eina::optional<T&> type; }; +template <> +struct out_traits<void*> { typedef void*& type; }; template <typename T> struct out_traits<efl::eina::future<T>> { typedef efl::eina::future<T>& type; }; template <typename T> -struct inout_traits { typedef T type; }; +struct inout_traits { typedef T& type; }; template <typename T> struct inout_traits<efl::eina::future<T>> { typedef efl::eina::future<T>& type; }; +template <typename To, typename From, bool Own = false, typename Lhs, typename Rhs> +void assign_out(Lhs& lhs, Rhs& rhs); + namespace impl { -template <typename From, typename To> +template <typename From, typename To, bool Own = false> struct tag { typedef To to; typedef From from; + typedef std::integral_constant<bool, Own> own; }; -template <typename To, typename From, typename Lhs, typename Rhs> -void assign_out(Lhs& lhs, Rhs& rhs); - template <typename T> -void assign_out_impl(T*& lhs, T& rhs, tag<T*, T>) +void assign_out_impl(T& lhs, T*& rhs, tag<T&, T*>) { - *lhs = rhs; + lhs = *rhs; } -template <typename U, typename T> -void assign_out_impl(std::unique_ptr<T, void(*)(const void*)>& lhs, U* rhs, tag<std::unique_ptr<T, void(*)(const void*)>&, U*>) +template <typename U, typename T, typename D> +void assign_out_impl(std::unique_ptr<T, D>& lhs, U* rhs, tag<std::unique_ptr<T, D>&, U*, true>) { + // with own lhs.reset(rhs); } template <typename Tag> @@ -101,31 +111,23 @@ void assign_out_impl(efl::eina::string_view& view, const char* string, Tag) { view = {string}; } -template <typename T, typename Rhs, typename U, typename O> -void assign_out_impl(efl::eina::optional<T>& lhs, Rhs*& rhs, tag<efl::eina::optional<U>&, O>) -{ - if(rhs) - assign_out<U, O>(*lhs, rhs); - else - lhs.disengage(); -} -template <typename T, typename Rhs, typename U, typename O> -void assign_out_impl(efl::eina::optional<T>& lhs, Rhs& rhs, tag<efl::eina::optional<U>&, O>) +template <typename Tag> +void assign_out_impl(efl::eina::string_view* view, const char* string, Tag) { - assign_out<U, O>(*lhs, rhs); + if(view) + *view = {string}; } -template <typename T, typename Rhs, typename U, typename O> -void assign_out_impl(efl::eina::optional<T>& lhs, Rhs*& rhs, tag<efl::eina::optional<U>, O>) +template <typename T> +void assign_out_impl(T*& lhs, T& rhs, tag<T*, T>) // optional { - if(rhs) - assign_out<U, O>(*lhs, rhs); - else - lhs.disengage(); + if(lhs) + *lhs = rhs; } -template <typename T, typename Rhs, typename U, typename O> -void assign_out_impl(efl::eina::optional<T>& lhs, Rhs& rhs, tag<efl::eina::optional<U>, O>) +template <typename T, typename Rhs, typename U, typename O, bool B> +void assign_out_impl(efl::eina::optional<T>& lhs, Rhs& rhs, tag<efl::eina::optional<U&>, O, B>) { - assign_out<U, O>(*lhs, rhs); + if(lhs) + assign_out<U&, O, true>(*lhs, rhs); } template <typename Tag> void assign_out_impl(eina::value& lhs, Eina_Value const& rhs, Tag) @@ -135,17 +137,57 @@ void assign_out_impl(eina::value& lhs, Eina_Value const& rhs, Tag) eina_value_copy(&rhs, v); lhs = {v}; } -template <typename T, typename Tag> -void assign_out_impl(efl::eina::list<T>& lhs, Eina_List* rhs, Tag) +template <typename T> +void assign_out_impl(efl::eina::list<T>& lhs, Eina_List* rhs, tag<efl::eina::list<T>&, Eina_List*, true>) { lhs = efl::eina::list<T>{rhs}; } +template <typename T> +void assign_out_impl(efl::eina::range_list<T>& lhs, Eina_List* rhs, tag<efl::eina::range_list<T>&, Eina_List*>) +{ + lhs = efl::eina::range_list<T>{rhs}; +} +template <typename T> +void assign_out_impl(efl::eina::array<T>& lhs, Eina_Array* rhs, tag<efl::eina::array<T>&, Eina_Array*, true>) +{ + lhs = efl::eina::array<T>{rhs}; +} +template <typename T> +void assign_out_impl(efl::eina::range_array<T>& lhs, Eina_Array* rhs, tag<efl::eina::range_array<T>&, Eina_Array*>) +{ + lhs = efl::eina::range_array<T>{rhs}; +} +inline void assign_out_impl(Eina_Hash*& lhs, Eina_Hash*& rhs, tag<Eina_Hash*&, Eina_Hash*, true>) +{ + lhs = rhs; +} +template <typename T> +void assign_out_impl(efl::eina::iterator<T>& /*lhs*/, Eina_Iterator* /*rhs*/, tag<efl::eina::iterator<T>&, Eina_Iterator*>) +{ + // Must copy here + std::abort(); +} +template <typename T> +void assign_out_impl(efl::eina::iterator<T>& lhs, Eina_Iterator* rhs, tag<efl::eina::iterator<T>&, Eina_Iterator*, true>) +{ + lhs = efl::eina::iterator<T>{rhs}; +} +template <typename T> +void assign_out_impl(efl::eina::accessor<T>& lhs, Eina_Accessor* rhs, tag<efl::eina::accessor<T>&, Eina_Accessor*>) +{ + lhs = efl::eina::accessor<T>{ ::eina_accessor_clone(rhs) }; +} +template <typename T> +void assign_out_impl(efl::eina::accessor<T>& lhs, Eina_Accessor* rhs, tag<efl::eina::accessor<T>&, Eina_Accessor*, true>) +{ + lhs = efl::eina::accessor<T>{rhs}; +} } -template <typename To, typename From, typename Lhs, typename Rhs> +template <typename To, typename From, bool Own, typename Lhs, typename Rhs> void assign_out(Lhs& lhs, Rhs& rhs) { - return impl::assign_out_impl(lhs, rhs, impl::tag<To, From>{}); + return impl::assign_out_impl(lhs, rhs, impl::tag<To, From, Own>{}); } namespace impl { @@ -185,7 +227,7 @@ auto convert_inout(V& object) -> decltype(impl::convert_inout_impl(object, impl: return impl::convert_inout_impl(object, impl::tag<From, To>{}); } -template <typename T, typename U, typename V> +template <typename T, typename U, bool Own = false, typename V> T convert_to_c(V&& object); namespace impl { @@ -198,6 +240,43 @@ auto convert_to_c_impl } template <typename T> +T convert_to_c_impl(T& /*v*/, tag<T, T, true>) +{ + std::abort(); +} +template <typename T> +T* convert_to_c_impl(T& v, tag<T*, T&>) +{ + return &v; +} +template <typename T> +T* convert_to_c_impl(T& v, tag<T*, T&, true>) +{ + std::abort(); +} +template <typename T> +T* convert_to_c_impl(T const& v, tag<T*, T const&>) // not own +{ + return const_cast<T*>(&v); +} +template <typename T> +T* convert_to_c_impl(T const& v, tag<T*, T const&, true>) // with own +{ + T* r = static_cast<T*>(malloc(sizeof(T))); + *r = v; + return r; +} +template <typename T> +T const* convert_to_c_impl(T& v, tag<T const*, T&>) +{ + return &v; +} +template <typename T> +T const* convert_to_c_impl(T* v, tag<T const*, T*>) +{ + return v; +} +template <typename T> T const& convert_to_c_impl(T const& v, tag<T, T const&>) { return v; @@ -209,15 +288,27 @@ Eo* convert_to_c_impl(T v, tag<Eo*, T> return v._eo_ptr(); } template <typename T> +Eo* convert_to_c_impl(T v, tag<Eo*, T, true> + , typename std::enable_if<eo::is_eolian_object<T>::value>::type* = 0) +{ + return ::eo_ref(v._eo_ptr()); +} +template <typename T> Eo const* convert_to_c_impl(T v, tag<Eo const*, T> , typename std::enable_if<eo::is_eolian_object<T>::value>::type* = 0) { - return v._eo_ptr(); + return const_cast<Eo const*>(v._eo_ptr()); } inline const char* convert_to_c_impl( ::efl::eina::string_view v, tag<const char*, ::efl::eina::string_view>) { return v.c_str(); } +inline const char* convert_to_c_impl( ::efl::eina::string_view v, tag<const char*, ::efl::eina::string_view, true>) +{ + char* string = static_cast<char*>(malloc(v.size() + 1)); + std::strcpy(string, v.c_str()); + return string; +} inline const char** convert_to_c_impl(efl::eina::string_view* /*view*/, tag<const char **, efl::eina::string_view*>) { std::abort(); @@ -254,6 +345,18 @@ T convert_to_c_impl(efl::eina::optional<T> const& optional, tag<T, efl::eina::op { return optional ? *optional : T{}; } +template <typename T> +T* convert_to_c_impl(efl::eina::optional<T const&>const& optional, tag<T*, efl::eina::optional<T const&>const&, true>) +{ + if(optional) + { + T* r = static_cast<T*>(malloc(sizeof(T))); + *r = *optional; + return r; + } + else + return nullptr; +} template <typename U, typename T> U convert_to_c_impl(efl::eina::optional<T> const& optional, tag<U, efl::eina::optional<T>const&>) { @@ -270,15 +373,16 @@ Eina_List const* convert_to_c_impl(efl::eina::range_list<T> range, tag<Eina_List return range.native_handle(); } template <typename T> -Eina_List* convert_to_c_impl(efl::eina::list<T>const& c, tag<Eina_List *, efl::eina::list<T>const&>) +Eina_List* convert_to_c_impl(efl::eina::list<T>const& c, tag<Eina_List *, efl::eina::list<T>const&, true>) { return const_cast<Eina_List*>(c.native_handle()); } template <typename T> -Eina_List const* convert_to_c_impl(efl::eina::list<T>const& c, tag<Eina_List const *, efl::eina::list<T>const&>) +Eina_List const* convert_to_c_impl(efl::eina::list<T>const& c, tag<Eina_List const *, efl::eina::list<T>const&, true>) { return c.native_handle(); } + template <typename T> Eina_Array* convert_to_c_impl(efl::eina::range_array<T> range, tag<Eina_Array *, efl::eina::range_array<T>>) { @@ -290,23 +394,54 @@ Eina_Array const* convert_to_c_impl(efl::eina::range_array<T> range, tag<Eina_Ar return range.native_handle(); } template <typename T> -Eina_Array* convert_to_c_impl(efl::eina::array<T>const& c, tag<Eina_Array *, efl::eina::array<T>const&>) +Eina_Array* convert_to_c_impl(efl::eina::array<T>const& c, tag<Eina_Array *, efl::eina::array<T>const&, true>) { - return c.native_handle(); + return const_cast<Eina_Array*>(c.native_handle()); } template <typename T> -Eina_Array const* convert_to_c_impl(efl::eina::array<T>const& c, tag<Eina_Array const *, efl::eina::array<T>const&>) +Eina_Array const* convert_to_c_impl(efl::eina::array<T>const& c, tag<Eina_Array const *, efl::eina::array<T>const&, true>) { return c.native_handle(); } +template <typename T> +Eina_Iterator* convert_to_c_impl(efl::eina::iterator<T>const& i, tag<Eina_Iterator *, efl::eina::iterator<T>const&>) +{ + return const_cast<Eina_Iterator*>(i.native_handle()); +} +template <typename T> +Eina_Iterator const* convert_to_c_impl(efl::eina::iterator<T>const& i, tag<Eina_Iterator const*, efl::eina::iterator<T>const&>) +{ + return i.native_handle(); +} +template <typename T> +Eina_Iterator* convert_to_c_impl(efl::eina::iterator<T>const& /*i*/, tag<Eina_Iterator *, efl::eina::iterator<T>const&, true>) +{ + // Eina Iterator must be copied + std::abort(); +} +template <typename T> +Eina_Accessor* convert_to_c_impl(efl::eina::accessor<T>const& i, tag<Eina_Accessor *, efl::eina::accessor<T>const&>) +{ + return const_cast<Eina_Accessor*>(i.native_handle()); +} +template <typename T> +Eina_Accessor const* convert_to_c_impl(efl::eina::accessor<T>const& i, tag<Eina_Accessor const*, efl::eina::accessor<T>const&>) +{ + return i.native_handle(); +} +template <typename T> +Eina_Accessor* convert_to_c_impl(efl::eina::accessor<T>const& i, tag<Eina_Accessor *, efl::eina::accessor<T>const&, true>) +{ + return ::eina_accessor_clone(const_cast<Eina_Accessor*>(i.native_handle())); +} inline const char** convert_to_c_impl(efl::eina::string_view /*view*/, tag<char const **, efl::eina::string_view>) { std::abort(); } -// inline const char* convert_to_c_impl(std::string const& x, tag<const char*, std::string>) -// { -// return x.c_str(); -// } +inline const char** convert_to_c_impl(efl::eina::string_view /*view*/, tag<char const **, efl::eina::string_view, true>) +{ + std::abort(); +} inline const char* convert_to_c_impl(efl::eina::stringshare x, tag<const char*, efl::eina::stringshare>) { return x.c_str(); @@ -321,7 +456,6 @@ T* convert_to_c_impl(std::unique_ptr<U, Deleter>& v, tag<T*, std::unique_ptr<U, { return convert_to_c<T*, U*>(v.release()); } - template <typename T> Eina_Array** convert_to_c_impl(efl::eina::array<T>& /*c*/, tag<Eina_Array **, efl::eina::array<T>&>) { @@ -334,10 +468,10 @@ Eina_Array** convert_to_c_impl(efl::eina::range_array<T>& /*c*/, tag<Eina_Array } } -template <typename T, typename U, typename V> +template <typename T, typename U, bool Own, typename V> T convert_to_c(V&& object) { - return impl::convert_to_c_impl(std::forward<V>(object), impl::tag<T, U>{}); + return impl::convert_to_c_impl(std::forward<V>(object), impl::tag<T, U, Own>{}); } namespace impl { template <typename T> @@ -389,6 +523,11 @@ T convert_to_return(T value, tag<T, T>) return value; } template <typename T> +T& convert_to_return(T* value, tag<T*, T&>) +{ + return *value; +} +template <typename T> T convert_to_return(Eo* value, tag<Eo*, T>, typename std::enable_if< eo::is_eolian_object<T>::value>::type* = 0) { return T{value}; @@ -479,23 +618,46 @@ inline eina::string_view convert_to_return(const char* value, tag<const char*, e { return {value}; } +inline eina::string_view convert_to_return(const char** value, tag<const char**, efl::eina::string_view>) +{ + return {*value}; +} inline std::string convert_to_return(const char* value, tag<const char*, std::string>) { - return {value}; + if(value) + { + std::string r{value}; + free((void*)value); + return r; + } + else + return {}; +} +inline std::string convert_to_return(const char** value, tag<const char**, std::string>) +{ + if(value) + { + std::string r{*value}; + free((void*)*value); + free((void*)value); + return r; + } + else + return {}; } inline bool convert_to_return(Eina_Bool value, tag<Eina_Bool, bool>) { return !!value; } -template <typename T> -std::unique_ptr<T, void(*)(const void*)> convert_to_return(T* value, tag<T*, std::unique_ptr<T, void(*)(const void*)>>) +template <typename T, typename D> +std::unique_ptr<T, D> convert_to_return(T* value, tag<T*, std::unique_ptr<T, D>>) { - return std::unique_ptr<T, void(*)(const void*)>{value, (void(*)(const void*))&free}; + return std::unique_ptr<T, D>{value, {}}; } -template <typename T, typename U> -std::unique_ptr<T, void(*)(const void*)> convert_to_return(U* value, tag<U*, std::unique_ptr<T, void(*)(const void*)>>) +template <typename T, typename U, typename D> +std::unique_ptr<T, D> convert_to_return(U* value, tag<U*, std::unique_ptr<T, D>>) { - return std::unique_ptr<T, void(*)(const void*)>{convert_to_return(value, tag<U*, T*>{}), (void(*)(const void*))&free}; + return std::unique_ptr<T, D>{convert_to_return(value, tag<U*, T*>{}), {}}; } } diff --git a/src/lib/eolian_cxx/grammar/attribute_conditional.hpp b/src/lib/eolian_cxx/grammar/attribute_conditional.hpp index 8bf107a..886b1ed 100644 --- a/src/lib/eolian_cxx/grammar/attribute_conditional.hpp +++ b/src/lib/eolian_cxx/grammar/attribute_conditional.hpp @@ -56,7 +56,10 @@ struct attribute_conditional_terminal namespace type_traits { template <typename F, typename G> -struct attributes_needed<functional_attribute_conditional_generator<F, G>> : attributes_needed<G> {}; +struct attributes_needed<functional_attribute_conditional_generator<F, G>> + : std::conditional<attributes_needed<G>::value + , attributes_needed<G> + , std::integral_constant<int, 1>>::type {}; template <typename F> struct attributes_needed<functional_attribute_conditional_directive<F>> : std::integral_constant<int, 1> {}; } diff --git a/src/lib/eolian_cxx/grammar/c_type.hpp b/src/lib/eolian_cxx/grammar/c_type.hpp index e6a72fd..54b996d 100644 --- a/src/lib/eolian_cxx/grammar/c_type.hpp +++ b/src/lib/eolian_cxx/grammar/c_type.hpp @@ -17,7 +17,7 @@ struct c_type_visitor as_generator(" ::" << *(string << "_") << string << string << "*") .generate(std::back_insert_iterator<std::string>(n) , std::make_tuple(name.namespaces, name.eolian_name - , std::string{is_const(name.base_qualifier) ? " const" : ""}) + , std::string{name.base_qualifier & qualifier_info::is_const ? " const" : ""}) , context_null {}); return n; } diff --git a/src/lib/eolian_cxx/grammar/container.hpp b/src/lib/eolian_cxx/grammar/container.hpp index 4612612..ca86044 100644 --- a/src/lib/eolian_cxx/grammar/container.hpp +++ b/src/lib/eolian_cxx/grammar/container.hpp @@ -8,27 +8,6 @@ namespace efl { namespace eolian { namespace grammar { -struct container_subtype_modify -{ - typedef void result_type; - void operator()(attributes::complex_type_def& /*x*/) const - { - } - - void operator()(attributes::regular_type_def& x) const - { - if(x.base_type == "string") - remove_own(x.base_qualifier); - else if(!x.pointers.empty()) - x.pointers.pop_back(); - } - - template <typename T> - void operator()(T& /*x*/) const - { - } -}; - template <typename OutputIterator, typename Context> void generate_container(OutputIterator sink, attributes::complex_type_def const& complex, Context const& context , std::string const& name) @@ -36,7 +15,6 @@ void generate_container(OutputIterator sink, attributes::complex_type_def const& if(!complex.subtypes.empty()) { attributes::type_def subtype = complex.subtypes[0]; - subtype.original_type.visit(container_subtype_modify{}); as_generator(" "<< name << "<" << type << ">").generate(sink, subtype, context); } } diff --git a/src/lib/eolian_cxx/grammar/converting_argument.hpp b/src/lib/eolian_cxx/grammar/converting_argument.hpp index 4a2d959..3b5cb1d 100644 --- a/src/lib/eolian_cxx/grammar/converting_argument.hpp +++ b/src/lib/eolian_cxx/grammar/converting_argument.hpp @@ -22,11 +22,15 @@ struct converting_argument_generator 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 ( attribute_reorder<1, -1, 2> ( - " ::efl::eolian::convert_to_c<" << c_type << ", " << parameter_type << ">(" << string << ")" + " ::efl::eolian::convert_to_c<" << c_type << ", " << parameter_type + << (qualifier & qualifier_info::is_own + ? ", true" : "") + << ">(" << string << ")" ) ).generate(sink, param, ctx); } diff --git a/src/lib/eolian_cxx/grammar/function_declaration.hpp b/src/lib/eolian_cxx/grammar/function_declaration.hpp index a6aa439..f01c214 100644 --- a/src/lib/eolian_cxx/grammar/function_declaration.hpp +++ b/src/lib/eolian_cxx/grammar/function_declaration.hpp @@ -19,7 +19,7 @@ struct function_declaration_generator bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const { return as_generator - (grammar::type << " " << string << "(" << (parameter % ", ") << ") const;\n") + (grammar::type(true) << " " << string << "(" << (parameter % ", ") << ") const;\n") .generate(sink, std::make_tuple(f.return_type, escape_keyword(f.name), f.parameters), context); } }; diff --git a/src/lib/eolian_cxx/grammar/function_definition.hpp b/src/lib/eolian_cxx/grammar/function_definition.hpp index 170fa98..b228027 100644 --- a/src/lib/eolian_cxx/grammar/function_definition.hpp +++ b/src/lib/eolian_cxx/grammar/function_definition.hpp @@ -54,7 +54,7 @@ struct function_definition_generator return false; if(!as_generator - ("inline " << grammar::type << " " << string << "::" << string << "(" << (parameter % ", ") << ") const\n{\n") + ("inline " << grammar::type(true) << " " << string << "::" << string << "(" << (parameter % ", ") << ") const\n{\n") .generate(sink, std::make_tuple(f.return_type, _klass_name.eolian_name, escape_keyword(f.name), f.parameters), ctx)) return false; @@ -105,9 +105,19 @@ struct function_definition_generator attribute_conditional([] (attributes::parameter_def const& p) -> bool { return p.direction != attributes::parameter_direction::in; }) [ - attribute_reorder<-1, 1, 2, 2> - (scope_tab << "::efl::eolian::assign_out<" << parameter_type << ", " << c_type - << ">(" << string << ", __out_param_" << string << ");\n") + attribute_reorder<-1, 1, 1, 2, 2> + ( + scope_tab << "::efl::eolian::assign_out<" << parameter_type << ", " << c_type + << + ( + attribute_conditional([] (attributes::type_def const& type) + { return type.original_type.visit(attributes::get_qualifier_visitor{}) & qualifier_info::is_own; }) + [ + ", true" + ] | eps + ) + << ">(" << string << ", __out_param_" << string << ");\n" + ) ] | eps ; @@ -116,7 +126,7 @@ struct function_definition_generator if(f.return_type != attributes::void_ && !as_generator(scope_tab << "return ::efl::eolian::convert_to_return<" - << type<< ">(__return_value);\n" + << type(true) << ">(__return_value);\n" ).generate(sink, f.return_type, ctx)) return false; if(!as_generator("}\n").generate(sink, attributes::unused, ctx)) diff --git a/src/lib/eolian_cxx/grammar/klass_def.hpp b/src/lib/eolian_cxx/grammar/klass_def.hpp index b42d6f2..0c5d820 100644 --- a/src/lib/eolian_cxx/grammar/klass_def.hpp +++ b/src/lib/eolian_cxx/grammar/klass_def.hpp @@ -18,7 +18,15 @@ #include <memory> #include <set> -namespace efl { namespace eolian { namespace grammar { namespace attributes { +namespace efl { namespace eolian { namespace grammar { + +namespace attributes { + +struct complex_type_def; + +} + +namespace attributes { template <typename...Args, std::size_t I> bool lexicographical_compare_impl(std::tuple<Args...> const& @@ -56,25 +64,6 @@ bool lexicographical_compare(std::tuple<T, U> const& lhs && std::get<1>(lhs) < std::get<1>(rhs)); } -struct pointer_indirection -{ - qualifier_def qualifier; - bool reference; -}; -inline bool operator<(pointer_indirection const& lhs, pointer_indirection const& rhs) -{ - return lexicographical_compare(std::make_tuple(lhs.qualifier, lhs.reference) - , std::make_tuple(rhs.qualifier, rhs.reference)); -} -inline bool operator==(pointer_indirection const& lhs, pointer_indirection const& rhs) -{ - return lhs.qualifier == rhs.qualifier && lhs.reference == rhs.reference; -} -inline bool operator!=(pointer_indirection const& lhs, pointer_indirection const& rhs) -{ - return !(lhs == rhs); -} - struct type_def; bool operator==(type_def const& rhs, type_def const& lhs); bool operator!=(type_def const& rhs, type_def const& lhs); @@ -89,19 +78,16 @@ struct klass_name std::vector<std::string> namespaces; std::string eolian_name; qualifier_def base_qualifier; - std::vector<pointer_indirection> pointers; class_type type; klass_name(std::vector<std::string> namespaces , std::string eolian_name, qualifier_def base_qualifier - , std::vector<pointer_indirection> pointers , class_type type) : namespaces(namespaces), eolian_name(eolian_name), base_qualifier(base_qualifier) - , pointers(pointers), type(type) {} - klass_name(Eolian_Class const* klass, qualifier_def base_qualifier - , std::vector<pointer_indirection> pointers) + , type(type) {} + klass_name(Eolian_Class const* klass, qualifier_def base_qualifier) : eolian_name( ::eolian_class_name_get(klass)) - , base_qualifier(base_qualifier), pointers(pointers) + , base_qualifier(base_qualifier) { for(efl::eina::iterator<const char> namespace_iterator ( ::eolian_class_namespaces_get(klass)) , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator) @@ -131,7 +117,7 @@ struct klass_name inline bool operator==(klass_name const& lhs, klass_name const& rhs) { return lhs.namespaces == rhs.namespaces && lhs.eolian_name == rhs.eolian_name - && lhs.base_qualifier == rhs.base_qualifier && lhs.pointers == rhs.pointers; + && lhs.base_qualifier == rhs.base_qualifier/* && lhs.pointers == rhs.pointers*/; } inline bool operator!=(klass_name const& lhs, klass_name const& rhs) { @@ -142,14 +128,13 @@ inline bool operator<(klass_name const& lhs, klass_name const& rhs) typedef std::tuple<std::vector<std::string>const& , std::string const& , qualifier_def const& - , std::vector<pointer_indirection> const& , class_type > tuple_type; return lexicographical_compare(tuple_type(lhs.namespaces, lhs.eolian_name - , lhs.base_qualifier, lhs.pointers + , lhs.base_qualifier , lhs.type) , tuple_type(rhs.namespaces, rhs.eolian_name - , rhs.base_qualifier, rhs.pointers + , rhs.base_qualifier , rhs.type)); } @@ -187,14 +172,12 @@ struct regular_type_def { std::string base_type; qualifier_def base_qualifier; - std::vector<pointer_indirection> pointers; std::vector<std::string> namespaces; }; inline bool operator==(regular_type_def const& rhs, regular_type_def const& lhs) { - return rhs.base_type == lhs.base_type && rhs.base_qualifier == lhs.base_qualifier - && rhs.pointers == lhs.pointers; + return rhs.base_type == lhs.base_type && rhs.base_qualifier == lhs.base_qualifier; } inline bool operator!=(regular_type_def const& rhs, regular_type_def const& lhs) { @@ -230,23 +213,23 @@ struct type_def { set(eolian_type); } - struct set_pointer_visitor - { - typedef void result_type; - std::vector<pointer_indirection> pointers; - template <typename T> - void operator()(T& v) const - { - v.pointers = pointers; - } - void operator()(complex_type_def& complex) const - { - (*this)(complex.outer); - } - }; void set(Eolian_Type const* eolian_type); }; +struct get_qualifier_visitor +{ + typedef qualifier_def result_type; + template <typename T> + qualifier_def operator()(T const& object) const + { + return object.base_qualifier; + } + qualifier_def operator()(complex_type_def const& complex) const + { + return complex.outer.base_qualifier; + } +}; + inline bool operator==(type_def const& lhs, type_def const& rhs) { return lhs.original_type == rhs.original_type && lhs.c_type == rhs.c_type; @@ -273,29 +256,17 @@ inline void type_def::set(Eolian_Type const* eolian_type) 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}}; + original_type = {regular_type_def{ ::eolian_type_name_get(eolian_type), {qualifiers(eolian_type), {}}, namespaces}}; } break; case EOLIAN_TYPE_POINTER: { - std::vector<pointer_indirection> pointers - {{ {qualifiers(eolian_type), {}}, false }}; - Eolian_Type const* base_type = eolian_type_base_type_get(eolian_type); - while(eolian_type_type_get(base_type) == EOLIAN_TYPE_POINTER) - { - pointers.push_back({{qualifiers(base_type), {}}}); - base_type = eolian_type_base_type_get(base_type); - } - - set(base_type); - original_type.visit(set_pointer_visitor{pointers}); - c_type = ::eolian_type_c_type_get(eolian_type); - break; + throw std::runtime_error(""); } case EOLIAN_TYPE_CLASS: { Eolian_Class const* klass = eolian_type_class_get(eolian_type); - original_type = klass_name(klass, {qualifiers(eolian_type), {}}, {}); + original_type = klass_name(klass, {qualifiers(eolian_type), {}}); } break; case EOLIAN_TYPE_COMPLEX: @@ -329,7 +300,7 @@ struct add_optional_qualifier_visitor template <typename T> void operator()(T& object) const { - add_optional(object.base_qualifier); + object.base_qualifier.qualifier |= qualifier_info::is_optional; } void operator()(complex_type_def& complex) const { @@ -612,26 +583,34 @@ struct klass_def Eolian_Function_Type type = ::eolian_function_type_get(function); if(type == EOLIAN_PROPERTY) { - if(! ::eolian_function_is_legacy_only(function, EOLIAN_PROP_GET) - && ::eolian_function_scope_get(function, type) != EOLIAN_SCOPE_PRIVATE) - functions.push_back({function, EOLIAN_PROP_GET}); - if(! ::eolian_function_is_legacy_only(function, EOLIAN_PROP_SET) - && ::eolian_function_scope_get(function, type) != EOLIAN_SCOPE_PRIVATE) - functions.push_back({function, EOLIAN_PROP_SET}); + try { + if(! ::eolian_function_is_legacy_only(function, EOLIAN_PROP_GET) + && ::eolian_function_scope_get(function, type) != EOLIAN_SCOPE_PRIVATE) + functions.push_back({function, EOLIAN_PROP_GET}); + } catch(std::exception const&) {} + try { + if(! ::eolian_function_is_legacy_only(function, EOLIAN_PROP_SET) + && ::eolian_function_scope_get(function, type) != EOLIAN_SCOPE_PRIVATE) + functions.push_back({function, EOLIAN_PROP_SET}); + } catch(std::exception const&) {} } else - if(! ::eolian_function_is_legacy_only(function, type) - && ::eolian_function_scope_get(function, type) != EOLIAN_SCOPE_PRIVATE) - functions.push_back({function, type}); + try { + if(! ::eolian_function_is_legacy_only(function, type) + && ::eolian_function_scope_get(function, type) != EOLIAN_SCOPE_PRIVATE) + functions.push_back({function, type}); + } catch(std::exception const&) {} } for(efl::eina::iterator<Eolian_Function const> eolian_functions ( ::eolian_class_functions_get(klass, EOLIAN_METHOD)) , functions_last; eolian_functions != functions_last; ++eolian_functions) { - Eolian_Function const* function = &*eolian_functions; - Eolian_Function_Type type = ::eolian_function_type_get(function); - if(! ::eolian_function_is_legacy_only(function, EOLIAN_METHOD) - && ::eolian_function_scope_get(function, type) != EOLIAN_SCOPE_PRIVATE) - functions.push_back({function, EOLIAN_METHOD}); + try { + Eolian_Function const* function = &*eolian_functions; + Eolian_Function_Type type = eolian_function_type_get(function); + if(! ::eolian_function_is_legacy_only(function, EOLIAN_METHOD) + && ::eolian_function_scope_get(function, type) != EOLIAN_SCOPE_PRIVATE) + functions.push_back({function, EOLIAN_METHOD}); + } catch(std::exception const&) {} } std::function<void(Eolian_Class const*)> inherit_algo = [&] (Eolian_Class const* klass) @@ -640,7 +619,7 @@ struct klass_def , inherit_last; inherit_iterator != inherit_last; ++inherit_iterator) { Eolian_Class const* inherit = ::eolian_class_get_by_name(&*inherit_iterator); - inherits.insert({inherit, {}, {}}); + inherits.insert({inherit, {}}); inherit_algo(inherit); } }; @@ -665,7 +644,9 @@ struct klass_def for(efl::eina::iterator<Eolian_Event const> event_iterator( ::eolian_class_events_get(klass)) , event_last; event_iterator != event_last; ++event_iterator) { - events.push_back(&*event_iterator); + try { + events.push_back(&*event_iterator); + } catch(std::exception const&) {} } } @@ -673,7 +654,7 @@ struct klass_def inline klass_name get_klass_name(klass_def const& klass) { - return {klass.namespaces, klass.eolian_name, {qualifier_info::is_none, {}}, {}, klass.type}; + return {klass.namespaces, klass.eolian_name, {qualifier_info::is_none, {}}, klass.type}; } inline Eolian_Class const* get_klass(klass_name const& klass_name_) @@ -703,6 +684,8 @@ struct is_tuple<attributes::parameter_def> : std::true_type {}; template <> struct is_tuple<attributes::event_def> : std::true_type {}; -} } } } +} + +} } } #endif diff --git a/src/lib/eolian_cxx/grammar/parameter.hpp b/src/lib/eolian_cxx/grammar/parameter.hpp index f236841..b29805e 100644 --- a/src/lib/eolian_cxx/grammar/parameter.hpp +++ b/src/lib/eolian_cxx/grammar/parameter.hpp @@ -7,20 +7,6 @@ namespace efl { namespace eolian { namespace grammar { -struct add_reference_visitor -{ - typedef void result_type; - template <typename T> - void operator()(T& object) const - { - object.pointers.insert(object.pointers.begin(), {{}, true}); - } - void operator()(attributes::complex_type_def& complex) const - { - (*this)(complex.outer); - } -}; - struct parameter_type_generator { template <typename OutputIterator, typename Context> diff --git a/src/lib/eolian_cxx/grammar/qualifier_def.hpp b/src/lib/eolian_cxx/grammar/qualifier_def.hpp index 3ba1a89..b43b2f1 100644 --- a/src/lib/eolian_cxx/grammar/qualifier_def.hpp +++ b/src/lib/eolian_cxx/grammar/qualifier_def.hpp @@ -10,68 +10,74 @@ namespace efl { namespace eolian { namespace grammar { namespace attributes { enum class qualifier_info { is_none , is_own = 1 -, is_const = 4 -, is_const_own -, is_optional = 8 -, is_optional_own -, is_optional_const -, is_optional_const_own +, is_const = 2 +, is_optional = 4 +, is_ref = 8 }; -inline qualifier_info qualifiers(Eolian_Type const* type) +struct qualifier_bool +{ + qualifier_info v; + qualifier_bool(qualifier_info v) + : v(v) {} + + typedef qualifier_info(qualifier_bool::*unspecified_bool_type)() const; + + operator unspecified_bool_type() const + { + return v != qualifier_info::is_none ? &qualifier_bool::operator qualifier_info : nullptr; + } + operator qualifier_info() const { return v; } +}; +inline qualifier_bool operator|(qualifier_info lhs, qualifier_info rhs) { - bool is_own = ::eolian_type_is_own(type); - bool is_const = ::eolian_type_is_const(type); - if(is_own && is_const) - return qualifier_info::is_const_own; - else if(is_own) - return qualifier_info::is_own; - else if(is_const) - return qualifier_info::is_const; - else - return qualifier_info::is_none; + return static_cast<qualifier_info>(static_cast<int>(lhs) | static_cast<int>(rhs)); } - -inline bool is_own(qualifier_info i) -{ - switch(i) - { - case qualifier_info::is_own: - case qualifier_info::is_const_own: - case qualifier_info::is_optional_own: - case qualifier_info::is_optional_const_own: - return true; - default: - return false; - } +inline qualifier_bool operator&(qualifier_info lhs, qualifier_info rhs) +{ + return static_cast<qualifier_info>(static_cast<int>(lhs) & static_cast<int>(rhs)); } - -inline bool is_const(qualifier_info i) -{ - switch(i) - { - case qualifier_info::is_const: - case qualifier_info::is_const_own: - case qualifier_info::is_optional_const: - case qualifier_info::is_optional_const_own: - return true; - default: - return false; - } +inline qualifier_info operator^(qualifier_info lhs, qualifier_info rhs) +{ + return static_cast<qualifier_info>(static_cast<int>(lhs) & ~static_cast<int>(rhs)); } - -inline bool is_optional(qualifier_info i) -{ - switch(i) - { - case qualifier_info::is_optional: - case qualifier_info::is_optional_own: - case qualifier_info::is_optional_const: - case qualifier_info::is_optional_const_own: - return true; - default: - return false; - } +inline qualifier_info& operator|=(qualifier_info& lhs, qualifier_info rhs) +{ + lhs = static_cast<qualifier_info>(static_cast<int>(lhs) | static_cast<int>(rhs)); + return lhs; +} +inline qualifier_info& operator&=(qualifier_info& lhs, qualifier_info rhs) +{ + lhs = static_cast<qualifier_info>(static_cast<int>(lhs) & static_cast<int>(rhs)); + return lhs; +} +inline qualifier_info& operator^=(qualifier_info& lhs, qualifier_info rhs) +{ + lhs = static_cast<qualifier_info>(static_cast<int>(lhs) & ~static_cast<int>(rhs)); + return lhs; +} +inline qualifier_bool operator|(qualifier_bool lhs, qualifier_info rhs) +{ + lhs.v |= rhs; + return lhs; +} +inline qualifier_bool operator&(qualifier_bool lhs, qualifier_info rhs) +{ + lhs.v &= rhs; + return lhs; +} +inline qualifier_bool operator^(qualifier_bool lhs, qualifier_info rhs) +{ + lhs.v ^= rhs; + return lhs; +} + +inline qualifier_info qualifiers(Eolian_Type const* type) +{ + qualifier_info is_own = ::eolian_type_is_own(type) ? qualifier_info::is_own : qualifier_info::is_none; + qualifier_info is_const = ::eolian_type_is_const(type) ? qualifier_info::is_const : qualifier_info::is_none; + qualifier_info is_ref = ::eolian_type_is_ref(type) ? qualifier_info::is_ref : qualifier_info::is_none; + return is_own | is_const | is_ref; } struct qualifier_def @@ -82,8 +88,30 @@ struct qualifier_def qualifier_def() : qualifier(qualifier_info::is_none) {} qualifier_def(qualifier_info info, std::string free_function) : qualifier(info), free_function(std::move(free_function)) {} + + typedef qualifier_info(qualifier_bool::*unspecified_bool_type)() const; + operator unspecified_bool_type() const + { + return qualifier != qualifier_info::is_none ? &qualifier_bool::operator qualifier_info : nullptr; + } }; +inline qualifier_def operator|(qualifier_def lhs, qualifier_info rhs) +{ + lhs.qualifier = lhs.qualifier | rhs; + return lhs; +} +inline qualifier_def operator&(qualifier_def lhs, qualifier_info rhs) +{ + lhs.qualifier = lhs.qualifier & rhs; + return lhs; +} +inline qualifier_def operator^(qualifier_def lhs, qualifier_info rhs) +{ + lhs.qualifier = lhs.qualifier ^ rhs; + return lhs; +} + inline bool operator<(qualifier_def const& lhs, qualifier_def const& rhs) { return lhs.qualifier < rhs.qualifier || @@ -102,81 +130,8 @@ inline bool operator!=(qualifier_def const& lhs, qualifier_def const& rhs) return !(rhs == lhs); } -inline void add_optional(qualifier_def& q) -{ - switch (q.qualifier) - { - case qualifier_info::is_none: - q.qualifier = qualifier_info::is_optional; - break; - case qualifier_info::is_own: - q.qualifier = qualifier_info::is_optional_own; - break; - case qualifier_info::is_const: - q.qualifier = qualifier_info::is_optional_const; - break; - case qualifier_info::is_const_own: - q.qualifier = qualifier_info::is_optional_const_own; - break; - default: - break; - } -} -inline void remove_optional(qualifier_def& q) -{ - switch (q.qualifier) - { - case qualifier_info::is_optional: - q.qualifier = qualifier_info::is_none; - break; - case qualifier_info::is_optional_own: - q.qualifier = qualifier_info::is_own; - break; - case qualifier_info::is_optional_const: - q.qualifier = qualifier_info::is_const; - break; - case qualifier_info::is_optional_const_own: - q.qualifier = qualifier_info::is_const_own; - break; - default: - break; - } -} -inline void remove_own(qualifier_def& q) -{ - switch (q.qualifier) - { - case qualifier_info::is_own: - q.qualifier = qualifier_info::is_none; - break; - case qualifier_info::is_const_own: - q.qualifier = qualifier_info::is_const; - break; - case qualifier_info::is_optional_own: - q.qualifier = qualifier_info::is_optional; - break; - case qualifier_info::is_optional_const_own: - q.qualifier = qualifier_info::is_optional_const; - break; - default: - break; - } -} - -inline bool is_optional(qualifier_def const& i) -{ - return is_optional(i.qualifier); -} -inline bool is_own(qualifier_def const& i) -{ - return is_own(i.qualifier); -} -inline bool is_const(qualifier_def const& i) -{ - return is_const(i.qualifier); } - - -} } } } +using attributes::qualifier_info; +} } } #endif diff --git a/src/lib/eolian_cxx/grammar/type.hpp b/src/lib/eolian_cxx/grammar/type.hpp index c2719c3..8a09b6e 100644 --- a/src/lib/eolian_cxx/grammar/type.hpp +++ b/src/lib/eolian_cxx/grammar/type.hpp @@ -12,29 +12,50 @@ struct visitor_generate; struct type_generator { + type_generator(bool is_return = false) + : is_return(is_return) {} + template <typename OutputIterator, typename Context> bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const { - return type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false}); + return type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false, is_return}); } template <typename OutputIterator, typename Context> bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const { return param.type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, param.c_type - , param.direction != attributes::parameter_direction::in}); + , param.direction != attributes::parameter_direction::in, false}); } + + bool is_return; }; +struct type_terminal +{ + type_generator const operator()(bool is_return) const + { + return type_generator(is_return); + } +} const type = {}; + +type_generator const as_generator(type_terminal) +{ + return type_generator{}; +} + template <> struct is_eager_generator<type_generator> : std::true_type {}; +template <> +struct is_generator<type_terminal> : std::true_type {}; namespace type_traits { template <> struct attributes_needed<type_generator> : std::integral_constant<int, 1> {}; +template <> +struct attributes_needed<type_terminal> : std::integral_constant<int, 1> {}; } -type_generator const type = {}; - + } } } #endif diff --git a/src/lib/eolian_cxx/grammar/type_impl.hpp b/src/lib/eolian_cxx/grammar/type_impl.hpp index 7eda7ad..2e75e12 100644 --- a/src/lib/eolian_cxx/grammar/type_impl.hpp +++ b/src/lib/eolian_cxx/grammar/type_impl.hpp @@ -9,52 +9,6 @@ namespace efl { namespace eolian { namespace grammar { -namespace detail { - -bool has_own(attributes::regular_type_def const& def) -{ - for(auto&& c : def.pointers) - if(is_own(c.qualifier)) - return true; - return false; -} - -} - -namespace detail { - -struct swap_pointers_visitor -{ - std::vector<attributes::pointer_indirection>* pointers; - typedef void result_type; - template <typename T> - void operator()(T& object) const - { - std::swap(*pointers, object.pointers); - } - void operator()(attributes::complex_type_def& complex) const - { - (*this)(complex.outer); - } -}; - -template <typename OutputIterator, typename Context> -bool generate_pointers(OutputIterator sink, std::vector<attributes::pointer_indirection> const& pointers, Context const& - , bool no_reference) -{ - for(auto first = pointers.rbegin() - , last = pointers.rend(); first != last; ++first) - { - if(std::next(first) == last && first->reference && !no_reference) - *sink++ = '&'; - else - *sink++ = '*'; - } - return true; -} - -} - template <typename T> T const* as_const_pointer(T* p) { return p; } @@ -90,6 +44,7 @@ struct visitor_generate Context const* context; std::string c_type; bool is_out; + bool is_return; typedef visitor_generate<OutputIterator, Context> visitor_type; typedef bool result_type; @@ -105,14 +60,8 @@ struct visitor_generate } const match_table[] = { - {"void_ptr", nullptr, [&] - { - std::vector<attributes::pointer_indirection> pointers = regular.pointers; - pointers.insert(pointers.begin(), {{}, false}); - return attributes::regular_type_def{"void", regular.base_qualifier, pointers, {}}; - }} // signed primitives - , {"byte", nullptr, [&] { return replace_base_type(regular, " char"); }} + {"byte", nullptr, [&] { return replace_base_type(regular, " char"); }} , {"llong", nullptr, [&] { return replace_base_type(regular, " long long"); }} , {"int8", nullptr, [&] { return replace_base_type(regular, " int8_t"); }} , {"int16", nullptr, [&] { return replace_base_type(regular, " int16_t"); }} @@ -133,25 +82,42 @@ struct visitor_generate , {"ptrdiff", nullptr, [&] { return replace_base_type(regular, " ptrdiff_t"); }} , {"intptr", nullptr, [&] { return replace_base_type(regular, " intptr_t"); }} - , {"string", true, [&] { return replace_base_type(regular, " ::std::string"); }} - , {"string", false, [&] { return replace_base_type(regular, " ::efl::eina::string_view"); }} + , {"string", true, [&] + { + regular_type_def r = regular; + r.base_qualifier.qualifier ^= qualifier_info::is_ref; + if(is_out || is_return) + return replace_base_type(r, " ::std::string"); + else return replace_base_type(r, " ::efl::eina::string_view"); + }} + , {"string", false, [&] + { + regular_type_def r = regular; + r.base_qualifier.qualifier ^= qualifier_info::is_ref; + return replace_base_type(r, " ::efl::eina::string_view"); + }} , {"generic_value", nullptr, [&] - { return regular_type_def{" ::efl::eina::value", regular.base_qualifier - , {regular.pointers.empty() - || (regular.pointers.size() == 1 && regular.pointers[0].reference) - ? regular.pointers - : std::vector<attributes::pointer_indirection> - {regular.pointers.begin(), std::prev(regular.pointers.end())}} - , {}}; + { return regular_type_def{" ::efl::eina::value", regular.base_qualifier, {}}; }} }; - - if(eina::optional<bool> b = call_match + if(regular.base_type == "void_ptr") + { + if(regular.base_qualifier & qualifier_info::is_ref) + throw std::runtime_error("ref of void_ptr is invalid"); + return as_generator + ( + lit("void") << (regular.base_qualifier & qualifier_info::is_const ? " const" : "") + << "*" + << (is_out ? "&" : "") + ) + .generate(sink, attributes::unused, *context); + } + else if(eina::optional<bool> b = call_match (match_table , [&] (match const& m) { return (!m.name || *m.name == regular.base_type) - && (!m.has_own || *m.has_own == is_own(regular.base_qualifier)) + && (!m.has_own || *m.has_own == (bool)(regular.base_qualifier & qualifier_info::is_own)) ; } , [&] (attributes::type_def::variant_type const& v) @@ -161,94 +127,83 @@ struct visitor_generate { return *b; } - else if(attributes::is_optional(regular.base_qualifier)) + // in A @optional -> optional<A> + // in A& @optional -> optional<A&> + // in A& @optional -> optional<A&> + // in own(A&) @optional -> A* + // + // out A @optional -> optional<A&> + // out A& @optional -> optional<A&> + // out own(A&) @optional -> optional<A*&> + else if(regular.base_qualifier & qualifier_info::is_optional) { - if(regular.pointers.empty() || (regular.pointers.size() == 1 && regular.pointers[0].reference == true)) + attributes::regular_type_def no_optional_regular = regular; + no_optional_regular.base_qualifier.qualifier ^= qualifier_info::is_optional; + if(is_out) { - attributes::complex_type_def def - {attributes::regular_type_def{" ::efl::eina::optional", {}}}; - attributes::regular_type_def no_optional_regular = regular; - attributes::remove_optional(no_optional_regular.base_qualifier); - - def.subtypes.push_back({no_optional_regular, c_type}); - return (*this)(def); + if(no_optional_regular.base_qualifier & qualifier_info::is_own) + { + return as_generator(" ::efl::eina::optional<").generate(sink, attributes::unused, *context) + && (*this)(no_optional_regular) + && as_generator("&>").generate(sink, attributes::unused, *context); + } + else if(no_optional_regular.base_qualifier & qualifier_info::is_ref) + { + no_optional_regular.base_qualifier.qualifier ^= qualifier_info::is_ref; + return (*this)(no_optional_regular) + && as_generator("**").generate(sink, attributes::unused, *context); + } + else + return (*this)(no_optional_regular) + && as_generator("*").generate(sink, attributes::unused, *context); } else { - attributes::regular_type_def no_optional_regular = regular; - attributes::remove_optional(no_optional_regular.base_qualifier); - no_optional_regular.pointers[0].reference = 0; - return (*this)(no_optional_regular); + // regular.base_qualifier & qualifier_info::is_ref + return as_generator(" ::efl::eina::optional<").generate(sink, attributes::unused, *context) + && (*this)(no_optional_regular) + && as_generator(">").generate(sink, attributes::unused, *context); } } - // else if(detail::has_own(regular) && !regular.pointers.empty()) - // { - // attributes::complex_type_def def - // {attributes::regular_type_def{" ::efl::eolian::own_ptr", attributes::qualifier_info::is_none, {}}}; - - // attributes::complex_type_def tagged_def - // {attributes::regular_type_def{" ::efl::eolian::own", attributes::qualifier_info::is_none, {}}}; - - // auto pointer_iterator = regular.pointers.begin() - // , pointer_last = regular.pointers.end(); - - // for(;pointer_iterator != pointer_last && !attributes::is_own(pointer_iterator->qualifier) - // ;++pointer_iterator) - // { - // tagged_def.outer.pointers.push_back(*pointer_iterator); - // tagged_def.outer.pointers.front().reference = false; - // } - - // assert(attributes::is_own(pointer_iterator->qualifier)); - - // attributes::regular_type_def base_type (regular); - // base_type.pointers.clear(); - - // for(;pointer_iterator != pointer_last; ++pointer_iterator) - // { - // base_type.pointers.insert(base_type.pointers.begin(), *pointer_iterator); - // attributes::remove_own(base_type.pointers.back().qualifier); - // } - - // tagged_def.subtypes.push_back({base_type, c_type}); - // def.subtypes.push_back({tagged_def, c_type}); - // return (*this)(def); - // } - else if(detail::has_own(regular) && !regular.pointers.empty()) - { - attributes::regular_type_def pointee = regular; - std::vector<attributes::pointer_indirection> pointers; - std::swap(pointers, pointee.pointers); - pointers.erase(pointers.begin()); - - attributes::pointer_indirection reference {{attributes::qualifier_info::is_none,{}}, true}; - - return as_generator(" ::std::unique_ptr<" << type).generate - (sink, attributes::type_def{pointee, c_type}, *context) - && detail::generate_pointers(sink, pointers, *context, true) - && as_generator(", void(*)(const void*)>").generate(sink, attributes::unused, *context) - && (!is_out || detail::generate_pointers(sink, {reference}, *context, false)); - } - else - { - auto pointers = regular.pointers; - if(is_out) - pointers.push_back({{attributes::qualifier_info::is_none,{}}, true}); - if(as_generator(*(string << "_") << string << (is_const(regular.base_qualifier)? " const" : "")) - .generate(sink, std::make_tuple(regular.namespaces, regular.base_type), *context)) - return detail::generate_pointers(sink, pointers, *context - , regular.base_type == "void"); - else - return false; - } + else if((is_return || is_out) && regular.base_qualifier & qualifier_info::is_ref + && regular.base_qualifier & qualifier_info::is_own) + { + if(as_generator + ( + " ::std::unique_ptr<" + << *(string << "_") + << string + << (regular.base_qualifier & qualifier_info::is_const ? " const" : "") + << ", ::efl::eina::malloc_deleter>" + ) + .generate(sink, std::make_tuple(regular.namespaces, regular.base_type), *context)) + return true; + else + return false; + } + else + { + if(as_generator + ( + *(string << "_") + << string + << (regular.base_qualifier & qualifier_info::is_const + || (regular.base_qualifier & qualifier_info::is_ref + && !is_return && !is_out) + ? " const" : "") + << (regular.base_qualifier & qualifier_info::is_ref? "&" : "") + ) + .generate(sink, std::make_tuple(regular.namespaces, regular.base_type), *context)) + return true; + else + return false; + } } bool operator()(attributes::klass_name klass) const { - if(is_out) - klass.pointers.push_back({{attributes::qualifier_info::is_none, {}}, true}); if(as_generator(" " << *("::" << lower_case[string]) << "::" << string) .generate(sink, std::make_tuple(attributes::cpp_namespaces(klass.namespaces), klass.eolian_name), *context)) - return detail::generate_pointers(sink, klass.pointers, *context, false); + return true; else return false; } @@ -286,26 +241,25 @@ struct visitor_generate }} , {"hash", nullptr, nullptr , [&] - { regular_type_def r{"Eina_Hash", complex.outer.base_qualifier, complex.outer.pointers, {}}; - r.pointers.push_back({{qualifier_info::is_none, {}}, false}); + { regular_type_def r{"Eina_Hash*", complex.outer.base_qualifier, {}}; return r; }} , {"promise", nullptr, nullptr, [&] { return replace_outer - (complex, regular_type_def{" ::efl::eina::future", complex.outer.base_qualifier, {}, {}}); + (complex, regular_type_def{" ::efl::eina::future", complex.outer.base_qualifier, {}}); } } , {"iterator", nullptr, nullptr, [&] { return replace_outer - (complex, regular_type_def{" ::efl::eina::iterator", complex.outer.base_qualifier, {}, {}}); + (complex, regular_type_def{" ::efl::eina::iterator", complex.outer.base_qualifier, {}}); } } , {"accessor", nullptr, nullptr, [&] { return replace_outer - (complex, regular_type_def{" ::efl::eina::accessor", complex.outer.base_qualifier, {}, {}}); + (complex, regular_type_def{" ::efl::eina::accessor", complex.outer.base_qualifier, {}}); } } }; @@ -313,13 +267,14 @@ struct visitor_generate auto default_match = [&] (attributes::complex_type_def const& complex) { regular_type_def no_pointer_regular = complex.outer; - std::vector<attributes::pointer_indirection> pointers; - pointers.swap(no_pointer_regular.pointers); - if(is_out) - pointers.push_back({{attributes::qualifier_info::is_none, {}}, true}); + // std::vector<attributes::pointer_indirection> pointers; + // pointers.swap(no_pointer_regular.pointers); + // if(is_out) + // pointers.push_back({{attributes::qualifier_info::is_none, {}}, true}); return visitor_type{sink, context, c_type, false}(no_pointer_regular) && as_generator("<" << (type % ", ") << ">").generate(sink, complex.subtypes, *context) - && detail::generate_pointers(sink, pointers, *context, false); + ; + // && detail::generate_pointers(sink, pointers, *context, false); }; if(eina::optional<bool> b = call_match @@ -327,8 +282,8 @@ struct visitor_generate , [&] (match const& m) { return (!m.name || *m.name == complex.outer.base_type) - && (!m.has_own || *m.has_own == is_own(complex.outer.base_qualifier)) - && (!m.is_const || *m.is_const == is_const(complex.outer.base_qualifier)); + && (!m.has_own || *m.has_own == bool(complex.outer.base_qualifier & qualifier_info::is_own)) + && (!m.is_const || *m.is_const == bool(complex.outer.base_qualifier & qualifier_info::is_const)); } , [&] (attributes::type_def::variant_type const& v) { diff --git a/src/tests/eolian_cxx/complex.eo b/src/tests/eolian_cxx/complex.eo index d7672e7..626298a 100644 --- a/src/tests/eolian_cxx/complex.eo +++ b/src/tests/eolian_cxx/complex.eo @@ -30,22 +30,22 @@ class Complex (Eo.Base) } incontcont { params { - l: list<list<int*>>; + l: list<list<int>>; } } incontcontown { params { - l: own(list<list<int*>>); + l: own(list<list<int>>); } } incontowncontown { params { - l: own(list<own(list<int*>)>); + l: own(list<own(list<int>)>); } } incontowncont { params { - l: list<own(list<int*>)>; + l: list<own(list<int>)>; } } instringcont { @@ -63,14 +63,140 @@ class Complex (Eo.Base) l: own(list<string>); } } - + inarray { + params { + l: array<int>; + } + } + inarrayown { + params { + l: own(array<int>); + } + } + inhash { + params { + l: hash<int, int>; + } + } + inhashown { + params { + l: own(hash<int, int>); + } + } + initerator { + params { + l: iterator<int>; + } + } + initeratorown { + params { + l: own(iterator<int>); + } + } + inaccessor { + params { + l: accessor<int>; + } + } + inaccessorown { + params { + l: own(accessor<int>); + } + } + // out + outptrcont { + params { + @out l: list<int*>; + } + } + outclasscont { + params { + @out l: list<Eo.Base>; + } + } + outcontcont { + params { + @out l: list<list<int>>; + } + } + outcontcontown { + params { + @out l: own(list<list<int>>); + } + } + outcontowncontown { + params { + @out l: own(list<own(list<int>)>); + } + } + outcontowncont { + params { + @out l: list<own(list<int>)>; + } + } + outstringcont { + params { + @out l: list<string>; + } + } + outstringowncont { + params { + @out l: list<own(string)>; + } + } + outstringcontown { + params { + @out l: own(list<string>); + } + } + outarray { + params { + @out l: array<int>; + } + } + outarrayown { + params { + @out l: own(array<int>); + } + } + outhash { + params { + @out l: hash<int, int>; + } + } + outhashown { + params { + @out l: own(hash<int, int>); + } + } + outiterator { + params { + @out l: iterator<int>; + } + } + outiteratorown { + params { + @out l: own(iterator<int>); + } + } + outaccessor { + params { + @out l: accessor<int>; + } + } + outaccessorown { + params { + @out l: own(accessor<int>); + } + } + // foo { params { - l: list<int*>; + l: list<int>; } } bar { - return: array<int*>; + return: array<int>; } wrapper_r { return: Complex; diff --git a/src/tests/eolian_cxx/complex_cxx.cc b/src/tests/eolian_cxx/complex_cxx.cc index 72f4608..91f8017 100644 --- a/src/tests/eolian_cxx/complex_cxx.cc +++ b/src/tests/eolian_cxx/complex_cxx.cc @@ -37,12 +37,8 @@ struct test_param_type<void(T::*)(P), U> static_assert(std::is_same<P, U>::value, "Wrong type"); }; -test_param_type<typeof( & nonamespace::Complex::inptrcont ), efl::eina::range_list<int>> inptrcont; test_param_type<typeof( & nonamespace::Complex::inclasscont ), efl::eina::range_list<eo::Base>> inclasscont; -test_param_type<typeof( & nonamespace::Complex::inptrptrcont ), efl::eina::range_list<int*>> inptrptrcont; -test_param_type<typeof( & nonamespace::Complex::inptrcontown ), efl::eina::list<int>const&> inptrcontown; -test_param_type<typeof( & nonamespace::Complex::inptrptrcontown ), efl::eina::list<int*>const&> inptrptrcontown; -test_param_type<typeof( & nonamespace::Complex::incontcont ), efl::eina::range_list<efl::eina::range_list<int>>> incontont; +test_param_type<typeof( & nonamespace::Complex::incontcont ), efl::eina::range_list<efl::eina::range_list<int>>> incontcont; test_param_type<typeof( & nonamespace::Complex::incontcontown ), efl::eina::list<efl::eina::range_list<int>>const&> incontcontown; test_param_type<typeof( & nonamespace::Complex::incontowncontown ), efl::eina::list<efl::eina::list<int>>const&> incontowncontown; test_param_type<typeof( & nonamespace::Complex::incontowncont ), efl::eina::range_list<efl::eina::list<int>>> incontowncont; @@ -50,6 +46,15 @@ test_param_type<typeof( & nonamespace::Complex::instringcont ), efl::eina::range test_param_type<typeof( & nonamespace::Complex::instringowncont ), efl::eina::range_list<efl::eina::string_view>> instringowncont; test_param_type<typeof( & nonamespace::Complex::instringcontown ), efl::eina::list<efl::eina::string_view>const&> instringcontown; +test_param_type<typeof( & nonamespace::Complex::outclasscont ), efl::eina::range_list<eo::Base>&> outclasscont; +test_param_type<typeof( & nonamespace::Complex::outcontcont ), efl::eina::range_list<efl::eina::range_list<int>>&> outcontcont; +test_param_type<typeof( & nonamespace::Complex::outcontcontown ), efl::eina::list<efl::eina::range_list<int>>&> outcontcontown; +test_param_type<typeof( & nonamespace::Complex::outcontowncontown ), efl::eina::list<efl::eina::list<int>>&> outcontowncontown; +test_param_type<typeof( & nonamespace::Complex::outcontowncont ), efl::eina::range_list<efl::eina::list<int>>&> outcontowncont; +test_param_type<typeof( & nonamespace::Complex::outstringcont ), efl::eina::range_list<efl::eina::string_view>&> outstringcont; +test_param_type<typeof( & nonamespace::Complex::outstringowncont ), efl::eina::range_list<efl::eina::string_view>&> outstringowncont; +test_param_type<typeof( & nonamespace::Complex::outstringcontown ), efl::eina::list<efl::eina::string_view>&> outstringcontown; + test_param_type<typeof( & nonamespace::Complex::foo ), efl::eina::range_list<int>> foo; test_return_type<typeof( & nonamespace::Complex::bar ), efl::eina::range_array<int>> bar; test_return_type<typeof( & nonamespace::Complex::wrapper_r ), nonamespace::Complex> wrapper_r; diff --git a/src/tests/eolian_cxx/eolian_cxx_test_binding.cc b/src/tests/eolian_cxx/eolian_cxx_test_binding.cc index 83cb394..c9ee5c8 100644 --- a/src/tests/eolian_cxx/eolian_cxx_test_binding.cc +++ b/src/tests/eolian_cxx/eolian_cxx_test_binding.cc @@ -11,7 +11,7 @@ START_TEST(eolian_cxx_test_binding_constructor_only_required) { - efl::eo::eo_init i; + efl::eo::eo_init init; nonamespace::Generic g ( @@ -54,73 +54,109 @@ START_TEST(eolian_cxx_test_type_generation) efl::eo::eo_init eo_init; name1::name2::Type_Generation g; +} +END_TEST + +START_TEST(eolian_cxx_test_type_generation_in) +{ + efl::eo::eo_init i; + + name1::name2::Type_Generation g; + int v = 42; + g.inrefint(v); + g.inrefintown(42); + g.inrefintownfree(42); g.invoidptr(nullptr); g.inint(42); - std::unique_ptr<int> i (new int(42)); - g.inintptr(i.get()); + g.inintptr(42); + g.inintptrown(42); + g.inintptrownfree(42); + g.instring("foobar"); + g.instringown("foobar"); +} +END_TEST + +START_TEST(eolian_cxx_test_type_generation_return) +{ + efl::eo::eo_init i; + + name1::name2::Type_Generation g; + { - int* p = (int*)malloc(sizeof(int)); - *p = 42; - std::unique_ptr<int, void(*)(const void*)> inintptrown(p, (void(*)(const void*))&free); - g.inintptrown(std::move(inintptrown)); + int&i = g.returnrefint(); + ck_assert(i == 42); } { - int** p = (int**)malloc(sizeof(int*)); - *p = (int*)malloc(sizeof(int)); - **p = 42; - std::unique_ptr<int*, void(*)(const void*)> inintptrownptr(p, (void(*)(const void*))&free); - g.inintptrownptr(std::move(inintptrownptr)); + int i = g.returnint(); + ck_assert(i == 42); } { - int*** p = (int***)malloc(sizeof(int**)); - *p = (int**)malloc(sizeof(int*)); - **p = (int*)malloc(sizeof(int)); - ***p = 42; - std::unique_ptr<int**, void(*)(const void*)> inintptrownptrptr(p, (void(*)(const void*))&free); - g.inintptrownptrptr(std::move(inintptrownptrptr)); + void* p = g.returnvoidptr(); + ck_assert(*(int*)p == 42); } { - int*** p = (int***)malloc(sizeof(int**)); - *p = (int**)malloc(sizeof(int*)); - **p = (int*)malloc(sizeof(int)); - ***p = 42; - std::unique_ptr<int**, void(*)(const void*)> inintptrptrownptr(p, (void(*)(const void*))&free); - g.inintptrptrownptr(std::move(inintptrptrownptr)); + int& p = g.returnintptr(); + ck_assert(p == 42); } { - int* p = (int*)malloc(sizeof(int)); - *p = 42; - std::unique_ptr<int, void(*)(const void*)> inintptrownfree(p, (void(*)(const void*))&free); - g.inintptrownfree(std::move(inintptrownfree)); + efl::eina::unique_malloc_ptr<int> p = g.returnintptrown(); + ck_assert(*p == 42); + } + { + efl::eina::string_view string = g.returnstring(); + ck_assert_str_eq(string.c_str(), "foobar"); + } + { + std::string string = g.returnstring(); + ck_assert_str_eq(string.c_str(), "foobar"); } - g.instring("foobar"); - // { - // efl::eina::string_view v("foobar"); - // g.instringptr(&v); - // } - g.instringown("foobar"); - // { - // std::string v("foobar"); - // g.instringptrown(&v); - // } - // { - // std::unique_ptr<efl::eina::string_view, void(*)(const void*)> v - // ((efl::eina::string_view*)malloc(sizeof(string_view)), (void(*)(const void*))&free); - // g.instringptrown(v); - // } - // { - // std::string v("foobar"); - // g.instringptrown(&v); - // } } END_TEST -START_TEST(eolian_cxx_test_type_generation_in) +START_TEST(eolian_cxx_test_type_generation_optional) { - efl::eo::eo_init i; + efl::eo::eo_init init; + + using efl::eina::optional; name1::name2::Type_Generation g; + + g.optionalinvoidptr(NULL); + g.optionalinvoidptr(&g); + g.optionalinvoidptr(nullptr); + + int i = 42; + g.optionalinint(nullptr); + g.optionalinint(i); + + g.optionalinintptr(i); + g.optionalinintptr(nullptr); + + g.optionalinintptrown(i); + g.optionalinintptrown(nullptr); + + g.optionalinintptrownfree(i); + g.optionalinintptrownfree(nullptr); + + i = 0; + g.optionaloutint(&i); + ck_assert(i == 42); + g.optionaloutint(nullptr); + + i = 0; + int* j = nullptr; + g.optionaloutintptr(&j); + ck_assert(j != nullptr); + ck_assert(*j == 42); + g.optionaloutintptr(nullptr); + + i = 0; + efl::eina::unique_malloc_ptr<int> k = nullptr; + g.optionaloutintptrown(k); + ck_assert(!!k); + ck_assert(*k == 42); + g.optionaloutintptrown(nullptr); } END_TEST @@ -177,5 +213,7 @@ eolian_cxx_test_binding(TCase* tc) tcase_add_test(tc, eolian_cxx_test_binding_constructor_all_optionals); tcase_add_test(tc, eolian_cxx_test_type_generation); tcase_add_test(tc, eolian_cxx_test_type_generation_in); + tcase_add_test(tc, eolian_cxx_test_type_generation_return); + tcase_add_test(tc, eolian_cxx_test_type_generation_optional); tcase_add_test(tc, eolian_cxx_test_type_callback); } diff --git a/src/tests/eolian_cxx/generic.eo b/src/tests/eolian_cxx/generic.eo index 20f471b..c4a2257 100644 --- a/src/tests/eolian_cxx/generic.eo +++ b/src/tests/eolian_cxx/generic.eo @@ -101,7 +101,7 @@ class Generic (Eo.Base) prefix,event1; prefix,event2: Generic; prefix,event3: int; - prefix,event4: list<int*>; + prefix,event4: list<int>; prefix,event5: Generic.Event; } } diff --git a/src/tests/eolian_cxx/name1_name2_type_generation.c b/src/tests/eolian_cxx/name1_name2_type_generation.c index 28b8c85..9af748d 100644 --- a/src/tests/eolian_cxx/name1_name2_type_generation.c +++ b/src/tests/eolian_cxx/name1_name2_type_generation.c @@ -16,6 +16,23 @@ typedef struct _Type_Generation_Data Type_Generation_Data; #include "name1_name2_type_generation.eo.h" +void _name1_name2_type_generation_inrefint(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int* v EINA_UNUSED) +{ + ck_assert(*v == 42); +} + +void _name1_name2_type_generation_inrefintown(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int* v EINA_UNUSED) +{ + ck_assert(*v == 42); + free(v); +} + +void _name1_name2_type_generation_inrefintownfree(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int* v EINA_UNUSED) +{ + ck_assert(*v == 42); + free(v); +} + void _name1_name2_type_generation_invoidptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, void *v) { ck_assert(v == NULL); @@ -58,7 +75,8 @@ void _name1_name2_type_generation_inintptrownfree(Eo *obj EINA_UNUSED, Type_Gene void * _name1_name2_type_generation_returnvoidptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED) { - return NULL; + static int i = 42; + return &i; } void _name1_name2_type_generation_instring(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, const char *v EINA_UNUSED) @@ -70,6 +88,11 @@ void _name1_name2_type_generation_instringptr(Eo *obj EINA_UNUSED, Type_Generati { ck_assert_str_eq(*v, "foobar"); } +void _name1_name2_type_generation_instringptrown(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, const char * *v) +{ + ck_assert_str_eq(*v, "foobar"); + free((void*)*v); +} void _name1_name2_type_generation_instringown(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, const char *v EINA_UNUSED) { @@ -89,6 +112,11 @@ void _name1_name2_type_generation_instringownptr(Eo *obj EINA_UNUSED, Type_Gener free(v); } +int* _name1_name2_type_generation_returnrefint(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED) +{ + static int i = 42; + return &i; +} int _name1_name2_type_generation_returnint(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED) { return 42; @@ -96,12 +124,15 @@ int _name1_name2_type_generation_returnint(Eo *obj EINA_UNUSED, Type_Generation_ int * _name1_name2_type_generation_returnintptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED) { - return NULL; + static int i = 42; + return &i; } int * _name1_name2_type_generation_returnintptrown(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED) { - return NULL; + int* i = malloc(sizeof(int)); + *i = 42; + return i; } int ** _name1_name2_type_generation_returnintptrownptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED) @@ -211,18 +242,29 @@ void _name1_name2_type_generation_optionaloutvoidptr(Eo *obj EINA_UNUSED, Type_G void _name1_name2_type_generation_optionaloutint(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int *v EINA_UNUSED) { + if(v) + *v = 42; } void _name1_name2_type_generation_optionaloutintptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int **v EINA_UNUSED) { + static int i = 42; + if(v) + *v = &i; } void _name1_name2_type_generation_optionaloutintptrown(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int **v EINA_UNUSED) { + int* i = malloc(sizeof(int)); + *i = 42; + if(v) *v = i; } void _name1_name2_type_generation_optionaloutintptrownfree(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int **v EINA_UNUSED) { + int* i = malloc(sizeof(int)); + *i = 42; + if(v) *v = i; } void _name1_name2_type_generation_optionalinclassname(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, Name1_Name2_Type_Generation *v EINA_UNUSED) diff --git a/src/tests/eolian_cxx/name1_name2_type_generation.eo b/src/tests/eolian_cxx/name1_name2_type_generation.eo index 66b6461..e202423 100644 --- a/src/tests/eolian_cxx/name1_name2_type_generation.eo +++ b/src/tests/eolian_cxx/name1_name2_type_generation.eo @@ -2,45 +2,46 @@ class Name1.Name2.Type_Generation (Eo.Base) { data: Type_Generation_Data; methods { - // in void ptr - invoidptr { + // inref + inrefint { params { - @in v: void*; + @in v: ref(int); } } - inint { + inrefintown { params { - @in v: int; + @in v: own(ref(int)); } } - inintptr { + inrefintownfree { params { - @in v: int*; + @in v: free(own(ref(int)), free); } } - inintptrown { + // in void ptr + invoidptr { params { - @in v: own(int*); + @in v: void_ptr; } } - inintptrownptr { + inint { params { - @in v: own(int*)*; + @in v: int; } } - inintptrownptrptr { + inintptr { params { - @in v: own(int*)**; + @in v: ref(int); } } - inintptrptrownptr { + inintptrown { params { - @in v: own(int**)*; + @in v: own(ref(int)); } } inintptrownfree { params { - @in v: free(own(int*), free); + @in v: free(own(ref(int)), free); } } instring { @@ -48,72 +49,58 @@ class Name1.Name2.Type_Generation (Eo.Base) @in v: string; } } - /* instringptr { params { - @in v: string*; + @in v: ref(string); } - }*/ + } instringown { params { @in v: own(string); } } - /* no sense instringptrown { params { - @in v: own(string*); + @in v: own(ref(string)); } } - instringownptrown { - params { - @in v: own(own(string)*); - } - }*/ // return + returnrefint { + return: ref(int); + } returnvoidptr { - return: void*; + return: void_ptr; } returnint { return: int; } returnintptr { - return: int*; + return: ref(int); } returnintptrown { - return: own(int*); - } - returnintptrownptr { - return: own(int*)*; - } - returnintptrownptrptr { - return: own(int*)**; - } - returnintptrptrownptr { - return: own(int**)*; + return: own(ref(int)); } returnintptrownfree { params { - @in v: free(own(int*), free); + @in v: free(own(ref(int)), free); } } returnstring { return: string; } returnstringptr { - return: string*; + return: ref(string); } returnstringown { return: own(string); } returnstringownptr { - return: own(string*); + return: own(ref(string)); } - // out outvoidptr { params { - @out v: void*; + @out v: void_ptr; } } outint { @@ -123,17 +110,17 @@ class Name1.Name2.Type_Generation (Eo.Base) } outintptr { params { - @out v: int*; + @out v: ref(int); } } outintptrown { params { - @out v: own(int*); + @out v: own(ref(int)); } } outintptrownfree { params { - @out v: free(own(int*), free); + @out v: free(own(ref(int)), free); } } inclassname { @@ -153,7 +140,7 @@ class Name1.Name2.Type_Generation (Eo.Base) } optionalinvoidptr { params { - @in v: void* @optional; + @in v: void_ptr @optional; } } optionalinint { @@ -163,22 +150,22 @@ class Name1.Name2.Type_Generation (Eo.Base) } optionalinintptr { params { - @in v: int* @optional; + @in v: ref(int) @optional; } } optionalinintptrown { params { - @in v: own(int*) @optional; + @in v: own(ref(int)) @optional; } } optionalinintptrownfree { params { - @in v: free(own(int*), free) @optional; + @in v: free(own(ref(int)), free) @optional; } } optionaloutvoidptr { params { - @out v: void* @optional; + @out v: void_ptr @optional; } } optionaloutint { @@ -188,17 +175,17 @@ class Name1.Name2.Type_Generation (Eo.Base) } optionaloutintptr { params { - @out v: int* @optional; + @out v: ref(int) @optional; } } optionaloutintptrown { params { - @out v: own(int*) @optional; + @out v: own(ref(int)) @optional; } } optionaloutintptrownfree { params { - @out v: free(own(int*), free) @optional; + @out v: free(own(ref(int)), free) @optional; } } optionalinclassname { --