felipealmeida pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=ce36f0be936f218d87055cf21b643ab327f07853

commit ce36f0be936f218d87055cf21b643ab327f07853
Author: Vitor Sousa <vitorsousasi...@gmail.com>
Date:   Thu Mar 26 11:48:09 2015 -0300

    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).
---
 src/Makefile_Eolian_Cxx.am                         |  15 +-
 src/Makefile_Eolian_Cxx_Helper.am                  |   5 +-
 src/bin/eolian_cxx/convert.cc                      |  68 +++++---
 src/bin/eolian_cxx/eolian_wrappers.hh              |   6 +-
 src/bindings/eo_cxx/eo_cxx_interop.hh              |  21 +++
 src/bindings/eo_cxx/eo_inherit.hh                  |  26 +--
 src/bindings/eo_cxx/eo_inherit_bindings.hh         | 192 ++-------------------
 src/examples/eolian_cxx/eolian_cxx_callbacks_01.cc |   2 +-
 src/examples/eolian_cxx/eolian_cxx_inherit_01.cc   |   4 +-
 src/examples/eolian_cxx/eolian_cxx_simple_01.cc    |   4 +-
 src/lib/eolian_cxx/eo_types.hh                     |  17 +-
 .../grammar/eo_class_constructors_generator.hh     | 184 +++++++++++++-------
 src/lib/eolian_cxx/grammar/eo_class_generator.hh   |   2 +-
 .../grammar/inheritance_base_generator.hh          |  68 --------
 src/lib/eolian_cxx/grammar/type_generator.hh       |   2 +-
 src/tests/eolian_cxx/eolian_cxx_suite.cc           |   2 +
 src/tests/eolian_cxx/eolian_cxx_test_binding.cc    |  58 +++++++
 src/tests/eolian_cxx/generic.c                     |  77 +++++++++
 src/tests/eolian_cxx/generic.eo                    |  58 +++++++
 19 files changed, 444 insertions(+), 367 deletions(-)

diff --git a/src/Makefile_Eolian_Cxx.am b/src/Makefile_Eolian_Cxx.am
index d086bff..77a62e3 100644
--- a/src/Makefile_Eolian_Cxx.am
+++ b/src/Makefile_Eolian_Cxx.am
@@ -70,33 +70,39 @@ tests/eolian_cxx/a.c \
 tests/eolian_cxx/b.c \
 tests/eolian_cxx/c.c \
 tests/eolian_cxx/d.c \
+tests/eolian_cxx/eolian_cxx_test_binding.cc \
 tests/eolian_cxx/eolian_cxx_test_callback.cc \
 tests/eolian_cxx/eolian_cxx_test_address_of.cc \
 tests/eolian_cxx/eolian_cxx_test_wrapper.cc \
 tests/eolian_cxx/simple.c \
+tests/eolian_cxx/generic.c \
 tests/eolian_cxx/eolian_cxx_test_inheritance.cc \
 tests/eolian_cxx/eolian_cxx_test_generate.cc
 
 
tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-eolian_cxx_test_wrapper.$(OBJEXT):
 tests/eolian_cxx/callback.eo.hh
 
tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-eolian_cxx_test_callback.$(OBJEXT):
 tests/eolian_cxx/callback.eo.hh
+tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-eolian_cxx_test_inheritance.$(OBJEXT):
 tests/eolian_cxx/simple.eo.hh
+tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-eolian_cxx_test_binding.$(OBJEXT):
 tests/eolian_cxx/generic.eo.hh
 
tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-eolian_cxx_test_address_of.$(OBJEXT):
 tests/eolian_cxx/a.eo.hh tests/eolian_cxx/b.eo.hh tests/eolian_cxx/c.eo.hh 
tests/eolian_cxx/d.eo.hh
 
 tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-callback.$(OBJEXT): 
tests/eolian_cxx/callback.eo.c tests/eolian_cxx/callback.eo.h
+tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-simple.$(OBJEXT): 
tests/eolian_cxx/simple.eo.c tests/eolian_cxx/simple.eo.h
+tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-generic.$(OBJEXT): 
tests/eolian_cxx/generic.eo.c tests/eolian_cxx/generic.eo.h
 tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-a.$(OBJEXT): 
tests/eolian_cxx/a.eo.c tests/eolian_cxx/a.eo.h
 tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-b.$(OBJEXT): 
tests/eolian_cxx/b.eo.c tests/eolian_cxx/b.eo.h
 tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-c.$(OBJEXT): 
tests/eolian_cxx/c.eo.c tests/eolian_cxx/c.eo.h
 tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-d.$(OBJEXT): 
tests/eolian_cxx/d.eo.c tests/eolian_cxx/d.eo.h
 
-tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-eolian_cxx_test_inheritance.$(OBJEXT):
 tests/eolian_cxx/simple.eo.hh
-
-tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-simple.$(OBJEXT): 
tests/eolian_cxx/simple.eo.c tests/eolian_cxx/simple.eo.h
-
 CLEANFILES += tests/eolian_cxx/callback.eo.hh tests/eolian_cxx/callback.eo.c \
 tests/eolian_cxx/callback.eo.h \
 tests/eolian_cxx/simple.eo.c \
 tests/eolian_cxx/simple.eo.h \
 tests/eolian_cxx/simple.eo.hh \
 tests/eolian_cxx/simple.eo.impl.hh \
+tests/eolian_cxx/generic.eo.c \
+tests/eolian_cxx/generic.eo.h \
+tests/eolian_cxx/generic.eo.hh \
+tests/eolian_cxx/generic.eo.impl.hh \
 tests/eolian_cxx/a.eo.hh tests/eolian_cxx/a.eo.impl.hh tests/eolian_cxx/a.eo.c 
tests/eolian_cxx/a.eo.h \
 tests/eolian_cxx/b.eo.hh tests/eolian_cxx/b.eo.impl.hh tests/eolian_cxx/b.eo.c 
tests/eolian_cxx/b.eo.h \
 tests/eolian_cxx/c.eo.hh tests/eolian_cxx/c.eo.impl.hh tests/eolian_cxx/c.eo.c 
tests/eolian_cxx/c.eo.h \
@@ -125,6 +131,7 @@ endif
 
 EXTRA_DIST += tests/eolian_cxx/callback.eo \
 tests/eolian_cxx/simple.eo \
+tests/eolian_cxx/generic.eo \
 tests/eolian_cxx/a.eo \
 tests/eolian_cxx/b.eo \
 tests/eolian_cxx/c.eo \
diff --git a/src/Makefile_Eolian_Cxx_Helper.am 
b/src/Makefile_Eolian_Cxx_Helper.am
index bb656c8..b754edf 100644
--- a/src/Makefile_Eolian_Cxx_Helper.am
+++ b/src/Makefile_Eolian_Cxx_Helper.am
@@ -12,10 +12,7 @@ am__v_EOLCXX_0 = @echo "  EOLCXX  " $@;
 
 SUFFIXES += .eo.hh
 
