summaryrefslogtreecommitdiff
path: root/src/lib/eolian_cxx
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2016-06-08 17:31:46 -0300
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2016-06-14 22:44:02 -0300
commit8906998ef2821a237c4deba07dc8336afdc4c471 (patch)
tree5da597c3a555b348e290656c3e7b3407065aec5d /src/lib/eolian_cxx
parent963d2af9742018059a91a4cfc403e61bcae2e3d0 (diff)
eolian-cxx: Add support for ref parameters and correct ownership handling
Diffstat (limited to 'src/lib/eolian_cxx')
-rw-r--r--src/lib/eolian_cxx/grammar/attribute_conditional.hpp5
-rw-r--r--src/lib/eolian_cxx/grammar/c_type.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/container.hpp22
-rw-r--r--src/lib/eolian_cxx/grammar/converting_argument.hpp6
-rw-r--r--src/lib/eolian_cxx/grammar/function_declaration.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/function_definition.hpp20
-rw-r--r--src/lib/eolian_cxx/grammar/klass_def.hpp145
-rw-r--r--src/lib/eolian_cxx/grammar/parameter.hpp14
-rw-r--r--src/lib/eolian_cxx/grammar/qualifier_def.hpp217
-rw-r--r--src/lib/eolian_cxx/grammar/type.hpp29
-rw-r--r--src/lib/eolian_cxx/grammar/type_impl.hpp261
11 files changed, 309 insertions, 414 deletions
diff --git a/src/lib/eolian_cxx/grammar/attribute_conditional.hpp b/src/lib/eolian_cxx/grammar/attribute_conditional.hpp
index 8bf107a041..886b1edb35 100644
--- a/src/lib/eolian_cxx/grammar/attribute_conditional.hpp
+++ b/src/lib/eolian_cxx/grammar/attribute_conditional.hpp
@@ -56,7 +56,10 @@ struct attribute_conditional_terminal
56 56
57namespace type_traits { 57namespace type_traits {
58template <typename F, typename G> 58template <typename F, typename G>
59struct attributes_needed<functional_attribute_conditional_generator<F, G>> : attributes_needed<G> {}; 59struct attributes_needed<functional_attribute_conditional_generator<F, G>>
60 : std::conditional<attributes_needed<G>::value
61 , attributes_needed<G>
62 , std::integral_constant<int, 1>>::type {};
60template <typename F> 63template <typename F>
61struct attributes_needed<functional_attribute_conditional_directive<F>> : std::integral_constant<int, 1> {}; 64struct attributes_needed<functional_attribute_conditional_directive<F>> : std::integral_constant<int, 1> {};
62} 65}
diff --git a/src/lib/eolian_cxx/grammar/c_type.hpp b/src/lib/eolian_cxx/grammar/c_type.hpp
index e6a72fd025..54b996d65a 100644
--- a/src/lib/eolian_cxx/grammar/c_type.hpp
+++ b/src/lib/eolian_cxx/grammar/c_type.hpp
@@ -17,7 +17,7 @@ struct c_type_visitor
17 as_generator(" ::" << *(string << "_") << string << string << "*") 17 as_generator(" ::" << *(string << "_") << string << string << "*")
18 .generate(std::back_insert_iterator<std::string>(n) 18 .generate(std::back_insert_iterator<std::string>(n)
19 , std::make_tuple(name.namespaces, name.eolian_name 19 , std::make_tuple(name.namespaces, name.eolian_name
20 , std::string{is_const(name.base_qualifier) ? " const" : ""}) 20 , std::string{name.base_qualifier & qualifier_info::is_const ? " const" : ""})
21 , context_null {}); 21 , context_null {});
22 return n; 22 return n;
23 } 23 }
diff --git a/src/lib/eolian_cxx/grammar/container.hpp b/src/lib/eolian_cxx/grammar/container.hpp
index 4612612360..ca86044c40 100644
--- a/src/lib/eolian_cxx/grammar/container.hpp
+++ b/src/lib/eolian_cxx/grammar/container.hpp
@@ -8,27 +8,6 @@
8 8
9namespace efl { namespace eolian { namespace grammar { 9namespace efl { namespace eolian { namespace grammar {
10 10
11struct container_subtype_modify
12{
13 typedef void result_type;
14 void operator()(attributes::complex_type_def& /*x*/) const
15 {
16 }
17
18 void operator()(attributes::regular_type_def& x) const
19 {
20 if(x.base_type == "string")
21 remove_own(x.base_qualifier);
22 else if(!x.pointers.empty())
23 x.pointers.pop_back();
24 }
25
26 template <typename T>
27 void operator()(T& /*x*/) const
28 {
29 }
30};
31
32template <typename OutputIterator, typename Context> 11template <typename OutputIterator, typename Context>
33void generate_container(OutputIterator sink, attributes::complex_type_def const& complex, Context const& context 12void generate_container(OutputIterator sink, attributes::complex_type_def const& complex, Context const& context
34 , std::string const& name) 13 , std::string const& name)
@@ -36,7 +15,6 @@ void generate_container(OutputIterator sink, attributes::complex_type_def const&
36 if(!complex.subtypes.empty()) 15 if(!complex.subtypes.empty())
37 { 16 {
38 attributes::type_def subtype = complex.subtypes[0]; 17 attributes::type_def subtype = complex.subtypes[0];
39 subtype.original_type.visit(container_subtype_modify{});
40 as_generator(" "<< name << "<" << type << ">").generate(sink, subtype, context); 18 as_generator(" "<< name << "<" << type << ">").generate(sink, subtype, context);
41 } 19 }
42} 20}
diff --git a/src/lib/eolian_cxx/grammar/converting_argument.hpp b/src/lib/eolian_cxx/grammar/converting_argument.hpp
index 4a2d959163..3b5cb1dcfc 100644
--- a/src/lib/eolian_cxx/grammar/converting_argument.hpp
+++ b/src/lib/eolian_cxx/grammar/converting_argument.hpp
@@ -22,11 +22,15 @@ struct converting_argument_generator
22 template <typename OutputIterator, typename Context> 22 template <typename OutputIterator, typename Context>
23 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& ctx) const 23 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& ctx) const
24 { 24 {
25 attributes::qualifier_def qualifier = param.type.original_type.visit(attributes::get_qualifier_visitor{});
25 return as_generator 26 return as_generator
26 ( 27 (
27 attribute_reorder<1, -1, 2> 28 attribute_reorder<1, -1, 2>
28 ( 29 (
29 " ::efl::eolian::convert_to_c<" << c_type << ", " << parameter_type << ">(" << string << ")" 30 " ::efl::eolian::convert_to_c<" << c_type << ", " << parameter_type
31 << (qualifier & qualifier_info::is_own
32 ? ", true" : "")
33 << ">(" << string << ")"
30 ) 34 )
31 ).generate(sink, param, ctx); 35 ).generate(sink, param, ctx);
32 } 36 }
diff --git a/src/lib/eolian_cxx/grammar/function_declaration.hpp b/src/lib/eolian_cxx/grammar/function_declaration.hpp
index a6aa43948e..f01c214483 100644
--- a/src/lib/eolian_cxx/grammar/function_declaration.hpp
+++ b/src/lib/eolian_cxx/grammar/function_declaration.hpp
@@ -19,7 +19,7 @@ struct function_declaration_generator
19 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const 19 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const
20 { 20 {
21 return as_generator 21 return as_generator
22 (grammar::type << " " << string << "(" << (parameter % ", ") << ") const;\n") 22 (grammar::type(true) << " " << string << "(" << (parameter % ", ") << ") const;\n")
23 .generate(sink, std::make_tuple(f.return_type, escape_keyword(f.name), f.parameters), context); 23 .generate(sink, std::make_tuple(f.return_type, escape_keyword(f.name), f.parameters), context);
24 } 24 }
25}; 25};
diff --git a/src/lib/eolian_cxx/grammar/function_definition.hpp b/src/lib/eolian_cxx/grammar/function_definition.hpp
index 170fa986e9..b2280271d9 100644
--- a/src/lib/eolian_cxx/grammar/function_definition.hpp
+++ b/src/lib/eolian_cxx/grammar/function_definition.hpp
@@ -54,7 +54,7 @@ struct function_definition_generator
54 return false; 54 return false;
55 55
56 if(!as_generator 56 if(!as_generator
57 ("inline " << grammar::type << " " << string << "::" << string << "(" << (parameter % ", ") << ") const\n{\n") 57 ("inline " << grammar::type(true) << " " << string << "::" << string << "(" << (parameter % ", ") << ") const\n{\n")
58 .generate(sink, std::make_tuple(f.return_type, _klass_name.eolian_name, escape_keyword(f.name), f.parameters), ctx)) 58 .generate(sink, std::make_tuple(f.return_type, _klass_name.eolian_name, escape_keyword(f.name), f.parameters), ctx))
59 return false; 59 return false;
60 60
@@ -105,9 +105,19 @@ struct function_definition_generator
105 attribute_conditional([] (attributes::parameter_def const& p) -> bool 105 attribute_conditional([] (attributes::parameter_def const& p) -> bool
106 { return p.direction != attributes::parameter_direction::in; }) 106 { return p.direction != attributes::parameter_direction::in; })
107 [ 107 [
108 attribute_reorder<-1, 1, 2, 2> 108 attribute_reorder<-1, 1, 1, 2, 2>
109 (scope_tab << "::efl::eolian::assign_out<" << parameter_type << ", " << c_type 109 (
110 << ">(" << string << ", __out_param_" << string << ");\n") 110 scope_tab << "::efl::eolian::assign_out<" << parameter_type << ", " << c_type
111 <<
112 (
113 attribute_conditional([] (attributes::type_def const& type)
114 { return type.original_type.visit(attributes::get_qualifier_visitor{}) & qualifier_info::is_own; })
115 [
116 ", true"
117 ] | eps
118 )
119 << ">(" << string << ", __out_param_" << string << ");\n"
120 )
111 ] 121 ]
112 | eps 122 | eps
113 ; 123 ;
@@ -116,7 +126,7 @@ struct function_definition_generator
116 126
117 if(f.return_type != attributes::void_ 127 if(f.return_type != attributes::void_
118 && !as_generator(scope_tab << "return ::efl::eolian::convert_to_return<" 128 && !as_generator(scope_tab << "return ::efl::eolian::convert_to_return<"
119 << type<< ">(__return_value);\n" 129 << type(true) << ">(__return_value);\n"
120 ).generate(sink, f.return_type, ctx)) return false; 130 ).generate(sink, f.return_type, ctx)) return false;
121 131
122 if(!as_generator("}\n").generate(sink, attributes::unused, ctx)) 132 if(!as_generator("}\n").generate(sink, attributes::unused, ctx))
diff --git a/src/lib/eolian_cxx/grammar/klass_def.hpp b/src/lib/eolian_cxx/grammar/klass_def.hpp
index b42d6f2d44..0c5d82056d 100644
--- a/src/lib/eolian_cxx/grammar/klass_def.hpp
+++ b/src/lib/eolian_cxx/grammar/klass_def.hpp
@@ -18,7 +18,15 @@
18#include <memory> 18#include <memory>
19#include <set> 19#include <set>
20 20
21namespace efl { namespace eolian { namespace grammar { namespace attributes { 21namespace efl { namespace eolian { namespace grammar {
22
23namespace attributes {
24
25struct complex_type_def;
26
27}
28
29namespace attributes {
22 30
23template <typename...Args, std::size_t I> 31template <typename...Args, std::size_t I>
24bool lexicographical_compare_impl(std::tuple<Args...> const& 32bool lexicographical_compare_impl(std::tuple<Args...> const&
@@ -56,25 +64,6 @@ bool lexicographical_compare(std::tuple<T, U> const& lhs
56 && std::get<1>(lhs) < std::get<1>(rhs)); 64 && std::get<1>(lhs) < std::get<1>(rhs));
57} 65}
58 66
59struct pointer_indirection
60{
61 qualifier_def qualifier;
62 bool reference;
63};
64inline bool operator<(pointer_indirection const& lhs, pointer_indirection const& rhs)
65{
66 return lexicographical_compare(std::make_tuple(lhs.qualifier, lhs.reference)
67 , std::make_tuple(rhs.qualifier, rhs.reference));
68}
69inline bool operator==(pointer_indirection const& lhs, pointer_indirection const& rhs)
70{
71 return lhs.qualifier == rhs.qualifier && lhs.reference == rhs.reference;
72}
73inline bool operator!=(pointer_indirection const& lhs, pointer_indirection const& rhs)
74{
75 return !(lhs == rhs);
76}
77
78struct type_def; 67struct type_def;
79bool operator==(type_def const& rhs, type_def const& lhs); 68bool operator==(type_def const& rhs, type_def const& lhs);
80bool operator!=(type_def const& rhs, type_def const& lhs); 69bool operator!=(type_def const& rhs, type_def const& lhs);
@@ -89,19 +78,16 @@ struct klass_name
89 std::vector<std::string> namespaces; 78 std::vector<std::string> namespaces;
90 std::string eolian_name; 79 std::string eolian_name;
91 qualifier_def base_qualifier; 80 qualifier_def base_qualifier;
92 std::vector<pointer_indirection> pointers;
93 class_type type; 81 class_type type;
94 82
95 klass_name(std::vector<std::string> namespaces 83 klass_name(std::vector<std::string> namespaces
96 , std::string eolian_name, qualifier_def base_qualifier 84 , std::string eolian_name, qualifier_def base_qualifier
97 , std::vector<pointer_indirection> pointers
98 , class_type type) 85 , class_type type)
99 : namespaces(namespaces), eolian_name(eolian_name), base_qualifier(base_qualifier) 86 : namespaces(namespaces), eolian_name(eolian_name), base_qualifier(base_qualifier)
100 , pointers(pointers), type(type) {} 87 , type(type) {}
101 klass_name(Eolian_Class const* klass, qualifier_def base_qualifier 88 klass_name(Eolian_Class const* klass, qualifier_def base_qualifier)
102 , std::vector<pointer_indirection> pointers)
103 : eolian_name( ::eolian_class_name_get(klass)) 89 : eolian_name( ::eolian_class_name_get(klass))
104 , base_qualifier(base_qualifier), pointers(pointers) 90 , base_qualifier(base_qualifier)
105 { 91 {
106 for(efl::eina::iterator<const char> namespace_iterator ( ::eolian_class_namespaces_get(klass)) 92 for(efl::eina::iterator<const char> namespace_iterator ( ::eolian_class_namespaces_get(klass))
107 , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator) 93 , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
@@ -131,7 +117,7 @@ struct klass_name
131inline bool operator==(klass_name const& lhs, klass_name const& rhs) 117inline bool operator==(klass_name const& lhs, klass_name const& rhs)
132{ 118{
133 return lhs.namespaces == rhs.namespaces && lhs.eolian_name == rhs.eolian_name 119 return lhs.namespaces == rhs.namespaces && lhs.eolian_name == rhs.eolian_name
134 && lhs.base_qualifier == rhs.base_qualifier && lhs.pointers == rhs.pointers; 120 && lhs.base_qualifier == rhs.base_qualifier/* && lhs.pointers == rhs.pointers*/;
135} 121}
136inline bool operator!=(klass_name const& lhs, klass_name const& rhs) 122inline bool operator!=(klass_name const& lhs, klass_name const& rhs)
137{ 123{
@@ -142,14 +128,13 @@ inline bool operator<(klass_name const& lhs, klass_name const& rhs)
142 typedef std::tuple<std::vector<std::string>const& 128 typedef std::tuple<std::vector<std::string>const&
143 , std::string const& 129 , std::string const&
144 , qualifier_def const& 130 , qualifier_def const&
145 , std::vector<pointer_indirection> const&
146 , class_type 131 , class_type
147 > tuple_type; 132 > tuple_type;
148 return lexicographical_compare(tuple_type(lhs.namespaces, lhs.eolian_name 133 return lexicographical_compare(tuple_type(lhs.namespaces, lhs.eolian_name
149 , lhs.base_qualifier, lhs.pointers 134 , lhs.base_qualifier
150 , lhs.type) 135 , lhs.type)
151 , tuple_type(rhs.namespaces, rhs.eolian_name 136 , tuple_type(rhs.namespaces, rhs.eolian_name
152 , rhs.base_qualifier, rhs.pointers 137 , rhs.base_qualifier
153 , rhs.type)); 138 , rhs.type));
154} 139}
155 140
@@ -187,14 +172,12 @@ struct regular_type_def
187{ 172{
188 std::string base_type; 173 std::string base_type;
189 qualifier_def base_qualifier; 174 qualifier_def base_qualifier;
190 std::vector<pointer_indirection> pointers;
191 std::vector<std::string> namespaces; 175 std::vector<std::string> namespaces;
192}; 176};
193 177
194inline bool operator==(regular_type_def const& rhs, regular_type_def const& lhs) 178inline bool operator==(regular_type_def const& rhs, regular_type_def const& lhs)
195{ 179{
196 return rhs.base_type == lhs.base_type && rhs.base_qualifier == lhs.base_qualifier 180 return rhs.base_type == lhs.base_type && rhs.base_qualifier == lhs.base_qualifier;
197 && rhs.pointers == lhs.pointers;
198} 181}
199inline bool operator!=(regular_type_def const& rhs, regular_type_def const& lhs) 182inline bool operator!=(regular_type_def const& rhs, regular_type_def const& lhs)
200{ 183{
@@ -230,23 +213,23 @@ struct type_def
230 { 213 {
231 set(eolian_type); 214 set(eolian_type);
232 } 215 }
233 struct set_pointer_visitor
234 {
235 typedef void result_type;
236 std::vector<pointer_indirection> pointers;
237 template <typename T>
238 void operator()(T& v) const
239 {
240 v.pointers = pointers;
241 }
242 void operator()(complex_type_def& complex) const
243 {
244 (*this)(complex.outer);
245 }
246 };
247 void set(Eolian_Type const* eolian_type); 216 void set(Eolian_Type const* eolian_type);
248}; 217};
249 218
219struct get_qualifier_visitor
220{
221 typedef qualifier_def result_type;
222 template <typename T>
223 qualifier_def operator()(T const& object) const
224 {
225 return object.base_qualifier;
226 }
227 qualifier_def operator()(complex_type_def const& complex) const
228 {
229 return complex.outer.base_qualifier;
230 }
231};
232
250inline bool operator==(type_def const& lhs, type_def const& rhs) 233inline bool operator==(type_def const& lhs, type_def const& rhs)
251{ 234{
252 return lhs.original_type == rhs.original_type && lhs.c_type == rhs.c_type; 235 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)
273 for(efl::eina::iterator<const char> namespace_iterator( ::eolian_type_namespaces_get(eolian_type)) 256 for(efl::eina::iterator<const char> namespace_iterator( ::eolian_type_namespaces_get(eolian_type))
274 , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator) 257 , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
275 namespaces.push_back(&*namespace_iterator); 258 namespaces.push_back(&*namespace_iterator);
276 original_type = {regular_type_def{ ::eolian_type_name_get(eolian_type), {qualifiers(eolian_type), {}}, {}, namespaces}}; 259 original_type = {regular_type_def{ ::eolian_type_name_get(eolian_type), {qualifiers(eolian_type), {}}, namespaces}};
277 } 260 }
278 break; 261 break;
279 case EOLIAN_TYPE_POINTER: 262 case EOLIAN_TYPE_POINTER:
280 { 263 {
281 std::vector<pointer_indirection> pointers 264 throw std::runtime_error("");
282 {{ {qualifiers(eolian_type), {}}, false }};
283 Eolian_Type const* base_type = eolian_type_base_type_get(eolian_type);
284 while(eolian_type_type_get(base_type) == EOLIAN_TYPE_POINTER)
285 {
286 pointers.push_back({{qualifiers(base_type), {}}});
287 base_type = eolian_type_base_type_get(base_type);
288 }
289
290 set(base_type);
291 original_type.visit(set_pointer_visitor{pointers});
292 c_type = ::eolian_type_c_type_get(eolian_type);
293 break;
294 } 265 }
295 case EOLIAN_TYPE_CLASS: 266 case EOLIAN_TYPE_CLASS:
296 { 267 {
297 Eolian_Class const* klass = eolian_type_class_get(eolian_type); 268 Eolian_Class const* klass = eolian_type_class_get(eolian_type);
298 original_type = klass_name(klass, {qualifiers(eolian_type), {}}, {}); 269 original_type = klass_name(klass, {qualifiers(eolian_type), {}});
299 } 270 }
300 break; 271 break;
301 case EOLIAN_TYPE_COMPLEX: 272 case EOLIAN_TYPE_COMPLEX:
@@ -329,7 +300,7 @@ struct add_optional_qualifier_visitor
329 template <typename T> 300 template <typename T>
330 void operator()(T& object) const 301 void operator()(T& object) const
331 { 302 {
332 add_optional(object.base_qualifier); 303 object.base_qualifier.qualifier |= qualifier_info::is_optional;
333 } 304 }
334 void operator()(complex_type_def& complex) const 305 void operator()(complex_type_def& complex) const
335 { 306 {
@@ -612,26 +583,34 @@ struct klass_def
612 Eolian_Function_Type type = ::eolian_function_type_get(function); 583 Eolian_Function_Type type = ::eolian_function_type_get(function);
613 if(type == EOLIAN_PROPERTY) 584 if(type == EOLIAN_PROPERTY)
614 { 585 {
615 if(! ::eolian_function_is_legacy_only(function, EOLIAN_PROP_GET) 586 try {
616 && ::eolian_function_scope_get(function, type) != EOLIAN_SCOPE_PRIVATE) 587 if(! ::eolian_function_is_legacy_only(function, EOLIAN_PROP_GET)
617 functions.push_back({function, EOLIAN_PROP_GET}); 588 && ::eolian_function_scope_get(function, type) != EOLIAN_SCOPE_PRIVATE)
618 if(! ::eolian_function_is_legacy_only(function, EOLIAN_PROP_SET) 589 functions.push_back({function, EOLIAN_PROP_GET});
619 && ::eolian_function_scope_get(function, type) != EOLIAN_SCOPE_PRIVATE) 590 } catch(std::exception const&) {}
620 functions.push_back({function, EOLIAN_PROP_SET}); 591 try {
592 if(! ::eolian_function_is_legacy_only(function, EOLIAN_PROP_SET)
593 && ::eolian_function_scope_get(function, type) != EOLIAN_SCOPE_PRIVATE)
594 functions.push_back({function, EOLIAN_PROP_SET});
595 } catch(std::exception const&) {}
621 } 596 }
622 else 597 else
623 if(! ::eolian_function_is_legacy_only(function, type) 598 try {
624 && ::eolian_function_scope_get(function, type) != EOLIAN_SCOPE_PRIVATE) 599 if(! ::eolian_function_is_legacy_only(function, type)
625 functions.push_back({function, type}); 600 && ::eolian_function_scope_get(function, type) != EOLIAN_SCOPE_PRIVATE)
601 functions.push_back({function, type});
602 } catch(std::exception const&) {}
626 } 603 }
627 for(efl::eina::iterator<Eolian_Function const> eolian_functions ( ::eolian_class_functions_get(klass, EOLIAN_METHOD)) 604 for(efl::eina::iterator<Eolian_Function const> eolian_functions ( ::eolian_class_functions_get(klass, EOLIAN_METHOD))
628 , functions_last; eolian_functions != functions_last; ++eolian_functions) 605 , functions_last; eolian_functions != functions_last; ++eolian_functions)
629 { 606 {
630 Eolian_Function const* function = &*eolian_functions; 607 try {
631 Eolian_Function_Type type = ::eolian_function_type_get(function); 608 Eolian_Function const* function = &*eolian_functions;
632 if(! ::eolian_function_is_legacy_only(function, EOLIAN_METHOD) 609 Eolian_Function_Type type = eolian_function_type_get(function);
633 && ::eolian_function_scope_get(function, type) != EOLIAN_SCOPE_PRIVATE) 610 if(! ::eolian_function_is_legacy_only(function, EOLIAN_METHOD)
634 functions.push_back({function, EOLIAN_METHOD}); 611 && ::eolian_function_scope_get(function, type) != EOLIAN_SCOPE_PRIVATE)
612 functions.push_back({function, EOLIAN_METHOD});
613 } catch(std::exception const&) {}
635 } 614 }
636 std::function<void(Eolian_Class const*)> inherit_algo = 615 std::function<void(Eolian_Class const*)> inherit_algo =
637 [&] (Eolian_Class const* klass) 616 [&] (Eolian_Class const* klass)
@@ -640,7 +619,7 @@ struct klass_def
640 , inherit_last; inherit_iterator != inherit_last; ++inherit_iterator) 619 , inherit_last; inherit_iterator != inherit_last; ++inherit_iterator)
641 { 620 {
642 Eolian_Class const* inherit = ::eolian_class_get_by_name(&*inherit_iterator); 621 Eolian_Class const* inherit = ::eolian_class_get_by_name(&*inherit_iterator);
643 inherits.insert({inherit, {}, {}}); 622 inherits.insert({inherit, {}});
644 inherit_algo(inherit); 623 inherit_algo(inherit);
645 } 624 }
646 }; 625 };
@@ -665,7 +644,9 @@ struct klass_def
665 for(efl::eina::iterator<Eolian_Event const> event_iterator( ::eolian_class_events_get(klass)) 644 for(efl::eina::iterator<Eolian_Event const> event_iterator( ::eolian_class_events_get(klass))
666 , event_last; event_iterator != event_last; ++event_iterator) 645 , event_last; event_iterator != event_last; ++event_iterator)
667 { 646 {
668 events.push_back(&*event_iterator); 647 try {
648 events.push_back(&*event_iterator);
649 } catch(std::exception const&) {}
669 } 650 }
670 } 651 }
671 652
@@ -673,7 +654,7 @@ struct klass_def
673 654
674inline klass_name get_klass_name(klass_def const& klass) 655inline klass_name get_klass_name(klass_def const& klass)
675{ 656{
676 return {klass.namespaces, klass.eolian_name, {qualifier_info::is_none, {}}, {}, klass.type}; 657 return {klass.namespaces, klass.eolian_name, {qualifier_info::is_none, {}}, klass.type};
677} 658}
678 659
679inline Eolian_Class const* get_klass(klass_name const& klass_name_) 660inline Eolian_Class const* get_klass(klass_name const& klass_name_)
@@ -703,6 +684,8 @@ struct is_tuple<attributes::parameter_def> : std::true_type {};
703template <> 684template <>
704struct is_tuple<attributes::event_def> : std::true_type {}; 685struct is_tuple<attributes::event_def> : std::true_type {};
705 686
706} } } } 687}
688
689} } }
707 690
708#endif 691#endif
diff --git a/src/lib/eolian_cxx/grammar/parameter.hpp b/src/lib/eolian_cxx/grammar/parameter.hpp
index f236841707..b29805e24a 100644
--- a/src/lib/eolian_cxx/grammar/parameter.hpp
+++ b/src/lib/eolian_cxx/grammar/parameter.hpp
@@ -7,20 +7,6 @@
7 7
8namespace efl { namespace eolian { namespace grammar { 8namespace efl { namespace eolian { namespace grammar {
9 9
10struct add_reference_visitor
11{
12 typedef void result_type;
13 template <typename T>
14 void operator()(T& object) const
15 {
16 object.pointers.insert(object.pointers.begin(), {{}, true});
17 }
18 void operator()(attributes::complex_type_def& complex) const
19 {
20 (*this)(complex.outer);
21 }
22};
23
24struct parameter_type_generator 10struct parameter_type_generator
25{ 11{
26 template <typename OutputIterator, typename Context> 12 template <typename OutputIterator, typename Context>
diff --git a/src/lib/eolian_cxx/grammar/qualifier_def.hpp b/src/lib/eolian_cxx/grammar/qualifier_def.hpp
index 3ba1a89553..b43b2f1b8f 100644
--- a/src/lib/eolian_cxx/grammar/qualifier_def.hpp
+++ b/src/lib/eolian_cxx/grammar/qualifier_def.hpp
@@ -10,68 +10,74 @@ namespace efl { namespace eolian { namespace grammar { namespace attributes {
10enum class qualifier_info { 10enum class qualifier_info {
11 is_none 11 is_none
12, is_own = 1 12, is_own = 1
13, is_const = 4 13, is_const = 2
14, is_const_own 14, is_optional = 4
15, is_optional = 8 15, is_ref = 8
16, is_optional_own
17, is_optional_const
18, is_optional_const_own
19}; 16};
20 17
21inline qualifier_info qualifiers(Eolian_Type const* type) 18struct qualifier_bool
19{
20 qualifier_info v;
21 qualifier_bool(qualifier_info v)
22 : v(v) {}
23
24 typedef qualifier_info(qualifier_bool::*unspecified_bool_type)() const;
25
26 operator unspecified_bool_type() const
27 {
28 return v != qualifier_info::is_none ? &qualifier_bool::operator qualifier_info : nullptr;
29 }
30 operator qualifier_info() const { return v; }
31};
32inline qualifier_bool operator|(qualifier_info lhs, qualifier_info rhs)
22{ 33{
23 bool is_own = ::eolian_type_is_own(type); 34 return static_cast<qualifier_info>(static_cast<int>(lhs) | static_cast<int>(rhs));
24 bool is_const = ::eolian_type_is_const(type);
25 if(is_own && is_const)
26 return qualifier_info::is_const_own;
27 else if(is_own)
28 return qualifier_info::is_own;
29 else if(is_const)
30 return qualifier_info::is_const;
31 else
32 return qualifier_info::is_none;
33} 35}
34 36inline qualifier_bool operator&(qualifier_info lhs, qualifier_info rhs)
35inline bool is_own(qualifier_info i) 37{
36{ 38 return static_cast<qualifier_info>(static_cast<int>(lhs) & static_cast<int>(rhs));
37 switch(i)
38 {
39 case qualifier_info::is_own:
40 case qualifier_info::is_const_own:
41 case qualifier_info::is_optional_own:
42 case qualifier_info::is_optional_const_own:
43 return true;
44 default:
45 return false;
46 }
47} 39}
48 40inline qualifier_info operator^(qualifier_info lhs, qualifier_info rhs)
49inline bool is_const(qualifier_info i) 41{
50{ 42 return static_cast<qualifier_info>(static_cast<int>(lhs) & ~static_cast<int>(rhs));
51 switch(i)
52 {
53 case qualifier_info::is_const:
54 case qualifier_info::is_const_own:
55 case qualifier_info::is_optional_const:
56 case qualifier_info::is_optional_const_own:
57 return true;
58 default:
59 return false;
60 }
61} 43}
62 44inline qualifier_info& operator|=(qualifier_info& lhs, qualifier_info rhs)
63inline bool is_optional(qualifier_info i) 45{
64{ 46 lhs = static_cast<qualifier_info>(static_cast<int>(lhs) | static_cast<int>(rhs));
65 switch(i) 47 return lhs;
66 { 48}
67 case qualifier_info::is_optional: 49inline qualifier_info& operator&=(qualifier_info& lhs, qualifier_info rhs)
68 case qualifier_info::is_optional_own: 50{
69 case qualifier_info::is_optional_const: 51 lhs = static_cast<qualifier_info>(static_cast<int>(lhs) & static_cast<int>(rhs));
70 case qualifier_info::is_optional_const_own: 52 return lhs;
71 return true; 53}
72 default: 54inline qualifier_info& operator^=(qualifier_info& lhs, qualifier_info rhs)
73 return false; 55{
74 } 56 lhs = static_cast<qualifier_info>(static_cast<int>(lhs) & ~static_cast<int>(rhs));
57 return lhs;
58}
59inline qualifier_bool operator|(qualifier_bool lhs, qualifier_info rhs)
60{
61 lhs.v |= rhs;
62 return lhs;
63}
64inline qualifier_bool operator&(qualifier_bool lhs, qualifier_info rhs)
65{
66 lhs.v &= rhs;
67 return lhs;
68}
69inline qualifier_bool operator^(qualifier_bool lhs, qualifier_info rhs)
70{
71 lhs.v ^= rhs;
72 return lhs;
73}
74
75inline qualifier_info qualifiers(Eolian_Type const* type)
76{
77 qualifier_info is_own = ::eolian_type_is_own(type) ? qualifier_info::is_own : qualifier_info::is_none;
78 qualifier_info is_const = ::eolian_type_is_const(type) ? qualifier_info::is_const : qualifier_info::is_none;
79 qualifier_info is_ref = ::eolian_type_is_ref(type) ? qualifier_info::is_ref : qualifier_info::is_none;
80 return is_own | is_const | is_ref;
75} 81}
76 82
77struct qualifier_def 83struct qualifier_def
@@ -82,8 +88,30 @@ struct qualifier_def
82 qualifier_def() : qualifier(qualifier_info::is_none) {} 88 qualifier_def() : qualifier(qualifier_info::is_none) {}
83 qualifier_def(qualifier_info info, std::string free_function) 89 qualifier_def(qualifier_info info, std::string free_function)
84 : qualifier(info), free_function(std::move(free_function)) {} 90 : qualifier(info), free_function(std::move(free_function)) {}
91
92 typedef qualifier_info(qualifier_bool::*unspecified_bool_type)() const;
93 operator unspecified_bool_type() const
94 {
95 return qualifier != qualifier_info::is_none ? &qualifier_bool::operator qualifier_info : nullptr;
96 }
85}; 97};
86 98
99inline qualifier_def operator|(qualifier_def lhs, qualifier_info rhs)
100{
101 lhs.qualifier = lhs.qualifier | rhs;
102 return lhs;
103}
104inline qualifier_def operator&(qualifier_def lhs, qualifier_info rhs)
105{
106 lhs.qualifier = lhs.qualifier & rhs;
107 return lhs;
108}
109inline qualifier_def operator^(qualifier_def lhs, qualifier_info rhs)
110{
111 lhs.qualifier = lhs.qualifier ^ rhs;
112 return lhs;
113}
114
87inline bool operator<(qualifier_def const& lhs, qualifier_def const& rhs) 115inline bool operator<(qualifier_def const& lhs, qualifier_def const& rhs)
88{ 116{
89 return lhs.qualifier < rhs.qualifier || 117 return lhs.qualifier < rhs.qualifier ||
@@ -102,81 +130,8 @@ inline bool operator!=(qualifier_def const& lhs, qualifier_def const& rhs)
102 return !(rhs == lhs); 130 return !(rhs == lhs);
103} 131}
104 132
105inline void add_optional(qualifier_def& q)
106{
107 switch (q.qualifier)
108 {
109 case qualifier_info::is_none:
110 q.qualifier = qualifier_info::is_optional;
111 break;
112 case qualifier_info::is_own:
113 q.qualifier = qualifier_info::is_optional_own;
114 break;
115 case qualifier_info::is_const:
116 q.qualifier = qualifier_info::is_optional_const;
117 break;
118 case qualifier_info::is_const_own:
119 q.qualifier = qualifier_info::is_optional_const_own;
120 break;
121 default:
122 break;
123 }
124}
125inline void remove_optional(qualifier_def& q)
126{
127 switch (q.qualifier)
128 {
129 case qualifier_info::is_optional:
130 q.qualifier = qualifier_info::is_none;
131 break;
132 case qualifier_info::is_optional_own:
133 q.qualifier = qualifier_info::is_own;
134 break;
135 case qualifier_info::is_optional_const:
136 q.qualifier = qualifier_info::is_const;
137 break;
138 case qualifier_info::is_optional_const_own:
139 q.qualifier = qualifier_info::is_const_own;
140 break;
141 default:
142 break;
143 }
144}
145inline void remove_own(qualifier_def& q)
146{
147 switch (q.qualifier)
148 {
149 case qualifier_info::is_own:
150 q.qualifier = qualifier_info::is_none;
151 break;
152 case qualifier_info::is_const_own:
153 q.qualifier = qualifier_info::is_const;
154 break;
155 case qualifier_info::is_optional_own:
156 q.qualifier = qualifier_info::is_optional;
157 break;
158 case qualifier_info::is_optional_const_own:
159 q.qualifier = qualifier_info::is_optional_const;
160 break;
161 default:
162 break;
163 }
164}
165
166inline bool is_optional(qualifier_def const& i)
167{
168 return is_optional(i.qualifier);
169}
170inline bool is_own(qualifier_def const& i)
171{
172 return is_own(i.qualifier);
173}
174inline bool is_const(qualifier_def const& i)
175{
176 return is_const(i.qualifier);
177} 133}
178 134using attributes::qualifier_info;
179 135} } }
180} } } }
181 136
182#endif 137#endif
diff --git a/src/lib/eolian_cxx/grammar/type.hpp b/src/lib/eolian_cxx/grammar/type.hpp
index c2719c35c1..8a09b6e199 100644
--- a/src/lib/eolian_cxx/grammar/type.hpp
+++ b/src/lib/eolian_cxx/grammar/type.hpp
@@ -12,29 +12,50 @@ struct visitor_generate;
12 12
13struct type_generator 13struct type_generator
14{ 14{
15 type_generator(bool is_return = false)
16 : is_return(is_return) {}
17
15 template <typename OutputIterator, typename Context> 18 template <typename OutputIterator, typename Context>
16 bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const 19 bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const
17 { 20 {
18 return type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false}); 21 return type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false, is_return});
19 } 22 }
20 template <typename OutputIterator, typename Context> 23 template <typename OutputIterator, typename Context>
21 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const 24 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
22 { 25 {
23 return param.type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, param.c_type 26 return param.type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, param.c_type
24 , param.direction != attributes::parameter_direction::in}); 27 , param.direction != attributes::parameter_direction::in, false});
25 } 28 }
29
30 bool is_return;
26}; 31};
27 32
33struct type_terminal
34{
35 type_generator const operator()(bool is_return) const
36 {
37 return type_generator(is_return);
38 }
39} const type = {};
40
41type_generator const as_generator(type_terminal)
42{
43 return type_generator{};
44}
45
28template <> 46template <>
29struct is_eager_generator<type_generator> : std::true_type {}; 47struct is_eager_generator<type_generator> : std::true_type {};
48template <>
49struct is_generator<type_terminal> : std::true_type {};
30 50
31namespace type_traits { 51namespace type_traits {
32template <> 52template <>
33struct attributes_needed<type_generator> : std::integral_constant<int, 1> {}; 53struct attributes_needed<type_generator> : std::integral_constant<int, 1> {};
54template <>
55struct attributes_needed<type_terminal> : std::integral_constant<int, 1> {};
34} 56}
35 57
36type_generator const type = {}; 58
37
38} } } 59} } }
39 60
40#endif 61#endif
diff --git a/src/lib/eolian_cxx/grammar/type_impl.hpp b/src/lib/eolian_cxx/grammar/type_impl.hpp
index 7eda7ad47d..2e75e126a4 100644
--- a/src/lib/eolian_cxx/grammar/type_impl.hpp
+++ b/src/lib/eolian_cxx/grammar/type_impl.hpp
@@ -9,52 +9,6 @@
9 9
10namespace efl { namespace eolian { namespace grammar { 10namespace efl { namespace eolian { namespace grammar {
11 11
12namespace detail {
13
14bool has_own(attributes::regular_type_def const& def)
15{
16 for(auto&& c : def.pointers)
17 if(is_own(c.qualifier))
18 return true;
19 return false;
20}
21
22}
23
24namespace detail {
25
26struct swap_pointers_visitor
27{
28 std::vector<attributes::pointer_indirection>* pointers;
29 typedef void result_type;
30 template <typename T>
31 void operator()(T& object) const
32 {
33 std::swap(*pointers, object.pointers);
34 }
35 void operator()(attributes::complex_type_def& complex) const
36 {
37 (*this)(complex.outer);
38 }
39};
40
41template <typename OutputIterator, typename Context>
42bool generate_pointers(OutputIterator sink, std::vector<attributes::pointer_indirection> const& pointers, Context const&
43 , bool no_reference)
44{
45 for(auto first = pointers.rbegin()
46 , last = pointers.rend(); first != last; ++first)
47 {
48 if(std::next(first) == last && first->reference && !no_reference)
49 *sink++ = '&';
50 else
51 *sink++ = '*';
52 }
53 return true;
54}
55
56}
57
58template <typename T> 12template <typename T>
59T const* as_const_pointer(T* p) { return p; } 13T const* as_const_pointer(T* p) { return p; }
60 14
@@ -90,6 +44,7 @@ struct visitor_generate
90 Context const* context; 44 Context const* context;
91 std::string c_type; 45 std::string c_type;
92 bool is_out; 46 bool is_out;
47 bool is_return;
93 48
94 typedef visitor_generate<OutputIterator, Context> visitor_type; 49 typedef visitor_generate<OutputIterator, Context> visitor_type;
95 typedef bool result_type; 50 typedef bool result_type;
@@ -105,14 +60,8 @@ struct visitor_generate
105 } 60 }
106 const match_table[] = 61 const match_table[] =
107 { 62 {
108 {"void_ptr", nullptr, [&]
109 {
110 std::vector<attributes::pointer_indirection> pointers = regular.pointers;
111 pointers.insert(pointers.begin(), {{}, false});
112 return attributes::regular_type_def{"void", regular.base_qualifier, pointers, {}};
113 }}
114 // signed primitives 63 // signed primitives
115 , {"byte", nullptr, [&] { return replace_base_type(regular, " char"); }} 64 {"byte", nullptr, [&] { return replace_base_type(regular, " char"); }}
116 , {"llong", nullptr, [&] { return replace_base_type(regular, " long long"); }} 65 , {"llong", nullptr, [&] { return replace_base_type(regular, " long long"); }}
117 , {"int8", nullptr, [&] { return replace_base_type(regular, " int8_t"); }} 66 , {"int8", nullptr, [&] { return replace_base_type(regular, " int8_t"); }}
118 , {"int16", nullptr, [&] { return replace_base_type(regular, " int16_t"); }} 67 , {"int16", nullptr, [&] { return replace_base_type(regular, " int16_t"); }}
@@ -133,25 +82,42 @@ struct visitor_generate
133 82
134 , {"ptrdiff", nullptr, [&] { return replace_base_type(regular, " ptrdiff_t"); }} 83 , {"ptrdiff", nullptr, [&] { return replace_base_type(regular, " ptrdiff_t"); }}
135 , {"intptr", nullptr, [&] { return replace_base_type(regular, " intptr_t"); }} 84 , {"intptr", nullptr, [&] { return replace_base_type(regular, " intptr_t"); }}
136 , {"string", true, [&] { return replace_base_type(regular, " ::std::string"); }} 85 , {"string", true, [&]
137 , {"string", false, [&] { return replace_base_type(regular, " ::efl::eina::string_view"); }} 86 {
87 regular_type_def r = regular;
88 r.base_qualifier.qualifier ^= qualifier_info::is_ref;
89 if(is_out || is_return)
90 return replace_base_type(r, " ::std::string");
91 else return replace_base_type(r, " ::efl::eina::string_view");
92 }}
93 , {"string", false, [&]
94 {
95 regular_type_def r = regular;
96 r.base_qualifier.qualifier ^= qualifier_info::is_ref;
97 return replace_base_type(r, " ::efl::eina::string_view");
98 }}
138 , {"generic_value", nullptr, [&] 99 , {"generic_value", nullptr, [&]
139 { return regular_type_def{" ::efl::eina::value", regular.base_qualifier 100 { return regular_type_def{" ::efl::eina::value", regular.base_qualifier, {}};
140 , {regular.pointers.empty()
141 || (regular.pointers.size() == 1 && regular.pointers[0].reference)
142 ? regular.pointers
143 : std::vector<attributes::pointer_indirection>
144 {regular.pointers.begin(), std::prev(regular.pointers.end())}}
145 , {}};
146 }} 101 }}
147 }; 102 };
148 103 if(regular.base_type == "void_ptr")
149 if(eina::optional<bool> b = call_match 104 {
105 if(regular.base_qualifier & qualifier_info::is_ref)
106 throw std::runtime_error("ref of void_ptr is invalid");
107 return as_generator
108 (
109 lit("void") << (regular.base_qualifier & qualifier_info::is_const ? " const" : "")
110 << "*"
111 << (is_out ? "&" : "")
112 )
113 .generate(sink, attributes::unused, *context);
114 }
115 else if(eina::optional<bool> b = call_match
150 (match_table 116 (match_table
151 , [&] (match const& m) 117 , [&] (match const& m)
152 { 118 {
153 return (!m.name || *m.name == regular.base_type) 119 return (!m.name || *m.name == regular.base_type)
154 && (!m.has_own || *m.has_own == is_own(regular.base_qualifier)) 120 && (!m.has_own || *m.has_own == (bool)(regular.base_qualifier & qualifier_info::is_own))
155 ; 121 ;
156 } 122 }
157 , [&] (attributes::type_def::variant_type const& v) 123 , [&] (attributes::type_def::variant_type const& v)
@@ -161,94 +127,83 @@ struct visitor_generate
161 { 127 {
162 return *b; 128 return *b;
163 } 129 }
164 else if(attributes::is_optional(regular.base_qualifier)) 130 // in A @optional -> optional<A>
131 // in A& @optional -> optional<A&>
132 // in A& @optional -> optional<A&>
133 // in own(A&) @optional -> A*
134 //
135 // out A @optional -> optional<A&>
136 // out A& @optional -> optional<A&>
137 // out own(A&) @optional -> optional<A*&>
138 else if(regular.base_qualifier & qualifier_info::is_optional)
165 { 139 {
166 if(regular.pointers.empty() || (regular.pointers.size() == 1 && regular.pointers[0].reference == true)) 140 attributes::regular_type_def no_optional_regular = regular;
141 no_optional_regular.base_qualifier.qualifier ^= qualifier_info::is_optional;
142 if(is_out)
167 { 143 {
168 attributes::complex_type_def def 144 if(no_optional_regular.base_qualifier & qualifier_info::is_own)
169 {attributes::regular_type_def{" ::efl::eina::optional", {}}}; 145 {
170 attributes::regular_type_def no_optional_regular = regular; 146 return as_generator(" ::efl::eina::optional<").generate(sink, attributes::unused, *context)
171 attributes::remove_optional(no_optional_regular.base_qualifier); 147 && (*this)(no_optional_regular)
172 148 && as_generator("&>").generate(sink, attributes::unused, *context);
173 def.subtypes.push_back({no_optional_regular, c_type}); 149 }
174 return (*this)(def); 150 else if(no_optional_regular.base_qualifier & qualifier_info::is_ref)
151 {
152 no_optional_regular.base_qualifier.qualifier ^= qualifier_info::is_ref;
153 return (*this)(no_optional_regular)
154 && as_generator("**").generate(sink, attributes::unused, *context);
155 }
156 else
157 return (*this)(no_optional_regular)
158 && as_generator("*").generate(sink, attributes::unused, *context);
175 } 159 }
176 else 160 else
177 { 161 {
178 attributes::regular_type_def no_optional_regular = regular; 162 // regular.base_qualifier & qualifier_info::is_ref
179 attributes::remove_optional(no_optional_regular.base_qualifier); 163 return as_generator(" ::efl::eina::optional<").generate(sink, attributes::unused, *context)
180 no_optional_regular.pointers[0].reference = 0; 164 && (*this)(no_optional_regular)
181 return (*this)(no_optional_regular); 165 && as_generator(">").generate(sink, attributes::unused, *context);
182 } 166 }
183 } 167 }
184 // else if(detail::has_own(regular) && !regular.pointers.empty()) 168 else if((is_return || is_out) && regular.base_qualifier & qualifier_info::is_ref
185 // { 169 && regular.base_qualifier & qualifier_info::is_own)
186 // attributes::complex_type_def def 170 {
187 // {attributes::regular_type_def{" ::efl::eolian::own_ptr", attributes::qualifier_info::is_none, {}}}; 171 if(as_generator
188 172 (
189 // attributes::complex_type_def tagged_def 173 " ::std::unique_ptr<"
190 // {attributes::regular_type_def{" ::efl::eolian::own", attributes::qualifier_info::is_none, {}}}; 174 << *(string << "_")
191 175 << string
192 // auto pointer_iterator = regular.pointers.begin() 176 << (regular.base_qualifier & qualifier_info::is_const ? " const" : "")
193 // , pointer_last = regular.pointers.end(); 177 << ", ::efl::eina::malloc_deleter>"
194 178 )
195 // for(;pointer_iterator != pointer_last && !attributes::is_own(pointer_iterator->qualifier) 179 .generate(sink, std::make_tuple(regular.namespaces, regular.base_type), *context))
196 // ;++pointer_iterator) 180 return true;
197 // { 181 else
198 // tagged_def.outer.pointers.push_back(*pointer_iterator); 182 return false;
199 // tagged_def.outer.pointers.front().reference = false; 183 }
200 // } 184 else
201 185 {
202 // assert(attributes::is_own(pointer_iterator->qualifier)); 186 if(as_generator
203 187 (
204 // attributes::regular_type_def base_type (regular); 188 *(string << "_")
205 // base_type.pointers.clear(); 189 << string
206 190 << (regular.base_qualifier & qualifier_info::is_const
207 // for(;pointer_iterator != pointer_last; ++pointer_iterator) 191 || (regular.base_qualifier & qualifier_info::is_ref
208 // { 192 && !is_return && !is_out)
209 // base_type.pointers.insert(base_type.pointers.begin(), *pointer_iterator); 193 ? " const" : "")
210 // attributes::remove_own(base_type.pointers.back().qualifier); 194 << (regular.base_qualifier & qualifier_info::is_ref? "&" : "")
211 // } 195 )
212 196 .generate(sink, std::make_tuple(regular.namespaces, regular.base_type), *context))
213 // tagged_def.subtypes.push_back({base_type, c_type}); 197 return true;
214 // def.subtypes.push_back({tagged_def, c_type}); 198 else
215 // return (*this)(def); 199 return false;
216 // } 200 }
217 else if(detail::has_own(regular) && !regular.pointers.empty())
218 {
219 attributes::regular_type_def pointee = regular;
220 std::vector<attributes::pointer_indirection> pointers;
221 std::swap(pointers, pointee.pointers);
222 pointers.erase(pointers.begin());
223
224 attributes::pointer_indirection reference {{attributes::qualifier_info::is_none,{}}, true};
225
226 return as_generator(" ::std::unique_ptr<" << type).generate
227 (sink, attributes::type_def{pointee, c_type}, *context)
228 && detail::generate_pointers(sink, pointers, *context, true)
229 && as_generator(", void(*)(const void*)>").generate(sink, attributes::unused, *context)
230 && (!is_out || detail::generate_pointers(sink, {reference}, *context, false));
231 }
232 else
233 {
234 auto pointers = regular.pointers;
235 if(is_out)
236 pointers.push_back({{attributes::qualifier_info::is_none,{}}, true});
237 if(as_generator(*(string << "_") << string << (is_const(regular.base_qualifier)? " const" : ""))
238 .generate(sink, std::make_tuple(regular.namespaces, regular.base_type), *context))
239 return detail::generate_pointers(sink, pointers, *context
240 , regular.base_type == "void");
241 else
242 return false;
243 }
244 } 201 }
245 bool operator()(attributes::klass_name klass) const 202 bool operator()(attributes::klass_name klass) const
246 { 203 {
247 if(is_out)
248 klass.pointers.push_back({{attributes::qualifier_info::is_none, {}}, true});
249 if(as_generator(" " << *("::" << lower_case[string]) << "::" << string) 204 if(as_generator(" " << *("::" << lower_case[string]) << "::" << string)
250 .generate(sink, std::make_tuple(attributes::cpp_namespaces(klass.namespaces), klass.eolian_name), *context)) 205 .generate(sink, std::make_tuple(attributes::cpp_namespaces(klass.namespaces), klass.eolian_name), *context))
251 return detail::generate_pointers(sink, klass.pointers, *context, false); 206 return true;
252 else 207 else
253 return false; 208 return false;
254 } 209 }
@@ -286,26 +241,25 @@ struct visitor_generate
286 }} 241 }}
287 , {"hash", nullptr, nullptr 242 , {"hash", nullptr, nullptr
288 , [&] 243 , [&]
289 { regular_type_def r{"Eina_Hash", complex.outer.base_qualifier, complex.outer.pointers, {}}; 244 { regular_type_def r{"Eina_Hash*", complex.outer.base_qualifier, {}};
290 r.pointers.push_back({{qualifier_info::is_none, {}}, false});
291 return r; 245 return r;
292 }} 246 }}
293 , {"promise", nullptr, nullptr, [&] 247 , {"promise", nullptr, nullptr, [&]
294 { 248 {
295 return replace_outer 249 return replace_outer
296 (complex, regular_type_def{" ::efl::eina::future", complex.outer.base_qualifier, {}, {}}); 250 (complex, regular_type_def{" ::efl::eina::future", complex.outer.base_qualifier, {}});
297 } 251 }
298 } 252 }
299 , {"iterator", nullptr, nullptr, [&] 253 , {"iterator", nullptr, nullptr, [&]
300 { 254 {
301 return replace_outer 255 return replace_outer
302 (complex, regular_type_def{" ::efl::eina::iterator", complex.outer.base_qualifier, {}, {}}); 256 (complex, regular_type_def{" ::efl::eina::iterator", complex.outer.base_qualifier, {}});
303 } 257 }
304 } 258 }
305 , {"accessor", nullptr, nullptr, [&] 259 , {"accessor", nullptr, nullptr, [&]
306 { 260 {
307 return replace_outer 261 return replace_outer
308 (complex, regular_type_def{" ::efl::eina::accessor", complex.outer.base_qualifier, {}, {}}); 262 (complex, regular_type_def{" ::efl::eina::accessor", complex.outer.base_qualifier, {}});
309 } 263 }
310 } 264 }
311 }; 265 };
@@ -313,13 +267,14 @@ struct visitor_generate
313 auto default_match = [&] (attributes::complex_type_def const& complex) 267 auto default_match = [&] (attributes::complex_type_def const& complex)
314 { 268 {
315 regular_type_def no_pointer_regular = complex.outer; 269 regular_type_def no_pointer_regular = complex.outer;
316 std::vector<attributes::pointer_indirection> pointers; 270 // std::vector<attributes::pointer_indirection> pointers;
317 pointers.swap(no_pointer_regular.pointers); 271 // pointers.swap(no_pointer_regular.pointers);
318 if(is_out) 272 // if(is_out)
319 pointers.push_back({{attributes::qualifier_info::is_none, {}}, true}); 273 // pointers.push_back({{attributes::qualifier_info::is_none, {}}, true});
320 return visitor_type{sink, context, c_type, false}(no_pointer_regular) 274 return visitor_type{sink, context, c_type, false}(no_pointer_regular)
321 && as_generator("<" << (type % ", ") << ">").generate(sink, complex.subtypes, *context) 275 && as_generator("<" << (type % ", ") << ">").generate(sink, complex.subtypes, *context)
322 && detail::generate_pointers(sink, pointers, *context, false); 276 ;
277 // && detail::generate_pointers(sink, pointers, *context, false);
323 }; 278 };
324 279
325 if(eina::optional<bool> b = call_match 280 if(eina::optional<bool> b = call_match
@@ -327,8 +282,8 @@ struct visitor_generate
327 , [&] (match const& m) 282 , [&] (match const& m)
328 { 283 {
329 return (!m.name || *m.name == complex.outer.base_type) 284 return (!m.name || *m.name == complex.outer.base_type)
330 && (!m.has_own || *m.has_own == is_own(complex.outer.base_qualifier)) 285 && (!m.has_own || *m.has_own == bool(complex.outer.base_qualifier & qualifier_info::is_own))
331 && (!m.is_const || *m.is_const == is_const(complex.outer.base_qualifier)); 286 && (!m.is_const || *m.is_const == bool(complex.outer.base_qualifier & qualifier_info::is_const));
332 } 287 }
333 , [&] (attributes::type_def::variant_type const& v) 288 , [&] (attributes::type_def::variant_type const& v)
334 { 289 {