#include <eina_pp.hh>
#include <eina_workarounds.hh>
#include <eina_future.hh>
+#include <eina_deleter.hh>
/**
* @page eina_cxx_main Eina C++ (BETA)
_self_type& operator=(_self_type const& other)
{
_base_type::operator=(other);
+ return *this;
}
/**
--- /dev/null
+#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
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.
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.
*/
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>
{
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)
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 {
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 {
}
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;
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();
{
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&>)
{
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>>)
{
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();
{
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>&>)
{
}
}
-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>
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};
{
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*>{}), {}};
}
}
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> {};
}
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;
}
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)
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);
}
}
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);
}
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);
}
};
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;
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
;
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))
#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&
&& 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);
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)
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)
{
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));
}
{
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)
{
{
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;
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:
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
{
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)
, 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);
}
};
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&) {}
}
}
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_)
template <>
struct is_tuple<attributes::event_def> : std::true_type {};
-} } } }
+}
+
+} } }
#endif
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>
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
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 ||
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
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
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; }
Context const* context;
std::string c_type;
bool is_out;
+ bool is_return;
typedef visitor_generate<OutputIterator, Context> visitor_type;
typedef bool result_type;
}
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"); }}
, {"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)
{
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;
}
}}
, {"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, {}});
}
}
};
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
, [&] (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)
{
}
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 {
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;
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;
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;
START_TEST(eolian_cxx_test_binding_constructor_only_required)
{
- efl::eo::eo_init i;
+ efl::eo::eo_init init;
nonamespace::Generic g
(
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
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);
}
prefix,event1;
prefix,event2: Generic;
prefix,event3: int;
- prefix,event4: list<int*>;
+ prefix,event4: list<int>;
prefix,event5: Generic.Event;
}
}
#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);
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)
{
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)
{
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;
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)
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)
{
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 {
@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 {
}
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 {
}
optionalinvoidptr {
params {
- @in v: void* @optional;
+ @in v: void_ptr @optional;
}
}
optionalinint {
}
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 {
}
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 {