-%.eo.hh: %.eo $(_EOLIAN_CXX_DEP)
+%.eo.impl.hh %.eo.hh: %.eo $(_EOLIAN_CXX_DEP)
        $(AM_V_EOLCXX)$(EOLIAN_CXX) $(EOLIAN_FLAGS) -o $@ $<
 
-%.eo.impl.hh: %.eo.hh $(_EOLIAN_CXX_DEP)
-       true $<
-
 CLEANFILES += $(BUILT_SOURCES)
diff --git a/src/bin/eolian_cxx/convert.cc b/src/bin/eolian_cxx/convert.cc
index 22ee22f..4d03c8f 100644
--- a/src/bin/eolian_cxx/convert.cc
+++ b/src/bin/eolian_cxx/convert.cc
@@ -212,6 +212,20 @@ _convert_property_get_to_function(Eolian_Class const& 
klass,
    return get_;
 }
 
+static efl::eolian::eo_function
+_convert_function(Eolian_Class const& klass, Eolian_Function const& func)
+{
+   return {
+     function_type(func),
+     function_scope(func),
+     function_name(func),
+     function_impl(func),
+     function_return_type(func),
+     _convert_eolian_parameters(func),
+     convert_comments_function(klass, func, eolian_cxx::method)
+   };
+}
+
 
 void
 convert_eolian_inheritances(efl::eolian::eo_class& cls, Eolian_Class const& 
klass)
@@ -276,32 +290,42 @@ convert_eolian_functions(efl::eolian::eo_class& cls, 
Eolian_Class const& klass)
     , last; first != last; ++first)
      {
         Eolian_Function const& func = *first;
-        Eolian_Function_Type const func_type = function_op_type(func);
-
-        if (!function_is_visible(func, func_type))
-          continue;
 
-        if (function_is_constructor(klass, func))
+        if (function_is_visible(func, function_op_type(func)) &&
+            !function_is_constructor(klass, func))
           {
-             cls.constructors.push_back({
-                  function_impl(func),
-                  _convert_eolian_parameters(func),
-                  convert_comments_function(klass, func)
-             });
-          }
-        else
-          {
-             cls.functions.push_back({
-                 function_type(func),
-                 function_scope(func),
-                 function_name(func),
-                 function_impl(func),
-                 function_return_type(func),
-                 _convert_eolian_parameters(func),
-                 convert_comments_function(klass, func, eolian_cxx::method)
-               });
+             cls.functions.push_back(_convert_function(klass, func));
           }
      }
+   if (class_eo_name(klass) != "EO_BASE_CLASS")
+     for(efl::eina::iterator<const Eolian_Constructor> first ( 
::eolian_class_constructors_get(&klass))
+      , last; first != last; ++first)
+       {
+          Eolian_Constructor const& ctor = *first;
+          Eolian_Function const& func = 
*(::eolian_constructor_function_get(&ctor));
+
+          efl::eolian::eo_function f;
+          if (::eolian_function_type_get(&func) != EOLIAN_PROPERTY)
+            f = _convert_function(klass, func);
+          else
+            f = _convert_property_set_to_function(klass, func);
+
+
+          (::eolian_constructor_is_optional(&ctor) ?
+            cls.optional_constructors :
+            cls.constructors
+          ).push_back({
+             function_name(func),
+             f.impl,
+             f.params,
+             f.comment
+          });
+       }
+
+   cls.all_constructors = cls.constructors;
+   cls.all_constructors.insert(cls.all_constructors.end(),
+    cls.optional_constructors.begin(), cls.optional_constructors.end());
+
    for(efl::eina::iterator<const Eolian_Function> first ( 
::eolian_class_functions_get(&klass, EOLIAN_PROPERTY))
     , last; first != last; ++first)
      {
diff --git a/src/bin/eolian_cxx/eolian_wrappers.hh 
b/src/bin/eolian_cxx/eolian_wrappers.hh
index 5cad797..5b6579e 100644
--- a/src/bin/eolian_cxx/eolian_wrappers.hh
+++ b/src/bin/eolian_cxx/eolian_wrappers.hh
@@ -375,10 +375,8 @@ parameter_type(Eolian_Function_Parameter const& parameter,
         if (!type.front().binding.empty())
           type.front().binding.insert(0, "const ");
      }
-   if (::eolian_parameter_is_nonull(&parameter))
-     {
-        type.is_nonull = true;
-     }
+   type.is_optional = ::eolian_parameter_is_optional(&parameter) ||
+                      ::eolian_parameter_is_nullable(&parameter);
    return type;
 }
 
diff --git a/src/bindings/eo_cxx/eo_cxx_interop.hh 
b/src/bindings/eo_cxx/eo_cxx_interop.hh
index 08ca300..ef3e9c7 100644
--- a/src/bindings/eo_cxx/eo_cxx_interop.hh
+++ b/src/bindings/eo_cxx/eo_cxx_interop.hh
@@ -6,10 +6,13 @@
 #include <tuple>
 #include <utility>
 #include <type_traits>
+#include <initializer_list>
 
 #include <Eina.hh>
 #include <Eo.hh>
 
+#include "eo_concrete.hh"
+
 namespace efl { namespace eolian {
 
 //// From C++ to C
@@ -443,6 +446,14 @@ Eina_Bool free_callback_calback(void* data, Eo* obj 
EINA_UNUSED
    return EO_CALLBACK_CONTINUE;
 }
 
+template <typename... Fs>
+inline
+void register_ev_del_free_callback(Eo* eoptr, Fs&&... fs)
+{
+   std::initializer_list<int const> const v 
{(fs.register_ev_del_free_callback(eoptr), 0)...};
+   (void) v; (void) eoptr;
+}
+
 template <typename F>
 inline
 std::vector<F>& get_static_callback_vector()
@@ -459,6 +470,16 @@ F* alloc_static_callback(F&& f)
    return &(get_static_callback_vector<F>().back());
 }
 
+/// Miscellaneous
+
+template <typename... Fs>
+inline
+void call_ctors(Fs&&... fs)
+{
+   std::initializer_list<int const> const v {(fs(), 0)...};
+   (void) v;
+}
+
 } } // namespace efl { namespace eolian {
 
 #endif // EFL_EOLIAN_INTEROP_HH
diff --git a/src/bindings/eo_cxx/eo_inherit.hh 
b/src/bindings/eo_cxx/eo_inherit.hh
index 734b6b6..3138d1e 100644
--- a/src/bindings/eo_cxx/eo_inherit.hh
+++ b/src/bindings/eo_cxx/eo_inherit.hh
@@ -13,16 +13,17 @@
 
 #include "eo_ops.hh"
 #include "eo_private.hh"
