cxx: General C++ Eo wrapper generation improvement

Using a new architecture in the generated files that simplify multiple
inheritance and allows the use of interface types as parameters.

No longer using a hand-crafted C++ header for eo_base.eo.
This file was added to the generation process.

Updated all files that are dependent in the hand-crafted eo_base
C++ header.

Now there is a class that contains the essentials functions of the former
eo::base wrapper and that is used to create (through inheritance) the
"concrete" classes for all Eo generated wrappers.

No longer binding any function or property that are protected, private or
legacy for now.

eolian_type_instance is now a struct with general information for the
whole type.

Added the new header file namespace_generator.hh to hold namespace
generation grammars.

Separated declaration and definition of Eo wrappers methods.

Referring for most objects by its full name (starting at the global
namespace ::) in the generated files.

Created additional helper grammars to avoid code replication.

Removed a TODO comment referring to a doubt about inheritance of
constructor methods.
Added a TODO comment regarding memory allocation for callbacks in static
member functions.
devs/tasn/tb2
Vitor Sousa 8 years ago
parent ebebcf6438
commit ed75aa32d6
  1. 2
      src/Makefile_Eina_Cxx.am
  2. 13
      src/Makefile_Eo_Cxx.am
  3. 1
      src/Makefile_Eolian_Cxx.am
  4. 69
      src/bin/eolian_cxx/convert.cc
  5. 9
      src/bin/eolian_cxx/eolian_cxx.cc
  6. 8
      src/bin/eolian_cxx/eolian_wrappers.hh
  7. 6
      src/bin/eolian_cxx/type_lookup.hh
  8. 34
      src/bin/eolian_cxx/type_lookup_table.cc
  9. 12
      src/bindings/eina_cxx/eina_accessor.hh
  10. 4
      src/bindings/eina_cxx/eina_array.hh
  11. 33
      src/bindings/eina_cxx/eina_eo_base_fwd.hh
  12. 33
      src/bindings/eina_cxx/eina_eo_concrete_fwd.hh
  13. 4
      src/bindings/eina_cxx/eina_list.hh
  14. 2
      src/bindings/eina_cxx/eina_ptrlist.hh
  15. 2
      src/bindings/eo_cxx/Eo.hh
  16. 117
      src/bindings/eo_cxx/eo_concrete.hh
  17. 12
      src/bindings/eo_cxx/eo_cxx_interop.hh
  18. 2
      src/bindings/eo_cxx/eo_inherit.hh
  19. 63
      src/lib/eolian_cxx/eo_types.hh
  20. 2
      src/lib/eolian_cxx/eo_validate.hh
  21. 113
      src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh
  22. 13
      src/lib/eolian_cxx/grammar/eo_class_events_generator.hh
  23. 103
      src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh
  24. 105
      src/lib/eolian_cxx/grammar/eo_class_generator.hh
  25. 38
      src/lib/eolian_cxx/grammar/eo_header_generator.hh
  26. 26
      src/lib/eolian_cxx/grammar/inheritance_base_generator.hh
  27. 68
      src/lib/eolian_cxx/grammar/namespace_generator.hh
  28. 2
      src/lib/eolian_cxx/grammar/parameters_generator.hh
  29. 63
      src/lib/eolian_cxx/grammar/type_generator.hh
  30. 4
      src/tests/eina_cxx/eina_cxx_test_accessor.cc
  31. 4
      src/tests/eina_cxx/eina_cxx_test_ptrarray.cc
  32. 4
      src/tests/eina_cxx/eina_cxx_test_ptrlist.cc
  33. 2
      src/tests/eolian_cxx/eolian_cxx_test_wrapper.cc

@ -12,7 +12,7 @@ bindings/eina_cxx/eina_accessor.hh \
bindings/eina_cxx/eina_array.hh \
bindings/eina_cxx/eina_clone_allocators.hh \
bindings/eina_cxx/eina_error.hh \
bindings/eina_cxx/eina_eo_base_fwd.hh \
bindings/eina_cxx/eina_eo_concrete_fwd.hh \
bindings/eina_cxx/eina_fold.hh \
bindings/eina_cxx/eina_inarray.hh \
bindings/eina_cxx/eina_inlist.hh \

@ -1,4 +1,15 @@
### Generated Headers
generated_eo_cxx_bindings = \
lib/eo/eo_base.eo.hh \
lib/eo/eo_abstract_class.eo.hh
CLEANFILES += $(generated_eo_cxx_bindings)
installed_eocxxheadersdir = $(includedir)/eo-cxx-@VMAJ@
nodist_installed_eocxxheaders_DATA = $(generated_eo_cxx_bindings)
### Library
if HAVE_CXX11
@ -9,7 +20,7 @@ bindings/eo_cxx/Eo.hh
installed_eocxxheadersdir = $(includedir)/eo-cxx-@VMAJ@/
dist_installed_eocxxheaders_DATA = \
bindings/eo_cxx/eo_base.hh \
bindings/eo_cxx/eo_concrete.hh \
bindings/eo_cxx/eo_event.hh \
bindings/eo_cxx/eo_init.hh \
bindings/eo_cxx/eo_wref.hh \

@ -18,6 +18,7 @@ lib/eolian_cxx/grammar/comment.hh \
lib/eolian_cxx/grammar/eo_class_constructors_generator.hh \
lib/eolian_cxx/grammar/eo_class_events_generator.hh \
lib/eolian_cxx/grammar/eo_class_functions_generator.hh \
lib/eolian_cxx/grammar/namespace_generator.hh \
lib/eolian_cxx/grammar/eo_class_generator.hh \
lib/eolian_cxx/grammar/eo_header_generator.hh \
lib/eolian_cxx/grammar/inheritance_base_generator.hh \

