eolian-cxx: Add support for ref parameters and correct ownership handling

This commit is contained in:
Felipe Magno de Almeida 2016-06-08 17:31:46 -03:00
parent 963d2af974
commit 8906998ef2
22 changed files with 900 additions and 607 deletions

View File

@ -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)

View File

@ -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;
}
/**

View File

@ -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

View File

@ -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.
*/

View File

@ -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>)
template <typename Tag>
void assign_out_impl(efl::eina::string_view* view, const char* string, Tag)
{
if(rhs)
assign_out<U, O>(*lhs, rhs);
else
lhs.disengage();
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
{
assign_out<U, O>(*lhs, rhs);
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>)
{
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>)
{
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 {
@ -197,6 +239,43 @@ auto convert_to_c_impl
return std::forward<T>(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& 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&>)
{
@ -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 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&, true>)
{
return 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_Iterator* convert_to_c_impl(efl::eina::iterator<T>const& i, tag<Eina_Iterator *, efl::eina::iterator<T>const&>)
{
return c.native_handle();
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*>{}), {}};
}
}

View File

@ -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> {};
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);
}
};

View File

@ -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))

View File

@ -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

View File

@ -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>

View File

@ -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
};
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)
{
return static_cast<qualifier_info>(static_cast<int>(lhs) | static_cast<int>(rhs));
}
inline qualifier_bool operator&(qualifier_info lhs, qualifier_info rhs)
{
return static_cast<qualifier_info>(static_cast<int>(lhs) & static_cast<int>(rhs));
}
inline qualifier_info operator^(qualifier_info lhs, qualifier_info rhs)
{
return static_cast<qualifier_info>(static_cast<int>(lhs) & ~static_cast<int>(rhs));
}
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)
{
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;
}
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 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 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;
}
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

View File

@ -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

View File

@ -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::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);
}
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);
}
}
// 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;
attributes::regular_type_def no_optional_regular = regular;
no_optional_regular.base_qualifier.qualifier ^= qualifier_info::is_optional;
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");
{
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
return false;
{
// 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((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)
{

View File

@ -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;

View File

@ -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;

View File

@ -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,65 +54,6 @@ START_TEST(eolian_cxx_test_type_generation)
efl::eo::eo_init eo_init;
name1::name2::Type_Generation g;
g.invoidptr(nullptr);
g.inint(42);
std::unique_ptr<int> i (new int(42));
g.inintptr(i.get());
{
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** 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*** 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));
}
{
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 = (int*)malloc(sizeof(int));
*p = 42;
std::unique_ptr<int, void(*)(const void*)> inintptrownfree(p, (void(*)(const void*))&free);
g.inintptrownfree(std::move(inintptrownfree));
}
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
@ -121,6 +62,101 @@ 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);
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&i = g.returnrefint();
ck_assert(i == 42);
}
{
int i = g.returnint();
ck_assert(i == 42);
}
{
void* p = g.returnvoidptr();
ck_assert(*(int*)p == 42);
}
{
int& p = g.returnintptr();
ck_assert(p == 42);
}
{
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");
}
}
END_TEST
START_TEST(eolian_cxx_test_type_generation_optional)
{
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);
}

View File

@ -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;
}
}

View File

@ -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)

View File

@ -2,10 +2,26 @@ class Name1.Name2.Type_Generation (Eo.Base)
{
data: Type_Generation_Data;
methods {
// inref
inrefint {
params {
@in v: ref(int);
}
}
inrefintown {
params {
@in v: own(ref(int));
}
}
inrefintownfree {
params {
@in v: free(own(ref(int)), free);
}
}
// in void ptr
invoidptr {
params {
@in v: void*;
@in v: void_ptr;
}
}
inint {
@ -15,32 +31,17 @@ class Name1.Name2.Type_Generation (Eo.Base)
}
inintptr {
params {
@in v: int*;
@in v: ref(int);
}
}
inintptrown {
params {
@in v: own(int*);
}
}
inintptrownptr {
params {
@in v: own(int*)*;
}
}
inintptrownptrptr {
params {
@in v: own(int*)**;
}
}
inintptrptrownptr {
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 {