+#include "eo_cxx_interop.hh"
 
 namespace efl { namespace eo {
 
 namespace detail {
 
-template <typename D, typename Args, typename... E, std::size_t... S>
+template <typename D, typename... E, std::size_t... S>
 Eo_Class const* create_class(eina::index_sequence<S...>);
 
-template <typename Args, typename ... E>
-void inherit_constructor(void* this_, Args args);
+inline
+void inherit_constructor(void* this_);
 
 }
 
@@ -67,23 +68,26 @@ struct inherit
    ///
    typedef inherit<D, E...> inherit_base;
 
+   //@{
    /// @brief Class constructor.
    ///
    /// @ref inherit has a "variadic" constructor implementation that
    /// allows from zero to EFL_MAX_ARGS heterogeneous parameters.
    ///
    template<typename... Args>
-   inherit(Args&& ... args)
+   inherit(efl::eo::parent_type _p, Args&& ... args)
    {
-      typedef std::tuple<typename std::remove_reference<Args>::type...> 
tuple_type;
-      _eo_cls = detail::create_class<D, tuple_type, E...> 
(eina::make_index_sequence<sizeof...(E)>());
-      _eo_raw = eo_add_ref
-        (_eo_cls, NULL,
-         detail::inherit_constructor
-         <tuple_type, E...>
-         (static_cast<void*>(this), tuple_type(std::forward<Args>(args)...)));
+      _eo_cls = detail::create_class<D, E...> 
(eina::make_index_sequence<sizeof...(E)>());
+      _eo_raw = eo_add_ref(_eo_cls, _p._eo_raw, 
detail::inherit_constructor(this), ::efl::eolian::call_ctors(args...));
+      ::efl::eolian::register_ev_del_free_callback(_eo_raw, args...);
   }
 
+  template<typename... Args>
+   inherit(Args&& ... args)
+     : inherit(::efl::eo::parent = nullptr, std::forward<Args>(args)...)
+   {}
+   //@}
+
    /// @brief Class destructor.
    ///
    ~inherit()
diff --git a/src/bindings/eo_cxx/eo_inherit_bindings.hh 
b/src/bindings/eo_cxx/eo_inherit_bindings.hh
index 73fc2b1..6022c1d 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 {
 
 /// @internal
 ///
-/// @brief Invokes the <em>EO C Constructor</em> that corresponds to the
-/// binded <em>EO C++ Class</em>.
-///
-/// @param T The corresponding <em>EO C++ Class</em>
-/// @param Args An heterogeneous list of constructor arguments
-///
-/// @param tag Used to instruct the compiler during compile-time which
-/// of the overloads should be invoked.
-/// @param eo A pointer to the <em>EO C Object</em> to be constructed.
-/// @param cls Unused.
-/// @param args An heterogenous vector containing the constructor
-/// arguments, in the correct order.
-///
-/// To ensure full reciprocity of the C++ binding there must exist one
-/// (and only one) implementation of @ref efl::eo::detail::call_constructor
-/// for each available <em>EO C++ Class</em> --- the implementations
-/// are differentiated by this unique specialization of
-/// @ref efl::eo::detail::tag for the first argument of
-/// @ref efl::eo::detail::call_constructor.
-///
-/// For example this is how the overload for @ref eo_simple is
-/// written as follows:
-///
-/// @dontinclude eo_simple.hh
-/// @skip call_constructor
-/// @until }
-///
-/// As you can see @c ::simple_constructor is called with a single
-/// argument in this case. Each EO Class has its own constructor
-/// prototype -- which can have different argument types as well as
-/// distinct number of arguments, etc. -- hence the need to specify a
-/// choice for every known <em>EO C++ Class</em>.
-///
-/// @see efl::eo::detail::tag
-///
-template <typename T, typename Args>
-void call_constructor(efl::eo::detail::tag<T> tag, Eo* eo, Eo_Class const* 
cls, Args args);
-
-/// @internal
-///
 /// @brief Sums up the number of <em>EO Operations</em> of each class
 /// passed as argument to the template.
 ///
@@ -73,132 +33,6 @@ struct operation_description_size<>
    static const int value = 0;
 };
 
-template <typename T>
-struct is_args_class : std::false_type
-{
-};
-
-template <typename T, typename Tuple>
-struct is_args_class<args_class<T, Tuple> >
-  : std::true_type
-{
-};
-
-template <typename Tuple>
-struct are_args_class;
-
-template <>
-struct are_args_class<std::tuple<> >
-  : std::true_type
-{
-};
-
-template <typename T0, typename... T>
-struct are_args_class<std::tuple<T0, T...> >
-  : std::integral_constant
-  <bool
-   , is_args_class<T0>::value
-   && are_args_class<std::tuple<T...> >::value
-  >
-{
-};
-
-template <typename T, typename Tuple>
-struct has_args_class : std::false_type
-{
-   typedef std::integral_constant<std::size_t, 0u> index;
-};
-
-template <typename T, typename Tuple, typename... Args>
-struct has_args_class<T, std::tuple<detail::args_class<T, Tuple>, Args...> >
-  : std::true_type
-{
-   typedef detail::args_class<T, Tuple> type;
-   typedef std::integral_constant<std::size_t, 0u> index;
-};
-
-template <typename T, typename T0, typename... Args>
-struct has_args_class<T, std::tuple<T0, Args...> >
-  : has_args_class<T, std::tuple<Args...> >
-{
-   typedef has_args_class<T, std::tuple<Args...> > base_type;
-   typedef std::integral_constant
-   <std::size_t, 1u + base_type::index::value> index;
-};
-
-/// @internal
-///
-/// @brief An auxiliary template-class used to select the correct
-/// implementation of @ref efl::eo::call_constructor for @p T with
-/// proper parameters and variadic size.
-///
-/// @param T An <em>EO C++ Class</em>.
-///
-template <typename T, std::size_t N>
-struct call_constructor_aux
-{
-   template <typename Args, typename P>
-   static void do_(Args const&, Eo* eo, Eo_Class const* cls
-                  , P, typename std::enable_if<!P::value>::type* = 0)
-   {
-      call_constructor(tag<T>(), eo, cls, args_class<T, std::tuple<> 
>(std::tuple<>()));
-   }
-
-   template <typename Args, typename P>
-   static void do_(Args const& args, Eo* eo, Eo_Class const* cls
-                  , P, typename std::enable_if<P::value>::type* = 0)
-   {
-      call_constructor(tag<T>(), eo, cls, std::get<P::index::value>(args));
-   }
-
-   /// @internal
-   ///
-   /// @brief Invoke @def efl::eo::detail::call_constructor
-   /// implementation for the parent and each available extension.
-   ///
-   /// @param args An heterogenous sequence of arguments.
-   /// @param eo The opaque <em>EO Object</em>.
-   /// @param cls The opaque <em>EO Class</em>.
-   ///
-   template <typename Args>
-   static int do_(Args const& args, Eo* eo, Eo_Class const* cls)
-   {
-      static_assert(std::tuple_size<Args>::value <= N, "");
-      static_assert(are_args_class<Args>::value, "");
-      do_(args, eo, cls, has_args_class<T, Args>());
-      return 0;
-   }
-};
-
-template <typename T>
-struct call_constructor_aux<T, 1u>
-{
-   template <typename Args>
-   static void do_(Args const& args, Eo* eo, Eo_Class const* cls
-                  , std::true_type)
-   {
-      static_assert(std::tuple_size<Args>::value == 1, "");
-      static_assert(std::is_same
-                    <typename std::tuple_element<0u, Args>::type::class_type
-                    , T>::value, "");
-      call_constructor(tag<T>(), eo, cls, std::get<0u>(args));
-   }
-
-   template <typename Args>
-   static void do_(Args const& args, Eo* eo, Eo_Class const* cls
-                  , std::false_type)
-   {
-      call_constructor(tag<T>(), eo, cls, args_class<T, Args>(args));
-   }
-
-   template <typename Args>
-   static int do_(Args const& args, Eo* eo, Eo_Class const* cls)
-   {
-      do_(args, eo, cls, has_args_class<T, Args>());
-      return 0;
-   }
-};
-
 template <typename... Args>
 void call_varargs(Args...)
 {
@@ -209,18 +43,14 @@ void call_varargs(Args...)
 /// @brief The procedure that actually is invoked when the constructor
 /// of @c D is sought from the <em>EO Subsystem</em>.
 ///
-/// @param obj The opaque <em>EO Object</em>.
 /// @param self A pointer to @p obj's private data.
 /// @param this_ A void pointer to the opaque <em>EO Class</em> ---
 /// passed as <em>user data</em>.
-/// @param args The arguments for the underlying constructor.
 ///
-template <typename D, typename Args, typename... E>
-void inherit_constructor_impl(Eo* obj, Inherit_Private_Data* self, void* 
this_, Args args)
+inline
+void inherit_constructor_impl(Eo*, Inherit_Private_Data* self, void* this_)
 {
    self->this_ = this_;
-   Eo_Class const* cls = static_cast<inherit<D, E...>*>(this_)->_eo_class();
-   detail::call_varargs(detail::call_constructor_aux<E, 
sizeof...(E)>::do_(args, obj, cls) ...);
 }
 
 /// @internal
@@ -231,16 +61,16 @@ void inherit_constructor_impl(Eo* obj, 
Inherit_Private_Data* self, void* this_,
 /// @param this_ The <em>user data</em> to be passed to the resolved function.
 /// @param args An heterogeneous sequence of arguments.
 ///
-template <typename Args, typename... E>
-EAPI void inherit_constructor(void* this_, Args args)
+EAPI inline
+void inherit_constructor(void* this_)
 {
-   typedef void (*func_t)(Eo *, void *, void*, Args);
+   typedef void (*func_t)(Eo *, void *, void*);
    Eo_Op_Call_Data ___call;
    static Eo_Op op = EO_NOOP;
    if ( op == EO_NOOP )
      op = _eo_api_op_id_get
        (reinterpret_cast<void*>
-        (static_cast<void(*)(void*, Args)>(&detail::inherit_constructor<Args, 
E...>)),
+        (&detail::inherit_constructor),
         ::eina_main_loop_is(), __FILE__, __LINE__);
    if (!_eo_call_resolve("detail::inherit_constructor", op, &___call,
                          ::eina_main_loop_is(), __FILE__, __LINE__))
@@ -251,7 +81,7 @@ EAPI void inherit_constructor(void* this_, Args args)
      }
    func_t func = (func_t) ___call.func;
    EO_HOOK_CALL_PREPARE(eo_hook_call_pre, "");
-   func(___call.obj, ___call.data, this_, args);
+   func(___call.obj, ___call.data, this_);
    EO_HOOK_CALL_PREPARE(eo_hook_call_post, "");
 }
 
@@ -289,7 +119,7 @@ operation_description_index<0u, E...>
 ///
 /// @see efl::eo::inherit::inherit
 ///
-template <typename D, typename TupleArgs, typename... E, std::size_t ... S>
+template <typename D, typename... E, std::size_t ... S>
 Eo_Class const* create_class(eina::index_sequence<S...>)
 {
    static const Eo_Class* my_class = NULL;
@@ -299,14 +129,12 @@ Eo_Class const* create_class(eina::index_sequence<S...>)
    op_descs[detail::operation_description_size<E...>::value].func =
      reinterpret_cast<void*>
      (
-      static_cast<void(*)(Eo*, Inherit_Private_Data*, void*, TupleArgs)>
-      (&detail::inherit_constructor_impl<D, TupleArgs, E...>)
+      &detail::inherit_constructor_impl
      );
    op_descs[detail::operation_description_size<E...>::value].api_func =
      reinterpret_cast<void*>
      (
-      static_cast<void(*)(void*, TupleArgs)>
-      (&detail::inherit_constructor<TupleArgs, E...>)
+      &detail::inherit_constructor
      );
    op_descs[detail::operation_description_size<E...>::value].op = EO_NOOP;
    op_descs[detail::operation_description_size<E...>::value].op_type = 
EO_OP_TYPE_REGULAR;
diff --git a/src/examples/eolian_cxx/eolian_cxx_callbacks_01.cc 
b/src/examples/eolian_cxx/eolian_cxx_callbacks_01.cc
index 8c41c0e..c9334bc 100644
--- a/src/examples/eolian_cxx/eolian_cxx_callbacks_01.cc
+++ b/src/examples/eolian_cxx/eolian_cxx_callbacks_01.cc
@@ -28,7 +28,7 @@ example_callbacks()
 {
    int count = 0;
    efl::ecore::poller poller(
-     poller.ecore_poller_constructor(ECORE_POLLER_CORE, 1,
+     poller.constructor(ECORE_POLLER_CORE, 1,
        [&count, &poller]
        {
           if (++count == 5)
diff --git a/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc 
b/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc
index 0e6fce9..bdfa3ad 100644
--- a/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc
+++ b/src/examples/eolian_cxx/eolian_cxx_inherit_01.cc
@@ -17,7 +17,7 @@ struct ColourableCircle
   : efl::eo::inherit<ColourableCircle, ::colourable>
 {
    ColourableCircle(int rgb)
-     : inherit_base(efl::eo::args<::colourable>(rgb))
+     : inherit_base(::colourable::rgb_24bits_constructor(rgb))
    {}
 
    int colour_get()
@@ -46,7 +46,7 @@ struct ColourableBar
   : efl::eo::inherit<ColourableBar, ::colourablesquare>
 {
    ColourableBar()
-     : inherit_base(efl::eo::args<::colourablesquare>(0))
+     : inherit_base(::colourable::rgb_24bits_constructor(0))
    {}
 
    int colour_get()
diff --git a/src/examples/eolian_cxx/eolian_cxx_simple_01.cc 
b/src/examples/eolian_cxx/eolian_cxx_simple_01.cc
index 47b98cb..04acebb 100644
--- a/src/examples/eolian_cxx/eolian_cxx_simple_01.cc
+++ b/src/examples/eolian_cxx/eolian_cxx_simple_01.cc
@@ -19,13 +19,13 @@ main()
 
    int r, g, b;
    ::colourable obj1(
-     obj1.colourable_rgb_24bits_constructor(0x123456)
+     obj1.rgb_24bits_constructor(0x123456)
    );
    obj1.colour_set(0xc0ffee);
    obj1.composite_colour_get(&r, &g, &b);
 
    ::colourablesquare obj2(
-     obj2.colourablesquare_size_constructor(10)
+     obj2.size_constructor(10)
    );
    obj2.composite_colour_set(r, g, b);
    obj2.size_set(11);
diff --git a/src/lib/eolian_cxx/eo_types.hh b/src/lib/eolian_cxx/eo_types.hh
index b50e692..987be69 100644
--- a/src/lib/eolian_cxx/eo_types.hh
+++ b/src/lib/eolian_cxx/eo_types.hh
@@ -90,21 +90,21 @@ struct eolian_type_instance
 {
   eolian_type_instance()
     : is_out(false)
-    , is_nonull(false)
+    , is_optional(false)
     , parts()
   {}
 
   eolian_type_instance(std::initializer_list<eolian_type> il,
                        bool is_out_ = false,
-                       bool is_nonull_ = false)
+                       bool is_optional_ = false)
     : is_out(is_out_)
-    , is_nonull(is_nonull_)
+    , is_optional(is_optional_)
     , parts(il)
   {}
 
   explicit eolian_type_instance(std::size_t size)
     : is_out(false)
-    , is_nonull(false)
+    , is_optional(false)
     , parts(size)
   {}
 
@@ -115,7 +115,7 @@ struct eolian_type_instance
   eolian_type const& front() const { return parts.front(); }
 
   bool is_out;
-  bool is_nonull;
+  bool is_optional;
   eolian_type_container parts;
 };
 
@@ -174,9 +174,9 @@ type_binding_requires_optional(eolian_type_instance const& 
type)
 }
 
 inline bool
-type_is_nonull(eolian_type_instance const& type)
+type_is_optional(eolian_type_instance const& type)
 {
-   return type.is_nonull;
+   return type.is_optional;
 }
 
 inline eolian_type
@@ -254,6 +254,8 @@ struct eo_class
    ancestors_container_type parents;
    ancestors_container_type ancestors;
    constructors_container_type constructors;
+   constructors_container_type optional_constructors;
+   constructors_container_type all_constructors;
    functions_container_type functions;
    events_container_type own_events;
    events_container_type concrete_events;
@@ -270,6 +272,7 @@ struct eo_parameter
 struct eo_constructor
 {
    std::string name;
+   std::string impl;
    parameters_container_type params;
    std::string comment;
 };
diff --git a/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh 
b/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh
index 2688552..5389a5d 100644
--- a/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh
+++ b/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh
@@ -109,8 +109,8 @@ inline std::ostream&
 operator<<(std::ostream& out, functors_constructor_methods const& x)
 {
    constructors_container_type::const_iterator it,
-     first = x._cls.constructors.cbegin(),
-     last = x._cls.constructors.cend();
+     first = x._cls.all_constructors.cbegin(),
+     last = x._cls.all_constructors.cend();
    for (it = first; it != last; ++it)
      {
         eo_constructor const& c = *it;
@@ -136,7 +136,7 @@ operator<<(std::ostream& out, functors_constructor_methods 
const& x)
             << endl;
 
         // Struct constructor
-        out << tab(2) << constructor_functor_type_name(c) << "("
+        out << tab(2) << "explicit " << constructor_functor_type_name(c) << "("
             << parameters_declaration(c.params) << ")"
             << parameters_cxx_generic(c.params,
                   [](param_data d)
@@ -160,7 +160,24 @@ operator<<(std::ostream& out, functors_constructor_methods 
const& x)
         // Struct operator()
         out << tab(2) << "void operator()()" << endl
             << tab(2) << "{" << endl
-            << tab(3) << "::" << c.name << "(" << 
parameters_forward_to_c(c.params) << ");" << endl
+            << tab(3) << "::" << c.impl << "(" << 
parameters_forward_to_c(c.params) << ");" << endl
+            << tab(2) << "}" << endl;
+
+        // Register event to free allocated callbacks when the Eo* is deleted
+        out << tab(2) << "void register_ev_del_free_callback(Eo* _eoptr)" << 
endl
+            << tab(2) << "{" << endl
+            << tab(3) << "(void) _eoptr;" << endl
+            << parameters_cxx_generic(c.params,
+                 [](param_data d)
+                 {
+                    if (d.is_cb)
+                      d.out << tab(3)
+                            << "eo_do(_eoptr," << endl
+                            << tab(4) << "eo_event_callback_add(EO_EV_DEL, "
+                            << "&::efl::eolian::free_callback_calback<"
+                            << parameter_no_ref_type(d.type, d.name)
+                            << ">, " << callback_tmp(d.name) << "));" << endl;
+                 })
             << tab(2) << "}" << endl;
 
         // Struct member variables
@@ -198,8 +215,8 @@ inline std::ostream&
 operator<<(std::ostream& out, constructor_method_function_declarations const& 
x)
 {
    constructors_container_type::const_iterator it,
-     first = x._cls.constructors.cbegin(),
-     last = x._cls.constructors.cend();
+     first = x._cls.all_constructors.cbegin(),
+     last = x._cls.all_constructors.cend();
    for (it = first; it != last; ++it)
      {
         eo_constructor const& c = *it;
@@ -216,8 +233,9 @@ operator<<(std::ostream& out, 
constructor_method_function_declarations const& x)
 
         out << comment(c.comment, 1)
             << template_parameters_declaration(c.params, 1)
-            << tab(1) << constructor_functor_type_decl(c) << " " << c.name << 
"("
-            << parameters_declaration(c.params) << ") const;" << endl << endl;
+            << tab(1) << "static " << constructor_functor_type_decl(c)
+            << " " << c.name << "("
+            << parameters_declaration(c.params) << ");" << endl << endl;
      }
 
    return out;
@@ -233,8 +251,8 @@ inline std::ostream&
 operator<<(std::ostream& out, constructor_method_function_definitions const& x)
 {
    constructors_container_type::const_iterator it,
-     first = x._cls.constructors.cbegin(),
-     last = x._cls.constructors.cend();
+     first = x._cls.all_constructors.cbegin(),
+     last = x._cls.all_constructors.cend();
    for (it = first; it != last; ++it)
      {
         eo_constructor const& c = *it;
@@ -249,7 +267,7 @@ operator<<(std::ostream& out, 
constructor_method_function_definitions const& x)
             << "inline " << full_name(x._cls)
             << "::" << constructor_functor_type_decl(c) << " "
             << full_name(x._cls, false) << "::" << c.name << "("
-            << parameters_declaration(c.params) << ") const" << endl
+            << parameters_declaration(c.params) << ")" << endl
             << "{" << endl
             << tab(1) << "return " << constructor_functor_type_decl(c) << "("
             << parameters_forward(c.params) << ");" << endl
@@ -280,24 +298,33 @@ operator<<(std::ostream& out, 
comment_constructor_with_constructor_methods const
    if (x._cls.constructors.size())
      {
         bool singular = (x._cls.constructors.size() == 1);
-        out << tab(2) << "Since this class have " << (singular ? "a " : "") << 
"constructor method" << (singular ? "" : "s")
+        out << tab(2) << "Since this class have " << (singular ? "a " : "")
+            << "necessary constructor method" << (singular ? "" : "s")
             <<  ", you must call " << (singular ? "it" : "each one of them") 
<< endl
             << tab(2) << "in the right place within this constructor 
parameters." << endl
             << endl;
      }
 
+   if (!x._cls.optional_constructors.empty())
+     {
+        out << tab(2) << "Optional constructors may be called in any 
combination as the" << endl
+            << tab(2) << "last parameters." << endl
+            << endl;
+     }
+
    out << tab(2) << "Example:" << endl
        << tab(2) << "@code" << endl
-       << tab(2) << full_name(x._cls, false) << " my_" << x._cls.name << "(" 
<< endl;
+       << tab(2) << full_name(x._cls, false) << " my_" << x._cls.name << 
"(efl::eo::parent = parent_object";
 
-   for (eo_constructor const& c : x._cls.constructors)
-      out << tab(3) << "my_" << x._cls.name << "." << c.name << "(" << 
parameters_names(c.params) << ")," << endl;
+   for (eo_constructor const& c : x._cls.all_constructors)
+      out << "," << endl
+          << tab(3) << "my_" << x._cls.name << "." << c.name << "(" << 
parameters_names(c.params) << ")";
 
-   out << tab(3) << "efl::eo::parent = parent_object);" << endl
+   out << ");" << endl
        << tab(2) << "@endcode" << endl
        << endl;
 
-   for (eo_constructor const& c : x._cls.constructors)
+   for (eo_constructor const& c : x._cls.all_constructors)
      out << tab(2) << "@see " << x._cls.name << "::" << c.name << endl;
    out << tab(2) << "@see " << x._cls.name << "(Eo* eo)" << endl;
 
@@ -307,8 +334,10 @@ operator<<(std::ostream& out, 
comment_constructor_with_constructor_methods const
 struct constructor_with_constructor_methods
 {
    eo_class const& _cls;
-   constructor_with_constructor_methods(eo_class const& cls)
+   bool _with_parent;
+   constructor_with_constructor_methods(eo_class const& cls, bool with_parent)
      : _cls(cls)
+     , _with_parent(with_parent)
    {}
 };
 
@@ -325,9 +354,7 @@ operator<<(std::ostream& out, 
constructor_with_constructor_methods const& x)
         cb_count += parameters_count_callbacks((*it).params);
      }
 
-   out << comment_constructor_with_constructor_methods(x._cls);
-
-   if (cb_count != 0)
+   if (cb_count != 0 || !x._cls.optional_constructors.empty())
      {
         out << tab(1) << "template <";
         for (unsigned i = 0; i != cb_count; ++i)
@@ -336,14 +363,26 @@ operator<<(std::ostream& out, 
constructor_with_constructor_methods const& x)
                out << ", ";
              out << "typename F" << i;
           }
+        if (!x._cls.optional_constructors.empty())
+          {
+             if (cb_count != 0)
+               out << ", ";
+             out << "typename... FOpts";
+          }
         out << ">" << endl;
      }
 
-   out << tab(1) << x._cls.name << "(";
+   out << tab(1) << "explicit " << x._cls.name << "(";
+
+   if (x._with_parent)
+     out << "::efl::eo::parent_type _p";
+
    {
       unsigned cb_idx = 0;
       for (it = first; it != last; ++it)
         {
+           if (x._with_parent || it != first)
+             out << ", ";
            out << constructor_functor_type_name(*it);
 
            if (cb_count != 0 && parameters_count_callbacks((*it).params) != 0)
@@ -357,22 +396,54 @@ operator<<(std::ostream& out, 
constructor_with_constructor_methods const& x)
                          })
                     << ">";
              }
-           out << " _c" << (it-first) << ", ";
+           out << " _c" << (it-first);
         }
         assert(cb_idx == cb_count);
    }
-   out << "::efl::eo::parent_type _p = (::efl::eo::parent = nullptr))" << endl
-       << tab(2) << ": " << x._cls.name << "(_ctors_call(";
+
+   if (!x._cls.optional_constructors.empty())
+     {
+        if (x._with_parent || first != last)
+          out << ", ";
+        out << "FOpts&&... _opts";
+     }
+
+   out << ")" << endl
+       << tab(2) << ": " << x._cls.name << "(_ctors_call("
+       << (x._with_parent ? "_p" : "::efl::eo::parent = nullptr");
    for (it = first; it != last; ++it)
      {
-        out << "_c" << (it-first) << ", ";
+        out << ", _c" << (it-first);
      }
-   out << "_p))" << endl
-       << tab(1) << "{}" << endl << endl;
+   if (!x._cls.optional_constructors.empty())
+     {
+        out << ", std::forward<FOpts>(_opts)...";
+     }
+   out << "))" << endl
+       << tab(1) << "{}" << endl;
 
    return out;
 }
 
+struct constructors_with_constructor_methods
+{
+   eo_class const& _cls;
+   constructors_with_constructor_methods(eo_class const& cls)
+     : _cls(cls)
+   {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, constructors_with_constructor_methods const& x)
+{
+   out << tab(1) << "//@{" << endl
+       << comment_constructor_with_constructor_methods(x._cls)
+       << constructor_with_constructor_methods(x._cls, true) << endl
+       << constructor_with_constructor_methods(x._cls, false)
+       << tab(1) << "//@}" << endl << endl;
+   return out;
+}
+
 struct constructor_eo
 {
    eo_class const& _cls;
@@ -460,24 +531,31 @@ operator<<(std::ostream& out, 
function_call_constructor_methods const& x)
      last = x._cls.constructors.cend();
    for (it = first; it != last; ++it)
      {
-        unsigned param_cb_count = parameters_count_callbacks((*it).params);
-        for (unsigned i = 0; i != param_cb_count; ++i)
+        cb_count += parameters_count_callbacks((*it).params);
+     }
+   if (cb_count != 0 || !x._cls.optional_constructors.empty())
+     {
+        out << tab(1) << "template <";
+        for (unsigned i = 0; i != cb_count; ++i)
           {
-             if(cb_count == 0)
-               out << tab(1) << "template <";
-             else
+             if (i != 0)
+               out << ", ";
+             out << "typename F" << i;
+          }
+        if (!x._cls.optional_constructors.empty())
+          {
+             if (cb_count != 0)
                out << ", ";
-             out << "typename F" << cb_count++;
+             out << "typename... FOpts";
           }
+        out << ">" << endl;
      }
-   if (cb_count != 0)
-     out << ">" << endl;
 
    unsigned cb_idx = 0;
-   out << tab(1) << "static Eo* _ctors_call(";
+   out << tab(1) << "static Eo* _ctors_call(::efl::eo::parent_type _p";
    for (it = first; it != last; ++it)
      {
-        out << constructor_functor_type_name(*it);
+        out << ", " << constructor_functor_type_name(*it);
 
         if (cb_count != 0 && parameters_count_callbacks((*it).params) != 0)
           {
@@ -490,39 +568,29 @@ operator<<(std::ostream& out, 
function_call_constructor_methods const& x)
                       })
                  << ">";
           }
-        out << " _c" << (it-first) << ", ";
+        out << " _c" << (it-first);
      }
    assert(cb_idx == cb_count);
 
-   out << "::efl::eo::parent_type _p)" << endl
+   if (!x._cls.optional_constructors.empty())
+     out << ", FOpts&&... _opts";
+
+   out << ")" << endl
        << tab(1) << "{" << endl
        << tab(2) << "Eo* _ret_eo = eo_add_ref(" << x._cls.eo_name << ", 
_p._eo_raw";
    for (it = first; it != last; ++it)
      {
         out << ", _c" << (it-first) << "()";
      }
+   if (!x._cls.optional_constructors.empty())
+     out << ", ::efl::eolian::call_ctors(_opts...)";
    out << ");" << endl << endl;
 
-   cb_idx = 0;
    for (it = first; it != last; ++it)
-     {
-        if (parameters_count_callbacks((*it).params) == 0)
-          continue;
+     out << tab(2) << "_c" << (it-first) << 
".register_ev_del_free_callback(_ret_eo);" << endl;
 
-        out << parameters_cxx_generic((*it).params,
-                 [&it, &first, &cb_idx](param_data d)
-                 {
-                    if (d.is_cb)
-                      d.out << tab(2)
-                            << "eo_do(_ret_eo," << endl
-                            << tab(3) << "eo_event_callback_add(EO_EV_DEL, "
-                            << "&::efl::eolian::free_callback_calback<F" << 
cb_idx++
-                            << ">, _c" << (it-first) << "." << 
callback_tmp(d.name)
-                            << "));" << endl;
-                 })
-            << endl;
-     }
-   assert(cb_idx == cb_count);
+   if (!x._cls.optional_constructors.empty())
+     out << tab(2) << "::efl::eolian::register_ev_del_free_callback(_ret_eo, 
_opts...);" << endl;
 
    out << tab(2) << "return _ret_eo;" << endl
        << tab(1) << "}" << endl << endl;
diff --git a/src/lib/eolian_cxx/grammar/eo_class_generator.hh 
b/src/lib/eolian_cxx/grammar/eo_class_generator.hh
index c1d227c..e1545fc 100644
--- a/src/lib/eolian_cxx/grammar/eo_class_generator.hh
+++ b/src/lib/eolian_cxx/grammar/eo_class_generator.hh
@@ -230,7 +230,7 @@ eo_class_declarations_generator(std::ostream& out, eo_class 
const& cls)
        << class_inheritance(cls)
        << '{' << endl
        << functors_constructor_methods(cls)
-       << constructor_with_constructor_methods(cls)
+       << constructors_with_constructor_methods(cls)
        << constructor_eo(cls)
        << copy_constructor(cls)
        << destructor(cls)
diff --git a/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh 
b/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh
index 11b8f2a..e134729 100644
--- a/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh
+++ b/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh
@@ -315,73 +315,6 @@ operator<<(std::ostream& out, inheritance_base_operations 
const& x)
    return out;
 }
 
-struct inheritance_call_constructor_arguments
-{
-   parameters_container_type const& _params;
-   inheritance_call_constructor_arguments(parameters_container_type const& 
params)
-     : _params(params)
-   {}
-};
-
-inline std::ostream&
-operator<<(std::ostream& out, inheritance_call_constructor_arguments const& x)
-{
-   parameters_container_type::size_type i, n = x._params.size();
-   for (i=0; i<n; i++)
-     {
-        if(i!=0) out << ", ";
-        out << "::efl::eolian::to_c(args.get<" << i << ">())";
-     }
-   return out;
-}
-
-struct inheritance_call_constructors
-{
-   eo_class const& _cls;
-   inheritance_call_constructors(eo_class const& cls) : _cls(cls) {}
-};
-
-inline std::ostream&
-operator<<(std::ostream& out, inheritance_call_constructors const& x)
-{
-   constructors_container_type::const_iterator it,
-     first = x._cls.constructors.begin(),
-     last = x._cls.constructors.end();
-   for (it = first; it != last; ++it)
-     {
-        eo_constructor const& ctor = *it;
-        out << "inline void" << endl
-            << "call_constructor(::efl::eo::detail::tag< "
-            << full_name(x._cls) << " >" << endl
-            << tab(5) << ", Eo* eo, Eo_Class const* cls EINA_UNUSED," << endl
-            << tab(5) << "::efl::eo::detail::args_class<"
-            << full_name(x._cls)
-            << ", ::std::tuple<"
-            << parameters_types(ctor.params)
-            << "> > const& args)" << endl
-            << "{" << endl
-            << tab(1) << "(void)args;" << endl
-            << tab(1)
-            << "eo_do_super(eo, cls, ::" << ctor.name
-            << "(" << inheritance_call_constructor_arguments(ctor.params)
-            << "));" << endl
-            << "}" << endl << endl;
-     }
-
-   out << "inline void" << endl
-       << "call_constructor(::efl::eo::detail::tag< "
-       << full_name(x._cls) << " >" << endl
-       << tab(5) << ", Eo* eo, Eo_Class const* cls EINA_UNUSED," << endl
-       << tab(5) << "::efl::eo::detail::args_class<"
-       << full_name(x._cls)
-       << ", ::std::tuple<::efl::eo::parent_type> > const& args)" << endl
-       << "{" << endl
-       << tab(1) << "eo_do(eo, ::eo_parent_set(args.get<0>()._eo_raw));" << 
endl
-       << "}" << endl << endl;
-
-   return out;
-}
-
 struct inheritance_eo_class_getter
 {
    eo_class const& _cls;
@@ -410,7 +343,6 @@ eo_inheritance_detail_generator(std::ostream& out, eo_class 
const& cls)
          << inheritance_base_operations(cls) << endl
          << inheritance_base_operations_size_scopes(cls)
          << inheritance_operations_description(cls)
-         << inheritance_call_constructors(cls)
          << inheritance_eo_class_getter(cls)
          <<  "} } }" << endl;
 }
diff --git a/src/lib/eolian_cxx/grammar/type_generator.hh 
b/src/lib/eolian_cxx/grammar/type_generator.hh
index 193d2ea..de01890 100644
--- a/src/lib/eolian_cxx/grammar/type_generator.hh
+++ b/src/lib/eolian_cxx/grammar/type_generator.hh
@@ -110,7 +110,7 @@ operator<<(std::ostream& out, 
efl::eolian::grammar::reinterpret_type const& x)
      {
         if (x._type.is_out)
           res += "*";
-        else if (!x._type.is_nonull && 
x._type.front().binding_requires_optional)
+        else if (x._type.is_optional && 
x._type.front().binding_requires_optional)
           res = "::efl::eina::optional< " + res + " >";
      }
 
diff --git a/src/tests/eolian_cxx/eolian_cxx_suite.cc 
b/src/tests/eolian_cxx/eolian_cxx_suite.cc
index cace098..7f80439 100644
--- a/src/tests/eolian_cxx/eolian_cxx_suite.cc
+++ b/src/tests/eolian_cxx/eolian_cxx_suite.cc
@@ -9,6 +9,7 @@ void eolian_cxx_test_generate(TCase* tc);
 void eolian_cxx_test_callback(TCase* tc);
 void eolian_cxx_test_address_of(TCase* tc);
 void eolian_cxx_test_inheritance(TCase* tc);
+void eolian_cxx_test_binding(TCase* tc);
 
 typedef struct _Eolian_Cxx_Test_Case Eolian_Cxx_Test_Case;
 struct _Eolian_Cxx_Test_Case
@@ -24,6 +25,7 @@ static const Eolian_Cxx_Test_Case etc[] = {
   { "Eolian-Cxx Callback", eolian_cxx_test_callback },
   { "Eolian-Cxx Address_of", eolian_cxx_test_address_of },
   { "Eolian-Cxx Inheritance", eolian_cxx_test_inheritance },
+  { "Eolian-Cxx Binding", eolian_cxx_test_binding },
   { NULL, NULL }
 };
 
diff --git a/src/tests/eolian_cxx/eolian_cxx_test_binding.cc 
b/src/tests/eolian_cxx/eolian_cxx_test_binding.cc
index ab3703c..a6d8ebb 100644
--- a/src/tests/eolian_cxx/eolian_cxx_test_binding.cc
+++ b/src/tests/eolian_cxx/eolian_cxx_test_binding.cc
@@ -1,2 +1,60 @@
 
 // test EFL++ generated bindings
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <generic.eo.hh>
+
+#include <check.h>
+
+START_TEST(eolian_cxx_test_binding_constructor_only_required)
+{
+  efl::eo::eo_init i;
+
+  bool called1 = false;
+
+  generic g(
+    g.required_ctor_a(1),
+    g.required_ctor_b(std::bind([&called1] { called1 = true; }))
+  );
+
+  g.call_req_ctor_b_callback();
+  g.call_opt_ctor_b_callback();
+
+  fail_if(!called1);
+  fail_if(1 != g.req_ctor_a_value_get());
+}
+END_TEST
+
+START_TEST(eolian_cxx_test_binding_constructor_all_optionals)
+{
+  efl::eo::eo_init i;
+
+  bool called1 = false;
+  bool called2 = false;
+
+  generic g(
+    g.required_ctor_a(2),
+    g.required_ctor_b(std::bind([&called1] { called1 = true; })),
+    g.optional_ctor_a(3),
+    g.optional_ctor_b(std::bind([&called2] { called2 = true; }))
+  );
+
+  g.call_req_ctor_b_callback();
+  g.call_opt_ctor_b_callback();
+
+  fail_if(!called1);
+  fail_if(!called2);
+  fail_if(2 != g.req_ctor_a_value_get());
+  fail_if(3 != g.opt_ctor_a_value_get());
+}
+END_TEST
+
+void
+eolian_cxx_test_binding(TCase* tc)
+{
+   tcase_add_test(tc, eolian_cxx_test_binding_constructor_only_required);
+   tcase_add_test(tc, eolian_cxx_test_binding_constructor_all_optionals);
+}
diff --git a/src/tests/eolian_cxx/generic.c b/src/tests/eolian_cxx/generic.c
new file mode 100644
index 0000000..1de4e5b
--- /dev/null
+++ b/src/tests/eolian_cxx/generic.c
@@ -0,0 +1,77 @@
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Eo.h>
+#include <Ecore.h>
+
+#include "generic.eo.h"
+
+struct _Generic_Data
+{
+   int        req_ctor_a_val;
+   Ecore_Cb   req_ctor_b_cb;
+   void      *req_ctor_b_data;
+   int        opt_ctor_a_val;
+   Ecore_Cb   opt_ctor_b_cb;
+   void      *opt_ctor_b_data;
+};
+typedef struct _Generic_Data Generic_Data;
+
+#define MY_CLASS GENERIC_CLASS
+
+static void _generic_eo_base_constructor(Eo *obj, Generic_Data *pd)
+{
+   pd->req_ctor_a_val = 0;
+   pd->req_ctor_b_cb = NULL;
+   pd->req_ctor_b_data = NULL;
+   pd->opt_ctor_a_val = 0;
+   pd->opt_ctor_b_cb = NULL;
+   pd->opt_ctor_b_data = NULL;
+   eo_do_super(obj, MY_CLASS, eo_constructor());
+}
+
+static void _generic_required_ctor_a(Eo *obj EINA_UNUSED, Generic_Data *pd, 
int value)
+{
+   pd->req_ctor_a_val = value;
+}
+
+static void _generic_required_ctor_b(Eo *obj EINA_UNUSED, Generic_Data *pd 
EINA_UNUSED, Ecore_Cb cb, void *data)
+{
+   cb(data);
+}
+
+static void _generic_optional_ctor_a(Eo *obj EINA_UNUSED, Generic_Data *pd, 
int value)
+{
+   pd->opt_ctor_a_val = value;
+}
+
+static void _generic_optional_ctor_b(Eo *obj EINA_UNUSED, Generic_Data *pd 
EINA_UNUSED, Ecore_Cb cb, void *data)
+{
+   cb(data);
+}
+
+static int _generic_req_ctor_a_value_get(Eo *obj EINA_UNUSED, Generic_Data *pd)
+{
+   return pd->req_ctor_a_val;
+}
+
+static int _generic_opt_ctor_a_value_get(Eo *obj EINA_UNUSED, Generic_Data *pd)
+{
+   return pd->opt_ctor_a_val;
+}
+
+static void _generic_call_req_ctor_b_callback(Eo *obj EINA_UNUSED, 
Generic_Data *pd)
+{
+   if (pd->req_ctor_b_cb)
+     pd->req_ctor_b_cb(pd->req_ctor_b_data);
+}
+
+static void _generic_call_opt_ctor_b_callback(Eo *obj EINA_UNUSED, 
Generic_Data *pd)
+{
+   if (pd->opt_ctor_b_cb)
+     pd->opt_ctor_b_cb(pd->opt_ctor_b_data);
+}
+
+#include "generic.eo.c"
diff --git a/src/tests/eolian_cxx/generic.eo b/src/tests/eolian_cxx/generic.eo
new file mode 100644
index 0000000..af21c02
--- /dev/null
+++ b/src/tests/eolian_cxx/generic.eo
@@ -0,0 +1,58 @@
+class Generic (Eo.Base)
+{
+   legacy_prefix: null;
+   data: Generic_Data;
+   properties {
+      req_ctor_a_value {
+         get {
+         }
+         values {
+            int value;
+         }
+      }
+      opt_ctor_a_value {
+         get {
+         }
+         values {
+            int value;
+         }
+      }
+   }
+   methods {
+      required_ctor_a {
+         params {
+            @in int value;
+         }
+      }
+      required_ctor_b {
+         params {
+            @in Ecore_Cb cb;
+            @in void* data;
+         }
+      }
+      optional_ctor_a {
+         params {
+            @in int value;
+         }
+      }
+      optional_ctor_b {
+         params {
+            @in Ecore_Cb cb;
+            @in void* data;
+         }
+      }
+      call_req_ctor_b_callback {
+      }
+      call_opt_ctor_b_callback {
+      }
+   }
+   constructors {
+      .required_ctor_a;
+      .required_ctor_b;
+      .optional_ctor_a @optional;
+      .optional_ctor_b @optional;
+   }
+   implements {
+      Eo.Base.constructor;
+   }
+}

-- 


Reply via email to