@ -22,6 +22,34 @@ namespace eolian_cxx {
extern efl::eina::log_domain domain;
void
remove_repeated_base(const char* klass_name, efl::eolian::parents_container_type& cont)
{
Eolian_Class const* klass = ::eolian_class_get_by_name(klass_name);
if (!klass)
{
std::cerr << "Error: could not get eolian class name `" << klass_name << "'" << std::endl;
return;
}
Eina_Iterator* inheritances = ::eolian_class_inherits_get(klass);
void* curr = 0;
EINA_ITERATOR_FOREACH(inheritances, curr)
{
if (!curr)
continue;
const char* parent = static_cast<const char*>(curr);
cont.erase(
std::remove(cont.begin(), cont.end(), safe_lower(class_format_cxx(parent)))
, cont.end());
remove_repeated_base(parent, cont);
}
eina_iterator_free(inheritances);
}
static efl::eolian::parameters_container_type
_convert_eolian_parameters(Eina_Iterator *parameters,
Eolian_Function_Type func_type)
@ -148,13 +176,6 @@ _convert_property_get_to_function(Eolian_Class const& klass,
return get_;
}
static std::string
_convert_class_name(std::string const& name)
{
return (name == "eo_base" || name == "eo::base" || name == "")
? "efl::eo::base"
: name;
}
void
convert_eolian_inheritances(efl::eolian::eo_class& cls, Eolian_Class const& klass)
@ -163,23 +184,21 @@ convert_eolian_inheritances(efl::eolian::eo_class& cls, Eolian_Class const& klas
::eolian_class_inherits_get(&klass);
void *curr;
if (!eina_iterator_next(inheritances, &curr) || !curr)
EINA_ITERATOR_FOREACH(inheritances, curr)
{
cls.parent = "efl::eo::base";
eina_iterator_free(inheritances);
return;
std::string parent = safe_lower(static_cast<const char*>(curr));
cls.parents.push_back(class_format_cxx(parent));
}
else
eina_iterator_free(inheritances);
if (cls.parents.empty())
return;
inheritances = ::eolian_class_inherits_get(&klass);
EINA_ITERATOR_FOREACH(inheritances, curr)
{
// First element is the parent
const char *ptr = static_cast<const char*>(curr);
cls.parent = _convert_class_name(class_format_cxx(safe_lower(ptr)));
EINA_ITERATOR_FOREACH(inheritances, curr)
{
std::string extension = safe_lower(static_cast<const char*>(curr));
cls.extensions.push_back(_convert_class_name(class_format_cxx(extension)));
}
if (curr)
remove_repeated_base(static_cast<const char*>(curr), cls.parents);
}
eina_iterator_free(inheritances);
}
@ -213,6 +232,9 @@ convert_eolian_functions(efl::eolian::eo_class& cls, Eolian_Class const& klass)
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))
{
cls.constructors.push_back({
@ -221,7 +243,7 @@ convert_eolian_functions(efl::eolian::eo_class& cls, Eolian_Class const& klass)
convert_comments_function(klass, func)
});
}
else if (function_is_visible(func, func_type))
else
{
cls.functions.push_back({
function_type(func),
@ -239,6 +261,9 @@ convert_eolian_functions(efl::eolian::eo_class& cls, Eolian_Class const& klass)
Eolian_Function const& func = *first;
Eolian_Function_Type t = ::eolian_function_type_get(&func);
if (!function_is_visible(func, t))
continue;
if(t == EOLIAN_PROP_GET)
{
cls.functions.push_back

@ -101,14 +101,7 @@ generator_options(const Eolian_Class& klass)
std::string eo_parent_file = class_base_file(*ext);
if (!eo_parent_file.empty())
{
// we have our own eo_base.hh
std::string eo_base_eo = "eo_base.eo";
if (eo_parent_file.length() < eo_base_eo.length() ||
!std::equal(eo_base_eo.begin(), eo_base_eo.end(),
eo_parent_file.end() - eo_base_eo.length()))
{
gen_opts.cxx_headers.push_back(eo_parent_file + ".hh");
}
gen_opts.cxx_headers.push_back(eo_parent_file + ".hh");
}
else
{

@ -350,14 +350,14 @@ parameter_type(Eolian_Function_Parameter const& parameter,
{
if (type.front().native == "char *")
type = { efl::eolian::type_to_native(type) };
type.front().is_out = true;
type.is_out = true;
type.front().native += "*";
}
if (parameter_is_const(parameter, func_type))
{
type[0].native.insert(0, "const ");
if (!type[0].binding.empty())
type[0].binding.insert(0, "const ");
type.front().native.insert(0, "const ");
if (!type.front().binding.empty())
type.front().binding.insert(0, "const ");
}
return type;
}

@ -77,14 +77,14 @@ type_lookup(const Eolian_Type* type,
efl::eolian::eolian_type_instance v(types.size());
for (std::size_t i = 0; i != types.size(); ++i)
{
v[i] = type_find(lut.begin(), lut.end(), type_from_eolian(*types[i]));
v.parts[i] = type_find(lut.begin(), lut.end(), type_from_eolian(*types[i]));
}
// Let's degrade to opaque classes when not enough information
// is available for complex types
if(v.size() == 1 && type_is_complex(v[0]))
if(v.parts.size() == 1 && type_is_complex(v.front()))
{
efl::eolian::eolian_type tmp = v[0];
efl::eolian::eolian_type tmp = v.front();
return {efl::eolian::type_to_native(tmp)};
}

@ -13,25 +13,25 @@ type_lookup_table
{"Ecore_Task_Cb", eolian_type::callback_, {"Ecore.h"}},
{"Ecore_Timeline_Cb", eolian_type::callback_, {"Ecore.h"}},
{"Edje_Signal_Cb", eolian_type::callback_, {"Edje.h"}},
{"Eina_Accessor *", eolian_type::complex_, false, false, "efl::eina::accessor", {"eina-cxx/eina_accessor.hh"}},
{"Eina_Bool", eolian_type::simple_, false, false, "bool", {}},
{"Eina_Bool *", eolian_type::simple_, false, false, "bool*", {}},
{"Eina_Inlist *", eolian_type::complex_, false, false, "efl::eina::range_inlist", {"eina-cxx/eina_inlist.hh"}},
{"Eina_Inlist *", eolian_type::complex_, false, true, "efl::eina::inlist", {"eina-cxx/eina_inlist.hh"}},
{"Eina_Iterator *", eolian_type::complex_, false, false, "efl::eina::iterator", {"eina-cxx/eina_iterator.hh"}},
{"Eina_List *", eolian_type::complex_, false, false, "efl::eina::range_list", {"eina-cxx/eina_list.hh"}},
{"Eina_List *", eolian_type::complex_, false, true, "efl::eina::list", {"eina-cxx/eina_list.hh"}},
{"const Eina_List *", eolian_type::complex_, true, false, "efl::eina::crange_list", {"eina-cxx/eina_list.hh"}},
{"Eina_Accessor *", eolian_type::complex_, false, false, true, "::efl::eina::accessor", {"eina-cxx/eina_accessor.hh"}},
{"Eina_Bool", eolian_type::simple_, false, false, false, "bool", {}},
{"Eina_Bool *", eolian_type::simple_, false, false, false, "bool*", {}},
{"Eina_Inlist *", eolian_type::complex_, false, false, true, "::efl::eina::range_inlist", {"eina-cxx/eina_inlist.hh"}},
{"Eina_Inlist *", eolian_type::complex_, false, true, true, "::efl::eina::inlist", {"eina-cxx/eina_inlist.hh"}},
{"Eina_Iterator *", eolian_type::complex_, false, false, true, "::efl::eina::iterator", {"eina-cxx/eina_iterator.hh"}},
{"Eina_List *", eolian_type::complex_, false, false, true, "::efl::eina::range_list", {"eina-cxx/eina_list.hh"}},
{"Eina_List *", eolian_type::complex_, false, true, true, "::efl::eina::list", {"eina-cxx/eina_list.hh"}},
{"const Eina_List *", eolian_type::complex_, true, false, true, "::efl::eina::crange_list", {"eina-cxx/eina_list.hh"}},
{"Eio_Filter_Direct_Cb", eolian_type::callback_, {"Eio.h"}},
{"Emodel *", eolian_type::simple_, false, false, "emodel", {"Emodel.hh"}},
{"Eo *", eolian_type::simple_, false, true, "efl::eo::base", {"eo_base.hh"}},
{"Eo *", eolian_type::simple_, false, false, "efl::eo::base", {"eo_base.hh"}},
{"Emodel *", eolian_type::simple_, false, false, true, "::emodel", {"Emodel.hh"}},
{"Eo *", eolian_type::simple_, false, true, true, "::efl::eo::concrete", {"eo_concrete.hh"}},
{"Eo *", eolian_type::simple_, false, false, true, "::efl::eo::concrete", {"eo_concrete.hh"}},
//{"Evas_Object_Box_Layout", eolian_type::callback_, {"Evas.h"}},
{"Evas_Object *", eolian_type::simple_, false, false, "evas::object", {"canvas/evas_object.eo.hh"}},
{"char *", eolian_type::simple_, false, true, "std::unique_ptr<char*>", {"memory"}},
{"const Eina_Inlist *", eolian_type::complex_, false, false, "efl::eina::range_inlist", {"eina-cxx/eina_inlist.hh"}},
{"const Eina_List *", eolian_type::complex_, false, false, "efl::eina::range_list", {"eina-cxx/eina_ptrlist.hh"}},
{"const char *", eolian_type::simple_, false, false, "std::string", {"string"}},
{"Evas_Object *", eolian_type::simple_, false, false, true, "::evas::object", {"canvas/evas_object.eo.hh"}},
{"char *", eolian_type::simple_, false, true, true, "std::unique_ptr<char*>", {"memory"}},
{"const Eina_Inlist *", eolian_type::complex_, false, false, true, "::efl::eina::range_inlist", {"eina-cxx/eina_inlist.hh"}},
{"const Eina_List *", eolian_type::complex_, false, false, true, "::efl::eina::range_list", {"eina-cxx/eina_ptrlist.hh"}},
{"const char *", eolian_type::simple_, false, false, true, "std::string", {"string"}},
};
}

@ -4,7 +4,7 @@
#include <Eina.h>
#include <eina_error.hh>
#include <eina_throw.hh>
#include <eina_eo_base_fwd.hh>
#include <eina_eo_concrete_fwd.hh>
#include <memory>
#include <iterator>
@ -151,7 +151,7 @@ template <typename T, typename Enable = T>
struct accessor;
template <typename T>
struct accessor<T, typename std::enable_if< ! std::is_base_of<efl::eo::base, T>::value, T>::type>
struct accessor<T, typename std::enable_if< ! std::is_base_of<::efl::eo::concrete, T>::value, T>::type>
: accessor_common_base<T>
{
typedef accessor_common_base<T> _base_type;
@ -262,7 +262,7 @@ struct accessor<T, typename std::enable_if< ! std::is_base_of<efl::eo::base, T>:
};
template <typename T>
struct accessor<T, typename std::enable_if<std::is_base_of<efl::eo::base, T>::value, T>::type>
struct accessor<T, typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value, T>::type>
: accessor_common_base<T>
{
typedef accessor_common_base<T> _base_type;
@ -404,7 +404,7 @@ struct accessor_iterator;
* Random access iterator for <tt>eina::accessor</tt>.
*/
template <typename T>
struct accessor_iterator<T, typename std::enable_if< ! std::is_base_of<efl::eo::base, T>::value, T>::type>
struct accessor_iterator<T, typename std::enable_if< ! std::is_base_of<::efl::eo::concrete, T>::value, T>::type>
{
typedef T value_type; /**< Type of the elements. */
typedef value_type* pointer; /**< Pointer to element type. */
@ -553,10 +553,10 @@ struct accessor_iterator<T, typename std::enable_if< ! std::is_base_of<efl::eo::
};
/**
* Specialization for all data types that are not derivated from efl::eo::base.
* Specialization for all data types that are not derivated from efl::eo::concrete.
*/
template <typename T>
struct accessor_iterator<T, typename std::enable_if<std::is_base_of<efl::eo::base, T>::value, T>::type>
struct accessor_iterator<T, typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value, T>::type>
{
typedef T value_type; /**< Type of the elements. */
typedef value_type* pointer; /**< Pointer to element type. */

@ -3,7 +3,7 @@
#include <Eo.h>
#include <eina_ptrarray.hh>
#include <eina_eo_base_fwd.hh>
#include <eina_eo_concrete_fwd.hh>
#include <iostream>
@ -132,7 +132,7 @@ struct _ptr_eo_array_iterator : _ptr_array_iterator<Eo>
};
template <typename T, typename CloneAllocator>
class array<T, CloneAllocator, typename std::enable_if<std::is_base_of<efl::eo::base, T>::value>::type>
class array<T, CloneAllocator, typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>::type>
: ptr_array<Eo, typename std::conditional
<std::is_same<CloneAllocator, default_clone_allocator_placeholder>::value
, eo_clone_allocator, CloneAllocator>::type>

@ -1,33 +0,0 @@
#ifndef EINA_EO_BASE_FWD_HH
#define EINA_EO_BASE_FWD_HH
#include <Eo.h>
#include <type_traits>
namespace efl { namespace eo {
struct base;
} }
namespace std {
template <>
struct is_base_of< ::efl::eo::base, ::Eo > : std::false_type {};
template <>
struct is_base_of< ::efl::eo::base, const ::Eo > : std::false_type {};
template <>
struct is_base_of< ::efl::eo::base, volatile ::Eo > : std::false_type {};
template <>
struct is_base_of< ::efl::eo::base, const volatile ::Eo > : std::false_type {};
template <>
struct is_base_of< const ::efl::eo::base, ::Eo > : std::false_type {};
template <>
struct is_base_of< const ::efl::eo::base, const ::Eo > : std::false_type {};
template <>
struct is_base_of< const ::efl::eo::base, volatile ::Eo > : std::false_type {};
template <>
struct is_base_of< const ::efl::eo::base, const volatile ::Eo > : std::false_type {};
}
#endif

@ -0,0 +1,33 @@
#ifndef EINA_EO_CONCRETE_FWD_HH
#define EINA_EO_CONCRETE_FWD_HH
#include <Eo.h>
#include <type_traits>
namespace efl { namespace eo {
struct concrete;
} }
namespace std {
template <>
struct is_base_of< ::efl::eo::concrete, ::Eo > : std::false_type {};
template <>
struct is_base_of< ::efl::eo::concrete, const ::Eo > : std::false_type {};
template <>
struct is_base_of< ::efl::eo::concrete, volatile ::Eo > : std::false_type {};
template <>
struct is_base_of< ::efl::eo::concrete, const volatile ::Eo > : std::false_type {};
template <>
struct is_base_of< const ::efl::eo::concrete, ::Eo > : std::false_type {};
template <>
struct is_base_of< const ::efl::eo::concrete, const ::Eo > : std::false_type {};
template <>
struct is_base_of< const ::efl::eo::concrete, volatile ::Eo > : std::false_type {};
template <>
struct is_base_of< const ::efl::eo::concrete, const volatile ::Eo > : std::false_type {};
}
#endif

@ -227,7 +227,7 @@ public:
};
template <typename T, typename CloneAllocator>
class list<T, CloneAllocator, typename std::enable_if<std::is_base_of<efl::eo::base, T>::value>::type>
class list<T, CloneAllocator, typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>::type>
: ptr_list<Eo, typename std::conditional
<std::is_same<CloneAllocator, default_clone_allocator_placeholder>::value
, eo_clone_allocator, CloneAllocator>::type>
@ -482,7 +482,7 @@ public:
};
template <typename T>
class range_list<T, typename std::enable_if<std::is_base_of<efl::eo::base, T>::value>::type>
class range_list<T, typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>::type>
: range_ptr_list<typename std::conditional<std::is_const<T>::value, Eo const, Eo>::type>
{
typedef range_ptr_list<typename std::conditional<std::is_const<T>::value, Eo const, Eo>::type> _base_type;

@ -6,7 +6,7 @@
#include <eina_lists_auxiliary.hh>
#include <eina_type_traits.hh>
#include <eina_accessor.hh>
#include <eina_eo_base_fwd.hh>
#include <eina_eo_concrete_fwd.hh>
#include <eina_iterator.hh>
#include <eina_throw.hh>

@ -1,7 +1,7 @@
#ifndef EFL_CXX_EO_HH
#define EFL_CXX_EO_HH
#include <eo_base.hh>
#include <eo_concrete.hh>
#include <eo_init.hh>
#include <eo_wref.hh>
#include <eo_inherit.hh>

@ -1,10 +1,9 @@
///
/// @file eo_base.hh
/// @file eo_concrete.hh
///
#ifndef EFL_CXX_EO_BASE_HH
#define EFL_CXX_EO_BASE_HH
#ifndef EFL_CXX_EO_CONCRETE_HH
#define EFL_CXX_EO_CONCRETE_HH
#include <cassert>
#include <stdexcept>
@ -27,41 +26,42 @@ namespace efl { namespace eo {
/// @addtogroup Efl_Cxx_API
/// @{
/// @brief A binding to the <em>EO Base Class</em>.
/// @brief Creates concrete versions for <em>Eo</em> wrappers.
///
/// This class implements C++ wrappers to all the <em>EO Base</em>
/// operations.
/// This class creates the concrete version of all C++ <em>Eo</em> wrappers.
/// It holds the Eo pointer that is used on all operations and provides some
/// functions for manipulating it.
///
struct base
struct concrete
{
/// @brief Class constructor.
///
/// @param eo The <em>EO Object</em>.
///
/// efl::eo::base constructors semantics are that of stealing the
/// efl::eo::concrete constructors semantics are that of stealing the
/// <em>EO Object</em> lifecycle management. Its constructors do not
/// increment the <em>EO</em> reference counter but the destructors
/// do decrement.
///
explicit base(Eo* eo) : _eo_raw(eo)
explicit concrete(Eo* eo) : _eo_raw(eo)
{
}
/// @brief Class destructor.
///
~base()
~concrete()
{
if(_eo_raw)
detail::unref(_eo_raw);
}
base(base const& other)
concrete(concrete const& other)
{
if(other._eo_raw)
_eo_raw = detail::ref(other._eo_raw);
}
base(base&& other)
concrete(concrete&& other)
{
if(_eo_raw) detail::unref(_eo_raw);
_eo_raw = other._eo_raw;
@ -70,7 +70,7 @@ struct base
/// @brief Assignment operator.
///
base& operator=(base const& other)
concrete& operator=(concrete const& other)
{
if(_eo_raw)
{
@ -82,7 +82,7 @@ struct base
return *this;
}
base& operator=(base&& other)
concrete& operator=(concrete&& other)
{
if(_eo_raw)
{
@ -100,7 +100,7 @@ struct base
///
Eo* _eo_ptr() const { return _eo_raw; }
/// @brief Releases the reference from this wrapper object and
/// @brief Releases the reference from this concrete object and
/// return the pointer to the <em>EO Object</em> stored in this
/// instance.
///
@ -132,85 +132,27 @@ struct base
///
/// @param parent The new parent.
///
void parent_set(base parent)
void parent_set(concrete parent)
{
detail::parent_set(_eo_raw, parent._eo_ptr());
}
/// @brief Get the parent of this object.
///
/// @return An @ref efl::eo::base instance that binds the parent
/// @return An @ref efl::eo::concrete instance that binds the parent
/// object. Returns NULL if there is no parent.
///
eina::optional<base> parent_get()
eina::optional<concrete> parent_get()
{
Eo *r = detail::parent_get(_eo_raw);
if(!r) return nullptr;
else
{
detail::ref(r); // XXX eo_parent_get does not call eo_ref so we may.
return base(r);
return concrete(r);
}
}
/// @brief Set generic data to object.
///
/// @param key The key associated with the data.
/// @param data The data to set.
/// @param free_func A pointer to the function that frees the
/// data. @c (::eo_key_data_free_func*)0 is valid.
///
void base_data_set(const char *key, const void *data, ::eo_key_data_free_func func)
{
detail::base_data_set(_eo_raw, key, data, func);
}
/// @brief Get generic data from object.
///
/// @param key The key associated with desired data.
/// @return A void pointer to the data.
///
void* base_data_get(const char *key)
{
return detail::base_data_get(_eo_raw, key);
}
/// @brief Delete generic data from object.
///
/// @param key The key associated with the data.
///
void base_data_del(const char *key)
{
detail::base_data_del(_eo_raw, key);
}
/// @brief Freeze any event directed to this object.
///
/// Prevents event callbacks from being called for this object.
///
void event_freeze()
{
detail::event_freeze(_eo_raw);
}
/// @brief Thaw the events of this object.
///
/// Let event callbacks be called for this object.
///
void event_thaw()
{
detail::event_thaw(_eo_raw);
}
/// @brief Get the event freeze count for this object.
///
/// @return The event freeze count for this object.
///
int event_freeze_get()
{
return detail::event_freeze_get(_eo_raw);
}
/// @brief Get debug information of this object.
///
/// @return The root node of the debug information tree.
@ -228,15 +170,14 @@ struct base
}
protected:
Eo* _eo_raw; ///< The opaque <em>EO Object</em>.
};
inline bool operator==(base const& lhs, base const& rhs)
inline bool operator==(concrete const& lhs, concrete const& rhs)
{
return lhs._eo_ptr() == rhs._eo_ptr();
}
inline bool operator!=(base const& lhs, base const& rhs)
inline bool operator!=(concrete const& lhs, concrete const& rhs)
{
return !(lhs == rhs);
}
@ -247,14 +188,14 @@ template <typename T>
struct extension_inheritance;
template<>
struct extension_inheritance<base>
struct extension_inheritance<concrete>
{
template <typename T>
struct type
{
operator base() const
operator concrete() const
{
return base(eo_ref(static_cast<T const*>(this)->_eo_ptr()));
return concrete(eo_ref(static_cast<T const*>(this)->_eo_ptr()));
}
};
@ -288,7 +229,7 @@ T downcast(U object)
}
///
/// @brief Type used to hold the parent passed to base Eo C++
/// @brief Type used to hold the parent passed to concrete Eo C++
/// constructors.
///
struct parent_type
@ -298,11 +239,11 @@ struct parent_type
///
/// @brief The expression type declaring the assignment operator used
/// in the parent argument of the base Eo C++ class.
/// in the parent argument of the concrete Eo C++ class.
///
struct parent_expr
{
parent_type operator=(efl::eo::base const& parent) const
parent_type operator=(efl::eo::concrete const& parent) const
{
return { parent._eo_ptr() };
}
@ -327,4 +268,4 @@ parent_expr const parent = {};
} } // namespace efl { namespace eo {
#endif // EFL_CXX_EO_BASE_HH
#endif // EFL_CXX_EO_CONCRETE_HH

@ -39,19 +39,19 @@ to_c(bool* x)
}
template <typename T>
T to_c(T const& v, typename std::enable_if<!std::is_convertible<T*, efl::eo::base*>::value>::type* = 0)
T to_c(T const& v, typename std::enable_if<!std::is_convertible<T*, ::efl::eo::concrete*>::value>::type* = 0)
{
return v;
}
template <typename T>
Eo* to_c(T const& v, typename std::enable_if<std::is_convertible<T*, efl::eo::base*>::value>::type* = 0)
Eo* to_c(T const& v, typename std::enable_if<std::is_convertible<T*, ::efl::eo::concrete*>::value>::type* = 0)
{
return v._eo_ptr();
}
template <typename T>
Eo** to_c(T* v, typename std::enable_if<std::is_convertible<T*, efl::eo::base*>::value>::type* = 0)
Eo** to_c(T* v, typename std::enable_if<std::is_convertible<T*, ::efl::eo::concrete*>::value>::type* = 0)
{
static_assert(sizeof(T) == sizeof(Eo*), "");
return static_cast<Eo**>(static_cast<void*>(v));
@ -137,7 +137,7 @@ struct traits
template <typename T>
struct traits
<T, typename std::enable_if<std::is_base_of<efl::eo::base, T>::value>::type>
<T, typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>::type>
{
typedef Eo* type;
};
@ -193,7 +193,7 @@ to_cxx(Eina_Iterator* x, std::tuple<std::false_type, Args...>, tag< efl::eina::i
template <typename T, typename ...Args>
T
to_cxx(Eo const* x, std::tuple<std::false_type, Args...>, tag< T >
, typename std::enable_if<std::is_base_of<efl::eo::base, T>::value>* = 0)
, typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>* = 0)
{
// Workaround for erroneous constness
return T{ ::eo_ref(const_cast<Eo*>(x))};
@ -202,7 +202,7 @@ to_cxx(Eo const* x, std::tuple<std::false_type, Args...>, tag< T >
template <typename T, typename ...Args>
T
to_cxx(Eo const* x, std::tuple<std::true_type, Args...>, tag< T >
, typename std::enable_if<std::is_base_of<efl::eo::base, T>::value>* = 0)
, typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>* = 0)
{
// Workaround for erroneous constness
return T{const_cast<Eo*>(x)};

@ -40,7 +40,7 @@ void inherit_constructor(void* this_, Args args);
///
/// The derived class @p D will inherit all EO operations and event
/// callbacks from the parent class @p P, as well as from the <c>Base
/// Class</c> (@ref efl::eo::base) since every EO C++ Class must
/// Class</c> (@ref efl::eo::concrete) since every EO C++ Class must
/// inherit from it.
///
/// efl::eo::inherit makes use of meta-template elements to build (in

@ -14,7 +14,7 @@ struct eo_parameter;
struct eo_function;
struct eo_event;
typedef std::vector<std::string> extensions_container_type;
typedef std::vector<std::string> parents_container_type;
typedef std::vector<std::string> includes_container_type;
typedef std::vector<eo_constructor> constructors_container_type;
typedef std::vector<eo_function> functions_container_type;
@ -33,7 +33,7 @@ struct eolian_type
, category(unknown_)
, is_const(false)
, is_own(false)
, is_out(false)
, is_class(false)
, binding()
, includes()
{}
@ -42,13 +42,14 @@ struct eolian_type
category_type category_,
bool is_const_,
bool is_own_,
bool is_class_,
std::string binding_,
includes_container_type includes_)
: native(native_)
, category(category_)
, is_const(is_const_)
, is_own(is_own_)
, is_out(false)
, is_class(is_class_)
, binding(binding_)
, includes(includes_)
{
@ -59,7 +60,7 @@ struct eolian_type
eolian_type(std::string native_,
category_type category_,
includes_container_type const& includes_)
: eolian_type(native_, category_, false, false, "", includes_)
: eolian_type(native_, category_, false, false, false, "", includes_)
{
assert(category == callback_);
}
@ -68,20 +69,48 @@ struct eolian_type
category_type category;
bool is_const;
bool is_own;
bool is_out;
bool is_class;
std::string binding;
includes_container_type includes;
};
typedef std::vector<eolian_type> eolian_type_instance;
typedef std::vector<eolian_type> eolian_type_container;
struct eolian_type_instance
{
eolian_type_instance()
: is_out(false)
, parts()
{}
eolian_type_instance(std::initializer_list<eolian_type> il,
bool is_out_ = false)
: is_out(is_out_)
, parts(il)
{}
explicit eolian_type_instance(std::size_t size)
: is_out(false)
, parts(size)
{}
bool empty() const { return parts.empty(); }
std::size_t size() const { return parts.size(); }
eolian_type& front() { return parts.front(); }
eolian_type const& front() const { return parts.front(); }
bool is_out;
eolian_type_container parts;
};
const efl::eolian::eolian_type
void_type { "void", efl::eolian::eolian_type::simple_, false, false, "", {} };
void_type { "void", efl::eolian::eolian_type::simple_, false, false, false, "", {} };
inline bool
type_is_void(eolian_type_instance const& type)
{
return type.empty() || type[0].native.compare("void") == 0;
return type.empty() || type.front().native.compare("void") == 0;
}
inline bool
@ -98,16 +127,22 @@ type_is_binding(eolian_type_instance const& type)
}
inline bool
type_is_out(eolian_type const& type)
type_is_out(eolian_type_instance const& type)
{
return type.is_out;
}
inline bool
type_is_out(eolian_type_instance const& type)
type_is_class(eolian_type const& type)
{
return type.is_class;
}
inline bool
type_is_class(eolian_type_instance const& type)
{
assert(!type.empty());
return type_is_out(type.front());
return type_is_class(type.front());
}
inline eolian_type
@ -116,6 +151,7 @@ type_to_native(eolian_type const& type)
eolian_type native(type);
native.binding.clear();
native.category = eolian_type::simple_;
native.is_class = false;
return native;
}
@ -179,8 +215,7 @@ struct eo_class
eo_class_type type;
std::string name;
std::string eo_name;
std::string parent;
extensions_container_type extensions;
parents_container_type parents;
constructors_container_type constructors;
functions_container_type functions;
events_container_type events;
@ -227,7 +262,7 @@ struct eo_event
inline bool
function_is_void(eo_function const& func)
{
return func.ret.empty() || func.ret[0].native.compare("void") == 0;
return func.ret.empty() || func.ret.front().native.compare("void") == 0;
}
inline bool

@ -23,7 +23,7 @@ _is_valid(eolian_type_instance const& type)
{
// if (type.empty() || (*type.rbegin()).category == eolian_type::complex_)
// return false;
for (auto rit = type.rbegin(), last = type.rend(); rit != last; ++rit)
for (auto rit = type.parts.rbegin(), last = type.parts.rend(); rit != last; ++rit)
{
if ((*rit).binding.empty() && (*rit).category == eolian_type::complex_)
return false;

@ -9,6 +9,7 @@
#include "tab.hh"
#include "comment.hh"
#include "parameters_generator.hh"
#include "namespace_generator.hh"
namespace efl { namespace eolian { namespace grammar {
@ -27,34 +28,6 @@ operator<<(std::ostream& out, class_name const& x)
return out;
}
struct class_extensions
{
eo_class const& _cls;
class_extensions(eo_class const& cls)
: _cls(cls)
{}
};
inline std::ostream&
operator<<(std::ostream& out, class_extensions const& x)
{
eo_class const& cls = x._cls;
extensions_container_type::const_iterator it, first = cls.extensions.begin();
extensions_container_type::const_iterator last = cls.extensions.end();
for (it = first; it != last; ++it)
{
if (it != first) out << ",\n";
out << tab(2)
<< "efl::eo::detail::extension_inheritance<"
<< *it << ">::template type< ::";
if(!cls.name_space.empty())
out << cls.name_space << "::";
out << cls.name << ">";
}
out << endl;
return out;
}
struct class_inheritance
{
eo_class const& _cls;
@ -68,12 +41,14 @@ operator<<(std::ostream& out, class_inheritance const& x)
{
eo_class const& cls = x._cls;
out << class_name(cls.parent);
if (cls.extensions.size() > 0)
parents_container_type::const_iterator it,
first = cls.parents.cbegin(),
last = cls.parents.cend();
for (it = first; it != last; ++it)
{
out << "," << endl << class_extensions(cls);
out << tab(2) << (it == first ? ": " : ", ")
<< "::" << abstract_namespace << "::" << *it << endl;
}
out << endl;
return out;
}
@ -208,14 +183,14 @@ operator<<(std::ostream& out, functors_constructor_methods const& x)
return out;
}
struct functions_constructor_methods
struct constructor_method_function_declarations
{
eo_class const& _cls;
functions_constructor_methods(eo_class const& cls) : _cls(cls) {}
constructor_method_function_declarations(eo_class const& cls) : _cls(cls) {}
};
inline std::ostream&
operator<<(std::ostream& out, functions_constructor_methods const& x)
operator<<(std::ostream& out, constructor_method_function_declarations const& x)
{
constructors_container_type::const_iterator it,
first = x._cls.constructors.cbegin(),
@ -224,14 +199,56 @@ operator<<(std::ostream& out, functions_constructor_methods const& x)
{
eo_constructor const& c = *it;
out << comment(c.comment, 1)
// "eo_constructor" is already called in the eo_add_ref macro (used in
// _ctors_call).
// Creating a function with this name yields an error in the eo_add_ref
// macro expansion, because "eo_constructor" will refers to the class
// function instead of the Eo.Base function which is intended.
if (c.name == "eo_constructor")
{
continue;
}
out << comment(c.comment, 0)
<< template_parameters_declaration(c.params, 1)
<< tab(1) << constructor_functor_type_decl(c) << " " << c.name << "("
<< parameters_declaration(c.params) << ")" << endl
<< tab(1) << "{" << endl
<< tab(2) << "return " << constructor_functor_type_decl(c) << "("
<< parameters_declaration(c.params) << ") const;" << endl << endl;
}
return out;
}
struct constructor_method_function_definitions
{
eo_class const& _cls;
constructor_method_function_definitions(eo_class const& cls) : _cls(cls) {}
};
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();
for (it = first; it != last; ++it)
{
eo_constructor const& c = *it;
// Same explanation as the one in constructor_method_function_declarations
if (c.name == "eo_constructor")
{
continue;
}
out << template_parameters_declaration(c.params, 0)
<< "inline " << abstract_full_name(x._cls)
<< "::" << constructor_functor_type_decl(c) << " "
<< abstract_full_name(x._cls, false) << "::" << c.name << "("
<< parameters_declaration(c.params) << ") const" << endl
<< "{" << endl
<< tab(1) << "return " << constructor_functor_type_decl(c) << "("
<< parameters_forward(c.params) << ");" << endl
<< tab(1) << "}" << endl << endl;
<< "}" << endl << endl;
}
return out;
@ -248,10 +265,6 @@ struct constructor_with_constructor_methods
inline std::ostream&
operator<<(std::ostream& out, constructor_with_constructor_methods const& x)
{
//
// TODO Require constructor methods of all base classes ?
//
unsigned cb_count = 0;
constructors_container_type::const_iterator it,
@ -296,7 +309,7 @@ operator<<(std::ostream& out, constructor_with_constructor_methods const& x)
}
assert(cb_idx == cb_count);
}
out << "efl::eo::parent_type _p = (efl::eo::parent = nullptr))" << endl
out << "::efl::eo::parent_type _p = (::efl::eo::parent = nullptr))" << endl
<< tab(2) << ": " << x._cls.name << "(_ctors_call(";
for (it = first; it != last; ++it)
{
@ -325,7 +338,7 @@ operator<<(std::ostream& out, constructor_eo const& x)
out << comment(doc, 1)
<< tab(1)
<< "explicit " << x._cls.name << "(Eo* eo)" << endl
<< tab(2) << ": " << class_name(x._cls.parent) << "(eo)" << endl
<< tab(2) << ": ::efl::eo::concrete(eo)" << endl
<< tab(1) << "{}" << endl << endl;
out << comment(
@ -335,7 +348,7 @@ operator<<(std::ostream& out, constructor_eo const& x)
)
<< tab(1)
<< "explicit " << x._cls.name << "(std::nullptr_t)" << endl
<< tab(2) << ": " << class_name(x._cls.parent) << "(nullptr)" << endl
<< tab(2) << ": ::efl::eo::concrete(nullptr)" << endl
<< tab(1) << "{}" << endl << endl;
return out;
}
@ -355,7 +368,7 @@ operator<<(std::ostream& out, copy_constructor const& x)
out << comment(doc, 1)
<< tab(1)
<< x._cls.name << "(" << x._cls.name << " const& other)" << endl
<< tab(2) << ": " << class_name(x._cls.parent)
<< tab(2) << ": " << x._cls.name
<< "(eo_ref(other._eo_ptr()))" << endl
<< tab(1) << "{}" << endl << endl;
return out;
@ -427,7 +440,7 @@ operator<<(std::ostream& out, function_call_constructor_methods const& x)
}
assert(cb_idx == cb_count);
out << "efl::eo::parent_type _p)" << endl
out << "::efl::eo::parent_type _p)" << 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)
@ -449,7 +462,7 @@ operator<<(std::ostream& out, function_call_constructor_methods const& x)
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++
<< "&::efl::eolian::free_callback_calback<F" << cb_idx++
<< ">, _c" << (it-first) << "." << callback_tmp(d.name)
<< "));" << endl;
})

@ -4,7 +4,7 @@
#include <iosfwd>
#include "eo_types.hh"
#include "type_generator.hh"
#include "tab.hh"
#include "comment.hh"
@ -50,14 +50,14 @@ operator<<(std::ostream& out, event_callback_add const& x)
<< tab(1) << "{" << endl
<< tab(2) << "typedef typename std::remove_reference<F>::type function_type;" << endl
<< tab(2) << "::std::unique_ptr<function_type> f ( new function_type(std::move(callback_)) );" << endl
<< tab(2) << "eo_do(" << add_cast_to_t(x._add_cast_to_t) << "_eo_ptr()," << endl