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.
This commit is contained in:
Vitor Sousa 2014-12-17 11:47:19 -02:00
parent ebebcf6438
commit ed75aa32d6
33 changed files with 606 additions and 381 deletions

View File

@ -12,7 +12,7 @@ bindings/eina_cxx/eina_accessor.hh \
bindings/eina_cxx/eina_array.hh \ bindings/eina_cxx/eina_array.hh \
bindings/eina_cxx/eina_clone_allocators.hh \ bindings/eina_cxx/eina_clone_allocators.hh \
bindings/eina_cxx/eina_error.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_fold.hh \
bindings/eina_cxx/eina_inarray.hh \ bindings/eina_cxx/eina_inarray.hh \
bindings/eina_cxx/eina_inlist.hh \ bindings/eina_cxx/eina_inlist.hh \

View File

@ -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 ### Library
if HAVE_CXX11 if HAVE_CXX11
@ -9,7 +20,7 @@ bindings/eo_cxx/Eo.hh
installed_eocxxheadersdir = $(includedir)/eo-cxx-@VMAJ@/ installed_eocxxheadersdir = $(includedir)/eo-cxx-@VMAJ@/
dist_installed_eocxxheaders_DATA = \ 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_event.hh \
bindings/eo_cxx/eo_init.hh \ bindings/eo_cxx/eo_init.hh \
bindings/eo_cxx/eo_wref.hh \ bindings/eo_cxx/eo_wref.hh \

View File

@ -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_constructors_generator.hh \
lib/eolian_cxx/grammar/eo_class_events_generator.hh \ lib/eolian_cxx/grammar/eo_class_events_generator.hh \
lib/eolian_cxx/grammar/eo_class_functions_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_class_generator.hh \
lib/eolian_cxx/grammar/eo_header_generator.hh \ lib/eolian_cxx/grammar/eo_header_generator.hh \
lib/eolian_cxx/grammar/inheritance_base_generator.hh \ lib/eolian_cxx/grammar/inheritance_base_generator.hh \

View File

