summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVitor Sousa <vitorsousasilva@gmail.com>2014-11-25 16:18:08 -0200
committerVitor Sousa <vitorsousasilva@gmail.com>2015-01-05 15:52:27 -0200
commitd5ec6c41d9bbd9e028503fe98dc6679f8c754140 (patch)
tree7f25de4940876272593b084e3fc449e516f84dba /src
parent890ce1f9cf902ccd0011a4041fd90d05f93f3c8a (diff)
eolian_cxx: Fix: Using binding type for @out parameter instead of native type
No longer reverting to the native type when the parameter has "@out" direction. Added "is_out" member variable to eolian_type class. With that, generators can keep track of the direction of the parameters. Also added helper functions "type_is_out" and "type_is_complex". Created "to_native" functions in eo_cxx_interop.hh to convert binding types from C++ arguments to the actual C function arguments. Added static assertions in these functions to enforce compatibility between the binding and the native type (Required by @out parameters). Reworked the overload of the "to_c" function for eo::base derivated objects. Now there is a overload that rely in the compatibility between the native type and the wrapper, enabling a wrapper to be used as an output parameter.
Diffstat (limited to 'src')
-rw-r--r--src/bin/eolian_cxx/eolian_wrappers.hh4
-rw-r--r--src/bindings/eo_cxx/eo_cxx_interop.hh36
-rw-r--r--src/lib/eolian_cxx/eo_types.hh23
-rw-r--r--src/lib/eolian_cxx/grammar/type_generator.hh10
4 files changed, 62 insertions, 11 deletions
diff --git a/src/bin/eolian_cxx/eolian_wrappers.hh b/src/bin/eolian_cxx/eolian_wrappers.hh
index 3dcb5e3c6b..d56379393f 100644
--- a/src/bin/eolian_cxx/eolian_wrappers.hh
+++ b/src/bin/eolian_cxx/eolian_wrappers.hh
@@ -348,7 +348,9 @@ parameter_type(Eolian_Function_Parameter const& parameter,
348 assert(!type.empty()); 348 assert(!type.empty());
349 if (parameter_is_out(parameter)) 349 if (parameter_is_out(parameter))
350 { 350 {
351 type = { efl::eolian::type_to_native(type) }; 351 if (type.front().native == "char *")
352 type = { efl::eolian::type_to_native(type) };
353 type.front().is_out = true;
352 type.front().native += "*"; 354 type.front().native += "*";
353 } 355 }
354 if (parameter_is_const(parameter, func_type)) 356 if (parameter_is_const(parameter, func_type))
diff --git a/src/bindings/eo_cxx/eo_cxx_interop.hh b/src/bindings/eo_cxx/eo_cxx_interop.hh
index fa3e44b282..d8292961f1 100644
--- a/src/bindings/eo_cxx/eo_cxx_interop.hh
+++ b/src/bindings/eo_cxx/eo_cxx_interop.hh
@@ -13,12 +13,6 @@ namespace efl { namespace eolian {
13 13
14//// From C++ to C 14//// From C++ to C
15 15
16inline Eo*
17to_c(efl::eo::base const& x)
18{
19 return x._eo_ptr();
20}
21
22inline const char* 16inline const char*
23to_c(std::string const& x) 17to_c(std::string const& x)
24{ 18{
@@ -45,10 +39,38 @@ to_c(bool* x)
45} 39}
46 40
47template <typename T> 41template <typename T>
48T to_c(T const& v, typename std::enable_if<!std::is_base_of<efl::eo::base, T>::value>::type* = 0) 42T to_c(T const& v, typename std::enable_if<!std::is_convertible<T*, efl::eo::base*>::value>::type* = 0)
49{ 43{
50 return v; 44 return v;
51} 45}
46
47template <typename T>
48Eo* to_c(T const& v, typename std::enable_if<std::is_convertible<T*, efl::eo::base*>::value>::type* = 0)
49{
50 return v._eo_ptr();
51}
52
53template <typename T>
54Eo** to_c(T* v, typename std::enable_if<std::is_convertible<T*, efl::eo::base*>::value>::type* = 0)
55{
56 static_assert(sizeof(T) == sizeof(Eo*), "");
57 return static_cast<Eo**>(static_cast<void*>(v));
58}
59
60template <typename R, typename T>
61R to_native(T const& v)
62{
63 static_assert(sizeof(T) == sizeof(R), "");
64 return v.native_handle();
65}
66
67template <typename R, typename T>
68R to_native(T* v)
69{
70 static_assert(sizeof(T) == sizeof(typename std::remove_pointer<R>::type), "");
71 return static_cast<R>(static_cast<void*>(v));
72}
73
52 74
53//// From C to C++ 75//// From C to C++
54 76
diff --git a/src/lib/eolian_cxx/eo_types.hh b/src/lib/eolian_cxx/eo_types.hh
index 92237790d2..15f88e21fd 100644
--- a/src/lib/eolian_cxx/eo_types.hh
+++ b/src/lib/eolian_cxx/eo_types.hh
@@ -33,6 +33,7 @@ struct eolian_type
33 , category(unknown_) 33 , category(unknown_)
34 , is_const(false) 34 , is_const(false)
35 , is_own(false) 35 , is_own(false)
36 , is_out(false)
36 , binding() 37 , binding()
37 , includes() 38 , includes()
38 {} 39 {}
@@ -47,6 +48,7 @@ struct eolian_type
47 , category(category_) 48 , category(category_)
48 , is_const(is_const_) 49 , is_const(is_const_)
49 , is_own(is_own_) 50 , is_own(is_own_)
51 , is_out(false)
50 , binding(binding_) 52 , binding(binding_)
51 , includes(includes_) 53 , includes(includes_)
52 { 54 {
@@ -66,6 +68,7 @@ struct eolian_type
66 category_type category; 68 category_type category;
67 bool is_const; 69 bool is_const;
68 bool is_own; 70 bool is_own;
71 bool is_out;
69 std::string binding; 72 std::string binding;
70 includes_container_type includes; 73 includes_container_type includes;
71}; 74};
@@ -94,6 +97,19 @@ type_is_binding(eolian_type_instance const& type)
94 return type_is_binding(type.front()); 97 return type_is_binding(type.front());
95} 98}
96 99
100inline bool
101type_is_out(eolian_type const& type)
102{
103 return type.is_out;
104}
105
106inline bool
107type_is_out(eolian_type_instance const& type)
108{
109 assert(!type.empty());
110 return type_is_out(type.front());
111}
112
97inline eolian_type 113inline eolian_type
98type_to_native(eolian_type const& type) 114type_to_native(eolian_type const& type)
99{ 115{
@@ -122,6 +138,13 @@ type_is_complex(eolian_type const& type)
122 return type.category == eolian_type::complex_; 138 return type.category == eolian_type::complex_;
123} 139}
124 140
141inline bool
142type_is_complex(eolian_type_instance const& type_ins)
143{
144 assert(!type_ins.empty());
145 return type_is_complex(type_ins.front());
146}
147
125template <typename T> 148template <typename T>
126inline bool 149inline bool
127type_is_callback(T const&); 150type_is_callback(T const&);
diff --git a/src/lib/eolian_cxx/grammar/type_generator.hh b/src/lib/eolian_cxx/grammar/type_generator.hh
index fcd16005c8..94e91c088b 100644
--- a/src/lib/eolian_cxx/grammar/type_generator.hh
+++ b/src/lib/eolian_cxx/grammar/type_generator.hh
@@ -47,10 +47,12 @@ operator<<(std::ostream& out, efl::eolian::grammar::reinterpret_type const& x)
47 std::string res; 47 std::string res;
48 for (auto rit = x._list.rbegin(), last = x._list.rend(); rit != last; ++rit) 48 for (auto rit = x._list.rbegin(), last = x._list.rend(); rit != last; ++rit)
49 { 49 {
50 if (type_is_complex(*rit)) 50 eolian_type const& t = *rit;
51 res = (*rit).binding + "< " + res + " >"; 51 if (type_is_complex(t))
52 res = t.binding + "< " + res + " >" + (t.is_out ? "*" : "");
52 else 53 else
53 res = type_is_binding(*rit) ? (*rit).binding : (*rit).native; 54 res = type_is_binding(t) ? t.binding + (t.is_out ? "*" : "")
55 : t.native;
54 } 56 }
55 assert(!res.empty()); 57 assert(!res.empty());
56 return out << res; 58 return out << res;
@@ -191,6 +193,8 @@ operator<<(std::ostream& out, to_c const& x)
191 if (type_is_callback(x._type)) 193 if (type_is_callback(x._type))
192 out << "efl::eolian::get_callback<" << type_to_native_str(x._type) 194 out << "efl::eolian::get_callback<" << type_to_native_str(x._type)
193 << ", " << parameter_no_ref_type(x._type, x._varname) << " >()"; 195 << ", " << parameter_no_ref_type(x._type, x._varname) << " >()";
196 else if (type_is_complex(x._type) && type_is_binding(x._type))
197 out << "efl::eolian::to_native<" << c_type(x._type) << ">(" << x._varname << ")";
194 else if (type_is_binding(x._type)) 198 else if (type_is_binding(x._type))
195 out << "efl::eolian::to_c(" << x._varname << ")"; 199 out << "efl::eolian::to_c(" << x._varname << ")";
196 else 200 else