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_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 \

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

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_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 \

View File

@ -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
{
// 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_free(inheritances);
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 (cls.parents.empty())
return;
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);
}
@ -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

View File

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

View File

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

View File

@ -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)};
}

View File

@ -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"}},
};
}

View File

@ -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. */

View File

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

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

View File

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

View File

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

View File

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

View File

@ -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)};

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

View File

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

View File

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

View File

@ -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;
})

View File

@ -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
<< 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) << "(" << 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(3) << "(f, " << add_cast_to_t(x._add_cast_to_t)
<< "_eo_ptr(), &efl::eo::_detail::event_callback<"
<< x._cls.name_space << "::" << x._cls.name << ", function_type>," << endl
<< "_concrete_eo_ptr(), &::efl::eo::_detail::event_callback<"
<< full_name(x._cls) << ", function_type>," << endl
<< tab(3) << x._event.eo_name << " );" << endl
<< tab(1) << "}" << endl;
return out;
@ -79,7 +79,7 @@ operator<<(std::ostream& out, event_callback_call const& x)
<< tab(1) << "void" << endl
<< tab(1) << "callback_" << x._event.name << "_call(T* info)" << 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(1) << "}" << endl;
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
<< event_callback_call(e, x._add_cast_to_t);
}
out << endl;
return out;
}

View File

@ -9,6 +9,7 @@
#include "comment.hh"
#include "parameters_generator.hh"
#include "type_generator.hh"
#include "namespace_generator.hh"
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) << ")";
}
struct function
struct function_declaration
{
eo_class const& _cls;
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&
operator<<(std::ostream& out, function const& x)
operator<<(std::ostream& out, function_declaration const& x)
{
eo_function const& func = x._func;
out << comment(x._func.comment, 1);
out << template_parameters_declaration(func.params, 1);
out << comment(x._func.comment, 1)
<< template_parameters_declaration(func.params, 1)
<< tab(1);
if (function_is_static(func))
out << tab(1) << "static ";
bool is_static = function_is_static(func);
if (is_static)
out << "static ";
out << tab(1)
<< reinterpret_type(func.ret) << " " << func.name << "("
out << reinterpret_type(func.ret) << " " << func.name << "("
<< parameters_declaration(func.params)
<< ") const" << endl
<< tab(1) << "{" << endl;
<< (is_static ? ");" : ") const;") << endl << 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;
}
struct functions
struct function_definition
{
functions_container_type const& _funcs;
functions(functions_container_type const& funcs) : _funcs(funcs) {}
eo_class const& _cls;
eo_function const& _func;
function_definition(eo_class const& cls, eo_function const& func)
: _cls(cls), _func(func)
{}
};
inline std::ostream&
operator<<(std::ostream& out, functions const& x)
operator<<(std::ostream& out, function_definition const& x)
{
functions_container_type::const_iterator it,
first = x._funcs.begin(),
last = x._funcs.end();
for (it = first; it != last; it++)
eo_function const& func = x._func;
bool is_static = function_is_static(func);
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;
}

View File

@ -8,6 +8,7 @@
#include "eo_types.hh"
#include "tab.hh"
#include "comment.hh"
#include "namespace_generator.hh"
#include "eo_class_constructors_generator.hh"
#include "eo_class_functions_generator.hh"
#include "eo_class_events_generator.hh"
@ -30,28 +31,112 @@ operator<<(std::ostream& out, eo_class_getter const& x)
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
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
<< tab(2) << ": " << class_inheritance(cls)
<< class_inheritance(cls)
<< '{' << endl
<< 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_eo(cls)
<< copy_constructor(cls)
<< destructor(cls)
<< functions(cls.functions)
<< events(cls)
<< eo_class_getter(cls)
<< "private:" << endl
<< function_call_constructor_methods(cls)
<< "};" << endl
<< "static_assert(sizeof(" << cls.name << ") == sizeof(Eo*), \"sizeof(" << cls.name << ") != sizeof(Eo*)\");" << endl
<< "static_assert(std::is_standard_layout<" << cls.name << ">::value, \"'" << cls.name << "' is not standard layout\");"
<< endl << endl;
<< "};" << endl << endl
<< "static_assert(sizeof(" << full_name(cls) << ") == sizeof(Eo*), \"\");" << endl
<< "static_assert(std::is_standard_layout<" << full_name(cls) << ">::value, \"\");" << endl
<< endl
<< namespace_tail(cls)
<< constructor_method_function_definitions(cls)
<< function_definitions(cls)
<< class_implicit_conversion_definition(cls);
}
} } } // namespace efl { namespace eolian { namespace grammar {