@ -22,6 +22,34 @@ namespace eolian_cxx {
extern efl::eina::log_domain domain; 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 static efl::eolian::parameters_container_type
_convert_eolian_parameters(Eina_Iterator *parameters, _convert_eolian_parameters(Eina_Iterator *parameters,
Eolian_Function_Type func_type) Eolian_Function_Type func_type)
@ -148,13 +176,6 @@ _convert_property_get_to_function(Eolian_Class const& klass,
return get_; 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 void
convert_eolian_inheritances(efl::eolian::eo_class& cls, Eolian_Class const& klass) 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); ::eolian_class_inherits_get(&klass);
void *curr; void *curr;
if (!eina_iterator_next(inheritances, &curr) || !curr) EINA_ITERATOR_FOREACH(inheritances, curr)
{ {
cls.parent = "efl::eo::base"; std::string parent = safe_lower(static_cast<const char*>(curr));
eina_iterator_free(inheritances); cls.parents.push_back(class_format_cxx(parent));
return;
} }
else eina_iterator_free(inheritances);
{
// 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) if (cls.parents.empty())
{ return;
std::string extension = safe_lower(static_cast<const char*>(curr));
cls.extensions.push_back(_convert_class_name(class_format_cxx(extension))); inheritances = ::eolian_class_inherits_get(&klass);
} EINA_ITERATOR_FOREACH(inheritances, curr)
{
if (curr)
remove_repeated_base(static_cast<const char*>(curr), cls.parents);
} }
eina_iterator_free(inheritances); 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 const& func = *first;
Eolian_Function_Type const func_type = function_op_type(func); 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_constructor(klass, func))
{ {
cls.constructors.push_back({ 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) convert_comments_function(klass, func)
}); });
} }
else if (function_is_visible(func, func_type)) else
{ {
cls.functions.push_back({ cls.functions.push_back({
function_type(func), 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 const& func = *first;
Eolian_Function_Type t = ::eolian_function_type_get(&func); Eolian_Function_Type t = ::eolian_function_type_get(&func);
if (!function_is_visible(func, t))
continue;
if(t == EOLIAN_PROP_GET) if(t == EOLIAN_PROP_GET)
{ {
cls.functions.push_back cls.functions.push_back

View File

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

View File

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

View File

@ -77,14 +77,14 @@ type_lookup(const Eolian_Type* type,
efl::eolian::eolian_type_instance v(types.size()); efl::eolian::eolian_type_instance v(types.size());
for (std::size_t i = 0; i != types.size(); ++i) 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 // Let's degrade to opaque classes when not enough information
// is available for complex types // 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)}; return {efl::eolian::type_to_native(tmp)};
} }

View File

@ -13,25 +13,25 @@ type_lookup_table
{"Ecore_Task_Cb", eolian_type::callback_, {"Ecore.h"}}, {"Ecore_Task_Cb", eolian_type::callback_, {"Ecore.h"}},
{"Ecore_Timeline_Cb", eolian_type::callback_, {"Ecore.h"}}, {"Ecore_Timeline_Cb", eolian_type::callback_, {"Ecore.h"}},
{"Edje_Signal_Cb", eolian_type::callback_, {"Edje.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_Accessor *", eolian_type::complex_, false, false, true, "::efl::eina::accessor", {"eina-cxx/eina_accessor.hh"}},
{"Eina_Bool", eolian_type::simple_, false, false, "bool", {}}, {"Eina_Bool", eolian_type::simple_, false, false, false, "bool", {}},
{"Eina_Bool *", eolian_type::simple_, false, false, "bool*", {}}, {"Eina_Bool *", eolian_type::simple_, false, 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, false, true, "::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_Inlist *", eolian_type::complex_, false, true, 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_Iterator *", eolian_type::complex_, false, false, true, "::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, false, true, "::efl::eina::range_list", {"eina-cxx/eina_list.hh"}},
{"Eina_List *", eolian_type::complex_, false, true, "efl::eina::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, "efl::eina::crange_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"}}, {"Eio_Filter_Direct_Cb", eolian_type::callback_, {"Eio.h"}},
{"Emodel *", eolian_type::simple_, false, false, "emodel", {"Emodel.hh"}}, {"Emodel *", eolian_type::simple_, false, false, true, "::emodel", {"Emodel.hh"}},
{"Eo *", eolian_type::simple_, false, true, "efl::eo::base", {"eo_base.hh"}}, {"Eo *", eolian_type::simple_, false, true, true, "::efl::eo::concrete", {"eo_concrete.hh"}},
{"Eo *", eolian_type::simple_, false, false, "efl::eo::base", {"eo_base.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_Box_Layout", eolian_type::callback_, {"Evas.h"}},
{"Evas_Object *", eolian_type::simple_, false, false, "evas::object", {"canvas/evas_object.eo.hh"}}, {"Evas_Object *", eolian_type::simple_, false, false, true, "::evas::object", {"canvas/evas_object.eo.hh"}},
{"char *", eolian_type::simple_, false, true, "std::unique_ptr<char*>", {"memory"}}, {"char *", eolian_type::simple_, false, true, 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_Inlist *", eolian_type::complex_, false, false, true, "::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 Eina_List *", eolian_type::complex_, false, false, true, "::efl::eina::range_list", {"eina-cxx/eina_ptrlist.hh"}},
{"const char *", eolian_type::simple_, false, false, "std::string", {"string"}}, {"const char *", eolian_type::simple_, false, false, true, "std::string", {"string"}},
}; };
} }

View File

@ -4,7 +4,7 @@
#include <Eina.h> #include <Eina.h>
#include <eina_error.hh> #include <eina_error.hh>
#include <eina_throw.hh> #include <eina_throw.hh>
#include <eina_eo_base_fwd.hh> #include <eina_eo_concrete_fwd.hh>
#include <memory> #include <memory>
#include <iterator> #include <iterator>
@ -151,7 +151,7 @@ template <typename T, typename Enable = T>
struct accessor; struct accessor;
template <typename 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> : accessor_common_base<T>
{ {
typedef accessor_common_base<T> _base_type; 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> 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> : accessor_common_base<T>
{ {
typedef accessor_common_base<T> _base_type; typedef accessor_common_base<T> _base_type;
@ -404,7 +404,7 @@ struct accessor_iterator;
* Random access iterator for <tt>eina::accessor</tt>. * Random access iterator for <tt>eina::accessor</tt>.
*/ */
template <typename T> 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 T value_type; /**< Type of the elements. */
typedef value_type* pointer; /**< Pointer to element type. */ 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> 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 T value_type; /**< Type of the elements. */
typedef value_type* pointer; /**< Pointer to element type. */ typedef value_type* pointer; /**< Pointer to element type. */

View File

@ -3,7 +3,7 @@
#include <Eo.h> #include <Eo.h>
#include <eina_ptrarray.hh> #include <eina_ptrarray.hh>
#include <eina_eo_base_fwd.hh> #include <eina_eo_concrete_fwd.hh>
#include <iostream> #include <iostream>
@ -132,7 +132,7 @@ struct _ptr_eo_array_iterator : _ptr_array_iterator<Eo>
}; };
template <typename T, typename CloneAllocator> 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 : ptr_array<Eo, typename std::conditional
<std::is_same<CloneAllocator, default_clone_allocator_placeholder>::value <std::is_same<CloneAllocator, default_clone_allocator_placeholder>::value
, eo_clone_allocator, CloneAllocator>::type> , eo_clone_allocator, CloneAllocator>::type>

View File

@ -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

View File

@ -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

View File

@ -227,7 +227,7 @@ public:
}; };
template <typename T, typename CloneAllocator> 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 : ptr_list<Eo, typename std::conditional
<std::is_same<CloneAllocator, default_clone_allocator_placeholder>::value <std::is_same<CloneAllocator, default_clone_allocator_placeholder>::value
, eo_clone_allocator, CloneAllocator>::type> , eo_clone_allocator, CloneAllocator>::type>
@ -482,7 +482,7 @@ public:
}; };
template <typename T> 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> : 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; typedef range_ptr_list<typename std::conditional<std::is_const<T>::value, Eo const, Eo>::type> _base_type;

View File

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

View File

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

View File

@ -1,10 +1,9 @@
/// ///
/// @file eo_base.hh /// @file eo_concrete.hh
/// ///
#ifndef EFL_CXX_EO_BASE_HH #ifndef EFL_CXX_EO_CONCRETE_HH
#define EFL_CXX_EO_BASE_HH #define EFL_CXX_EO_CONCRETE_HH
#include <cassert> #include <cassert>
#include <stdexcept> #include <stdexcept>
@ -27,41 +26,42 @@ namespace efl { namespace eo {
/// @addtogroup Efl_Cxx_API /// @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> /// This class creates the concrete version of all C++ <em>Eo</em> wrappers.
/// operations. /// 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. /// @brief Class constructor.
/// ///
/// @param eo The <em>EO Object</em>. /// @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 /// <em>EO Object</em> lifecycle management. Its constructors do not
/// increment the <em>EO</em> reference counter but the destructors /// increment the <em>EO</em> reference counter but the destructors
/// do decrement. /// do decrement.
/// ///
explicit base(Eo* eo) : _eo_raw(eo) explicit concrete(Eo* eo) : _eo_raw(eo)
{ {
} }
/// @brief Class destructor. /// @brief Class destructor.
/// ///
~base() ~concrete()
{ {
if(_eo_raw) if(_eo_raw)
detail::unref(_eo_raw); detail::unref(_eo_raw);
} }
base(base const& other) concrete(concrete const& other)
{ {
if(other._eo_raw) if(other._eo_raw)
_eo_raw = detail::ref(other._eo_raw); _eo_raw = detail::ref(other._eo_raw);
} }
base(base&& other) concrete(concrete&& other)
{ {
if(_eo_raw) detail::unref(_eo_raw); if(_eo_raw) detail::unref(_eo_raw);
_eo_raw = other._eo_raw; _eo_raw = other._eo_raw;
@ -70,7 +70,7 @@ struct base
/// @brief Assignment operator. /// @brief Assignment operator.
/// ///
base& operator=(base const& other) concrete& operator=(concrete const& other)
{ {
if(_eo_raw) if(_eo_raw)
{ {
@ -82,7 +82,7 @@ struct base
return *this; return *this;
} }
base& operator=(base&& other) concrete& operator=(concrete&& other)
{ {
if(_eo_raw) if(_eo_raw)
{ {
@ -100,7 +100,7 @@ struct base
/// ///
Eo* _eo_ptr() const { return _eo_raw; } 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 /// return the pointer to the <em>EO Object</em> stored in this
/// instance. /// instance.
/// ///
@ -132,85 +132,27 @@ struct base
/// ///
/// @param parent The new parent. /// @param parent The new parent.
/// ///
void parent_set(base parent) void parent_set(concrete parent)
{ {
detail::parent_set(_eo_raw, parent._eo_ptr()); detail::parent_set(_eo_raw, parent._eo_ptr());
} }
/// @brief Get the parent of this object. /// @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. /// 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); Eo *r = detail::parent_get(_eo_raw);
if(!r) return nullptr; if(!r) return nullptr;
else else
{ {
detail::ref(r); // XXX eo_parent_get does not call eo_ref so we may. 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. /// @brief Get debug information of this object.
/// ///
/// @return The root node of the debug information tree. /// @return The root node of the debug information tree.
@ -228,15 +170,14 @@ struct base
} }
protected: protected:
Eo* _eo_raw; ///< The opaque <em>EO Object</em>. 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(); 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); return !(lhs == rhs);
} }
@ -247,14 +188,14 @@ template <typename T>
struct extension_inheritance; struct extension_inheritance;
template<> template<>
struct extension_inheritance<base> struct extension_inheritance<concrete>
{ {
template <typename T> template <typename T>
struct type 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. /// constructors.
/// ///
struct parent_type struct parent_type
@ -298,11 +239,11 @@ struct parent_type
/// ///
/// @brief The expression type declaring the assignment operator used /// @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 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() }; return { parent._eo_ptr() };
} }
@ -327,4 +268,4 @@ parent_expr const parent = {};
} } // namespace efl { namespace eo { } } // namespace efl { namespace eo {
#endif // EFL_CXX_EO_BASE_HH #endif // EFL_CXX_EO_CONCRETE_HH

View File

@ -39,19 +39,19 @@ to_c(bool* x)
} }
template <typename T> 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; return v;
} }
template <typename T> 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(); return v._eo_ptr();
} }
template <typename T> 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*), ""); static_assert(sizeof(T) == sizeof(Eo*), "");
return static_cast<Eo**>(static_cast<void*>(v)); return static_cast<Eo**>(static_cast<void*>(v));
@ -137,7 +137,7 @@ struct traits
template <typename T> template <typename T>
struct traits 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; 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> template <typename T, typename ...Args>
T T
to_cxx(Eo const* x, std::tuple<std::false_type, Args...>, tag< 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 // Workaround for erroneous constness
return T{ ::eo_ref(const_cast<Eo*>(x))}; 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> template <typename T, typename ...Args>
T T
to_cxx(Eo const* x, std::tuple<std::true_type, Args...>, tag< 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 // Workaround for erroneous constness
return T{const_cast<Eo*>(x)}; return T{const_cast<Eo*>(x)};

View File

@ -40,7 +40,7 @@ void inherit_constructor(void* this_, Args args);
/// ///
/// The derived class @p D will inherit all EO operations and event /// 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 /// 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. /// inherit from it.
/// ///
/// efl::eo::inherit makes use of meta-template elements to build (in /// efl::eo::inherit makes use of meta-template elements to build (in

View File

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

View File

@ -23,7 +23,7 @@ _is_valid(eolian_type_instance const& type)
{ {
// if (type.empty() || (*type.rbegin()).category == eolian_type::complex_) // if (type.empty() || (*type.rbegin()).category == eolian_type::complex_)
// return false; // 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_) if ((*rit).binding.empty() && (*rit).category == eolian_type::complex_)
return false; return false;

View File

@ -9,6 +9,7 @@
#include "tab.hh" #include "tab.hh"
#include "comment.hh" #include "comment.hh"
#include "parameters_generator.hh" #include "parameters_generator.hh"
#include "namespace_generator.hh"
namespace efl { namespace eolian { namespace grammar { namespace efl { namespace eolian { namespace grammar {
@ -27,34 +28,6 @@ operator<<(std::ostream& out, class_name const& x)
return out; 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 struct class_inheritance
{ {
eo_class const& _cls; eo_class const& _cls;
@ -68,12 +41,14 @@ operator<<(std::ostream& out, class_inheritance const& x)
{ {
eo_class const& cls = x._cls; eo_class const& cls = x._cls;
out << class_name(cls.parent); parents_container_type::const_iterator it,
if (cls.extensions.size() > 0) 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; return out;
} }
@ -208,14 +183,14 @@ operator<<(std::ostream& out, functors_constructor_methods const& x)
return out; return out;
} }
struct functions_constructor_methods struct constructor_method_function_declarations
{ {
eo_class const& _cls; 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& 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, constructors_container_type::const_iterator it,
first = x._cls.constructors.cbegin(), first = x._cls.constructors.cbegin(),
@ -224,14 +199,56 @@ operator<<(std::ostream& out, functions_constructor_methods const& x)
{ {
eo_constructor const& c = *it; 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) << template_parameters_declaration(c.params, 1)
<< tab(1) << constructor_functor_type_decl(c) << " " << c.name << "(" << tab(1) << constructor_functor_type_decl(c) << " " << c.name << "("
<< parameters_declaration(c.params) << ")" << endl << parameters_declaration(c.params) << ") const;" << endl << endl;
<< tab(1) << "{" << endl }
<< tab(2) << "return " << constructor_functor_type_decl(c) << "("
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 << parameters_forward(c.params) << ");" << endl
<< tab(1) << "}" << endl << endl; << "}" << endl << endl;
} }
return out; return out;
@ -248,10 +265,6 @@ struct constructor_with_constructor_methods
inline std::ostream& inline std::ostream&
operator<<(std::ostream& out, constructor_with_constructor_methods const& x) operator<<(std::ostream& out, constructor_with_constructor_methods const& x)
{ {
//
// TODO Require constructor methods of all base classes ?
//
unsigned cb_count = 0; unsigned cb_count = 0;
constructors_container_type::const_iterator it, 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); 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("; << tab(2) << ": " << x._cls.name << "(_ctors_call(";
for (it = first; it != last; ++it) for (it = first; it != last; ++it)
{ {
@ -325,7 +338,7 @@ operator<<(std::ostream& out, constructor_eo const& x)
out << comment(doc, 1) out << comment(doc, 1)
<< tab(1) << tab(1)
<< "explicit " << x._cls.name << "(Eo* eo)" << endl << "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; << tab(1) << "{}" << endl << endl;
out << comment( out << comment(
@ -335,7 +348,7 @@ operator<<(std::ostream& out, constructor_eo const& x)
) )
<< tab(1) << tab(1)
<< "explicit " << x._cls.name << "(std::nullptr_t)" << endl << "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; << tab(1) << "{}" << endl << endl;
return out; return out;
} }
@ -355,7 +368,7 @@ operator<<(std::ostream& out, copy_constructor const& x)
out << comment(doc, 1) out << comment(doc, 1)
<< tab(1) << tab(1)
<< x._cls.name << "(" << x._cls.name << " const& other)" << endl << 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 << "(eo_ref(other._eo_ptr()))" << endl
<< tab(1) << "{}" << endl << endl; << tab(1) << "{}" << endl << endl;
return out; return out;
@ -427,7 +440,7 @@ operator<<(std::ostream& out, function_call_constructor_methods const& x)
} }
assert(cb_idx == cb_count); assert(cb_idx == cb_count);
out << "efl::eo::parent_type _p)" << endl out << "::efl::eo::parent_type _p)" << endl
<< tab(1) << "{" << endl << tab(1) << "{" << endl
<< tab(2) << "Eo* _ret_eo = eo_add_ref(" << x._cls.eo_name << ", _p._eo_raw, "; << tab(2) << "Eo* _ret_eo = eo_add_ref(" << x._cls.eo_name << ", _p._eo_raw, ";
for (it = first; it != last; ++it) for (it = first; it != last; ++it)
@ -449,7 +462,7 @@ operator<<(std::ostream& out, function_call_constructor_methods const& x)
d.out << tab(2) d.out << tab(2)
<< "eo_do(_ret_eo," << endl << "eo_do(_ret_eo," << endl
<< tab(3) << "eo_event_callback_add(EO_EV_DEL, " << 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) << ">, _c" << (it-first) << "." << callback_tmp(d.name)
<< "));" << endl; << "));" << endl;
}) })

View File

@ -4,7 +4,7 @@
#include <iosfwd> #include <iosfwd>
#include "eo_types.hh" #include "type_generator.hh"
#include "tab.hh" #include "tab.hh"
#include "comment.hh" #include "comment.hh"
@ -50,14 +50,14 @@ operator<<(std::ostream& out, event_callback_add const& x)
<< tab(1) << "{" << endl << tab(1) << "{" << endl
<< tab(2) << "typedef typename std::remove_reference<F>::type function_type;" << 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) << "::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 << tab(2) << "eo_do(" << add_cast_to_t(x._add_cast_to_t) << "_concrete_eo_ptr()," << endl
<< tab(4) << "eo_event_callback_priority_add" << endl << tab(4) << "eo_event_callback_priority_add" << endl
<< tab(4) << "(" << x._event.eo_name << ", priority_," << endl << tab(4) << "(" << x._event.eo_name << ", priority_," << endl
<< tab(4) << "&efl::eo::_detail::event_callback<" << x._cls.name_space << "::" << x._cls.name << ", function_type>, f.get()));" << endl << tab(4) << "&::efl::eo::_detail::event_callback<" << full_name(x._cls) << ", function_type>, f.get()));" << endl
<< tab(2) << "return ::efl::eo::make_signal_connection" << endl << tab(2) << "return ::efl::eo::make_signal_connection" << endl
<< tab(3) << "(f, " << add_cast_to_t(x._add_cast_to_t) << tab(3) << "(f, " << add_cast_to_t(x._add_cast_to_t)
<< "_eo_ptr(), &efl::eo::_detail::event_callback<" << "_concrete_eo_ptr(), &::efl::eo::_detail::event_callback<"
<< x._cls.name_space << "::" << x._cls.name << ", function_type>," << endl << full_name(x._cls) << ", function_type>," << endl
<< tab(3) << x._event.eo_name << " );" << endl << tab(3) << x._event.eo_name << " );" << endl
<< tab(1) << "}" << endl; << tab(1) << "}" << endl;
return out; return out;
@ -79,7 +79,7 @@ operator<<(std::ostream& out, event_callback_call const& x)
<< tab(1) << "void" << endl << tab(1) << "void" << endl
<< tab(1) << "callback_" << x._event.name << "_call(T* info)" << endl << tab(1) << "callback_" << x._event.name << "_call(T* info)" << endl
<< tab(1) << "{" << endl << tab(1) << "{" << endl
<< tab(2) << "eo_do(" << add_cast_to_t(x._add_cast_to_t) << "_eo_ptr(), eo_event_callback_call" << endl << tab(2) << "eo_do(" << add_cast_to_t(x._add_cast_to_t) << "_concrete_eo_ptr(), eo_event_callback_call" << endl
<< tab(4) << "(" << x._event.eo_name << ", info));" << endl << tab(4) << "(" << x._event.eo_name << ", info));" << endl
<< tab(1) << "}" << endl; << tab(1) << "}" << endl;
return out; return out;
@ -101,6 +101,7 @@ operator<<(std::ostream& out, events const& x)
out << event_callback_add(e, x._cls, x._add_cast_to_t) << endl out << event_callback_add(e, x._cls, x._add_cast_to_t) << endl
<< event_callback_call(e, x._add_cast_to_t); << event_callback_call(e, x._add_cast_to_t);
} }
out << endl;
return out; return out;
} }

View File

@ -9,6 +9,7 @@
#include "comment.hh" #include "comment.hh"
#include "parameters_generator.hh" #include "parameters_generator.hh"
#include "type_generator.hh" #include "type_generator.hh"
#include "namespace_generator.hh"
namespace efl { namespace eolian { namespace grammar { namespace efl { namespace eolian { namespace grammar {
@ -27,60 +28,110 @@ operator<<(std::ostream& out, function_call const& x)
<< "(" << parameters_forward_to_c(x._func.params) << ")"; << "(" << parameters_forward_to_c(x._func.params) << ")";
} }
struct function struct function_declaration
{ {
eo_class const& _cls;
eo_function const& _func; eo_function const& _func;
function(eo_function const& func) : _func(func) {} function_declaration(eo_class const& cls, eo_function const& func)
: _cls(cls), _func(func)
{}
}; };
inline std::ostream& inline std::ostream&
operator<<(std::ostream& out, function const& x) operator<<(std::ostream& out, function_declaration const& x)
{ {
eo_function const& func = x._func; eo_function const& func = x._func;
out << comment(x._func.comment, 1); out << comment(x._func.comment, 1)
out << template_parameters_declaration(func.params, 1); << template_parameters_declaration(func.params, 1)
<< tab(1);
if (function_is_static(func)) bool is_static = function_is_static(func);
out << tab(1) << "static "; if (is_static)
out << "static ";
out << tab(1) out << reinterpret_type(func.ret) << " " << func.name << "("
<< reinterpret_type(func.ret) << " " << func.name << "("
<< parameters_declaration(func.params) << parameters_declaration(func.params)
<< ") const" << endl << (is_static ? ");" : ") const;") << endl << endl;
<< tab(1) << "{" << endl;
if (!function_is_void(func))
out << tab(2)
<< func.ret.front().native << " _tmp_ret;" << endl;
out << callbacks_heap_alloc("_eo_ptr()", func.params, 2);
out << tab(2)
<< "eo_do(_eo_ptr(), " << function_call(x._func) << ");" << endl;
if (!function_is_void(func))
out << tab(2) << "return " << to_cxx(func.ret, "_tmp_ret") << ";" << endl;
out << tab(1) << "}" << endl;
return out; return out;
} }
struct functions struct function_definition
{ {
functions_container_type const& _funcs; eo_class const& _cls;
functions(functions_container_type const& funcs) : _funcs(funcs) {} eo_function const& _func;
function_definition(eo_class const& cls, eo_function const& func)
: _cls(cls), _func(func)
{}
}; };
inline std::ostream& inline std::ostream&
operator<<(std::ostream& out, functions const& x) operator<<(std::ostream& out, function_definition const& x)
{ {
functions_container_type::const_iterator it, eo_function const& func = x._func;
first = x._funcs.begin(),
last = x._funcs.end(); bool is_static = function_is_static(func);
for (it = first; it != last; it++)
out << template_parameters_declaration(func.params, 0)
<< "inline " << reinterpret_type(func.ret) << " "
<< abstract_full_name(x._cls, false) << "::" << func.name << "("
<< parameters_declaration(func.params)
<< (is_static ? ")" : ") const") << endl
<< "{" << endl;
if (!function_is_void(func))
out << tab(1)
<< func.ret.front().native << " _tmp_ret;" << endl;
if (!is_static)
out << callbacks_heap_alloc("_concrete_eo_ptr()", func.params, 1);
// TODO : register free callback for static methods
out << tab(1) << "eo_do("
<< (is_static ? "_eo_class(), " : "_concrete_eo_ptr(), ")
<< function_call(x._func) << ");" << endl;
if (!function_is_void(func))
out << tab(1) << "return " << to_cxx(func.ret, "_tmp_ret") << ";" << endl;
out << "}" << endl << endl;
return out;
}
struct function_declarations
{
eo_class const& _cls;
function_declarations(eo_class const& cls)
: _cls(cls)
{}
};
inline std::ostream&
operator<<(std::ostream& out, function_declarations const& x)
{
for (eo_function const& f : x._cls.functions)
{ {
out << function(*it) << endl; out << function_declaration(x._cls, f) << endl;
}
return out;
}
struct function_definitions
{
eo_class const& _cls;
function_definitions(eo_class const& cls)
: _cls(cls)
{}
};
inline std::ostream&
operator<<(std::ostream& out, function_definitions const& x)
{
for (eo_function const& f : x._cls.functions)
{
out << function_definition(x._cls, f) << endl;
} }
return out; return out;
} }

View File

@ -8,6 +8,7 @@
#include "eo_types.hh" #include "eo_types.hh"
#include "tab.hh" #include "tab.hh"
#include "comment.hh" #include "comment.hh"
#include "namespace_generator.hh"
#include "eo_class_constructors_generator.hh" #include "eo_class_constructors_generator.hh"
#include "eo_class_functions_generator.hh" #include "eo_class_functions_generator.hh"
#include "eo_class_events_generator.hh" #include "eo_class_events_generator.hh"
@ -30,28 +31,112 @@ operator<<(std::ostream& out, eo_class_getter const& x)
return out; return out;
} }
struct concrete_eo_ptr_getter
{
eo_class const& _cls;
concrete_eo_ptr_getter(eo_class const& cls) : _cls(cls) {}
};
inline std::ostream&
operator<<(std::ostream& out, concrete_eo_ptr_getter const&)
{
out << tab(1) << "Eo* _concrete_eo_ptr() const" << endl
<< tab(1) << "{" << endl
<< tab(2) << "return static_cast<::efl::eo::concrete const*>(static_cast<void const*>(this))->_eo_ptr();" << endl
<< tab(1) << "}" << endl << endl;
return out;
}
struct class_implicit_conversion_declaration
{
eo_class const& _cls;
class_implicit_conversion_declaration(eo_class const& cls) : _cls(cls) {}
};
inline std::ostream&
operator<<(std::ostream& out, class_implicit_conversion_declaration const& x)
{
out << tab(1) << "operator " << full_name(x._cls) << "() const;" << endl;
out << tab(1) << "operator " << full_name(x._cls) << "&();" << endl;
out << tab(1) << "operator " << full_name(x._cls) << " const&() const;" << endl;
return out << endl;
}
struct class_implicit_conversion_definition
{
eo_class const& _cls;
class_implicit_conversion_definition(eo_class const& cls) : _cls(cls) {}
};
inline std::ostream&
operator<<(std::ostream& out, class_implicit_conversion_definition const& x)
{
out << "inline " << abstract_full_name(x._cls) << "::operator "
<< full_name(x._cls) << "() const" << endl
<< "{" << endl
<< tab(1) << "return *static_cast<" << full_name(x._cls)
<< " const*>(static_cast<void const*>(this));" << endl
<< "}" << endl << endl;
out << "inline " << abstract_full_name(x._cls) << "::operator "
<< full_name(x._cls) << "&()" << endl
<< "{" << endl
<< tab(1) << "return *static_cast<" << full_name(x._cls)
<< "*>(static_cast<void*>(this));" << endl
<< "}" << endl << endl;
out << "inline " << abstract_full_name(x._cls) << "::operator "
<< full_name(x._cls) << " const&() const" << endl
<< "{" << endl
<< tab(1) << "return *static_cast<" << full_name(x._cls)
<< " const*>(static_cast<void const*>(this));" << endl
<< "}" << endl << endl;
return out;
}
inline void inline void
eo_class_generator(std::ostream& out, eo_class const& cls) eo_class_generator(std::ostream& out, eo_class const& cls)
{ {
out << comment(cls.comment) out << namespace_head(cls)
<< "struct " << cls.name << ";" << endl << endl
<< namespace_tail(cls)
<< "namespace " << abstract_namespace << " {" << endl << endl
<< namespace_head(cls)
<< comment(cls.comment)
<< "struct " << cls.name << endl << "struct " << cls.name << endl
<< tab(2) << ": " << class_inheritance(cls) << class_inheritance(cls)
<< '{' << endl << '{' << endl
<< functors_constructor_methods(cls) << functors_constructor_methods(cls)
<< functions_constructor_methods(cls) << constructor_method_function_declarations(cls)
<< function_declarations(cls)
<< events(cls)
<< eo_class_getter(cls)
<< class_implicit_conversion_declaration(cls)
<< "private:" << endl
<< concrete_eo_ptr_getter(cls)
<< "};" << endl << endl
<< namespace_tail(cls)
<< "}" << endl << endl
<< namespace_head(cls)
<< "struct " << cls.name << endl
<< tab(2) << ": " << abstract_full_name(cls) << endl
<< tab(2) << ", ::efl::eo::concrete" << endl
<< '{' << endl
<< constructor_with_constructor_methods(cls) << constructor_with_constructor_methods(cls)
<< constructor_eo(cls) << constructor_eo(cls)
<< copy_constructor(cls) << copy_constructor(cls)
<< destructor(cls) << destructor(cls)
<< functions(cls.functions)
<< events(cls)
<< eo_class_getter(cls)
<< "private:" << endl << "private:" << endl
<< function_call_constructor_methods(cls) << function_call_constructor_methods(cls)
<< "};" << endl << "};" << endl << endl
<< "static_assert(sizeof(" << cls.name << ") == sizeof(Eo*), \"sizeof(" << cls.name << ") != sizeof(Eo*)\");" << endl << "static_assert(sizeof(" << full_name(cls) << ") == sizeof(Eo*), \"\");" << endl
<< "static_assert(std::is_standard_layout<" << cls.name << ">::value, \"'" << cls.name << "' is not standard layout\");" << "static_assert(std::is_standard_layout<" << full_name(cls) << ">::value, \"\");" << endl
<< endl << endl; << endl
<< namespace_tail(cls)
<< constructor_method_function_definitions(cls)
<< function_definitions(cls)
<< class_implicit_conversion_definition(cls);
} }
} } } // namespace efl { namespace eolian { namespace grammar { } } } // namespace efl { namespace eolian { namespace grammar {

View File

@ -56,7 +56,7 @@ operator<<(std::ostream& out, include_dependencies const& x)
it != last; ++it) it != last; ++it)
for (auto it_p = (*it).params.begin(), last_p = (*it).params.end(); for (auto it_p = (*it).params.begin(), last_p = (*it).params.end();
it_p != last_p; ++it_p) it_p != last_p; ++it_p)
for (eolian_type const& subtype : (*it_p).type) for (eolian_type const& subtype : (*it_p).type.parts)
for (std::string header : subtype.includes) for (std::string header : subtype.includes)
headers.insert(header); headers.insert(header);
@ -64,7 +64,7 @@ operator<<(std::ostream& out, include_dependencies const& x)
it != last; ++it) it != last; ++it)
for (auto it_p = (*it).params.begin(), last_p = (*it).params.end(); for (auto it_p = (*it).params.begin(), last_p = (*it).params.end();
it_p != last_p; ++it_p) it_p != last_p; ++it_p)
for (eolian_type const& subtype : (*it_p).type) for (eolian_type const& subtype : (*it_p).type.parts)
for (std::string header : subtype.includes) for (std::string header : subtype.includes)
headers.insert(header); headers.insert(header);
@ -89,38 +89,6 @@ onceguard_tail(std::ostream& out, eo_class const& cls)
out << "#endif // EFL_GENERATED_" << key << "_HH" << endl; out << "#endif // EFL_GENERATED_" << key << "_HH" << endl;
} }
inline void
namespace_head(std::ostream& out, eo_class const& cls)
{
if (cls.name_space != "")
{
std::string ns = cls.name_space;
size_t pos = 0;
while ((pos = ns.find("::")) != std::string::npos)
{
out << "namespace " << ns.substr(0, pos) << " { ";
ns.erase(0, pos+2);
}
out << "namespace " << ns << " {" << endl << endl;
}
}
inline void
namespace_tail(std::ostream& out, eo_class const& cls)
{
if (cls.name_space != "")
{
std::string ns = cls.name_space;
size_t pos = 0;
while ((pos = ns.find("::")) != std::string::npos)
{
out << "} ";
ns.erase(0, pos+2);
}
out << "} " << endl << endl;
}
}
inline void inline void
include_headers(std::ostream& out, include_headers(std::ostream& out,
eo_class const& cls EINA_UNUSED, eo_class const& cls EINA_UNUSED,
@ -151,9 +119,7 @@ eo_header_generator(std::ostream& out, eo_class const& cls, eo_generator_options
{ {
onceguard_head(out, cls); onceguard_head(out, cls);
include_headers(out, cls, opts); include_headers(out, cls, opts);
namespace_head(out, cls);
eo_class_generator(out, cls); eo_class_generator(out, cls);
namespace_tail(out, cls);
eo_inheritance_detail_generator(out, cls); eo_inheritance_detail_generator(out, cls);
onceguard_tail(out, cls); onceguard_tail(out, cls);
out << endl; out << endl;

View File

@ -66,8 +66,8 @@ inline std::ostream&
operator<<(std::ostream& out, inheritance_operations_description const& x) operator<<(std::ostream& out, inheritance_operations_description const& x)
{ {
out << "template <typename T>" out << "template <typename T>"
<< endl << "int initialize_operation_description(efl::eo::detail::tag<" << endl << "int initialize_operation_description(::efl::eo::detail::tag<"
<< x._cls.name_space << "::" << x._cls.name << ">" << endl << full_name(x._cls) << ">" << endl
<< tab(11) << tab(11)
<< ", Eo_Op_Description* ops)" << endl << ", Eo_Op_Description* ops)" << endl
<< "{" << endl << "{" << endl
@ -103,7 +103,7 @@ operator<<(std::ostream& out, inheritance_wrappers const& x)
<< _ns_as_prefix(x._cls) << "_" << _ns_as_prefix(x._cls) << "_"
<< x._cls.name << "_" << func.name << x._cls.name << "_" << func.name
<< "_wrapper(Eo* objid EINA_UNUSED, " << "_wrapper(Eo* objid EINA_UNUSED, "
<< "efl::eo::detail::Inherit_Private_Data* self" << "::efl::eo::detail::Inherit_Private_Data* self"
<< (func.params.size() ? ", " : "") << (func.params.size() ? ", " : "")
<< parameters_c_declaration(func.params) << parameters_c_declaration(func.params)
<< ")" << endl << ")" << endl
@ -122,7 +122,7 @@ operator<<(std::ostream& out, inheritance_wrappers const& x)
<< tab(2) << "}" << endl << tab(2) << "}" << endl
<< tab(1) << "catch (...)" << endl << tab(1) << "catch (...)" << endl
<< tab(2) << "{" << endl << tab(2) << "{" << endl
<< tab(3) << "eina_error_set( efl::eina::unknown_error() );" << endl << tab(3) << "eina_error_set( ::efl::eina::unknown_error() );" << endl
<< tab(2) << "}" << endl; << tab(2) << "}" << endl;
if (!function_is_void(func)) if (!function_is_void(func))
@ -146,7 +146,7 @@ operator<<(std::ostream& out, inheritance_base_operations_size const& x)
{ {
out << "template<>" out << "template<>"
<< endl << "struct operation_description_class_size< " << endl << "struct operation_description_class_size< "
<< x._cls.name_space << "::" << x._cls.name << " >" << endl << full_name(x._cls) << " >" << endl
<< "{" << endl << "{" << endl
<< tab(1) << "static const int value = " << tab(1) << "static const int value = "
<< x._cls.functions.size() << x._cls.functions.size()
@ -209,7 +209,7 @@ operator<<(std::ostream& out, inheritance_base_operations const& x)
{ {
out << "template<>" << endl out << "template<>" << endl
<< "struct operations< " << "struct operations< "
<< x._cls.name_space << "::" << x._cls.name << " >" << endl << full_name(x._cls) << " >" << endl
<< "{" << endl << "{" << endl
<< tab(1) << "template <typename T>" << endl << tab(1) << "template <typename T>" << endl
<< tab(1) << "struct type" << endl << tab(1) << "struct type" << endl
@ -263,10 +263,10 @@ operator<<(std::ostream& out, inheritance_call_constructors const& x)
eo_constructor const& ctor = *it; eo_constructor const& ctor = *it;
out << "inline void" << endl out << "inline void" << endl
<< "call_constructor(tag< " << "call_constructor(tag< "
<< x._cls.name_space << "::" << x._cls.name << " >" << endl << full_name(x._cls) << " >" << endl
<< tab(5) << ", Eo* eo, Eo_Class const* cls EINA_UNUSED," << endl << tab(5) << ", Eo* eo, Eo_Class const* cls EINA_UNUSED," << endl
<< tab(5) << "args_class<" << tab(5) << "args_class<"
<< x._cls.name_space << "::" << x._cls.name << full_name(x._cls)
<< ", ::std::tuple<" << ", ::std::tuple<"
<< parameters_types(ctor.params) << parameters_types(ctor.params)
<< "> > const& args)" << endl << "> > const& args)" << endl
@ -281,11 +281,11 @@ operator<<(std::ostream& out, inheritance_call_constructors const& x)
out << "inline void" << endl out << "inline void" << endl
<< "call_constructor(tag< " << "call_constructor(tag< "
<< x._cls.name_space << "::" << x._cls.name << " >" << endl << full_name(x._cls) << " >" << endl
<< tab(5) << ", Eo* eo, Eo_Class const* cls EINA_UNUSED," << endl << tab(5) << ", Eo* eo, Eo_Class const* cls EINA_UNUSED," << endl
<< tab(5) << "args_class<" << tab(5) << "args_class<"
<< x._cls.name_space << "::" << x._cls.name << full_name(x._cls)
<< ", ::std::tuple<efl::eo::parent_type> > const& args)" << endl << ", ::std::tuple<::efl::eo::parent_type> > const& args)" << endl
<< "{" << endl << "{" << endl
<< tab(1) << "eo_do_super(eo, cls, ::eo_constructor());" << endl << tab(1) << "eo_do_super(eo, cls, ::eo_constructor());" << endl
<< tab(1) << "eo_do(eo, ::eo_parent_set(args.get<0>()._eo_raw));" << endl << tab(1) << "eo_do(eo, ::eo_parent_set(args.get<0>()._eo_raw));" << endl
@ -341,7 +341,7 @@ struct inheritance_extension
inline std::ostream& inline std::ostream&
operator<<(std::ostream& out, inheritance_extension const& x) operator<<(std::ostream& out, inheritance_extension const& x)
{ {
std::string cls = x._cls.name_space + "::" + x._cls.name; full_name const cls(x._cls);
out << "template<>" << endl out << "template<>" << endl
<< "struct extension_inheritance< " << "struct extension_inheritance< "
<< cls << ">" << endl << cls << ">" << endl
@ -381,7 +381,7 @@ inline std::ostream&
operator<<(std::ostream& out, inheritance_eo_class_getter const& x) operator<<(std::ostream& out, inheritance_eo_class_getter const& x)
{ {
out << "inline Eo_Class const* get_eo_class(tag<" out << "inline Eo_Class const* get_eo_class(tag<"
<< x._cls.name_space << "::" << x._cls.name << ">)" << endl << full_name(x._cls) << ">)" << endl
<< "{" << endl << "{" << endl
<< tab(1) << "return (" << x._cls.eo_name << ");" << endl << tab(1) << "return (" << x._cls.eo_name << ");" << endl
<< "}" << endl << endl; << "}" << endl << endl;

View File

@ -0,0 +1,68 @@
#ifndef EOLIAN_CXX_NAMESPACE_GENERATOR_HH
#define EOLIAN_CXX_NAMESPACE_GENERATOR_HH
#include "eo_types.hh"
#include "tab.hh"
namespace efl { namespace eolian { namespace grammar {
struct abstract_namespace_type {};
abstract_namespace_type const abstract_namespace = {};
inline std::ostream&
operator<<(std::ostream& out, abstract_namespace_type const&)
{
return out << "eo_cxx";
}
struct namespace_head
{
namespace_head(eo_class const& cls) : _cls(cls) {}
eo_class const& _cls;
};
inline std::ostream&
operator<<(std::ostream& out, namespace_head const& x)
{
if (x._cls.name_space != "")
{
std::string ns = x._cls.name_space;
size_t pos = 0;
while ((pos = ns.find("::")) != std::string::npos)
{
out << "namespace " << ns.substr(0, pos) << " { ";
ns.erase(0, pos+2);
}
out << "namespace " << ns << " {" << endl << endl;
}
return out;
}
struct namespace_tail
{
namespace_tail(eo_class const& cls) : _cls(cls) {}
eo_class const& _cls;
};
inline std::ostream&
operator<<(std::ostream& out, namespace_tail const& x)
{
if (x._cls.name_space != "")
{
std::string ns = x._cls.name_space;
size_t pos = 0;
while ((pos = ns.find("::")) != std::string::npos)
{
out << "} ";
ns.erase(0, pos+2);
}
out << "}" << endl << endl;
}
return out;
}
} } } // namespace efl { namespace eolian { namespace grammar {
#endif

View File

@ -146,7 +146,7 @@ inline std::ostream&
operator<<(std::ostream& out, callback_parameter_free_ev_add const& x) operator<<(std::ostream& out, callback_parameter_free_ev_add const& x)
{ {
out << "eo_do(" << x._eo_raw_expr out << "eo_do(" << x._eo_raw_expr
<< ", eo_event_callback_add(EO_EV_DEL, &efl::eolian::free_callback_calback<" << ", eo_event_callback_add(EO_EV_DEL, &::efl::eolian::free_callback_calback<"
<< parameter_no_ref_type(x._type, x._name) << ">, " << parameter_no_ref_type(x._type, x._name) << ">, "
<< callback_tmp(x._name) << "));"; << callback_tmp(x._name) << "));";
return out; return out;

View File

@ -6,11 +6,42 @@
#include <iosfwd> #include <iosfwd>
#include "eo_types.hh" #include "eo_types.hh"
#include "namespace_generator.hh"
namespace efl { namespace eolian { namespace grammar { namespace efl { namespace eolian { namespace grammar {
using std::endl; using std::endl;
struct full_name
{
eo_class const& _cls;
full_name(eo_class const& cls) : _cls(cls) {}
};
inline std::ostream&
operator<<(std::ostream& out, full_name const& x)
{
if(!x._cls.name_space.empty())
out << "::" << x._cls.name_space;
return out << "::" << x._cls.name;
}
struct abstract_full_name
{
eo_class const& _cls;
bool _from_golbal;
abstract_full_name(eo_class const& cls, bool from_golbal = true)
: _cls(cls), _from_golbal(from_golbal) {}
};
inline std::ostream&
operator<<(std::ostream& out, abstract_full_name const& x)
{
if (x._from_golbal)
out << "::";
return out << abstract_namespace << full_name(x._cls);
}
struct c_type struct c_type
{ {
eolian_type_instance const& _list; eolian_type_instance const& _list;
@ -24,7 +55,7 @@ operator<<(std::ostream& out, efl::eolian::grammar::c_type const& x)
{ {
assert(x._list.size() > 0); assert(x._list.size() > 0);
std::string res; std::string res;
for (auto rit = x._list.rbegin(), last = x._list.rend(); rit != last; ++rit) for (auto rit = x._list.parts.rbegin(), last = x._list.parts.rend(); rit != last; ++rit)
{ {
res = /*type_is_binding(*rit) ? (*rit).binding :*/ (*rit).native; res = /*type_is_binding(*rit) ? (*rit).binding :*/ (*rit).native;
} }
@ -34,27 +65,31 @@ operator<<(std::ostream& out, efl::eolian::grammar::c_type const& x)
struct reinterpret_type struct reinterpret_type
{ {
eolian_type_instance const& _list; eolian_type_instance const& _type;
reinterpret_type(eolian_type_instance const& list) reinterpret_type(eolian_type_instance const& type)
: _list(list) : _type(type)
{} {}
}; };
inline std::ostream& inline std::ostream&
operator<<(std::ostream& out, efl::eolian::grammar::reinterpret_type const& x) operator<<(std::ostream& out, efl::eolian::grammar::reinterpret_type const& x)
{ {
assert(x._list.size() > 0); assert(x._type.size() > 0);
std::string res; std::string res;
for (auto rit = x._list.rbegin(), last = x._list.rend(); rit != last; ++rit) for (auto rit = x._type.parts.rbegin(), last = x._type.parts.rend(); rit != last; ++rit)
{ {
eolian_type const& t = *rit; eolian_type const& t = *rit;
if (type_is_complex(t)) if (type_is_complex(t))
res = t.binding + "< " + res + " >" + (t.is_out ? "*" : ""); res = t.binding + "< " + res + " >";
else else
res = type_is_binding(t) ? t.binding + (t.is_out ? "*" : "") res = type_is_binding(t) ? t.binding
: t.native; : t.native;
} }
assert(!res.empty()); assert(!res.empty());
if (x._type.is_out && type_is_binding(x._type.front()))
res += "*";
return out << res; return out << res;
} }
@ -70,9 +105,9 @@ inline std::ostream&
operator<<(std::ostream& out, type_ownership const& x) operator<<(std::ostream& out, type_ownership const& x)
{ {
out << "std::tuple<"; out << "std::tuple<";
for (auto it=x._type.begin(), last=x._type.end(); it != last; ++it) for (auto it=x._type.parts.begin(), last=x._type.parts.end(); it != last; ++it)
{ {
if (it != x._type.begin()) if (it != x._type.parts.begin())
out << ", "; out << ", ";
out << ((*it).is_own ? "std::true_type" : "std::false_type"); out << ((*it).is_own ? "std::true_type" : "std::false_type");
} }
@ -168,7 +203,7 @@ operator<<(std::ostream& out, to_cxx const& x)
{ {
if (type_is_binding(x._type)) if (type_is_binding(x._type))
{ {
out << "efl::eolian::to_cxx<" out << "::efl::eolian::to_cxx<"
<< reinterpret_type(x._type) << reinterpret_type(x._type)
<< ">(" << x._varname << ">(" << x._varname
<< ", " << type_ownership(x._type) << ")"; << ", " << type_ownership(x._type) << ")";
@ -191,12 +226,12 @@ inline std::ostream&
operator<<(std::ostream& out, to_c const& x) operator<<(std::ostream& out, to_c const& x)
{ {
if (type_is_callback(x._type)) if (type_is_callback(x._type))
out << "efl::eolian::get_callback<" << type_to_native_str(x._type) out << "::efl::eolian::get_callback<" << type_to_native_str(x._type)
<< ", " << parameter_no_ref_type(x._type, x._varname) << " >()"; << ", " << parameter_no_ref_type(x._type, x._varname) << " >()";
else if (type_is_complex(x._type) && type_is_binding(x._type)) else if (type_is_complex(x._type) && type_is_binding(x._type))
out << "efl::eolian::to_native<" << c_type(x._type) << ">(" << x._varname << ")"; out << "::efl::eolian::to_native<" << c_type(x._type) << ">(" << x._varname << ")";
else if (type_is_binding(x._type)) else if (type_is_binding(x._type))
out << "efl::eolian::to_c(" << x._varname << ")"; out << "::efl::eolian::to_c(" << x._varname << ")";
else else
out << x._varname; out << x._varname;
return out; return out;

View File

@ -14,10 +14,10 @@
const Eo_Class *simple_class_get(void); const Eo_Class *simple_class_get(void);
#define MY_CLASS simple_class_get() #define MY_CLASS simple_class_get()
struct wrapper : efl::eo::base struct wrapper : efl::eo::concrete
{ {
explicit wrapper(Eo* o) explicit wrapper(Eo* o)
: base(o) {} : concrete(o) {}
}; };
START_TEST(eina_cxx_accessor_indexing) START_TEST(eina_cxx_accessor_indexing)

View File

@ -15,10 +15,10 @@
const Eo_Class *simple_class_get(void); const Eo_Class *simple_class_get(void);
#define MY_CLASS simple_class_get() #define MY_CLASS simple_class_get()
struct wrapper : efl::eo::base struct wrapper : efl::eo::concrete
{ {
explicit wrapper(Eo* o) explicit wrapper(Eo* o)
: base(o) {} : concrete(o) {}
}; };
START_TEST(eina_cxx_ptrarray_push_back) START_TEST(eina_cxx_ptrarray_push_back)

View File

@ -47,10 +47,10 @@ static const Eo_Class_Description class_desc = {
EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_CLASS, NULL); EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_CLASS, NULL);
struct wrapper : efl::eo::base struct wrapper : efl::eo::concrete
{ {
explicit wrapper(Eo* o) explicit wrapper(Eo* o)
: base(o) {} : concrete(o) {}
}; };
START_TEST(eina_cxx_ptrlist_push_back) START_TEST(eina_cxx_ptrlist_push_back)

View File

@ -16,7 +16,7 @@ START_TEST(eolian_cxx_test_wrapper_size)
{ {
efl::eo::eo_init init; efl::eo::eo_init init;
::efl::eo::base b(nullptr); ::efl::eo::concrete b(nullptr);
::callback c; ::callback c;
fail_if(sizeof(b) != sizeof(Eo*)); fail_if(sizeof(b) != sizeof(Eo*));