forked from enlightenment/efl
eolian-cxx: Rewrite to accomodate new features of the C++ binding
This commit is contained in:
parent
4d1b3191d9
commit
2a3d7860db
|
@ -7,15 +7,15 @@ installed_eocxxheadersdir = $(includedir)/eo-cxx-@VMAJ@/
|
|||
nodist_installed_eocxxheaders_DATA = $(eo_eolian_cxx_hh) $(eo_eolian_cxx_impl)
|
||||
dist_installed_eocxxheaders_DATA = \
|
||||
bindings/cxx/eo_cxx/eo_concrete.hh \
|
||||
bindings/cxx/eo_cxx/eo_event.hh \
|
||||
bindings/cxx/eo_cxx/eo_init.hh \
|
||||
bindings/cxx/eo_cxx/eo_wref.hh \
|
||||
bindings/cxx/eo_cxx/eo_inherit.hh \
|
||||
bindings/cxx/eo_cxx/eo_ops.hh \
|
||||
bindings/cxx/eo_cxx/eo_private.hh \
|
||||
bindings/cxx/eo_cxx/eo_inherit_bindings.hh \
|
||||
bindings/cxx/eo_cxx/eo_cxx_interop.hh \
|
||||
bindings/cxx/eo_cxx/Eo.hh
|
||||
bindings/cxx/eo_cxx/eo_event.hh \
|
||||
bindings/cxx/eo_cxx/Eo.hh \
|
||||
bindings/cxx/eo_cxx/eo_inherit.hh \
|
||||
bindings/cxx/eo_cxx/eo_inherit_bindings.hh \
|
||||
bindings/cxx/eo_cxx/eo_init.hh \
|
||||
bindings/cxx/eo_cxx/eo_ops.hh \
|
||||
bindings/cxx/eo_cxx/eo_wref.hh \
|
||||
bindings/cxx/eo_cxx/eo_private.hh
|
||||
|
||||
### Elementary C++
|
||||
installed_elementarycxxmainheadersdir = $(includedir)/elementary-cxx-@VMAJ@/
|
||||
|
@ -138,6 +138,7 @@ bindings/cxx/eina_cxx/eina_accessor.hh \
|
|||
bindings/cxx/eina_cxx/eina_array.hh \
|
||||
bindings/cxx/eina_cxx/eina_clone_allocators.hh \
|
||||
bindings/cxx/eina_cxx/eina_error.hh \
|
||||
bindings/cxx/eina_cxx/eina_future.hh \
|
||||
bindings/cxx/eina_cxx/eina_eo_concrete_fwd.hh \
|
||||
bindings/cxx/eina_cxx/eina_fold.hh \
|
||||
bindings/cxx/eina_cxx/eina_function.hh \
|
||||
|
|
|
@ -6,40 +6,53 @@ installed_eoliancxxmainheadersdir = $(includedir)/eolian-cxx-@VMAJ@/
|
|||
dist_installed_eoliancxxmainheaders_DATA = \
|
||||
lib/eolian_cxx/Eolian_Cxx.hh
|
||||
|
||||
installed_eoliancxxheadersdir = $(includedir)/eolian-cxx-@VMAJ@/
|
||||
dist_installed_eoliancxxheaders_DATA = \
|
||||
lib/eolian_cxx/eo_generate.hh \
|
||||
lib/eolian_cxx/eo_types.hh \
|
||||
lib/eolian_cxx/eo_validate.hh
|
||||
|
||||
installed_eoliancxxgrammarheadersdir = $(includedir)/eolian-cxx-@VMAJ@/grammar/
|
||||
dist_installed_eoliancxxgrammarheaders_DATA = \
|
||||
lib/eolian_cxx/grammar/comment.hh \
|
||||
lib/eolian_cxx/grammar/eo_class_scope_guard_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_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 \
|
||||
lib/eolian_cxx/grammar/parameters_generator.hh \
|
||||
lib/eolian_cxx/grammar/type_generator.hh \
|
||||
lib/eolian_cxx/grammar/tab.hh
|
||||
lib/eolian_cxx/grammar/address_of.hpp \
|
||||
lib/eolian_cxx/grammar/alternative.hpp \
|
||||
lib/eolian_cxx/grammar/attribute_conditional.hpp \
|
||||
lib/eolian_cxx/grammar/attribute_reorder.hpp \
|
||||
lib/eolian_cxx/grammar/attribute_replace.hpp \
|
||||
lib/eolian_cxx/grammar/attributes.hpp \
|
||||
lib/eolian_cxx/grammar/base_class_definition.hpp \
|
||||
lib/eolian_cxx/grammar/case.hpp \
|
||||
lib/eolian_cxx/grammar/class_declaration.hpp \
|
||||
lib/eolian_cxx/grammar/class_definition.hpp \
|
||||
lib/eolian_cxx/grammar/class_implementation.hpp \
|
||||
lib/eolian_cxx/grammar/container.hpp \
|
||||
lib/eolian_cxx/grammar/context.hpp \
|
||||
lib/eolian_cxx/grammar/converting_argument.hpp \
|
||||
lib/eolian_cxx/grammar/c_type.hpp \
|
||||
lib/eolian_cxx/grammar/eps.hpp \
|
||||
lib/eolian_cxx/grammar/function_declaration.hpp \
|
||||
lib/eolian_cxx/grammar/function_definition.hpp \
|
||||
lib/eolian_cxx/grammar/generator.hpp \
|
||||
lib/eolian_cxx/grammar/header_guards.hpp \
|
||||
lib/eolian_cxx/grammar/header.hpp \
|
||||
lib/eolian_cxx/grammar/header_include_directive.hpp \
|
||||
lib/eolian_cxx/grammar/implementation_include_directive.hpp \
|
||||
lib/eolian_cxx/grammar/impl_header.hpp \
|
||||
lib/eolian_cxx/grammar/indentation.hpp \
|
||||
lib/eolian_cxx/grammar/keyword.hpp \
|
||||
lib/eolian_cxx/grammar/klass_def.hpp \
|
||||
lib/eolian_cxx/grammar/kleene.hpp \
|
||||
lib/eolian_cxx/grammar/list.hpp \
|
||||
lib/eolian_cxx/grammar/meta.hpp \
|
||||
lib/eolian_cxx/grammar/namespace.hpp \
|
||||
lib/eolian_cxx/grammar/parameter.hpp \
|
||||
lib/eolian_cxx/grammar/qualifier_def.hpp \
|
||||
lib/eolian_cxx/grammar/sequence.hpp \
|
||||
lib/eolian_cxx/grammar/string.hpp \
|
||||
lib/eolian_cxx/grammar/type.hpp \
|
||||
lib/eolian_cxx/grammar/type_impl.hpp \
|
||||
lib/eolian_cxx/grammar/type_traits.hpp \
|
||||
lib/eolian_cxx/grammar/variant.hpp
|
||||
|
||||
### Binary
|
||||
|
||||
bin_PROGRAMS += bin/eolian_cxx/eolian_cxx
|
||||
|
||||
bin_eolian_cxx_eolian_cxx_SOURCES = \
|
||||
bin/eolian_cxx/convert_comments.cc \
|
||||
bin/eolian_cxx/convert_comments.hh \
|
||||
bin/eolian_cxx/convert.cc \
|
||||
bin/eolian_cxx/convert.hh \
|
||||
bin/eolian_cxx/eolian_wrappers.hh \
|
||||
bin/eolian_cxx/safe_strings.hh \
|
||||
bin/eolian_cxx/type_lookup.hh \
|
||||
bin/eolian_cxx/type_lookup_table.cc \
|
||||
bin/eolian_cxx/eolian_cxx.cc
|
||||
|
||||
bin_eolian_cxx_eolian_cxx_CXXFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
|
@ -63,32 +76,29 @@ TESTS += tests/eolian_cxx/eolian_cxx_suite
|
|||
tests_eolian_cxx_eolian_cxx_suite_SOURCES = \
|
||||
tests/eolian_cxx/eolian_cxx_suite.cc \
|
||||
tests/eolian_cxx/eolian_cxx_test_parse.cc \
|
||||
tests/eolian_cxx/callback.c \
|
||||
tests/eolian_cxx/a.c \
|
||||
tests/eolian_cxx/b.c \
|
||||
tests/eolian_cxx/c.c \
|
||||
tests/eolian_cxx/d.c \
|
||||
tests/eolian_cxx/eolian_cxx_test_binding.cc \
|
||||
tests/eolian_cxx/eolian_cxx_test_callback.cc \
|
||||
tests/eolian_cxx/eolian_cxx_test_address_of.cc \
|
||||
tests/eolian_cxx/eolian_cxx_test_wrapper.cc \
|
||||
tests/eolian_cxx/simple.c \
|
||||
tests/eolian_cxx/name_name.c \
|
||||
tests/eolian_cxx/name_name_cxx.cc \
|
||||
tests/eolian_cxx/generic.c \
|
||||
tests/eolian_cxx/name1_name2_type_generation.c \
|
||||
tests/eolian_cxx/eolian_cxx_test_inheritance.cc \
|
||||
tests/eolian_cxx/eolian_cxx_test_generate.cc \
|
||||
tests/eolian_cxx/complex.c \
|
||||
tests/eolian_cxx/complex_cxx.cc \
|
||||
tests/eolian_cxx/eolian_cxx_suite.h
|
||||
|
||||
tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-eolian_cxx_test_wrapper.$(OBJEXT): tests/eolian_cxx/callback.eo.hh tests/eolian_cxx/callback.eo.h
|
||||
tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-eolian_cxx_test_callback.$(OBJEXT): tests/eolian_cxx/callback.eo.hh tests/eolian_cxx/callback.eo.h
|
||||
tests/eolian_cxx/name1_name2_type_generation.$(OBJEXT): tests/eolian_cxx/name1_name2_type_generation.eo.h tests/eolian_cxx/name1_name2_type_generation.eo.c
|
||||
tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-eolian_cxx_test_inheritance.$(OBJEXT): tests/eolian_cxx/simple.eo.hh tests/eolian_cxx/simple.eo.h
|
||||
tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-eolian_cxx_test_binding.$(OBJEXT): tests/eolian_cxx/generic.eo.hh tests/eolian_cxx/generic.eo.h
|
||||
tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-eolian_cxx_test_binding.$(OBJEXT): tests/eolian_cxx/generic.eo.hh tests/eolian_cxx/generic.eo.h tests/eolian_cxx/name1_name2_type_generation.eo.hh tests/eolian_cxx/name1_name2_type_generation.eo.h tests/eolian_cxx/name1_name2_type_generation.eo.c
|
||||
tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-eolian_cxx_test_address_of.$(OBJEXT): tests/eolian_cxx/a.eo.hh tests/eolian_cxx/b.eo.hh tests/eolian_cxx/c.eo.hh tests/eolian_cxx/d.eo.hh tests/eolian_cxx/a.eo.h tests/eolian_cxx/b.eo.h tests/eolian_cxx/c.eo.h tests/eolian_cxx/d.eo.h
|
||||
|
||||
tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-callback.$(OBJEXT): tests/eolian_cxx/callback.eo.c tests/eolian_cxx/callback.eo.h
|
||||
tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-simple.$(OBJEXT): tests/eolian_cxx/simple.eo.c tests/eolian_cxx/simple.eo.h
|
||||
tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-generic.$(OBJEXT): tests/eolian_cxx/generic.eo.c tests/eolian_cxx/generic.eo.h
|
||||
tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-a.$(OBJEXT): tests/eolian_cxx/a.eo.c tests/eolian_cxx/a.eo.h
|
||||
|
@ -103,10 +113,6 @@ tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-complex.$(OBJEXT): tests/eoli
|
|||
tests/eolian_cxx/tests_eolian_cxx_eolian_cxx_suite-complex_cxx.$(OBJEXT): tests/eolian_cxx/complex.eo.h tests/eolian_cxx/complex.eo.hh
|
||||
|
||||
CLEANFILES += \
|
||||
tests/eolian_cxx/callback.eo.hh \
|
||||
tests/eolian_cxx/callback.eo.c \
|
||||
tests/eolian_cxx/callback.eo.h \
|
||||
tests/eolian_cxx/callback.eo.impl.hh \
|
||||
tests/eolian_cxx/simple.eo.c \
|
||||
tests/eolian_cxx/simple.eo.h \
|
||||
tests/eolian_cxx/simple.eo.hh \
|
||||
|
@ -134,7 +140,11 @@ tests/eolian_cxx/ns_name_other.eo.impl.hh \
|
|||
tests/eolian_cxx/complex.eo.hh \
|
||||
tests/eolian_cxx/complex.eo.c \
|
||||
tests/eolian_cxx/complex.eo.h \
|
||||
tests/eolian_cxx/complex.eo.impl.hh
|
||||
tests/eolian_cxx/complex.eo.impl.hh \
|
||||
tests/eolian_cxx/name1_name2_type_generation.eo.hh \
|
||||
tests/eolian_cxx/name1_name2_type_generation.eo.impl.hh \
|
||||
tests/eolian_cxx/name1_name2_type_generation.eo.h \
|
||||
tests/eolian_cxx/name1_name2_type_generation.eo.c
|
||||
|
||||
|
||||
tests_eolian_cxx_eolian_cxx_suite_CXXFLAGS = \
|
||||
|
@ -159,7 +169,7 @@ tests_eolian_cxx_eolian_cxx_suite_DEPENDENCIES = @USE_EOLIAN_INTERNAL_LIBS@
|
|||
|
||||
endif
|
||||
|
||||
EXTRA_DIST += tests/eolian_cxx/callback.eo \
|
||||
EXTRA_DIST += \
|
||||
tests/eolian_cxx/simple.eo \
|
||||
tests/eolian_cxx/generic.eo \
|
||||
tests/eolian_cxx/a.eo \
|
||||
|
@ -169,6 +179,7 @@ tests/eolian_cxx/d.eo \
|
|||
tests/eolian_cxx/name_name.eo \
|
||||
tests/eolian_cxx/ns_name.eo \
|
||||
tests/eolian_cxx/ns_name_other.eo \
|
||||
tests/eolian_cxx/name1_name2_type_generation.eo \
|
||||
tests/eolian_cxx/complex.eo
|
||||
|
||||
include Makefile_Eolian_Cxx_Helper.am
|
||||
|
|
|
@ -1,373 +0,0 @@
|
|||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Eina.hh>
|
||||
#include <Eolian.h>
|
||||
|
||||
#include "eo_types.hh"
|
||||
#include "eo_validate.hh"
|
||||
|
||||
#include "safe_strings.hh"
|
||||
#include "convert_comments.hh"
|
||||
#include "eolian_wrappers.hh"
|
||||
|
||||
namespace eolian_cxx {
|
||||
|
||||
extern efl::eina::log_domain domain;
|
||||
typedef std::map<efl::eolian::eo_event, bool> event_map;
|
||||
|
||||
void
|
||||
add_ancestor_recursive(const char* klass_name, std::set<std::string>& ancestor)
|
||||
{
|
||||
if (!klass_name)
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ancestor.insert(class_format_cxx(safe_str(klass_name)));
|
||||
|
||||
Eina_Iterator* inheritances = ::eolian_class_inherits_get(klass);
|
||||
void* curr = 0;
|
||||
|
||||
EINA_ITERATOR_FOREACH(inheritances, curr)
|
||||
{
|
||||
add_ancestor_recursive(static_cast<const char*>(curr), ancestor);
|
||||
}
|
||||
eina_iterator_free(inheritances);
|
||||
}
|
||||
|
||||
void
|
||||
add_events_recursive(event_map& events, Eolian_Class const& klass, std::set<std::string>& ancestors)
|
||||
{
|
||||
for (efl::eolian::eo_event const& e : event_list(klass))
|
||||
{
|
||||
auto it = events.find(e);
|
||||
if (it == events.end())
|
||||
events[e] = true;
|
||||
else
|
||||
it->second = false;
|
||||
}
|
||||
|
||||
Eina_Iterator* inheritances = ::eolian_class_inherits_get(&klass);
|
||||
void* curr = 0;
|
||||
|
||||
EINA_ITERATOR_FOREACH(inheritances, curr)
|
||||
{
|
||||
const char* ancestor_name = static_cast<const char*>(curr);
|
||||
if (!ancestor_name || ancestors.find(ancestor_name) != ancestors.end())
|
||||
continue;
|
||||
|
||||
Eolian_Class const* ancestor_klass = ::eolian_class_get_by_name(ancestor_name);
|
||||
if (!ancestor_klass)
|
||||
{
|
||||
std::cerr << "Error: could not get eolian class name `" << ancestor_name << "'" << std::endl;
|
||||
continue;
|
||||
}
|
||||
ancestors.insert(ancestor_name);
|
||||
add_events_recursive(events, *ancestor_klass, ancestors);
|
||||
}
|
||||
|
||||
eina_iterator_free(inheritances);
|
||||
}
|
||||
|
||||
static efl::eolian::parameters_container_type
|
||||
_convert_eolian_parameters(Eina_Iterator *parameters,
|
||||
Eolian_Function_Type func_type)
|
||||
{
|
||||
if (parameters == NULL) return {};
|
||||
assert(func_type != EOLIAN_PROPERTY);
|
||||
|
||||
void *curr;
|
||||
efl::eolian::parameters_container_type list;
|
||||
EINA_ITERATOR_FOREACH(parameters, curr)
|
||||
{
|
||||
const Eolian_Function_Parameter *id =
|
||||
(static_cast<const Eolian_Function_Parameter*>(curr));
|
||||
list.push_back
|
||||
({
|
||||
parameter_type(*id),
|
||||
parameter_name(*id)
|
||||
});
|
||||
}
|
||||
eina_iterator_free(parameters);
|
||||
return list;
|
||||
}
|
||||
|
||||
static efl::eolian::parameters_container_type
|
||||
_convert_eolian_parameters(Eina_Iterator *parameters, getter_t func_type)
|
||||
{
|
||||
return _convert_eolian_parameters(parameters, func_type.value);
|
||||
}
|
||||
|
||||
static efl::eolian::parameters_container_type
|
||||
_convert_eolian_parameters(Eina_Iterator *parameters, setter_t func_type)
|
||||
{
|
||||
return _convert_eolian_parameters(parameters, func_type.value);
|
||||
}
|
||||
|
||||
static efl::eolian::parameters_container_type
|
||||
_convert_eolian_parameters(Eolian_Function const& func)
|
||||
{
|
||||
assert(function_op_type(func) != EOLIAN_PROPERTY);
|
||||
return _convert_eolian_parameters
|
||||
(::eolian_function_parameters_get(&func), function_op_type(func));
|
||||
}
|
||||
|
||||
static efl::eolian::eo_function
|
||||
_convert_property_set_to_function(Eolian_Class const& klass,
|
||||
Eolian_Function const& prop_)
|
||||
{
|
||||
efl::eolian::eo_function set_ =
|
||||
{
|
||||
efl::eolian::eo_function::regular_,
|
||||
function_scope(prop_),
|
||||
function_is_beta(prop_),
|
||||
function_name(prop_) + "_set",
|
||||
function_impl(prop_) + "_set",
|
||||
function_return_type(prop_, eolian_cxx::setter),
|
||||
_convert_eolian_parameters(::eolian_property_values_get(&prop_, EOLIAN_PROP_SET),
|
||||
eolian_cxx::setter),
|
||||
convert_comments_function(klass, prop_, eolian_cxx::setter)
|
||||
};
|
||||
efl::eolian::parameters_container_type keys =
|
||||
_convert_eolian_parameters(::eolian_property_keys_get(&prop_, EOLIAN_PROP_SET),
|
||||
eolian_cxx::setter);
|
||||
if (!keys.empty())
|
||||
{
|
||||
keys.reserve(keys.size() + set_.params.size());
|
||||
keys.insert(keys.end(), set_.params.begin(),
|
||||
set_.params.end());
|
||||
set_.params = keys;
|
||||
}
|
||||
return set_;
|
||||
}
|
||||
|
||||
static efl::eolian::eo_function
|
||||
_convert_property_get_to_function(Eolian_Class const& klass,
|
||||
Eolian_Function const& prop_)
|
||||
{
|
||||
efl::eolian::eo_function get_ =
|
||||
{
|
||||
efl::eolian::eo_function::regular_,
|
||||
function_scope(prop_),
|
||||
function_is_beta(prop_),
|
||||
function_name(prop_) + "_get",
|
||||
function_impl(prop_) + "_get",
|
||||
function_return_type(prop_, eolian_cxx::getter),
|
||||
_convert_eolian_parameters(::eolian_property_values_get(&prop_, EOLIAN_PROP_GET),
|
||||
eolian_cxx::getter),
|
||||
convert_comments_function(klass, prop_, eolian_cxx::getter)
|
||||
};
|
||||
|
||||
// if the getter has a single parameter and a void return
|
||||
// it is transformed into a getter with no parameters
|
||||
// that actually returns what would be the first argument.
|
||||
if (get_.params.size() == 1 && efl::eolian::type_is_void(get_.ret) &&
|
||||
!function_return_is_explicit_void(prop_, eolian_cxx::getter))
|
||||
{
|
||||
get_.ret = get_.params[0].type;
|
||||
get_.params.clear();
|
||||
}
|
||||
else // otherwise just create the described getter
|
||||
{
|
||||
std::transform
|
||||
(get_.params.begin(), get_.params.end(), get_.params.begin(),
|
||||
[](efl::eolian::eo_parameter const& param)
|
||||
{
|
||||
efl::eolian::eolian_type getter_param_type =
|
||||
type_to_native(param.type);
|
||||
getter_param_type.native += "*";
|
||||
return efl::eolian::eo_parameter
|
||||
{ { getter_param_type }, param.name };
|
||||
});
|
||||
}
|
||||
efl::eolian::parameters_container_type keys =
|
||||
_convert_eolian_parameters(::eolian_property_keys_get(&prop_, EOLIAN_PROP_GET),
|
||||
eolian_cxx::getter);
|
||||
if (!keys.empty())
|
||||
{
|
||||
keys.reserve(keys.size() + get_.params.size());
|
||||
keys.insert(keys.end(), get_.params.begin(),
|
||||
get_.params.end());
|
||||
get_.params = keys;
|
||||
}
|
||||
return get_;
|
||||
}
|
||||
|
||||
static efl::eolian::eo_function
|
||||
_convert_function(Eolian_Class const& klass, Eolian_Function const& func)
|
||||
{
|
||||
return {
|
||||
function_type(func),
|
||||
function_scope(func),
|
||||
function_is_beta(func),
|
||||
function_name(func),
|
||||
function_impl(func),
|
||||
function_return_type(func),
|
||||
_convert_eolian_parameters(func),
|
||||
convert_comments_function(klass, func, eolian_cxx::method)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
convert_eolian_inheritances(efl::eolian::eo_class& cls, Eolian_Class const& klass)
|
||||
{
|
||||
Eina_Iterator *inheritances =
|
||||
::eolian_class_inherits_get(&klass);
|
||||
void *curr;
|
||||
|
||||
std::set<std::string> ancestors;
|
||||
|
||||
EINA_ITERATOR_FOREACH(inheritances, curr)
|
||||
{
|
||||
const char* klass_name = static_cast<const char*>(curr);
|
||||
cls.parents.push_back(class_format_cxx(safe_str(klass_name)));
|
||||
add_ancestor_recursive(klass_name, ancestors);
|
||||
}
|
||||
eina_iterator_free(inheritances);
|
||||
|
||||
cls.ancestors.assign(ancestors.begin(), ancestors.end());
|
||||
}
|
||||
|
||||
void
|
||||
convert_eolian_events(efl::eolian::eo_class& cls, Eolian_Class const& klass)
|
||||
{
|
||||
efl::eolian::events_container_type events = event_list(klass);
|
||||
cls.own_events.reserve(cls.own_events.size() + events.size());
|
||||
cls.own_events.insert(cls.own_events.end(), events.begin(), events.end());
|
||||
|
||||
event_map concrete_events;
|
||||
std::set<std::string> ancestors;
|
||||
|
||||
add_events_recursive(concrete_events, klass, ancestors);
|
||||
|
||||
for (auto const& e : events)
|
||||
{
|
||||
concrete_events[e] = true;
|
||||
}
|
||||
|
||||
for (auto const& pair : concrete_events)
|
||||
{
|
||||
if (pair.second)
|
||||
cls.concrete_events.push_back(pair.first);
|
||||
}
|
||||
}
|
||||
|
||||
efl::eolian::eo_class
|
||||
convert_eolian_class_new(Eolian_Class const& klass)
|
||||
{
|
||||
efl::eolian::eo_class cls;
|
||||
cls.type = class_type(klass);
|
||||
cls.name = class_name(klass);
|
||||
cls.name_space = class_namespace_full(klass);
|
||||
if(cls.name_space.empty())
|
||||
cls.name_space = "nonamespace";
|
||||
cls.eo_name = class_eo_name(klass);
|
||||
cls.comment = convert_comments_class(klass);
|
||||
return cls;
|
||||
}
|
||||
|
||||
void
|
||||
convert_eolian_functions(efl::eolian::eo_class& cls, Eolian_Class const& klass)
|
||||
{
|
||||
for(efl::eina::iterator<const Eolian_Function> first ( ::eolian_class_functions_get(&klass, EOLIAN_METHOD))
|
||||
, last; first != last; ++first)
|
||||
{
|
||||
Eolian_Function const& func = *first;
|
||||
|
||||
if (function_is_visible(func, function_op_type(func)) &&
|
||||
!function_is_constructor(klass, func))
|
||||
{
|
||||
cls.functions.push_back(_convert_function(klass, func));
|
||||
}
|
||||
}
|
||||
if (class_eo_name(klass) != "EO_BASE_CLASS")
|
||||
for(efl::eina::iterator<const Eolian_Constructor> first ( ::eolian_class_constructors_get(&klass))
|
||||
, last; first != last; ++first)
|
||||
{
|
||||
Eolian_Constructor const& ctor = *first;
|
||||
Eolian_Function const& func = *(::eolian_constructor_function_get(&ctor));
|
||||
|
||||
efl::eolian::eo_function f;
|
||||
if (function_op_type(func) == EOLIAN_METHOD)
|
||||
f = _convert_function(klass, func);
|
||||
else
|
||||
f = _convert_property_set_to_function(klass, func);
|
||||
|
||||
|
||||
(::eolian_constructor_is_optional(&ctor) ?
|
||||
cls.optional_constructors :
|
||||
cls.constructors
|
||||
).push_back({
|
||||
function_name(func),
|
||||
f.impl,
|
||||
f.params,
|
||||
f.comment
|
||||
});
|
||||
}
|
||||
|
||||
cls.all_constructors = cls.constructors;
|
||||
cls.all_constructors.insert(cls.all_constructors.end(),
|
||||
cls.optional_constructors.begin(), cls.optional_constructors.end());
|
||||
|
||||
for(efl::eina::iterator<const Eolian_Function> first ( ::eolian_class_functions_get(&klass, EOLIAN_PROPERTY))
|
||||
, last; first != last; ++first)
|
||||
{
|
||||
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
|
||||
(_convert_property_get_to_function(klass, func));
|
||||
}
|
||||
else if(t == EOLIAN_PROP_SET)
|
||||
{
|
||||
cls.functions.push_back
|
||||
(_convert_property_set_to_function(klass, func));
|
||||
}
|
||||
else if(t == EOLIAN_PROPERTY)
|
||||
{
|
||||
cls.functions.push_back
|
||||
(_convert_property_get_to_function(klass, func));
|
||||
cls.functions.push_back
|
||||
(_convert_property_set_to_function(klass, func));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Error: Inconsistent type for Eolian function \'" << ::eolian_function_name_get(&func) << "\'." << std::endl;
|
||||
throw std::runtime_error("Invalid Eolian function type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
efl::eolian::eo_class
|
||||
convert_eolian_class(const Eolian_Class& klass)
|
||||
{
|
||||
efl::eolian::eo_class cls(eolian_cxx::convert_eolian_class_new(klass));
|
||||
eolian_cxx::convert_eolian_inheritances(cls, klass);
|
||||
eolian_cxx::convert_eolian_functions(cls, klass);
|
||||
eolian_cxx::convert_eolian_events(cls, klass);
|
||||
efl::eolian::eo_class_validate(cls);
|
||||
return cls;
|
||||
}
|
||||
|
||||
} // namespace eolian_cxx {
|
|
@ -1,19 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_EOLIAN_CONVERT_CLASSES_HH
|
||||
#define EOLIAN_CXX_EOLIAN_CONVERT_CLASSES_HH
|
||||
|
||||
#include "eo_types.hh"
|
||||
|
||||
namespace eolian_cxx
|
||||
{
|
||||
|
||||
///
|
||||
/// @brief Retrieve a efl::eolian::eo_class from an Eolian_Class* name.
|
||||
/// @param cls The Eolian class.
|
||||
/// @return The @p eo_class describing @p classname.
|
||||
///
|
||||
efl::eolian::eo_class convert_eolian_class(const Eolian_Class& klass);
|
||||
|
||||
}
|
||||
|
||||
#endif // EOLIAN_CXX_EOLIAN_CONVERT_CLASSES_HH
|
|
@ -1,95 +0,0 @@
|
|||
|
||||
#include "convert_comments.hh"
|
||||
#include "safe_strings.hh"
|
||||
|
||||
namespace eolian_cxx {
|
||||
|
||||
static std::string
|
||||
_comment_parameter(Eolian_Function_Parameter *param)
|
||||
{
|
||||
Eolian_Parameter_Dir direction = eolian_parameter_direction_get(param);
|
||||
|
||||
std::string doc = "@param";
|
||||
if (direction == EOLIAN_IN_PARAM) doc += " ";
|
||||
else if (direction == EOLIAN_OUT_PARAM) doc += "[out] ";
|
||||
else if (direction == EOLIAN_INOUT_PARAM) doc += "[inout] ";
|
||||
else assert(false);
|
||||
|
||||
doc += safe_str(::eolian_parameter_name_get(param));
|
||||
doc += " ";
|
||||
/* FIXME */
|
||||
doc += safe_str(NULL);
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
static std::string
|
||||
_comment_parameters_list(Eina_Iterator *params)
|
||||
{
|
||||
std::string doc = "";
|
||||
void *curr;
|
||||
EINA_ITERATOR_FOREACH(params, curr)
|
||||
{
|
||||
doc += _comment_parameter
|
||||
(static_cast<Eolian_Function_Parameter*>(curr)) + "\n";
|
||||
}
|
||||
eina_iterator_free(params);
|
||||
return doc;
|
||||
}
|
||||
|
||||
static std::string
|
||||
_comment_brief_and_params(Eolian_Function const& function, Eolian_Function_Type)
|
||||
{
|
||||
std::string doc = "";
|
||||
/* FIXME */
|
||||
std::string func = safe_str(NULL);
|
||||
if (func != "")
|
||||
{
|
||||
doc += "@brief " + func + "\n\n";
|
||||
}
|
||||
std::string params = _comment_parameters_list(::eolian_function_parameters_get(&function));
|
||||
if (params != "")
|
||||
{
|
||||
doc += params + "\n";
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
|
||||
static std::string
|
||||
_comment_return(Eolian_Function const& function,
|
||||
Eolian_Function_Type rettype)
|
||||
{
|
||||
const Eolian_Type *rettypet = ::eolian_function_return_type_get(&function, rettype);
|
||||
const char *rettypes = NULL;
|
||||
if (rettypet) rettypes = ::eolian_type_c_type_get(rettypet);
|
||||
std::string doc = "";
|
||||
std::string ret = safe_str(rettypes);
|
||||
if (rettypes) eina_stringshare_del(rettypes);
|
||||
/* FIXME */
|
||||
std::string comment = safe_str(NULL);
|
||||
if (ret != "void" && ret != "" && comment != "")
|
||||
{
|
||||
doc = "@return " + comment;
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
|
||||
std::string
|
||||
convert_comments_class(Eolian_Class const&)
|
||||
{
|
||||
/* FIXME */
|
||||
return safe_str(NULL);
|
||||
}
|
||||
|
||||
std::string
|
||||
convert_comments_function(Eolian_Class const& klass,
|
||||
Eolian_Function const& function,
|
||||
Eolian_Function_Type func_type)
|
||||
{
|
||||
std::string doc = _comment_brief_and_params(function, func_type);
|
||||
if (!function_is_constructor(klass, function))
|
||||
doc += _comment_return(function, func_type);
|
||||
return doc;
|
||||
}
|
||||
|
||||
} // namespace eolian_cxx
|
|
@ -1,46 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_CONVERT_COMMENTS_HH
|
||||
#define EOLIAN_CXX_CONVERT_COMMENTS_HH
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <Eolian.h>
|
||||
#include <Eolian_Cxx.hh>
|
||||
|
||||
#include "eolian_wrappers.hh"
|
||||
|
||||
namespace eolian_cxx {
|
||||
|
||||
std::string convert_comments_class(Eolian_Class const& klass);
|
||||
|
||||
std::string convert_comments_function(Eolian_Class const& klass,
|
||||
Eolian_Function const& function,
|
||||
Eolian_Function_Type func_type);
|
||||
|
||||
inline std::string
|
||||
convert_comments_function(Eolian_Class const& klass, Eolian_Function const& function_, method_t func_type_)
|
||||
{
|
||||
return convert_comments_function(klass, function_, func_type_.value);
|
||||
}
|
||||
|
||||
inline std::string
|
||||
convert_comments_function(Eolian_Class const& klass, Eolian_Function const& property_, getter_t func_type_)
|
||||
{
|
||||
return convert_comments_function(klass, property_, func_type_.value);
|
||||
}
|
||||
|
||||
inline std::string
|
||||
convert_comments_function(Eolian_Class const& klass, Eolian_Function const& property_, setter_t func_type_)
|
||||
{
|
||||
return convert_comments_function(klass, property_, func_type_.value);
|
||||
}
|
||||
|
||||
inline std::string
|
||||
convert_comments_function(Eolian_Class const& klass, Eolian_Function const& function_)
|
||||
{
|
||||
return convert_comments_function(klass, function_, eolian_cxx::method);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // EOLIAN_CXX_CONVERT_COMMENTS_HH
|
|
@ -21,12 +21,9 @@
|
|||
#include <Eina.hh>
|
||||
#include <Eolian_Cxx.hh>
|
||||
|
||||
#include "convert.hh"
|
||||
#include "type_lookup.hh"
|
||||
|
||||
#include "convert.hh"
|
||||
#include "eolian_wrappers.hh"
|
||||
#include "safe_strings.hh"
|
||||
#include "grammar/klass_def.hpp"
|
||||
#include "grammar/header.hpp"
|
||||
#include "grammar/impl_header.hpp"
|
||||
|
||||
namespace eolian_cxx {
|
||||
|
||||
|
@ -36,20 +33,6 @@ struct options_type
|
|||
std::vector<std::string> include_dirs;
|
||||
std::string in_file;
|
||||
std::string out_file;
|
||||
std::string out_dir;
|
||||
std::string classname;
|
||||
bool recurse;
|
||||
bool generate_all;
|
||||
|
||||
options_type()
|
||||
: include_dirs()
|
||||
, in_file()
|
||||
, out_file()
|
||||
, out_dir()
|
||||
, classname()
|
||||
, recurse(false)
|
||||
, generate_all(false)
|
||||
{}
|
||||
};
|
||||
|
||||
efl::eina::log_domain domain("eolian_cxx");
|
||||
|
@ -57,29 +40,11 @@ efl::eina::log_domain domain("eolian_cxx");
|
|||
static bool
|
||||
opts_check(eolian_cxx::options_type const& opts)
|
||||
{
|
||||
if (!opts.generate_all && opts.in_file.empty())
|
||||
if (opts.in_file.empty())
|
||||
{
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Nothing to generate?" << std::endl;
|
||||
}
|
||||
else if (opts.generate_all && !opts.in_file.empty())
|
||||
{
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Didn't expect to receive input files (" << opts.in_file
|
||||
<< ") with parameter -a."
|
||||
<< std::endl;
|
||||
}
|
||||
else if (opts.generate_all && !opts.out_file.empty())
|
||||
{
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Can't use -a and -o together." << std::endl;
|
||||
}
|
||||
else if (opts.generate_all && opts.include_dirs.empty())
|
||||
{
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Option -a requires at least one include directory (-I)."
|
||||
<< std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true; // valid.
|
||||
|
@ -87,39 +52,11 @@ opts_check(eolian_cxx::options_type const& opts)
|
|||
return false;
|
||||
}
|
||||
|
||||
efl::eolian::eo_generator_options
|
||||
generator_options(const Eolian_Class& klass)
|
||||
{
|
||||
efl::eolian::eo_generator_options gen_opts;
|
||||
gen_opts.c_headers.push_back(class_base_file(klass) + ".h");
|
||||
|
||||
void *cur = NULL;
|
||||
Eina_Iterator *inheritances = ::eolian_class_inherits_get(&klass);
|
||||
EINA_ITERATOR_FOREACH(inheritances, cur)
|
||||
{
|
||||
const Eolian_Class *ext = ::eolian_class_get_by_name(static_cast<const char*>(cur));
|
||||
std::string eo_parent_file = class_base_file(*ext);
|
||||
if (!eo_parent_file.empty())
|
||||
{
|
||||
gen_opts.cxx_headers.push_back(eo_parent_file + ".hh");
|
||||
}
|
||||
else
|
||||
{
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Couldn't find source file for class '" << ext << "'"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
eina_iterator_free(inheritances);
|
||||
return gen_opts;
|
||||
}
|
||||
|
||||
static bool
|
||||
generate(const Eolian_Class& klass, eolian_cxx::options_type const& opts)
|
||||
generate(const Eolian_Class* klass, eolian_cxx::options_type const& opts)
|
||||
{
|
||||
efl::eolian::eo_class cls = eolian_cxx::convert_eolian_class(klass);
|
||||
efl::eolian::eo_generator_options gen_opts = generator_options(klass);
|
||||
std::string header_decl_file_name = opts.out_file.empty() ? (class_base_file(klass) + ".hh") : opts.out_file;
|
||||
std::string header_decl_file_name = opts.out_file.empty()
|
||||
? (::eolian_class_file_get(klass) + std::string(".hh")) : opts.out_file;
|
||||
|
||||
std::string header_impl_file_name = header_decl_file_name;
|
||||
std::size_t dot_pos = header_impl_file_name.rfind(".hh");
|
||||
|
@ -128,24 +65,101 @@ generate(const Eolian_Class& klass, eolian_cxx::options_type const& opts)
|
|||
else
|
||||
header_impl_file_name.insert(header_impl_file_name.size(), ".impl");
|
||||
|
||||
std::size_t slash_pos = header_decl_file_name.rfind('/');
|
||||
gen_opts.header_decl_file_name = (slash_pos == std::string::npos) ?
|
||||
header_decl_file_name :
|
||||
header_decl_file_name.substr(slash_pos+1);
|
||||
efl::eolian::grammar::attributes::klass_def klass_def(klass);
|
||||
std::vector<efl::eolian::grammar::attributes::klass_def> klasses{klass_def};
|
||||
|
||||
slash_pos = header_impl_file_name.rfind('/');
|
||||
gen_opts.header_impl_file_name = (slash_pos == std::string::npos) ?
|
||||
header_impl_file_name :
|
||||
header_impl_file_name.substr(slash_pos+1);
|
||||
|
||||
if (!opts.out_dir.empty())
|
||||
std::set<std::string> c_headers;
|
||||
std::set<std::string> cpp_headers;
|
||||
c_headers.insert(eolian_class_file_get(klass) + std::string(".h"));
|
||||
|
||||
std::function<void(efl::eolian::grammar::attributes::type_def const&)>
|
||||
variant_function;
|
||||
auto klass_name_function
|
||||
= [&] (efl::eolian::grammar::attributes::klass_name const& name)
|
||||
{
|
||||
header_decl_file_name = opts.out_dir + "/" + header_decl_file_name;
|
||||
header_impl_file_name = opts.out_dir + "/" + header_impl_file_name;
|
||||
}
|
||||
Eolian_Class const* klass = get_klass(name);
|
||||
assert(klass);
|
||||
c_headers.insert(eolian_class_file_get(klass) + std::string(".h"));
|
||||
cpp_headers.insert(eolian_class_file_get(klass) + std::string(".hh"));
|
||||
};
|
||||
auto complex_function
|
||||
= [&] (efl::eolian::grammar::attributes::complex_type_def const& complex)
|
||||
{
|
||||
for(auto&& t : complex.subtypes)
|
||||
{
|
||||
variant_function(t);
|
||||
}
|
||||
};
|
||||
variant_function = [&] (efl::eolian::grammar::attributes::type_def const& type)
|
||||
{
|
||||
if(efl::eolian::grammar::attributes::klass_name const*
|
||||
name = efl::eolian::grammar::attributes::get<efl::eolian::grammar::attributes::klass_name>
|
||||
(&type.original_type))
|
||||
klass_name_function(*name);
|
||||
else if(efl::eolian::grammar::attributes::complex_type_def const*
|
||||
complex = efl::eolian::grammar::attributes::get<efl::eolian::grammar::attributes::complex_type_def>
|
||||
(&type.original_type))
|
||||
complex_function(*complex);
|
||||
};
|
||||
|
||||
std::function<void(Eolian_Class const*)> klass_function
|
||||
= [&] (Eolian_Class const* klass)
|
||||
{
|
||||
for(efl::eina::iterator<const char> inherit_iterator ( ::eolian_class_inherits_get(klass))
|
||||
, inherit_last; inherit_iterator != inherit_last; ++inherit_iterator)
|
||||
{
|
||||
Eolian_Class const* inherit = ::eolian_class_get_by_name(&*inherit_iterator);
|
||||
c_headers.insert(eolian_class_file_get(inherit) + std::string(".h"));
|
||||
cpp_headers.insert(eolian_class_file_get(inherit) + std::string(".hh"));
|
||||
|
||||
klass_function(inherit);
|
||||
}
|
||||
|
||||
efl::eolian::grammar::attributes::klass_def klass_def(klass);
|
||||
for(auto&& f : klass_def.functions)
|
||||
{
|
||||
variant_function(f.return_type);
|
||||
for(auto&& p : f.parameters)
|
||||
{
|
||||
variant_function(p.type);
|
||||
}
|
||||
}
|
||||
for(auto&& e : klass_def.events)
|
||||
{
|
||||
if(e.type)
|
||||
variant_function(*e.type);
|
||||
}
|
||||
};
|
||||
klass_function(klass);
|
||||
|
||||
cpp_headers.erase(eolian_class_file_get(klass) + std::string(".hh"));
|
||||
|
||||
std::string guard_name;
|
||||
as_generator(*(efl::eolian::grammar::string << "_") << efl::eolian::grammar::string << "_EO_HH")
|
||||
.generate(std::back_insert_iterator<std::string>(guard_name)
|
||||
, std::make_tuple(klass_def.namespaces, klass_def.eolian_name)
|
||||
, efl::eolian::grammar::context_null{});
|
||||
|
||||
std::tuple<std::string, std::set<std::string>&, std::set<std::string>&
|
||||
, std::vector<efl::eolian::grammar::attributes::klass_def>&
|
||||
, std::vector<efl::eolian::grammar::attributes::klass_def>&
|
||||
, std::vector<efl::eolian::grammar::attributes::klass_def>&
|
||||
, std::vector<efl::eolian::grammar::attributes::klass_def>&
|
||||
> attributes
|
||||
{guard_name, c_headers, cpp_headers, klasses, klasses, klasses, klasses};
|
||||
|
||||
if(opts.out_file == "-")
|
||||
{
|
||||
efl::eolian::generate(std::cout, std::cout, cls, gen_opts);
|
||||
std::ostream_iterator<char> iterator(std::cout);
|
||||
|
||||
efl::eolian::grammar::class_header.generate(iterator, attributes, efl::eolian::grammar::context_null());
|
||||
std::endl(std::cout);
|
||||
|
||||
efl::eolian::grammar::impl_header.generate(iterator, klasses, efl::eolian::grammar::context_null());
|
||||
|
||||
std::endl(std::cout);
|
||||
std::flush(std::cout);
|
||||
std::flush(std::cerr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -167,10 +181,18 @@ generate(const Eolian_Class& klass, eolian_cxx::options_type const& opts)
|
|||
return false;
|
||||
}
|
||||
|
||||
efl::eolian::generate(header_decl, header_impl, cls, gen_opts);
|
||||
#if 1
|
||||
efl::eolian::grammar::class_header.generate
|
||||
(std::ostream_iterator<char>(header_decl), attributes, efl::eolian::grammar::context_null());
|
||||
|
||||
efl::eolian::grammar::impl_header.generate
|
||||
(std::ostream_iterator<char>(header_impl), klasses, efl::eolian::grammar::context_null());
|
||||
#else
|
||||
efl::eolian::generate(header_decl, header_impl, cls, gen_opts);
|
||||
#endif
|
||||
|
||||
header_decl.close();
|
||||
header_impl.close();
|
||||
header_decl.close();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -179,34 +201,23 @@ static void
|
|||
run(options_type const& opts)
|
||||
{
|
||||
const Eolian_Class *klass = NULL;
|
||||
if (!opts.classname.empty())
|
||||
klass = class_from_name(opts.classname);
|
||||
else if (!opts.in_file.empty())
|
||||
klass = class_from_file(opts.in_file);
|
||||
char* dup = strdup(opts.in_file.c_str());
|
||||
char* base = basename(dup);
|
||||
klass = ::eolian_class_get_by_file(base);
|
||||
free(dup);
|
||||
if (klass)
|
||||
{
|
||||
if (!generate(*klass, opts))
|
||||
if (!generate(klass, opts))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
efl::eina::iterator<const Eolian_Class> it(class_list_all());
|
||||
efl::eina::iterator<const Eolian_Class> end;
|
||||
while (it != end)
|
||||
{
|
||||
Eolian_Class c = (*it);
|
||||
if (!generate(c, opts))
|
||||
{
|
||||
klass = &c;
|
||||
goto err;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
std::abort();
|
||||
}
|
||||
return;
|
||||
err:
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Error generating: " << class_name(*klass)
|
||||
<< "Error generating: " << ::eolian_class_name_get(klass)
|
||||
<< std::endl;
|
||||
assert(false && "error generating class");
|
||||
}
|
||||
|
@ -228,20 +239,17 @@ database_load(options_type const& opts)
|
|||
<< "Eolian failed parsing eot files";
|
||||
assert(false && "Error parsing eot files");
|
||||
}
|
||||
if (!opts.in_file.empty())
|
||||
if (opts.in_file.empty())
|
||||
{
|
||||
if (!::eolian_file_parse(opts.in_file.c_str()))
|
||||
{
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Failed parsing: " << opts.in_file << ".";
|
||||
assert(false && "Error parsing input file");
|
||||
}
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "No input file.";
|
||||
assert(false && "Error parsing input file");
|
||||
}
|
||||
else if (!::eolian_all_eo_files_parse())
|
||||
if (!::eolian_file_parse(opts.in_file.c_str()))
|
||||
{
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Eolian failed parsing input files";
|
||||
assert(false && "Error parsing input files");
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Failed parsing: " << opts.in_file << ".";
|
||||
assert(false && "Error parsing input file");
|
||||
}
|
||||
if (!::eolian_database_validate(EINA_FALSE))
|
||||
{
|
||||
|
@ -299,11 +307,7 @@ opts_get(int argc, char **argv)
|
|||
const struct option long_options[] =
|
||||
{
|
||||
{ "in", required_argument, 0, 'I' },
|
||||
{ "out-dir", required_argument, 0, 'D' },
|
||||
{ "out-file", required_argument, 0, 'o' },
|
||||
{ "class", required_argument, 0, 'c' },
|
||||
{ "all", no_argument, 0, 'a' },
|
||||
{ "recurse", no_argument, 0, 'r' },
|
||||
{ "version", no_argument, 0, 'v' },
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ 0, 0, 0, 0 }
|
||||
|
@ -317,29 +321,11 @@ opts_get(int argc, char **argv)
|
|||
{
|
||||
opts.include_dirs.push_back(optarg);
|
||||
}
|
||||
else if (c == 'D')
|
||||
{
|
||||
_assert_not_dup("D", opts.out_dir);
|
||||
opts.out_dir = optarg;
|
||||
}
|
||||
else if (c == 'o')
|
||||
{
|
||||
_assert_not_dup("o", opts.out_file);
|
||||
opts.out_file = optarg;
|
||||
}
|
||||
else if (c == 'c')
|
||||
{
|
||||
_assert_not_dup("c", opts.classname);
|
||||
opts.classname = optarg;
|
||||
}
|
||||
else if (c == 'a')
|
||||
{
|
||||
opts.generate_all = true;
|
||||
}
|
||||
else if (c == 'r')
|
||||
{
|
||||
opts.recurse = true;
|
||||
}
|
||||
else if (c == 'h')
|
||||
{
|
||||
_usage(argv[0]);
|
||||
|
|
|
@ -1,430 +0,0 @@
|
|||
#ifndef EOLIAN_CXX_EOLIAN_WRAPPERS_HH
|
||||
#define EOLIAN_CXX_EOLIAN_WRAPPERS_HH
|
||||
|
||||
#include <cassert>
|
||||
#include <libgen.h>
|
||||
|
||||
#include <Eolian.h>
|
||||
|
||||
#include "eo_types.hh"
|
||||
#include "safe_strings.hh"
|
||||
#include "type_lookup.hh"
|
||||
|
||||
namespace eolian_cxx
|
||||
{
|
||||
|
||||
struct property_t { static constexpr ::Eolian_Function_Type value = ::EOLIAN_PROPERTY; };
|
||||
property_t const property = {};
|
||||
|
||||
struct setter_t { static constexpr ::Eolian_Function_Type value = ::EOLIAN_PROP_SET; };
|
||||
setter_t const setter = {};
|
||||
|
||||
struct getter_t { static constexpr ::Eolian_Function_Type value = ::EOLIAN_PROP_GET; };
|
||||
getter_t const getter = {};
|
||||
|
||||
struct method_t { static constexpr ::Eolian_Function_Type value = ::EOLIAN_METHOD; };
|
||||
method_t const method = {};
|
||||
|
||||
inline efl::eolian::eolian_scope
|
||||
eolian_scope_cxx(Eolian_Object_Scope s)
|
||||
{
|
||||
using efl::eolian::eolian_scope;
|
||||
return s == EOLIAN_SCOPE_PRIVATE ? eolian_scope::private_ :
|
||||
s == EOLIAN_SCOPE_PROTECTED ? eolian_scope::protected_ :
|
||||
eolian_scope::public_;
|
||||
}
|
||||
|
||||
inline const Eolian_Class*
|
||||
class_from_file(std::string const& file)
|
||||
{
|
||||
char *dup = strdup(file.c_str());
|
||||
char *bn = basename(dup);
|
||||
const Eolian_Class *cl = ::eolian_class_get_by_file(bn);
|
||||
free(dup);
|
||||
return cl;
|
||||
}
|
||||
|
||||
inline std::string
|
||||
class_file(Eolian_Class const& klass)
|
||||
{
|
||||
return safe_str(::eolian_class_file_get(&klass));
|
||||
}
|
||||
|
||||
inline std::string
|
||||
class_base_file(Eolian_Class const& klass)
|
||||
{
|
||||
return path_base(safe_str(::eolian_class_file_get(&klass)));
|
||||
}
|
||||
|
||||
inline std::string
|
||||
class_name(Eolian_Class const& klass)
|
||||
{
|
||||
return ::eolian_class_name_get(&klass);
|
||||
}
|
||||
|
||||
inline std::string
|
||||
class_full_name(Eolian_Class const& klass)
|
||||
{
|
||||
return safe_str(::eolian_class_full_name_get(&klass));
|
||||
}
|
||||
|
||||
inline const Eolian_Class *
|
||||
class_from_name(std::string const& classname)
|
||||
{
|
||||
return ::eolian_class_get_by_name(classname.c_str());
|
||||
}
|
||||
|
||||
inline std::string
|
||||
class_eo_name(Eolian_Class const& klass)
|
||||
{
|
||||
std::string suffix;
|
||||
switch (::eolian_class_type_get(&klass))
|
||||
{
|
||||
case EOLIAN_CLASS_REGULAR:
|
||||
case EOLIAN_CLASS_ABSTRACT:
|
||||
suffix = "CLASS";
|
||||
break;
|
||||
case EOLIAN_CLASS_MIXIN:
|
||||
suffix = "MIXIN";
|
||||
break;
|
||||
case EOLIAN_CLASS_INTERFACE:
|
||||
suffix = "INTERFACE";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return safe_upper
|
||||
(find_replace(class_full_name(klass) + "_" + suffix, ".", "_"));
|
||||
}
|
||||
|
||||
inline efl::eolian::eo_class::eo_class_type
|
||||
class_type(Eolian_Class const& klass)
|
||||
{
|
||||
efl::eolian::eo_class::eo_class_type type = {};
|
||||
Eolian_Class_Type cls_type = ::eolian_class_type_get(&klass);
|
||||
|
||||
if (cls_type == EOLIAN_CLASS_REGULAR)
|
||||
type = efl::eolian::eo_class::regular_;
|
||||
else if (cls_type == EOLIAN_CLASS_ABSTRACT)
|
||||
type = efl::eolian::eo_class::regular_noninst_;
|
||||
else if (cls_type == EOLIAN_CLASS_MIXIN)
|
||||
type = efl::eolian::eo_class::mixin_;
|
||||
else if (cls_type == EOLIAN_CLASS_INTERFACE)
|
||||
type = efl::eolian::eo_class::interface_;
|
||||
else { assert(false); }
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
inline std::string
|
||||
class_namespace_full(Eolian_Class const& klass)
|
||||
{
|
||||
std::string s;
|
||||
Eina_Iterator* itr = ::eolian_class_namespaces_get(&klass);
|
||||
void* name;
|
||||
EINA_ITERATOR_FOREACH(itr, name)
|
||||
{
|
||||
s += static_cast<const char*>(name);
|
||||
s += "::";
|
||||
}
|
||||
eina_iterator_free(itr);
|
||||
if (s.size() >= 2)
|
||||
s = s.substr(0, s.size()-2);
|
||||
return safe_lower(s);
|
||||
}
|
||||
|
||||
inline efl::eina::iterator<const Eolian_Class>
|
||||
class_list_all()
|
||||
{
|
||||
return efl::eina::iterator<const Eolian_Class>(::eolian_all_classes_get());
|
||||
}
|
||||
|
||||
inline Eolian_Function const&
|
||||
constructor_function(Eolian_Constructor const& ctor)
|
||||
{
|
||||
assert(!!::eolian_constructor_function_get(&ctor));
|
||||
return * ::eolian_constructor_function_get(&ctor);
|
||||
}
|
||||
|
||||
inline efl::eina::iterator<const Eolian_Function>
|
||||
functions_get(Eolian_Class const& cls)
|
||||
{
|
||||
Eina_Iterator *itr = ::eolian_class_functions_get(&cls, EOLIAN_METHOD); // XXX
|
||||
return itr
|
||||
? efl::eina::iterator<const Eolian_Function>(itr)
|
||||
: efl::eina::iterator<const Eolian_Function>();
|
||||
}
|
||||
|
||||
inline std::string
|
||||
function_name(Eolian_Function const& func)
|
||||
{
|
||||
return keyword_avoid(::eolian_function_name_get(&func));
|
||||
}
|
||||
|
||||
inline std::string
|
||||
function_impl(Eolian_Function const& func)
|
||||
{
|
||||
const char *s = ::eolian_function_full_c_name_get(&func, EOLIAN_METHOD, EINA_FALSE);
|
||||
std::string ret(s);
|
||||
::eina_stringshare_del(s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline Eolian_Function_Type
|
||||
function_op_type(Eolian_Function const& func)
|
||||
{
|
||||
return ::eolian_function_type_get(&func);
|
||||
}
|
||||
|
||||
inline efl::eolian::eo_function::eo_function_type
|
||||
function_type(Eolian_Function const& func)
|
||||
{
|
||||
return ::eolian_function_is_class(&func)
|
||||
? efl::eolian::eo_function::class_
|
||||
: efl::eolian::eo_function::regular_
|
||||
;
|
||||
}
|
||||
|
||||
inline bool
|
||||
function_is_constructor(Eolian_Class const& cls, Eolian_Function const& func)
|
||||
{
|
||||
return ::eolian_function_is_constructor(&func, &cls);
|
||||
}
|
||||
|
||||
inline bool
|
||||
function_is_beta(Eolian_Function const& func)
|
||||
{
|
||||
return ::eolian_function_is_beta(&func);
|
||||
}
|
||||
|
||||
inline efl::eolian::eolian_scope
|
||||
function_scope(Eolian_Function const& func)
|
||||
{
|
||||
return eolian_scope_cxx(::eolian_function_scope_get(&func));
|
||||
}
|
||||
|
||||
inline bool
|
||||
function_is_visible(Eolian_Function const& func, Eolian_Function_Type func_type)
|
||||
{
|
||||
Eolian_Object_Scope s = ::eolian_function_scope_get(&func);
|
||||
return ((s == EOLIAN_SCOPE_PUBLIC || s == EOLIAN_SCOPE_PROTECTED) &&
|
||||
!::eolian_function_is_legacy_only(&func, func_type));
|
||||
}
|
||||
|
||||
inline bool
|
||||
function_is_visible(Eolian_Function const& func, method_t)
|
||||
{
|
||||
return function_is_visible(func, method_t::value);
|
||||
}
|
||||
|
||||
inline bool
|
||||
function_is_visible(Eolian_Function const& func)
|
||||
{
|
||||
return function_is_visible(func, function_op_type(func));
|
||||
}
|
||||
|
||||
inline bool
|
||||
function_is_visible(Eolian_Constructor const& ctor_)
|
||||
{
|
||||
Eolian_Function const* func = ::eolian_constructor_function_get(&ctor_);
|
||||
Eolian_Class const* cls = ::eolian_constructor_class_get(&ctor_);
|
||||
assert(!!func);
|
||||
assert(!!cls);
|
||||
return (::eolian_class_ctor_enable_get(cls) &&
|
||||
function_is_visible(*func, method_t::value));
|
||||
}
|
||||
|
||||
inline efl::eolian::eolian_type_instance
|
||||
function_return_type(Eolian_Function const& func, Eolian_Function_Type func_type = method_t::value)
|
||||
{
|
||||
return type_lookup(::eolian_function_return_type_get(&func, func_type));
|
||||
}
|
||||
|
||||
inline efl::eolian::eolian_type_instance
|
||||
function_return_type(Eolian_Function const& func, setter_t func_type)
|
||||
{
|
||||
return function_return_type(func, func_type.value);
|
||||
}
|
||||
|
||||
inline efl::eolian::eolian_type_instance
|
||||
function_return_type(Eolian_Function const& func, getter_t func_type)
|
||||
{
|
||||
return function_return_type(func, func_type.value);
|
||||
}
|
||||
|
||||
inline efl::eolian::eolian_type_instance
|
||||
function_return_type(Eolian_Function const& func, method_t func_type)
|
||||
{
|
||||
return function_return_type(func, func_type.value);
|
||||
}
|
||||
|
||||
inline bool
|
||||
function_return_is_explicit_void(Eolian_Function const& func, getter_t func_type)
|
||||
{
|
||||
// XXX This function shouldn't exist. Eolian should
|
||||
// forge functions a priori. Bindings generators
|
||||
// shouldn't be required to convert such thing.
|
||||
Eolian_Type const* type =
|
||||
::eolian_function_return_type_get(&func, func_type.value);
|
||||
return !!type && type->type == EOLIAN_TYPE_VOID;
|
||||
}
|
||||
|
||||
inline efl::eina::iterator<const Eolian_Function>
|
||||
properties_get(Eolian_Class const& cls)
|
||||
{
|
||||
Eina_Iterator *itr = ::eolian_class_functions_get(&cls, EOLIAN_PROPERTY); // XXX
|
||||
return itr
|
||||
? efl::eina::iterator<const Eolian_Function>(itr)
|
||||
: efl::eina::iterator<const Eolian_Function>();
|
||||
}
|
||||
|
||||
inline bool
|
||||
property_is_getter(Eolian_Function_Type func_type)
|
||||
{
|
||||
return func_type == property_t::value || func_type == getter_t::value;
|
||||
}
|
||||
|
||||
inline bool
|
||||
property_is_getter(Eolian_Function const& func)
|
||||
{
|
||||
return property_is_getter(function_op_type(func));
|
||||
}
|
||||
|
||||
inline bool
|
||||
property_is_setter(Eolian_Function_Type func_type)
|
||||
{
|
||||
return func_type == property_t::value || func_type == setter_t::value;
|
||||
}
|
||||
|
||||
inline bool
|
||||
property_is_setter(Eolian_Function const& func)
|
||||
{
|
||||
return property_is_setter(function_op_type(func));
|
||||
}
|
||||
|
||||
inline std::string
|
||||
parameter_name(Eolian_Function_Parameter const& parameter)
|
||||
{
|
||||
return safe_str(::eolian_parameter_name_get(¶meter)) + "_";
|
||||
}
|
||||
|
||||
inline bool
|
||||
parameter_is_out(Eolian_Function_Parameter const& parameter)
|
||||
{
|
||||
Eolian_Parameter_Dir direction = eolian_parameter_direction_get(¶meter);
|
||||
return direction == EOLIAN_OUT_PARAM || direction == EOLIAN_INOUT_PARAM;
|
||||
}
|
||||
|
||||
inline efl::eolian::eolian_type_instance
|
||||
parameter_type(Eolian_Function_Parameter const& parameter)
|
||||
{
|
||||
efl::eolian::eolian_type_instance type
|
||||
(type_lookup(::eolian_parameter_type_get(¶meter)));
|
||||
assert(!type.empty());
|
||||
if (parameter_is_out(parameter))
|
||||
{
|
||||
if (type.front().native.find("char") != std::string::npos)
|
||||
type = { efl::eolian::type_to_native(type) };
|
||||
type.is_out = true;
|
||||
type.front().native += "*";
|
||||
}
|
||||
type.is_optional = ::eolian_parameter_is_optional(¶meter) ||
|
||||
::eolian_parameter_is_nullable(¶meter);
|
||||
return type;
|
||||
}
|
||||
|
||||
inline efl::eolian::eo_event
|
||||
event_create(const Eolian_Event *event_)
|
||||
{
|
||||
efl::eolian::eo_event event;
|
||||
const char *name = ::eolian_event_name_get(event_);
|
||||
if (name)
|
||||
{
|
||||
std::string name_ = safe_str(name);
|
||||
std::transform(name_.begin(), name_.end(), name_.begin(),
|
||||
[](int c) { return c != ',' ? c : '_'; });
|
||||
event.scope = eolian_scope_cxx(::eolian_event_scope_get(event_));
|
||||
event.is_beta = (::eolian_event_is_beta(event_) != EINA_FALSE);
|
||||
event.name = normalize_spaces(name_);
|
||||
event.eo_name = safe_str(::eolian_event_c_name_get(event_));
|
||||
/* FIXME: use doc api */
|
||||
event.comment = safe_str("");
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
inline efl::eolian::events_container_type
|
||||
event_list(Eolian_Class const& klass)
|
||||
{
|
||||
efl::eolian::events_container_type events;
|
||||
Eina_Iterator *itr = ::eolian_class_events_get(&klass);
|
||||
Eolian_Event *e;
|
||||
EINA_ITERATOR_FOREACH(itr, e)
|
||||
{
|
||||
events.push_back(event_create(e));
|
||||
}
|
||||
eina_iterator_free(itr);
|
||||
return events;
|
||||
}
|
||||
|
||||
inline efl::eina::iterator<const Eolian_Implement>
|
||||
implements_get(Eolian_Class const& cls)
|
||||
{
|
||||
Eina_Iterator *itr = ::eolian_class_implements_get(&cls);
|
||||
return itr
|
||||
? efl::eina::iterator<const Eolian_Implement>(itr)
|
||||
: efl::eina::iterator<const Eolian_Implement>();
|
||||
}
|
||||
|
||||
inline bool
|
||||
implement_is_property_get(Eolian_Implement const& impl)
|
||||
{
|
||||
return ::eolian_implement_is_prop_get(&impl);
|
||||
}
|
||||
|
||||
inline bool
|
||||
implement_is_property_set(Eolian_Implement const& impl)
|
||||
{
|
||||
return ::eolian_implement_is_prop_set(&impl);
|
||||
}
|
||||
|
||||
inline bool
|
||||
implement_is_property(Eolian_Implement const& impl)
|
||||
{
|
||||
return implement_is_property_get(impl) ||
|
||||
implement_is_property_set(impl);
|
||||
}
|
||||
|
||||
inline Eolian_Function const*
|
||||
implement_function(Eolian_Implement const& impl)
|
||||
{
|
||||
return ::eolian_implement_function_get(&impl, nullptr);
|
||||
}
|
||||
|
||||
inline Eolian_Class const*
|
||||
implement_class(Eolian_Implement const& impl)
|
||||
{
|
||||
return ::eolian_implement_class_get(&impl);
|
||||
}
|
||||
|
||||
// XXX This function shouldn't exist. Eolian should provide some way
|
||||
// to determine if a method is a destructor.
|
||||
inline bool
|
||||
implement_is_destructor(Eolian_Implement const& impl)
|
||||
{
|
||||
return !safe_str
|
||||
(::eolian_implement_full_name_get(&impl)).compare("Eo.Base.destructor");
|
||||
}
|
||||
|
||||
inline bool
|
||||
implement_is_visible(Eolian_Implement const& impl)
|
||||
{
|
||||
return function_is_visible(*implement_function(impl)) &&
|
||||
!::eolian_implement_is_virtual(&impl) &&
|
||||
!::eolian_implement_is_empty(&impl) &&
|
||||
!implement_is_destructor(impl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // EOLIAN_CXX_EOLIAN_WRAPPERS_HH
|
|
@ -1,160 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_BIN_SAFE_STRINGS_HH
|
||||
#define EOLIAN_CXX_BIN_SAFE_STRINGS_HH
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cctype>
|
||||
#include <iterator>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <Eina.h>
|
||||
}
|
||||
|
||||
/// @brief Safely convert const char* to std::string.
|
||||
///
|
||||
inline std::string
|
||||
safe_str(const char* str)
|
||||
{
|
||||
return (str != NULL) ? str : "";
|
||||
}
|
||||
|
||||
/// @brief Safely convert Eina_Stringshare to std::string.
|
||||
///
|
||||
inline std::string
|
||||
safe_strshare(Eina_Stringshare* strsh)
|
||||
{
|
||||
std::string ret = strsh != NULL ? strsh : "";
|
||||
eina_stringshare_del(strsh);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// @brief Get a lower-case copy of string.
|
||||
///
|
||||
inline std::string
|
||||
safe_lower(std::string const& s)
|
||||
{
|
||||
std::string res;
|
||||
res.resize(s.size());
|
||||
std::transform(s.begin(), s.end(), res.begin(), ::tolower);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// @brief Get a lower-case copy of string.
|
||||
///
|
||||
inline std::string
|
||||
safe_lower(const char *s)
|
||||
{
|
||||
return safe_lower(safe_str(s));
|
||||
}
|
||||
|
||||
/// @brief Get a upper-case copy of string.
|
||||
///
|
||||
inline std::string
|
||||
safe_upper(std::string const& s)
|
||||
{
|
||||
std::string res;
|
||||
res.resize(s.size());
|
||||
std::transform(s.begin(), s.end(), res.begin(), ::toupper);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// @brief Get a upper-case copy of string.
|
||||
///
|
||||
inline std::string
|
||||
safe_upper(const char* s)
|
||||
{
|
||||
return safe_upper(safe_str(s));
|
||||
}
|
||||
|
||||
/// @brief Trim both ends of the string and replaces any
|
||||
/// subsequence of contiguous spaces with a single space.
|
||||
///
|
||||
inline std::string
|
||||
normalize_spaces(std::string const& s)
|
||||
{
|
||||
std::ostringstream os;
|
||||
bool prev_is_space = true;
|
||||
std::remove_copy_if
|
||||
(s.begin(), s.end(),
|
||||
std::ostream_iterator<char>(os),
|
||||
[&prev_is_space] (char c)
|
||||
{
|
||||
bool r = ::isspace(c);
|
||||
if (r && prev_is_space)
|
||||
return true;
|
||||
prev_is_space = r;
|
||||
return false;
|
||||
});
|
||||
std::string r = os.str();
|
||||
if (!r.empty() && ::isspace(r.back()))
|
||||
r.erase(r.end()-1, r.end());
|
||||
return r;
|
||||
}
|
||||
|
||||
/// @brief Return the basename of a path.
|
||||
///
|
||||
inline std::string
|
||||
path_base(std::string path)
|
||||
{
|
||||
std::string::reverse_iterator
|
||||
slash = std::find(path.rbegin(), path.rend(), '/');
|
||||
return std::string(slash.base(), path.end());
|
||||
}
|
||||
|
||||
/// @brief Find-and-replace patterns in a string.
|
||||
///
|
||||
inline std::string
|
||||
find_replace(std::string const& s_,
|
||||
std::string const& old,
|
||||
std::string const& new_)
|
||||
{
|
||||
std::string s = s_;
|
||||
std::string::size_type found = s.find(old);
|
||||
std::string::size_type len = new_.length();
|
||||
while (found != std::string::npos)
|
||||
{
|
||||
s.replace(found, len, new_);
|
||||
found = s.find(old);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/// @brief Append '_' if @p key is a C++ keyword.
|
||||
///
|
||||
inline std::string
|
||||
keyword_avoid(std::string const& name)
|
||||
{
|
||||
if (name == "delete" ||
|
||||
name == "throw" ||
|
||||
name == "break" ||
|
||||
name == "friend" ||
|
||||
name == "goto" ||
|
||||
name == "default" ||
|
||||
name == "new" ||
|
||||
name == "auto" ||
|
||||
name == "do" ||
|
||||
name == "sizeof" ||
|
||||
name == "try" ||
|
||||
name == "this" ||
|
||||
name == "virtual" ||
|
||||
name == "register" ||
|
||||
name == "typename" ||
|
||||
name == "template")
|
||||
{
|
||||
return name + "_"; // XXX Warn?
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/// @brief Append '_' if @p key is a C++ keyword.
|
||||
///
|
||||
inline std::string
|
||||
keyword_avoid(const char* name)
|
||||
{
|
||||
return keyword_avoid(safe_str(name));
|
||||
}
|
||||
|
||||
#endif // EOLIAN_CXX_BIN_SAFE_STRINGS_HH
|
|
@ -1,160 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_TYPE_LOOKUP_HH
|
||||
#define EOLIAN_CXX_TYPE_LOOKUP_HH
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cctype>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
|
||||
#include <Eolian.h>
|
||||
#include <eolian_database.h>
|
||||
|
||||
#include <Eina.hh>
|
||||
|
||||
#include "eo_types.hh"
|
||||
#include "safe_strings.hh"
|
||||
|
||||
namespace eolian_cxx {
|
||||
|
||||
typedef std::vector<efl::eolian::eolian_type> lookup_table_type;
|
||||
extern const lookup_table_type type_lookup_table;
|
||||
|
||||
inline std::string
|
||||
class_format_cxx(std::string const& fullname)
|
||||
{
|
||||
auto current = fullname.begin(), last = fullname.end();
|
||||
auto found = std::find(current, last, '.');
|
||||
std::string new_string;
|
||||
if(found == last)
|
||||
new_string = "nonamespace::" + fullname;
|
||||
else
|
||||
while (current != last)
|
||||
{
|
||||
if(found == last)
|
||||
{
|
||||
new_string.insert(new_string.end(), current, found);
|
||||
current = found;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_string += std::tolower(*current);
|
||||
new_string.insert(new_string.end(), std::next(current), found);
|
||||
new_string = safe_lower(new_string);
|
||||
new_string += "::";
|
||||
current = std::next(found);
|
||||
found = std::find(current, last, '.');
|
||||
}
|
||||
}
|
||||
return new_string;
|
||||
}
|
||||
|
||||
inline bool
|
||||
type_is_complex(Eolian_Type const& type)
|
||||
{
|
||||
return ::eolian_type_type_get(&type) == EOLIAN_TYPE_COMPLEX;
|
||||
}
|
||||
|
||||
inline efl::eolian::eolian_type
|
||||
type_from_eolian(Eolian_Type const& type)
|
||||
{
|
||||
efl::eolian::eolian_type x;
|
||||
|
||||
Eolian_Type_Type tpt = ::eolian_type_type_get(&type);
|
||||
if (tpt == EOLIAN_TYPE_CLASS)
|
||||
{
|
||||
Eolian_Class const* klass = ::eolian_type_class_get(&type);
|
||||
if (klass)
|
||||
{
|
||||
x.category = efl::eolian::eolian_type::simple_;
|
||||
x.is_class = true;
|
||||
x.binding_requires_optional = false;
|
||||
x.binding = "::" + class_format_cxx(safe_str(::eolian_class_full_name_get(klass)));
|
||||
x.native = "::";
|
||||
x.native += safe_str( ::eolian_class_full_name_get(klass));
|
||||
std::replace(x.native.begin(), x.native.end(), '.', '_');
|
||||
|
||||
if( ::eolian_type_is_const(&type))
|
||||
x.native += " const";
|
||||
|
||||
x.native += '*';
|
||||
|
||||
Eina_Stringshare* klass_file = ::eolian_class_file_get(klass);
|
||||
if (klass_file)
|
||||
x.includes = {safe_str(klass_file) + ".hh"};
|
||||
}
|
||||
}
|
||||
|
||||
if(x.native.empty())
|
||||
x.native = normalize_spaces(safe_str(::eolian_type_c_type_get(&type)));
|
||||
x.is_own = ::eolian_type_is_own(&type);
|
||||
x.is_const = ::eolian_type_is_const(&type);
|
||||
return x;
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
inline const efl::eolian::eolian_type&
|
||||
type_find(Iterator first, Iterator last, efl::eolian::eolian_type const& type)
|
||||
{
|
||||
auto res = std::find_if
|
||||
(first, last,
|
||||
[&type] (efl::eolian::eolian_type const& x)
|
||||
{
|
||||
return (x.native == type.native && x.is_own == type.is_own);
|
||||
});
|
||||
return (res != last) ? *res : type;
|
||||
}
|
||||
|
||||
inline efl::eolian::eolian_type_instance
|
||||
type_lookup(const Eolian_Type* type,
|
||||
lookup_table_type const& lut = type_lookup_table)
|
||||
{
|
||||
if (type == NULL) return { efl::eolian::void_type }; // XXX shouldn't
|
||||
// assert(type != NULL);
|
||||
|
||||
std::vector<Eolian_Type const*> types;
|
||||
types.push_back(type);
|
||||
|
||||
if (type_is_complex(*type))
|
||||
{
|
||||
efl::eina::iterator<Eolian_Type const> end;
|
||||
efl::eina::iterator<Eolian_Type const> it
|
||||
(::eolian_type_subtypes_get(type));
|
||||
while(it != end)
|
||||
{
|
||||
if(Eolian_Type const* t = &*it)
|
||||
{
|
||||
types.push_back
|
||||
/* remove this base type get when pointers are removed */
|
||||
( ::eolian_type_type_get(t) == EOLIAN_TYPE_POINTER ? ::eolian_type_base_type_get(t)
|
||||
: t
|
||||
);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
efl::eolian::eolian_type_instance v(types.size());
|
||||
for (std::size_t i = 0; i != types.size(); ++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.parts.size() == 1 && type_is_complex(v.front()))
|
||||
{
|
||||
efl::eolian::eolian_type tmp = v.front();
|
||||
return {efl::eolian::type_to_native(tmp)};
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
} // namespace eolian_cxx {
|
||||
|
||||
#endif // EOLIAN_CXX_TYPE_LOOKUP_HH
|
|
@ -1,36 +0,0 @@
|
|||
#include "type_lookup.hh"
|
||||
|
||||
namespace eolian_cxx {
|
||||
|
||||
using efl::eolian::eolian_type;
|
||||
|
||||
const lookup_table_type
|
||||
type_lookup_table
|
||||
{
|
||||
{"Ecore_Cb", eolian_type::callback_, {"Ecore.h"}},
|
||||
{"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, true, false, "::efl::eina::accessor", {"eina_accessor.hh"}},
|
||||
{"Eina_Bool", eolian_type::simple_, false, false, false, false, "bool", {}},
|
||||
{"Eina_Bool *", eolian_type::simple_, false, false, false, false, "bool*", {}},
|
||||
{"Eina_Inlist *", eolian_type::complex_, false, false, true, true, "::efl::eina::range_inlist", {"eina_inlist.hh"}},
|
||||
{"Eina_Inlist *", eolian_type::complex_, false, true, true, true, "::efl::eina::inlist", {"eina_inlist.hh"}},
|
||||
{"Eina_Iterator *", eolian_type::complex_, false, false, true, true, "::efl::eina::iterator", {"eina_iterator.hh"}},
|
||||
{"Eina_List *", eolian_type::complex_, false, false, true, true, "::efl::eina::range_list", {"eina_list.hh"}},
|
||||
{"Eina_List *", eolian_type::complex_, false, true, true, true, "::efl::eina::list", {"eina_list.hh"}},
|
||||
{"const Eina_List *", eolian_type::complex_, true, false, true, true, "::efl::eina::crange_list", {"eina_list.hh"}},
|
||||
{"Eina_Array *", eolian_type::complex_, false, false, true, true, "::efl::eina::range_array", {"eina_array.hh"}},
|
||||
{"Eina_Array *", eolian_type::complex_, false, true, true, true, "::efl::eina::array", {"eina_array.hh"}},
|
||||
{"const Eina_Array *", eolian_type::complex_, true, false, true, true, "::efl::eina::crange_array", {"eina_array.hh"}},
|
||||
{"Eio_Filter_Direct_Cb", eolian_type::callback_, {"Eio.h"}},
|
||||
{"Eo *", eolian_type::simple_, false, true, true, false, "::efl::eo::concrete", {"eo_concrete.hh"}},
|
||||
{"Eo *", eolian_type::simple_, false, false, true, false, "::efl::eo::concrete", {"eo_concrete.hh"}},
|
||||
//{"Evas_Object_Box_Layout", eolian_type::callback_, {"Evas.h"}},
|
||||
//{"char *", eolian_type::simple_, false, true, true, false, "std::unique_ptr<char*>", {"memory"}},
|
||||
{"const Eina_Inlist *", eolian_type::complex_, false, false, true, true, "::efl::eina::range_inlist", {"eina_inlist.hh"}},
|
||||
{"const Eina_List *", eolian_type::complex_, false, false, true, true, "::efl::eina::range_list", {"eina_ptrlist.hh"}},
|
||||
{"const char *", eolian_type::simple_, false, false, true, true, "::efl::eina::string_view", {"string"}},
|
||||
};
|
||||
|
||||
}
|
|
@ -4,6 +4,9 @@
|
|||
#include <eo_concrete.hh>
|
||||
#include <eo_init.hh>
|
||||
#include <eo_wref.hh>
|
||||
#include <eo_inherit.hh>
|
||||
// #include <eo_inherit.hh>
|
||||
//#include <eo_own_ptr.hh>
|
||||
#include <eo_cxx_interop.hh>
|
||||
#include <eo_event.hh>
|
||||
|
||||
#endif // EFL_CXX_EO_HH
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include <eina_optional.hh>
|
||||
|
||||
#include "eo_ops.hh"
|
||||
#include "eo_event.hh"
|
||||
|
||||
#ifndef EFL_CXX_THROW
|
||||
#if defined ( EFL_CXX_NO_EXCEPTIONS )
|
||||
|
@ -22,9 +21,9 @@
|
|||
#endif
|
||||
|
||||
#if !defined(EFL_DOXYGEN) && !defined(EO_CXX_INHERIT)
|
||||
# define EO_CXX_INHERIT(name) ::eo_cxx::name
|
||||
# define EO_CXX_INHERIT(name) ::eo_cxx name
|
||||
#elif !defined(EO_CXX_INHERIT)
|
||||
# define EO_CXX_INHERIT(name) ::name
|
||||
# define EO_CXX_INHERIT(name) name
|
||||
#endif
|
||||
|
||||
namespace efl { namespace eo {
|
||||
|
@ -137,53 +136,11 @@ struct concrete
|
|||
_eo_raw = _ptr;
|
||||
}
|
||||
|
||||
/// @brief Get the reference count of this object.
|
||||
///
|
||||
/// @return The referencer count of this object.
|
||||
///
|
||||
int ref_get() const { return detail::ref_get(_eo_raw); }
|
||||
|
||||
/// @brief Set the parent of this object.
|
||||
///
|
||||
/// @param parent The new 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::concrete instance that binds the parent
|
||||
/// object. Returns NULL if there is no parent.
|
||||
///
|
||||
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 concrete(r);
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Get debug information of this object.
|
||||
///
|
||||
/// @return The root node of the debug information tree.
|
||||
///
|
||||
Eo_Dbg_Info dbg_info_get()
|
||||
{
|
||||
Eo_Dbg_Info info;
|
||||
detail::dbg_info_get(_eo_raw, &info);
|
||||
return info;
|
||||
}
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return _eo_raw;
|
||||
}
|
||||
protected:
|
||||
protected:
|
||||
Eo* _eo_raw; ///< The opaque <em>EO Object</em>.
|
||||
};
|
||||
|
||||
|
@ -223,20 +180,6 @@ struct extension_inheritance<concrete>
|
|||
};
|
||||
};
|
||||
|
||||
struct concrete_address_of
|
||||
{
|
||||
explicit concrete_address_of(void* p) : p(p) {}
|
||||
operator void*() { return p; }
|
||||
void* p;
|
||||
};
|
||||
|
||||
struct concrete_address_const_of
|
||||
{
|
||||
explicit concrete_address_const_of(void const* p) : p(p) {}
|
||||
operator void const*() { return p; }
|
||||
void const* p;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/// @brief Downcast @p U to @p T.
|
||||
|
@ -264,42 +207,17 @@ T downcast(U object)
|
|||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Type used to hold the parent passed to concrete Eo C++
|
||||
/// constructors.
|
||||
///
|
||||
struct parent_type
|
||||
{
|
||||
Eo* _eo_raw;
|
||||
};
|
||||
|
||||
///
|
||||
/// @brief The expression type declaring the assignment operator used
|
||||
/// in the parent argument of the concrete Eo C++ class.
|
||||
///
|
||||
struct parent_expr
|
||||
{
|
||||
parent_type operator=(efl::eo::concrete const& parent) const
|
||||
{
|
||||
return { parent._eo_ptr() };
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
parent_type operator=(T const& parent) const
|
||||
{
|
||||
return { parent._eo_ptr() };
|
||||
}
|
||||
parent_type operator=(std::nullptr_t) const
|
||||
{
|
||||
return { nullptr };
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// @brief Placeholder for the parent argument.
|
||||
///
|
||||
parent_expr const parent = {};
|
||||
|
||||
template <typename T>
|
||||
struct is_eolian_object : std::false_type {};
|
||||
template <typename T>
|
||||
struct is_eolian_object<T const> : is_eolian_object<T> {};
|
||||
template <typename T>
|
||||
struct is_eolian_object<T const&> : is_eolian_object<T> {};
|
||||
template <typename T>
|
||||
struct is_eolian_object<T&> : is_eolian_object<T> {};
|
||||
template <>
|
||||
struct is_eolian_object<eo::concrete> : std::true_type {};
|
||||
|
||||
/// @}
|
||||
|
||||
} } // namespace efl { namespace eo {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,11 +8,13 @@
|
|||
|
||||
#include <Eo.h>
|
||||
#include <Ecore.h>
|
||||
#include "eo_concrete.hh"
|
||||
#include "eo_cxx_interop.hh"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace efl { namespace eo {
|
||||
namespace efl { namespace eolian {
|
||||
|
||||
typedef ::Eo_Callback_Priority callback_priority;
|
||||
namespace callback_priorities
|
||||
|
@ -121,30 +123,77 @@ signal_connection make_signal_connection(std::unique_ptr<F>& data, Eo* eo, ::Eo_
|
|||
|
||||
namespace _detail {
|
||||
|
||||
template <typename T, typename F>
|
||||
Eina_Bool really_call_event(T& wrapper, F& f, Eo_Event_Description const& desc, void *info
|
||||
, std::true_type)
|
||||
template <typename T, typename P, typename F>
|
||||
Eina_Bool really_call_event(T& wrapper, F& f, void *, std::true_type, std::true_type)
|
||||
{
|
||||
f(wrapper, desc, info);
|
||||
f(wrapper);
|
||||
return true;
|
||||
}
|
||||
template <typename T, typename F>
|
||||
Eina_Bool really_call_event(T& wrapper, F& f, Eo_Event_Description const& desc, void *info
|
||||
, std::false_type)
|
||||
template <typename T, typename P, typename F>
|
||||
Eina_Bool really_call_event(T& wrapper, F& f, void *info, std::true_type, std::false_type)
|
||||
{
|
||||
return f(wrapper, desc, info);
|
||||
f(wrapper, convert_to_event<P>(info));
|
||||
return true;
|
||||
}
|
||||
template <typename T, typename P, typename F>
|
||||
Eina_Bool really_call_event(T& wrapper, F& f, void *, std::false_type, std::true_type)
|
||||
{
|
||||
return f(wrapper);
|
||||
}
|
||||
template <typename T, typename P, typename F>
|
||||
Eina_Bool really_call_event(T& wrapper, F& f, void *info, std::false_type, std::false_type)
|
||||
{
|
||||
return f(wrapper, convert_to_event<P>(info));
|
||||
}
|
||||
|
||||
template <typename T, typename P, typename F, typename Enable = void>
|
||||
struct is_void;
|
||||
template <typename T, typename P, typename F>
|
||||
struct is_void<T, P, F, typename std::enable_if
|
||||
<std::is_void<decltype(std::declval<F>()(std::declval<T>(), std::declval<P>()))>::value>::type>
|
||||
: std::true_type {};
|
||||
template <typename T, typename P, typename F>
|
||||
struct is_void<T, P, F, typename std::enable_if
|
||||
<!std::is_void<decltype(std::declval<F>()(std::declval<T>(), std::declval<P>()))>::value>::type>
|
||||
: std::false_type {};
|
||||
template <typename T, typename F>
|
||||
struct is_void<T, void, F, typename std::enable_if
|
||||
<std::is_void<decltype(std::declval<F>()(std::declval<T>()))>::value>::type>
|
||||
: std::true_type {};
|
||||
template <typename T, typename F>
|
||||
struct is_void<T, void, F, typename std::enable_if
|
||||
<!std::is_void<decltype(std::declval<F>()(std::declval<T>()))>::value>::type>
|
||||
: std::false_type {};
|
||||
|
||||
template <typename T, typename P, typename F>
|
||||
Eina_Bool
|
||||
event_callback(void *data, ::Eo_Event const* event)
|
||||
{
|
||||
T wrapper(::eo_ref(event->object));
|
||||
F *f = static_cast<F*>(data);
|
||||
return _detail::really_call_event(wrapper, *f, *event->desc, event->info
|
||||
, std::is_void<decltype((*f)(wrapper, *event->desc, event->info))>());
|
||||
return _detail::really_call_event<T, P>
|
||||
(wrapper, *f, event->info, is_void<T, P, F>(), std::is_void<P>{});
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Event, typename Object, typename F>
|
||||
signal_connection event_add(Event event, Object object, F&& function)
|
||||
{
|
||||
static_assert((eo::is_eolian_object<Object>::value), "Type is not an object");
|
||||
|
||||
typedef typename std::remove_reference<F>::type function_type;
|
||||
std::unique_ptr<function_type> f(new function_type(std::forward<F>(function)));
|
||||
|
||||
::eo_event_callback_priority_add
|
||||
(object._eo_ptr(), event.description(), 0
|
||||
, static_cast<Eo_Event_Cb>
|
||||
(&_detail::event_callback<Object, typename Event::parameter_type, function_type>)
|
||||
, f.get());
|
||||
return make_signal_connection
|
||||
(f, object._eo_ptr()
|
||||
, static_cast<Eo_Event_Cb>
|
||||
(&_detail::event_callback<Object, typename Event::parameter_type, function_type>)
|
||||
, event.description());
|
||||
}
|
||||
|
||||
} }
|
||||
|
|
|
@ -1,155 +1,155 @@
|
|||
|
||||
///
|
||||
/// @file eo_inherit.hh
|
||||
///
|
||||
// ///
|
||||
// /// @file eo_inherit.hh
|
||||
// ///
|
||||
|
||||
#ifndef EFL_CXX_EO_INHERIT_HH
|
||||
#define EFL_CXX_EO_INHERIT_HH
|
||||
// #ifndef EFL_CXX_EO_INHERIT_HH
|
||||
// #define EFL_CXX_EO_INHERIT_HH
|
||||
|
||||
#include <tuple>
|
||||
#include <cassert>
|
||||
// #include <tuple>
|
||||
// #include <cassert>
|
||||
|
||||
#include <eina_integer_sequence.hh>
|
||||
// #include <eina_integer_sequence.hh>
|
||||
|
||||
#include "eo_ops.hh"
|
||||
#include "eo_private.hh"
|
||||
#include "eo_cxx_interop.hh"
|
||||
// #include "eo_ops.hh"
|
||||
// #include "eo_private.hh"
|
||||
// #include "eo_cxx_interop.hh"
|
||||
|
||||
namespace efl { namespace eo {
|
||||
// namespace efl { namespace eo {
|
||||
|
||||
namespace detail {
|
||||
// namespace detail {
|
||||
|
||||
template <typename D, typename... E, std::size_t... S>
|
||||
Eo_Class const* create_class(eina::index_sequence<S...>);
|
||||
// template <typename D, typename... E, std::size_t... S>
|
||||
// Eo_Class const* create_class(eina::index_sequence<S...>);
|
||||
|
||||
/// @internal
|
||||
///
|
||||
/// @brief Find the correct function for the <em>"constructor"</em>
|
||||
/// operation and invoke it.
|
||||
///
|
||||
/// @param this_ The <em>user data</em> to be passed to the resolved function.
|
||||
/// @param args An heterogeneous sequence of arguments.
|
||||
///
|
||||
inline EO_VOID_FUNC_BODYV(inherit_constructor, EO_FUNC_CALL(this_), void* this_);
|
||||
// /// @internal
|
||||
// ///
|
||||
// /// @brief Find the correct function for the <em>"constructor"</em>
|
||||
// /// operation and invoke it.
|
||||
// ///
|
||||
// /// @param this_ The <em>user data</em> to be passed to the resolved function.
|
||||
// /// @param args An heterogeneous sequence of arguments.
|
||||
// ///
|
||||
// inline EO_VOID_FUNC_BODYV(inherit_constructor, EO_FUNC_CALL(this_), void* this_);
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
/// @addtogroup Efl_Cxx_API
|
||||
/// @{
|
||||
// /// @addtogroup Efl_Cxx_API
|
||||
// /// @{
|
||||
|
||||
/// @brief Template-class that allows client code to inherit from
|
||||
/// <em>EO C++ Classes</em> without the need to make explicit calls to
|
||||
/// <em>EO</em> methods --- that would naturally be necessary to
|
||||
/// register itself in the <em>EO Subsystem</em>.
|
||||
///
|
||||
/// @param D The derived class
|
||||
/// @param O The parent class
|
||||
/// @param E Class extensions (either mixins or interfaces)
|
||||
///
|
||||
/// 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::concrete) since every EO C++ Class must
|
||||
/// inherit from it.
|
||||
///
|
||||
/// efl::eo::inherit makes use of meta-template elements to build (in
|
||||
/// compile-time) code capable of registering @p D as an <em>EO
|
||||
/// Class</em> within <em>EO Subsystem</em>. Each class is registered
|
||||
/// only once upon instantiation of an object of its type.
|
||||
///
|
||||
/// @note Function overriding is currently not supported.
|
||||
///
|
||||
template <typename D, typename... E>
|
||||
struct inherit;
|
||||
// /// @brief Template-class that allows client code to inherit from
|
||||
// /// <em>EO C++ Classes</em> without the need to make explicit calls to
|
||||
// /// <em>EO</em> methods --- that would naturally be necessary to
|
||||
// /// register itself in the <em>EO Subsystem</em>.
|
||||
// ///
|
||||
// /// @param D The derived class
|
||||
// /// @param O The parent class
|
||||
// /// @param E Class extensions (either mixins or interfaces)
|
||||
// ///
|
||||
// /// 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::concrete) since every EO C++ Class must
|
||||
// /// inherit from it.
|
||||
// ///
|
||||
// /// efl::eo::inherit makes use of meta-template elements to build (in
|
||||
// /// compile-time) code capable of registering @p D as an <em>EO
|
||||
// /// Class</em> within <em>EO Subsystem</em>. Each class is registered
|
||||
// /// only once upon instantiation of an object of its type.
|
||||
// ///
|
||||
// /// @note Function overriding is currently not supported.
|
||||
// ///
|
||||
// template <typename D, typename... E>
|
||||
// struct inherit;
|
||||
|
||||
/// @}
|
||||
// /// @}
|
||||
|
||||
/// @addtogroup Efl_Cxx_API
|
||||
/// @{
|
||||
// /// @addtogroup Efl_Cxx_API
|
||||
// /// @{
|
||||
|
||||
template <typename D, typename... E>
|
||||
struct inherit
|
||||
: detail::operations<E>::template type<inherit<D, E...> > ...
|
||||
, detail::conversion_operator<inherit<D, E...>, E>...
|
||||
{
|
||||
/// @typedef inherit_base
|
||||
///
|
||||
typedef inherit<D, E...> inherit_base;
|
||||
// template <typename D, typename... E>
|
||||
// struct inherit
|
||||
// : detail::operations<E>::template type<inherit<D, E...> > ...
|
||||
// , detail::conversion_operator<inherit<D, E...>, E>...
|
||||
// {
|
||||
// /// @typedef inherit_base
|
||||
// ///
|
||||
// typedef inherit<D, E...> inherit_base;
|
||||
|
||||
//@{
|
||||
/// @brief Class constructor.
|
||||
///
|
||||
/// @ref inherit has a "variadic" constructor implementation that
|
||||
/// allows from zero to EFL_MAX_ARGS heterogeneous parameters.
|
||||
///
|
||||
template<typename... Args>
|
||||
inherit(efl::eo::parent_type _p, Args&& ... args)
|
||||
{
|
||||
_eo_cls = detail::create_class<D, E...> (eina::make_index_sequence<sizeof...(E)>());
|
||||
_eo_raw = eo_add_ref(_eo_cls, _p._eo_raw, detail::inherit_constructor(eo_self, this), ::efl::eolian::call_ctors(eo_self, args...));
|
||||
::efl::eolian::register_ev_del_free_callback(_eo_raw, args...);
|
||||
}
|
||||
// //@{
|
||||
// /// @brief Class constructor.
|
||||
// ///
|
||||
// /// @ref inherit has a "variadic" constructor implementation that
|
||||
// /// allows from zero to EFL_MAX_ARGS heterogeneous parameters.
|
||||
// ///
|
||||
// template<typename... Args>
|
||||
// inherit(efl::eo::parent_type _p, Args&& ... args)
|
||||
// {
|
||||
// _eo_cls = detail::create_class<D, E...> (eina::make_index_sequence<sizeof...(E)>());
|
||||
// _eo_raw = eo_add_ref(_eo_cls, _p._eo_raw, detail::inherit_constructor(eo_self, this), ::efl::eolian::call_ctors(eo_self, args...));
|
||||
// ::efl::eolian::register_ev_del_free_callback(_eo_raw, args...);
|
||||
// }
|
||||
|
||||
template<typename... Args>
|
||||
inherit(Args&& ... args)
|
||||
: inherit(::efl::eo::parent = nullptr, std::forward<Args>(args)...)
|
||||
{}
|
||||
//@}
|
||||
// template<typename... Args>
|
||||
// inherit(Args&& ... args)
|
||||
// : inherit(::efl::eo::parent = nullptr, std::forward<Args>(args)...)
|
||||
// {}
|
||||
// //@}
|
||||
|
||||
/// @brief Class destructor.
|
||||
///
|
||||
~inherit()
|
||||
{
|
||||
detail::unref(_eo_raw);
|
||||
}
|
||||
// /// @brief Class destructor.
|
||||
// ///
|
||||
// ~inherit()
|
||||
// {
|
||||
// detail::unref(_eo_raw);
|
||||
// }
|
||||
|
||||
/// @brief Gets the <em>EO Object</em> corresponding to this <em>EO
|
||||
/// C++ Object</em>.
|
||||
///
|
||||
/// @return A pointer to the <em>EO Object</em>.
|
||||
///
|
||||
Eo* _eo_ptr() const { return _eo_raw; }
|
||||
// /// @brief Gets the <em>EO Object</em> corresponding to this <em>EO
|
||||
// /// C++ Object</em>.
|
||||
// ///
|
||||
// /// @return A pointer to the <em>EO Object</em>.
|
||||
// ///
|
||||
// Eo* _eo_ptr() const { return _eo_raw; }
|
||||
|
||||
/// @brief Gets the <em>EO Class</em> corresponding to this <em>EO
|
||||
/// C++ Class</em>.
|
||||
///
|
||||
/// @return A pointer to the <em>EO Class</em>.
|
||||
///
|
||||
Eo_Class const* _eo_class() const { return _eo_cls; }
|
||||
// /// @brief Gets the <em>EO Class</em> corresponding to this <em>EO
|
||||
// /// C++ Class</em>.
|
||||
// ///
|
||||
// /// @return A pointer to the <em>EO Class</em>.
|
||||
// ///
|
||||
// Eo_Class const* _eo_class() const { return _eo_cls; }
|
||||
|
||||
Eo* _release()
|
||||
{
|
||||
Eo* tmp = _eo_raw;
|
||||
_eo_raw = nullptr;
|
||||
return tmp;
|
||||
}
|
||||
// Eo* _release()
|
||||
// {
|
||||
// Eo* tmp = _eo_raw;
|
||||
// _eo_raw = nullptr;
|
||||
// return tmp;
|
||||
// }
|
||||
|
||||
protected:
|
||||
/// @brief Copy constructor.
|
||||
///
|
||||
inherit(inherit const& other)
|
||||
: _eo_cls(other._eo_cls)
|
||||
, _eo_raw(other._eo_raw)
|
||||
{ detail::ref(_eo_raw); }
|
||||
// protected:
|
||||
// /// @brief Copy constructor.
|
||||
// ///
|
||||
// inherit(inherit const& other)
|
||||
// : _eo_cls(other._eo_cls)
|
||||
// , _eo_raw(other._eo_raw)
|
||||
// { detail::ref(_eo_raw); }
|
||||
|
||||
/// @brief Assignment Operator
|
||||
///
|
||||
inherit& operator=(inherit const& other)
|
||||
{
|
||||
_eo_cls = other._eo_cls;
|
||||
_eo_raw = other._eo_raw;
|
||||
detail::ref(_eo_raw);
|
||||
return *this;
|
||||
}
|
||||
// /// @brief Assignment Operator
|
||||
// ///
|
||||
// inherit& operator=(inherit const& other)
|
||||
// {
|
||||
// _eo_cls = other._eo_cls;
|
||||
// _eo_raw = other._eo_raw;
|
||||
// detail::ref(_eo_raw);
|
||||
// return *this;
|
||||
// }
|
||||
|
||||
private:
|
||||
Eo_Class const* _eo_cls; ///< The <em>EO Class</em>.
|
||||
Eo* _eo_raw; ///< The <em>EO Object</em>.
|
||||
};
|
||||
// private:
|
||||
// Eo_Class const* _eo_cls; ///< The <em>EO Class</em>.
|
||||
// Eo* _eo_raw; ///< The <em>EO Object</em>.
|
||||
// };
|
||||
|
||||
/// @}
|
||||
// /// @}
|
||||
|
||||
} } // namespace efl { namespace eo {
|
||||
// } } // namespace efl { namespace eo {
|
||||
|
||||
#include "eo_inherit_bindings.hh"
|
||||
// #include "eo_inherit_bindings.hh"
|
||||
|
||||
#endif // EFL_CXX_INHERIT_HH
|
||||
// #endif // EFL_CXX_INHERIT_HH
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#define EFL_EO_API_SUPPORT
|
||||
|
||||
#include <Elementary.hh>
|
||||
|
||||
EAPI_MAIN int
|
||||
|
@ -5,16 +7,11 @@ elm_main (int argc, char *argv[])
|
|||
{
|
||||
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_HIDDEN);
|
||||
|
||||
::elm::win_standard win;
|
||||
win.title_set("Bg Plain");
|
||||
::elm::win::Standard win;
|
||||
// win.title_set("Bg Plain");
|
||||
win.autohide_set(true);
|
||||
|
||||
::elm::bg bg(efl::eo::parent = win);
|
||||
bg.size_hint_weight_set(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
win.resize_object_add(bg);
|
||||
bg.visible_set(true);
|
||||
|
||||
win.size_set(320,320);
|
||||
win.eo_cxx::efl::Gfx::size_set(320,320);
|
||||
win.visible_set(true);
|
||||
|
||||
elm_run();
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#define EFL_EO_API_SUPPORT
|
||||
|
||||
#include <Elementary.hh>
|
||||
|
||||
EAPI_MAIN int
|
||||
|
@ -5,28 +7,23 @@ elm_main (int argc, char *argv[])
|
|||
{
|
||||
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_HIDDEN);
|
||||
|
||||
::elm::win_standard win;
|
||||
win.title_set("Hello, World!");
|
||||
::elm::win::Standard win;
|
||||
//win.title_set("Hello, World!");
|
||||
win.autohide_set(true);
|
||||
|
||||
::elm::bg bg(efl::eo::parent = win);
|
||||
bg.size_hint_weight_set(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
win.resize_object_add(bg);
|
||||
bg.visible_set(true);
|
||||
|
||||
::elm::button btn(efl::eo::parent = win);
|
||||
::elm::Button btn(win);
|
||||
btn.text_set("elm.text","Good-Bye, World!");
|
||||
btn.size_set(120, 30);
|
||||
btn.position_set(60, 15);
|
||||
btn.size_hint_weight_set(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
btn.size_hint_align_set(EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
btn.eo_cxx::efl::Gfx::size_set(120, 30);
|
||||
btn.eo_cxx::efl::Gfx::position_set(60, 15);
|
||||
// btn.size_hint_weight_set(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
// btn.size_hint_align_set(EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
btn.visible_set(true);
|
||||
|
||||
auto on_click = std::bind([] () { elm_exit(); });
|
||||
|
||||
btn.callback_clicked_add( on_click );
|
||||
efl::eolian::event_add(evas::Clickable_Interface::clicked_event, btn, on_click);
|
||||
|
||||
win.size_set(240, 60);
|
||||
win.eo_cxx::efl::Gfx::size_set(240, 60);
|
||||
win.visible_set(true);
|
||||
|
||||
elm_run();
|
||||
|
|
|
@ -93,15 +93,15 @@ IMPL = \
|
|||
|
||||
SRCS = \
|
||||
eolian_cxx_simple_01.cc \
|
||||
eolian_cxx_inherit_01.cc \
|
||||
eolian_cxx_callbacks_01.cc \
|
||||
$(IMPL)
|
||||
# eolian_cxx_inherit_01.cc
|
||||
|
||||
EXTRA_PROGRAMS = \
|
||||
eolian_cxx_simple_01 \
|
||||
eolian_cxx_simple_01_cxx_impl \
|
||||
eolian_cxx_inherit_01 \
|
||||
eolian_cxx_callbacks_01
|
||||
# eolian_cxx_inherit_01
|
||||
|
||||
DATA_FILES = Makefile.examples $(ECXX_EXAMPLE_EOS)
|
||||
EXTRA_DIST = $(DATA_FILES)
|
||||
|
@ -120,11 +120,11 @@ eolian_cxx_simple_01_cxx_impl_SOURCES = \
|
|||
colourablesquare_cxx.cc
|
||||
eolian_cxx_simple_01_cxx_impl.$(OBJEXT): $(GENERATED)
|
||||
|
||||
eolian_cxx_inherit_01_SOURCES = \
|
||||
eolian_cxx_inherit_01.cc \
|
||||
colourable.c \
|
||||
colourablesquare.c
|
||||
eolian_cxx_inherit_01.$(OBJEXT): $(GENERATED)
|
||||
# eolian_cxx_inherit_01_SOURCES = \
|
||||
# eolian_cxx_inherit_01.cc \
|
||||
# colourable.c \
|
||||
# colourablesquare.c
|
||||
# eolian_cxx_inherit_01.$(OBJEXT): $(GENERATED)
|
||||
|
||||
eolian_cxx_callbacks_01_SOURCES = eolian_cxx_callbacks_01.cc
|
||||
|
||||
|
|
|
@ -63,7 +63,6 @@ _ns_colourable_rgb_24bits_constructor(Eo *obj, Colourable_Data *self, int rgb)
|
|||
self->g = (rgb & 0x0000ff00) >> 8;
|
||||
self->b = rgb & 0x000000ff;
|
||||
DBG("_ns_colourable_rgb_24bits_constructor(0x%.6x)\n", (int)rgb);
|
||||
eo_constructor(eo_super(obj, MY_CLASS));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -42,7 +42,6 @@ _colourable_rgb_24bits_constructor(Eo *obj, Colourable_Data *self, int rgb)
|
|||
self->r = (rgb & 0x00ff0000) >> 16;
|
||||
self->g = (rgb & 0x0000ff00) >> 8;
|
||||
self->b = rgb & 0x000000ff;
|
||||
eo_constructor(eo_super(obj, MY_CLASS));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -35,7 +35,6 @@ _ns_colourablesquare_size_constructor(Eo *obj, ColourableSquare_Data *self, int
|
|||
}
|
||||
self->size = size;
|
||||
DBG("_ns_colourablesquare_constructor(%d)\n", size);
|
||||
eo_constructor(eo_super(obj, MY_CLASS));
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -25,7 +25,6 @@ _colourablesquare_size_constructor(Eo *obj, ColourableSquare_Data *self, int siz
|
|||
{
|
||||
self->size = size;
|
||||
EINA_CXX_DOM_LOG_DBG(domain) << __func__ << " [ size = " << size << " ]" << std::endl;
|
||||
eo_constructor(eo_super(obj, MY_CLASS));
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -18,15 +18,13 @@ main()
|
|||
eina_log_domain_level_set("colourablesquare", EINA_LOG_LEVEL_DBG);
|
||||
|
||||
int r, g, b;
|
||||
::ns::Colourable obj1(
|
||||
obj1.rgb_24bits_constructor(0x123456)
|
||||
);
|
||||
::ns::Colourable obj1
|
||||
([&] { obj1.rgb_24bits_constructor(0x123456); });
|
||||
obj1.colour_set(0xc0ffee);
|
||||
obj1.composite_colour_get(&r, &g, &b);
|
||||
obj1.composite_colour_get(r, g, b);
|
||||
|
||||
::ns::ColourableSquare obj2(
|
||||
obj2.size_constructor(10)
|
||||
);
|
||||
::ns::ColourableSquare obj2
|
||||
([&] { obj2.size_constructor(10); });
|
||||
obj2.composite_colour_set(r, g, b);
|
||||
obj2.size_set(11);
|
||||
assert(obj1.colour_get() == obj2.colour_get());
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
class Ns.Colourable (Eo.Base)
|
||||
{
|
||||
[[Colourable class.]]
|
||||
legacy_prefix: legacy;
|
||||
data: Colourable_Data;
|
||||
methods {
|
||||
rgb_24bits_constructor {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
class Ns.ColourableSquare (Ns.Colourable)
|
||||
{
|
||||
legacy_prefix: legacy;
|
||||
data: ColourableSquare_Data;
|
||||
methods {
|
||||
@property size {
|
||||
|
|
|
@ -26,12 +26,4 @@ struct eolian_init
|
|||
|
||||
} }
|
||||
|
||||
#ifdef EFL_BETA_API_SUPPORT
|
||||
|
||||
#include "eo_types.hh"
|
||||
#include "eo_validate.hh"
|
||||
#include "eo_generate.hh"
|
||||
|
||||
#endif
|
||||
|
||||
#endif // EOLIAN_CXX_LIB_HH
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_EO_GENERATE_HH
|
||||
#define EOLIAN_CXX_EO_GENERATE_HH
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
#include "eo_types.hh"
|
||||
#include "grammar/eo_header_generator.hh"
|
||||
|
||||
namespace efl { namespace eolian {
|
||||
|
||||
inline void
|
||||
generate(std::ostream& header_decl,
|
||||
std::ostream& header_impl,
|
||||
eo_class const& cls,
|
||||
eo_generator_options const& opts)
|
||||
{
|
||||
grammar::eo_headers_generator(header_decl, header_impl, cls, opts);
|
||||
}
|
||||
|
||||
} }
|
||||
|
||||
#endif // EOLIAN_CXX_EO_GENERATE_HH
|
|
@ -1,350 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_EO_TYPES_HH
|
||||
#define EOLIAN_CXX_EO_TYPES_HH
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
namespace efl { namespace eolian {
|
||||
|
||||
struct eo_constructor;
|
||||
struct eo_parameter;
|
||||
struct eo_function;
|
||||
struct eo_event;
|
||||
|
||||
typedef std::vector<std::string> ancestors_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;
|
||||
typedef std::vector<eo_parameter> parameters_container_type;
|
||||
typedef std::vector<eo_event> events_container_type;
|
||||
|
||||
|
||||
enum class eolian_scope
|
||||
{
|
||||
public_, protected_, private_
|
||||
};
|
||||
|
||||
struct eolian_type
|
||||
{
|
||||
enum category_type
|
||||
{
|
||||
unknown_, simple_, complex_, callback_
|
||||
};
|
||||
|
||||
eolian_type()
|
||||
: native("")
|
||||
, category(unknown_)
|
||||
, is_const(false)
|
||||
, is_own(false)
|
||||
, is_class(false)
|
||||
, binding_requires_optional(false)
|
||||
, binding()
|
||||
, includes()
|
||||
{}
|
||||
|
||||
eolian_type(std::string native_,
|
||||
category_type category_,
|
||||
bool is_const_,
|
||||
bool is_own_,
|
||||
bool is_class_,
|
||||
bool binding_requires_optional_,
|
||||
std::string binding_,
|
||||
includes_container_type includes_)
|
||||
: native(native_)
|
||||
, category(category_)
|
||||
, is_const(is_const_)
|
||||
, is_own(is_own_)
|
||||
, is_class(is_class_)
|
||||
, binding_requires_optional(binding_requires_optional_)
|
||||
, binding(binding_)
|
||||
, includes(includes_)
|
||||
{
|
||||
assert(!native.empty());
|
||||
assert(category != unknown_);
|
||||
}
|
||||
|
||||
eolian_type(std::string native_,
|
||||
category_type category_,
|
||||
includes_container_type const& includes_)
|
||||
: eolian_type(native_, category_, false, false, false, false, "", includes_)
|
||||
{
|
||||
assert(category == callback_);
|
||||
}
|
||||
|
||||
std::string native;
|
||||
category_type category;
|
||||
bool is_const;
|
||||
bool is_own;
|
||||
bool is_class;
|
||||
bool binding_requires_optional;
|
||||
std::string binding;
|
||||
includes_container_type includes;
|
||||
};
|
||||
|
||||
typedef std::vector<eolian_type> eolian_type_container;
|
||||
|
||||
struct eolian_type_instance
|
||||
{
|
||||
eolian_type_instance()
|
||||
: is_out(false)
|
||||
, is_optional(false)
|
||||
, parts()
|
||||
{}
|
||||
|
||||
eolian_type_instance(std::initializer_list<eolian_type> il,
|
||||
bool is_out_ = false,
|
||||
bool is_optional_ = false)
|
||||
: is_out(is_out_)
|
||||
, is_optional(is_optional_)
|
||||
, parts(il)
|
||||
{}
|
||||
|
||||
explicit eolian_type_instance(std::size_t size)
|
||||
: is_out(false)
|
||||
, is_optional(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;
|
||||
bool is_optional;
|
||||
eolian_type_container parts;
|
||||
};
|
||||
|
||||
const efl::eolian::eolian_type
|
||||
void_type { "void", efl::eolian::eolian_type::simple_, false, false, false, false, "", {} };
|
||||
|
||||
inline bool
|
||||
type_is_void(eolian_type_instance const& type)
|
||||
{
|
||||
return type.empty() || type.front().native.compare("void") == 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
type_is_binding(eolian_type const& type)
|
||||
{
|
||||
return !type.binding.empty();
|
||||
}
|
||||
|
||||
inline bool
|
||||
type_is_binding(eolian_type_instance const& type)
|
||||
{
|
||||
assert(!type.empty());
|
||||
return type_is_binding(type.front());
|
||||
}
|
||||
|
||||
inline bool
|
||||
type_is_out(eolian_type_instance const& type)
|
||||
{
|
||||
return type.is_out;
|
||||
}
|
||||
|
||||
inline bool
|
||||
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_class(type.front());
|
||||
}
|
||||
|
||||
inline bool
|
||||
type_binding_requires_optional(eolian_type const& type)
|
||||
{
|
||||
return type.binding_requires_optional;
|
||||
}
|
||||
|
||||
inline bool
|
||||
type_binding_requires_optional(eolian_type_instance const& type)
|
||||
{
|
||||
assert(!type.empty());
|
||||
return type_binding_requires_optional(type.front());
|
||||
}
|
||||
|
||||
inline bool
|
||||
type_is_optional(eolian_type_instance const& type)
|
||||
{
|
||||
return type.is_optional;
|
||||
}
|
||||
|
||||
inline eolian_type
|
||||
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;
|
||||
}
|
||||
|
||||
inline eolian_type
|
||||
type_to_native(eolian_type_instance const& type_ins)
|
||||
{
|
||||
assert(!type_ins.empty());
|
||||
return type_to_native(type_ins.front());
|
||||
}
|
||||
|
||||
inline std::string
|
||||
type_to_native_str(eolian_type_instance const& type_ins)
|
||||
{
|
||||
return type_to_native(type_ins).native;
|
||||
}
|
||||
|
||||
inline bool
|
||||
type_is_complex(eolian_type const& type)
|
||||
{
|
||||
return type.category == eolian_type::complex_;
|
||||
}
|
||||
|
||||
inline bool
|
||||
type_is_complex(eolian_type_instance const& type_ins)
|
||||
{
|
||||
assert(!type_ins.empty());
|
||||
return type_is_complex(type_ins.front());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool
|
||||
type_is_callback(T const&);
|
||||
|
||||
template <>
|
||||
inline bool
|
||||
type_is_callback(eolian_type const& type)
|
||||
{
|
||||
return type.category == eolian_type::callback_;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool
|
||||
type_is_callback(eolian_type_instance const& type_ins)
|
||||
{
|
||||
return type_is_callback(type_ins.front());
|
||||
}
|
||||
|
||||
struct eo_generator_options
|
||||
{
|
||||
std::string header_decl_file_name;
|
||||
std::string header_impl_file_name;
|
||||
includes_container_type cxx_headers;
|
||||
includes_container_type c_headers;
|
||||
};
|
||||
|
||||
struct eo_class
|
||||
{
|
||||
enum eo_class_type
|
||||
{
|
||||
regular_, regular_noninst_, interface_, mixin_
|
||||
};
|
||||
|
||||
eo_class_type type;
|
||||
std::string name;
|
||||
std::string eo_name;
|
||||
ancestors_container_type parents;
|
||||
ancestors_container_type ancestors;
|
||||
constructors_container_type constructors;
|
||||
constructors_container_type optional_constructors;
|
||||
constructors_container_type all_constructors;
|
||||
functions_container_type functions;
|
||||
events_container_type own_events;
|
||||
events_container_type concrete_events;
|
||||
std::string comment;
|
||||
std::string name_space;
|
||||
};
|
||||
|
||||
struct eo_parameter
|
||||
{
|
||||
eolian_type_instance type;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
struct eo_constructor
|
||||
{
|
||||
std::string name;
|
||||
std::string impl;
|
||||
parameters_container_type params;
|
||||
std::string comment;
|
||||
};
|
||||
|
||||
struct eo_function
|
||||
{
|
||||
enum eo_function_type
|
||||
{
|
||||
regular_, class_
|
||||
};
|
||||
eo_function_type type;
|
||||
eolian_scope scope;
|
||||
bool is_beta;
|
||||
std::string name;
|
||||
std::string impl;
|
||||
eolian_type_instance ret;
|
||||
parameters_container_type params;
|
||||
std::string comment;
|
||||
};
|
||||
|
||||
struct eo_event
|
||||
{
|
||||
eo_event() : scope(eolian_scope::public_), is_beta(false), name(),
|
||||
eo_name(), comment()
|
||||
{}
|
||||
|
||||
eolian_scope scope;
|
||||
bool is_beta;
|
||||
std::string name;
|
||||
std::string eo_name;
|
||||
//parameters_container_type params; // XXX desirable.
|
||||
std::string comment;
|
||||
|
||||
bool operator<(eo_event const& other) const { return name < other.name; }
|
||||
};
|
||||
|
||||
|
||||
inline bool
|
||||
function_is_void(eo_function const& func)
|
||||
{
|
||||
return func.ret.empty() || func.ret.front().native.compare("void") == 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
function_is_static(eo_function const& func)
|
||||
{
|
||||
return func.type == eo_function::class_;
|
||||
}
|
||||
|
||||
inline unsigned int
|
||||
parameters_count_callbacks(parameters_container_type const& parameters)
|
||||
{
|
||||
unsigned int r = 0u;
|
||||
for (auto first = parameters.begin(), last = parameters.end()
|
||||
; first != last ; ++first)
|
||||
if(type_is_callback(first->type) && first + 1 != last)
|
||||
++r;
|
||||
return r;
|
||||
}
|
||||
|
||||
inline parameters_container_type::const_iterator
|
||||
parameters_find_callback(parameters_container_type const& parameters)
|
||||
{
|
||||
for (auto it = parameters.cbegin(), last = parameters.cend();
|
||||
it != last; ++it)
|
||||
{
|
||||
if (type_is_callback((*it).type) && it + 1 != last)
|
||||
return it;
|
||||
}
|
||||
return parameters.cend();
|
||||
}
|
||||
|
||||
} } // namespace efl { namespace eolian {
|
||||
|
||||
#endif // EFL_EOLIAN_CXX_EO_TYPES_HH
|
|
@ -1,116 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_EO_CLASS_VALIDATE_HH
|
||||
#define EOLIAN_CXX_EO_CLASS_VALIDATE_HH
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include "eo_types.hh"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace efl { namespace eolian {
|
||||
|
||||
inline bool
|
||||
_is_valid(std::string const& value)
|
||||
{
|
||||
return !value.empty() and (isalpha(value[0]) || value[0] == '_');
|
||||
}
|
||||
|
||||
inline bool
|
||||
_is_valid(eolian_type_instance const& type)
|
||||
{
|
||||
// if (type.empty() || (*type.rbegin()).category == eolian_type::complex_)
|
||||
// return false;
|
||||
for (auto rit = type.parts.rbegin(), last = type.parts.rend(); rit != last; ++rit)
|
||||
{
|
||||
if ((*rit).binding.empty() && (*rit).category == eolian_type::complex_)
|
||||
return false;
|
||||
// else if (rit != type.rbegin() && (*rit).category != eolian_type::complex_)
|
||||
// {
|
||||
// std::cout << "begin " << (rit != type.rbegin()) << std::endl;
|
||||
// std::cout << "category " << rit->category << std::endl;
|
||||
// return false;
|
||||
// }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
_is_valid(parameters_container_type const& parameters)
|
||||
{
|
||||
unsigned int n_callbacks = parameters_count_callbacks(parameters);
|
||||
return n_callbacks == 0 || n_callbacks == 1;
|
||||
}
|
||||
|
||||
inline bool
|
||||
_is_valid(events_container_type const& events)
|
||||
{
|
||||
for (eo_event event : events)
|
||||
{
|
||||
if (event.name.empty() || event.eo_name.empty())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void
|
||||
_validate(T const& val, eo_class const& cls)
|
||||
{
|
||||
if(!_is_valid(val))
|
||||
{
|
||||
static_cast<void>(cls);
|
||||
assert(false && "Failed identifier validation");
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
eo_class_validate(const eo_class& cls)
|
||||
{
|
||||
// class name and type
|
||||
_validate(cls.name, cls);
|
||||
assert(cls.type == eo_class::regular_ ||
|
||||
cls.type == eo_class::regular_noninst_ ||
|
||||
cls.type == eo_class::interface_ ||
|
||||
cls.type == eo_class::mixin_);
|
||||
|
||||
// constructors
|
||||
for (auto it = cls.constructors.cbegin(), last = cls.constructors.cend();
|
||||
it != last; ++it)
|
||||
{
|
||||
_validate((*it).name, cls);
|
||||
_validate((*it).params, cls);
|
||||
// parameters
|
||||
for (auto it_p = (*it).params.begin(), last_p = (*it).params.end();
|
||||
it_p != last_p; ++it_p)
|
||||
{
|
||||
_validate((*it_p).name, cls);
|
||||
_validate((*it_p).type, cls);
|
||||
}
|
||||
}
|
||||
// functions
|
||||
for (auto it = cls.functions.begin(), last = cls.functions.end();
|
||||
it != last; ++it)
|
||||
{
|
||||
_validate((*it).name, cls);
|
||||
_validate((*it).impl, cls);
|
||||
_validate((*it).ret, cls);
|
||||
_validate((*it).params, cls);
|
||||
// parameters
|
||||
for (auto it_p = (*it).params.begin(), last_p = (*it).params.end();
|
||||
it_p != last_p; ++it_p)
|
||||
{
|
||||
_validate((*it_p).name, cls);
|
||||
_validate((*it_p).type, cls);
|
||||
}
|
||||
}
|
||||
// events
|
||||
_validate(cls.own_events, cls);
|
||||
_validate(cls.concrete_events, cls);
|
||||
}
|
||||
|
||||
} } // namespace efl { namespace eolian {
|
||||
|
||||
#endif // EOLIAN_CXX_EO_CLASS_VALIDATE_HH
|
|
@ -0,0 +1,74 @@
|
|||
#ifndef EOLIAN_CXX_ADDRESS_OF_HH
|
||||
#define EOLIAN_CXX_ADDRESS_OF_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
|
||||
#include "grammar/indentation.hpp"
|
||||
#include "grammar/list.hpp"
|
||||
#include "grammar/alternative.hpp"
|
||||
#include "grammar/type.hpp"
|
||||
#include "grammar/parameter.hpp"
|
||||
#include "grammar/function_declaration.hpp"
|
||||
#include "grammar/case.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct address_of_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const
|
||||
{
|
||||
std::vector<std::string> cpp_namespaces = attributes::cpp_namespaces(cls.namespaces);
|
||||
|
||||
if(!as_generator
|
||||
(
|
||||
scope_tab << " ::efl::eolian::address_of_operator<" << string
|
||||
).generate(sink, cls.cxx_name, context)) return false;
|
||||
|
||||
for(auto&& i : cls.inherits)
|
||||
{
|
||||
if(!as_generator(", " << *("::" << lower_case[string]) << "::" << string)
|
||||
.generate(sink, std::make_tuple(attributes::cpp_namespaces(i.namespaces), i.eolian_name), context))
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!as_generator
|
||||
(
|
||||
"> operator&() { return {this}; }\n"
|
||||
).generate(sink, attributes::unused, context)) return false;
|
||||
|
||||
if(!as_generator
|
||||
(
|
||||
scope_tab << " ::efl::eolian::address_of_operator<" << string << " const "
|
||||
).generate(sink, cls.cxx_name, context)) return false;
|
||||
|
||||
for(auto&& i : cls.inherits)
|
||||
{
|
||||
if(!as_generator(", " << *("::" << lower_case[string]) << "::" << string << " const ")
|
||||
.generate(sink, std::make_tuple(attributes::cpp_namespaces(i.namespaces), i.eolian_name), context))
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!as_generator
|
||||
(
|
||||
"> operator&() const { return {this}; }\n"
|
||||
).generate(sink, attributes::unused, context)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<address_of_generator> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed<address_of_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
address_of_generator const address_of;
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,52 @@
|
|||
#ifndef EOLIAN_CXX_ALTERNATIVE_HH
|
||||
#define EOLIAN_CXX_ALTERNATIVE_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/meta.hpp"
|
||||
#include "grammar/variant.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
template <typename L, typename R>
|
||||
struct alternative_generator
|
||||
{
|
||||
template <typename OutputIterator, typename...Args, typename Context>
|
||||
bool generate(OutputIterator /*sink*/, attributes::variant<Args...> const& /*attribute*/, Context const& /*context*/) const
|
||||
{
|
||||
// return grammar::alternative_sequence(left, right, sink, attribute);
|
||||
return false;
|
||||
}
|
||||
template <typename OutputIterator, typename Attribute, typename...Args, typename Context>
|
||||
bool generate(OutputIterator sink, Attribute const& attribute, Context const& context) const
|
||||
{
|
||||
if(!attributes::generate(as_generator(left), sink, attribute, context))
|
||||
return attributes::generate(as_generator(right), sink, attribute, context);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
L left;
|
||||
R right;
|
||||
};
|
||||
|
||||
template <typename L, typename R>
|
||||
struct is_eager_generator<alternative_generator<L, R> > : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <typename L, typename R>
|
||||
struct attributes_needed<alternative_generator<L, R> > : std::integral_constant
|
||||
<int, meta::max<attributes_needed<L>::value, attributes_needed<R>::value>::value> {};
|
||||
template <typename L, typename R>
|
||||
struct accepts_tuple<alternative_generator<L, R> > : std::true_type {};
|
||||
}
|
||||
|
||||
template <typename L, typename R>
|
||||
typename std::enable_if<grammar::is_generator<L>::value && grammar::is_generator<R>::value, alternative_generator<L, R>>::type
|
||||
operator|(L l, R r)
|
||||
{
|
||||
return alternative_generator<L, R>{l, r};
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,66 @@
|
|||
#ifndef EOLIAN_CXX_ATTRIBUTE_CONDITIONAL_HH
|
||||
#define EOLIAN_CXX_ATTRIBUTE_CONDITIONAL_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
template <typename F, typename G>
|
||||
struct functional_attribute_conditional_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(OutputIterator sink, Attribute const& attribute, Context const& ctx) const
|
||||
{
|
||||
if(f(attribute))
|
||||
return as_generator(g).generate(sink, attribute, ctx);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
F f;
|
||||
G g;
|
||||
};
|
||||
|
||||
template <typename F, typename G>
|
||||
struct is_eager_generator<functional_attribute_conditional_generator<F, G>> : std::true_type {};
|
||||
|
||||
template <typename F>
|
||||
struct functional_attribute_conditional_directive
|
||||
{
|
||||
template <typename G>
|
||||
functional_attribute_conditional_generator<F, G> operator[](G g) const
|
||||
{
|
||||
return {f, g};
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(OutputIterator, Attribute const& attribute, Context const&) const
|
||||
{
|
||||
return f(attribute);
|
||||
}
|
||||
|
||||
F f;
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct is_eager_generator<functional_attribute_conditional_directive<F>> : std::true_type {};
|
||||
|
||||
struct attribute_conditional_terminal
|
||||
{
|
||||
template <typename F>
|
||||
functional_attribute_conditional_directive<F> operator()(F f) const
|
||||
{
|
||||
return {f};
|
||||
}
|
||||
} const attribute_conditional;
|
||||
|
||||
namespace type_traits {
|
||||
template <typename F, typename G>
|
||||
struct attributes_needed<functional_attribute_conditional_generator<F, G>> : attributes_needed<G> {};
|
||||
template <typename F>
|
||||
struct attributes_needed<functional_attribute_conditional_directive<F>> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,87 @@
|
|||
#ifndef EOLIAN_CXX_ATTRIBUTE_REORDER_HH
|
||||
#define EOLIAN_CXX_ATTRIBUTE_REORDER_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/attributes.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
template <typename Tuple, int...S>
|
||||
struct reorder_tuple
|
||||
{
|
||||
Tuple* tuple;
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
|
||||
template <int N, typename T>
|
||||
struct index_calc;
|
||||
|
||||
template <int N, typename Tuple, int...S>
|
||||
struct index_calc<0, reorder_tuple<Tuple, N, S...>> : std::integral_constant<int, N> {};
|
||||
|
||||
template <int I, int N, typename Tuple, int...S>
|
||||
struct index_calc<I, reorder_tuple<Tuple, N, S...>> : index_calc<I-1, reorder_tuple<Tuple, S...>> {};
|
||||
|
||||
}
|
||||
namespace attributes {
|
||||
template <int N, typename Tuple, int...S>
|
||||
struct tuple_element<N, reorder_tuple<Tuple, S...>>
|
||||
{
|
||||
template <typename T>
|
||||
struct identity { typedef T type; };
|
||||
typedef impl::index_calc<N, reorder_tuple<Tuple, S...>> index;
|
||||
typedef typename std::conditional
|
||||
<index::value == -1
|
||||
, identity<Tuple>
|
||||
, tuple_element<index::value, typename std::remove_const<Tuple>::type>>::type::type type;
|
||||
static type const& get_impl(reorder_tuple<Tuple, S...> const& t
|
||||
, std::integral_constant<int, -1>)
|
||||
{ return *t.tuple; }
|
||||
template <int I>
|
||||
static type const& get_impl(reorder_tuple<Tuple, S...> const& t
|
||||
, std::integral_constant<int, I>)
|
||||
{ using std::get; return get<index::value>(*t.tuple); }
|
||||
static type const& get(reorder_tuple<Tuple, S...> const& t)
|
||||
{ return get_impl(t, index{}); }
|
||||
};
|
||||
}
|
||||
template <int N, typename Tuple, int...S>
|
||||
typename attributes::tuple_element<N, reorder_tuple<Tuple, S...>>::type const& get(reorder_tuple<Tuple, S...>const& t)
|
||||
{
|
||||
return attributes::tuple_element<N, reorder_tuple<Tuple, S...>>::get(t);
|
||||
}
|
||||
|
||||
template <typename G, int...S>
|
||||
struct attribute_reorder_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(OutputIterator sink, Attribute const& attribute, Context const& ctx) const
|
||||
{
|
||||
return attributes::generate(as_generator(g), sink, reorder_tuple<Attribute const, S...>{&attribute}, ctx);
|
||||
}
|
||||
|
||||
G g;
|
||||
};
|
||||
|
||||
template <typename G, int...S>
|
||||
struct is_eager_generator<attribute_reorder_generator<G, S...>> : std::true_type {};
|
||||
|
||||
template <int...S, typename G>
|
||||
attribute_reorder_generator<G, S...> attribute_reorder(G g)
|
||||
{
|
||||
return {g};
|
||||
}
|
||||
|
||||
namespace type_traits {
|
||||
template <typename G, int...S>
|
||||
struct attributes_needed<attribute_reorder_generator<G, S...>> : attributes_needed<G> {};
|
||||
template <int...S, typename Tuple>
|
||||
struct is_explicit_tuple<reorder_tuple<Tuple, S...>> : std::true_type {};
|
||||
template <int...S, typename Tuple>
|
||||
struct is_tuple<reorder_tuple<Tuple, S...>> : std::true_type {};
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,63 @@
|
|||
#ifndef EOLIAN_CXX_ATTRIBUTE_REPLACE_HH
|
||||
#define EOLIAN_CXX_ATTRIBUTE_REPLACE_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
template <typename F, typename G>
|
||||
struct functional_attribute_replace_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(OutputIterator sink, Attribute const& attribute, Context const& ctx) const
|
||||
{
|
||||
return as_generator(g).generate(sink, f(attribute), ctx);
|
||||
}
|
||||
|
||||
F f;
|
||||
G g;
|
||||
};
|
||||
|
||||
template <typename F, typename G>
|
||||
struct is_eager_generator<functional_attribute_replace_generator<F, G>> : std::true_type {};
|
||||
|
||||
template <typename F>
|
||||
struct functional_attribute_replace_directive
|
||||
{
|
||||
template <typename G>
|
||||
functional_attribute_replace_generator<F, G> operator[](G g) const
|
||||
{
|
||||
return {f, g};
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(OutputIterator, Attribute const& attribute, Context const&) const
|
||||
{
|
||||
return f(attribute);
|
||||
}
|
||||
|
||||
F f;
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct is_eager_generator<functional_attribute_replace_directive<F>> : std::true_type {};
|
||||
|
||||
struct attribute_replace_terminal
|
||||
{
|
||||
template <typename F>
|
||||
functional_attribute_replace_directive<F> operator()(F f) const
|
||||
{
|
||||
return {f};
|
||||
}
|
||||
} const attribute_replace;
|
||||
|
||||
namespace type_traits {
|
||||
template <typename F, typename G>
|
||||
struct attributes_needed<functional_attribute_replace_generator<F, G>> : attributes_needed<G> {};
|
||||
template <typename F>
|
||||
struct attributes_needed<functional_attribute_replace_directive<F>> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,185 @@
|
|||
#ifndef EOLIAN_CXX_ATTRIBUTES_HH
|
||||
#define EOLIAN_CXX_ATTRIBUTES_HH
|
||||
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include "grammar/type_traits.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
namespace attributes {
|
||||
|
||||
struct unused_type {};
|
||||
unused_type const unused;
|
||||
|
||||
template <int N, typename Tuple, typename Enable = void>
|
||||
struct tuple_element;
|
||||
|
||||
template <int N, typename Tuple>
|
||||
struct tuple_element<N, Tuple, typename std::enable_if
|
||||
<type_traits::is_std_tuple<Tuple>::value>::type> : std::tuple_element<N, Tuple>
|
||||
{};
|
||||
|
||||
template <int N, typename Tuple>
|
||||
typename tuple_element<N, typename std::remove_const<Tuple>::type>::type get_adl(Tuple& tuple)
|
||||
{
|
||||
using std::get;
|
||||
return get<N>(tuple);
|
||||
}
|
||||
|
||||
template <int I, typename Tuple>
|
||||
struct lazy_offset_tuple
|
||||
{
|
||||
lazy_offset_tuple(Tuple& tuple)
|
||||
: tuple(tuple) {}
|
||||
|
||||
template <int N>
|
||||
typename tuple_element<N+I, typename std::remove_const<Tuple>::type>::type get() const
|
||||
{
|
||||
return attributes::get_adl<N+I>(tuple);
|
||||
}
|
||||
|
||||
Tuple& tuple;
|
||||
};
|
||||
|
||||
}
|
||||
namespace type_traits {
|
||||
template <int N, typename T>
|
||||
struct is_tuple<attributes::lazy_offset_tuple<N, T>> : std::true_type {};
|
||||
template <int N, typename T>
|
||||
struct is_explicit_tuple<attributes::lazy_offset_tuple<N, T>> : std::true_type {};
|
||||
}
|
||||
namespace attributes {
|
||||
|
||||
template <typename T>
|
||||
struct infinite_tuple
|
||||
{
|
||||
T object;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
infinite_tuple<T> make_infinite_tuple(T&& object)
|
||||
{
|
||||
return infinite_tuple<T>{std::forward<T>(object)};
|
||||
}
|
||||
|
||||
template <int N, typename T>
|
||||
struct tuple_element<N, infinite_tuple<T>>
|
||||
{
|
||||
typedef T type;
|
||||
static type& get(infinite_tuple<T>& tuple) { return tuple.object; }
|
||||
static type const& get(infinite_tuple<T> const& tuple) { return tuple.object; }
|
||||
};
|
||||
template <int N, typename T>
|
||||
struct tuple_element<N, infinite_tuple<T> const> : tuple_element<N, infinite_tuple<T>> {};
|
||||
template <int N, typename T>
|
||||
typename tuple_element<N, infinite_tuple<T>>::type&
|
||||
get(infinite_tuple<T>& tuple)
|
||||
{
|
||||
return tuple_element<N, infinite_tuple<T>>::get(tuple);
|
||||
}
|
||||
template <int N, typename T>
|
||||
typename tuple_element<N, infinite_tuple<T>>::type const&
|
||||
get(infinite_tuple<T> const& tuple)
|
||||
{
|
||||
return tuple_element<N, infinite_tuple<T>>::get(tuple);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace type_traits {
|
||||
template <typename T>
|
||||
struct is_tuple<attributes::infinite_tuple<T>> : std::true_type {};
|
||||
template <typename T>
|
||||
struct is_explicit_tuple<attributes::infinite_tuple<T>> : std::true_type {};
|
||||
}
|
||||
namespace attributes {
|
||||
|
||||
template <int N, int I, typename Tuple>
|
||||
struct tuple_element<N, lazy_offset_tuple<I, Tuple>> : tuple_element<N+I, typename std::remove_const<Tuple>::type>
|
||||
{};
|
||||
template <int N, int I, typename Tuple>
|
||||
struct tuple_element<N, lazy_offset_tuple<I, Tuple> const> : tuple_element<N+I, typename std::remove_const<Tuple>::type>
|
||||
{};
|
||||
|
||||
template <int N, int I, typename Tuple>
|
||||
typename tuple_element<N, lazy_offset_tuple<I, Tuple> const>::type
|
||||
get(lazy_offset_tuple<I, Tuple> const& tuple)
|
||||
{
|
||||
return tuple.template get<N>();
|
||||
}
|
||||
|
||||
template <typename Tuple>
|
||||
lazy_offset_tuple<1, Tuple> pop_front(Tuple& tuple, typename std::enable_if<type_traits::is_tuple<Tuple>::value>::type* = 0)
|
||||
{
|
||||
return lazy_offset_tuple<1, Tuple>(tuple);
|
||||
}
|
||||
|
||||
template <int N, typename Tuple>
|
||||
lazy_offset_tuple<N + 1, Tuple> pop_front(lazy_offset_tuple<N, Tuple> tuple, typename std::enable_if<type_traits::is_tuple<Tuple>::value>::type* = 0)
|
||||
{
|
||||
return lazy_offset_tuple<N + 1, Tuple>(tuple.tuple);
|
||||
}
|
||||
|
||||
template <int I, typename Tuple>
|
||||
lazy_offset_tuple<I, Tuple> pop_front_n(Tuple& tuple, typename std::enable_if<type_traits::is_tuple<Tuple>::value && I>::type* = 0)
|
||||
{
|
||||
return lazy_offset_tuple<I, Tuple>(tuple);
|
||||
}
|
||||
template <int I, typename Tuple>
|
||||
Tuple& pop_front_n(Tuple& tuple, typename std::enable_if<I == 0>::type* = 0)
|
||||
{
|
||||
return tuple;
|
||||
}
|
||||
|
||||
template <int I, int N, typename Tuple>
|
||||
lazy_offset_tuple<N + I, Tuple> pop_front_n(lazy_offset_tuple<N, Tuple> tuple, typename std::enable_if<type_traits::is_tuple<Tuple>::value>::type* = 0)
|
||||
{
|
||||
return lazy_offset_tuple<N + I, Tuple>(tuple.tuple);
|
||||
}
|
||||
|
||||
template <typename Generator, typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(Generator const& gen, OutputIterator sink, Attribute const& attribute, Context const& context
|
||||
, typename std::enable_if
|
||||
<type_traits::is_explicit_tuple<Attribute>::value
|
||||
&& !type_traits::accepts_tuple<Generator>::value
|
||||
&& type_traits::attributes_needed<Generator>::value != 0
|
||||
>::type* = 0)
|
||||
{
|
||||
return gen.generate(sink, get<0>(attribute), context);
|
||||
}
|
||||
|
||||
template <typename Generator, typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(Generator const& gen, OutputIterator sink, Attribute const& attribute, Context const& context
|
||||
, typename std::enable_if
|
||||
<type_traits::is_explicit_tuple<Attribute>::value
|
||||
&& type_traits::accepts_tuple<Generator>::value
|
||||
&& type_traits::attributes_needed<Generator>::value != 0
|
||||
>::type* = 0)
|
||||
{
|
||||
return gen.generate(sink, attribute, context);
|
||||
}
|
||||
|
||||
template <typename Generator, typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(Generator const& gen, OutputIterator sink, Attribute const&
|
||||
, Context const& context
|
||||
, typename std::enable_if
|
||||
<type_traits::attributes_needed<Generator>::value == 0
|
||||
>::type* = 0)
|
||||
{
|
||||
return gen.generate(sink, unused, context);
|
||||
}
|
||||
|
||||
template <typename Generator, typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(Generator const& gen, OutputIterator sink, Attribute const& attribute, Context const& context
|
||||
, typename std::enable_if
|
||||
<!type_traits::is_explicit_tuple<Attribute>::value
|
||||
&& type_traits::attributes_needed<Generator>::value != 0
|
||||
>::type* = 0)
|
||||
{
|
||||
return gen.generate(sink, attribute, context);
|
||||
}
|
||||
|
||||
} } } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,112 @@
|
|||
#ifndef EOLIAN_CXX_BASE_CLASS_DEFINITION_HH
|
||||
#define EOLIAN_CXX_BASE_CLASS_DEFINITION_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
|
||||
#include "grammar/indentation.hpp"
|
||||
#include "grammar/list.hpp"
|
||||
#include "grammar/alternative.hpp"
|
||||
#include "grammar/type.hpp"
|
||||
#include "grammar/parameter.hpp"
|
||||
#include "grammar/function_declaration.hpp"
|
||||
#include "grammar/namespace.hpp"
|
||||
#include "grammar/case.hpp"
|
||||
#include "grammar/address_of.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct base_class_definition_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const
|
||||
{
|
||||
std::vector<std::string> cpp_namespaces = attributes::cpp_namespaces(cls.namespaces);
|
||||
// static_assert(std::is_same<OutputIterator, void>::value, "");
|
||||
auto open_namespace = *("namespace " << string << " { ") << "\n";
|
||||
if(!as_generator(open_namespace).generate
|
||||
(sink, cpp_namespaces, add_lower_case_context(context))) return false;
|
||||
|
||||
if(!as_generator
|
||||
(
|
||||
"struct " << string << " {\n"
|
||||
).generate(sink, cls.cxx_name, context)) return false;
|
||||
|
||||
if(!as_generator(*(scope_tab << function_declaration))
|
||||
.generate(sink, cls.functions, context)) return false;
|
||||
|
||||
// static Eo_Class const* _eo_class();
|
||||
std::string suffix;
|
||||
switch(cls.type)
|
||||
{
|
||||
case attributes::class_type::regular:
|
||||
case attributes::class_type::abstract_:
|
||||
suffix = "CLASS";
|
||||
break;
|
||||
case attributes::class_type::mixin:
|
||||
suffix = "MIXIN";
|
||||
break;
|
||||
case attributes::class_type::interface_:
|
||||
suffix = "INTERFACE";
|
||||
break;
|
||||
}
|
||||
|
||||
if(!as_generator
|
||||
(
|
||||
scope_tab << "static Eo_Class const* _eo_class()\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << "return "
|
||||
).generate(sink, attributes::unused, context)) return false;
|
||||
if(!as_generator
|
||||
(*(lower_case[string] << "_") << string << "_" << string)
|
||||
.generate(sink, std::make_tuple(cls.namespaces, cls.eolian_name, suffix), add_upper_case_context(context)))
|
||||
return false;
|
||||
if(!as_generator(";\n" << scope_tab << "}\n").generate(sink, attributes::unused, context)) return false;
|
||||
|
||||
if(!as_generator
|
||||
(
|
||||
scope_tab << "Eo* _eo_ptr() const { return *(Eo**)this; }\n"
|
||||
).generate(sink, attributes::unused, context)) return false;
|
||||
|
||||
// operator ::ns::Class_Name() const;
|
||||
// operator ::ns::Class_Name&();
|
||||
// operator ::ns::Class_Name const&() const;
|
||||
if(!as_generator
|
||||
(
|
||||
scope_tab << "operator " << *("::" << lower_case[string]) << "::" << string << "() const;\n"
|
||||
<< scope_tab << "operator " << *("::" << lower_case[string]) << "::" << string << "&();\n"
|
||||
<< scope_tab << "operator " << *("::" << lower_case[string]) << "::" << string << " const&() const;\n"
|
||||
).generate(sink, std::make_tuple
|
||||
(cpp_namespaces, cls.cxx_name, cpp_namespaces, cls.cxx_name, cpp_namespaces, cls.cxx_name)
|
||||
, context))
|
||||
return false;
|
||||
|
||||
// /// @cond LOCAL
|
||||
if(!as_generator(scope_tab << "/// @cond LOCAL\n").generate(sink, attributes::unused, context)) return false;
|
||||
|
||||
if(!as_generator(address_of).generate(sink, cls, context)) return false;
|
||||
|
||||
// /// @endcond
|
||||
if(!as_generator(scope_tab << "/// @endcond\n").generate(sink, attributes::unused, context)) return false;
|
||||
|
||||
if(!as_generator("};\n").generate(sink, attributes::unused, context)) return false;
|
||||
auto close_namespace = *(lit("} ")) << "\n";
|
||||
if(!as_generator(close_namespace).generate(sink, cpp_namespaces, context)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<base_class_definition_generator> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed<base_class_definition_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
base_class_definition_generator const base_class_definition;
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,74 @@
|
|||
#ifndef EOLIAN_CXX_C_TYPE_HH
|
||||
#define EOLIAN_CXX_C_TYPE_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
#include "grammar/string.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar { namespace attributes {
|
||||
|
||||
struct c_type_visitor
|
||||
{
|
||||
std::string const* c_type;
|
||||
typedef std::string result_type;
|
||||
std::string operator()(attributes::klass_name const& name) const
|
||||
{
|
||||
std::string n;
|
||||
as_generator(" ::" << *(string << "_") << string << string << "*")
|
||||
.generate(std::back_insert_iterator<std::string>(n)
|
||||
, std::make_tuple(name.namespaces, name.eolian_name
|
||||
, std::string{is_const(name.base_qualifier) ? " const" : ""})
|
||||
, context_null {});
|
||||
return n;
|
||||
}
|
||||
template <typename T>
|
||||
std::string operator()(T const&) const
|
||||
{
|
||||
return *c_type;
|
||||
}
|
||||
};
|
||||
|
||||
inline std::string c_type(parameter_def const& param)
|
||||
{
|
||||
switch(param.direction)
|
||||
{
|
||||
case parameter_direction::in:
|
||||
return param.type.original_type.visit(c_type_visitor{¶m.c_type});
|
||||
case parameter_direction::out:
|
||||
case parameter_direction::inout:
|
||||
return param.type.original_type.visit(c_type_visitor{¶m.c_type}) + "*";
|
||||
default:
|
||||
throw std::runtime_error("Unknown parameter direction");
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct c_type_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::parameter_def const& attribute, Context const& context) const
|
||||
{
|
||||
return as_generator(attributes::c_type(attribute)).generate(sink, attributes::unused, context);
|
||||
}
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::type_def const& attribute, Context const& context) const
|
||||
{
|
||||
return as_generator(attribute.original_type.visit(attributes::c_type_visitor{&attribute.c_type}))
|
||||
.generate(sink, attributes::unused, context);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<c_type_generator> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed<c_type_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
c_type_generator const c_type;
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,86 @@
|
|||
#ifndef EOLIAN_CXX_CASE_HH
|
||||
#define EOLIAN_CXX_CASE_HH
|
||||
|
||||
#include "grammar/context.hpp"
|
||||
#include "grammar/generator.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct upper_case_tag {};
|
||||
struct lower_case_tag {};
|
||||
|
||||
template <typename Context>
|
||||
context_cons<upper_case_tag, Context>
|
||||
add_upper_case_context(Context const& context)
|
||||
{
|
||||
return context_add_tag(upper_case_tag{}, context);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
context_cons<lower_case_tag, Context>
|
||||
add_lower_case_context(Context const& context)
|
||||
{
|
||||
return context_add_tag(lower_case_tag{}, context);
|
||||
}
|
||||
|
||||
template <typename G>
|
||||
struct lower_case_generator
|
||||
{
|
||||
lower_case_generator(G g) : g(g) {}
|
||||
|
||||
template <typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(OutputIterator sink, Attribute const& attribute, Context const& context) const
|
||||
{
|
||||
return as_generator(g).generate(sink, attribute, add_lower_case_context(context));
|
||||
}
|
||||
|
||||
G g;
|
||||
};
|
||||
|
||||
template <typename G>
|
||||
struct upper_case_generator
|
||||
{
|
||||
upper_case_generator(G g) : g(g) {}
|
||||
|
||||
template <typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(OutputIterator sink, Attribute const& attribute, Context const& context) const
|
||||
{
|
||||
return as_generator(g).generate(sink, attribute, add_upper_case_context(context));
|
||||
}
|
||||
|
||||
G g;
|
||||
};
|
||||
|
||||
template <typename G>
|
||||
struct is_eager_generator<lower_case_generator<G>> : std::true_type {};
|
||||
template <typename G>
|
||||
struct is_eager_generator<upper_case_generator<G>> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <typename G>
|
||||
struct attributes_needed<lower_case_generator<G>> : attributes_needed<G> {};
|
||||
template <typename G>
|
||||
struct attributes_needed<upper_case_generator<G>> : attributes_needed<G> {};
|
||||
}
|
||||
|
||||
struct lower_case_directive
|
||||
{
|
||||
template <typename G>
|
||||
lower_case_generator<G> operator[](G&& g) const
|
||||
{
|
||||
return lower_case_generator<G>{g};
|
||||
}
|
||||
} const lower_case;
|
||||
|
||||
struct upper_case_directive
|
||||
{
|
||||
template <typename G>
|
||||
upper_case_generator<G> operator[](G&& g) const
|
||||
{
|
||||
return upper_case_generator<G>{g};
|
||||
}
|
||||
} const upper_case;
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef EOLIAN_CXX_CLASS_DECLARATION_HH
|
||||
#define EOLIAN_CXX_CLASS_DECLARATION_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
|
||||
#include "grammar/indentation.hpp"
|
||||
#include "grammar/list.hpp"
|
||||
#include "grammar/alternative.hpp"
|
||||
#include "grammar/type.hpp"
|
||||
#include "grammar/parameter.hpp"
|
||||
#include "grammar/function_declaration.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct class_declaration_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const
|
||||
{
|
||||
std::vector<std::string> cpp_namespaces = attributes::cpp_namespaces(cls.namespaces);
|
||||
auto open_namespace = *("namespace " << string << " { ") << "\n";
|
||||
if(!as_generator(open_namespace).generate(sink, cpp_namespaces, add_lower_case_context(context))) return false;
|
||||
|
||||
if(!as_generator
|
||||
(
|
||||
"struct " << string << ";\n"
|
||||
).generate(sink, cls.cxx_name, context)) return false;
|
||||
|
||||
auto close_namespace = *(lit("} ")) << "\n";
|
||||
if(!as_generator(close_namespace).generate(sink, cpp_namespaces, context)) return false;
|
||||
|
||||
if(!as_generator
|
||||
(
|
||||
"namespace efl { namespace eo { template<> struct is_eolian_object< "
|
||||
"::" << *(lower_case[string] << "::") << string << "> : ::std::true_type {}; } }\n"
|
||||
).generate(sink, std::make_tuple(cpp_namespaces, cls.cxx_name), context)) return false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<class_declaration_generator> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed<class_declaration_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
class_declaration_generator const class_declaration;
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,176 @@
|
|||
#ifndef EOLIAN_CXX_CLASS_DEFINITION_HH
|
||||
#define EOLIAN_CXX_CLASS_DEFINITION_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
|
||||
#include "grammar/indentation.hpp"
|
||||
#include "grammar/list.hpp"
|
||||
#include "grammar/alternative.hpp"
|
||||
#include "grammar/type.hpp"
|
||||
#include "grammar/parameter.hpp"
|
||||
#include "grammar/function_declaration.hpp"
|
||||
#include "grammar/case.hpp"
|
||||
#include "grammar/address_of.hpp"
|
||||
#include "grammar/attribute_reorder.hpp"
|
||||
#include "grammar/attribute_conditional.hpp"
|
||||
#include "grammar/attribute_replace.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct class_definition_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const
|
||||
{
|
||||
std::vector<std::string> cpp_namespaces = attributes::cpp_namespaces(cls.namespaces);
|
||||
auto open_namespace = *("namespace " << string << " { ") << "\n";
|
||||
if(!as_generator(open_namespace).generate(sink, cpp_namespaces, add_lower_case_context(context))) return false;
|
||||
|
||||
if(!as_generator
|
||||
(
|
||||
"struct " << string << " : ::efl::eo::concrete"
|
||||
)
|
||||
.generate(sink, cls.cxx_name, context))
|
||||
return false;
|
||||
for(auto&& i : cls.inherits)
|
||||
{
|
||||
if(!as_generator("\n" << scope_tab << ", EO_CXX_INHERIT(" << *(" ::" << lower_case[string]) << "::" << string << ")")
|
||||
.generate(sink, std::make_tuple(attributes::cpp_namespaces(i.namespaces), i.eolian_name), context))
|
||||
return false;
|
||||
}
|
||||
if(!as_generator("\n{\n").generate(sink, attributes::unused, context)) return false;
|
||||
|
||||
// constructors
|
||||
if(!as_generator
|
||||
(
|
||||
scope_tab << "explicit " << string << "( ::Eo* eo)\n"
|
||||
<< scope_tab << scope_tab << ": ::efl::eo::concrete(eo) {}\n"
|
||||
<< scope_tab << "explicit " << string << "(std::nullptr_t)\n"
|
||||
<< scope_tab << scope_tab << ": ::efl::eo::concrete(nullptr) {}\n"
|
||||
<< scope_tab << string << "(" << string << " const& other) = default;\n"
|
||||
<< scope_tab << string << "(" << string << "&& other) = default;\n"
|
||||
<< scope_tab << string << "& operator=(" << string << " const& other) = default;\n"
|
||||
<< scope_tab << string << "& operator=(" << string << "&& other) = default;\n"
|
||||
<< scope_tab << string << "()\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << "::efl::eolian::do_eo_add( ::efl::eo::concrete::_eo_raw, ::efl::eo::concrete{nullptr}, _eo_class());\n"
|
||||
<< scope_tab << "}\n"
|
||||
<< scope_tab << string << "( ::efl::eo::concrete parent)\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << "::efl::eolian::do_eo_add( ::efl::eo::concrete::_eo_raw, parent, _eo_class());\n"
|
||||
<< scope_tab << "}\n"
|
||||
<< scope_tab << "template <typename F> " << string << "(F f, typename ::std::enable_if< ::efl::eolian::is_callable<F>::value>::type* = 0)\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << "::efl::eolian::do_eo_add( ::efl::eo::concrete::_eo_raw, ::efl::eo::concrete{nullptr}, _eo_class(), f);\n"
|
||||
<< scope_tab << "}\n"
|
||||
// << scope_tab << "explicit " << string << "( ::efl::eo::concrete const& parent)\n"
|
||||
// << scope_tab << scope_tab << ": ::efl::eo::concrete( ::efl::eo::do_eo_add(parent)) {}\n"
|
||||
// << scope_tab << "template <typename F>\n"
|
||||
// << scope_tab << "explicit " << string << "( ::efl::eo::concrete const& parent, F f)\n"
|
||||
// << scope_tab << scope_tab << ": ::efl::eo::concrete( ::efl::eo::do_eo_add(parent, f)) {}\n"
|
||||
// << scope_tab << "template <typename F>\n"
|
||||
// << scope_tab << "explicit " << string << "(F f)\n"
|
||||
// << scope_tab << scope_tab << ": ::efl::eo::concrete( ::efl::eo::do_eo_add( ::efl::eo::concrete{nullptr}, f)) {}\n"
|
||||
).generate(sink, attributes::make_infinite_tuple(cls.cxx_name), context)) return false;
|
||||
|
||||
if(!as_generator(*(scope_tab << function_declaration))
|
||||
.generate(sink, cls.functions, context)) return false;
|
||||
|
||||
// static Eo_Class const* _eo_class();
|
||||
std::string suffix;
|
||||
switch(cls.type)
|
||||
{
|
||||
case attributes::class_type::regular:
|
||||
case attributes::class_type::abstract_:
|
||||
suffix = "CLASS";
|
||||
break;
|
||||
case attributes::class_type::mixin:
|
||||
suffix = "MIXIN";
|
||||
break;
|
||||
case attributes::class_type::interface_:
|
||||
suffix = "INTERFACE";
|
||||
break;
|
||||
}
|
||||
|
||||
if(!as_generator
|
||||
(
|
||||
scope_tab << "static Eo_Class const* _eo_class()\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << "return "
|
||||
).generate(sink, attributes::unused, context)) return false;
|
||||
if(!as_generator
|
||||
(*(string << "_") << string << "_" << string)
|
||||
.generate(sink, std::make_tuple(cls.namespaces, cls.eolian_name, suffix), add_upper_case_context(context)))
|
||||
return false;
|
||||
if(!as_generator(";\n" << scope_tab << "}\n").generate(sink, attributes::unused, context)) return false;
|
||||
|
||||
if(!as_generator
|
||||
(
|
||||
scope_tab << "Eo* _eo_ptr() const { return *(Eo**)this; }\n"
|
||||
).generate(sink, attributes::unused, context)) return false;
|
||||
|
||||
// operator ::ns::Class_Name() const;
|
||||
// operator ::ns::Class_Name&();
|
||||
// operator ::ns::Class_Name const&() const;
|
||||
if(!as_generator
|
||||
(
|
||||
scope_tab << "operator " << *("::" << lower_case[string]) << "::" << string << "() const;\n"
|
||||
<< scope_tab << "operator " << *("::" << lower_case[string]) << "::" << string << "&();\n"
|
||||
<< scope_tab << "operator " << *("::" << lower_case[string]) << "::" << string << " const&() const;\n"
|
||||
).generate(sink, std::make_tuple(cpp_namespaces, cls.cxx_name, cpp_namespaces, cls.cxx_name
|
||||
, cpp_namespaces, cls.cxx_name), context))
|
||||
return false;
|
||||
|
||||
if(!as_generator
|
||||
(
|
||||
*attribute_reorder<1, 2, 0, 1>
|
||||
((scope_tab << "static struct " << string_replace(',', '_') << "_event\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << scope_tab << "static Eo_Event_Description const* description()\n"
|
||||
<< scope_tab << scope_tab << "{ return " << string << "; }\n"
|
||||
<< scope_tab << scope_tab << "typedef "
|
||||
<< (attribute_conditional([] (eina::optional<attributes::type_def> t) { return !!t; })
|
||||
[attribute_replace([] (eina::optional<attributes::type_def> t) { return *t; }) [type]]
|
||||
| "void")
|
||||
<< " parameter_type;\n"
|
||||
<< scope_tab << "} const " << string_replace(',', '_') << "_event;\n"
|
||||
))).generate(sink, cls.events, context))
|
||||
return false;
|
||||
|
||||
// /// @cond LOCAL
|
||||
if(!as_generator(scope_tab << "/// @cond LOCAL\n").generate(sink, attributes::unused, context)) return false;
|
||||
|
||||
if(!as_generator(address_of).generate(sink, cls, context)) return false;
|
||||
|
||||
// /// @endcond
|
||||
if(!as_generator(scope_tab << "/// @endcond\n").generate(sink, attributes::unused, context)) return false;
|
||||
|
||||
if(!as_generator("};\n").generate(sink, attributes::unused, context)) return false;
|
||||
|
||||
// static asserts
|
||||
if(!as_generator("static_assert(sizeof(" << string << ") == sizeof(Eo*), \"\");\n")
|
||||
.generate(sink, cls.cxx_name, context)) return false;
|
||||
if(!as_generator("static_assert(std::is_standard_layout<" << string << ">::value, \"\");\n")
|
||||
.generate(sink, cls.cxx_name, context)) return false;
|
||||
|
||||
auto close_namespace = *(lit("} ")) << "\n";
|
||||
if(!as_generator(close_namespace).generate(sink, cpp_namespaces, context)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<class_definition_generator> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed<class_definition_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
class_definition_generator const class_definition;
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef EOLIAN_CXX_CLASS_IMPLEMENTATION_HH
|
||||
#define EOLIAN_CXX_CLASS_IMPLEMENTATION_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
|
||||
#include "grammar/string.hpp"
|
||||
#include "grammar/indentation.hpp"
|
||||
#include "grammar/list.hpp"
|
||||
#include "grammar/alternative.hpp"
|
||||
#include "grammar/type.hpp"
|
||||
#include "grammar/parameter.hpp"
|
||||
#include "grammar/function_definition.hpp"
|
||||
#include "grammar/namespace.hpp"
|
||||
#include "grammar/type_impl.hpp"
|
||||
#include "grammar/attribute_reorder.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct class_implementation_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::klass_def const& cls, Context const& ctx) const
|
||||
{
|
||||
return as_generator
|
||||
(
|
||||
(namespaces
|
||||
[*function_definition(get_klass_name(cls))]
|
||||
// << "namespace eo_cxx {\n"
|
||||
// << namespaces
|
||||
// [*function_definition(get_klass_name(cls))]
|
||||
// << "}\n\n"
|
||||
)).generate(sink, std::make_tuple(cls.namespaces, cls.functions), ctx)
|
||||
&& as_generator
|
||||
(
|
||||
"namespace eo_cxx {\n"
|
||||
<< namespaces
|
||||
[*function_definition(get_klass_name(cls))]
|
||||
<< "}\n\n"
|
||||
).generate(sink, std::make_tuple(cls.namespaces, cls.functions), ctx);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<class_implementation_generator> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed<class_implementation_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
class_implementation_generator const class_implementation;
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -1,45 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_STD_COMMENT_HH
|
||||
#define EOLIAN_CXX_STD_COMMENT_HH
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iosfwd>
|
||||
#include <ostream>
|
||||
|
||||
#include "tab.hh"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
using std::endl;
|
||||
|
||||
const std::string comment_prefix("///");
|
||||
|
||||
struct comment
|
||||
{
|
||||
std::string _doc;
|
||||
int _tab;
|
||||
std::string _if_empty;
|
||||
comment(std::string const& doc, int tab = 0, std::string const& if_empty = "")
|
||||
: _doc(doc), _tab(tab), _if_empty(if_empty)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, comment const& x)
|
||||
{
|
||||
std::string const& doc = !x._doc.empty() ? x._doc : x._if_empty;
|
||||
std::istringstream ss(doc);
|
||||
std::string line;
|
||||
while(std::getline(ss, line))
|
||||
{
|
||||
out << tab(x._tab) << comment_prefix
|
||||
<< (line.size() ? (" " + line) : "")
|
||||
<< endl;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
} } } // namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
#endif // EOLIAN_CXX_STD_COMMENT_HH
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef EOLIAN_CXX_CONTAINER_HH
|
||||
#define EOLIAN_CXX_CONTAINER_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
#include "grammar/case.hpp"
|
||||
#include "grammar/type.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct container_subtype_modify
|
||||
{
|
||||
typedef void result_type;
|
||||
void operator()(attributes::complex_type_def& /*x*/) const
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(attributes::regular_type_def& x) const
|
||||
{
|
||||
if(x.base_type == "string")
|
||||
remove_own(x.base_qualifier);
|
||||
else if(!x.pointers.empty())
|
||||
x.pointers.pop_back();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void operator()(T& /*x*/) const
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename OutputIterator, typename Context>
|
||||
void generate_container(OutputIterator sink, attributes::complex_type_def const& complex, Context const& context
|
||||
, std::string const& name)
|
||||
{
|
||||
if(!complex.subtypes.empty())
|
||||
{
|
||||
attributes::type_def subtype = complex.subtypes[0];
|
||||
subtype.original_type.visit(container_subtype_modify{});
|
||||
as_generator(" "<< name << "<" << type << ">").generate(sink, subtype, context);
|
||||
}
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef EOLIAN_CXX_CONTEXT_HH
|
||||
#define EOLIAN_CXX_CONTEXT_HH
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct context_null {};
|
||||
|
||||
template <typename Tag, typename Tail = context_null>
|
||||
struct context_cons
|
||||
{
|
||||
Tag tag;
|
||||
Tail const& tail;
|
||||
};
|
||||
|
||||
template <typename Tag>
|
||||
struct context_cons<Tag, context_null>
|
||||
{
|
||||
Tag tag;
|
||||
context_null tail;
|
||||
};
|
||||
|
||||
template <typename NewTag, typename Tag, typename Tail>
|
||||
context_cons<NewTag, context_cons<Tag, Tail>>
|
||||
context_add_tag(NewTag tag, context_cons<Tag, Tail> const& context)
|
||||
{
|
||||
return context_cons<NewTag, context_cons<Tag, Tail>>{tag, context};
|
||||
}
|
||||
template <typename NewTag>
|
||||
context_cons<NewTag, context_null>
|
||||
context_add_tag(NewTag tag, context_null context)
|
||||
{
|
||||
return context_cons<NewTag, context_null>{tag, context};
|
||||
}
|
||||
|
||||
template <typename Tag, typename Context>
|
||||
struct tag_check;
|
||||
template <typename Tag, typename Tail>
|
||||
struct tag_check<Tag, context_cons<Tag, Tail>> : std::true_type {};
|
||||
template <typename Tag>
|
||||
struct tag_check<Tag, context_null> : std::false_type {};
|
||||
template <typename Tag, typename OtherTag, typename Context>
|
||||
struct tag_check<Tag, context_cons<OtherTag, Context>> : tag_check<Tag, Context> {};
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef EOLIAN_CXX_CONVERTING_ARGUMENT_HH
|
||||
#define EOLIAN_CXX_CONVERTING_ARGUMENT_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
|
||||
#include "grammar/string.hpp"
|
||||
#include "grammar/indentation.hpp"
|
||||
#include "grammar/list.hpp"
|
||||
#include "grammar/alternative.hpp"
|
||||
#include "grammar/type.hpp"
|
||||
#include "grammar/parameter.hpp"
|
||||
#include "grammar/function_definition.hpp"
|
||||
#include "grammar/namespace.hpp"
|
||||
#include "grammar/c_type.hpp"
|
||||
#include "grammar/attribute_reorder.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct converting_argument_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& ctx) const
|
||||
{
|
||||
return as_generator
|
||||
(
|
||||
attribute_reorder<1, -1, 2>
|
||||
(
|
||||
" ::efl::eolian::convert_to_c<" << c_type << ", " << parameter_type << ">(" << string << ")"
|
||||
)
|
||||
).generate(sink, param, ctx);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<converting_argument_generator> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed<converting_argument_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
converting_argument_generator const converting_argument;
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -1,603 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_STD_EO_CLASS_CONSTRUCTORS_GENERATOR_HH
|
||||
#define EOLIAN_CXX_STD_EO_CLASS_CONSTRUCTORS_GENERATOR_HH
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
#include "eo_types.hh"
|
||||
#include "tab.hh"
|
||||
#include "comment.hh"
|
||||
#include "parameters_generator.hh"
|
||||
#include "namespace_generator.hh"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct class_name
|
||||
{
|
||||
std::string _name;
|
||||
class_name(std::string name)
|
||||
: _name(name)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, class_name const& x)
|
||||
{
|
||||
out << x._name;
|
||||
return out;
|
||||
}
|
||||
|
||||
struct class_inheritance
|
||||
{
|
||||
eo_class const& _cls;
|
||||
class_inheritance(eo_class const& cls)
|
||||
: _cls(cls)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, class_inheritance const& x)
|
||||
{
|
||||
eo_class const& cls = x._cls;
|
||||
|
||||
ancestors_container_type::const_iterator it,
|
||||
first = cls.ancestors.cbegin(),
|
||||
last = cls.ancestors.cend();
|
||||
for (it = first; it != last; ++it)
|
||||
{
|
||||
out << tab(2) << ", EO_CXX_INHERIT(" << *it << ")" << endl;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct constructor_functor_type_name
|
||||
{
|
||||
eo_constructor const& _ctor;
|
||||
constructor_functor_type_name(eo_constructor const& ctor)
|
||||
: _ctor(ctor)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, constructor_functor_type_name const& x)
|
||||
{
|
||||
out << "_c_" << x._ctor.name;
|
||||
return out;
|
||||
}
|
||||
|
||||
struct constructor_functor_type_decl
|
||||
{
|
||||
eo_constructor const& _ctor;
|
||||
constructor_functor_type_decl(eo_constructor const& ctor)
|
||||
: _ctor(ctor)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, constructor_functor_type_decl const& x)
|
||||
{
|
||||
out << constructor_functor_type_name(x._ctor);
|
||||
|
||||
if (parameters_count_callbacks(x._ctor.params) == 0)
|
||||
return out;
|
||||
|
||||
bool comma = false;
|
||||
out << "<";
|
||||
auto first = x._ctor.params.cbegin(), last = x._ctor.params.cend();
|
||||
for(auto it = first; it != last; ++it)
|
||||
{
|
||||
if (type_is_callback((*it).type) && it+1 != last)
|
||||
{
|
||||
if (comma)
|
||||
out << ", ";
|
||||
else
|
||||
comma = true;
|
||||
out << template_parameter_type((*it).type, (*it).name);
|
||||
}
|
||||
}
|
||||
return out << ">";
|
||||
}
|
||||
|
||||
struct functors_constructor_methods
|
||||
{
|
||||
eo_class const& _cls;
|
||||
functors_constructor_methods(eo_class const& cls) : _cls(cls) {}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, functors_constructor_methods const& x)
|
||||
{
|
||||
constructors_container_type::const_iterator it,
|
||||
first = x._cls.all_constructors.cbegin(),
|
||||
last = x._cls.all_constructors.cend();
|
||||
for (it = first; it != last; ++it)
|
||||
{
|
||||
eo_constructor const& c = *it;
|
||||
|
||||
// Hide documentation condition
|
||||
out << comment("@cond LOCAL", 1);
|
||||
|
||||
// Struct declaration
|
||||
out << template_parameters_declaration(c.params, 1)
|
||||
<< tab(1) << "struct " << constructor_functor_type_name(c) << endl
|
||||
<< tab(1) << "{" << endl;
|
||||
|
||||
// Callbacks typedefs
|
||||
out << parameters_cxx_generic(c.params,
|
||||
[](param_data d)
|
||||
{
|
||||
if (d.is_cb)
|
||||
d.out << tab(2)
|
||||
<< parameter_remove_reference_typedef(d.type, d.name)
|
||||
<< endl;
|
||||
}
|
||||
)
|
||||
<< endl;
|
||||
|
||||
// Struct constructor
|
||||
out << tab(2) << "explicit " << constructor_functor_type_name(c) << "("
|
||||
<< parameters_declaration(c.params) << ")"
|
||||
<< parameters_cxx_generic(c.params,
|
||||
[](param_data d)
|
||||
{
|
||||
if(d.pos == 0u)
|
||||
d.out << endl << tab(3) << ": ";
|
||||
else
|
||||
d.out << ", ";
|
||||
|
||||
if (d.is_cb)
|
||||
d.out << callback_tmp(d.name) << "(new "
|
||||
<< template_parameter_type(d.type, d.name)
|
||||
<< "(" << parameter_forward(d.type, d.name) << "))";
|
||||
else
|
||||
d.out << d.name << "(" << parameter_forward(d.type, d.name) << ")";
|
||||
}
|
||||
)
|
||||
<< endl
|
||||
<< tab(2) << "{}" << endl;
|
||||
|
||||
// Struct operator()
|
||||
out << tab(2) << "void operator()(Eo* _obj_eo_self)" << endl
|
||||
<< tab(2) << "{" << endl
|
||||
<< tab(3) << "::" << c.impl << "(_obj_eo_self" << (c.params.empty() ? "" : ", ")
|
||||
<< parameters_forward_to_c(c.params) << ");" << endl
|
||||
<< tab(2) << "}" << endl;
|
||||
|
||||
// Register event to free allocated callbacks when the Eo* is deleted
|
||||
out << tab(2) << "void register_ev_del_free_callback(Eo* _eoptr)" << endl
|
||||
<< tab(2) << "{" << endl
|
||||
<< tab(3) << "(void) _eoptr;" << endl
|
||||
<< parameters_cxx_generic(c.params,
|
||||
[](param_data d)
|
||||
{
|
||||
if (d.is_cb)
|
||||
d.out << tab(3)
|
||||
<< "eo_event_callback_add(_eoptr, EO_EVENT_DEL, "
|
||||
<< "&::efl::eolian::free_callback_callback<"
|
||||
<< parameter_no_ref_type(d.type, d.name)
|
||||
<< ">, " << callback_tmp(d.name) << ");" << endl;
|
||||
})
|
||||
<< tab(2) << "}" << endl;
|
||||
|
||||
// Struct member variables
|
||||
out << endl
|
||||
<< parameters_cxx_generic(c.params,
|
||||
[](param_data d)
|
||||
{
|
||||
d.out << tab(2);
|
||||
if (d.is_cb)
|
||||
d.out << parameter_no_ref_type(d.type, d.name) << "* "
|
||||
<< callback_tmp(d.name);
|
||||
else
|
||||
d.out << parameter_type(d.type, d.name) << " " << d.name;
|
||||
d.out << ";" << endl;
|
||||
}
|
||||
);
|
||||
|
||||
// Close struct
|
||||
out << tab(1) << "};" << endl;
|
||||
|
||||
// End documentation condition
|
||||
out << comment("@endcond", 1) << endl;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
struct constructor_method_function_declarations
|
||||
{
|
||||
eo_class const& _cls;
|
||||
constructor_method_function_declarations(eo_class const& cls) : _cls(cls) {}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, constructor_method_function_declarations const& x)
|
||||
{
|
||||
constructors_container_type::const_iterator it,
|
||||
first = x._cls.all_constructors.cbegin(),
|
||||
last = x._cls.all_constructors.cend();
|
||||
for (it = first; it != last; ++it)
|
||||
{
|
||||
eo_constructor const& c = *it;
|
||||
|
||||
// "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, 1)
|
||||
<< template_parameters_declaration(c.params, 1)
|
||||
<< tab(1) << "static " << constructor_functor_type_decl(c)
|
||||
<< " " << c.name << "("
|
||||
<< parameters_declaration(c.params) << ");" << 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.all_constructors.cbegin(),
|
||||
last = x._cls.all_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 " << full_name(x._cls)
|
||||
<< "::" << constructor_functor_type_decl(c) << " "
|
||||
<< full_name(x._cls, false) << "::" << c.name << "("
|
||||
<< parameters_declaration(c.params) << ")" << endl
|
||||
<< "{" << endl
|
||||
<< tab(1) << "return " << constructor_functor_type_decl(c) << "("
|
||||
<< parameters_forward(c.params) << ");" << endl
|
||||
<< "}" << endl << endl;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
struct comment_constructor_with_constructor_methods
|
||||
{
|
||||
eo_class const& _cls;
|
||||
comment_constructor_with_constructor_methods(eo_class const& cls)
|
||||
: _cls(cls)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, comment_constructor_with_constructor_methods const& x)
|
||||
{
|
||||
out << tab(1) << "/**" << endl
|
||||
<< tab(2) << "@brief Constructs a new " << full_name(x._cls, false) << " object." << endl
|
||||
<< endl
|
||||
<< tab(2) << "Constructs a new " << full_name(x._cls, false) << " object. If you want this object to be a child" << endl
|
||||
<< tab(2) << "of another Eo object, use an @ref efl::eo::parent expression, like the example." << endl
|
||||
<< endl;
|
||||
|
||||
if (x._cls.constructors.size())
|
||||
{
|
||||
bool singular = (x._cls.constructors.size() == 1);
|
||||
out << tab(2) << "Since this class have " << (singular ? "a " : "")
|
||||
<< "necessary constructor method" << (singular ? "" : "s")
|
||||
<< ", you must call " << (singular ? "it" : "each one of them") << endl
|
||||
<< tab(2) << "in the right place within this constructor parameters." << endl
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if (!x._cls.optional_constructors.empty())
|
||||
{
|
||||
out << tab(2) << "Optional constructors may be called in any combination as the" << endl
|
||||
<< tab(2) << "last parameters." << endl
|
||||
<< endl;
|
||||
}
|
||||
|
||||
out << tab(2) << "Example:" << endl
|
||||
<< tab(2) << "@code" << endl
|
||||
<< tab(2) << full_name(x._cls, false) << " my_" << x._cls.name << "(efl::eo::parent = parent_object";
|
||||
|
||||
for (eo_constructor const& c : x._cls.all_constructors)
|
||||
out << "," << endl
|
||||
<< tab(3) << "my_" << x._cls.name << "." << c.name << "(" << parameters_names(c.params) << ")";
|
||||
|
||||
out << ");" << endl
|
||||
<< tab(2) << "@endcode" << endl
|
||||
<< endl;
|
||||
|
||||
for (eo_constructor const& c : x._cls.all_constructors)
|
||||
out << tab(2) << "@see " << x._cls.name << "::" << c.name << endl;
|
||||
out << tab(2) << "@see " << x._cls.name << "(Eo* eo)" << endl;
|
||||
|
||||
return out << tab(1) << "*/" << endl;
|
||||
}
|
||||
|
||||
struct constructor_with_constructor_methods
|
||||
{
|
||||
eo_class const& _cls;
|
||||
bool _with_parent;
|
||||
constructor_with_constructor_methods(eo_class const& cls, bool with_parent)
|
||||
: _cls(cls)
|
||||
, _with_parent(with_parent)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, constructor_with_constructor_methods const& x)
|
||||
{
|
||||
unsigned cb_count = 0;
|
||||
|
||||
constructors_container_type::const_iterator it,
|
||||
first = x._cls.constructors.cbegin(),
|
||||
last = x._cls.constructors.cend();
|
||||
for (it = first; it != last; ++it)
|
||||
{
|
||||
cb_count += parameters_count_callbacks((*it).params);
|
||||
}
|
||||
|
||||
if (cb_count != 0 || !x._cls.optional_constructors.empty())
|
||||
{
|
||||
out << tab(1) << "template <";
|
||||
for (unsigned i = 0; i != cb_count; ++i)
|
||||
{
|
||||
if (i != 0)
|
||||
out << ", ";
|
||||
out << "typename F" << i;
|
||||
}
|
||||
if (!x._cls.optional_constructors.empty())
|
||||
{
|
||||
if (cb_count != 0)
|
||||
out << ", ";
|
||||
out << "typename... FOpts";
|
||||
}
|
||||
out << ">" << endl;
|
||||
}
|
||||
|
||||
out << tab(1) << "explicit " << x._cls.name << "(";
|
||||
|
||||
if (x._with_parent)
|
||||
out << "::efl::eo::parent_type _p";
|
||||
|
||||
{
|
||||
unsigned cb_idx = 0;
|
||||
for (it = first; it != last; ++it)
|
||||
{
|
||||
if (x._with_parent || it != first)
|
||||
out << ", ";
|
||||
out << constructor_functor_type_name(*it);
|
||||
|
||||
if (cb_count != 0 && parameters_count_callbacks((*it).params) != 0)
|
||||
{
|
||||
out << "<"
|
||||
<< parameters_cxx_generic((*it).params,
|
||||
[&cb_idx](param_data d)
|
||||
{
|
||||
if (d.is_cb)
|
||||
d.out << (d.cb_idx ? ", " : "") << "F" << cb_idx++;
|
||||
})
|
||||
<< ">";
|
||||
}
|
||||
out << " _c" << (it-first);
|
||||
}
|
||||
assert(cb_idx == cb_count);
|
||||
}
|
||||
|
||||
if (!x._cls.optional_constructors.empty())
|
||||
{
|
||||
if (x._with_parent || first != last)
|
||||
out << ", ";
|
||||
out << "FOpts&&... _opts";
|
||||
}
|
||||
|
||||
out << ")" << endl
|
||||
<< tab(2) << ": " << x._cls.name << "(_ctors_call("
|
||||
<< (x._with_parent ? "_p" : "::efl::eo::parent = nullptr");
|
||||
for (it = first; it != last; ++it)
|
||||
{
|
||||
out << ", _c" << (it-first);
|
||||
}
|
||||
if (!x._cls.optional_constructors.empty())
|
||||
{
|
||||
out << ", std::forward<FOpts>(_opts)...";
|
||||
}
|
||||
out << "))" << endl
|
||||
<< tab(1) << "{}" << endl;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
struct constructors_with_constructor_methods
|
||||
{
|
||||
eo_class const& _cls;
|
||||
constructors_with_constructor_methods(eo_class const& cls)
|
||||
: _cls(cls)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, constructors_with_constructor_methods const& x)
|
||||
{
|
||||
out << tab(1) << "//@{" << endl
|
||||
<< comment_constructor_with_constructor_methods(x._cls)
|
||||
<< constructor_with_constructor_methods(x._cls, true) << endl
|
||||
<< constructor_with_constructor_methods(x._cls, false)
|
||||
<< tab(1) << "//@}" << endl << endl;
|
||||
return out;
|
||||
}
|
||||
|
||||
struct constructor_eo
|
||||
{
|
||||
eo_class const& _cls;
|
||||
constructor_eo(eo_class const& cls)
|
||||
: _cls(cls)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, constructor_eo const& x)
|
||||
{
|
||||
std::string doc = "@brief Eo Constructor.\n\n"
|
||||
"Constructs the object from an Eo* pointer stealing its ownership.\n\n"
|
||||
"@param eo The Eo object pointer.\n\n";
|
||||
out << comment(doc, 1)
|
||||
<< tab(1)
|
||||
<< "explicit " << x._cls.name << "(Eo* eo)" << endl
|
||||
<< tab(2) << ": ::efl::eo::concrete(eo)" << endl
|
||||
<< tab(1) << "{}" << endl << endl;
|
||||
|
||||
out << comment(
|
||||
"@brief nullptr_t Constructor.\n\n"
|
||||
"Constructs an empty (null) object.\n\n"
|
||||
, 1
|
||||
)
|
||||
<< tab(1)
|
||||
<< "explicit " << x._cls.name << "(std::nullptr_t)" << endl
|
||||
<< tab(2) << ": ::efl::eo::concrete(nullptr)" << endl
|
||||
<< tab(1) << "{}" << endl << endl;
|
||||
return out;
|
||||
}
|
||||
|
||||
struct copy_constructor
|
||||
{
|
||||
eo_class const& _cls;
|
||||
copy_constructor(eo_class const& cls)
|
||||
: _cls(cls)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, copy_constructor const& x)
|
||||
{
|
||||
std::string doc = "@brief Copy Constructor.\n\n";
|
||||
out << comment(doc, 1)
|
||||
<< tab(1)
|
||||
<< x._cls.name << "(" << x._cls.name << " const& other)" << endl
|
||||
<< tab(2) << ": " << x._cls.name
|
||||
<< "(eo_ref(other._eo_ptr()))" << endl
|
||||
<< tab(1) << "{}" << endl << endl;
|
||||
return out;
|
||||
}
|
||||
|
||||
struct destructor
|
||||
{
|
||||
eo_class const& _cls;
|
||||
destructor(eo_class const& cls)
|
||||
: _cls(cls)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, destructor const& x)
|
||||
{
|
||||
out << tab(1)
|
||||
<< '~' << x._cls.name << "() {}" << endl << endl;
|
||||
return out;
|
||||
}
|
||||
|
||||
struct function_call_constructor_methods
|
||||
{
|
||||
eo_class const& _cls;
|
||||
function_call_constructor_methods(eo_class const& cls) : _cls(cls) {}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, function_call_constructor_methods const& x)
|
||||
{
|
||||
out << comment("@internal", 1);
|
||||
|
||||
unsigned cb_count = 0;
|
||||
|
||||
constructors_container_type::const_iterator it,
|
||||
first = x._cls.constructors.cbegin(),
|
||||
last = x._cls.constructors.cend();
|
||||
for (it = first; it != last; ++it)
|
||||
{
|
||||
cb_count += parameters_count_callbacks((*it).params);
|
||||
}
|
||||
if (cb_count != 0 || !x._cls.optional_constructors.empty())
|
||||
{
|
||||
out << tab(1) << "template <";
|
||||
for (unsigned i = 0; i != cb_count; ++i)
|
||||
{
|
||||
if (i != 0)
|
||||
out << ", ";
|
||||
out << "typename F" << i;
|
||||
}
|
||||
if (!x._cls.optional_constructors.empty())
|
||||
{
|
||||
if (cb_count != 0)
|
||||
out << ", ";
|
||||
out << "typename... FOpts";
|
||||
}
|
||||
out << ">" << endl;
|
||||
}
|
||||
|
||||
unsigned cb_idx = 0;
|
||||
out << tab(1) << "static Eo* _ctors_call(::efl::eo::parent_type _p";
|
||||
for (it = first; it != last; ++it)
|
||||
{
|
||||
out << ", " << constructor_functor_type_name(*it);
|
||||
|
||||
if (cb_count != 0 && parameters_count_callbacks((*it).params) != 0)
|
||||
{
|
||||
out << "<"
|
||||
<< parameters_cxx_generic((*it).params,
|
||||
[&cb_idx](param_data d)
|
||||
{
|
||||
if (d.is_cb)
|
||||
d.out << (d.cb_idx ? ", " : "") << "F" << cb_idx++;
|
||||
})
|
||||
<< ">";
|
||||
}
|
||||
out << " _c" << (it-first);
|
||||
}
|
||||
assert(cb_idx == cb_count);
|
||||
|
||||
if (!x._cls.optional_constructors.empty())
|
||||
out << ", FOpts&&... _opts";
|
||||
|
||||
out << ")" << endl
|
||||
<< tab(1) << "{" << endl
|
||||
<< tab(2) << "Eo* _ret_eo = eo_add_ref(" << x._cls.eo_name << ", _p._eo_raw";
|
||||
for (it = first; it != last; ++it)
|
||||
{
|
||||
out << ", _c" << (it-first) << "(eo_self)";
|
||||
}
|
||||
if (!x._cls.optional_constructors.empty())
|
||||
out << ", ::efl::eolian::call_ctors(eo_self, _opts...)";
|
||||
out << ");" << endl << endl;
|
||||
|
||||
for (it = first; it != last; ++it)
|
||||
out << tab(2) << "_c" << (it-first) << ".register_ev_del_free_callback(_ret_eo);" << endl;
|
||||
|
||||
if (!x._cls.optional_constructors.empty())
|
||||
out << tab(2) << "::efl::eolian::register_ev_del_free_callback(_ret_eo, _opts...);" << endl;
|
||||
|
||||
out << tab(2) << "return _ret_eo;" << endl
|
||||
<< tab(1) << "}" << endl << endl;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
} } } // namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
#endif // EOLIAN_CXX_STD_EO_CLASS_CONSTRUCTORS_GENERATOR_HH
|
|
@ -1,117 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_STD_EO_CLASS_EVENTS_GENERATOR_HH
|
||||
#define EOLIAN_CXX_STD_EO_CLASS_EVENTS_GENERATOR_HH
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
#include "type_generator.hh"
|
||||
#include "eo_class_scope_guard_generator.hh"
|
||||
#include "tab.hh"
|
||||
#include "comment.hh"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct add_cast_to_t
|
||||
{
|
||||
add_cast_to_t(bool b)
|
||||
: _b(b)
|
||||
{
|
||||
}
|
||||
|
||||
bool _b;
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, add_cast_to_t x)
|
||||
{
|
||||
if(x._b)
|
||||
out << "static_cast<U*>(this)->";
|
||||
return out;
|
||||
}
|
||||
|
||||
struct event_callback_add
|
||||
{
|
||||
eo_event const& _event;
|
||||
eo_class const& _cls;
|
||||
bool _add_cast_to_t;
|
||||
event_callback_add(eo_event const& event, eo_class const& cls
|
||||
, bool add_cast_to_t)
|
||||
: _event(event), _cls(cls), _add_cast_to_t(add_cast_to_t)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, event_callback_add const& x)
|
||||
{
|
||||
out << comment(x._event.comment, 1)
|
||||
<< tab(1) << "template <typename F>" << endl
|
||||
<< tab(1) << "::efl::eo::signal_connection" << endl
|
||||
<< tab(1) << "callback_" << x._event.name << "_add(F && callback_," << endl
|
||||
<< tab(8) << "::efl::eo::callback_priority priority_ =" << endl
|
||||
<< tab(8) << "::efl::eo::callback_priorities::default_)" << endl
|
||||
<< 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::forward<F>(callback_)) );" << endl
|
||||
<< tab(2) << "eo_event_callback_priority_add(" << add_cast_to_t(x._add_cast_to_t) << "_concrete_eo_ptr()," << endl
|
||||
<< tab(2) << x._event.eo_name << ", priority_," << endl
|
||||
<< tab(2) << "&::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)
|
||||
<< "_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;
|
||||
}
|
||||
|
||||
struct event_callback_call
|
||||
{
|
||||
eo_event const& _event;
|
||||
bool _add_cast_to_t;
|
||||
event_callback_call(eo_event const& event, bool add_cast_to_t)
|
||||
: _event(event), _add_cast_to_t(add_cast_to_t)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, event_callback_call const& x)
|
||||
{
|
||||
out << comment(x._event.comment, 1)
|
||||
<< tab(1) << "template <typename T>" << endl
|
||||
<< tab(1) << "void" << endl
|
||||
<< tab(1) << "callback_" << x._event.name << "_call(T* info)" << endl
|
||||
<< tab(1) << "{" << endl
|
||||
<< tab(2) << "eo_event_callback_call" << endl
|
||||
<< tab(4) << "(" << add_cast_to_t(x._add_cast_to_t) << "_concrete_eo_ptr(), " << x._event.eo_name << ", info);" << endl
|
||||
<< tab(1) << "}" << endl;
|
||||
return out;
|
||||
}
|
||||
|
||||
struct events
|
||||
{
|
||||
eo_class const& _cls;
|
||||
events_container_type const& _events;
|
||||
bool _add_cast_to_t;
|
||||
events(eo_class const& cls, events_container_type const& evts, bool add_cast_to_t = false)
|
||||
: _cls(cls), _events(evts), _add_cast_to_t(add_cast_to_t) {}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, events const& x)
|
||||
{
|
||||
for (eo_event const& e : x._events)
|
||||
{
|
||||
out << scope_guard_head(x._cls, e);
|
||||
|
||||
out << event_callback_add(e, x._cls, x._add_cast_to_t) << endl
|
||||
<< event_callback_call(e, x._add_cast_to_t);
|
||||
|
||||
out << scope_guard_tail(x._cls, e) << endl;
|
||||
}
|
||||
out << endl;
|
||||
return out;
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif // EOLIAN_CXX_STD_EO_CLASS_EVENTS_GENERATOR_HH
|
|
@ -1,173 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_STD_EO_CLASS_FUNCTIONS_GENERATOR_HH
|
||||
#define EOLIAN_CXX_STD_EO_CLASS_FUNCTIONS_GENERATOR_HH
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
#include "eo_types.hh"
|
||||
#include "tab.hh"
|
||||
#include "comment.hh"
|
||||
#include "parameters_generator.hh"
|
||||
#include "type_generator.hh"
|
||||
#include "namespace_generator.hh"
|
||||
#include "eo_class_scope_guard_generator.hh"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct function_call
|
||||
{
|
||||
eo_function const& _func;
|
||||
function_call(eo_function const& func) : _func(func) {}
|
||||
};
|
||||
|
||||
struct parameterized_obj_function_call
|
||||
{
|
||||
eo_function const& _func;
|
||||
std::string obj;
|
||||
parameterized_obj_function_call(eo_function const& func, std::string obj) : _func(func), obj(obj) {}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, function_call const& x)
|
||||
{
|
||||
bool is_void = function_is_void(x._func);
|
||||
bool is_static = function_is_static(x._func);
|
||||
return out << (!is_void ? "_tmp_ret = " : "")
|
||||
<< "::" << x._func.impl
|
||||
<< "("
|
||||
<< (is_static ? "const_cast<Eo*>(_eo_class())" : "_concrete_eo_ptr()")
|
||||
<< (x._func.params.empty() ? "" : ",")
|
||||
<< parameters_forward_to_c(x._func.params) << ")";
|
||||
}
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, parameterized_obj_function_call const& x)
|
||||
{
|
||||
bool is_void = function_is_void(x._func);
|
||||
return out << (!is_void ? "_tmp_ret = " : "")
|
||||
<< "::" << x._func.impl
|
||||
<< "("
|
||||
<< x.obj
|
||||
<< (x._func.params.empty() ? "" : ",")
|
||||
<< parameters_forward_to_c(x._func.params) << ")";
|
||||
}
|
||||
|
||||
struct function_declaration
|
||||
{
|
||||
eo_class const& _cls;
|
||||
eo_function const& _func;
|
||||
function_declaration(eo_class const& cls, eo_function const& func)
|
||||
: _cls(cls), _func(func)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, function_declaration const& x)
|
||||
{
|
||||
eo_function const& func = x._func;
|
||||
|
||||
out << comment(x._func.comment, 1)
|
||||
<< template_parameters_declaration(func.params, 1)
|
||||
<< tab(1);
|
||||
|
||||
bool is_static = function_is_static(func);
|
||||
if (is_static)
|
||||
out << "static ";
|
||||
|
||||
out << reinterpret_type(func.ret) << " " << func.name << "("
|
||||
<< parameters_declaration(func.params)
|
||||
<< (is_static ? ");" : ") const;") << endl;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
struct function_definition
|
||||
{
|
||||
eo_class const& _cls;
|
||||
eo_function const& _func;
|
||||
bool _concrete;
|
||||
function_definition(eo_class const& cls, eo_function const& func, bool concrete)
|
||||
: _cls(cls), _func(func), _concrete(concrete)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, function_definition const& x)
|
||||
{
|
||||
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) << " ";
|
||||
|
||||
if (x._concrete)
|
||||
out << full_name(x._cls, false);
|
||||
else
|
||||
out << abstract_full_name(x._cls, false);
|
||||
|
||||
out << "::" << 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;
|
||||
|
||||
out << callbacks_heap_alloc("_concrete_eo_ptr()", func.params, is_static, 1);
|
||||
|
||||
out << tab(1) << function_call(x._func) << ";" << endl;
|
||||
|
||||
if (!function_is_void(func))
|
||||
out << tab(1) << "return " << to_cxx(func.ret, "_tmp_ret") << ";" << endl;
|
||||
|
||||
out << "}" << 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 << scope_guard_head(x._cls, f)
|
||||
<< function_declaration(x._cls, f)
|
||||
<< scope_guard_tail(x._cls, f) << endl;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct function_definitions
|
||||
{
|
||||
eo_class const& _cls;
|
||||
bool _concrete;
|
||||
function_definitions(eo_class const& cls, bool concrete)
|
||||
: _cls(cls)
|
||||
, _concrete(concrete)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, function_definitions const& x)
|
||||
{
|
||||
for (eo_function const& f : x._cls.functions)
|
||||
{
|
||||
out << scope_guard_head(x._cls, f)
|
||||
<< function_definition(x._cls, f, x._concrete)
|
||||
<< scope_guard_tail(x._cls, f) << endl;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
} } } // namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
#endif // EOLIAN_CXX_STD_EO_CLASS_FUNCTIONS_GENERATOR_HH
|
|
@ -1,265 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_EO_CLASS_GENERATOR_HH
|
||||
#define EOLIAN_CXX_EO_CLASS_GENERATOR_HH
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
#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"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct eo_class_getter
|
||||
{
|
||||
eo_class const& _cls;
|
||||
eo_class_getter(eo_class const& cls) : _cls(cls) {}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, eo_class_getter const& x)
|
||||
{
|
||||
out << tab(1) << "static Eo_Class const* _eo_class()" << endl
|
||||
<< tab(1) << "{" << endl
|
||||
<< tab(2) << "return("<< x._cls.eo_name << ");" << endl
|
||||
<< tab(1) << "}" << endl << endl;
|
||||
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 << comment("@internal", 1)
|
||||
<< 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;
|
||||
}
|
||||
|
||||
struct address_of_to_pointer
|
||||
{
|
||||
eo_class const& _cls;
|
||||
bool _is_const;
|
||||
address_of_to_pointer(eo_class const& cls, bool is_const)
|
||||
: _cls(cls), _is_const(is_const)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, address_of_to_pointer const& x)
|
||||
{
|
||||
out << "operator " << full_name(x._cls) << (x._is_const ? " const" : "")
|
||||
<< "*() const { return static_cast<" << full_name(x._cls)
|
||||
<< (x._is_const ? " const" : "")
|
||||
<< "*>(static_cast<D const*>(this)->p); }";
|
||||
return out;
|
||||
}
|
||||
|
||||
struct abstract_address_of
|
||||
{
|
||||
eo_class const& _cls;
|
||||
abstract_address_of(eo_class const& cls) : _cls(cls) {}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, abstract_address_of const& x)
|
||||
{
|
||||
out << comment("@cond LOCAL", 1);
|
||||
|
||||
out << tab(1) << "template <typename D>" << endl
|
||||
<< tab(1) << "struct address_of" << endl
|
||||
<< tab(1) << "{" << endl
|
||||
<< tab(2) << address_of_to_pointer(x._cls, false) << endl
|
||||
<< tab(2) << address_of_to_pointer(x._cls, true) << endl
|
||||
<< tab(1) << "};" << endl << endl;
|
||||
|
||||
out << tab(1) << "template <typename D>" << endl
|
||||
<< tab(1) << "struct address_const_of" << endl
|
||||
<< tab(1) << "{" << endl
|
||||
<< tab(2) << address_of_to_pointer(x._cls, true) << endl
|
||||
<< tab(1) << "};" << endl;
|
||||
|
||||
out << comment("@endcond", 1) << endl;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
struct address_of_inheritance
|
||||
{
|
||||
eo_class const& _cls;
|
||||
std::string _struct_name;
|
||||
address_of_inheritance(eo_class const& cls, std::string const& struct_name)
|
||||
: _cls(cls), _struct_name(struct_name)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, address_of_inheritance const& x)
|
||||
{
|
||||
for (std::string const& parent : x._cls.ancestors)
|
||||
{
|
||||
out << tab(2) << ", ::" << abstract_namespace << "::" << parent << "::"
|
||||
<< x._struct_name << "<" << x._struct_name << ">" << endl;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct concrete_address_of
|
||||
{
|
||||
eo_class const& _cls;
|
||||
concrete_address_of(eo_class const& cls) : _cls(cls) {}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, concrete_address_of const& x)
|
||||
{
|
||||
out << comment("@cond LOCAL", 1);
|
||||
std::vector<std::string> names {"address_of", "address_const_of"};
|
||||
for (int is_const = 0; is_const != 2; ++is_const)
|
||||
{
|
||||
std::string const& name = names[is_const];
|
||||
|
||||
out << tab(1) << "struct " << name << endl
|
||||
<< tab(2) << ": " << abstract_full_name(x._cls) << "::"
|
||||
<< name << "<" << name << ">" << endl
|
||||
<< address_of_inheritance(x._cls, name)
|
||||
<< tab(2) << ", ::efl::eo::detail::concrete_" << name << endl
|
||||
<< tab(1) << "{" << endl
|
||||
<< tab(2) << "explicit " << name << "(" << full_name(x._cls)
|
||||
<< (is_const ? " const" : "")
|
||||
<< "* p)" << endl
|
||||
<< tab(3) << ": ::efl::eo::detail::concrete_" << name << "(p)" << endl
|
||||
<< tab(2) << "{}" << endl
|
||||
<< tab(1) << "};" << endl
|
||||
<< tab(1) << name << " operator&()"
|
||||
<< (is_const ? " const" : "")
|
||||
<< " { return " << name << "(this); }" << endl << endl;
|
||||
}
|
||||
out << comment("@endcond", 1) << endl;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
inline void
|
||||
eo_class_declarations_generator(std::ostream& out, eo_class const& cls)
|
||||
{
|
||||
out << namespace_head(cls)
|
||||
<< "struct " << cls.name << ";" << endl << endl
|
||||
<< namespace_tail(cls)
|
||||
<< comment("@cond EO_CXX_ABSTRACT")
|
||||
<< "namespace " << abstract_namespace << " {" << endl << endl
|
||||
<< namespace_head(cls)
|
||||
<< comment(cls.comment)
|
||||
<< "struct " << cls.name << endl
|
||||
<< '{' << endl
|
||||
<< function_declarations(cls)
|
||||
<< events(cls, cls.own_events) << endl
|
||||
<< eo_class_getter(cls)
|
||||
<< class_implicit_conversion_declaration(cls)
|
||||
<< abstract_address_of(cls)
|
||||
<< "private:" << endl << endl
|
||||
<< concrete_eo_ptr_getter(cls)
|
||||
<< "};" << endl << endl
|
||||
<< namespace_tail(cls)
|
||||
<< "}" << endl
|
||||
<< comment("@endcond") << endl
|
||||
<< namespace_head(cls)
|
||||
<< comment(cls.comment, 0, "@brief Class " + cls.name)
|
||||
<< "struct " << cls.name << endl
|
||||
<< tab(2) << ": ::efl::eo::concrete" << endl
|
||||
<< class_inheritance(cls)
|
||||
<< '{' << endl
|
||||
<< functors_constructor_methods(cls)
|
||||
<< constructors_with_constructor_methods(cls)
|
||||
<< constructor_eo(cls)
|
||||
<< copy_constructor(cls)
|
||||
<< destructor(cls)
|
||||
<< constructor_method_function_declarations(cls)
|
||||
<< function_declarations(cls)
|
||||
<< events(cls, cls.concrete_events) << endl
|
||||
<< eo_class_getter(cls)
|
||||
<< concrete_address_of(cls)
|
||||
<< "private:" << endl << endl
|
||||
<< function_call_constructor_methods(cls)
|
||||
<< comment("@internal", 1)
|
||||
<< tab(1) << "Eo* _concrete_eo_ptr() const { return _eo_ptr(); }" << 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)
|
||||
<< endl;
|
||||
}
|
||||
|
||||
inline void
|
||||
eo_class_definitions_generator(std::ostream& out, eo_class const& cls)
|
||||
{
|
||||
out << constructor_method_function_definitions(cls)
|
||||
<< function_definitions(cls, true)
|
||||
<< function_definitions(cls, false)
|
||||
<< class_implicit_conversion_definition(cls);
|
||||
}
|
||||
|
||||
} } } // namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
#endif // EOLIAN_CXX_EO_CLASS_GENERATOR_HH
|
|
@ -1,65 +0,0 @@
|
|||
#ifndef EOLIAN_CXX_STD_EO_CLASS_SCOPE_GUARD_GENERATOR_HH
|
||||
#define EOLIAN_CXX_STD_EO_CLASS_SCOPE_GUARD_GENERATOR_HH
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "type_generator.hh"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
template <typename T>
|
||||
struct _scope_guard_head
|
||||
{
|
||||
eo_class const& _cls;
|
||||
T const& _e;
|
||||
_scope_guard_head(eo_class const& cls, T const& e)
|
||||
: _cls(cls), _e(e) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
_scope_guard_head<T> scope_guard_head(eo_class const& cls, T const& e)
|
||||
{
|
||||
return _scope_guard_head<T>(cls, e);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, _scope_guard_head<T> const& x)
|
||||
{
|
||||
assert(x._e.scope != eolian_scope::private_);
|
||||
if (x._e.scope == eolian_scope::protected_)
|
||||
out << "#ifdef " << name_upper(x._cls) << "_PROTECTED" << endl;
|
||||
if (x._e.is_beta)
|
||||
out << "#ifdef " << name_upper(x._cls) << "_BETA" << endl;
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct _scope_guard_tail
|
||||
{
|
||||
eo_class const& _cls;
|
||||
T const& _e;
|
||||
_scope_guard_tail(eo_class const& cls, T const& e)
|
||||
: _cls(cls), _e(e) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct _scope_guard_tail<T> scope_guard_tail(eo_class const& cls, T const& e)
|
||||
{
|
||||
return _scope_guard_tail<T>(cls, e);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, _scope_guard_tail<T> const& x)
|
||||
{
|
||||
if (x._e.scope == eolian_scope::protected_)
|
||||
out << "#endif" << endl;
|
||||
if (x._e.is_beta)
|
||||
out << "#endif" << endl;
|
||||
return out;
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -1,150 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_STD_EO_HEADER_GENERATOR_HH
|
||||
#define EOLIAN_CXX_STD_EO_HEADER_GENERATOR_HH
|
||||
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
#include <iosfwd>
|
||||
#include <cctype>
|
||||
|
||||
#include "eo_types.hh"
|
||||
#include "tab.hh"
|
||||
#include "eo_class_generator.hh"
|
||||
#include "inheritance_base_generator.hh"
|
||||
|
||||
namespace {
|
||||
std::string
|
||||
_onceguard_key(efl::eolian::eo_class const& cls)
|
||||
{
|
||||
std::string key;
|
||||
if (cls.name_space != "")
|
||||
{
|
||||
std::string ns = cls.name_space;
|
||||
size_t pos = 0;
|
||||
while ((pos = ns.find("::")) != std::string::npos)
|
||||
{
|
||||
key += ns.substr(0, pos) + "_";
|
||||
ns.erase(0, pos+2);
|
||||
}
|
||||
key += ns + "_";
|
||||
}
|
||||
key += cls.name;
|
||||
std::transform(key.begin(), key.end(), key.begin(), ::toupper);
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct include_dependencies
|
||||
{
|
||||
eo_class const& _cls;
|
||||
eo_generator_options const& _opts;
|
||||
include_dependencies(eo_class const& cls, eo_generator_options const& opts)
|
||||
: _cls(cls)
|
||||
, _opts(opts)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, include_dependencies const& x)
|
||||
{
|
||||
std::set<std::string> headers;
|
||||
eo_class const& cls = x._cls;
|
||||
|
||||
for (auto it = cls.constructors.cbegin(), last = cls.constructors.cend();
|
||||
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.parts)
|
||||
for (std::string header : subtype.includes)
|
||||
if (header != x._opts.header_decl_file_name)
|
||||
headers.insert(header);
|
||||
|
||||
for (auto it = cls.functions.begin(), last = cls.functions.end();
|
||||
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.parts)
|
||||
for (std::string header : subtype.includes)
|
||||
if (header != x._opts.header_decl_file_name)
|
||||
headers.insert(header);
|
||||
|
||||
for (std::string header : headers)
|
||||
out << "#include <" << header << ">" << endl;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
inline void
|
||||
onceguard_head(std::ostream& out, eo_class const& cls)
|
||||
{
|
||||
std::string key = ::_onceguard_key(cls);
|
||||
out << "#ifndef EFL_GENERATED_" << key << "_HH" << endl
|
||||
<< "#define EFL_GENERATED_" << key << "_HH" << endl << endl;
|
||||
}
|
||||
|
||||
inline void
|
||||
onceguard_tail(std::ostream& out, eo_class const& cls)
|
||||
{
|
||||
std::string key = ::_onceguard_key(cls);
|
||||
out << "#endif // EFL_GENERATED_" << key << "_HH" << endl;
|
||||
}
|
||||
|
||||
inline void
|
||||
include_headers(std::ostream& out,
|
||||
eo_class const& cls EINA_UNUSED,
|
||||
eo_generator_options const& opts)
|
||||
{
|
||||
out << "extern \"C\"" << endl
|
||||
<< "{" << endl
|
||||
<< "#include <Efl.h>" << endl
|
||||
<< "}" << endl
|
||||
<< "#include <Eo.hh>" << endl << endl
|
||||
<< "#include <eo_cxx_interop.hh>" << endl << endl
|
||||
<< "extern \"C\"" << endl
|
||||
<< "{" << endl;
|
||||
for (auto c_header : opts.c_headers)
|
||||
{
|
||||
out << "#include \"" << c_header << "\"" << endl;
|
||||
}
|
||||
out << "}" << endl << endl;
|
||||
for (auto cxx_header : opts.cxx_headers)
|
||||
{
|
||||
out << "#include \"" << cxx_header << "\"" << endl;
|
||||
}
|
||||
out << include_dependencies(cls, opts) << endl;
|
||||
}
|
||||
|
||||
inline void
|
||||
include_header_impl(std::ostream& out,
|
||||
eo_class const& cls EINA_UNUSED,
|
||||
eo_generator_options const& opts)
|
||||
{
|
||||
out << "#include \"" << opts.header_impl_file_name << "\"" << endl << endl;
|
||||
}
|
||||
|
||||
inline void
|
||||
eo_headers_generator(std::ostream& header_decl,
|
||||
std::ostream& header_impl,
|
||||
eo_class const& cls,
|
||||
eo_generator_options const& opts)
|
||||
{
|
||||
onceguard_head(header_decl, cls);
|
||||
include_headers(header_decl, cls, opts);
|
||||
eo_class_declarations_generator(header_decl, cls);
|
||||
include_header_impl(header_decl, cls, opts);
|
||||
onceguard_tail(header_decl, cls);
|
||||
header_decl << endl;
|
||||
|
||||
header_impl << comment("@cond EO_CXX_EO_IMPL") << endl;
|
||||
eo_class_definitions_generator(header_impl, cls);
|
||||
eo_inheritance_detail_generator(header_impl, cls);
|
||||
header_impl << endl << comment("@endcond") << endl;
|
||||
}
|
||||
|
||||
} } } // namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
#endif // EOLIAN_CXX_STD_EO_HEADER_GENERATOR_HH
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef EOLIAN_CXX_EPS_HH
|
||||
#define EOLIAN_CXX_EPS_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct eps_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(OutputIterator, Attribute const&, Context const&) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<eps_generator> : std::true_type {};
|
||||
|
||||
eps_generator const eps;
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef EOLIAN_CXX_FUNCTION_DECLARATION_HH
|
||||
#define EOLIAN_CXX_FUNCTION_DECLARATION_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
|
||||
#include "grammar/indentation.hpp"
|
||||
#include "grammar/list.hpp"
|
||||
#include "grammar/alternative.hpp"
|
||||
#include "grammar/type.hpp"
|
||||
#include "grammar/parameter.hpp"
|
||||
#include "grammar/keyword.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct function_declaration_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const
|
||||
{
|
||||
return as_generator
|
||||
(grammar::type << " " << string << "(" << (parameter % ", ") << ") const;\n")
|
||||
.generate(sink, std::make_tuple(f.return_type, escape_keyword(f.name), f.parameters), context);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<function_declaration_generator> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed<function_declaration_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
function_declaration_generator const function_declaration;
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,155 @@
|
|||
#ifndef EOLIAN_CXX_FUNCTION_DEFINITION_HH
|
||||
#define EOLIAN_CXX_FUNCTION_DEFINITION_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
|
||||
#include "grammar/string.hpp"
|
||||
#include "grammar/indentation.hpp"
|
||||
#include "grammar/list.hpp"
|
||||
#include "grammar/alternative.hpp"
|
||||
#include "grammar/type.hpp"
|
||||
#include "grammar/parameter.hpp"
|
||||
#include "grammar/function_declaration.hpp"
|
||||
#include "grammar/converting_argument.hpp"
|
||||
#include "grammar/case.hpp"
|
||||
#include "grammar/keyword.hpp"
|
||||
#include "grammar/attribute_conditional.hpp"
|
||||
#include "grammar/attribute_reorder.hpp"
|
||||
#include "grammar/type_impl.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct function_definition_generator
|
||||
{
|
||||
function_definition_generator(attributes::klass_name const& name)
|
||||
: _klass_name(name)
|
||||
{}
|
||||
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::function_def const& f, Context const& ctx) const
|
||||
{
|
||||
std::string suffix;
|
||||
switch(_klass_name.type)
|
||||
{
|
||||
case attributes::class_type::regular:
|
||||
case attributes::class_type::abstract_:
|
||||
suffix = "CLASS";
|
||||
break;
|
||||
case attributes::class_type::mixin:
|
||||
suffix = "MIXIN";
|
||||
break;
|
||||
case attributes::class_type::interface_:
|
||||
suffix = "INTERFACE";
|
||||
break;
|
||||
}
|
||||
|
||||
if(f.is_beta &&
|
||||
!as_generator("#ifdef " << *(string << "_") << string << "_" << string << "_BETA\n")
|
||||
.generate(sink, std::make_tuple(_klass_name.namespaces, _klass_name.eolian_name, suffix), add_upper_case_context(ctx)))
|
||||
return false;
|
||||
if(f.is_protected &&
|
||||
!as_generator("#ifdef " << *(string << "_") << string << "_" << string << "_PROTECTED\n")
|
||||
.generate(sink, std::make_tuple(_klass_name.namespaces, _klass_name.eolian_name, suffix), add_upper_case_context(ctx)))
|
||||
return false;
|
||||
|
||||
if(!as_generator
|
||||
("inline " << grammar::type << " " << string << "::" << string << "(" << (parameter % ", ") << ") const\n{\n")
|
||||
.generate(sink, std::make_tuple(f.return_type, _klass_name.eolian_name, escape_keyword(f.name), f.parameters), ctx))
|
||||
return false;
|
||||
|
||||
auto out_declaration =
|
||||
attribute_conditional([] (attributes::parameter_def const& p) -> bool
|
||||
{ return p.direction == attributes::parameter_direction::out; })
|
||||
[
|
||||
attribute_reorder<1, 2>
|
||||
(scope_tab << c_type << " __out_param_" << string << " = {};\n")
|
||||
]
|
||||
| attribute_conditional([] (attributes::parameter_def const& p) -> bool
|
||||
{ return p.direction == attributes::parameter_direction::inout; })
|
||||
[
|
||||
attribute_reorder<1, 2, 1, 1, 2>
|
||||
(scope_tab << c_type << " __out_param_" << string << " = ::efl::eolian::convert_inout<" << c_type
|
||||
<< ", " << type << ">(" << string << ");\n")
|
||||
]
|
||||
| eps
|
||||
;
|
||||
if(!as_generator(*(out_declaration))
|
||||
.generate(sink, f.parameters, ctx)) return false;
|
||||
|
||||
if(!as_generator(scope_tab).generate(sink, attributes::unused, ctx)) return false;
|
||||
|
||||
if(f.return_type != attributes::void_
|
||||
&& !as_generator(attributes::c_type({attributes::parameter_direction::in, f.return_type, "", f.return_type.c_type})
|
||||
<< " __return_value = "
|
||||
).generate(sink, attributes::unused, ctx)) return false;
|
||||
|
||||
if(!as_generator
|
||||
(" ::" << string << "(this->_eo_ptr()"
|
||||
<<
|
||||
*(
|
||||
"\n" << scope_tab << scope_tab << ", "
|
||||
<<
|
||||
(
|
||||
attribute_conditional([] (attributes::parameter_def const& p)
|
||||
{ return p.direction == attributes::parameter_direction::in; })
|
||||
[converting_argument]
|
||||
| ("& __out_param_" << attribute_reorder<2>(string))
|
||||
)
|
||||
)
|
||||
<< ");\n"
|
||||
).generate(sink, std::make_tuple(f.c_name, f.parameters), ctx))
|
||||
return false;
|
||||
|
||||
auto out_assignments =
|
||||
attribute_conditional([] (attributes::parameter_def const& p) -> bool
|
||||
{ return p.direction != attributes::parameter_direction::in; })
|
||||
[
|
||||
attribute_reorder<-1, 1, 2, 2>
|
||||
(scope_tab << "::efl::eolian::assign_out<" << parameter_type << ", " << c_type
|
||||
<< ">(" << string << ", __out_param_" << string << ");\n")
|
||||
]
|
||||
| eps
|
||||
;
|
||||
if(!as_generator(*(out_assignments))
|
||||
.generate(sink, f.parameters, ctx)) return false;
|
||||
|
||||
if(f.return_type != attributes::void_
|
||||
&& !as_generator(scope_tab << "return ::efl::eolian::convert_to_return<"
|
||||
<< type<< ">(__return_value);\n"
|
||||
).generate(sink, f.return_type, ctx)) return false;
|
||||
|
||||
if(!as_generator("}\n").generate(sink, attributes::unused, ctx))
|
||||
return false;
|
||||
|
||||
if(f.is_beta &&
|
||||
!as_generator("#endif\n").generate(sink, attributes::unused, ctx))
|
||||
return false;
|
||||
if(f.is_protected &&
|
||||
!as_generator("#endif\n").generate(sink, attributes::unused, ctx))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
attributes::klass_name _klass_name;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<function_definition_generator> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed<function_definition_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
struct function_definition_terminal
|
||||
{
|
||||
function_definition_generator operator()(attributes::klass_name name) const
|
||||
{
|
||||
return function_definition_generator{name};
|
||||
}
|
||||
} const function_definition;
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef EOLIAN_CXX_GENERATOR_HH
|
||||
#define EOLIAN_CXX_GENERATOR_HH
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct is_generator : std::false_type {};
|
||||
template <typename T, typename Enable = void>
|
||||
struct is_eager_generator : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_generator<T&> : is_generator<T> {};
|
||||
template <typename T>
|
||||
struct is_eager_generator<T&> : is_eager_generator<T> {};
|
||||
template <typename T>
|
||||
struct is_generator<T const&> : is_generator<T> {};
|
||||
template <typename T>
|
||||
struct is_eager_generator<T const&> : is_eager_generator<T> {};
|
||||
template <typename T>
|
||||
struct is_generator<T const> : is_generator<T> {};
|
||||
template <typename T>
|
||||
struct is_eager_generator<T const> : is_eager_generator<T> {};
|
||||
template <typename T>
|
||||
struct is_generator<T volatile> : is_generator<T> {};
|
||||
template <typename T>
|
||||
struct is_eager_generator<T volatile> : is_eager_generator<T> {};
|
||||
template <typename T>
|
||||
struct is_generator<T volatile&> : is_generator<T> {};
|
||||
template <typename T>
|
||||
struct is_eager_generator<T volatile&> : is_eager_generator<T> {};
|
||||
template <typename T>
|
||||
struct is_generator<T volatile const> : is_generator<T> {};
|
||||
template <typename T>
|
||||
struct is_eager_generator<T volatile const> : is_eager_generator<T> {};
|
||||
template <typename T>
|
||||
struct is_generator<T volatile const&> : is_generator<T> {};
|
||||
template <typename T>
|
||||
struct is_eager_generator<T volatile const&> : is_eager_generator<T> {};
|
||||
template <typename T>
|
||||
struct is_generator<T> : is_eager_generator<T> {};
|
||||
|
||||
template <typename G, typename Enable = typename std::enable_if<is_eager_generator<G>::value>::type>
|
||||
G as_generator(G&& g) { return g; }
|
||||
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef EOLIAN_CXX_HEADER_HH
|
||||
#define EOLIAN_CXX_HEADER_HH
|
||||
|
||||
#include "header_guards.hpp"
|
||||
#include "eps.hpp"
|
||||
#include "string.hpp"
|
||||
#include "sequence.hpp"
|
||||
#include "kleene.hpp"
|
||||
#include "header_include_directive.hpp"
|
||||
#include "base_class_definition.hpp"
|
||||
#include "class_definition.hpp"
|
||||
#include "class_declaration.hpp"
|
||||
#include "implementation_include_directive.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
auto class_header =
|
||||
header_guards // class name
|
||||
[
|
||||
"#include <Eo.h>\n"
|
||||
"\nextern \"C\" {\n"
|
||||
<< *header_include_directive // sequence<string>
|
||||
<< "}\n"
|
||||
<< "#include <Eina.hh>\n"
|
||||
"#include <Eo.hh>\n"
|
||||
<< *header_include_directive // sequence<string>
|
||||
<< *class_declaration // sequence<class> | class
|
||||
<< "\nnamespace eo_cxx {\n"
|
||||
<< *base_class_definition // sequence<class> | class
|
||||
<< "}\n"
|
||||
<< *class_definition // sequence<class> | class
|
||||
<< *implementation_include_directive
|
||||
]
|
||||
;
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,79 @@
|
|||
#ifndef EOLIAN_CXX_HEADER_GUARDS_HH
|
||||
#define EOLIAN_CXX_HEADER_GUARDS_HH
|
||||
|
||||
#include <utility>
|
||||
#include <tuple>
|
||||
#include <algorithm>
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/attributes.hpp"
|
||||
#include "grammar/string.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
template <typename Generator>
|
||||
struct header_guards_generator
|
||||
{
|
||||
header_guards_generator(Generator generator)
|
||||
: generator(std::move(generator))
|
||||
{}
|
||||
|
||||
template <typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(OutputIterator sink, Attribute const& attribute, Context const& context) const
|
||||
{
|
||||
using std::get;
|
||||
auto&& v = get<0>(attribute);
|
||||
const char ifndef_directive[] = "#ifndef ";
|
||||
const char define_directive[] = "#define ";
|
||||
const char endif_directive[] = "#endif\n";
|
||||
std::copy(&ifndef_directive[0],
|
||||
&ifndef_directive[0] + sizeof(ifndef_directive)-1,
|
||||
sink);
|
||||
|
||||
std::transform(std::begin(v), std::end(v), sink, ::toupper);
|
||||
*sink++ = '\n';
|
||||
|
||||
std::copy(&define_directive[0],
|
||||
&define_directive[0] + sizeof(define_directive)-1,
|
||||
sink);
|
||||
std::transform(std::begin(v), std::end(v), sink, ::toupper);
|
||||
*sink++ = '\n';
|
||||
|
||||
bool b = as_generator(generator).generate(sink, attributes::pop_front(attribute), context);
|
||||
if(!b)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
std::copy(&endif_directive[0],
|
||||
&endif_directive[0] + sizeof(endif_directive)-1,
|
||||
sink);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Generator generator;
|
||||
};
|
||||
|
||||
template <typename G>
|
||||
struct is_eager_generator<header_guards_generator<G> > : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <typename G>
|
||||
struct attributes_needed<header_guards_generator<G> >
|
||||
: std::integral_constant<int, 1 + attributes_needed<G>::value> {};
|
||||
}
|
||||
|
||||
struct header_guards_directive
|
||||
{
|
||||
template <typename Generator>
|
||||
header_guards_generator<Generator> operator[](Generator generator) const
|
||||
{
|
||||
return header_guards_generator<Generator>(generator);
|
||||
}
|
||||
};
|
||||
|
||||
header_guards_directive const header_guards;
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef EOLIAN_CXX_HEADER_INCLUDE_DIRECTIVE_HH
|
||||
#define EOLIAN_CXX_HEADER_INCLUDE_DIRECTIVE_HH
|
||||
|
||||
#include "generator.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct header_include_directive_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(OutputIterator sink, Attribute const& attribute, Context const&) const
|
||||
{
|
||||
const char include_directive[] = "#include \"";
|
||||
std::copy(include_directive, include_directive + sizeof(include_directive)-1, sink);
|
||||
std::copy(std::begin(attribute), std::end(attribute), sink);
|
||||
*sink++ = '\"';
|
||||
*sink++ = '\n';
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<header_include_directive_generator> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed<header_include_directive_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
header_include_directive_generator const header_include_directive;
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef EOLIAN_CXX_IMPL_HEADER_HH
|
||||
#define EOLIAN_CXX_IMPL_HEADER_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
|
||||
#include "grammar/indentation.hpp"
|
||||
#include "grammar/list.hpp"
|
||||
#include "grammar/alternative.hpp"
|
||||
#include "grammar/kleene.hpp"
|
||||
#include "grammar/class_implementation.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
auto impl_header =
|
||||
*(class_implementation)
|
||||
;
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef EOLIAN_CXX_IMPLEMENTATION_INCLUDE_DIRECTIVE_HH
|
||||
#define EOLIAN_CXX_IMPLEMENTATION_INCLUDE_DIRECTIVE_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
|
||||
#include "grammar/string.hpp"
|
||||
#include "grammar/indentation.hpp"
|
||||
#include "grammar/list.hpp"
|
||||
#include "grammar/alternative.hpp"
|
||||
#include "grammar/type.hpp"
|
||||
#include "grammar/parameter.hpp"
|
||||
#include "grammar/function_declaration.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct implementation_include_directive_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::klass_def const& cls, Context const& ctx) const
|
||||
{
|
||||
return as_generator("#include \"" << string << ".impl.hh\"\n")
|
||||
.generate(sink, std::string(eolian_class_file_get(get_klass(get_klass_name(cls)))), add_lower_case_context(ctx));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<implementation_include_directive_generator> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed<implementation_include_directive_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
implementation_include_directive_generator const implementation_include_directive;
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef EOLIAN_CXX_GRAMMAR_INDENTATION_HPP
|
||||
#define EOLIAN_CXX_GRAMMAR_INDENTATION_HPP
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/attributes.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct scope_tab_generator
|
||||
{
|
||||
scope_tab_generator(int n)
|
||||
: n(n) {}
|
||||
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::unused_type, Context const&) const
|
||||
{
|
||||
for(int i = 0; i != n; ++i)
|
||||
{
|
||||
*sink++ = ' ';
|
||||
*sink++ = ' ';
|
||||
*sink++ = ' ';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int n;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<scope_tab_generator> : std::true_type {};
|
||||
|
||||
struct scope_tab_terminal
|
||||
{
|
||||
scope_tab_generator operator()(int n) const
|
||||
{
|
||||
return scope_tab_generator(n);
|
||||
}
|
||||
} const scope_tab;
|
||||
|
||||
template <>
|
||||
struct is_generator<scope_tab_terminal> : std::true_type {};
|
||||
|
||||
scope_tab_generator as_generator(scope_tab_terminal)
|
||||
{
|
||||
return scope_tab_generator(1);
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -1,339 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_STD_INHERITANCE_GENERATOR_HH
|
||||
#define EOLIAN_CXX_STD_INHERITANCE_GENERATOR_HH
|
||||
|
||||
#include <iosfwd>
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
|
||||
#include "eo_types.hh"
|
||||
#include "tab.hh"
|
||||
#include "parameters_generator.hh"
|
||||
#include "eo_class_functions_generator.hh"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
inline std::string
|
||||
_ns_as_prefix(eo_class const& cls)
|
||||
{
|
||||
// XXX Use eolian_cxx::find_replace() instead.
|
||||
std::string s = cls.name_space;
|
||||
std::string::size_type found = s.find("::");
|
||||
while (found != std::string::npos)
|
||||
{
|
||||
s.replace(found, 2, "_");
|
||||
found = s.find("::");
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
struct inheritance_operation
|
||||
{
|
||||
eo_class const& _cls;
|
||||
eo_function const& _func;
|
||||
inheritance_operation(eo_class const& cls, eo_function const& func)
|
||||
: _cls(cls), _func(func)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, inheritance_operation const& x)
|
||||
{
|
||||
eo_function const& func = x._func;
|
||||
out << scope_guard_head(x._cls, func)
|
||||
<< tab(1)
|
||||
<< "ops[i].func = reinterpret_cast<void*>(& ::"
|
||||
<< _ns_as_prefix(x._cls) << "_"
|
||||
<< x._cls.name << "_" << func.name << "_wrapper<T>);" << endl
|
||||
<< tab(1) << "ops[i].api_func = reinterpret_cast<void*>(& ::"
|
||||
<< func.impl << ");" << endl
|
||||
<< tab(1) << "ops[i].op_type = EO_OP_TYPE_REGULAR;" << endl // XXX class ops
|
||||
<< tab(1) << "++i;" << endl
|
||||
<< scope_guard_tail(x._cls, func)
|
||||
<< endl;
|
||||
return out;
|
||||
}
|
||||
|
||||
struct inheritance_operations_description
|
||||
{
|
||||
eo_class const& _cls;
|
||||
inheritance_operations_description(eo_class const& cls)
|
||||
: _cls(cls)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, inheritance_operations_description const& x)
|
||||
{
|
||||
std::string s;
|
||||
|
||||
out << "template <typename T>"
|
||||
<< endl << "int initialize_operation_description(::efl::eo::detail::tag<"
|
||||
<< full_name(x._cls) << ">" << endl
|
||||
<< tab(11)
|
||||
<< ", Eo_Op_Description* ops)" << endl
|
||||
<< "{" << endl
|
||||
<< tab(1) << "int i = 0;" << endl
|
||||
<< tab(1) << "(void)i;" << endl
|
||||
<< tab(1) << "(void)ops;" << endl;
|
||||
|
||||
for (auto const& f : x._cls.functions)
|
||||
{
|
||||
out << inheritance_operation(x._cls, f);
|
||||
}
|
||||
|
||||
for (std::string const& parent : x._cls.parents)
|
||||
{
|
||||
out << tab(1)
|
||||
<< "initialize_operation_description<T>(::efl::eo::detail::tag<::"
|
||||
<< parent << ">(), &ops[operation_description_class_size< "
|
||||
<< full_name(x._cls) << " >::value" << s << "]);" << endl;
|
||||
|
||||
s += " + operation_description_class_size<::" + parent + ">::value";
|
||||
}
|
||||
|
||||
out << tab(1) << "return 0;" << endl
|
||||
<< "}" << endl;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
struct inheritance_wrappers
|
||||
{
|
||||
eo_class const& _cls;
|
||||
inheritance_wrappers(eo_class const& cls) : _cls(cls) {}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, inheritance_wrappers const& x)
|
||||
{
|
||||
functions_container_type::const_iterator it,
|
||||
first = x._cls.functions.begin(),
|
||||
last = x._cls.functions.end();
|
||||
for (it = first; it != last; ++it)
|
||||
{
|
||||
eo_function const& func = *it;
|
||||
|
||||
out << scope_guard_head(x._cls, func);
|
||||
|
||||
out << "template <typename T>" << endl
|
||||
<< reinterpret_type(func.ret) << " "
|
||||
<< _ns_as_prefix(x._cls) << "_"
|
||||
<< x._cls.name << "_" << func.name
|
||||
<< "_wrapper(Eo* objid EINA_UNUSED, "
|
||||
<< "::efl::eo::detail::Inherit_Private_Data* self"
|
||||
<< (func.params.size() ? ", " : "")
|
||||
<< parameters_c_declaration(func.params)
|
||||
<< ")" << endl
|
||||
<< "{" << endl;
|
||||
|
||||
out << tab(1)
|
||||
<< "try" << endl
|
||||
<< tab(2) << "{" << endl
|
||||
<< tab(3)
|
||||
<< (!function_is_void(func) ? "return ": "")
|
||||
<< "static_cast<T*>(self->this_)->"
|
||||
<< func.name << "(" << parameters_cxx_list(func.params) << ");" << endl
|
||||
<< tab(2) << "}" << endl
|
||||
<< tab(1) << "catch (...)" << endl
|
||||
<< tab(2) << "{" << endl
|
||||
<< tab(3) << "eina_error_set( ::efl::eina::unknown_error() );" << endl;
|
||||
|
||||
if (!function_is_void(func))
|
||||
out << tab(3) << func.ret.front().native << " _tmp_ret{};" << endl
|
||||
<< tab(3) << "return " << to_cxx(func.ret, "_tmp_ret") << ";" << endl;
|
||||
|
||||
out << tab(2) << "}" << endl
|
||||
<< "}" << endl;
|
||||
|
||||
out << scope_guard_tail(x._cls, func) << endl;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct inheritance_base_operations_size
|
||||
{
|
||||
eo_class const& _cls;
|
||||
inheritance_base_operations_size(eo_class const& cls)
|
||||
: _cls(cls)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, inheritance_base_operations_size const& x)
|
||||
{
|
||||
int pcted = 0;
|
||||
int beta = 0;
|
||||
int pcted_beta = 0;
|
||||
|
||||
auto funcs = x._cls.functions;
|
||||
|
||||
for (auto const& f : funcs)
|
||||
{
|
||||
if (f.is_beta && f.scope != eolian_scope::public_)
|
||||
++pcted_beta;
|
||||
if (f.scope != eolian_scope::public_)
|
||||
++pcted;
|
||||
if (f.is_beta)
|
||||
++beta;
|
||||
}
|
||||
auto all = funcs.size();
|
||||
|
||||
out << "template<>"
|
||||
<< endl << "struct operation_description_class_size< "
|
||||
<< full_name(x._cls) << " >" << endl
|
||||
<< "{" << endl
|
||||
<< tab(1) << "static constexpr int value = " << endl
|
||||
<< "#if defined(" << name_upper(x._cls) << "_PROTECTED)"
|
||||
<< " && defined(" << name_upper(x._cls) << "_BETA)" << endl
|
||||
<< tab(2) << all << endl
|
||||
<< "#elif defined(" << name_upper(x._cls) << "_PROTECTED)" << endl
|
||||
<< tab(2) << (all - beta) << endl
|
||||
<< "#elif defined(" << name_upper(x._cls) << "_BETA)" << endl
|
||||
<< tab(2) << (all - pcted) << endl
|
||||
<< "#else" << endl
|
||||
<< tab(2) << (all + pcted_beta - beta - pcted) << endl
|
||||
<< "#endif" << endl;
|
||||
|
||||
for (std::string const& parent : x._cls.parents)
|
||||
{
|
||||
out << tab(2) << "+ operation_description_class_size<::" << parent << " >::value";
|
||||
}
|
||||
|
||||
out << ";" << endl
|
||||
<< "};" << endl
|
||||
<< endl;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
struct inheritance_base_operations_extensions
|
||||
{
|
||||
eo_class const& _cls;
|
||||
inheritance_base_operations_extensions(eo_class const& cls)
|
||||
: _cls(cls)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, inheritance_base_operations_extensions const& x)
|
||||
{
|
||||
eo_class const& cls = x._cls;
|
||||
ancestors_container_type::const_iterator it, first = cls.parents.begin();
|
||||
ancestors_container_type::const_iterator last = cls.parents.end();
|
||||
|
||||
for (it = first; it != last; ++it)
|
||||
{
|
||||
out << endl
|
||||
<< tab(3) << (it == first ? ": " : ", ")
|
||||
<< "virtual operations< ::" << *it
|
||||
<< " >::template type<T>";
|
||||
}
|
||||
|
||||
return out << endl;
|
||||
}
|
||||
|
||||
struct inheritance_base_operations_function
|
||||
{
|
||||
eo_class const& _cls;
|
||||
eo_function const& _func;
|
||||
inheritance_base_operations_function(eo_class const& cls, eo_function const& func)
|
||||
: _cls(cls) , _func(func)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, inheritance_base_operations_function const& x)
|
||||
{
|
||||
eo_function const& func = x._func;
|
||||
bool is_void = function_is_void(func);
|
||||
|
||||
if (parameters_count_callbacks(func.params))
|
||||
out << template_parameters_declaration(func.params, 2) << tab(2);
|
||||
else
|
||||
out << tab(2) << "virtual ";
|
||||
|
||||
out << reinterpret_type(func.ret) << " "
|
||||
<< func.name << "("
|
||||
<< parameters_declaration(func.params) << ")" << endl
|
||||
<< tab(2) << "{" << endl;
|
||||
|
||||
if (!is_void)
|
||||
out << tab(3) << func.ret.front().native << " _tmp_ret = {};" << endl;
|
||||
|
||||
out << callbacks_heap_alloc("dynamic_cast<T*>(this)->_eo_ptr()", func.params, function_is_static(x._func), 3)
|
||||
<< endl;
|
||||
|
||||
out << tab(3) << parameterized_obj_function_call(func, "eo_super(dynamic_cast<T*>(this)->_eo_ptr(), dynamic_cast<T*>(this)->_eo_class())") << ";" << endl;
|
||||
|
||||
if (!is_void)
|
||||
out << tab(4) << "return " << to_cxx(func.ret, "_tmp_ret") << ";" << endl;
|
||||
|
||||
return out << tab(2) << "}" << endl;
|
||||
}
|
||||
|
||||
struct inheritance_base_operations
|
||||
{
|
||||
eo_class const& _cls;
|
||||
inheritance_base_operations(eo_class const& cls) : _cls(cls) {}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, inheritance_base_operations const& x)
|
||||
{
|
||||
out << "template<>" << endl
|
||||
<< "struct operations< "
|
||||
<< full_name(x._cls) << " >" << endl
|
||||
<< "{" << endl
|
||||
<< tab(1) << "template <typename T>" << endl
|
||||
<< tab(1) << "struct type" << inheritance_base_operations_extensions(x._cls)
|
||||
<< tab(1) << "{" << endl;
|
||||
functions_container_type::const_iterator it,
|
||||
first = x._cls.functions.begin(),
|
||||
last = x._cls.functions.end();
|
||||
for (it = first; it != last; ++it)
|
||||
{
|
||||
out << scope_guard_head(x._cls, *it);
|
||||
out << inheritance_base_operations_function(x._cls, *it);
|
||||
out << scope_guard_tail(x._cls, *it) << endl;
|
||||
}
|
||||
out << tab(1) << "};" << endl
|
||||
<< "};" << endl << endl;
|
||||
return out;
|
||||
}
|
||||
|
||||
struct inheritance_eo_class_getter
|
||||
{
|
||||
eo_class const& _cls;
|
||||
inheritance_eo_class_getter(eo_class const& cls)
|
||||
: _cls(cls)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, inheritance_eo_class_getter const& x)
|
||||
{
|
||||
out << "inline Eo_Class const* get_eo_class(tag<"
|
||||
<< full_name(x._cls) << ">)" << endl
|
||||
<< "{" << endl
|
||||
<< tab(1) << "return (" << x._cls.eo_name << ");" << endl
|
||||
<< "}" << endl << endl;
|
||||
return out;
|
||||
}
|
||||
|
||||
inline void
|
||||
eo_inheritance_detail_generator(std::ostream& out, eo_class const& cls)
|
||||
{
|
||||
if(cls.eo_name != "EO_BASE_CLASS")
|
||||
out << inheritance_wrappers(cls)
|
||||
<< "namespace efl { namespace eo { namespace detail {" << endl << endl
|
||||
<< inheritance_base_operations(cls) << endl
|
||||
<< inheritance_base_operations_size(cls)
|
||||
<< inheritance_operations_description(cls)
|
||||
<< inheritance_eo_class_getter(cls)
|
||||
<< "} } }" << endl;
|
||||
}
|
||||
|
||||
} } } // namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
#endif // EOLIAN_CXX_STD_INHERITANCE_GENERATOR_HH
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef EOLIAN_CXX_KEYWORD_HH
|
||||
#define EOLIAN_CXX_KEYWORD_HH
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
inline std::string escape_keyword(std::string const& name)
|
||||
{
|
||||
if(name == "delete" || name == "register")
|
||||
return "cxx_" + name;
|
||||
return name;
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,704 @@
|
|||
#ifndef EOLIAN_CXX_KLASS_DEF_HH
|
||||
#define EOLIAN_CXX_KLASS_DEF_HH
|
||||
|
||||
#include "grammar/type_traits.hpp"
|
||||
#include "grammar/variant.hpp"
|
||||
#include "grammar/attributes.hpp"
|
||||
#include "grammar/qualifier_def.hpp"
|
||||
#include "grammar/string.hpp"
|
||||
#include "grammar/sequence.hpp"
|
||||
#include "grammar/kleene.hpp"
|
||||
#include "grammar/case.hpp"
|
||||
|
||||
#include <Eolian.h>
|
||||
|
||||
#include <Eina.hh>
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar { namespace attributes {
|
||||
|
||||
template <typename...Args, std::size_t I>
|
||||
bool lexicographical_compare_impl(std::tuple<Args...> const&
|
||||
, std::tuple<Args...> const&
|
||||
, std::integral_constant<std::size_t, I>
|
||||
, std::true_type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
template <typename...Args, std::size_t I>
|
||||
bool lexicographical_compare_impl(std::tuple<Args...> const& lhs
|
||||
, std::tuple<Args...> const& rhs
|
||||
, std::integral_constant<std::size_t, I>
|
||||
, std::false_type)
|
||||
{
|
||||
return std::get<I>(lhs) < std::get<I>(rhs)
|
||||
|| (!(std::get<I>(rhs) < std::get<I>(lhs))
|
||||
&& lexicographical_compare_impl(lhs, rhs, std::integral_constant<std::size_t, I+1>()
|
||||
, std::integral_constant<bool, I + 1 == sizeof...(Args)>())
|
||||
)
|
||||
;
|
||||
}
|
||||
template <typename...Args>
|
||||
bool lexicographical_compare(std::tuple<Args...> const& lhs
|
||||
, std::tuple<Args...> const& rhs)
|
||||
{
|
||||
return lexicographical_compare_impl(lhs, rhs, std::integral_constant<std::size_t, 0ul>(), std::false_type());
|
||||
}
|
||||
template <typename T, typename U>
|
||||
bool lexicographical_compare(std::tuple<T, U> const& lhs
|
||||
, std::tuple<T, U> const& rhs)
|
||||
{
|
||||
return std::get<0>(lhs) < std::get<0>(rhs)
|
||||
|| (!(std::get<0>(rhs) < std::get<0>(lhs))
|
||||
&& std::get<1>(lhs) < std::get<1>(rhs));
|
||||
}
|
||||
|
||||
struct pointer_indirection
|
||||
{
|
||||
qualifier_def qualifier;
|
||||
bool reference;
|
||||
};
|
||||
inline bool operator<(pointer_indirection const& lhs, pointer_indirection const& rhs)
|
||||
{
|
||||
return lexicographical_compare(std::make_tuple(lhs.qualifier, lhs.reference)
|
||||
, std::make_tuple(rhs.qualifier, rhs.reference));
|
||||
}
|
||||
inline bool operator==(pointer_indirection const& lhs, pointer_indirection const& rhs)
|
||||
{
|
||||
return lhs.qualifier == rhs.qualifier && lhs.reference == rhs.reference;
|
||||
}
|
||||
inline bool operator!=(pointer_indirection const& lhs, pointer_indirection const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
struct type_def;
|
||||
bool operator==(type_def const& rhs, type_def const& lhs);
|
||||
bool operator!=(type_def const& rhs, type_def const& lhs);
|
||||
|
||||
enum class class_type
|
||||
{
|
||||
regular, abstract_, mixin, interface_
|
||||
};
|
||||
|
||||
struct klass_name
|
||||
{
|
||||
std::vector<std::string> namespaces;
|
||||
std::string eolian_name;
|
||||
qualifier_def base_qualifier;
|
||||
std::vector<pointer_indirection> pointers;
|
||||
class_type type;
|
||||
|
||||
klass_name(std::vector<std::string> namespaces
|
||||
, std::string eolian_name, qualifier_def base_qualifier
|
||||
, std::vector<pointer_indirection> pointers
|
||||
, class_type type)
|
||||
: namespaces(namespaces), eolian_name(eolian_name), base_qualifier(base_qualifier)
|
||||
, pointers(pointers), type(type) {}
|
||||
klass_name(Eolian_Class const* klass, qualifier_def base_qualifier
|
||||
, std::vector<pointer_indirection> pointers)
|
||||
: eolian_name( ::eolian_class_name_get(klass))
|
||||
, base_qualifier(base_qualifier), pointers(pointers)
|
||||
{
|
||||
for(efl::eina::iterator<const char> namespace_iterator ( ::eolian_class_namespaces_get(klass))
|
||||
, namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
|
||||
{
|
||||
namespaces.push_back(&*namespace_iterator);
|
||||
}
|
||||
switch(eolian_class_type_get(klass))
|
||||
{
|
||||
case EOLIAN_CLASS_REGULAR:
|
||||
type = class_type::regular;
|
||||
break;
|
||||
case EOLIAN_CLASS_ABSTRACT:
|
||||
type = class_type::abstract_;
|
||||
break;
|
||||
case EOLIAN_CLASS_MIXIN:
|
||||
type = class_type::mixin;
|
||||
break;
|
||||
case EOLIAN_CLASS_INTERFACE:
|
||||
type = class_type::interface_;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Class with unknown type");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline bool operator==(klass_name const& lhs, klass_name const& rhs)
|
||||
{
|
||||
return lhs.namespaces == rhs.namespaces && lhs.eolian_name == rhs.eolian_name
|
||||
&& lhs.base_qualifier == rhs.base_qualifier && lhs.pointers == rhs.pointers;
|
||||
}
|
||||
inline bool operator!=(klass_name const& lhs, klass_name const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
inline bool operator<(klass_name const& lhs, klass_name const& rhs)
|
||||
{
|
||||
typedef std::tuple<std::vector<std::string>const&
|
||||
, std::string const&
|
||||
, qualifier_def const&
|
||||
, std::vector<pointer_indirection> const&
|
||||
, class_type
|
||||
> tuple_type;
|
||||
return lexicographical_compare(tuple_type(lhs.namespaces, lhs.eolian_name
|
||||
, lhs.base_qualifier, lhs.pointers
|
||||
, lhs.type)
|
||||
, tuple_type(rhs.namespaces, rhs.eolian_name
|
||||
, rhs.base_qualifier, rhs.pointers
|
||||
, rhs.type));
|
||||
}
|
||||
|
||||
template <>
|
||||
struct tuple_element<0ul, klass_name>
|
||||
{
|
||||
typedef std::vector<std::string> type;
|
||||
static type& get(klass_name& klass) { return klass.namespaces; }
|
||||
static type const& get(klass_name const& klass) { return klass.namespaces; }
|
||||
};
|
||||
template <>
|
||||
struct tuple_element<1ul, klass_name>
|
||||
{
|
||||
typedef std::string type;
|
||||
static type& get(klass_name& klass) { return klass.eolian_name; }
|
||||
static type const& get(klass_name const& klass) { return klass.eolian_name; }
|
||||
};
|
||||
template <int N>
|
||||
struct tuple_element<N, klass_name const> : tuple_element<N, klass_name> {};
|
||||
|
||||
template <int N>
|
||||
typename tuple_element<N, klass_name>::type&
|
||||
get(klass_name& klass)
|
||||
{
|
||||
return tuple_element<N, klass_name>::get(klass);
|
||||
}
|
||||
template <int N>
|
||||
typename tuple_element<N, klass_name>::type const&
|
||||
get(klass_name const& klass)
|
||||
{
|
||||
return tuple_element<N, klass_name>::get(klass);
|
||||
}
|
||||
|
||||
struct regular_type_def
|
||||
{
|
||||
std::string base_type;
|
||||
qualifier_def base_qualifier;
|
||||
std::vector<pointer_indirection> pointers;
|
||||
std::vector<std::string> namespaces;
|
||||
};
|
||||
|
||||
inline bool operator==(regular_type_def const& rhs, regular_type_def const& lhs)
|
||||
{
|
||||
return rhs.base_type == lhs.base_type && rhs.base_qualifier == lhs.base_qualifier
|
||||
&& rhs.pointers == lhs.pointers;
|
||||
}
|
||||
inline bool operator!=(regular_type_def const& rhs, regular_type_def const& lhs)
|
||||
{
|
||||
return !(rhs == lhs);
|
||||
}
|
||||
|
||||
struct complex_type_def
|
||||
{
|
||||
regular_type_def outer;
|
||||
std::vector<type_def> subtypes;
|
||||
};
|
||||
|
||||
inline bool operator==(complex_type_def const& lhs, complex_type_def const& rhs)
|
||||
{
|
||||
return lhs.outer == rhs.outer && lhs.subtypes == rhs.subtypes;
|
||||
}
|
||||
inline bool operator!=(complex_type_def const& lhs, complex_type_def const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
struct type_def
|
||||
{
|
||||
typedef attributes::variant<klass_name, regular_type_def, complex_type_def> variant_type;
|
||||
variant_type original_type;
|
||||
std::string c_type;
|
||||
|
||||
type_def() {}
|
||||
type_def(variant_type original_type, std::string c_type)
|
||||
: original_type(original_type), c_type(c_type) {}
|
||||
|
||||
type_def(Eolian_Type const* eolian_type)
|
||||
{
|
||||
set(eolian_type);
|
||||
}
|
||||
struct set_pointer_visitor
|
||||
{
|
||||
typedef void result_type;
|
||||
std::vector<pointer_indirection> pointers;
|
||||
template <typename T>
|
||||
void operator()(T& v) const
|
||||
{
|
||||
v.pointers = pointers;
|
||||
}
|
||||
void operator()(complex_type_def& complex) const
|
||||
{
|
||||
(*this)(complex.outer);
|
||||
}
|
||||
};
|
||||
void set(Eolian_Type const* eolian_type);
|
||||
};
|
||||
|
||||
inline bool operator==(type_def const& lhs, type_def const& rhs)
|
||||
{
|
||||
return lhs.original_type == rhs.original_type && lhs.c_type == rhs.c_type;
|
||||
}
|
||||
inline bool operator!=(type_def const& lhs, type_def const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
type_def const void_ {attributes::regular_type_def{"void", {qualifier_info::is_none, {}}, {}}, "void"};
|
||||
|
||||
inline void type_def::set(Eolian_Type const* eolian_type)
|
||||
{
|
||||
c_type = ::eolian_type_c_type_get(eolian_type);
|
||||
// ::eina_stringshare_del(stringshare); // this crashes
|
||||
switch( ::eolian_type_type_get(eolian_type))
|
||||
{
|
||||
case EOLIAN_TYPE_VOID:
|
||||
original_type = attributes::regular_type_def{"void", {qualifiers(eolian_type), {}}, {}};
|
||||
break;
|
||||
case EOLIAN_TYPE_REGULAR:
|
||||
{
|
||||
std::vector<std::string> namespaces;
|
||||
for(efl::eina::iterator<const char> namespace_iterator( ::eolian_type_namespaces_get(eolian_type))
|
||||
, namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
|
||||
namespaces.push_back(&*namespace_iterator);
|
||||
original_type = {regular_type_def{ ::eolian_type_name_get(eolian_type), {qualifiers(eolian_type), {}}, {}, namespaces}};
|
||||
}
|
||||
break;
|
||||
case EOLIAN_TYPE_POINTER:
|
||||
{
|
||||
std::vector<pointer_indirection> pointers
|
||||
{{ {qualifiers(eolian_type)}, false }};
|
||||
Eolian_Type const* base_type = eolian_type_base_type_get(eolian_type);
|
||||
while(eolian_type_type_get(base_type) == EOLIAN_TYPE_POINTER)
|
||||
{
|
||||
pointers.push_back({qualifiers(base_type)});
|
||||
base_type = eolian_type_base_type_get(base_type);
|
||||
}
|
||||
|
||||
set(base_type);
|
||||
original_type.visit(set_pointer_visitor{pointers});
|
||||
c_type = ::eolian_type_c_type_get(eolian_type);
|
||||
break;
|
||||
}
|
||||
case EOLIAN_TYPE_CLASS:
|
||||
{
|
||||
Eolian_Class const* klass = eolian_type_class_get(eolian_type);
|
||||
original_type = klass_name(klass, {qualifiers(eolian_type)}, {});
|
||||
}
|
||||
break;
|
||||
case EOLIAN_TYPE_COMPLEX:
|
||||
{
|
||||
complex_type_def complex
|
||||
{{::eolian_type_name_get(eolian_type), {qualifiers(eolian_type), {}}, {}}, {}};
|
||||
for(efl::eina::iterator<Eolian_Type const> type_iterator( ::eolian_type_subtypes_get(eolian_type))
|
||||
, type_last; type_iterator != type_last; ++type_iterator)
|
||||
{
|
||||
Eolian_Type const* type = &*type_iterator;
|
||||
complex.subtypes.push_back({type});
|
||||
}
|
||||
original_type = complex;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
std::abort();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
enum class parameter_direction
|
||||
{
|
||||
in, inout, out
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
struct add_optional_qualifier_visitor
|
||||
{
|
||||
typedef void result_type;
|
||||
template <typename T>
|
||||
void operator()(T& object) const
|
||||
{
|
||||
add_optional(object.base_qualifier);
|
||||
}
|
||||
void operator()(complex_type_def& complex) const
|
||||
{
|
||||
(*this)(complex.outer);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
struct parameter_def
|
||||
{
|
||||
parameter_direction direction;
|
||||
type_def type;
|
||||
std::string param_name;
|
||||
std::string c_type;
|
||||
|
||||
parameter_def(parameter_direction direction, type_def type, std::string param_name, std::string c_type)
|
||||
: direction(direction), type(type), param_name(param_name), c_type(c_type) {}
|
||||
parameter_def(Eolian_Function_Parameter const* param)
|
||||
: type( ::eolian_parameter_type_get(param))
|
||||
, param_name( ::eolian_parameter_name_get(param))
|
||||
, c_type( ::eolian_type_c_type_get(::eolian_parameter_type_get(param)))
|
||||
{
|
||||
Eolian_Parameter_Dir direction = ::eolian_parameter_direction_get(param);
|
||||
switch(direction)
|
||||
{
|
||||
case EOLIAN_IN_PARAM:
|
||||
this->direction = parameter_direction::in;
|
||||
break;
|
||||
case EOLIAN_INOUT_PARAM:
|
||||
this->direction = parameter_direction::inout;
|
||||
break;
|
||||
case EOLIAN_OUT_PARAM:
|
||||
this->direction = parameter_direction::out;
|
||||
break;
|
||||
}
|
||||
if( ::eolian_parameter_is_optional(param))
|
||||
type.original_type.visit(detail::add_optional_qualifier_visitor{});
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct tuple_element<0ul, parameter_def>
|
||||
{
|
||||
typedef parameter_direction type;
|
||||
static type const& get(parameter_def const& p) { return p.direction; }
|
||||
static type& get(parameter_def& p) { return p.direction; }
|
||||
};
|
||||
template <>
|
||||
struct tuple_element<1ul, parameter_def>
|
||||
{
|
||||
typedef type_def type;
|
||||
static type const& get(parameter_def const& p) { return p.type; }
|
||||
static type& get(parameter_def& p) { return p.type; }
|
||||
};
|
||||
template <>
|
||||
struct tuple_element<2ul, parameter_def>
|
||||
{
|
||||
typedef std::string type;
|
||||
static type const& get(parameter_def const& p) { return p.param_name; }
|
||||
static type& get(parameter_def& p) { return p.param_name; }
|
||||
};
|
||||
template <>
|
||||
struct tuple_element<3ul, parameter_def>
|
||||
{
|
||||
typedef std::string type;
|
||||
static type const& get(parameter_def const& p) { return p.c_type; }
|
||||
static type& get(parameter_def& p) { return p.c_type; }
|
||||
};
|
||||
template <int I>
|
||||
typename tuple_element<I, parameter_def>::type const& get(parameter_def const& p)
|
||||
{ return tuple_element<I, parameter_def>::get(p); }
|
||||
template <int I>
|
||||
typename tuple_element<I, parameter_def>::type& get(parameter_def& p)
|
||||
{ return tuple_element<I, parameter_def>::get(p); }
|
||||
|
||||
struct function_def
|
||||
{
|
||||
type_def return_type;
|
||||
std::string name;
|
||||
std::vector<parameter_def> parameters;
|
||||
std::string c_name;
|
||||
bool is_beta;
|
||||
bool is_protected;
|
||||
|
||||
function_def(type_def return_type, std::string name, std::vector<parameter_def> parameters
|
||||
, std::string c_name, bool is_beta)
|
||||
: return_type(return_type), name(name), parameters(parameters), c_name(c_name), is_beta(is_beta) {}
|
||||
function_def() = default;
|
||||
function_def( ::Eolian_Function const* function, Eolian_Function_Type type)
|
||||
: return_type(void_)
|
||||
{
|
||||
Eolian_Type const* r_type = ::eolian_function_return_type_get(function, type);
|
||||
name = ::eolian_function_name_get(function);
|
||||
if(r_type)
|
||||
return_type.set(r_type);
|
||||
if(type == EOLIAN_METHOD)
|
||||
{
|
||||
for(efl::eina::iterator<Eolian_Function_Parameter> param_iterator ( ::eolian_function_parameters_get(function))
|
||||
, param_last; param_iterator != param_last; ++param_iterator)
|
||||
{
|
||||
parameters.push_back(&*param_iterator);
|
||||
}
|
||||
}
|
||||
else if(type == EOLIAN_PROP_GET || type == EOLIAN_PROP_SET)
|
||||
{
|
||||
if(type == EOLIAN_PROP_GET)
|
||||
name += "_get";
|
||||
else
|
||||
name += "_set";
|
||||
for(efl::eina::iterator<Eolian_Function_Parameter> param_iterator
|
||||
( ::eolian_property_keys_get(function, type))
|
||||
, param_last; param_iterator != param_last; ++param_iterator)
|
||||
{
|
||||
parameters.push_back(&*param_iterator);
|
||||
}
|
||||
std::vector<parameter_def> values;
|
||||
for(efl::eina::iterator<Eolian_Function_Parameter> param_iterator
|
||||
( ::eolian_property_values_get(function, type))
|
||||
, param_last; param_iterator != param_last; ++param_iterator)
|
||||
{
|
||||
values.push_back(&*param_iterator);
|
||||
}
|
||||
|
||||
if(type == EOLIAN_PROP_GET && values.size() == 1 && return_type == void_)
|
||||
{
|
||||
return_type = values[0].type;
|
||||
}
|
||||
else if(type == EOLIAN_PROP_GET)
|
||||
{
|
||||
for(auto&& v : values)
|
||||
{
|
||||
v.direction = parameter_direction::out;
|
||||
parameters.push_back(v);
|
||||
}
|
||||
}
|
||||
else
|
||||
parameters.insert(parameters.end(), values.begin(), values.end());
|
||||
}
|
||||
c_name = eolian_function_full_c_name_get(function, type, EINA_FALSE);
|
||||
is_beta = eolian_function_is_beta(function);
|
||||
is_protected = eolian_function_scope_get(function) == EOLIAN_SCOPE_PROTECTED;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct tuple_element<0ul, function_def>
|
||||
{
|
||||
typedef type_def type;
|
||||
static type& get(function_def& f) { return f.return_type; }
|
||||
static type const& get(function_def const& f) { return f.return_type; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct tuple_element<1ul, function_def>
|
||||
{
|
||||
typedef std::string type;
|
||||
static type& get(function_def& f) { return f.name; }
|
||||
static type const& get(function_def const& f) { return f.name; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct tuple_element<2ul, function_def>
|
||||
{
|
||||
typedef std::vector<parameter_def> type;
|
||||
static type& get(function_def& f) { return f.parameters; }
|
||||
static type const& get(function_def const& f) { return f.parameters; }
|
||||
};
|
||||
|
||||
// template <int N>
|
||||
// struct tuple_element<N, function_def const> : tuple_element<N, function_def> {};
|
||||
// template <int N>
|
||||
// struct tuple_element<N, function_def&> : tuple_element<N, function_def> {};
|
||||
// template <int N>
|
||||
// struct tuple_element<N, function_def const&> : tuple_element<N, function_def> {};
|
||||
|
||||
// template <std::size_t I>
|
||||
// typename tuple_element<I, function_def>::type const&
|
||||
// get(function_def const& f)
|
||||
// {
|
||||
// return tuple_element<I, function_def>::get(f);
|
||||
// }
|
||||
|
||||
// template <std::size_t I>
|
||||
// typename tuple_element<I, function_def>::type&
|
||||
// get(function_def& f)
|
||||
// {
|
||||
// return tuple_element<I, function_def>::get(f);
|
||||
// }
|
||||
|
||||
struct compare_klass_name_by_name
|
||||
{
|
||||
bool operator()(klass_name const& lhs, klass_name const& rhs) const
|
||||
{
|
||||
return lhs.namespaces < rhs.namespaces
|
||||
|| (!(rhs.namespaces < lhs.namespaces) && lhs.eolian_name < rhs.eolian_name);
|
||||
}
|
||||
};
|
||||
|
||||
struct event_def
|
||||
{
|
||||
eina::optional<type_def> type;
|
||||
std::string name, c_name;
|
||||
|
||||
event_def(type_def type, std::string name, std::string c_name)
|
||||
: type(type), name(name), c_name(c_name) {}
|
||||
event_def(Eolian_Event const* event)
|
||||
: type( ::eolian_event_type_get(event) ? ::eolian_event_type_get(event) : eina::optional<type_def>{})
|
||||
, name( ::eolian_event_name_get(event))
|
||||
, c_name( ::eolian_event_c_name_get(event)) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct tuple_element<0, event_def>
|
||||
{
|
||||
typedef eina::optional<type_def> type;
|
||||
static type& get(event_def& def) { return def.type; }
|
||||
static type const& get(event_def const& def) { return def.type; }
|
||||
};
|
||||
template <>
|
||||
struct tuple_element<1, event_def>
|
||||
{
|
||||
typedef std::string type;
|
||||
static type& get(event_def& def) { return def.name; }
|
||||
static type const& get(event_def const& def) { return def.name; }
|
||||
};
|
||||
template <>
|
||||
struct tuple_element<2, event_def>
|
||||
{
|
||||
typedef std::string type;
|
||||
static type& get(event_def& def) { return def.c_name; }
|
||||
static type const& get(event_def const& def) { return def.c_name; }
|
||||
};
|
||||
template <int N>
|
||||
struct tuple_element<N, event_def const> : tuple_element<N, event_def> {};
|
||||
template <int N>
|
||||
auto get(event_def const& def) -> decltype(tuple_element<N, event_def>::get(def))
|
||||
{
|
||||
return tuple_element<N, event_def>::get(def);
|
||||
}
|
||||
template <int N>
|
||||
auto get(event_def& def) -> decltype(tuple_element<N, event_def>::get(def))
|
||||
{
|
||||
return tuple_element<N, event_def>::get(def);
|
||||
}
|
||||
|
||||
struct klass_def
|
||||
{
|
||||
std::string eolian_name;
|
||||
std::string cxx_name;
|
||||
std::vector<std::string> namespaces;
|
||||
std::vector<function_def> functions;
|
||||
std::set<klass_name, compare_klass_name_by_name> inherits;
|
||||
class_type type;
|
||||
std::vector<event_def> events;
|
||||
|
||||
klass_def(std::string eolian_name, std::string cxx_name
|
||||
, std::vector<std::string> namespaces
|
||||
, std::vector<function_def> functions
|
||||
, std::set<klass_name, compare_klass_name_by_name> inherits
|
||||
, class_type type)
|
||||
: eolian_name(eolian_name), cxx_name(cxx_name)
|
||||
, namespaces(namespaces)
|
||||
, functions(functions), inherits(inherits), type(type)
|
||||
{}
|
||||
klass_def(Eolian_Class const* klass)
|
||||
{
|
||||
for(efl::eina::iterator<const char> namespace_iterator( ::eolian_class_namespaces_get(klass))
|
||||
, namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
|
||||
{
|
||||
this->namespaces.push_back(&*namespace_iterator);
|
||||
}
|
||||
cxx_name = eolian_name = eolian_class_name_get(klass);
|
||||
for(efl::eina::iterator<Eolian_Function const> eolian_functions ( ::eolian_class_functions_get(klass, EOLIAN_PROPERTY))
|
||||
, functions_last; eolian_functions != functions_last; ++eolian_functions)
|
||||
{
|
||||
Eolian_Function const* function = &*eolian_functions;
|
||||
Eolian_Function_Type type = ::eolian_function_type_get(function);
|
||||
if(type == EOLIAN_PROPERTY)
|
||||
{
|
||||
if(! ::eolian_function_is_legacy_only(function, EOLIAN_PROP_GET)
|
||||
&& ::eolian_function_scope_get(function) != EOLIAN_SCOPE_PRIVATE)
|
||||
functions.push_back({function, EOLIAN_PROP_GET});
|
||||
if(! ::eolian_function_is_legacy_only(function, EOLIAN_PROP_SET)
|
||||
&& ::eolian_function_scope_get(function) != EOLIAN_SCOPE_PRIVATE)
|
||||
functions.push_back({function, EOLIAN_PROP_SET});
|
||||
}
|
||||
else
|
||||
if(! ::eolian_function_is_legacy_only(function, type)
|
||||
&& ::eolian_function_scope_get(function) != EOLIAN_SCOPE_PRIVATE)
|
||||
functions.push_back({function, type});
|
||||
}
|
||||
for(efl::eina::iterator<Eolian_Function const> eolian_functions ( ::eolian_class_functions_get(klass, EOLIAN_METHOD))
|
||||
, functions_last; eolian_functions != functions_last; ++eolian_functions)
|
||||
{
|
||||
Eolian_Function const* function = &*eolian_functions;
|
||||
if(! ::eolian_function_is_legacy_only(function, EOLIAN_METHOD)
|
||||
&& ::eolian_function_scope_get(function) != EOLIAN_SCOPE_PRIVATE)
|
||||
functions.push_back({function, EOLIAN_METHOD});
|
||||
}
|
||||
std::function<void(Eolian_Class const*)> inherit_algo =
|
||||
[&] (Eolian_Class const* klass)
|
||||
{
|
||||
for(efl::eina::iterator<const char> inherit_iterator ( ::eolian_class_inherits_get(klass))
|
||||
, inherit_last; inherit_iterator != inherit_last; ++inherit_iterator)
|
||||
{
|
||||
Eolian_Class const* inherit = ::eolian_class_get_by_name(&*inherit_iterator);
|
||||
inherits.insert({inherit, {qualifier_info::is_none}, {}});
|
||||
inherit_algo(inherit);
|
||||
}
|
||||
};
|
||||
inherit_algo(klass);
|
||||
switch(eolian_class_type_get(klass))
|
||||
{
|
||||
case EOLIAN_CLASS_REGULAR:
|
||||
type = class_type::regular;
|
||||
break;
|
||||
case EOLIAN_CLASS_ABSTRACT:
|
||||
type = class_type::abstract_;
|
||||
break;
|
||||
case EOLIAN_CLASS_MIXIN:
|
||||
type = class_type::mixin;
|
||||
break;
|
||||
case EOLIAN_CLASS_INTERFACE:
|
||||
type = class_type::interface_;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Class with unknown type");
|
||||
}
|
||||
for(efl::eina::iterator<Eolian_Event const> event_iterator( ::eolian_class_events_get(klass))
|
||||
, event_last; event_iterator != event_last; ++event_iterator)
|
||||
{
|
||||
events.push_back(&*event_iterator);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
inline klass_name get_klass_name(klass_def const& klass)
|
||||
{
|
||||
return {klass.namespaces, klass.eolian_name, {qualifier_info::is_none, {}}, {}, klass.type};
|
||||
}
|
||||
|
||||
inline Eolian_Class const* get_klass(klass_name const& klass_name_)
|
||||
{
|
||||
std::string klass_name;
|
||||
if(!as_generator(*(string << ".") << string)
|
||||
.generate(std::back_insert_iterator<std::string>(klass_name)
|
||||
, std::make_tuple(klass_name_.namespaces, klass_name_.eolian_name)
|
||||
, context_null{}))
|
||||
return nullptr;
|
||||
else
|
||||
return ::eolian_class_get_by_name(klass_name.c_str());
|
||||
}
|
||||
|
||||
inline std::vector<std::string> cpp_namespaces(std::vector<std::string> namespaces)
|
||||
{
|
||||
if(namespaces.empty())
|
||||
namespaces.push_back("nonamespace");
|
||||
return namespaces;
|
||||
}
|
||||
|
||||
}
|
||||
namespace type_traits {
|
||||
|
||||
template <>
|
||||
struct is_tuple<attributes::parameter_def> : std::true_type {};
|
||||
template <>
|
||||
struct is_tuple<attributes::event_def> : std::true_type {};
|
||||
|
||||
} } } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef EOLIAN_CXX_KLEENE_HH
|
||||
#define EOLIAN_CXX_KLEENE_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
template <typename Generator>
|
||||
struct kleene_generator
|
||||
{
|
||||
kleene_generator(Generator g)
|
||||
: generator(g) {}
|
||||
|
||||
template <typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(OutputIterator sink, Attribute const& attribute, Context const& context) const
|
||||
{
|
||||
bool b;
|
||||
for(auto&& c : attribute)
|
||||
{
|
||||
b = as_generator(generator).generate(sink, c, context);
|
||||
if(!b)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Generator generator;
|
||||
};
|
||||
|
||||
template <typename Generator>
|
||||
struct is_eager_generator<kleene_generator<Generator> > : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <typename G>
|
||||
struct attributes_needed<kleene_generator<G> > : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
template <typename Generator>
|
||||
typename std::enable_if<grammar::is_generator<Generator>::value, kleene_generator<Generator>>::type
|
||||
operator*(Generator g)
|
||||
{
|
||||
return kleene_generator<Generator>{g};
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,52 @@
|
|||
#ifndef EOLIAN_CXX_LIST_HH
|
||||
#define EOLIAN_CXX_LIST_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
template <typename G, typename S>
|
||||
struct list_generator
|
||||
{
|
||||
list_generator(G g, S s)
|
||||
: g(g), s(s) {}
|
||||
|
||||
template <typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(OutputIterator sink, Attribute const& attribute, Context const& context) const
|
||||
{
|
||||
auto generator = as_generator(g);
|
||||
auto separator = as_generator(s);
|
||||
bool first = true;
|
||||
for(auto&& c : attribute)
|
||||
{
|
||||
if(!first)
|
||||
if(!separator.generate(sink, attributes::unused, context)) return false;
|
||||
if(!generator.generate(sink, c, context))
|
||||
return false;
|
||||
first = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
G g;
|
||||
S s;
|
||||
};
|
||||
|
||||
template <typename G, typename S>
|
||||
struct is_eager_generator<list_generator<G, S> > : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <typename G, typename S>
|
||||
struct attributes_needed<list_generator<G, S> > : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
template <typename G, typename S>
|
||||
typename std::enable_if<grammar::is_generator<G>::value && grammar::is_generator<S>::value, list_generator<G, S>>::type
|
||||
operator%(G g, S s)
|
||||
{
|
||||
return list_generator<G, S>{g, s};
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef EOLIAN_CXX_META_HH_
|
||||
#define EOLIAN_CXX_META_HH_
|
||||
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar { namespace meta {
|
||||
|
||||
template <std::size_t A0, std::size_t A1 = 0, std::size_t...args>
|
||||
struct max : max<((A0 > A1) ? A0 : A1), args...> {};
|
||||
|
||||
template <std::size_t A0, std::size_t A1>
|
||||
struct max<A0, A1> : std::integral_constant<std::size_t, (A0 > A1 ? A0 : A1)> {};
|
||||
|
||||
template <typename T>
|
||||
struct identity { typedef T type; };
|
||||
|
||||
template <typename T, typename U, typename...Others>
|
||||
struct is_one_of : std::conditional<std::is_same<T, U>::value
|
||||
, std::is_same<T, U>
|
||||
, is_one_of<T, Others...> >::type::type
|
||||
{};
|
||||
|
||||
template <typename T, typename U>
|
||||
struct is_one_of<T, U> : std::is_same<T, U>
|
||||
{};
|
||||
|
||||
|
||||
template <std::size_t size, typename T, typename U, typename...Args>
|
||||
struct find_impl : find_impl<size+1, T, Args...>
|
||||
{};
|
||||
|
||||
template <std::size_t size, typename T, typename...Args>
|
||||
struct find_impl<size, T, T, Args...> : std::integral_constant<std::size_t, size> {};
|
||||
|
||||
template <typename T, typename U, typename...Args>
|
||||
struct find : find_impl<0u, T, U, Args...>
|
||||
{};
|
||||
|
||||
} } } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
#ifndef EOLIAN_CXX_NAMESPACES_HH
|
||||
#define EOLIAN_CXX_NAMESPACES_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/attributes.hpp"
|
||||
#include "grammar/type_traits.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
template <typename Generator>
|
||||
struct namespaces_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Attributes, typename Context>
|
||||
bool generate(OutputIterator sink, Attributes const& attributes, Context const& context) const
|
||||
{
|
||||
using std::get;
|
||||
typedef typename attributes::tuple_element<0ul, Attributes>::type namespaces_t;
|
||||
namespaces_t const& namespaces = attributes::cpp_namespaces(get<0>(attributes));
|
||||
std::size_t size = namespaces.size();
|
||||
|
||||
for(auto&& n : namespaces)
|
||||
{
|
||||
const char keyword[] = "namespace ";
|
||||
const char open[] = " { ";
|
||||
std::copy(keyword, &keyword[0] + sizeof(keyword)-1, sink);
|
||||
std::transform(std::begin(n), std::end(n), sink, &::tolower);
|
||||
std::copy(open, &open[0] + sizeof(open)-1, sink);
|
||||
}
|
||||
*sink++ = '\n';
|
||||
|
||||
if(!attributes::generate(as_generator(generator), sink, attributes::pop_front(attributes), context))
|
||||
return false;
|
||||
|
||||
for(std::size_t i = 0; i != size; ++i)
|
||||
{
|
||||
const char close[] = "} ";
|
||||
std::copy(close, &close[0] + sizeof(close)-1, sink);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Generator generator;
|
||||
};
|
||||
|
||||
struct namespaces_directive
|
||||
{
|
||||
template <typename G>
|
||||
namespaces_generator<G> operator[](G g) const
|
||||
{
|
||||
return namespaces_generator<G>{g};
|
||||
}
|
||||
} const namespaces;
|
||||
|
||||
template <typename G>
|
||||
struct is_eager_generator<namespaces_generator<G>> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <typename G>
|
||||
struct attributes_needed<namespaces_generator<G>> : std::integral_constant<int, attributes_needed<G>::value+1> {};
|
||||
template <typename G>
|
||||
struct accepts_tuple<namespaces_generator<G> > : std::true_type {};
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -1,68 +0,0 @@
|
|||
|
||||
#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
|
|
@ -0,0 +1,78 @@
|
|||
#ifndef EOLIAN_CXX_PARAMETER_HH
|
||||
#define EOLIAN_CXX_PARAMETER_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
#include "grammar/type.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct add_reference_visitor
|
||||
{
|
||||
typedef void result_type;
|
||||
template <typename T>
|
||||
void operator()(T& object) const
|
||||
{
|
||||
object.pointers.insert(object.pointers.begin(), {{attributes::qualifier_info::is_none}, true});
|
||||
}
|
||||
void operator()(attributes::complex_type_def& complex) const
|
||||
{
|
||||
(*this)(complex.outer);
|
||||
}
|
||||
};
|
||||
|
||||
struct parameter_type_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
|
||||
{
|
||||
std::string dir;
|
||||
switch(param.direction)
|
||||
{
|
||||
case attributes::parameter_direction::out:
|
||||
dir = "out";
|
||||
break;
|
||||
case attributes::parameter_direction::inout:
|
||||
dir = "inout";
|
||||
break;
|
||||
case attributes::parameter_direction::in:
|
||||
dir = "in";
|
||||
break;
|
||||
}
|
||||
return as_generator
|
||||
(
|
||||
" ::efl::eolian::" << string << "_traits<"
|
||||
<< type << ">::type"
|
||||
).generate(sink, std::make_tuple(dir, param), context);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<parameter_type_generator> : std::true_type {};
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed<parameter_type_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
parameter_type_generator const parameter_type;
|
||||
|
||||
struct parameter_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
|
||||
{
|
||||
return as_generator(parameter_type << " " << string).generate(sink, std::make_tuple(param, param.param_name), context);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<parameter_generator> : std::true_type {};
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed<parameter_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
parameter_generator const parameter;
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -1,453 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_STD_PARAMETERS_GENERATOR_HH
|
||||
#define EOLIAN_CXX_STD_PARAMETERS_GENERATOR_HH
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
#include "tab.hh"
|
||||
#include "eo_types.hh"
|
||||
#include "type_generator.hh"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
struct
|
||||
parameter_forward
|
||||
{
|
||||
eolian_type_instance const& _type;
|
||||
std::string const& _name;
|
||||
parameter_forward(eolian_type_instance const& type, std::string const& name)
|
||||
: _type(type)
|
||||
, _name(name)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, parameter_forward const& x)
|
||||
{
|
||||
if (type_is_callback(x._type))
|
||||
{
|
||||
out << "std::forward<" << template_parameter_type(x._type, x._name) << ">(" << x._name << ")";
|
||||
}
|
||||
else
|
||||
out << x._name;
|
||||
return out;
|
||||
}
|
||||
|
||||
struct param_data
|
||||
{
|
||||
std::ostream& out;
|
||||
unsigned pos;
|
||||
eolian_type_instance const& type;
|
||||
std::string const& name;
|
||||
int cb_idx;
|
||||
bool is_cb;
|
||||
param_data(std::ostream& out_, unsigned pos_, eolian_type_instance const& type_, std::string const& name_, int cb_idx_)
|
||||
: out(out_)
|
||||
, pos(pos_)
|
||||
, type(type_)
|
||||
, name(name_)
|
||||
, cb_idx(cb_idx_)
|
||||
, is_cb(cb_idx_ >= 0)
|
||||
{}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct
|
||||
_parameters_cxx_generic
|
||||
{
|
||||
parameters_container_type const& _params;
|
||||
T _fparam;
|
||||
_parameters_cxx_generic(parameters_container_type const& params, T fparam)
|
||||
: _params(params)
|
||||
, _fparam(fparam)
|
||||
{}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
std::ostream&
|
||||
operator<<(std::ostream& out, _parameters_cxx_generic<T> const& x)
|
||||
{
|
||||
int cb_idx = 0u;
|
||||
auto first = x._params.cbegin(),
|
||||
last = x._params.cend();
|
||||
for (auto it = first; it != last; ++it)
|
||||
{
|
||||
if (type_is_callback((*it).type) && it+1 != last)
|
||||
{
|
||||
x._fparam(param_data(out, it - first, (*it).type, (*it).name, cb_idx++));
|
||||
++it; // skip next.
|
||||
}
|
||||
else
|
||||
x._fparam(param_data(out, it - first, (*it).type, (*it).name, -1));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
_parameters_cxx_generic<T>
|
||||
parameters_cxx_generic(parameters_container_type const& params, T fparam)
|
||||
{
|
||||
return _parameters_cxx_generic<T>(params, fparam);
|
||||
}
|
||||
|
||||
struct
|
||||
callback_tmp
|
||||
{
|
||||
std::string const& _name;
|
||||
callback_tmp(std::string const& name)
|
||||
: _name(name)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, callback_tmp const& x)
|
||||
{
|
||||
return out << "_tmp_" << x._name;
|
||||
}
|
||||
|
||||
struct
|
||||
callback_parameter_free_ev_add
|
||||
{
|
||||
std::string const& _eo_raw_expr;
|
||||
eolian_type_instance const& _type;
|
||||
std::string const& _name;
|
||||
callback_parameter_free_ev_add(std::string const& eo_raw_expr, eolian_type_instance const& type, std::string const& name)
|
||||
: _eo_raw_expr(eo_raw_expr)
|
||||
, _type(type)
|
||||
, _name(name)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, callback_parameter_free_ev_add const& x)
|
||||
{
|
||||
out
|
||||
<< "eo_event_callback_add(" << x._eo_raw_expr
|
||||
<< ", EO_EVENT_DEL, &::efl::eolian::free_callback_callback<"
|
||||
<< parameter_no_ref_type(x._type, x._name) << ">, "
|
||||
<< callback_tmp(x._name) << ");";
|
||||
return out;
|
||||
}
|
||||
|
||||
struct
|
||||
callbacks_heap_alloc
|
||||
{
|
||||
std::string const& _eo_raw_expr;
|
||||
parameters_container_type const& _params;
|
||||
bool _is_static_func;
|
||||
int _tab;
|
||||
callbacks_heap_alloc(std::string const& eo_raw_expr, parameters_container_type const& params, bool is_static_func, int tab)
|
||||
: _eo_raw_expr(eo_raw_expr)
|
||||
, _params(params)
|
||||
, _is_static_func(is_static_func)
|
||||
, _tab(tab)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, callbacks_heap_alloc const& x)
|
||||
{
|
||||
auto first = x._params.cbegin(), last = x._params.cend();
|
||||
for (auto it = first; it != last; ++it)
|
||||
{
|
||||
auto type = (*it).type;
|
||||
auto name = (*it).name;
|
||||
if (type_is_callback(type) && it+1 != last)
|
||||
{
|
||||
|
||||
out << tab(x._tab) << parameter_remove_reference_typedef(type, name) << endl
|
||||
<< tab(x._tab) << parameter_no_ref_type(type, name) << "* "
|
||||
<< callback_tmp(name) << " = ";
|
||||
|
||||
if (!x._is_static_func)
|
||||
{
|
||||
out << "new " << parameter_no_ref_type(type, name)
|
||||
<< "(std::forward< "
|
||||
<< template_parameter_type(type, name) << " >(" << name << "));" << endl
|
||||
<< tab(x._tab)
|
||||
<< callback_parameter_free_ev_add(x._eo_raw_expr, type, name)
|
||||
<< endl << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "::efl::eolian::alloc_static_callback< "
|
||||
<< parameter_no_ref_type(type, name) << " >(std::forward< "
|
||||
<< template_parameter_type(type, name) << " >(" << name << "));" << endl;
|
||||
}
|
||||
++it; // skip next.
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct
|
||||
template_parameters_declaration
|
||||
{
|
||||
parameters_container_type const& _params;
|
||||
int _tab;
|
||||
template_parameters_declaration(parameters_container_type const& params, int tab)
|
||||
: _params(params)
|
||||
, _tab(tab)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, template_parameters_declaration const& x)
|
||||
{
|
||||
if (parameters_count_callbacks(x._params) == 0)
|
||||
return out;
|
||||
|
||||
bool comma = false;
|
||||
out << tab(x._tab) << "template <";
|
||||
auto first = x._params.cbegin(), last = x._params.cend();
|
||||
for (auto it = first; it != last; ++it)
|
||||
{
|
||||
if (type_is_callback((*it).type) && it+1 != last)
|
||||
{
|
||||
if (comma)
|
||||
out << ", ";
|
||||
else
|
||||
comma = true;
|
||||
out << "typename " << template_parameter_type((*it).type, (*it).name);
|
||||
++it; // skip next.
|
||||
}
|
||||
}
|
||||
return out << ">" << endl;
|
||||
}
|
||||
|
||||
struct
|
||||
parameters_declaration
|
||||
{
|
||||
parameters_container_type const& _params;
|
||||
parameters_declaration(parameters_container_type const& params)
|
||||
: _params(params)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, parameters_declaration const& x)
|
||||
{
|
||||
auto first = x._params.cbegin(),
|
||||
last = x._params.cend();
|
||||
for (auto it = first; it != last; ++it)
|
||||
{
|
||||
if (it != first)
|
||||
out << ", ";
|
||||
// TODO What to do when callback happens in the middle of parameters
|
||||
// and does not have a following userdata pointer ?
|
||||
if (type_is_callback((*it).type) && it+1 != last)
|
||||
{
|
||||
out << template_parameter_type((*it).type, (*it).name) << " && " << (*it).name;
|
||||
++it; // skip next.
|
||||
}
|
||||
else
|
||||
out << reinterpret_type((*it).type) << " " << (*it).name;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct
|
||||
parameters_c_declaration
|
||||
{
|
||||
parameters_container_type const& _params;
|
||||
parameters_c_declaration(parameters_container_type const& params)
|
||||
: _params(params)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, parameters_c_declaration const& x)
|
||||
{
|
||||
auto first = x._params.cbegin(),
|
||||
last = x._params.cend();
|
||||
for (auto it = first; it != last; ++it)
|
||||
{
|
||||
if (it != first)
|
||||
out << ", ";
|
||||
out << c_type(it->type) << " " << (*it).name;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct
|
||||
parameters_names
|
||||
{
|
||||
parameters_container_type const& _params;
|
||||
parameters_names(parameters_container_type const& params)
|
||||
: _params(params)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, parameters_names const& x)
|
||||
{
|
||||
auto first = x._params.cbegin(),
|
||||
last = x._params.cend();
|
||||
for (auto it = first; it != last; ++it)
|
||||
{
|
||||
if (it != first)
|
||||
out << ", ";
|
||||
|
||||
out << it->name;
|
||||
|
||||
if (type_is_callback(it->type) && it+1 != last)
|
||||
++it; // skip next.
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct
|
||||
parameters_c_names
|
||||
{
|
||||
parameters_container_type const& _params;
|
||||
parameters_c_names(parameters_container_type const& params)
|
||||
: _params(params)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, parameters_c_names const& x)
|
||||
{
|
||||
auto first = x._params.cbegin(),
|
||||
last = x._params.cend();
|
||||
for (auto it = first; it != last; ++it)
|
||||
{
|
||||
if (it != first)
|
||||
out << ", ";
|
||||
out << it->name;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct
|
||||
parameters_types
|
||||
{
|
||||
parameters_container_type const& _params;
|
||||
parameters_types(parameters_container_type const& params)
|
||||
: _params(params)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, parameters_types const& x)
|
||||
{
|
||||
parameters_container_type::const_iterator it,
|
||||
first = x._params.begin(),
|
||||
last = x._params.end();
|
||||
for (it = first; it != last; ++it)
|
||||
{
|
||||
if(it != first) out << ", ";
|
||||
out << reinterpret_type((*it).type);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct
|
||||
parameters_c_list
|
||||
{
|
||||
parameters_container_type const& _params;
|
||||
parameters_c_list(parameters_container_type const& params)
|
||||
: _params(params)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, parameters_c_list const& x)
|
||||
{
|
||||
auto first = x._params.cbegin(), last = x._params.cend();
|
||||
for (auto it = first; it != last; ++it)
|
||||
{
|
||||
if (it != first)
|
||||
out << ", ";
|
||||
out << it->name;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct
|
||||
parameters_cxx_list
|
||||
{
|
||||
parameters_container_type const& _params;
|
||||
parameters_cxx_list(parameters_container_type const& params)
|
||||
: _params(params)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, parameters_cxx_list const& x)
|
||||
{
|
||||
auto first = x._params.cbegin(), last = x._params.cend();
|
||||
for (auto it = first; it != last; ++it)
|
||||
{
|
||||
if (it != first)
|
||||
out << ", ";
|
||||
out << to_cxx(it->type, it->name);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct
|
||||
parameters_forward
|
||||
{
|
||||
parameters_container_type const& _params;
|
||||
parameters_forward(parameters_container_type const& params)
|
||||
: _params(params)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, parameters_forward const& x)
|
||||
{
|
||||
auto first = x._params.cbegin(), last = x._params.cend();
|
||||
for (auto it = first; it != last; ++it)
|
||||
{
|
||||
if (it != first)
|
||||
out << ", ";
|
||||
out << parameter_forward((*it).type, (*it).name);
|
||||
if (type_is_callback((*it).type) && it+1 != last)
|
||||
{
|
||||
++it; // skip next.
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct
|
||||
parameters_forward_to_c
|
||||
{
|
||||
parameters_container_type const& _params;
|
||||
parameters_forward_to_c(parameters_container_type const& params)
|
||||
: _params(params)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, parameters_forward_to_c const& x)
|
||||
{
|
||||
auto first = x._params.cbegin(), last = x._params.cend();
|
||||
for (auto it = first; it != last; ++it)
|
||||
{
|
||||
if (it != first)
|
||||
out << ", ";
|
||||
if (type_is_callback((*it).type))
|
||||
{
|
||||
// TODO: Is it correct to simple not translate the callback type
|
||||
// when it is the last paramenter?
|
||||
if(it + 1 != last)
|
||||
{
|
||||
out << to_c((*it).type, (*it).name) << ", " << callback_tmp((*it).name);
|
||||
++it; // skip next
|
||||
}
|
||||
else
|
||||
out << (*it).name;
|
||||
}
|
||||
else
|
||||
out << to_c((*it).type, (*it).name);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
} } } // namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
|
||||
#endif // EOLIAN_CXX_STD_PARAMETERS_GENERATOR_HH
|
|
@ -0,0 +1,178 @@
|
|||
#ifndef EOLIAN_CXX_QUALIFIER_DEF_HH
|
||||
#define EOLIAN_CXX_QUALIFIER_DEF_HH
|
||||
|
||||
#include "grammar/type_traits.hpp"
|
||||
|
||||
#include <Eolian.h>
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar { namespace attributes {
|
||||
|
||||
enum class qualifier_info {
|
||||
is_none
|
||||
, is_own = 1
|
||||
, is_const = 4
|
||||
, is_const_own
|
||||
, is_optional = 8
|
||||
, is_optional_own
|
||||
, is_optional_const
|
||||
, is_optional_const_own
|
||||
};
|
||||
|
||||
inline qualifier_info qualifiers(Eolian_Type const* type)
|
||||
{
|
||||
bool is_own = ::eolian_type_is_own(type);
|
||||
bool is_const = ::eolian_type_is_const(type);
|
||||
if(is_own && is_const)
|
||||
return qualifier_info::is_const_own;
|
||||
else if(is_own)
|
||||
return qualifier_info::is_own;
|
||||
else if(is_const)
|
||||
return qualifier_info::is_const;
|
||||
else
|
||||
return qualifier_info::is_none;
|
||||
}
|
||||
|
||||
inline bool is_own(qualifier_info i)
|
||||
{
|
||||
switch(i)
|
||||
{
|
||||
case qualifier_info::is_own:
|
||||
case qualifier_info::is_const_own:
|
||||
case qualifier_info::is_optional_own:
|
||||
case qualifier_info::is_optional_const_own:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool is_const(qualifier_info i)
|
||||
{
|
||||
switch(i)
|
||||
{
|
||||
case qualifier_info::is_const:
|
||||
case qualifier_info::is_const_own:
|
||||
case qualifier_info::is_optional_const:
|
||||
case qualifier_info::is_optional_const_own:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool is_optional(qualifier_info i)
|
||||
{
|
||||
switch(i)
|
||||
{
|
||||
case qualifier_info::is_optional:
|
||||
case qualifier_info::is_optional_own:
|
||||
case qualifier_info::is_optional_const:
|
||||
case qualifier_info::is_optional_const_own:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
struct qualifier_def
|
||||
{
|
||||
qualifier_info qualifier;
|
||||
std::string free_function;
|
||||
};
|
||||
|
||||
inline bool operator<(qualifier_def const& lhs, qualifier_def const& rhs)
|
||||
{
|
||||
return lhs.qualifier < rhs.qualifier ||
|
||||
(!(rhs.qualifier < lhs.qualifier) && lhs.free_function < rhs.free_function);
|
||||
}
|
||||
inline bool operator>(qualifier_def const& lhs, qualifier_def const& rhs)
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
inline bool operator==(qualifier_def const& lhs, qualifier_def const& rhs)
|
||||
{
|
||||
return rhs.qualifier == lhs.qualifier && rhs.free_function == lhs.free_function;
|
||||
}
|
||||
inline bool operator!=(qualifier_def const& lhs, qualifier_def const& rhs)
|
||||
{
|
||||
return !(rhs == lhs);
|
||||
}
|
||||
|
||||
inline void add_optional(qualifier_def& q)
|
||||
{
|
||||
switch (q.qualifier)
|
||||
{
|
||||
case qualifier_info::is_none:
|
||||
q.qualifier = qualifier_info::is_optional;
|
||||
break;
|
||||
case qualifier_info::is_own:
|
||||
q.qualifier = qualifier_info::is_optional_own;
|
||||
break;
|
||||
case qualifier_info::is_const:
|
||||
q.qualifier = qualifier_info::is_optional_const;
|
||||
break;
|
||||
case qualifier_info::is_const_own:
|
||||
q.qualifier = qualifier_info::is_optional_const_own;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
inline void remove_optional(qualifier_def& q)
|
||||
{
|
||||
switch (q.qualifier)
|
||||
{
|
||||
case qualifier_info::is_optional:
|
||||
q.qualifier = qualifier_info::is_none;
|
||||
break;
|
||||
case qualifier_info::is_optional_own:
|
||||
q.qualifier = qualifier_info::is_own;
|
||||
break;
|
||||
case qualifier_info::is_optional_const:
|
||||
q.qualifier = qualifier_info::is_const;
|
||||
break;
|
||||
case qualifier_info::is_optional_const_own:
|
||||
q.qualifier = qualifier_info::is_const_own;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
inline void remove_own(qualifier_def& q)
|
||||
{
|
||||
switch (q.qualifier)
|
||||
{
|
||||
case qualifier_info::is_own:
|
||||
q.qualifier = qualifier_info::is_none;
|
||||
break;
|
||||
case qualifier_info::is_const_own:
|
||||
q.qualifier = qualifier_info::is_const;
|
||||
break;
|
||||
case qualifier_info::is_optional_own:
|
||||
q.qualifier = qualifier_info::is_optional;
|
||||
break;
|
||||
case qualifier_info::is_optional_const_own:
|
||||
q.qualifier = qualifier_info::is_optional_const;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool is_optional(qualifier_def const& i)
|
||||
{
|
||||
return is_optional(i.qualifier);
|
||||
}
|
||||
inline bool is_own(qualifier_def const& i)
|
||||
{
|
||||
return is_own(i.qualifier);
|
||||
}
|
||||
inline bool is_const(qualifier_def const& i)
|
||||
{
|
||||
return is_const(i.qualifier);
|
||||
}
|
||||
|
||||
|
||||
} } } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,136 @@
|
|||
#ifndef EOLIAN_CXX_SEQUENCE_HH
|
||||
#define EOLIAN_CXX_SEQUENCE_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
template <typename L, typename R>
|
||||
struct sequence_generator;
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct sequence_size : std::integral_constant<int, 0> {};
|
||||
|
||||
template <typename L, typename R>
|
||||
struct sequence_size<sequence_generator<L, R>> : std::integral_constant<int, 1 + sequence_size<L>::value> {};
|
||||
|
||||
template <typename L, typename R, typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate_sequence(L const& l, R const& r
|
||||
, OutputIterator sink, Attribute const& attr, Context const& context
|
||||
, typename std::enable_if<type_traits::is_tuple<Attribute>::value>::type* = 0)
|
||||
{
|
||||
auto gen_left = as_generator(l);
|
||||
bool b = attributes::generate(gen_left, sink, attr, context);
|
||||
if(b)
|
||||
{
|
||||
return attributes::generate(as_generator(r), sink
|
||||
, attributes::pop_front_n<type_traits::attributes_needed<decltype(gen_left)>::value>
|
||||
(attr), context);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename L, typename R, typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate_sequence(L const& l, R const& r
|
||||
, OutputIterator sink, Attribute const& attr, Context const& context
|
||||
, typename std::enable_if
|
||||
<
|
||||
!type_traits::is_tuple<Attribute>::value
|
||||
&& type_traits::attributes_needed<L>::value == 0
|
||||
&& type_traits::attributes_needed<R>::value == 1
|
||||
>::type* = 0)
|
||||
{
|
||||
bool b = as_generator(l).generate(sink, attributes::unused, context);
|
||||
if(b)
|
||||
{
|
||||
return as_generator(r).generate(sink, attr, context);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename L, typename R, typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate_sequence(L const& l, R const& r
|
||||
, OutputIterator sink, Attribute const&, Context const& context
|
||||
, typename std::enable_if
|
||||
<
|
||||
!type_traits::is_tuple<Attribute>::value
|
||||
&& type_traits::attributes_needed<L>::value == 0
|
||||
&& type_traits::attributes_needed<R>::value == 0
|
||||
>::type* = 0)
|
||||
{
|
||||
bool b = as_generator(l).generate(sink, attributes::unused, context);
|
||||
if(b)
|
||||
{
|
||||
return as_generator(r).generate(sink, attributes::unused, context);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename L, typename R, typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate_sequence(L const& l, R const& r
|
||||
, OutputIterator sink, Attribute const& attr, Context const& context
|
||||
, typename std::enable_if
|
||||
<
|
||||
!type_traits::is_tuple<Attribute>::value
|
||||
&& type_traits::attributes_needed<L>::value == 1
|
||||
&& type_traits::attributes_needed<R>::value == 0
|
||||
>::type* = 0)
|
||||
{
|
||||
bool b = as_generator(l).generate(sink, attr, context);
|
||||
if(b)
|
||||
{
|
||||
return as_generator(r).generate(sink, attributes::unused, context);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename L, typename R, typename OutputIterator, typename Context>
|
||||
bool generate_sequence(L const& l, R const& r, OutputIterator sink, attributes::unused_type, Context const& context)
|
||||
{
|
||||
bool b = as_generator(l).generate(sink, attributes::unused, context);
|
||||
if(b)
|
||||
{
|
||||
return as_generator(r).generate(sink, attributes::unused, context);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename L, typename R>
|
||||
struct sequence_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(OutputIterator sink, Attribute const& attribute, Context const& context) const
|
||||
{
|
||||
return grammar::generate_sequence(left, right, sink, attribute, context);
|
||||
}
|
||||
|
||||
L left;
|
||||
R right;
|
||||
};
|
||||
|
||||
template <typename L, typename R>
|
||||
struct is_eager_generator<sequence_generator<L, R> > : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <typename L, typename R>
|
||||
struct attributes_needed<sequence_generator<L, R> > : std::integral_constant
|
||||
<int, attributes_needed<L>::value + attributes_needed<R>::value> {};
|
||||
template <typename L, typename R>
|
||||
struct accepts_tuple<sequence_generator<L, R> > : std::true_type {};
|
||||
}
|
||||
|
||||
template <typename L, typename R>
|
||||
typename std::enable_if<grammar::is_generator<L>::value && grammar::is_generator<R>::value, sequence_generator<L, R>>::type
|
||||
operator<<(L l, R r)
|
||||
{
|
||||
return sequence_generator<L, R>{l, r};
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,185 @@
|
|||
#ifndef EOLIAN_CXX_STRING_HH
|
||||
#define EOLIAN_CXX_STRING_HH
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/attributes.hpp"
|
||||
#include "grammar/case.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
// literal
|
||||
struct literal_generator
|
||||
{
|
||||
literal_generator(const char* string)
|
||||
: string(string) {}
|
||||
|
||||
template <typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(OutputIterator sink, Attribute const&, Context const&) const
|
||||
{
|
||||
std::copy(string, string + std::strlen(string), sink);
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* string;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<literal_generator> : std::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_generator<const char*> : std::true_type {};
|
||||
|
||||
template <int N>
|
||||
struct is_generator<const char[N]> : std::true_type {};
|
||||
|
||||
literal_generator as_generator(char const* literal) { return literal; }
|
||||
|
||||
struct {
|
||||
literal_generator operator()(const char* literal) const
|
||||
{
|
||||
return literal_generator(literal);
|
||||
}
|
||||
} const lit;
|
||||
|
||||
// string
|
||||
struct string_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(OutputIterator sink, Attribute const& attribute, Context const&) const
|
||||
{
|
||||
if(tag_check<upper_case_tag, Context>::value)
|
||||
{
|
||||
std::transform(std::begin(attribute), std::end(attribute), sink, &::toupper);
|
||||
}
|
||||
else if(tag_check<lower_case_tag, Context>::value)
|
||||
{
|
||||
std::transform(std::begin(attribute), std::end(attribute), sink, &::tolower);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::copy(std::begin(attribute), std::end(attribute), sink);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct specific_string_generator
|
||||
{
|
||||
specific_string_generator(std::string string) : string(string) {}
|
||||
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::unused_type, Context const&) const
|
||||
{
|
||||
if(tag_check<upper_case_tag, Context>::value)
|
||||
{
|
||||
std::transform(std::begin(string), std::end(string), sink, &::toupper);
|
||||
}
|
||||
else if(tag_check<lower_case_tag, Context>::value)
|
||||
{
|
||||
std::transform(std::begin(string), std::end(string), sink, &::tolower);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::copy(std::begin(string), std::end(string), sink);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string string;
|
||||
};
|
||||
|
||||
struct string_replace_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Attribute, typename Context>
|
||||
bool generate(OutputIterator sink, Attribute const& string, Context const&) const
|
||||
{
|
||||
if(tag_check<upper_case_tag, Context>::value)
|
||||
{
|
||||
std::transform(std::begin(string), std::end(string), sink,
|
||||
[&] (char c) -> char
|
||||
{
|
||||
if(c == from)
|
||||
return to;
|
||||
else
|
||||
return ::toupper(c);
|
||||
}
|
||||
);
|
||||
}
|
||||
else if(tag_check<lower_case_tag, Context>::value)
|
||||
{
|
||||
std::transform(std::begin(string), std::end(string), sink,
|
||||
[&] (char c) -> char
|
||||
{
|
||||
if(c == from)
|
||||
return to;
|
||||
else
|
||||
return ::tolower(c);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
std::transform(std::begin(string), std::end(string), sink
|
||||
, [&] (char c) { return c == from ? to : c; });
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
char from, to;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<string_generator> : std::true_type {};
|
||||
template <>
|
||||
struct is_eager_generator<specific_string_generator> : std::true_type {};
|
||||
template <>
|
||||
struct is_eager_generator<string_replace_generator> : std::true_type {};
|
||||
|
||||
struct string_generator_terminal
|
||||
{
|
||||
specific_string_generator operator[](std::string string) const
|
||||
{
|
||||
return specific_string_generator{string};
|
||||
}
|
||||
} const string;
|
||||
|
||||
struct string_replace_terminal
|
||||
{
|
||||
string_replace_generator operator()(char from, char to) const
|
||||
{
|
||||
return string_replace_generator{from, to};
|
||||
}
|
||||
} const string_replace;
|
||||
|
||||
template <>
|
||||
struct is_generator<string_generator_terminal> : std::true_type {};
|
||||
template <>
|
||||
struct is_generator<std::string> : std::true_type {};
|
||||
|
||||
string_generator as_generator(string_generator_terminal)
|
||||
{
|
||||
return string_generator{};
|
||||
}
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed<string_generator> : std::integral_constant<int, 1> {};
|
||||
template <>
|
||||
struct attributes_needed<string_generator_terminal> : std::integral_constant<int, 1> {};
|
||||
template <>
|
||||
struct attributes_needed<string_replace_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
namespace std {
|
||||
|
||||
::efl::eolian::grammar::specific_string_generator as_generator(std::string string)
|
||||
{
|
||||
return ::efl::eolian::grammar::specific_string_generator{string};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,30 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_STD_TAB_HH
|
||||
#define EOLIAN_CXX_STD_TAB_HH
|
||||
|
||||
#include <ostream>
|
||||
#include <iosfwd>
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
using std::endl;
|
||||
|
||||
const int tabsize = 3;
|
||||
|
||||
struct tab
|
||||
{
|
||||
int _n;
|
||||
tab(int n) : _n(n * tabsize) {}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, efl::eolian::grammar::tab tab)
|
||||
{
|
||||
for (int i = tab._n; i; --i)
|
||||
out << ' ';
|
||||
return out;
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif // EOLIAN_CXX_STD_TAB_HH
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef EOLIAN_CXX_TYPE_HH
|
||||
#define EOLIAN_CXX_TYPE_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
#include "grammar/case.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
template <typename OutputIterator, typename Context>
|
||||
struct visitor_generate;
|
||||
|
||||
struct type_generator
|
||||
{
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const
|
||||
{
|
||||
return type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false});
|
||||
}
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
|
||||
{
|
||||
return param.type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, param.c_type
|
||||
, param.direction != attributes::parameter_direction::in});
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_eager_generator<type_generator> : std::true_type {};
|
||||
|
||||
namespace type_traits {
|
||||
template <>
|
||||
struct attributes_needed<type_generator> : std::integral_constant<int, 1> {};
|
||||
}
|
||||
|
||||
type_generator const type;
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -1,266 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_GRAMMAR_TYPE_GENERATOR_HH
|
||||
#define EOLIAN_CXX_GRAMMAR_TYPE_GENERATOR_HH
|
||||
|
||||
#include <ostream>
|
||||
#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;
|
||||
bool _from_global;
|
||||
full_name(eo_class const& cls, bool from_global = true)
|
||||
: _cls(cls), _from_global(from_global) {}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, full_name const& x)
|
||||
{
|
||||
if (x._from_global)
|
||||
out << "::";
|
||||
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 name_upper
|
||||
{
|
||||
eo_class const& _cls;
|
||||
name_upper(eo_class const& cls)
|
||||
: _cls(cls) {}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, name_upper const& x)
|
||||
{
|
||||
std::string key = x._cls.name;
|
||||
std::transform(key.begin(), key.end(), key.begin(), ::toupper);
|
||||
return out << key;
|
||||
}
|
||||
|
||||
struct c_type
|
||||
{
|
||||
eolian_type_instance const& _list;
|
||||
c_type(eolian_type_instance const& list)
|
||||
: _list(list)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, efl::eolian::grammar::c_type const& x)
|
||||
{
|
||||
assert(x._list.size() > 0);
|
||||
std::string res;
|
||||
for (auto rit = x._list.parts.rbegin(), last = x._list.parts.rend(); rit != last; ++rit)
|
||||
{
|
||||
res = (*rit).native;
|
||||
}
|
||||
assert(!res.empty());
|
||||
return out << res;
|
||||
}
|
||||
|
||||
struct reinterpret_type
|
||||
{
|
||||
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._type.size() > 0);
|
||||
std::string res;
|
||||
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 + " >";
|
||||
else
|
||||
res = type_is_binding(t) ? t.binding
|
||||
: t.native;
|
||||
}
|
||||
assert(!res.empty());
|
||||
|
||||
if (type_is_binding(x._type.front()))
|
||||
{
|
||||
if (x._type.is_out)
|
||||
res += "*";
|
||||
else if (x._type.is_optional && x._type.front().binding_requires_optional)
|
||||
res = "::efl::eina::optional< " + res + " >";
|
||||
}
|
||||
|
||||
return out << res;
|
||||
}
|
||||
|
||||
struct type_ownership
|
||||
{
|
||||
eolian_type_instance const& _type;
|
||||
type_ownership(eolian_type_instance const& type)
|
||||
: _type(type)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, type_ownership const& x)
|
||||
{
|
||||
out << "std::tuple<";
|
||||
for (auto it=x._type.parts.begin(), last=x._type.parts.end(); it != last; ++it)
|
||||
{
|
||||
if (it != x._type.parts.begin())
|
||||
out << ", ";
|
||||
out << ((*it).is_own ? "std::true_type" : "std::false_type");
|
||||
}
|
||||
return out << ">()";
|
||||
}
|
||||
|
||||
struct
|
||||
template_parameter_type
|
||||
{
|
||||
eolian_type_instance const& _type;
|
||||
std::string const& _name;
|
||||
template_parameter_type(eolian_type_instance const& type, std::string const& name)
|
||||
: _type(type)
|
||||
, _name(name)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, template_parameter_type const& x)
|
||||
{
|
||||
return out << "F_" << x._name;
|
||||
}
|
||||
|
||||
struct
|
||||
parameter_type
|
||||
{
|
||||
eolian_type_instance const& _type;
|
||||
std::string const& _name;
|
||||
parameter_type(eolian_type_instance const& t, std::string const& name)
|
||||
: _type(t)
|
||||
, _name(name)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, parameter_type const& x)
|
||||
{
|
||||
if(type_is_callback(x._type))
|
||||
out << template_parameter_type(x._type, x._name);
|
||||
else
|
||||
out << reinterpret_type(x._type);
|
||||
return out;
|
||||
}
|
||||
|
||||
struct
|
||||
parameter_no_ref_type
|
||||
{
|
||||
eolian_type_instance const& _type;
|
||||
std::string const& _name;
|
||||
parameter_no_ref_type(eolian_type_instance const& type, std::string const& name)
|
||||
: _type(type)
|
||||
, _name(name)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, parameter_no_ref_type const& x)
|
||||
{
|
||||
return out << "_no_ref_" << parameter_type(x._type, x._name);
|
||||
}
|
||||
|
||||
struct
|
||||
parameter_remove_reference_typedef
|
||||
{
|
||||
eolian_type_instance const& _type;
|
||||
std::string const& _name;
|
||||
parameter_remove_reference_typedef(eolian_type_instance const& type, std::string const& name)
|
||||
: _type(type)
|
||||
, _name(name)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, parameter_remove_reference_typedef const& x)
|
||||
{
|
||||
out << "typedef typename std::remove_reference<"
|
||||
<< parameter_type(x._type, x._name)
|
||||
<< ">::type " << parameter_no_ref_type(x._type, x._name) << ";";
|
||||
return out;
|
||||
}
|
||||
|
||||
struct to_cxx
|
||||
{
|
||||
eolian_type_instance const& _type;
|
||||
std::string const& _varname;
|
||||
to_cxx(eolian_type_instance const& type, std::string const& varname)
|
||||
: _type(type), _varname(varname)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, to_cxx const& x)
|
||||
{
|
||||
if (type_is_binding(x._type))
|
||||
{
|
||||
out << "::efl::eolian::to_cxx<"
|
||||
<< reinterpret_type(x._type)
|
||||
<< ">(" << x._varname
|
||||
<< ", " << type_ownership(x._type) << ")";
|
||||
}
|
||||
else
|
||||
out << x._varname;
|
||||
return out;
|
||||
}
|
||||
|
||||
struct to_c
|
||||
{
|
||||
eolian_type_instance const& _type;
|
||||
std::string const& _varname;
|
||||
to_c(eolian_type_instance const& type, std::string const& varname)
|
||||
: _type(type), _varname(varname)
|
||||
{}
|
||||
};
|
||||
|
||||
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)
|
||||
<< ", " << 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 << ")";
|
||||
else if (type_is_binding(x._type))
|
||||
out << "::efl::eolian::to_c(" << x._varname << ")";
|
||||
else
|
||||
out << x._varname;
|
||||
return out;
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif // EOLIAN_CXX_GRAMMAR_TYPE_GENERATOR_HH
|
|
@ -0,0 +1,333 @@
|
|||
#ifndef EOLIAN_CXX_TYPE_IMPL_HH
|
||||
#define EOLIAN_CXX_TYPE_IMPL_HH
|
||||
|
||||
#include "grammar/generator.hpp"
|
||||
#include "grammar/klass_def.hpp"
|
||||
#include "grammar/case.hpp"
|
||||
#include "grammar/container.hpp"
|
||||
#include "grammar/type.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
namespace detail {
|
||||
|
||||
bool has_own(attributes::regular_type_def const& def)
|
||||
{
|
||||
for(auto&& c : def.pointers)
|
||||
if(is_own(c.qualifier))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct swap_pointers_visitor
|
||||
{
|
||||
std::vector<attributes::pointer_indirection>* pointers;
|
||||
typedef void result_type;
|
||||
template <typename T>
|
||||
void operator()(T& object) const
|
||||
{
|
||||
std::swap(*pointers, object.pointers);
|
||||
}
|
||||
void operator()(attributes::complex_type_def& complex) const
|
||||
{
|
||||
(*this)(complex.outer);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate_pointers(OutputIterator sink, std::vector<attributes::pointer_indirection> const& pointers, Context const&
|
||||
, bool no_reference)
|
||||
{
|
||||
for(auto first = pointers.rbegin()
|
||||
, last = pointers.rend(); first != last; ++first)
|
||||
{
|
||||
if(std::next(first) == last && first->reference && !no_reference)
|
||||
*sink++ = '&';
|
||||
else
|
||||
*sink++ = '*';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T const* as_const_pointer(T* p) { return p; }
|
||||
|
||||
attributes::regular_type_def replace_base_type(attributes::regular_type_def v, std::string name)
|
||||
{
|
||||
v.base_type = name;
|
||||
return v;
|
||||
}
|
||||
|
||||
attributes::complex_type_def replace_outer(attributes::complex_type_def v, attributes::regular_type_def const& regular)
|
||||
{
|
||||
v.outer = regular;
|
||||
return v;
|
||||
}
|
||||
|
||||
template <typename Array, typename F, int N, typename A>
|
||||
eina::optional<bool> call_match(Array const (&array)[N], F f, A a)
|
||||
{
|
||||
typedef Array const* iterator_type;
|
||||
iterator_type match_iterator = &array[0], match_last = match_iterator + N;
|
||||
match_iterator = std::find_if(match_iterator, match_last, f);
|
||||
if(match_iterator != match_last)
|
||||
{
|
||||
return a(match_iterator->function());
|
||||
}
|
||||
return {nullptr};
|
||||
}
|
||||
|
||||
template <typename OutputIterator, typename Context>
|
||||
struct visitor_generate
|
||||
{
|
||||
mutable OutputIterator sink;
|
||||
Context const* context;
|
||||
std::string c_type;
|
||||
bool is_out;
|
||||
|
||||
typedef visitor_generate<OutputIterator, Context> visitor_type;
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator()(attributes::regular_type_def const& regular) const
|
||||
{
|
||||
using attributes::regular_type_def;
|
||||
struct match
|
||||
{
|
||||
eina::optional<std::string> name;
|
||||
eina::optional<bool> has_own;
|
||||
std::function<attributes::type_def::variant_type()> function;
|
||||
}
|
||||
const match_table[] =
|
||||
{
|
||||
"void_ptr", nullptr, [&]
|
||||
{
|
||||
std::vector<attributes::pointer_indirection> pointers = regular.pointers;
|
||||
pointers.insert(pointers.begin(), {{attributes::qualifier_info::is_none, {}}, false});
|
||||
return attributes::regular_type_def{"void", regular.base_qualifier, pointers, {}};
|
||||
}
|
||||
, {"size", nullptr, [&] { return replace_base_type(regular, " ::std::size_t"); }}
|
||||
, {"ubyte", nullptr, [&] { return replace_base_type(regular, " unsigned char"); }}
|
||||
, {"string", true, [&] { return replace_base_type(regular, " ::std::string"); }}
|
||||
, {"string", false, [&] { return replace_base_type(regular, " ::efl::eina::string_view"); }}
|
||||
, {"generic_value", nullptr, [&]
|
||||
{ return regular_type_def{" ::efl::eina::value", regular.base_qualifier
|
||||
, {regular.pointers.empty()
|
||||
|| (regular.pointers.size() == 1 && regular.pointers[0].reference)
|
||||
? regular.pointers
|
||||
: std::vector<attributes::pointer_indirection>
|
||||
{regular.pointers.begin(), std::prev(regular.pointers.end())}}
|
||||
, {}};
|
||||
}}
|
||||
};
|
||||
|
||||
if(eina::optional<bool> b = call_match
|
||||
(match_table
|
||||
, [&] (match const& m)
|
||||
{
|
||||
return (!m.name || *m.name == regular.base_type)
|
||||
&& (!m.has_own || *m.has_own == is_own(regular.base_qualifier))
|
||||
;
|
||||
}
|
||||
, [&] (attributes::type_def::variant_type const& v)
|
||||
{
|
||||
return v.visit(*this); // we want to keep is_out info
|
||||
}))
|
||||
{
|
||||
return *b;
|
||||
}
|
||||
else if(attributes::is_optional(regular.base_qualifier))
|
||||
{
|
||||
if(regular.pointers.empty() || (regular.pointers.size() == 1 && regular.pointers[0].reference == true))
|
||||
{
|
||||
attributes::complex_type_def def
|
||||
{attributes::regular_type_def{" ::efl::eina::optional", attributes::qualifier_info::is_none, {}}};
|
||||
attributes::regular_type_def no_optional_regular = regular;
|
||||
attributes::remove_optional(no_optional_regular.base_qualifier);
|
||||
|
||||
def.subtypes.push_back({no_optional_regular, c_type});
|
||||
return (*this)(def);
|
||||
}
|
||||
else
|
||||
{
|
||||
attributes::regular_type_def no_optional_regular = regular;
|
||||
attributes::remove_optional(no_optional_regular.base_qualifier);
|
||||
no_optional_regular.pointers[0].reference = 0;
|
||||
return (*this)(no_optional_regular);
|
||||
}
|
||||
}
|
||||
// else if(detail::has_own(regular) && !regular.pointers.empty())
|
||||
// {
|
||||
// attributes::complex_type_def def
|
||||
// {attributes::regular_type_def{" ::efl::eolian::own_ptr", attributes::qualifier_info::is_none, {}}};
|
||||
|
||||
// attributes::complex_type_def tagged_def
|
||||
// {attributes::regular_type_def{" ::efl::eolian::own", attributes::qualifier_info::is_none, {}}};
|
||||
|
||||
// auto pointer_iterator = regular.pointers.begin()
|
||||
// , pointer_last = regular.pointers.end();
|
||||
|
||||
// for(;pointer_iterator != pointer_last && !attributes::is_own(pointer_iterator->qualifier)
|
||||
// ;++pointer_iterator)
|
||||
// {
|
||||
// tagged_def.outer.pointers.push_back(*pointer_iterator);
|
||||
// tagged_def.outer.pointers.front().reference = false;
|
||||
// }
|
||||
|
||||
// assert(attributes::is_own(pointer_iterator->qualifier));
|
||||
|
||||
// attributes::regular_type_def base_type (regular);
|
||||
// base_type.pointers.clear();
|
||||
|
||||
// for(;pointer_iterator != pointer_last; ++pointer_iterator)
|
||||
// {
|
||||
// base_type.pointers.insert(base_type.pointers.begin(), *pointer_iterator);
|
||||
// attributes::remove_own(base_type.pointers.back().qualifier);
|
||||
// }
|
||||
|
||||
// tagged_def.subtypes.push_back({base_type, c_type});
|
||||
// def.subtypes.push_back({tagged_def, c_type});
|
||||
// return (*this)(def);
|
||||
// }
|
||||
else if(detail::has_own(regular) && !regular.pointers.empty())
|
||||
{
|
||||
attributes::regular_type_def pointee = regular;
|
||||
std::vector<attributes::pointer_indirection> pointers;
|
||||
std::swap(pointers, pointee.pointers);
|
||||
pointers.erase(pointers.begin());
|
||||
|
||||
attributes::pointer_indirection reference {{{},{}}, true};
|
||||
|
||||
return as_generator(" ::std::unique_ptr<" << type).generate
|
||||
(sink, attributes::type_def{pointee, c_type}, *context)
|
||||
&& detail::generate_pointers(sink, pointers, *context, true)
|
||||
&& as_generator(", void(*)(const void*)>").generate(sink, attributes::unused, *context)
|
||||
&& (!is_out || detail::generate_pointers(sink, {reference}, *context, false));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto pointers = regular.pointers;
|
||||
if(is_out)
|
||||
pointers.push_back({{{},{}}, true});
|
||||
if(as_generator(*(string << "_") << string << (is_const(regular.base_qualifier)? " const" : ""))
|
||||
.generate(sink, std::make_tuple(regular.namespaces, regular.base_type), *context))
|
||||
return detail::generate_pointers(sink, pointers, *context
|
||||
, regular.base_type == "void");
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool operator()(attributes::klass_name klass) const
|
||||
{
|
||||
if(is_out)
|
||||
klass.pointers.push_back({{{}, {}}, true});
|
||||
if(as_generator(" " << *("::" << lower_case[string]) << "::" << string)
|
||||
.generate(sink, std::make_tuple(attributes::cpp_namespaces(klass.namespaces), klass.eolian_name), *context))
|
||||
return detail::generate_pointers(sink, klass.pointers, *context, false);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
bool operator()(attributes::complex_type_def const& complex) const
|
||||
{
|
||||
using attributes::regular_type_def;
|
||||
using attributes::qualifier_info;
|
||||
struct match
|
||||
{
|
||||
eina::optional<std::string> name;
|
||||
eina::optional<bool> has_own;
|
||||
eina::optional<bool> is_const;
|
||||
std::function<attributes::type_def::variant_type()> function;
|
||||
} const matches[] =
|
||||
{
|
||||
{"list", true, nullptr, [&]
|
||||
{
|
||||
generate_container(sink, complex, *context, " ::efl::eina::list");
|
||||
return attributes::type_def::variant_type();
|
||||
}}
|
||||
, {"list", false, nullptr, [&]
|
||||
{
|
||||
generate_container(sink, complex, *context, " ::efl::eina::range_list");
|
||||
return attributes::type_def::variant_type();
|
||||
}}
|
||||
, {"array", true, nullptr, [&]
|
||||
{
|
||||
generate_container(sink, complex, *context, " ::efl::eina::array");
|
||||
return attributes::type_def::variant_type();
|
||||
}}
|
||||
, {"array", false, nullptr, [&]
|
||||
{
|
||||
generate_container(sink, complex, *context, " ::efl::eina::range_array");
|
||||
return attributes::type_def::variant_type();
|
||||
}}
|
||||
, {"hash", nullptr, nullptr
|
||||
, [&]
|
||||
{ regular_type_def r{"Eina_Hash", complex.outer.base_qualifier, complex.outer.pointers, {}};
|
||||
r.pointers.push_back({{qualifier_info::is_none, {}}, false});
|
||||
return r;
|
||||
}}
|
||||
, {"promise", nullptr, nullptr, [&]
|
||||
{
|
||||
return replace_outer
|
||||
(complex, regular_type_def{" ::efl::eina::future", complex.outer.base_qualifier, {}, {}});
|
||||
}
|
||||
}
|
||||
, {"iterator", nullptr, nullptr, [&]
|
||||
{
|
||||
return replace_outer
|
||||
(complex, regular_type_def{" ::efl::eina::iterator", complex.outer.base_qualifier, {}, {}});
|
||||
}
|
||||
}
|
||||
, {"accessor", nullptr, nullptr, [&]
|
||||
{
|
||||
return replace_outer
|
||||
(complex, regular_type_def{" ::efl::eina::accessor", complex.outer.base_qualifier, {}, {}});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto default_match = [&] (attributes::complex_type_def const& complex)
|
||||
{
|
||||
regular_type_def no_pointer_regular = complex.outer;
|
||||
std::vector<attributes::pointer_indirection> pointers;
|
||||
pointers.swap(no_pointer_regular.pointers);
|
||||
if(is_out)
|
||||
pointers.push_back({{{}, {}}, true});
|
||||
return visitor_type{sink, context, c_type, false}(no_pointer_regular)
|
||||
&& as_generator("<" << (type % ", ") << ">").generate(sink, complex.subtypes, *context)
|
||||
&& detail::generate_pointers(sink, pointers, *context, false);
|
||||
};
|
||||
|
||||
if(eina::optional<bool> b = call_match
|
||||
(matches
|
||||
, [&] (match const& m)
|
||||
{
|
||||
return (!m.name || *m.name == complex.outer.base_type)
|
||||
&& (!m.has_own || *m.has_own == is_own(complex.outer.base_qualifier))
|
||||
&& (!m.is_const || *m.is_const == is_const(complex.outer.base_qualifier));
|
||||
}
|
||||
, [&] (attributes::type_def::variant_type const& v)
|
||||
{
|
||||
if(v.empty())
|
||||
return true;
|
||||
else if(attributes::complex_type_def const* complex
|
||||
= attributes::get<attributes::complex_type_def>(&v))
|
||||
return default_match(*complex);
|
||||
else
|
||||
return v.visit(*this);
|
||||
}))
|
||||
return *b;
|
||||
else
|
||||
{
|
||||
return default_match(complex);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,63 @@
|
|||
#ifndef EOLIAN_CXX_TYPE_TRAITS_HH
|
||||
#define EOLIAN_CXX_TYPE_TRAITS_HH
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar { namespace type_traits {
|
||||
|
||||
template <typename G>
|
||||
struct accepts_tuple : std::false_type {};
|
||||
|
||||
template <typename G>
|
||||
struct attributes_needed : std::integral_constant<int, 0> {};
|
||||
template <typename G>
|
||||
struct attributes_needed<G const> : attributes_needed<G> {};
|
||||
template <typename G>
|
||||
struct attributes_needed<G&> : attributes_needed<G> {};
|
||||
template <typename G>
|
||||
struct attributes_needed<G const&> : attributes_needed<G> {};
|
||||
template <typename G>
|
||||
struct attributes_needed<G volatile> : attributes_needed<G> {};
|
||||
template <typename G>
|
||||
struct attributes_needed<G volatile&> : attributes_needed<G> {};
|
||||
template <typename G>
|
||||
struct attributes_needed<G const volatile> : attributes_needed<G> {};
|
||||
template <typename G>
|
||||
struct attributes_needed<G const volatile&> : attributes_needed<G> {};
|
||||
|
||||
template <typename T>
|
||||
struct is_std_tuple : std::false_type {};
|
||||
|
||||
template <typename...Args>
|
||||
struct is_std_tuple<std::tuple<Args...> > : std::true_type {};
|
||||
template <typename...Args>
|
||||
struct is_std_tuple<std::tuple<Args...>&> : std::true_type {};
|
||||
template <typename...Args>
|
||||
struct is_std_tuple<const std::tuple<Args...> > : std::true_type {};
|
||||
template <typename...Args>
|
||||
struct is_std_tuple<const std::tuple<Args...>&> : std::true_type {};
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct is_explicit_tuple : std::false_type {};
|
||||
template <typename T>
|
||||
struct is_explicit_tuple<T, typename std::enable_if<is_std_tuple<T>::value>::type> : std::true_type {};
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct is_tuple : std::false_type {};
|
||||
template <typename T>
|
||||
struct is_tuple<T const> : is_tuple<T> {};
|
||||
template <typename T>
|
||||
struct is_tuple<T const&> : is_tuple<T> {};
|
||||
template <typename T>
|
||||
struct is_tuple<T const volatile> : is_tuple<T> {};
|
||||
template <typename T>
|
||||
struct is_tuple<T const volatile&> : is_tuple<T> {};
|
||||
template <typename T>
|
||||
struct is_tuple<T volatile> : is_tuple<T> {};
|
||||
template <typename T>
|
||||
struct is_tuple<T volatile&> : is_tuple<T> {};
|
||||
|
||||
template <typename T>
|
||||
struct is_tuple<T, typename std::enable_if<!std::is_const<T>::value && is_std_tuple<T>::value>::type> : std::true_type {};
|
||||
|
||||
} } } }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,276 @@
|
|||
#ifndef EOLIAN_CXX_VARIANT_HH_
|
||||
#define EOLIAN_CXX_VARIANT_HH_
|
||||
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
|
||||
#include "grammar/meta.hpp"
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar { namespace attributes {
|
||||
|
||||
template <std::size_t N, std::size_t L, typename Tuple>
|
||||
struct call_visitor
|
||||
{
|
||||
template <typename F>
|
||||
static typename F::result_type call(int type, void const* buffer, F f)
|
||||
{
|
||||
if(type == N)
|
||||
{
|
||||
using std::tuple_element;
|
||||
typedef typename tuple_element<N, Tuple>::type type;
|
||||
type const* o = static_cast<type const*>(buffer);
|
||||
return f(*o);
|
||||
}
|
||||
else
|
||||
return call_visitor<N+1, L, Tuple>::call(type, buffer, f);
|
||||
}
|
||||
template <typename F>
|
||||
static typename F::result_type call(int type, void* buffer, F f)
|
||||
{
|
||||
if(type == N)
|
||||
{
|
||||
using std::tuple_element;
|
||||
typedef typename tuple_element<N, Tuple>::type type;
|
||||
type* o = static_cast<type*>(buffer);
|
||||
return f(*o);
|
||||
}
|
||||
else
|
||||
return call_visitor<N+1, L, Tuple>::call(type, buffer, f);
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t L, typename Tuple>
|
||||
struct call_visitor<L, L, Tuple>
|
||||
{
|
||||
template <typename F>
|
||||
static typename F::result_type call(int, void const*, F)
|
||||
{
|
||||
std::abort();
|
||||
}
|
||||
};
|
||||
|
||||
struct compare_equal_visitor
|
||||
{
|
||||
void const* buffer;
|
||||
typedef bool result_type;
|
||||
template <typename T>
|
||||
bool operator()(T const& other) const
|
||||
{
|
||||
return *static_cast<T const*>(buffer) == other;
|
||||
}
|
||||
};
|
||||
|
||||
struct copy_visitor
|
||||
{
|
||||
typedef void result_type;
|
||||
void* buffer;
|
||||
template <typename T>
|
||||
void operator()(T const& other) const
|
||||
{
|
||||
new (buffer) T(other);
|
||||
}
|
||||
};
|
||||
|
||||
struct move_visitor
|
||||
{
|
||||
typedef void result_type;
|
||||
void* buffer;
|
||||
template <typename T>
|
||||
void operator()(T& other) const
|
||||
{
|
||||
typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type type;
|
||||
new (buffer) type(std::move(other));
|
||||
}
|
||||
};
|
||||
|
||||
struct assign_visitor
|
||||
{
|
||||
typedef void result_type;
|
||||
void* buffer;
|
||||
template <typename T>
|
||||
void operator()(T const& other) const
|
||||
{
|
||||
typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type type;
|
||||
type* assigned = static_cast<type*>(buffer);
|
||||
*assigned = other;
|
||||
}
|
||||
};
|
||||
|
||||
struct destroy_visitor
|
||||
{
|
||||
typedef void result_type;
|
||||
template <typename T>
|
||||
void operator()(T&& other) const
|
||||
{
|
||||
typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type type;
|
||||
other.~type();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct get_visitor
|
||||
{
|
||||
typedef T* result_type;
|
||||
T* operator()(T& object) const
|
||||
{
|
||||
return &object;
|
||||
}
|
||||
template <typename U>
|
||||
T* operator()(U&) const { return nullptr; }
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
struct variant
|
||||
{
|
||||
typedef variant<Args...> _self_type; /**< Type for the optional class itself. */
|
||||
|
||||
constexpr variant()
|
||||
: type(-1)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
variant(T object,
|
||||
typename std::enable_if<meta::is_one_of
|
||||
<typename std::remove_cv<typename std::remove_reference<T>::type>::type, Args...>::value>::type* = 0)
|
||||
: type(meta::find<typename std::remove_cv<typename std::remove_reference<T>::type>::type, Args...>::value)
|
||||
{
|
||||
construct(object);
|
||||
}
|
||||
|
||||
variant(variant const& other)
|
||||
: type(other.type)
|
||||
{
|
||||
if(other.type != -1)
|
||||
other.visit(copy_visitor{static_cast<void*>(&buffer)});
|
||||
}
|
||||
variant& operator=(variant const& other)
|
||||
{
|
||||
if(type == other.type && type != -1)
|
||||
{
|
||||
other.visit(assign_visitor{static_cast<void*>(&buffer)});
|
||||
}
|
||||
else if(type != other.type)
|
||||
{
|
||||
if(type != -1)
|
||||
destroy_unsafe();
|
||||
type = other.type;
|
||||
other.visit(copy_visitor{static_cast<void*>(&buffer)});
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
~variant()
|
||||
{
|
||||
if(type != -1)
|
||||
destroy_unsafe();
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
destroy_unsafe();
|
||||
type = -1;
|
||||
}
|
||||
|
||||
void destroy_unsafe()
|
||||
{
|
||||
visit(destroy_visitor());
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return type == -1;
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
typename F::result_type visit(F f) const
|
||||
{
|
||||
if(type == -1)
|
||||
{
|
||||
throw std::runtime_error("variant is empty");
|
||||
}
|
||||
else
|
||||
return call_visitor<0u, sizeof...(Args), std::tuple<Args...>>::call(type, static_cast<const void*>(&buffer), f);
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
typename F::result_type visit(F f)
|
||||
{
|
||||
if(type == -1)
|
||||
{
|
||||
throw std::runtime_error("variant is empty");
|
||||
}
|
||||
else
|
||||
return call_visitor<0u, sizeof...(Args), std::tuple<Args...>>::call(type, static_cast<void*>(&buffer), f);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
void construct(T object)
|
||||
{
|
||||
new (&buffer) T(std::move(object));
|
||||
}
|
||||
|
||||
typedef typename std::aligned_storage
|
||||
<
|
||||
meta::max<sizeof(Args)...>::value
|
||||
, meta::max<std::alignment_of<Args>::value...>::value
|
||||
>::type buffer_type;
|
||||
|
||||
friend bool operator==(variant<Args...> const& lhs, variant<Args...> const& rhs)
|
||||
{
|
||||
return rhs.type == lhs.type
|
||||
&& (rhs.type == -1
|
||||
|| rhs.visit(compare_equal_visitor{&lhs.buffer}));
|
||||
}
|
||||
|
||||
int type;
|
||||
/**
|
||||
* Member variable for holding the contained value.
|
||||
*/
|
||||
buffer_type buffer;
|
||||
};
|
||||
|
||||
template <typename...Args>
|
||||
inline bool operator!=(variant<Args...>const& lhs, variant<Args...> const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template <typename T, typename...Args>
|
||||
T* get(variant<Args...>* variant, typename std::enable_if<meta::is_one_of
|
||||
<typename std::remove_cv<typename std::remove_reference<T>::type>::type, Args...>::value>::type* = 0)
|
||||
{
|
||||
return variant->visit(get_visitor<T>{});
|
||||
}
|
||||
template <typename T, typename...Args>
|
||||
T const* get(variant<Args...>const* variant, typename std::enable_if<meta::is_one_of
|
||||
<typename std::remove_cv<typename std::remove_reference<T>::type>::type, Args...>::value>::type* = 0)
|
||||
{
|
||||
return variant->visit(get_visitor<T const>{});
|
||||
}
|
||||
template <typename T, typename...Args>
|
||||
T& get(variant<Args...>& variant, typename std::enable_if<meta::is_one_of
|
||||
<typename std::remove_cv<typename std::remove_reference<T>::type>::type, Args...>::value>::type* = 0)
|
||||
{
|
||||
T* p = variant.visit(get_visitor<T>{});
|
||||
if(p)
|
||||
return *p;
|
||||
else
|
||||
throw std::logic_error("");
|
||||
}
|
||||
template <typename T, typename...Args>
|
||||
T const& get(variant<Args...>const& variant, typename std::enable_if<meta::is_one_of
|
||||
<typename std::remove_cv<typename std::remove_reference<T>::type>::type, Args...>::value>::type* = 0)
|
||||
{
|
||||
T const* p = variant.visit(get_visitor<T const>{});
|
||||
if(p)
|
||||
return *p;
|
||||
else
|
||||
throw std::logic_error("");
|
||||
}
|
||||
|
||||
} } } }
|
||||
|
||||
#endif
|
|
@ -1,56 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <Eo.h>
|
||||
#include <Ecore.h>
|
||||
|
||||
#include "callback.eo.h"
|
||||
|
||||
struct _Callback_Data
|
||||
{
|
||||
int callbacks;
|
||||
};
|
||||
typedef struct _Callback_Data Callback_Data;
|
||||
|
||||
#define MY_CLASS CALLBACK_CLASS
|
||||
|
||||
static Eina_Bool _callback_callback_added(void* data EINA_UNUSED, Eo_Event const* event)
|
||||
{
|
||||
Callback_Data* pd = event->info;
|
||||
++pd->callbacks;
|
||||
eo_event_callback_call(event->object, CALLBACK_EVENT_CALL_ON_ADD, &pd->callbacks);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eo *_callback_eo_base_constructor(Eo *obj, Callback_Data *pd EINA_UNUSED)
|
||||
{
|
||||
pd->callbacks = 0;
|
||||
obj = eo_constructor(eo_super(obj, MY_CLASS));
|
||||
|
||||
eo_event_callback_priority_add(obj, EO_EVENT_CALLBACK_ADD, EO_CALLBACK_PRIORITY_DEFAULT
|
||||
, &_callback_callback_added, pd);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void _callback_onecallback(Eo *obj EINA_UNUSED, Callback_Data *pd EINA_UNUSED, Ecore_Cb cb, void *data)
|
||||
{
|
||||
cb(data);
|
||||
}
|
||||
|
||||
static void _callback_twocallback(Eo *obj EINA_UNUSED, Callback_Data *pd EINA_UNUSED, Ecore_Cb cb, void *data
|
||||
, Ecore_Cb cb2 EINA_UNUSED)
|
||||
{
|
||||
cb(data);
|
||||
}
|
||||
|
||||
static void _callback_test_global_callbacks(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED
|
||||
, Ecore_Cb cb, void *data)
|
||||
{
|
||||
cb(data);
|
||||
}
|
||||
|
||||
#include "callback.eo.c"
|
|
@ -1,33 +1,19 @@
|
|||
import ecore_types;
|
||||
|
||||
struct Callback_Event
|
||||
{
|
||||
field1: int;
|
||||
field2: list<int*>;
|
||||
}
|
||||
|
||||
class Callback (Eo.Base)
|
||||
{
|
||||
data: Callback_Data;
|
||||
methods {
|
||||
onecallback {
|
||||
params {
|
||||
@in cb: Ecore_Cb;
|
||||
@in data: void_ptr;
|
||||
}
|
||||
}
|
||||
twocallback {
|
||||
params {
|
||||
@in cb: Ecore_Cb;
|
||||
@in data: void_ptr;
|
||||
@in cb2: Ecore_Cb;
|
||||
}
|
||||
}
|
||||
test_global_callbacks @class {
|
||||
params {
|
||||
@in cb: Ecore_Cb;
|
||||
@in data: void_ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
implements {
|
||||
Eo.Base.constructor;
|
||||
}
|
||||
events {
|
||||
call_on_add;
|
||||
prefix,event1;
|
||||
prefix,event2: Callback;
|
||||
prefix,event3: int;
|
||||
prefix,event4: list<int*>;
|
||||
prefix,event5: Callback_Event;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <Eina.h>
|
||||
#include <Eo.h>
|
||||
|
||||
struct Complex_Data {};
|
||||
|
|
|
@ -2,6 +2,68 @@ class Complex (Eo.Base)
|
|||
{
|
||||
data: Complex_Data;
|
||||
methods {
|
||||
// container test
|
||||
inptrcont {
|
||||
params {
|
||||
l: list<int*>;
|
||||
}
|
||||
}
|
||||
inclasscont {
|
||||
params {
|
||||
l: list<Eo.Base>;
|
||||
}
|
||||
}
|
||||
inptrptrcont {
|
||||
params {
|
||||
l: list<int**>;
|
||||
}
|
||||
}
|
||||
inptrcontown {
|
||||
params {
|
||||
l: own(list<int*>);
|
||||
}
|
||||
}
|
||||
inptrptrcontown {
|
||||
params {
|
||||
l: own(list<int**>);
|
||||
}
|
||||
}
|
||||
incontcont {
|
||||
params {
|
||||
l: list<list<int*>>;
|
||||
}
|
||||
}
|
||||
incontcontown {
|
||||
params {
|
||||
l: own(list<list<int*>>);
|
||||
}
|
||||
}
|
||||
incontowncontown {
|
||||
params {
|
||||
l: own(list<own(list<int*>)>);
|
||||
}
|
||||
}
|
||||
incontowncont {
|
||||
params {
|
||||
l: list<own(list<int*>)>;
|
||||
}
|
||||
}
|
||||
instringcont {
|
||||
params {
|
||||
l: list<string>;
|
||||
}
|
||||
}
|
||||
instringowncont {
|
||||
params {
|
||||
l: list<own(string)>;
|
||||
}
|
||||
}
|
||||
instringcontown {
|
||||
params {
|
||||
l: own(list<string>);
|
||||
}
|
||||
}
|
||||
|
||||
foo {
|
||||
params {
|
||||
l: list<int*>;
|
||||
|
@ -28,6 +90,24 @@ class Complex (Eo.Base)
|
|||
@out a1: Complex;
|
||||
}
|
||||
}
|
||||
with_promise_r {
|
||||
return: promise<int>;
|
||||
}
|
||||
with_promise_in {
|
||||
params {
|
||||
@in p: promise<int>;
|
||||
}
|
||||
}
|
||||
with_promise_out {
|
||||
params {
|
||||
@out p: promise<int>;
|
||||
}
|
||||
}
|
||||
with_promise_inout {
|
||||
params {
|
||||
@inout p: promise<int>;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <Eina.h>
|
||||
#include <Eo.h>
|
||||
|
||||
#include "complex.eo.h"
|
||||
|
@ -32,9 +37,22 @@ struct test_param_type<void(T::*)(P), U>
|
|||
static_assert(std::is_same<P, U>::value, "Wrong type");
|
||||
};
|
||||
|
||||
test_param_type<typeof( & nonamespace::Complex::inptrcont ), efl::eina::range_list<int>> inptrcont;
|
||||
test_param_type<typeof( & nonamespace::Complex::inclasscont ), efl::eina::range_list<eo::Base>> inclasscont;
|
||||
test_param_type<typeof( & nonamespace::Complex::inptrptrcont ), efl::eina::range_list<int*>> inptrptrcont;
|
||||
test_param_type<typeof( & nonamespace::Complex::inptrcontown ), efl::eina::list<int>const&> inptrcontown;
|
||||
test_param_type<typeof( & nonamespace::Complex::inptrptrcontown ), efl::eina::list<int*>const&> inptrptrcontown;
|
||||
test_param_type<typeof( & nonamespace::Complex::incontcont ), efl::eina::range_list<efl::eina::range_list<int>>> incontont;
|
||||
test_param_type<typeof( & nonamespace::Complex::incontcontown ), efl::eina::list<efl::eina::range_list<int>>const&> incontcontown;
|
||||
test_param_type<typeof( & nonamespace::Complex::incontowncontown ), efl::eina::list<efl::eina::list<int>>const&> incontowncontown;
|
||||
test_param_type<typeof( & nonamespace::Complex::incontowncont ), efl::eina::range_list<efl::eina::list<int>>> incontowncont;
|
||||
test_param_type<typeof( & nonamespace::Complex::instringcont ), efl::eina::range_list<efl::eina::string_view>> instringcont;
|
||||
test_param_type<typeof( & nonamespace::Complex::instringowncont ), efl::eina::range_list<efl::eina::string_view>> instringowncont;
|
||||
test_param_type<typeof( & nonamespace::Complex::instringcontown ), efl::eina::list<efl::eina::string_view>const&> instringcontown;
|
||||
|
||||
test_param_type<typeof( & nonamespace::Complex::foo ), efl::eina::range_list<int>> foo;
|
||||
test_return_type<typeof( & nonamespace::Complex::bar ), efl::eina::range_array<int>> bar;
|
||||
test_return_type<typeof( & nonamespace::Complex::wrapper_r ), nonamespace::Complex> wrapper_r;
|
||||
test_param_type<typeof( & nonamespace::Complex::wrapper_in ), nonamespace::Complex> wrapper_in;
|
||||
test_param_type<typeof( & nonamespace::Complex::wrapper_inout ), nonamespace::Complex*> wrapper_inout;
|
||||
test_param_type<typeof( & nonamespace::Complex::wrapper_out ), nonamespace::Complex*> wrapper_out;
|
||||
test_param_type<typeof( & nonamespace::Complex::wrapper_inout ), nonamespace::Complex&> wrapper_inout;
|
||||
test_param_type<typeof( & nonamespace::Complex::wrapper_out ), nonamespace::Complex&> wrapper_out;
|
||||
|
|
|
@ -9,7 +9,6 @@ static const Efl_Test_Case etc[] = {
|
|||
{ "Eolian-Cxx Parsing", eolian_cxx_test_parse },
|
||||
{ "Eolian-Cxx Wrapper", eolian_cxx_test_wrapper },
|
||||
{ "Eolian-Cxx Generation", eolian_cxx_test_generate },
|
||||
{ "Eolian-Cxx Callback", eolian_cxx_test_callback },
|
||||
{ "Eolian-Cxx Address_of", eolian_cxx_test_address_of },
|
||||
{ "Eolian-Cxx Inheritance", eolian_cxx_test_inheritance },
|
||||
{ "Eolian-Cxx Binding", eolian_cxx_test_binding },
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
void eolian_cxx_test_parse(TCase* tc);
|
||||
void eolian_cxx_test_wrapper(TCase* tc);
|
||||
void eolian_cxx_test_generate(TCase* tc);
|
||||
void eolian_cxx_test_callback(TCase* tc);
|
||||
void eolian_cxx_test_address_of(TCase* tc);
|
||||
void eolian_cxx_test_inheritance(TCase* tc);
|
||||
void eolian_cxx_test_binding(TCase* tc);
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Ecore.h>
|
||||
|
||||
#include <generic.eo.hh>
|
||||
#include <name1_name2_type_generation.eo.hh>
|
||||
|
||||
#include "eolian_cxx_suite.h"
|
||||
|
||||
|
@ -10,18 +13,17 @@ START_TEST(eolian_cxx_test_binding_constructor_only_required)
|
|||
{
|
||||
efl::eo::eo_init i;
|
||||
|
||||
bool called1 = false;
|
||||
nonamespace::Generic g
|
||||
(
|
||||
[&]
|
||||
{
|
||||
g.required_ctor_a(1);
|
||||
g.required_ctor_b(2);
|
||||
}
|
||||
);
|
||||
|
||||
nonamespace::Generic g(
|
||||
g.required_ctor_a(1),
|
||||
g.required_ctor_b(std::bind([&called1] { called1 = true; }))
|
||||
);
|
||||
|
||||
g.call_req_ctor_b_callback();
|
||||
g.call_opt_ctor_b_callback();
|
||||
|
||||
fail_if(!called1);
|
||||
fail_if(1 != g.req_ctor_a_value_get());
|
||||
fail_if(2 != g.req_ctor_b_value_get());
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
@ -29,23 +31,142 @@ START_TEST(eolian_cxx_test_binding_constructor_all_optionals)
|
|||
{
|
||||
efl::eo::eo_init i;
|
||||
|
||||
bool called1 = false;
|
||||
bool called2 = false;
|
||||
nonamespace::Generic g
|
||||
(
|
||||
[&]
|
||||
{
|
||||
g.required_ctor_a(2);
|
||||
g.required_ctor_b(4);
|
||||
g.optional_ctor_a(3);
|
||||
g.optional_ctor_b(5);
|
||||
}
|
||||
);
|
||||
|
||||
nonamespace::Generic g(
|
||||
g.required_ctor_a(2),
|
||||
g.required_ctor_b(std::bind([&called1] { called1 = true; })),
|
||||
g.optional_ctor_a(3),
|
||||
g.optional_ctor_b(std::bind([&called2] { called2 = true; }))
|
||||
);
|
||||
|
||||
g.call_req_ctor_b_callback();
|
||||
g.call_opt_ctor_b_callback();
|
||||
|
||||
fail_if(!called1);
|
||||
fail_if(!called2);
|
||||
fail_if(2 != g.req_ctor_a_value_get());
|
||||
fail_if(3 != g.opt_ctor_a_value_get());
|
||||
fail_if(4 != g.req_ctor_b_value_get());
|
||||
fail_if(5 != g.opt_ctor_b_value_get());
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eolian_cxx_test_type_generation)
|
||||
{
|
||||
efl::eo::eo_init eo_init;
|
||||
|
||||
name1::name2::Type_Generation g;
|
||||
|
||||
g.invoidptr(nullptr);
|
||||
g.inint(42);
|
||||
std::unique_ptr<int> i (new int(42));
|
||||
g.inintptr(i.get());
|
||||
{
|
||||
int* p = (int*)malloc(sizeof(int));
|
||||
*p = 42;
|
||||
std::unique_ptr<int, void(*)(const void*)> inintptrown(p, (void(*)(const void*))&free);
|
||||
g.inintptrown(std::move(inintptrown));
|
||||
}
|
||||
{
|
||||
int** p = (int**)malloc(sizeof(int*));
|
||||
*p = (int*)malloc(sizeof(int));
|
||||
**p = 42;
|
||||
std::unique_ptr<int*, void(*)(const void*)> inintptrownptr(p, (void(*)(const void*))&free);
|
||||
g.inintptrownptr(std::move(inintptrownptr));
|
||||
}
|
||||
{
|
||||
int*** p = (int***)malloc(sizeof(int**));
|
||||
*p = (int**)malloc(sizeof(int*));
|
||||
**p = (int*)malloc(sizeof(int));
|
||||
***p = 42;
|
||||
std::unique_ptr<int**, void(*)(const void*)> inintptrownptrptr(p, (void(*)(const void*))&free);
|
||||
g.inintptrownptrptr(std::move(inintptrownptrptr));
|
||||
}
|
||||
{
|
||||
int*** p = (int***)malloc(sizeof(int**));
|
||||
*p = (int**)malloc(sizeof(int*));
|
||||
**p = (int*)malloc(sizeof(int));
|
||||
***p = 42;
|
||||
std::unique_ptr<int**, void(*)(const void*)> inintptrptrownptr(p, (void(*)(const void*))&free);
|
||||
g.inintptrptrownptr(std::move(inintptrptrownptr));
|
||||
}
|
||||
{
|
||||
int* p = (int*)malloc(sizeof(int));
|
||||
*p = 42;
|
||||
std::unique_ptr<int, void(*)(const void*)> inintptrownfree(p, (void(*)(const void*))&free);
|
||||
g.inintptrownfree(std::move(inintptrownfree));
|
||||
}
|
||||
g.instring("foobar");
|
||||
// {
|
||||
// efl::eina::string_view v("foobar");
|
||||
// g.instringptr(&v);
|
||||
// }
|
||||
g.instringown("foobar");
|
||||
// {
|
||||
// std::string v("foobar");
|
||||
// g.instringptrown(&v);
|
||||
// }
|
||||
// {
|
||||
// std::unique_ptr<efl::eina::string_view, void(*)(const void*)> v
|
||||
// ((efl::eina::string_view*)malloc(sizeof(string_view)), (void(*)(const void*))&free);
|
||||
// g.instringptrown(v);
|
||||
// }
|
||||
// {
|
||||
// std::string v("foobar");
|
||||
// g.instringptrown(&v);
|
||||
// }
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eolian_cxx_test_type_generation_in)
|
||||
{
|
||||
efl::eo::eo_init i;
|
||||
|
||||
name1::name2::Type_Generation g;
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eolian_cxx_test_type_callback)
|
||||
{
|
||||
efl::eo::eo_init i;
|
||||
|
||||
bool event1 = false, event2 = false, event3 = false, event4 = false
|
||||
, event5 = false;
|
||||
|
||||
nonamespace::Generic g;
|
||||
efl::eolian::event_add(g.prefix_event1_event, g, [&] (nonamespace::Generic)
|
||||
{
|
||||
event1 = true;
|
||||
});
|
||||
efl::eolian::event_add(g.prefix_event2_event, g, [&] (nonamespace::Generic, nonamespace::Generic)
|
||||
{
|
||||
event2 = true;
|
||||
});
|
||||
efl::eolian::event_add(g.prefix_event3_event, g, [&] (nonamespace::Generic, int v)
|
||||
{
|
||||
event3 = true;
|
||||
ck_assert(v == 42);
|
||||
});
|
||||
efl::eolian::event_add(g.prefix_event4_event, g, [&] (nonamespace::Generic, efl::eina::range_list<int> e)
|
||||
{
|
||||
event4 = true;
|
||||
ck_assert(e.size() == 1);
|
||||
ck_assert(*e.begin() == 42);
|
||||
});
|
||||
efl::eolian::event_add(g.prefix_event5_event, g, [&] (nonamespace::Generic, Generic_Event)
|
||||
{
|
||||
event5 = true;
|
||||
});
|
||||
|
||||
g.call_event1();
|
||||
g.call_event2();
|
||||
g.call_event3();
|
||||
g.call_event4();
|
||||
g.call_event5();
|
||||
|
||||
ck_assert(event1);
|
||||
ck_assert(event2);
|
||||
ck_assert(event3);
|
||||
ck_assert(event4);
|
||||
ck_assert(event5);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
@ -54,4 +175,7 @@ eolian_cxx_test_binding(TCase* tc)
|
|||
{
|
||||
tcase_add_test(tc, eolian_cxx_test_binding_constructor_only_required);
|
||||
tcase_add_test(tc, eolian_cxx_test_binding_constructor_all_optionals);
|
||||
tcase_add_test(tc, eolian_cxx_test_type_generation);
|
||||
tcase_add_test(tc, eolian_cxx_test_type_generation_in);
|
||||
tcase_add_test(tc, eolian_cxx_test_type_callback);
|
||||
}
|
||||
|
|
|
@ -1,184 +0,0 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
#include <Eo.h>
|
||||
#include <Ecore.h>
|
||||
|
||||
#include <callback.eo.hh>
|
||||
|
||||
#include "eolian_cxx_suite.h"
|
||||
|
||||
void foo(void*) {}
|
||||
|
||||
START_TEST(eolian_cxx_test_callback_method)
|
||||
{
|
||||
efl::eo::eo_init i;
|
||||
|
||||
nonamespace::Callback c;
|
||||
|
||||
bool called1 = false, called2 = false;
|
||||
|
||||
c.onecallback(std::bind([&called1] { called1 = true; }));
|
||||
c.twocallback(std::bind([&called2] { called2 = true; }), &foo);
|
||||
|
||||
fail_if(!called1);
|
||||
fail_if(!called2);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eolian_cxx_test_callback_event_add)
|
||||
{
|
||||
efl::eo::eo_init i;
|
||||
|
||||
nonamespace::Callback c;
|
||||
|
||||
bool called1 = false, called2 = false;
|
||||
|
||||
|
||||
c.callback_call_on_add_add(std::bind([&called1] { called1 = true; }));
|
||||
c.callback_call_on_add_add(std::bind([&called2] { called2 = true; }));
|
||||
|
||||
fail_if(!called1);
|
||||
fail_if(!called2);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eolian_cxx_test_callback_event_del)
|
||||
{
|
||||
efl::eo::eo_init i;
|
||||
|
||||
nonamespace::Callback c;
|
||||
|
||||
int called1 = 0, called2 = 0, called3 = 0, called4 = 0;
|
||||
|
||||
efl::eo::signal_connection s1 = c.callback_call_on_add_add
|
||||
(std::bind([&]
|
||||
{
|
||||
std::cerr << "called1 " << called1 << " called2 " << called2 << " called3 " << called3
|
||||
<< " called4 " << called4 << " 1" << std::endl;
|
||||
fail_if(!( (called1 == 0 && called2 == 0 && called3 == 0 && called4 == 0)
|
||||
|| (called1 == 1 && called2 == 1 && called3 == 0 && called4 == 0)
|
||||
));
|
||||
++called1;
|
||||
}));
|
||||
efl::eo::signal_connection s2 = c.callback_call_on_add_add
|
||||
(std::bind([&]
|
||||
{
|
||||
std::cerr << "called1 " << called1 << " called2 " << called2 << " called3 " << called3
|
||||
<< " called4 " << called4 << " 2" << std::endl;
|
||||
fail_if(!( (called1 == 1 && called2 == 0 && called3 == 0 && called4 == 0)
|
||||
|| (called1 == 1 && called2 == 1 && called3 == 0 && called4 == 0)
|
||||
|| (called1 == 2 && called2 == 1 && called3 == 1 && called4 == 0)
|
||||
));
|
||||
++called2;
|
||||
}));
|
||||
|
||||
s1.disconnect();
|
||||
|
||||
c.callback_call_on_add_add
|
||||
(
|
||||
std::bind([&]
|
||||
{
|
||||
std::cerr << "called1 " << called1 << " called2 " << called2 << " called3 " << called3
|
||||
<< " called4 " << called4 << " 3" << std::endl;
|
||||
fail_if(!( (called1 == 2 && called2 == 1 && called3 == 0 && called4 == 0)
|
||||
|| (called1 == 2 && called2 == 2 && called3 == 1 && called4 == 1)
|
||||
));
|
||||
++called3;
|
||||
}));
|
||||
|
||||
s2.disconnect();
|
||||
|
||||
c.callback_call_on_add_add
|
||||
(
|
||||
std::bind([&]
|
||||
{
|
||||
std::cerr << "called1 " << called1 << " called2 " << called2 << " called3 " << called3
|
||||
<< " called4 " << called4 << " 4" << std::endl;
|
||||
fail_if(!( (called1 == 2 && called2 == 2 && called3 == 1 && called4 == 0)
|
||||
));
|
||||
++called4;
|
||||
}));
|
||||
|
||||
fail_if(called1 != 2);
|
||||
fail_if(called2 != 2);
|
||||
fail_if(called3 != 2);
|
||||
fail_if(called4 != 1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eolian_cxx_test_global_callback)
|
||||
{
|
||||
efl::eo::eo_init i;
|
||||
|
||||
bool called = false;
|
||||
|
||||
nonamespace::Callback::test_global_callbacks(std::bind([&called] { called = true; }));
|
||||
|
||||
fail_if(!called);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eolian_cxx_test_disconnect_inside_callback)
|
||||
{
|
||||
efl::eo::eo_init i;
|
||||
nonamespace::Callback c;
|
||||
|
||||
std::vector<long> capture_me;
|
||||
int times_called = 0;
|
||||
|
||||
::efl::eo::signal_connection sig(nullptr);
|
||||
sig = c.callback_callback_add_add(
|
||||
std::bind([&sig, &capture_me, ×_called](void *info)
|
||||
{
|
||||
++times_called;
|
||||
std::cout << "times_called: " << times_called << std::endl;
|
||||
std::cout << "&sig: " << &sig << std::endl;
|
||||
if (times_called <= 1)
|
||||
return;
|
||||
|
||||
sig.disconnect();
|
||||
|
||||
long* info_l = static_cast<long*>(info);
|
||||
std::cout << "info: " << info << std::endl;
|
||||
std::cout << "*info_l: " << *info_l << std::endl;
|
||||
|
||||
fail_if(*info_l != 42);
|
||||
|
||||
capture_me = {9, 0, 8, 1, 7, 2, 6, 3, 5, 4};
|
||||
std::sort(capture_me.begin(), capture_me.end());
|
||||
|
||||
capture_me[0] = capture_me[1] + +capture_me[2] + capture_me[9];
|
||||
|
||||
std::cout << "&capture_me: " << &capture_me << std::endl;
|
||||
std::cout << "capture_me [0] [9]: [" << capture_me[0] << "] ["<< capture_me[9] << "]" << std::endl;
|
||||
|
||||
fail_if(capture_me.size() != 10);
|
||||
fail_if(capture_me[0] != 12);
|
||||
fail_if(times_called != 2);
|
||||
}, std::placeholders::_3));
|
||||
|
||||
long n = 42;
|
||||
c.callback_callback_add_call(&n);
|
||||
|
||||
fail_if(capture_me.size() != 10);
|
||||
fail_if(capture_me[0] != 12);
|
||||
fail_if(times_called != 2);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
void
|
||||
eolian_cxx_test_callback(TCase* tc)
|
||||
{
|
||||
tcase_add_test(tc, eolian_cxx_test_callback_method);
|
||||
tcase_add_test(tc, eolian_cxx_test_callback_event_add);
|
||||
tcase_add_test(tc, eolian_cxx_test_callback_event_del);
|
||||
tcase_add_test(tc, eolian_cxx_test_global_callback);
|
||||
tcase_add_test(tc, eolian_cxx_test_disconnect_inside_callback);
|
||||
}
|
|
@ -2,15 +2,69 @@
|
|||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
#include <Eolian_Cxx.hh>
|
||||
#include <iterator>
|
||||
|
||||
#include "eolian_cxx_suite.h"
|
||||
|
||||
#include <grammar/header.hpp>
|
||||
|
||||
START_TEST(eolian_cxx_test_generate_complex_types)
|
||||
{
|
||||
// TODO implement
|
||||
using efl::eolian::grammar::class_header;
|
||||
using efl::eolian::grammar::attributes::unused_type;
|
||||
using efl::eolian::grammar::attributes::regular_type_def;
|
||||
using efl::eolian::grammar::attributes::klass_name;
|
||||
using efl::eolian::grammar::attributes::complex_type_def;
|
||||
using efl::eolian::grammar::attributes::parameter_direction;
|
||||
using efl::eolian::grammar::attributes::qualifier_info;
|
||||
using efl::eolian::grammar::context_null;;
|
||||
|
||||
// efl::eolian::grammar::attributes::klass_def my_class
|
||||
// {
|
||||
// "Class_Name", "Class_Name", {"Namespace1", "Namesapce2"}
|
||||
// , {
|
||||
// {{regular_type_def{"int", {qualifier_info::is_none, {}}, {}}}
|
||||
// , "function_name"
|
||||
// , {
|
||||
// {parameter_direction::in, {regular_type_def{"unsigned", {qualifier_info::is_none, {}}, {}}}, "param1", ""}
|
||||
// , {parameter_direction::out, {klass_name{{"Namespace1","Namesapce2"}, "Class_Name",
|
||||
// {qualifier_info::is_none, {}}, {}, {}}}
|
||||
// , "param2", ""}
|
||||
// , {parameter_direction::inout, {complex_type_def
|
||||
// {{
|
||||
// {regular_type_def{"list", {qualifier_info::is_none, {}}, {}}}
|
||||
// , {regular_type_def{"int", {qualifier_info::is_none, {}}, {}}}
|
||||
// }}}
|
||||
// , "param3", ""}
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// , {}
|
||||
// , {}
|
||||
// };
|
||||
|
||||
// std::tuple<std::string, std::vector<std::string>
|
||||
// , std::vector<std::string>, std::vector<efl::eolian::grammar::attributes::klass_def>
|
||||
// , std::vector<efl::eolian::grammar::attributes::klass_def>
|
||||
// , std::vector<efl::eolian::grammar::attributes::klass_def>> attributes
|
||||
// {"GUARD_HEADER_HH", {"abc.h", "def.h"}, {"abc.hh", "def.hh"}, {my_class}, {my_class}, {my_class}};
|
||||
// std::vector<char> buffer;
|
||||
// class_header.generate(std::back_inserter<std::vector<char>>(buffer), attributes, context_null());
|
||||
|
||||
// const char result[] =
|
||||
// "#ifndef GUARD_HEADER_HH\n"
|
||||
// "#define GUARD_HEADER_HH\n"
|
||||
// "#endif\n"
|
||||
// ;
|
||||
|
||||
// std::cout << "Beginning of generated file" << std::endl;
|
||||
// std::copy(buffer.begin(), buffer.end(), std::ostream_iterator<char>(std::cout));
|
||||
// std::cout << "\n End of generated file" << std::endl;
|
||||
|
||||
// ck_assert(buffer.size() == (sizeof(result) - 1));
|
||||
// ck_assert(std::equal(buffer.begin(), buffer.end(), result));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
|
|
@ -9,35 +9,35 @@
|
|||
|
||||
#include "eolian_cxx_suite.h"
|
||||
|
||||
struct bar
|
||||
: efl::eo::inherit<bar, nonamespace::Simple>
|
||||
{
|
||||
bar()
|
||||
: inherit_base(efl::eo::parent = nullptr)
|
||||
{}
|
||||
// struct bar
|
||||
// : efl::eo::inherit<bar, nonamespace::Simple>
|
||||
// {
|
||||
// bar()
|
||||
// : inherit_base(efl::eo::parent = nullptr)
|
||||
// {}
|
||||
|
||||
bool simple_get()
|
||||
{
|
||||
printf("calling bar::%s\n", __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
// bool simple_get()
|
||||
// {
|
||||
// printf("calling bar::%s\n", __FUNCTION__);
|
||||
// return false;
|
||||
// }
|
||||
// };
|
||||
|
||||
void foo(nonamespace::Simple is)
|
||||
{
|
||||
fail_if(is.simple_get());
|
||||
}
|
||||
// void foo(nonamespace::Simple is)
|
||||
// {
|
||||
// fail_if(is.simple_get());
|
||||
// }
|
||||
|
||||
START_TEST(eolian_cxx_test_inheritance_simple)
|
||||
{
|
||||
efl::eo::eo_init i;
|
||||
bar b;
|
||||
foo(b);
|
||||
}
|
||||
END_TEST
|
||||
// START_TEST(eolian_cxx_test_inheritance_simple)
|
||||
// {
|
||||
// efl::eo::eo_init i;
|
||||
// bar b;
|
||||
// foo(b);
|
||||
// }
|
||||
// END_TEST
|
||||
|
||||
void
|
||||
eolian_cxx_test_inheritance(TCase* tc)
|
||||
eolian_cxx_test_inheritance(TCase* /*tc*/)
|
||||
{
|
||||
tcase_add_test(tc, eolian_cxx_test_inheritance_simple);
|
||||
// tcase_add_test(tc, eolian_cxx_test_inheritance_simple);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <Eo.h>
|
||||
#include <Ecore.h>
|
||||
|
||||
#include <callback.eo.hh>
|
||||
#include <a.eo.hh>
|
||||
|
||||
#include "eolian_cxx_suite.h"
|
||||
|
||||
|
@ -14,7 +14,7 @@ START_TEST(eolian_cxx_test_wrapper_size)
|
|||
efl::eo::eo_init init;
|
||||
|
||||
::efl::eo::concrete b(nullptr);
|
||||
::nonamespace::Callback c;
|
||||
::nonamespace::A c;
|
||||
|
||||
fail_if(sizeof(b) != sizeof(Eo*));
|
||||
fail_if(sizeof(b) != sizeof(c));
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
|
||||
#include "generic.eo.h"
|
||||
|
||||
#include <check.h>
|
||||
|
||||
struct _Generic_Data
|
||||
{
|
||||
int req_ctor_a_val;
|
||||
Ecore_Cb req_ctor_b_cb;
|
||||
void *req_ctor_b_data;
|
||||
int req_ctor_b_val;
|
||||
int opt_ctor_a_val;
|
||||
Ecore_Cb opt_ctor_b_cb;
|
||||
void *opt_ctor_b_data;
|
||||
int opt_ctor_b_val;
|
||||
};
|
||||
typedef struct _Generic_Data Generic_Data;
|
||||
|
||||
|
@ -23,11 +23,7 @@ typedef struct _Generic_Data Generic_Data;
|
|||
static Eo *_generic_eo_base_constructor(Eo *obj, Generic_Data *pd)
|
||||
{
|
||||
pd->req_ctor_a_val = 0;
|
||||
pd->req_ctor_b_cb = NULL;
|
||||
pd->req_ctor_b_data = NULL;
|
||||
pd->opt_ctor_a_val = 0;
|
||||
pd->opt_ctor_b_cb = NULL;
|
||||
pd->opt_ctor_b_data = NULL;
|
||||
return eo_constructor(eo_super(obj, MY_CLASS));
|
||||
}
|
||||
|
||||
|
@ -36,9 +32,9 @@ static void _generic_required_ctor_a(Eo *obj EINA_UNUSED, Generic_Data *pd, int
|
|||
pd->req_ctor_a_val = value;
|
||||
}
|
||||
|
||||
static void _generic_required_ctor_b(Eo *obj EINA_UNUSED, Generic_Data *pd EINA_UNUSED, Ecore_Cb cb, void *data)
|
||||
static void _generic_required_ctor_b(Eo *obj EINA_UNUSED, Generic_Data *pd EINA_UNUSED, int value)
|
||||
{
|
||||
cb(data);
|
||||
pd->req_ctor_b_val = value;
|
||||
}
|
||||
|
||||
static void _generic_optional_ctor_a(Eo *obj EINA_UNUSED, Generic_Data *pd, int value)
|
||||
|
@ -46,9 +42,9 @@ static void _generic_optional_ctor_a(Eo *obj EINA_UNUSED, Generic_Data *pd, int
|
|||
pd->opt_ctor_a_val = value;
|
||||
}
|
||||
|
||||
static void _generic_optional_ctor_b(Eo *obj EINA_UNUSED, Generic_Data *pd EINA_UNUSED, Ecore_Cb cb, void *data)
|
||||
static void _generic_optional_ctor_b(Eo *obj EINA_UNUSED, Generic_Data *pd EINA_UNUSED, int value)
|
||||
{
|
||||
cb(data);
|
||||
pd->opt_ctor_b_val = value;
|
||||
}
|
||||
|
||||
static int _generic_req_ctor_a_value_get(Eo *obj EINA_UNUSED, Generic_Data *pd)
|
||||
|
@ -56,21 +52,78 @@ static int _generic_req_ctor_a_value_get(Eo *obj EINA_UNUSED, Generic_Data *pd)
|
|||
return pd->req_ctor_a_val;
|
||||
}
|
||||
|
||||
static int _generic_req_ctor_b_value_get(Eo *obj EINA_UNUSED, Generic_Data *pd)
|
||||
{
|
||||
return pd->req_ctor_b_val;
|
||||
}
|
||||
|
||||
static int _generic_opt_ctor_a_value_get(Eo *obj EINA_UNUSED, Generic_Data *pd)
|
||||
{
|
||||
return pd->opt_ctor_a_val;
|
||||
}
|
||||
|
||||
static void _generic_call_req_ctor_b_callback(Eo *obj EINA_UNUSED, Generic_Data *pd)
|
||||
static int _generic_opt_ctor_b_value_get(Eo *obj EINA_UNUSED, Generic_Data *pd)
|
||||
{
|
||||
if (pd->req_ctor_b_cb)
|
||||
pd->req_ctor_b_cb(pd->req_ctor_b_data);
|
||||
return pd->opt_ctor_b_val;
|
||||
}
|
||||
|
||||
static void _generic_call_opt_ctor_b_callback(Eo *obj EINA_UNUSED, Generic_Data *pd)
|
||||
/* static void _generic_req_ctor_a_value_set(Eo *obj EINA_UNUSED, Generic_Data* pd EINA_UNUSED, int value EINA_UNUSED) */
|
||||
/* { */
|
||||
/* } */
|
||||
|
||||
/* static void _generic_opt_ctor_a_value_set(Eo *obj EINA_UNUSED, Generic_Data* pd EINA_UNUSED, int value EINA_UNUSED) */
|
||||
/* { */
|
||||
/* } */
|
||||
|
||||
static void _generic_out_required_ctor_a(Eo *obj EINA_UNUSED, Generic_Data* pd, int *value)
|
||||
{
|
||||
if (pd->opt_ctor_b_cb)
|
||||
pd->opt_ctor_b_cb(pd->opt_ctor_b_data);
|
||||
*value = pd->req_ctor_a_val;
|
||||
}
|
||||
|
||||
static void _generic_out_required_ctor_b(Eo *obj EINA_UNUSED, Generic_Data* pd, int *value)
|
||||
{
|
||||
*value = pd->req_ctor_b_val;
|
||||
}
|
||||
|
||||
static void _generic_out_optional_ctor_a(Eo *obj EINA_UNUSED, Generic_Data* pd, int *value)
|
||||
{
|
||||
*value = pd->opt_ctor_a_val;
|
||||
}
|
||||
|
||||
static void _generic_out_optional_ctor_b(Eo *obj EINA_UNUSED, Generic_Data* pd, int *value)
|
||||
{
|
||||
*value = pd->opt_ctor_b_val;
|
||||
}
|
||||
|
||||
static void _generic_call_event1(Eo *obj, Generic_Data* pd EINA_UNUSED)
|
||||
{
|
||||
eo_event_callback_call(obj, GENERIC_EVENT_PREFIX_EVENT1, NULL);
|
||||
}
|
||||
static void _generic_call_event2(Eo *obj, Generic_Data* pd EINA_UNUSED)
|
||||
{
|
||||
eo_event_callback_call(obj, GENERIC_EVENT_PREFIX_EVENT2, obj);
|
||||
}
|
||||
static void _generic_call_event3(Eo *obj, Generic_Data* pd EINA_UNUSED)
|
||||
{
|
||||
int p = 42;
|
||||
eo_event_callback_call(obj, GENERIC_EVENT_PREFIX_EVENT3, &p);
|
||||
}
|
||||
static void _generic_call_event4(Eo *obj, Generic_Data* pd EINA_UNUSED)
|
||||
{
|
||||
int i = 42;
|
||||
Eina_List* p = eina_list_append(NULL, &i);
|
||||
ck_assert(p != NULL);
|
||||
eo_event_callback_call(obj, GENERIC_EVENT_PREFIX_EVENT4, p);
|
||||
eina_list_free(p);
|
||||
}
|
||||
static void _generic_call_event5(Eo *obj, Generic_Data* pd EINA_UNUSED)
|
||||
{
|
||||
int i = 42;
|
||||
Eina_List* p = eina_list_append(NULL, &i);
|
||||
|
||||
Generic_Event e = {.field1 = 42, .field2 = p};
|
||||
eo_event_callback_call(obj, GENERIC_EVENT_PREFIX_EVENT5, &e);
|
||||
eina_list_free(p);
|
||||
}
|
||||
|
||||
#include "generic.eo.c"
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import ecore_types;
|
||||
|
||||
struct Generic.Event
|
||||
{
|
||||
field1: int;
|
||||
field2: list<int*>;
|
||||
}
|
||||
|
||||
class Generic (Eo.Base)
|
||||
{
|
||||
|
@ -25,8 +30,7 @@ class Generic (Eo.Base)
|
|||
}
|
||||
required_ctor_b {
|
||||
params {
|
||||
@in cb: Ecore_Cb;
|
||||
@in data: void_ptr;
|
||||
@in value: int;
|
||||
}
|
||||
}
|
||||
optional_ctor_a {
|
||||
|
@ -36,13 +40,52 @@ class Generic (Eo.Base)
|
|||
}
|
||||
optional_ctor_b {
|
||||
params {
|
||||
@in cb: Ecore_Cb;
|
||||
@in data: void_ptr;
|
||||
@in value: int;
|
||||
}
|
||||
}
|
||||
call_req_ctor_b_callback {
|
||||
|
||||
@property req_ctor_b_value {
|
||||
get {}
|
||||
values {
|
||||
value: int;
|
||||
}
|
||||
}
|
||||
call_opt_ctor_b_callback {
|
||||
@property opt_ctor_b_value {
|
||||
get {}
|
||||
values {
|
||||
value: int;
|
||||
}
|
||||
}
|
||||
out_required_ctor_a {
|
||||
params {
|
||||
@out value: int;
|
||||
}
|
||||
}
|
||||
out_required_ctor_b {
|
||||
params {
|
||||
@out value: int;
|
||||
}
|
||||
}
|
||||
out_optional_ctor_a {
|
||||
params {
|
||||
@out value: int;
|
||||
}
|
||||
}
|
||||
out_optional_ctor_b {
|
||||
params {
|
||||
@out value: int;
|
||||
}
|
||||
}
|
||||
|
||||
call_event1 {
|
||||
}
|
||||
call_event2 {
|
||||
}
|
||||
call_event3 {
|
||||
}
|
||||
call_event4 {
|
||||
}
|
||||
call_event5 {
|
||||
}
|
||||
}
|
||||
constructors {
|
||||
|
@ -54,4 +97,11 @@ class Generic (Eo.Base)
|
|||
implements {
|
||||
Eo.Base.constructor;
|
||||
}
|
||||
events {
|
||||
prefix,event1;
|
||||
prefix,event2: Generic;
|
||||
prefix,event3: int;
|
||||
prefix,event4: list<int*>;
|
||||
prefix,event5: Generic.Event;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,240 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Eo.h>
|
||||
#include <Ecore.h>
|
||||
|
||||
#include <check.h>
|
||||
|
||||
struct _Type_Generation_Data
|
||||
{
|
||||
};
|
||||
typedef struct _Type_Generation_Data Type_Generation_Data;
|
||||
|
||||
#define MY_CLASS TYPE1_TYPE2_TYPE_GENERATION_CLASS
|
||||
|
||||
#include "name1_name2_type_generation.eo.h"
|
||||
|
||||
void _name1_name2_type_generation_invoidptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, void *v)
|
||||
{
|
||||
ck_assert(v == NULL);
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_inint(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int v EINA_UNUSED)
|
||||
{
|
||||
ck_assert(v == 42);
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_inintptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int *v EINA_UNUSED)
|
||||
{
|
||||
ck_assert(*v == 42);
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_inintptrown(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int *v EINA_UNUSED)
|
||||
{
|
||||
ck_assert(*v == 42);
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_inintptrownptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int **v EINA_UNUSED)
|
||||
{
|
||||
ck_assert(**v == 42);
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_inintptrownptrptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int ***v EINA_UNUSED)
|
||||
{
|
||||
ck_assert(***v == 42);
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_inintptrptrownptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int ***v EINA_UNUSED)
|
||||
{
|
||||
ck_assert(***v == 42);
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_inintptrownfree(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int *v EINA_UNUSED)
|
||||
{
|
||||
ck_assert(*v == 42);
|
||||
}
|
||||
|
||||
void * _name1_name2_type_generation_returnvoidptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_instring(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, const char *v EINA_UNUSED)
|
||||
{
|
||||
ck_assert_str_eq(v, "foobar");
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_instringptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, const char * *v EINA_UNUSED)
|
||||
{
|
||||
ck_assert_str_eq(*v, "foobar");
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_instringown(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, const char *v EINA_UNUSED)
|
||||
{
|
||||
ck_assert_str_eq(v, "foobar");
|
||||
free((void*)v);
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_instringownptrown(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, const char **v EINA_UNUSED)
|
||||
{
|
||||
ck_assert_str_eq(*v, "foobar");
|
||||
free(v);
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_instringownptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, const char * *v EINA_UNUSED)
|
||||
{
|
||||
ck_assert_str_eq(*v, "foobar");
|
||||
free(v);
|
||||
}
|
||||
|
||||
int _name1_name2_type_generation_returnint(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED)
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
int * _name1_name2_type_generation_returnintptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int * _name1_name2_type_generation_returnintptrown(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ** _name1_name2_type_generation_returnintptrownptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int *** _name1_name2_type_generation_returnintptrownptrptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int *** _name1_name2_type_generation_returnintptrptrownptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_returnintptrownfree(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int *v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
const char * _name1_name2_type_generation_returnstring(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED)
|
||||
{
|
||||
return "foobar";
|
||||
}
|
||||
|
||||
const char * * _name1_name2_type_generation_returnstringptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED)
|
||||
{
|
||||
static const char* foobar = "foobar";
|
||||
return &foobar;
|
||||
}
|
||||
|
||||
const char * _name1_name2_type_generation_returnstringown(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED)
|
||||
{
|
||||
const char foobar[] = "foobar";
|
||||
char* p = malloc(sizeof(foobar));
|
||||
memcpy(p, foobar, sizeof(foobar));
|
||||
return p;
|
||||
}
|
||||
|
||||
const char * * _name1_name2_type_generation_returnstringownptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED)
|
||||
{
|
||||
const char foobar[] = "foobar";
|
||||
char** p1 = malloc(sizeof(const char*));
|
||||
char* p = malloc(sizeof(foobar));
|
||||
memcpy(p, foobar, sizeof(foobar));
|
||||
|
||||
*p1 = p;
|
||||
return (const char**)p1;
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_outvoidptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, void **v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_outint(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int *v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_outintptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int **v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_outintptrown(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int **v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_outintptrownfree(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int **v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_inclassname(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, Name1_Name2_Type_Generation *v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_outclassname(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, Name1_Name2_Type_Generation **v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_inoutclassname(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, Name1_Name2_Type_Generation **v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_optionalinvoidptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, void *v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_optionalinint(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_optionalinintptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int *v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_optionalinintptrown(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int *v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_optionalinintptrownfree(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int *v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_optionaloutvoidptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, void **v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_optionaloutint(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int *v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_optionaloutintptr(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int **v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_optionaloutintptrown(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int **v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_optionaloutintptrownfree(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, int **v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_optionalinclassname(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, Name1_Name2_Type_Generation *v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_optionaloutclassname(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, Name1_Name2_Type_Generation **v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
void _name1_name2_type_generation_optionalinoutclassname(Eo *obj EINA_UNUSED, Type_Generation_Data *pd EINA_UNUSED, Name1_Name2_Type_Generation **v EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
#include "name1_name2_type_generation.eo.c"
|
|
@ -0,0 +1,220 @@
|
|||
class Name1.Name2.Type_Generation (Eo.Base)
|
||||
{
|
||||
data: Type_Generation_Data;
|
||||
methods {
|
||||
// in void ptr
|
||||
invoidptr {
|
||||
params {
|
||||
@in v: void*;
|
||||
}
|
||||
}
|
||||
inint {
|
||||
params {
|
||||
@in v: int;
|
||||
}
|
||||
}
|
||||
inintptr {
|
||||
params {
|
||||
@in v: int*;
|
||||
}
|
||||
}
|
||||
inintptrown {
|
||||
params {
|
||||
@in v: own(int*);
|
||||
}
|
||||
}
|
||||
inintptrownptr {
|
||||
params {
|
||||
@in v: own(int*)*;
|
||||
}
|
||||
}
|
||||
inintptrownptrptr {
|
||||
params {
|
||||
@in v: own(int*)**;
|
||||
}
|
||||
}
|
||||
inintptrptrownptr {
|
||||
params {
|
||||
@in v: own(int**)*;
|
||||
}
|
||||
}
|
||||
inintptrownfree {
|
||||
params {
|
||||
@in v: free(own(int*), free);
|
||||
}
|
||||
}
|
||||
instring {
|
||||
params {
|
||||
@in v: string;
|
||||
}
|
||||
}
|
||||
/*
|
||||
instringptr {
|
||||
params {
|
||||
@in v: string*;
|
||||
}
|
||||
}*/
|
||||
instringown {
|
||||
params {
|
||||
@in v: own(string);
|
||||
}
|
||||
}
|
||||
/* no sense
|
||||
instringptrown {
|
||||
params {
|
||||
@in v: own(string*);
|
||||
}
|
||||
}
|
||||
instringownptrown {
|
||||
params {
|
||||
@in v: own(own(string)*);
|
||||
}
|
||||
}*/
|
||||
// return
|
||||
returnvoidptr {
|
||||
return: void*;
|
||||
}
|
||||
returnint {
|
||||
return: int;
|
||||
}
|
||||
returnintptr {
|
||||
return: int*;
|
||||
}
|
||||
returnintptrown {
|
||||
return: own(int*);
|
||||
}
|
||||
returnintptrownptr {
|
||||
return: own(int*)*;
|
||||
}
|
||||
returnintptrownptrptr {
|
||||
return: own(int*)**;
|
||||
}
|
||||
returnintptrptrownptr {
|
||||
return: own(int**)*;
|
||||
}
|
||||
returnintptrownfree {
|
||||
params {
|
||||
@in v: free(own(int*), free);
|
||||
}
|
||||
}
|
||||
returnstring {
|
||||
return: string;
|
||||
}
|
||||
returnstringptr {
|
||||
return: string*;
|
||||
}
|
||||
returnstringown {
|
||||
return: own(string);
|
||||
}
|
||||
returnstringownptr {
|
||||
return: own(string*);
|
||||
}
|
||||
|
||||
// out
|
||||
outvoidptr {
|
||||
params {
|
||||
@out v: void*;
|
||||
}
|
||||
}
|
||||
outint {
|
||||
params {
|
||||
@out v: int;
|
||||
}
|
||||
}
|
||||
outintptr {
|
||||
params {
|
||||
@out v: int*;
|
||||
}
|
||||
}
|
||||
outintptrown {
|
||||
params {
|
||||
@out v: own(int*);
|
||||
}
|
||||
}
|
||||
outintptrownfree {
|
||||
params {
|
||||
@out v: free(own(int*), free);
|
||||
}
|
||||
}
|
||||
inclassname {
|
||||
params {
|
||||
@in v: Name1.Name2.Type_Generation;
|
||||
}
|
||||
}
|
||||
outclassname {
|
||||
params {
|
||||
@out v: Name1.Name2.Type_Generation;
|
||||
}
|
||||
}
|
||||
inoutclassname {
|
||||
params {
|
||||
@inout v: Name1.Name2.Type_Generation;
|
||||
}
|
||||
}
|
||||
optionalinvoidptr {
|
||||
params {
|
||||
@in v: void* @optional;
|
||||
}
|
||||
}
|
||||
optionalinint {
|
||||
params {
|
||||
@in v: int @optional;
|
||||
}
|
||||
}
|
||||
optionalinintptr {
|
||||
params {
|
||||
@in v: int* @optional;
|
||||
}
|
||||
}
|
||||
optionalinintptrown {
|
||||
params {
|
||||
@in v: own(int*) @optional;
|
||||
}
|
||||
}
|
||||
optionalinintptrownfree {
|
||||
params {
|
||||
@in v: free(own(int*), free) @optional;
|
||||
}
|
||||
}
|
||||
optionaloutvoidptr {
|
||||
params {
|
||||
@out v: void* @optional;
|
||||
}
|
||||
}
|
||||
optionaloutint {
|
||||
params {
|
||||
@out v: int @optional;
|
||||
}
|
||||
}
|
||||
optionaloutintptr {
|
||||
params {
|
||||
@out v: int* @optional;
|
||||
}
|
||||
}
|
||||
optionaloutintptrown {
|
||||
params {
|
||||
@out v: own(int*) @optional;
|
||||
}
|
||||
}
|
||||
optionaloutintptrownfree {
|
||||
params {
|
||||
@out v: free(own(int*), free) @optional;
|
||||
}
|
||||
}
|
||||
optionalinclassname {
|
||||
params {
|
||||
@in v: Name1.Name2.Type_Generation @optional;
|
||||
}
|
||||
}
|
||||
optionaloutclassname {
|
||||
params {
|
||||
@out v: Name1.Name2.Type_Generation @optional;
|
||||
}
|
||||
}
|
||||
optionalinoutclassname {
|
||||
params {
|
||||
@inout v: Name1.Name2.Type_Generation @optional;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,8 @@
|
|||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <Eo.h>
|
||||
|
||||
#include "name_name.eo.h"
|
||||
|
|
Loading…
Reference in New Issue