forked from enlightenment/efl
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).
This commit is contained in:
parent
72604d4957
commit
ce36f0be93
|
@ -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 \
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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(¶meter))
|
||||
{
|
||||
type.is_nonull = true;
|
||||
}
|
||||
type.is_optional = ::eolian_parameter_is_optional(¶meter) ||
|
||||
::eolian_parameter_is_nullable(¶meter);
|
||||
return type;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -10,46 +10,6 @@ namespace efl { namespace eo { namespace detail {
|
|||
/// @addtogroup Efl_Cxx_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
|
||||
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
if(cb_count == 0)
|
||||
out << tab(1) << "template <";
|
||||
else
|
||||
out << ", ";
|
||||
out << "typename F" << cb_count++;
|
||||
}
|
||||
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 (i != 0)
|
||||
out << ", ";
|
||||
out << "typename F" << i;
|
||||
}
|
||||
if (!x._cls.optional_constructors.empty())
|
||||
{
|
||||
if (cb_count != 0)
|
||||
out << ", ";
|
||||
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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 + " >";
|
||||
}
|
||||
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue