summaryrefslogtreecommitdiff
path: root/src/bindings
diff options
context:
space:
mode:
authorVitor Sousa <vitorsousasilva@gmail.com>2015-03-26 11:48:09 -0300
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2015-04-14 01:06:57 -0300
commitce36f0be936f218d87055cf21b643ab327f07853 (patch)
treefde18f8d5e3e33b57583ba321e61e7f4a07de224 /src/bindings
parent72604d49574dba6d540d631895facbbc9b12bb2f (diff)
eolain_cxx: Fix C++ support for new Eolian features
Added optional constructor methods for C++ Eolian wrappers. Changed the interface of wrappers' main constructors. If there are optional constructor methods they should be passed as variadic template argument at the end of the constructor. To support variadic template arguments, the optional "parent" parameter is now the first parameter and there is another constructor without the "parent" parameter. Checking for @optinal and @nullable attributes instead of @nonull. Now @nonull is the default, and eina::optional is only used when @optional or @nullable attribute is specified. The names of constructor methods no longer have the class name prefixed. Added unit tests for checking the binding of optional constructors. Added new .eo file to be used in the test. Changed the generated documentation of constructors. Changed the efl::eo::inherit accordingly, to address these new features. Now the constructor methods should be explicit called in the efl::eo::inherit constructor, which will receive them via variadic template arguments. Added another constructor to efl::eo::inherit for passing the parent object. Updated some tests and examples to follow the new interface. Removed some code that is no longer necessary. Also, fix Eolian C++ support for constructing properties. fix assertion when parsing constructing properties. Now if a property is a constructing property eolian_cxx will generate a constructor method that have the property name (without the "_set" suffix).
Diffstat (limited to 'src/bindings')
-rw-r--r--src/bindings/eo_cxx/eo_cxx_interop.hh21
-rw-r--r--src/bindings/eo_cxx/eo_inherit.hh26
-rw-r--r--src/bindings/eo_cxx/eo_inherit_bindings.hh192
3 files changed, 46 insertions, 193 deletions
diff --git a/src/bindings/eo_cxx/eo_cxx_interop.hh b/src/bindings/eo_cxx/eo_cxx_interop.hh
index 08ca3005ba..ef3e9c73f5 100644
--- a/src/bindings/eo_cxx/eo_cxx_interop.hh
+++ b/src/bindings/eo_cxx/eo_cxx_interop.hh
@@ -6,10 +6,13 @@
6#include <tuple> 6#include <tuple>
7#include <utility> 7#include <utility>
8#include <type_traits> 8#include <type_traits>
9#include <initializer_list>
9 10
10#include <Eina.hh> 11#include <Eina.hh>
11#include <Eo.hh> 12#include <Eo.hh>
12 13
14#include "eo_concrete.hh"
15
13namespace efl { namespace eolian { 16namespace efl { namespace eolian {
14 17
15//// From C++ to C 18//// From C++ to C
@@ -443,6 +446,14 @@ Eina_Bool free_callback_calback(void* data, Eo* obj EINA_UNUSED
443 return EO_CALLBACK_CONTINUE; 446 return EO_CALLBACK_CONTINUE;
444} 447}
445 448
449template <typename... Fs>
450inline
451void register_ev_del_free_callback(Eo* eoptr, Fs&&... fs)
452{
453 std::initializer_list<int const> const v {(fs.register_ev_del_free_callback(eoptr), 0)...};
454 (void) v; (void) eoptr;
455}
456
446template <typename F> 457template <typename F>
447inline 458inline
448std::vector<F>& get_static_callback_vector() 459std::vector<F>& get_static_callback_vector()
@@ -459,6 +470,16 @@ F* alloc_static_callback(F&& f)
459 return &(get_static_callback_vector<F>().back()); 470 return &(get_static_callback_vector<F>().back());
460} 471}
461 472
473/// Miscellaneous
474
475template <typename... Fs>
476inline
477void call_ctors(Fs&&... fs)
478{
479 std::initializer_list<int const> const v {(fs(), 0)...};
480 (void) v;
481}
482
462} } // namespace efl { namespace eolian { 483} } // namespace efl { namespace eolian {
463 484
464#endif // EFL_EOLIAN_INTEROP_HH 485#endif // EFL_EOLIAN_INTEROP_HH
diff --git a/src/bindings/eo_cxx/eo_inherit.hh b/src/bindings/eo_cxx/eo_inherit.hh
index 734b6b6561..3138d1e9a9 100644
--- a/src/bindings/eo_cxx/eo_inherit.hh
+++ b/src/bindings/eo_cxx/eo_inherit.hh
@@ -13,16 +13,17 @@
13 13
14#include "eo_ops.hh" 14#include "eo_ops.hh"
15#include "eo_private.hh" 15#include "eo_private.hh"
16#include "eo_cxx_interop.hh"
16 17
17namespace efl { namespace eo { 18namespace efl { namespace eo {
18 19
19namespace detail { 20namespace detail {
20 21
21template <typename D, typename Args, typename... E, std::size_t... S> 22template <typename D, typename... E, std::size_t... S>
22Eo_Class const* create_class(eina::index_sequence<S...>); 23Eo_Class const* create_class(eina::index_sequence<S...>);
23 24
24template <typename Args, typename ... E> 25inline
25void inherit_constructor(void* this_, Args args); 26void inherit_constructor(void* this_);
26 27
27} 28}
28 29
@@ -67,23 +68,26 @@ struct inherit
67 /// 68 ///
68 typedef inherit<D, E...> inherit_base; 69 typedef inherit<D, E...> inherit_base;
69 70
71 //@{
70 /// @brief Class constructor. 72 /// @brief Class constructor.
71 /// 73 ///
72 /// @ref inherit has a "variadic" constructor implementation that 74 /// @ref inherit has a "variadic" constructor implementation that
73 /// allows from zero to EFL_MAX_ARGS heterogeneous parameters. 75 /// allows from zero to EFL_MAX_ARGS heterogeneous parameters.
74 /// 76 ///
75 template<typename... Args> 77 template<typename... Args>
76 inherit(Args&& ... args) 78 inherit(efl::eo::parent_type _p, Args&& ... args)
77 { 79 {
78 typedef std::tuple<typename std::remove_reference<Args>::type...> tuple_type; 80 _eo_cls = detail::create_class<D, E...> (eina::make_index_sequence<sizeof...(E)>());
79 _eo_cls = detail::create_class<D, tuple_type, E...> (eina::make_index_sequence<sizeof...(E)>()); 81 _eo_raw = eo_add_ref(_eo_cls, _p._eo_raw, detail::inherit_constructor(this), ::efl::eolian::call_ctors(args...));
80 _eo_raw = eo_add_ref 82 ::efl::eolian::register_ev_del_free_callback(_eo_raw, args...);
81 (_eo_cls, NULL,
82 detail::inherit_constructor
83 <tuple_type, E...>
84 (static_cast<void*>(this), tuple_type(std::forward<Args>(args)...)));
85 } 83 }
86 84
85 template<typename... Args>
86 inherit(Args&& ... args)
87 : inherit(::efl::eo::parent = nullptr, std::forward<Args>(args)...)
88 {}
89 //@}
90
87 /// @brief Class destructor. 91 /// @brief Class destructor.
88 /// 92 ///
89 ~inherit() 93 ~inherit()
diff --git a/src/bindings/eo_cxx/eo_inherit_bindings.hh b/src/bindings/eo_cxx/eo_inherit_bindings.hh
index 73fc2b1554..6022c1d305 100644
--- a/src/bindings/eo_cxx/eo_inherit_bindings.hh
+++ b/src/bindings/eo_cxx/eo_inherit_bindings.hh
@@ -12,46 +12,6 @@ namespace efl { namespace eo { namespace detail {
12 12
13/// @internal 13/// @internal
14/// 14///
15/// @brief Invokes the <em>EO C Constructor</em> that corresponds to the
16/// binded <em>EO C++ Class</em>.
17///
18/// @param T The corresponding <em>EO C++ Class</em>
19/// @param Args An heterogeneous list of constructor arguments
20///
21/// @param tag Used to instruct the compiler during compile-time which
22/// of the overloads should be invoked.
23/// @param eo A pointer to the <em>EO C Object</em> to be constructed.
24/// @param cls Unused.
25/// @param args An heterogenous vector containing the constructor
26/// arguments, in the correct order.
27///
28/// To ensure full reciprocity of the C++ binding there must exist one
29/// (and only one) implementation of @ref efl::eo::detail::call_constructor
30/// for each available <em>EO C++ Class</em> --- the implementations
31/// are differentiated by this unique specialization of
32/// @ref efl::eo::detail::tag for the first argument of
33/// @ref efl::eo::detail::call_constructor.
34///
35/// For example this is how the overload for @ref eo_simple is
36/// written as follows:
37///
38/// @dontinclude eo_simple.hh
39/// @skip call_constructor
40/// @until }
41///
42/// As you can see @c ::simple_constructor is called with a single
43/// argument in this case. Each EO Class has its own constructor
44/// prototype -- which can have different argument types as well as
45/// distinct number of arguments, etc. -- hence the need to specify a
46/// choice for every known <em>EO C++ Class</em>.
47///
48/// @see efl::eo::detail::tag
49///
50template <typename T, typename Args>
51void call_constructor(efl::eo::detail::tag<T> tag, Eo* eo, Eo_Class const* cls, Args args);
52
53/// @internal
54///
55/// @brief Sums up the number of <em>EO Operations</em> of each class 15/// @brief Sums up the number of <em>EO Operations</em> of each class
56/// passed as argument to the template. 16/// passed as argument to the template.
57/// 17///
@@ -73,132 +33,6 @@ struct operation_description_size<>
73 static const int value = 0; 33 static const int value = 0;
74}; 34};
75 35
76template <typename T>
77struct is_args_class : std::false_type
78{
79};
80
81template <typename T, typename Tuple>
82struct is_args_class<args_class<T, Tuple> >
83 : std::true_type
84{
85};
86
87template <typename Tuple>
88struct are_args_class;
89
90template <>
91struct are_args_class<std::tuple<> >
92 : std::true_type
93{
94};
95
96template <typename T0, typename... T>
97struct are_args_class<std::tuple<T0, T...> >
98 : std::integral_constant
99 <bool
100 , is_args_class<T0>::value
101 && are_args_class<std::tuple<T...> >::value
102 >
103{
104};
105
106template <typename T, typename Tuple>
107struct has_args_class : std::false_type
108{
109 typedef std::integral_constant<std::size_t, 0u> index;
110};
111
112template <typename T, typename Tuple, typename... Args>
113struct has_args_class<T, std::tuple<detail::args_class<T, Tuple>, Args...> >
114 : std::true_type
115{
116 typedef detail::args_class<T, Tuple> type;
117 typedef std::integral_constant<std::size_t, 0u> index;
118};
119
120template <typename T, typename T0, typename... Args>
121struct has_args_class<T, std::tuple<T0, Args...> >
122 : has_args_class<T, std::tuple<Args...> >
123{
124 typedef has_args_class<T, std::tuple<Args...> > base_type;
125 typedef std::integral_constant
126 <std::size_t, 1u + base_type::index::value> index;
127};
128
129/// @internal
130///
131/// @brief An auxiliary template-class used to select the correct
132/// implementation of @ref efl::eo::call_constructor for @p T with
133/// proper parameters and variadic size.
134///
135/// @param T An <em>EO C++ Class</em>.
136///
137template <typename T, std::size_t N>
138struct call_constructor_aux
139{
140 template <typename Args, typename P>
141 static void do_(Args const&, Eo* eo, Eo_Class const* cls
142 , P, typename std::enable_if<!P::value>::type* = 0)
143 {
144 call_constructor(tag<T>(), eo, cls, args_class<T, std::tuple<> >(std::tuple<>()));
145 }
146
147 template <typename Args, typename P>
148 static void do_(Args const& args, Eo* eo, Eo_Class const* cls
149 , P, typename std::enable_if<P::value>::type* = 0)
150 {
151 call_constructor(tag<T>(), eo, cls, std::get<P::index::value>(args));
152 }
153
154 /// @internal
155 ///
156 /// @brief Invoke @def efl::eo::detail::call_constructor
157 /// implementation for the parent and each available extension.
158 ///
159 /// @param args An heterogenous sequence of arguments.
160 /// @param eo The opaque <em>EO Object</em>.
161 /// @param cls The opaque <em>EO Class</em>.
162 ///
163 template <typename Args>
164 static int do_(Args const& args, Eo* eo, Eo_Class const* cls)
165 {
166 static_assert(std::tuple_size<Args>::value <= N, "");
167 static_assert(are_args_class<Args>::value, "");
168 do_(args, eo, cls, has_args_class<T, Args>());
169 return 0;
170 }
171};
172
173template <typename T>
174struct call_constructor_aux<T, 1u>
175{
176 template <typename Args>
177 static void do_(Args const& args, Eo* eo, Eo_Class const* cls
178 , std::true_type)
179 {
180 static_assert(std::tuple_size<Args>::value == 1, "");
181 static_assert(std::is_same
182 <typename std::tuple_element<0u, Args>::type::class_type
183 , T>::value, "");
184 call_constructor(tag<T>(), eo, cls, std::get<0u>(args));
185 }
186
187 template <typename Args>
188 static void do_(Args const& args, Eo* eo, Eo_Class const* cls
189 , std::false_type)
190 {
191 call_constructor(tag<T>(), eo, cls, args_class<T, Args>(args));
192 }
193
194 template <typename Args>
195 static int do_(Args const& args, Eo* eo, Eo_Class const* cls)
196 {
197 do_(args, eo, cls, has_args_class<T, Args>());
198 return 0;
199 }
200};
201
202template <typename... Args> 36template <typename... Args>
203void call_varargs(Args...) 37void call_varargs(Args...)
204{ 38{
@@ -209,18 +43,14 @@ void call_varargs(Args...)
209/// @brief The procedure that actually is invoked when the constructor 43/// @brief The procedure that actually is invoked when the constructor
210/// of @c D is sought from the <em>EO Subsystem</em>. 44/// of @c D is sought from the <em>EO Subsystem</em>.
211/// 45///
212/// @param obj The opaque <em>EO Object</em>.
213/// @param self A pointer to @p obj's private data. 46/// @param self A pointer to @p obj's private data.
214/// @param this_ A void pointer to the opaque <em>EO Class</em> --- 47/// @param this_ A void pointer to the opaque <em>EO Class</em> ---
215/// passed as <em>user data</em>. 48/// passed as <em>user data</em>.
216/// @param args The arguments for the underlying constructor.
217/// 49///
218template <typename D, typename Args, typename... E> 50inline
219void inherit_constructor_impl(Eo* obj, Inherit_Private_Data* self, void* this_, Args args) 51void inherit_constructor_impl(Eo*, Inherit_Private_Data* self, void* this_)
220{ 52{
221 self->this_ = this_; 53 self->this_ = this_;
222 Eo_Class const* cls = static_cast<inherit<D, E...>*>(this_)->_eo_class();
223 detail::call_varargs(detail::call_constructor_aux<E, sizeof...(E)>::do_(args, obj, cls) ...);
224} 54}
225 55
226/// @internal 56/// @internal
@@ -231,16 +61,16 @@ void inherit_constructor_impl(Eo* obj, Inherit_Private_Data* self, void* this_,
231/// @param this_ The <em>user data</em> to be passed to the resolved function. 61/// @param this_ The <em>user data</em> to be passed to the resolved function.
232/// @param args An heterogeneous sequence of arguments. 62/// @param args An heterogeneous sequence of arguments.
233/// 63///
234template <typename Args, typename... E> 64EAPI inline
235EAPI void inherit_constructor(void* this_, Args args) 65void inherit_constructor(void* this_)
236{ 66{
237 typedef void (*func_t)(Eo *, void *, void*, Args); 67 typedef void (*func_t)(Eo *, void *, void*);
238 Eo_Op_Call_Data ___call; 68 Eo_Op_Call_Data ___call;
239 static Eo_Op op = EO_NOOP; 69 static Eo_Op op = EO_NOOP;
240 if ( op == EO_NOOP ) 70 if ( op == EO_NOOP )
241 op = _eo_api_op_id_get 71 op = _eo_api_op_id_get
242 (reinterpret_cast<void*> 72 (reinterpret_cast<void*>
243 (static_cast<void(*)(void*, Args)>(&detail::inherit_constructor<Args, E...>)), 73 (&detail::inherit_constructor),
244 ::eina_main_loop_is(), __FILE__, __LINE__); 74 ::eina_main_loop_is(), __FILE__, __LINE__);
245 if (!_eo_call_resolve("detail::inherit_constructor", op, &___call, 75 if (!_eo_call_resolve("detail::inherit_constructor", op, &___call,
246 ::eina_main_loop_is(), __FILE__, __LINE__)) 76 ::eina_main_loop_is(), __FILE__, __LINE__))
@@ -251,7 +81,7 @@ EAPI void inherit_constructor(void* this_, Args args)
251 } 81 }
252 func_t func = (func_t) ___call.func; 82 func_t func = (func_t) ___call.func;
253 EO_HOOK_CALL_PREPARE(eo_hook_call_pre, ""); 83 EO_HOOK_CALL_PREPARE(eo_hook_call_pre, "");
254 func(___call.obj, ___call.data, this_, args); 84 func(___call.obj, ___call.data, this_);
255 EO_HOOK_CALL_PREPARE(eo_hook_call_post, ""); 85 EO_HOOK_CALL_PREPARE(eo_hook_call_post, "");
256} 86}
257 87
@@ -289,7 +119,7 @@ operation_description_index<0u, E...>
289/// 119///
290/// @see efl::eo::inherit::inherit 120/// @see efl::eo::inherit::inherit
291/// 121///
292template <typename D, typename TupleArgs, typename... E, std::size_t ... S> 122template <typename D, typename... E, std::size_t ... S>
293Eo_Class const* create_class(eina::index_sequence<S...>) 123Eo_Class const* create_class(eina::index_sequence<S...>)
294{ 124{
295 static const Eo_Class* my_class = NULL; 125 static const Eo_Class* my_class = NULL;
@@ -299,14 +129,12 @@ Eo_Class const* create_class(eina::index_sequence<S...>)
299 op_descs[detail::operation_description_size<E...>::value].func = 129 op_descs[detail::operation_description_size<E...>::value].func =
300 reinterpret_cast<void*> 130 reinterpret_cast<void*>
301 ( 131 (
302 static_cast<void(*)(Eo*, Inherit_Private_Data*, void*, TupleArgs)> 132 &detail::inherit_constructor_impl
303 (&detail::inherit_constructor_impl<D, TupleArgs, E...>)
304 ); 133 );
305 op_descs[detail::operation_description_size<E...>::value].api_func = 134 op_descs[detail::operation_description_size<E...>::value].api_func =
306 reinterpret_cast<void*> 135 reinterpret_cast<void*>
307 ( 136 (
308 static_cast<void(*)(void*, TupleArgs)> 137 &detail::inherit_constructor
309 (&detail::inherit_constructor<TupleArgs, E...>)
310 ); 138 );
311 op_descs[detail::operation_description_size<E...>::value].op = EO_NOOP; 139 op_descs[detail::operation_description_size<E...>::value].op = EO_NOOP;
312 op_descs[detail::operation_description_size<E...>::value].op_type = EO_OP_TYPE_REGULAR; 140 op_descs[detail::operation_description_size<E...>::value].op_type = EO_OP_TYPE_REGULAR;