View File

@ -56,7 +56,7 @@ operator<<(std::ostream& out, include_dependencies const& x)
it != last; ++it)
for (auto it_p = (*it).params.begin(), last_p = (*it).params.end();
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)
headers.insert(header);
@ -64,7 +64,7 @@ operator<<(std::ostream& out, include_dependencies const& x)
it != last; ++it)
for (auto it_p = (*it).params.begin(), last_p = (*it).params.end();
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)
headers.insert(header);
@ -89,38 +89,6 @@ onceguard_tail(std::ostream& out, eo_class const& cls)
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
include_headers(std::ostream& out,
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);
include_headers(out, cls, opts);
namespace_head(out, cls);
eo_class_generator(out, cls);
namespace_tail(out, cls);
eo_inheritance_detail_generator(out, cls);
onceguard_tail(out, cls);
out << endl;

View File

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

View File

@ -6,11 +6,42 @@
#include <iosfwd>
#include "eo_types.hh"
#include "namespace_generator.hh"
namespace efl { namespace eolian { namespace grammar {
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
{
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);
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;
}
@ -34,27 +65,31 @@ operator<<(std::ostream& out, efl::eolian::grammar::c_type const& x)
struct reinterpret_type
{
eolian_type_instance const& _list;
reinterpret_type(eolian_type_instance const& list)
: _list(list)
eolian_type_instance const& _type;
reinterpret_type(eolian_type_instance const& type)
: _type(type)
{}
};
inline std::ostream&
operator<<(std::ostream& out, efl::eolian::grammar::reinterpret_type const& x)
{
assert(x._list.size() > 0);
assert(x._type.size() > 0);
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;
if (type_is_complex(t))
res = t.binding + "< " + res + " >" + (t.is_out ? "*" : "");
res = t.binding + "< " + res + " >";
else
res = type_is_binding(t) ? t.binding + (t.is_out ? "*" : "")
res = type_is_binding(t) ? t.binding
: t.native;
}
assert(!res.empty());
if (x._type.is_out && type_is_binding(x._type.front()))
res += "*";
return out << res;
}
@ -70,9 +105,9 @@ inline std::ostream&
operator<<(std::ostream& out, type_ownership const& x)
{
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 << ((*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))
{
out << "efl::eolian::to_cxx<"
out << "::efl::eolian::to_cxx<"
<< reinterpret_type(x._type)
<< ">(" << x._varname
<< ", " << type_ownership(x._type) << ")";
@ -191,12 +226,12 @@ inline std::ostream&
operator<<(std::ostream& out, to_c const& x)
{
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) << " >()";
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))
out << "efl::eolian::to_c(" << x._varname << ")";
out << "::efl::eolian::to_c(" << x._varname << ")";
else
out << x._varname;
return out;

View File

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

View File

@ -15,10 +15,10 @@
const Eo_Class *simple_class_get(void);
#define MY_CLASS simple_class_get()
struct wrapper : efl::eo::base
struct wrapper : efl::eo::concrete
{
explicit wrapper(Eo* o)
: base(o) {}
: concrete(o) {}
};
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);
struct wrapper : efl::eo::base
struct wrapper : efl::eo::concrete
{
explicit wrapper(Eo* o)
: base(o) {}
: concrete(o) {}
};
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::base b(nullptr);
::efl::eo::concrete b(nullptr);
::callback c;
fail_if(sizeof(b) != sizeof(Eo*));