aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2016-06-06 02:54:36 -0300
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2016-06-06 02:54:36 -0300
commit2a3d7860dbc11458425e162cd69ee399e9025251 (patch)
tree84c5b21b644c4cf8806a8eee07b4ed81922c92b4
parenteina-cxx: Add placeholder for futures in C++ binding (diff)
downloadefl-2a3d7860dbc11458425e162cd69ee399e9025251.tar.gz
eolian-cxx: Rewrite to accomodate new features of the C++ binding
-rw-r--r--src/Makefile_Cxx.am13
-rw-r--r--src/Makefile_Eolian_Cxx.am87
-rw-r--r--src/bin/eolian_cxx/convert.cc373
-rw-r--r--src/bin/eolian_cxx/convert.hh19
-rw-r--r--src/bin/eolian_cxx/convert_comments.cc95
-rw-r--r--src/bin/eolian_cxx/convert_comments.hh46
-rw-r--r--src/bin/eolian_cxx/eolian_cxx.cc258
-rw-r--r--src/bin/eolian_cxx/eolian_wrappers.hh430
-rw-r--r--src/bin/eolian_cxx/safe_strings.hh160
-rw-r--r--src/bin/eolian_cxx/type_lookup.hh160
-rw-r--r--src/bin/eolian_cxx/type_lookup_table.cc36
-rw-r--r--src/bindings/cxx/eo_cxx/Eo.hh5
-rw-r--r--src/bindings/cxx/eo_cxx/eo_concrete.hh110
-rw-r--r--src/bindings/cxx/eo_cxx/eo_cxx_interop.hh751
-rw-r--r--src/bindings/cxx/eo_cxx/eo_event.hh71
-rw-r--r--src/bindings/cxx/eo_cxx/eo_inherit.hh308
-rw-r--r--src/examples/elementary/bg_cxx_example_01.cc13
-rw-r--r--src/examples/elementary/button_cxx_example_00.cc25
-rw-r--r--src/examples/eolian_cxx/Makefile.am14
-rw-r--r--src/examples/eolian_cxx/colourable.c1
-rw-r--r--src/examples/eolian_cxx/colourable_cxx.cc1
-rw-r--r--src/examples/eolian_cxx/colourablesquare.c1
-rw-r--r--src/examples/eolian_cxx/colourablesquare_cxx.cc1
-rw-r--r--src/examples/eolian_cxx/eolian_cxx_simple_01.cc12
-rw-r--r--src/examples/eolian_cxx/ns_colourable.eo1
-rw-r--r--src/examples/eolian_cxx/ns_colourablesquare.eo1
-rw-r--r--src/lib/eolian_cxx/Eolian_Cxx.hh8
-rw-r--r--src/lib/eolian_cxx/eo_generate.hh23
-rw-r--r--src/lib/eolian_cxx/eo_types.hh350
-rw-r--r--src/lib/eolian_cxx/eo_validate.hh116
-rw-r--r--src/lib/eolian_cxx/grammar/address_of.hpp74
-rw-r--r--src/lib/eolian_cxx/grammar/alternative.hpp52
-rw-r--r--src/lib/eolian_cxx/grammar/attribute_conditional.hpp66
-rw-r--r--src/lib/eolian_cxx/grammar/attribute_reorder.hpp87
-rw-r--r--src/lib/eolian_cxx/grammar/attribute_replace.hpp63
-rw-r--r--src/lib/eolian_cxx/grammar/attributes.hpp185
-rw-r--r--src/lib/eolian_cxx/grammar/base_class_definition.hpp112
-rw-r--r--src/lib/eolian_cxx/grammar/c_type.hpp74
-rw-r--r--src/lib/eolian_cxx/grammar/case.hpp86
-rw-r--r--src/lib/eolian_cxx/grammar/class_declaration.hpp56
-rw-r--r--src/lib/eolian_cxx/grammar/class_definition.hpp176
-rw-r--r--src/lib/eolian_cxx/grammar/class_implementation.hpp56
-rw-r--r--src/lib/eolian_cxx/grammar/comment.hh45
-rw-r--r--src/lib/eolian_cxx/grammar/container.hpp46
-rw-r--r--src/lib/eolian_cxx/grammar/context.hpp46
-rw-r--r--src/lib/eolian_cxx/grammar/converting_argument.hpp47
-rw-r--r--src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh603
-rw-r--r--src/lib/eolian_cxx/grammar/eo_class_events_generator.hh117
-rw-r--r--src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh173
-rw-r--r--src/lib/eolian_cxx/grammar/eo_class_generator.hh265
-rw-r--r--src/lib/eolian_cxx/grammar/eo_class_scope_guard_generator.hh65
-rw-r--r--src/lib/eolian_cxx/grammar/eo_header_generator.hh150
-rw-r--r--src/lib/eolian_cxx/grammar/eps.hpp24
-rw-r--r--src/lib/eolian_cxx/grammar/function_declaration.hpp39
-rw-r--r--src/lib/eolian_cxx/grammar/function_definition.hpp155
-rw-r--r--src/lib/eolian_cxx/grammar/generator.hpp50
-rw-r--r--src/lib/eolian_cxx/grammar/header.hpp38
-rw-r--r--src/lib/eolian_cxx/grammar/header_guards.hpp79
-rw-r--r--src/lib/eolian_cxx/grammar/header_include_directive.hpp34
-rw-r--r--src/lib/eolian_cxx/grammar/impl_header.hpp21
-rw-r--r--src/lib/eolian_cxx/grammar/implementation_include_directive.hpp39
-rw-r--r--src/lib/eolian_cxx/grammar/indentation.hpp50
-rw-r--r--src/lib/eolian_cxx/grammar/inheritance_base_generator.hh339
-rw-r--r--src/lib/eolian_cxx/grammar/keyword.hpp15
-rw-r--r--src/lib/eolian_cxx/grammar/klass_def.hpp704
-rw-r--r--src/lib/eolian_cxx/grammar/kleene.hpp47
-rw-r--r--src/lib/eolian_cxx/grammar/list.hpp52
-rw-r--r--src/lib/eolian_cxx/grammar/meta.hpp42
-rw-r--r--src/lib/eolian_cxx/grammar/namespace.hpp67
-rw-r--r--src/lib/eolian_cxx/grammar/namespace_generator.hh68
-rw-r--r--src/lib/eolian_cxx/grammar/parameter.hpp78
-rw-r--r--src/lib/eolian_cxx/grammar/parameters_generator.hh453
-rw-r--r--src/lib/eolian_cxx/grammar/qualifier_def.hpp178
-rw-r--r--src/lib/eolian_cxx/grammar/sequence.hpp136
-rw-r--r--src/lib/eolian_cxx/grammar/string.hpp185
-rw-r--r--src/lib/eolian_cxx/grammar/tab.hh30
-rw-r--r--src/lib/eolian_cxx/grammar/type.hpp40
-rw-r--r--src/lib/eolian_cxx/grammar/type_generator.hh266
-rw-r--r--src/lib/eolian_cxx/grammar/type_impl.hpp333
-rw-r--r--src/lib/eolian_cxx/grammar/type_traits.hpp63
-rw-r--r--src/lib/eolian_cxx/grammar/variant.hpp276
-rw-r--r--src/tests/eolian_cxx/callback.c56
-rw-r--r--src/tests/eolian_cxx/callback.eo36
-rw-r--r--src/tests/eolian_cxx/complex.c5
-rw-r--r--src/tests/eolian_cxx/complex.eo80
-rw-r--r--src/tests/eolian_cxx/complex_cxx.cc22
-rw-r--r--src/tests/eolian_cxx/eolian_cxx_suite.cc1
-rw-r--r--src/tests/eolian_cxx/eolian_cxx_suite.h1
-rw-r--r--src/tests/eolian_cxx/eolian_cxx_test_binding.cc172
-rw-r--r--src/tests/eolian_cxx/eolian_cxx_test_callback.cc184
-rw-r--r--src/tests/eolian_cxx/eolian_cxx_test_generate.cc60
-rw-r--r--src/tests/eolian_cxx/eolian_cxx_test_inheritance.cc56
-rw-r--r--src/tests/eolian_cxx/eolian_cxx_test_wrapper.cc4
-rw-r--r--src/tests/eolian_cxx/generic.c89
-rw-r--r--src/tests/eolian_cxx/generic.eo64
-rw-r--r--src/tests/eolian_cxx/name1_name2_type_generation.c240
-rw-r--r--src/tests/eolian_cxx/name1_name2_type_generation.eo220
-rw-r--r--src/tests/eolian_cxx/name_name_cxx.cc4
98 files changed, 5737 insertions, 5591 deletions
diff --git a/src/Makefile_Cxx.am b/src/Makefile_Cxx.am
index 9a199bd5f9..4343b5d875 100644
--- a/src/Makefile_Cxx.am
+++ b/src/Makefile_Cxx.am
@@ -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_cxx_interop.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.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_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 \
diff --git a/src/Makefile_Eolian_Cxx.am b/src/Makefile_Eolian_Cxx.am
index 57dc265b97..981cca5bb2 100644
--- a/src/Makefile_Eolian_Cxx.am
+++ b/src/Makefile_Eolian_Cxx.am
@@ -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
diff --git a/src/bin/eolian_cxx/convert.cc b/src/bin/eolian_cxx/convert.cc
deleted file mode 100644
index 97e88c9171..0000000000
--- a/src/bin/eolian_cxx/convert.cc
+++ /dev/null
@@ -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 {
diff --git a/src/bin/eolian_cxx/convert.hh b/src/bin/eolian_cxx/convert.hh
deleted file mode 100644
index df829f4afe..0000000000
--- a/src/bin/eolian_cxx/convert.hh
+++ /dev/null
@@ -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
diff --git a/src/bin/eolian_cxx/convert_comments.cc b/src/bin/eolian_cxx/convert_comments.cc
deleted file mode 100644
index 94fed90c72..0000000000
--- a/src/bin/eolian_cxx/convert_comments.cc
+++ /dev/null
@@ -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
diff --git a/src/bin/eolian_cxx/convert_comments.hh b/src/bin/eolian_cxx/convert_comments.hh
deleted file mode 100644
index 788362e4be..0000000000
--- a/src/bin/eolian_cxx/convert_comments.hh
+++ /dev/null
@@ -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
diff --git a/src/bin/eolian_cxx/eolian_cxx.cc b/src/bin/eolian_cxx/eolian_cxx.cc
index d7f3d935b5..12cd5f4ee6 100644
--- a/src/bin/eolian_cxx/eolian_cxx.cc
+++ b/src/bin/eolian_cxx/eolian_cxx.cc
@@ -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);
-
- 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);
+ efl::eolian::grammar::attributes::klass_def klass_def(klass);
+ std::vector<efl::eolian::grammar::attributes::klass_def> klasses{klass_def};
+
+ 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)
+ {
+ 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);
+ };
- if (!opts.out_dir.empty())
+ std::function<void(Eolian_Class const*)> klass_function
+ = [&] (Eolian_Class const* klass)
{
- header_decl_file_name = opts.out_dir + "/" + header_decl_file_name;
- header_impl_file_name = opts.out_dir + "/" + header_impl_file_name;
- }
+ 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;
}
+#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]);
diff --git a/src/bin/eolian_cxx/eolian_wrappers.hh b/src/bin/eolian_cxx/eolian_wrappers.hh
deleted file mode 100644
index c2b8f66a14..0000000000
--- a/src/bin/eolian_cxx/eolian_wrappers.hh
+++ /dev/null
@@ -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(&parameter)) + "_";
-}
-
-inline bool
-parameter_is_out(Eolian_Function_Parameter const& parameter)
-{
- Eolian_Parameter_Dir direction = eolian_parameter_direction_get(&parameter);
- 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(&parameter)));
- 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(&parameter) ||
- ::eolian_parameter_is_nullable(&parameter);
- 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
diff --git a/src/bin/eolian_cxx/safe_strings.hh b/src/bin/eolian_cxx/safe_strings.hh
deleted file mode 100644
index 4601af6b85..0000000000
--- a/src/bin/eolian_cxx/safe_strings.hh
+++ /dev/null
@@ -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
diff --git a/src/bin/eolian_cxx/type_lookup.hh b/src/bin/eolian_cxx/type_lookup.hh
deleted file mode 100644
index 9410bdf358..0000000000
--- a/src/bin/eolian_cxx/type_lookup.hh
+++ /dev/null
@@ -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
diff --git a/src/bin/eolian_cxx/type_lookup_table.cc b/src/bin/eolian_cxx/type_lookup_table.cc
deleted file mode 100644
index 046b8b8744..0000000000
--- a/src/bin/eolian_cxx/type_lookup_table.cc
+++ /dev/null
@@ -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"}},
-};
-
-}
diff --git a/src/bindings/cxx/eo_cxx/Eo.hh b/src/bindings/cxx/eo_cxx/Eo.hh
index a6f0423724..b7d1e856a3 100644
--- a/src/bindings/cxx/eo_cxx/Eo.hh
+++ b/src/bindings/cxx/eo_cxx/Eo.hh
@@ -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
diff --git a/src/bindings/cxx/eo_cxx/eo_concrete.hh b/src/bindings/cxx/eo_cxx/eo_concrete.hh
index c975bbc5e3..11d2c5b5da 100644
--- a/src/bindings/cxx/eo_cxx/eo_concrete.hh
+++ b/src/bindings/cxx/eo_cxx/eo_concrete.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 {
diff --git a/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh b/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh
index a588b5b8e1..a19bb24226 100644
--- a/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh
+++ b/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh
@@ -7,6 +7,7 @@
#include <utility>
#include <type_traits>
#include <initializer_list>
+#include <future>
#include <Eina.hh>
#include <Eo.hh>
@@ -15,519 +16,537 @@
namespace efl { namespace eolian {
-//// From C++ to C
+template <typename T, typename Enable = void>
+struct in_traits { typedef T const& type; };
+template <typename T>
+struct in_traits<T, typename std::enable_if<eo::is_eolian_object<T>::value>::type> { typedef T type; };
+template <typename T>
+struct in_traits<T, typename std::enable_if<std::is_fundamental<T>::value>::type> { typedef T type; };
+template <>
+struct in_traits<eina::string_view> { typedef eina::string_view type; };
+template <>
+struct in_traits<eina::string_view const> { typedef eina::string_view const type; };
+template <typename T>
+struct in_traits<T&> { typedef T& type; };
+template <typename T>
+struct in_traits<T*> { typedef T* type; };
+template <typename T, typename D>
+struct in_traits<std::unique_ptr<T, D>> { typedef std::unique_ptr<T, D> type; };
-inline const char*
-to_c(std::string const& x)
+template <typename T>
+struct in_traits<eina::range_list<T>> { typedef eina::range_list<T> type; };
+template <typename T>
+struct in_traits<eina::range_array<T>> { typedef eina::range_array<T> type; };
+
+template <typename T>
+struct out_traits { typedef T type; };
+template <typename T>
+struct out_traits<efl::eina::future<T>> { typedef efl::eina::future<T>& type; };
+
+template <typename T>
+struct inout_traits { typedef T type; };
+template <typename T>
+struct inout_traits<efl::eina::future<T>> { typedef efl::eina::future<T>& type; };
+
+namespace impl {
+
+template <typename From, typename To>
+struct tag
{
- return x.c_str();
+ typedef To to;
+ typedef From from;
+};
+
+template <typename To, typename From, typename Lhs, typename Rhs>
+void assign_out(Lhs& lhs, Rhs& rhs);
+
+template <typename T>
+void assign_out_impl(T*& lhs, T& rhs, tag<T*, T>)
+{
+ *lhs = rhs;
}
-
-inline const char*
-to_c(eina::optional<std::string> const& x)
+template <typename U, typename T>
+void assign_out_impl(std::unique_ptr<T, void(*)(const void*)>& lhs, U* rhs, tag<std::unique_ptr<T, void(*)(const void*)>&, U*>)
{
- if (!x)
- return nullptr;
- return x->c_str();
+ lhs.reset(rhs);
}
-
-inline const char*
-to_c(eina::string_view const& x)
+template <typename Tag>
+void assign_out_impl(bool& lhs, Eina_Bool rhs, Tag)
{
- return x.data();
+ lhs = rhs;
}
-
-inline const char*
-to_c(eina::optional<eina::string_view> const& x)
+template <typename T>
+void assign_out_impl(T& lhs, T& rhs, tag<T&, T>)
{
- if (!x)
- return nullptr;
- return x->data();
+ lhs = rhs;
}
-
-inline const char*
-to_c(efl::eina::stringshare const& x)
+template <typename T>
+void assign_out_impl(T& lhs, Eo* rhs, tag<T&, Eo*>
+ , typename std::enable_if<eo::is_eolian_object<T>::value>::type* = 0)
{
- return x.c_str();
+ lhs._reset(rhs);
}
-
-inline const char*
-to_c(eina::optional<efl::eina::stringshare> const& x)
+template <typename T>
+void assign_out_impl(T& lhs, Eo const* rhs, tag<T&, Eo const*>
+ , typename std::enable_if<eo::is_eolian_object<T>::value>::type* = 0)
{
- if (!x)
- return nullptr;
- return x->c_str();
+ lhs._reset(const_cast<Eo*>(rhs));
}
-
-inline Eina_Bool
-to_c(bool x)
+template <typename T>
+void assign_out_impl(efl::eina::future<T>& /*v*/, Eina_Promise*, tag<efl::eina::future<T>&, Eina_Promise*>)
{
- return x ? EINA_TRUE : EINA_FALSE;
}
-
-inline Eina_Bool*
-to_c(bool* x)
+template <typename Tag>
+void assign_out_impl(efl::eina::string_view& view, const char* string, Tag)
{
- static_assert(sizeof(bool) == sizeof(Eina_Bool), "");
- return reinterpret_cast<Eina_Bool*>(x);
+ view = {string};
}
-
-template <typename T>
-T to_c(T const& v, typename std::enable_if<!std::is_convertible<T*, ::efl::eo::concrete*>::value>::type* = 0)
+template <typename T, typename Rhs, typename U, typename O>
+void assign_out_impl(efl::eina::optional<T>& lhs, Rhs*& rhs, tag<efl::eina::optional<U>&, O>)
{
- return v;
+ if(rhs)
+ assign_out<U, O>(*lhs, rhs);
+ else
+ lhs.disengage();
}
-
-template <typename T>
-Eo* to_c(T const& v, typename std::enable_if<std::is_convertible<T*, ::efl::eo::concrete*>::value>::type* = 0)
+template <typename T, typename Rhs, typename U, typename O>
+void assign_out_impl(efl::eina::optional<T>& lhs, Rhs& rhs, tag<efl::eina::optional<U>&, O>)
{
- return v._eo_ptr();
+ assign_out<U, O>(*lhs, rhs);
}
-
-template <typename T>
-Eo* to_c(eina::optional<T> const& v, typename std::enable_if<std::is_convertible<T*, ::efl::eo::concrete*>::value>::type* = 0)
+template <typename T, typename Rhs, typename U, typename O>
+void assign_out_impl(efl::eina::optional<T>& lhs, Rhs*& rhs, tag<efl::eina::optional<U>, O>)
{
- if (!v)
- return nullptr;
- return v->_eo_ptr();
+ if(rhs)
+ assign_out<U, O>(*lhs, rhs);
+ else
+ lhs.disengage();
}
-
-template <typename T>
-Eo** to_c(T* v, typename std::enable_if<std::is_convertible<T*, ::efl::eo::concrete*>::value>::type* = 0)
+template <typename T, typename Rhs, typename U, typename O>
+void assign_out_impl(efl::eina::optional<T>& lhs, Rhs& rhs, tag<efl::eina::optional<U>, O>)
{
- static_assert(sizeof(T) == sizeof(Eo*), "");
- return static_cast<Eo**>(static_cast<void*>(v));
+ assign_out<U, O>(*lhs, rhs);
}
-
-template <typename R, typename T>
-R to_native(T& v)
+template <typename Tag>
+void assign_out_impl(eina::value& lhs, Eina_Value const& rhs, Tag)
{
- static_assert(sizeof(T) == sizeof(R), "");
- return v.native_handle();
+ Eina_Value* v = eina_value_new(EINA_VALUE_TYPE_CHAR);
+ eina_value_flush(v);
+ eina_value_copy(&rhs, v);
+ lhs = {v};
}
-
-template <typename R, typename T>
-R to_native(eina::optional<T>& v)
+template <typename T, typename Tag>
+void assign_out_impl(efl::eina::list<T>& lhs, Eina_List* rhs, Tag)
{
- static_assert(sizeof(T) == sizeof(R), "");
- if (!v)
- return nullptr;
- return v->native_handle();
+ lhs = efl::eina::list<T>{rhs};
}
-
-template <typename R, typename T>
-R to_native(T* v)
+}
+
+template <typename To, typename From, typename Lhs, typename Rhs>
+void assign_out(Lhs& lhs, Rhs& rhs)
{
- static_assert(sizeof(T) == sizeof(typename std::remove_pointer<R>::type), "");
- return static_cast<R>(static_cast<void*>(v));
+ return impl::assign_out_impl(lhs, rhs, impl::tag<To, From>{});
}
-
-//// From C to C++
+namespace impl {
template <typename T>
-struct tag {};
-
-template <typename T, typename U, typename O>
-T to_cxx(U object, O o);
-
-// XXX
-inline void*
-to_cxx(void *x, std::tuple<std::false_type>, tag<void*>)
+T* convert_inout_impl(T& v, tag<T, T*>)
{
- return x;
+ return v;
}
-
-// XXX
-inline const void*
-to_cxx(const void *x, std::tuple<std::false_type>, tag<const void*>)
+template <typename T>
+T& convert_inout_impl(T& v, tag<T, T>)
{
- return x;
+ return v;
}
-
template <typename T>
-inline T
-to_cxx(Eo* x, std::tuple<std::true_type>, tag<T>)
+Eo* convert_inout_impl(T& v, tag<T, Eo*>
+ , typename std::enable_if<eo::is_eolian_object<T>::value>::type* = 0)
{
- return T(x);
+ return v._eo_ptr();
}
-
template <typename T>
-inline T
-to_cxx(Eo* x, std::tuple<std::false_type>, tag<T>)
+Eo const* convert_inout_impl(T v, tag<T, Eo const*>
+ , typename std::enable_if<eo::is_eolian_object<T>::value>::type* = 0)
{
- return T(::eo_ref(x));
+ return v._eo_ptr();
}
-
template <typename T>
-inline eina::optional<T>
-to_cxx(Eo* x, std::tuple<std::true_type>, tag<eina::optional<T> >)
+Eina_Promise* convert_inout_impl(efl::eina::future<T>& /*v*/, tag<efl::eina::future<T>, Eina_Promise*>)
+{
+ return nullptr;
+}
+}
+
+template <typename To, typename From, typename V>
+auto convert_inout(V& object) -> decltype(impl::convert_inout_impl(object, impl::tag<From, To>{}))
{
- if (!x)
- return nullptr;
- return T(x);
+ return impl::convert_inout_impl(object, impl::tag<From, To>{});
}
+
+template <typename T, typename U, typename V>
+T convert_to_c(V&& object);
+
+namespace impl {
-template <typename T>
-inline eina::optional<T>
-to_cxx(Eo* x, std::tuple<std::false_type>, tag<eina::optional<T> >)
+template <typename U, typename T>
+auto convert_to_c_impl
+(T&& v, tag<U, U>, typename std::enable_if<std::is_same<typename std::remove_reference<T>::type, U>::value>::type* =0) -> decltype(std::forward<T>(v))
{
- if (!x)
- return nullptr;
- return T(::eo_ref(x));
+ return std::forward<T>(v);
}
template <typename T>
-inline T
-to_cxx(Eo** x, std::tuple<std::false_type>, tag<T>)
+T const& convert_to_c_impl(T const& v, tag<T, T const&>)
{
- static_assert(sizeof(Eo*) == sizeof(typename std::remove_pointer<T>::type), "");
- return static_cast<T>((static_cast<void*>(x)));
+ return v;
}
-
-#ifdef _EVAS_H
template <typename T>
-Evas_Object_Textblock_Node_Format *
-to_cxx(Evas_Object_Textblock_Node_Format* x, std::tuple<std::false_type>, tag<T>)
+Eo* convert_to_c_impl(T v, tag<Eo*, T>
+ , typename std::enable_if<eo::is_eolian_object<T>::value>::type* = 0)
{
- return x; // XXX
+ return v._eo_ptr();
}
-#endif
-
-inline bool
-to_cxx(Eina_Bool x, std::tuple<std::false_type>, tag<bool>)
+template <typename T>
+Eo const* convert_to_c_impl(T v, tag<Eo const*, T>
+ , typename std::enable_if<eo::is_eolian_object<T>::value>::type* = 0)
{
- return !!x;
+ return v._eo_ptr();
}
-
-inline std::string
-to_cxx(const char* x, std::tuple<std::false_type>, tag<std::string>)
+inline const char* convert_to_c_impl( ::efl::eina::string_view v, tag<const char*, ::efl::eina::string_view>)
{
- return std::string(x);
+ return v.c_str();
}
-
-inline eina::optional<std::string>
-to_cxx(const char* x, std::tuple<std::false_type>, tag<eina::optional<std::string> >)
+inline const char** convert_to_c_impl(efl::eina::string_view* /*view*/, tag<const char **, efl::eina::string_view*>)
{
- if (!x)
- return nullptr;
- return std::string(x);
+ std::abort();
}
-
-inline eina::string_view
-to_cxx(const char* x, std::tuple<std::false_type>, tag<eina::string_view>)
+inline const char* convert_to_c_impl( std::string const& v, tag<const char*, std::string const&>)
{
- return eina::string_view(x);
+ std::size_t len = v.size()+1;
+ char* buffer = static_cast<char*>(malloc(len));
+ std::memcpy(buffer, v.data(), len);
+ return buffer;
}
-
-inline eina::optional<eina::string_view>
-to_cxx(const char* x, std::tuple<std::false_type>, tag<eina::optional<eina::string_view> >)
+inline const char** convert_to_c_impl(std::string* /*view*/, tag<const char **, std::string*>)
{
- if (!x)
- return nullptr;
- return eina::string_view(x);
+ std::abort();
}
-
-template <typename T, typename Enable = void>
-struct traits
+inline Eina_Value* convert_to_c_impl( ::efl::eina::value v, tag<Eina_Value*, in_traits<eina::value>::type>)
{
- typedef T type;
-};
-
+ Eina_Value* nv = eina_value_new(v.type_info());
+ eina_value_copy(v.native_handle(), nv);
+ return nv;
+}
+inline Eina_Value const* convert_to_c_impl( ::efl::eina::value v, tag<Eina_Value const*, in_traits<eina::value>::type>)
+{
+ Eina_Value* nv = eina_value_new(v.type_info());
+ eina_value_copy(v.native_handle(), nv);
+ return nv;
+}
+inline Eina_Bool convert_to_c_impl( bool b, tag<Eina_Bool, bool>)
+{
+ return b;
+}
template <typename T>
-struct traits
- <T, typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>::type>
+T convert_to_c_impl(efl::eina::optional<T> const& optional, tag<T, efl::eina::optional<T>const&>)
{
- typedef Eo* type;
-};
-
+ return optional ? *optional : T{};
+}
+template <typename U, typename T>
+U convert_to_c_impl(efl::eina::optional<T> const& optional, tag<U, efl::eina::optional<T>const&>)
+{
+ return impl::convert_to_c_impl(optional ? *optional : T{}, tag<U, typename in_traits<T>::type>{});
+}
template <typename T>
-struct traits
- <T, typename std::enable_if<std::is_base_of<std::basic_string<char>, T>::value>::type>
+Eina_List* convert_to_c_impl(efl::eina::range_list<T> range, tag<Eina_List *, efl::eina::range_list<T>>)
{
- typedef const char* type;
-};
-
+ return range.native_handle();
+}
template <typename T>
-struct traits
- <T, typename std::enable_if<std::is_base_of<::efl::eina::basic_string_view<char>, T>::value>::type>
+Eina_List const* convert_to_c_impl(efl::eina::range_list<T> range, tag<Eina_List const *, efl::eina::range_list<T>>)
{
- typedef const char* type;
-};
-
-template <typename T, typename ...Args>
-inline efl::eina::range_list<T const>
-to_cxx(const Eina_List* x, std::tuple<std::false_type, Args...>, tag< efl::eina::range_list<T> >)
+ return range.native_handle();
+}
+template <typename T>
+Eina_List* convert_to_c_impl(efl::eina::list<T>const& c, tag<Eina_List *, efl::eina::list<T>const&>)
{
- return efl::eina::range_list<T const> {x};
+ return const_cast<Eina_List*>(c.native_handle());
}
-
-template <typename T, typename ...Args>
-inline eina::optional<efl::eina::range_list<T const> >
-to_cxx(const Eina_List* x, std::tuple<std::false_type, Args...>, tag< eina::optional<efl::eina::range_list<T> > >)
+template <typename T>
+Eina_List const* convert_to_c_impl(efl::eina::list<T>const& c, tag<Eina_List const *, efl::eina::list<T>const&>)
{
- if (!x)
- return nullptr;
- return efl::eina::range_list<T const> {x};
+ return c.native_handle();
}
-
-template <typename T, typename ...Args>
-inline efl::eina::range_list<T>
-to_cxx(Eina_List* x, std::tuple<std::false_type, Args...>, tag< efl::eina::range_list<T> >)
+template <typename T>
+Eina_Array* convert_to_c_impl(efl::eina::range_array<T> range, tag<Eina_Array *, efl::eina::range_array<T>>)
{
- return efl::eina::range_list<T>{x};
+ return range.native_handle();
}
-
-template <typename T, typename ...Args>
-inline eina::optional<efl::eina::range_list<T> >
-to_cxx(Eina_List* x, std::tuple<std::false_type, Args...>, tag< eina::optional<efl::eina::range_list<T> > >)
+template <typename T>
+Eina_Array const* convert_to_c_impl(efl::eina::range_array<T> range, tag<Eina_Array const *, efl::eina::range_array<T>>)
{
- if (!x)
- return nullptr;
- return efl::eina::range_list<T>{x};
+ return range.native_handle();
}
-
-template <typename T, typename ...Args>
-inline efl::eina::list<T>
-to_cxx(Eina_List* x, std::tuple<std::true_type, Args...>, tag< efl::eina::list<T> >)
+template <typename T>
+Eina_Array* convert_to_c_impl(efl::eina::array<T>const& c, tag<Eina_Array *, efl::eina::array<T>const&>)
{
- return efl::eina::list<T> {x};
+ return c.native_handle();
}
-
-template <typename T, typename ...Args>
-inline eina::optional<efl::eina::list<T> >
-to_cxx(Eina_List* x, std::tuple<std::true_type, Args...>, tag< eina::optional<efl::eina::list<T> > >)
+template <typename T>
+Eina_Array const* convert_to_c_impl(efl::eina::array<T>const& c, tag<Eina_Array const *, efl::eina::array<T>const&>)
{
- if (!x)
- return nullptr;
- return efl::eina::list<T> {x};
+ return c.native_handle();
}
-
-template <typename T, typename ...Args>
-inline efl::eina::range_array<T const>
-to_cxx(const Eina_Array* x, std::tuple<std::false_type, Args...>, tag< efl::eina::range_array<T> >)
+inline const char** convert_to_c_impl(efl::eina::string_view /*view*/, tag<char const **, efl::eina::string_view>)
{
- return efl::eina::range_array<T const> {x};
+ std::abort();
}
-
-template <typename T, typename ...Args>
-inline eina::optional<efl::eina::range_array<T const> >
-to_cxx(const Eina_Array* x, std::tuple<std::false_type, Args...>, tag< eina::optional<efl::eina::range_array<T> > >)
+// inline const char* convert_to_c_impl(std::string const& x, tag<const char*, std::string>)
+// {
+// return x.c_str();
+// }
+inline const char* convert_to_c_impl(efl::eina::stringshare x, tag<const char*, efl::eina::stringshare>)
{
- if (!x)
- return nullptr;
- return efl::eina::range_array<T const> {x};
+ return x.c_str();
}
-
-template <typename T, typename ...Args>
-inline efl::eina::range_array<T>
-to_cxx(Eina_Array* x, std::tuple<std::false_type, Args...>, tag< efl::eina::range_array<T> >)
+template <typename T>
+Eina_Promise* convert_to_c_impl(efl::eina::future<T> const&, tag<Eina_Promise*, efl::eina::future<T>const&>)
{
- return efl::eina::range_array<T>{x};
+ std::abort();
}
-
-template <typename T, typename ...Args>
-inline eina::optional<efl::eina::range_array<T> >
-to_cxx(Eina_Array* x, std::tuple<std::false_type, Args...>, tag< eina::optional<efl::eina::range_array<T> > >)
+template <typename T, typename U, typename Deleter>
+T* convert_to_c_impl(std::unique_ptr<U, Deleter>& v, tag<T*, std::unique_ptr<U, Deleter>>)
{
- if (!x)
- return nullptr;
- return efl::eina::range_array<T>{x};
+ return convert_to_c<T*, U*>(v.release());
}
-template <typename T, typename ...Args>
-inline efl::eina::array<T>
-to_cxx(Eina_Array* x, std::tuple<std::true_type, Args...>, tag< efl::eina::array<T> >)
+template <typename T>
+Eina_Array** convert_to_c_impl(efl::eina::array<T>& c, tag<Eina_Array **, efl::eina::array<T>&>)
{
- return efl::eina::array<T> {x};
+ std::abort();
}
-
-template <typename T, typename ...Args>
-inline eina::optional<efl::eina::array<T> >
-to_cxx(Eina_Array* x, std::tuple<std::true_type, Args...>, tag< eina::optional<efl::eina::array<T> > >)
+template <typename T>
+Eina_Array** convert_to_c_impl(efl::eina::range_array<T>& c, tag<Eina_Array **, efl::eina::range_array<T>&>)
{
- if (!x)
- return nullptr;
- return efl::eina::array<T> {x};
+ std::abort();
+}
}
-
-inline eina::stringshare
-to_cxx(Eina_Stringshare const* x, const std::false_type, tag<eina::stringshare>)
+template <typename T, typename U, typename V>
+T convert_to_c(V&& object)
{
- return ::eina_stringshare_ref(x);
+ return impl::convert_to_c_impl(std::forward<V>(object), impl::tag<T, U>{});
}
+namespace impl {
+template <typename T>
+struct is_range : std::false_type {};
+template <typename T>
+struct is_range<efl::eina::range_list<T>> : std::true_type {};
+template <typename T>
+struct is_range<efl::eina::range_array<T>> : std::true_type {};
-inline eina::optional<eina::stringshare>
-to_cxx(Eina_Stringshare const* x, const std::false_type, tag<eina::optional<eina::stringshare> >)
+template <typename T>
+struct is_container : std::false_type {};
+template <typename T>
+struct is_container<efl::eina::list<T>> : std::true_type {};
+template <typename T>
+struct is_container<efl::eina::array<T>> : std::true_type {};
+
+// event
+template <typename T>
+T convert_to_event(void* value, typename std::enable_if< eo::is_eolian_object<T>::value>::type* = 0)
{
- if (!x)
- return nullptr;
- return eina::stringshare(::eina_stringshare_ref(x));
+ return T{::eo_ref(static_cast<Eo*>(value))};
}
-
-template <typename T, typename ...Args>
-inline efl::eina::accessor<T>
-to_cxx(Eina_Accessor* x, std::tuple<std::false_type, Args...>, tag< efl::eina::accessor<T> >)
+template <typename T>
+T convert_to_event(void* value, typename std::enable_if< is_container<T>::value
+ || is_range<T>::value>::type* = 0)
{
- return efl::eina::accessor<T>(x);
+ return T{static_cast<typename T::native_handle_type>(value)};
}
-
-template <typename T, typename ...Args>
-inline eina::optional<efl::eina::accessor<T> >
-to_cxx(Eina_Accessor* x, std::tuple<std::false_type, Args...>, tag< eina::optional<efl::eina::accessor<T> > >)
+template <typename T>
+T convert_to_event(void* value, typename std::enable_if< !std::is_pointer<T>::value
+ && !is_container<T>::value && !is_range<T>::value
+ && !eo::is_eolian_object<T>::value>::type* = 0)
{
- if (!x)
- return nullptr;
- return efl::eina::accessor<T>(x);
+ return *static_cast<T*>(value);
}
-
-template <typename T, typename ...Args>
-inline efl::eina::iterator<T>
-to_cxx(Eina_Iterator* x, std::tuple<std::false_type, Args...>, tag< efl::eina::iterator<T> >)
+template <typename T>
+T convert_to_event(void* value, typename std::enable_if<std::is_same<T, bool>::value>::type* = 0)
{
- return efl::eina::iterator<T>(x);
+ return *static_cast<Eina_Bool*>(value);
}
-
-template <typename T, typename ...Args>
-inline eina::optional<efl::eina::iterator<T> >
-to_cxx(Eina_Iterator* x, std::tuple<std::false_type, Args...>, tag< eina::optional<efl::eina::iterator<T> > >)
+}
+template <typename T>
+T convert_to_event(void* value) { return impl::convert_to_event<T>(value); }
+namespace impl {
+
+template <typename T>
+T convert_to_return(T value, tag<T, T>)
{
- if (!x)
- return nullptr;
- return efl::eina::iterator<T>(x);
+ return value;
}
-
-template <typename T, typename ...Args>
-T
-to_cxx(Eo const* x, std::tuple<std::false_type, Args...>, tag< T >
- , typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>* = 0)
+template <typename T>
+T convert_to_return(Eo* value, tag<Eo*, T>, typename std::enable_if< eo::is_eolian_object<T>::value>::type* = 0)
{
- // Workaround for erroneous constness
- return T{ ::eo_ref(const_cast<Eo*>(x))};
+ return T{value};
}
-
-template <typename T, typename ...Args>
-eina::optional<T>
-to_cxx(Eo const* x, std::tuple<std::false_type, Args...>, tag< eina::optional<T> >
- , typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>* = 0)
+template <typename T>
+T convert_to_return(Eo const* value, tag<Eo const*, T>, typename std::enable_if<eo::is_eolian_object<T>::value>::type* = 0)
{
- // Workaround for erroneous constness
- if (!x)
- return nullptr;
- return T{ ::eo_ref(const_cast<Eo*>(x))};
+ return T{const_cast<Eo*>(value)};
}
-
-template <typename T, typename ...Args>
-T
-to_cxx(Eo const* x, std::tuple<std::true_type, Args...>, tag< T >
- , typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>* = 0)
+template <typename T>
+eina::list<T> convert_to_return(Eina_List* value, tag<Eina_List*, eina::list<T>>)
{
- // Workaround for erroneous constness
- return T{const_cast<Eo*>(x)};
+ return eina::list<T>{value};
}
-
-template <typename T, typename ...Args>
-eina::optional<T>
-to_cxx(Eo const* x, std::tuple<std::true_type, Args...>, tag< eina::optional<T> >
- , typename std::enable_if<std::is_base_of<::efl::eo::concrete, T>::value>* = 0)
+template <typename T>
+eina::list<T> convert_to_return(Eina_List const* value, tag<Eina_List const*, eina::list<T>>)
{
- // Workaround for erroneous constness
- if (!x)
- return nullptr;
- return T{const_cast<Eo*>(x)};
+ return eina::list<T>{const_cast<Eina_List*>(value)};
}
-
-template <typename T, typename U, typename O>
-T to_cxx(U object, O o)
+template <typename T>
+eina::range_list<T> convert_to_return(Eina_List* value, tag<Eina_List*, eina::range_list<T>>)
{
- return to_cxx(object, o, tag<T>());
+ return eina::range_list<T>{value};
}
-
-//// Callbacks
-
-template <typename F, typename R, typename V, typename... Args>
-R funcall(V* data, Args... args)
+template <typename T>
+eina::range_list<T> convert_to_return(Eina_List const* value, tag<Eina_List const*, eina::range_list<T>>)
{
- F const* f = static_cast<F const*>(data);
- return (*f)(args...);
+ return eina::range_list<T>{const_cast<Eina_List*>(value)};
}
-
template <typename T>
-struct callback_result_type;
-
-template <typename R, typename... Args>
-struct callback_result_type<R(*)(Args...)>
+eina::array<T> convert_to_return(Eina_Array* value, tag<Eina_Array*, eina::array<T>>)
{
- typedef R type;
-};
-
-template <typename R>
-struct callback_args_type;
-
-template <typename R, typename... Args>
-struct callback_args_type<R(*)(Args...)>
+ return eina::array<T>{value};
+}
+template <typename T>
+eina::array<T> convert_to_return(Eina_Array const* value, tag<Eina_Array const*, eina::array<T>>)
{
- typedef std::tuple<Args...> type;
-};
-
-template <typename C, typename F, typename R, typename V, typename... Args>
-C get_callback_impl(tag<std::tuple<V*, Args...> >)
+ return eina::array<T>{const_cast<Eina_Array*>(value)};
+}
+template <typename T>
+eina::range_array<T> convert_to_return(Eina_Array* value, tag<Eina_Array*, eina::range_array<T>>)
{
- static_assert(std::is_same<void, typename std::remove_cv<V>::type>::value,
- "First argument of callback should be void* or const void*");
- return static_cast<C>(&eolian::funcall<F, R, V, Args...>);
+ return eina::range_array<T>{value};
}
-
-template <typename C, typename F>
-C get_callback()
+template <typename T>
+eina::range_array<T> convert_to_return(Eina_Array const* value, tag<Eina_Array const*, eina::range_array<T>>)
{
- return get_callback_impl<C, F, typename callback_result_type<C>::type>
- (tag<typename callback_args_type<C>::type>());
+ return eina::range_array<T>{const_cast<Eina_Array*>(value)};
}
-
-template <typename F>
-Eina_Bool free_callback_callback(void* data, ::Eo_Event const*)
+
+template <typename T>
+eina::iterator<T> convert_to_return(Eina_Iterator* value, tag<Eina_Iterator*, eina::iterator<T>>)
{
- delete static_cast<F*>(data);
- return EO_CALLBACK_CONTINUE;
+ return eina::iterator<T>{value};
}
-
-template <typename... Fs>
-inline
-void register_ev_del_free_callback(Eo* eoptr, Fs&&... fs)
+template <typename T>
+struct is_future : std::false_type {};
+template <typename T>
+struct is_future<efl::eina::future<T>> : std::true_type {};
+template <typename T>
+T convert_to_return(Eina_Promise* /*value*/, tag<Eina_Promise*, T>, typename std::enable_if<is_future<T>::value>::type* = 0)
{
- std::initializer_list<int const> const v {(fs.register_ev_del_free_callback(eoptr), 0)...};
- (void) v; (void) eoptr;
+ std::abort();
+ return {};
}
-
-template <typename F>
-inline
-std::vector<F>& get_static_callback_vector()
+// Eina_Value*
+inline efl::eina::value convert_to_return(Eina_Value* value, tag<Eina_Value*, efl::eina::value>)
+{
+ return efl::eina::value{value};
+}
+template <typename T, typename U>
+T convert_to_return(U* value, tag<T, U*>, typename std::enable_if<is_range<T>::value || is_container<T>::value>::type* = 0)
+{
+ // const should be to the type if value is const
+ return T{const_cast<typename std::remove_const<U>::type*>(value)};
+}
+template <typename T>
+T convert_to_return(const char** /*value*/, tag<const char**, T>, typename std::enable_if<std::is_same<T, efl::eina::string_view*>::value>::type* = 0)
+{
+ std::abort();
+}
+inline eina::string_view convert_to_return(const char* value, tag<const char*, efl::eina::string_view>)
{
- static std::vector<F> vec;
- return vec;
+ return {value};
+}
+inline std::string convert_to_return(const char* value, tag<const char*, std::string>)
+{
+ return {value};
+}
+inline bool convert_to_return(Eina_Bool value, tag<Eina_Bool, bool>)
+{
+ return !!value;
+}
+template <typename T>
+std::unique_ptr<T, void(*)(const void*)> convert_to_return(T* value, tag<T*, std::unique_ptr<T, void(*)(const void*)>>)
+{
+ return std::unique_ptr<T, void(*)(const void*)>{value, (void(*)(const void*))&free};
+}
+template <typename T, typename U>
+std::unique_ptr<T, void(*)(const void*)> convert_to_return(U* value, tag<U*, std::unique_ptr<T, void(*)(const void*)>>)
+{
+ return std::unique_ptr<T, void(*)(const void*)>{convert_to_return(value, tag<U*, T*>{}), (void(*)(const void*))&free};
+}
}
-template <typename F>
-inline
-F* alloc_static_callback(F&& f)
+template <typename T, typename U>
+T convert_to_return(U& object)
{
- get_static_callback_vector<F>().push_back(std::forward<F>(f));
- return &(get_static_callback_vector<F>().back());
+ return impl::convert_to_return(object, impl::tag<U, T>{});
}
/// Miscellaneous
+template <typename T, typename Enable = void>
+struct is_callable : std::false_type {};
+template <typename T>
+struct is_callable<T, decltype(std::declval<T>() ())> : std::true_type {};
-template <typename... Fs>
-inline
-void call_ctors(Eo* _obj_eo_self, Fs&&... fs)
+inline void do_eo_add(Eo*& object, efl::eo::concrete const& parent
+ , Eo_Class const* klass)
+{
+ object = ::_eo_add_internal_start(__FILE__, __LINE__, klass, parent._eo_ptr(), EINA_TRUE, EINA_FALSE);
+ object = ::_eo_add_end(object, EINA_FALSE);
+}
+template <typename F>
+void do_eo_add(Eo*& object, efl::eo::concrete const& parent, Eo_Class const* klass, F f)
{
- std::initializer_list<int const> const v {(fs(_obj_eo_self), 0)...};
- (void) v;
- (void) _obj_eo_self;
+ object = ::_eo_add_internal_start(__FILE__, __LINE__, klass, parent._eo_ptr(), EINA_TRUE, EINA_FALSE);
+ f();
+ object = ::_eo_add_end(object, EINA_FALSE);
}
+template <typename D, typename T>
+struct light_address_of_operator
+{
+ operator T* () const { return static_cast<T*>(static_cast<void*>(static_cast<D const*>(this)->p)); }
+};
+template <typename D, typename T>
+struct light_address_of_operator<D, T const>
+{
+ operator T const* () const { return static_cast<T const*>(static_cast<void const*>(static_cast<D const*>(this)->p)); }
+};
+
+template <typename T, typename...Args>
+struct address_of_operator : light_address_of_operator<address_of_operator<T, Args...>, Args>...
+{
+ operator T* () { return p; };
+ address_of_operator(T* p) : p(p) {}
+ T* p;
+};
+
+template <typename T, typename...Args>
+struct address_of_operator<T const, Args...> : light_address_of_operator<address_of_operator<T const, Args...>, Args>...
+{
+ operator T const* () { return p; };
+ address_of_operator(T const* p) : p(p) {}
+ T const* p;
+};
+
} } // namespace efl { namespace eolian {
#endif // EFL_EOLIAN_INTEROP_HH
diff --git a/src/bindings/cxx/eo_cxx/eo_event.hh b/src/bindings/cxx/eo_cxx/eo_event.hh
index 320bfc9cba..2120121cd8 100644
--- a/src/bindings/cxx/eo_cxx/eo_event.hh
+++ b/src/bindings/cxx/eo_cxx/eo_event.hh
@@ -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)
+{
+ 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, desc, info);
+ 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());
}
} }
diff --git a/src/bindings/cxx/eo_cxx/eo_inherit.hh b/src/bindings/cxx/eo_cxx/eo_inherit.hh
index a05d11fe94..96ee1dc3bf 100644
--- a/src/bindings/cxx/eo_cxx/eo_inherit.hh
+++ b/src/bindings/cxx/eo_cxx/eo_inherit.hh
@@ -1,155 +1,155 @@
-///
-/// @file eo_inherit.hh
-///
-
-#ifndef EFL_CXX_EO_INHERIT_HH
-#define EFL_CXX_EO_INHERIT_HH
-
-#include <tuple>
-#include <cassert>
-
-#include <eina_integer_sequence.hh>
-
-#include "eo_ops.hh"
-#include "eo_private.hh"
-#include "eo_cxx_interop.hh"
-
-namespace efl { namespace eo {
-
-namespace detail {
-
-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_);
-
-}
-
-/// @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;
-
-/// @}
-
-/// @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;
-
- //@{
- /// @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)...)
- {}
- //@}
-
- /// @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 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;
- }
-
-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;
- }
-
-private:
- Eo_Class const* _eo_cls; ///< The <em>EO Class</em>.
- Eo* _eo_raw; ///< The <em>EO Object</em>.
-};
-
-/// @}
-
-} } // namespace efl { namespace eo {
-
-#include "eo_inherit_bindings.hh"
-
-#endif // EFL_CXX_INHERIT_HH
+// ///
+// /// @file eo_inherit.hh
+// ///
+
+// #ifndef EFL_CXX_EO_INHERIT_HH
+// #define EFL_CXX_EO_INHERIT_HH
+
+// #include <tuple>
+// #include <cassert>
+
+// #include <eina_integer_sequence.hh>
+
+// #include "eo_ops.hh"
+// #include "eo_private.hh"
+// #include "eo_cxx_interop.hh"
+
+// namespace efl { namespace eo {
+
+// namespace detail {
+
+// 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_);
+
+// }
+
+// /// @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;
+
+// /// @}
+
+// /// @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;
+
+// //@{
+// /// @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)...)
+// {}
+// //@}
+
+// /// @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 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;
+// }
+
+// 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;
+// }
+
+// private:
+// Eo_Class const* _eo_cls; ///< The <em>EO Class</em>.
+// Eo* _eo_raw; ///< The <em>EO Object</em>.
+// };
+
+// /// @}
+
+// } } // namespace efl { namespace eo {
+
+// #include "eo_inherit_bindings.hh"
+
+// #endif // EFL_CXX_INHERIT_HH
diff --git a/src/examples/elementary/bg_cxx_example_01.cc b/src/examples/elementary/bg_cxx_example_01.cc
index 9fe20f445c..a1db40aa91 100644
--- a/src/examples/elementary/bg_cxx_example_01.cc
+++ b/src/examples/elementary/bg_cxx_example_01.cc
@@ -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();
diff --git a/src/examples/elementary/button_cxx_example_00.cc b/src/examples/elementary/button_cxx_example_00.cc
index a18d652146..c12f504c70 100644
--- a/src/examples/elementary/button_cxx_example_00.cc
+++ b/src/examples/elementary/button_cxx_example_00.cc
@@ -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();
diff --git a/src/examples/eolian_cxx/Makefile.am b/src/examples/eolian_cxx/Makefile.am
index 8b6b68f6dd..f0b82d1da9 100644
--- a/src/examples/eolian_cxx/Makefile.am
+++ b/src/examples/eolian_cxx/Makefile.am
@@ -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
diff --git a/src/examples/eolian_cxx/colourable.c b/src/examples/eolian_cxx/colourable.c
index dd2cc11833..04c233a2d7 100644
--- a/src/examples/eolian_cxx/colourable.c
+++ b/src/examples/eolian_cxx/colourable.c
@@ -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
diff --git a/src/examples/eolian_cxx/colourable_cxx.cc b/src/examples/eolian_cxx/colourable_cxx.cc
index 513e3dc4ba..30f1bb318f 100644
--- a/src/examples/eolian_cxx/colourable_cxx.cc
+++ b/src/examples/eolian_cxx/colourable_cxx.cc
@@ -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
diff --git a/src/examples/eolian_cxx/colourablesquare.c b/src/examples/eolian_cxx/colourablesquare.c
index f367c59ae4..f67d3e2ff1 100644
--- a/src/examples/eolian_cxx/colourablesquare.c
+++ b/src/examples/eolian_cxx/colourablesquare.c
@@ -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
diff --git a/src/examples/eolian_cxx/colourablesquare_cxx.cc b/src/examples/eolian_cxx/colourablesquare_cxx.cc
index b4c92b8e88..ecaf757ac7 100644
--- a/src/examples/eolian_cxx/colourablesquare_cxx.cc
+++ b/src/examples/eolian_cxx/colourablesquare_cxx.cc
@@ -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
diff --git a/src/examples/eolian_cxx/eolian_cxx_simple_01.cc b/src/examples/eolian_cxx/eolian_cxx_simple_01.cc
index 0bf9642284..eb093d904b 100644
--- a/src/examples/eolian_cxx/eolian_cxx_simple_01.cc
+++ b/src/examples/eolian_cxx/eolian_cxx_simple_01.cc
@@ -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());
diff --git a/src/examples/eolian_cxx/ns_colourable.eo b/src/examples/eolian_cxx/ns_colourable.eo
index 90abc65ae8..21af926274 100644
--- a/src/examples/eolian_cxx/ns_colourable.eo
+++ b/src/examples/eolian_cxx/ns_colourable.eo
@@ -1,7 +1,6 @@
class Ns.Colourable (Eo.Base)
{
[[Colourable class.]]
- legacy_prefix: legacy;
data: Colourable_Data;
methods {
rgb_24bits_constructor {
diff --git a/src/examples/eolian_cxx/ns_colourablesquare.eo b/src/examples/eolian_cxx/ns_colourablesquare.eo
index 70fb471e1f..66fe8ae5cd 100644
--- a/src/examples/eolian_cxx/ns_colourablesquare.eo
+++ b/src/examples/eolian_cxx/ns_colourablesquare.eo
@@ -1,6 +1,5 @@
class Ns.ColourableSquare (Ns.Colourable)
{
- legacy_prefix: legacy;
data: ColourableSquare_Data;
methods {
@property size {
diff --git a/src/lib/eolian_cxx/Eolian_Cxx.hh b/src/lib/eolian_cxx/Eolian_Cxx.hh
index dfa748247e..5a8ea813c7 100644
--- a/src/lib/eolian_cxx/Eolian_Cxx.hh
+++ b/src/lib/eolian_cxx/Eolian_Cxx.hh
@@ -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
diff --git a/src/lib/eolian_cxx/eo_generate.hh b/src/lib/eolian_cxx/eo_generate.hh
deleted file mode 100644
index 97e53bb9dc..0000000000
--- a/src/lib/eolian_cxx/eo_generate.hh
+++ /dev/null
@@ -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
diff --git a/src/lib/eolian_cxx/eo_types.hh b/src/lib/eolian_cxx/eo_types.hh
deleted file mode 100644
index 4431d3b44f..0000000000
--- a/src/lib/eolian_cxx/eo_types.hh
+++ /dev/null
@@ -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
diff --git a/src/lib/eolian_cxx/eo_validate.hh b/src/lib/eolian_cxx/eo_validate.hh
deleted file mode 100644
index 8ffa7dccd7..0000000000
--- a/src/lib/eolian_cxx/eo_validate.hh
+++ /dev/null
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/address_of.hpp b/src/lib/eolian_cxx/grammar/address_of.hpp
new file mode 100644
index 0000000000..41a027667c
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/address_of.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/alternative.hpp b/src/lib/eolian_cxx/grammar/alternative.hpp
new file mode 100644
index 0000000000..2d70052f45
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/alternative.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/attribute_conditional.hpp b/src/lib/eolian_cxx/grammar/attribute_conditional.hpp
new file mode 100644
index 0000000000..1fab57d897
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/attribute_conditional.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/attribute_reorder.hpp b/src/lib/eolian_cxx/grammar/attribute_reorder.hpp
new file mode 100644
index 0000000000..b3f8b3196b
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/attribute_reorder.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/attribute_replace.hpp b/src/lib/eolian_cxx/grammar/attribute_replace.hpp
new file mode 100644
index 0000000000..448abc23b2
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/attribute_replace.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/attributes.hpp b/src/lib/eolian_cxx/grammar/attributes.hpp
new file mode 100644
index 0000000000..4e63676712
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/attributes.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/base_class_definition.hpp b/src/lib/eolian_cxx/grammar/base_class_definition.hpp
new file mode 100644
index 0000000000..29b68133f7
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/base_class_definition.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/c_type.hpp b/src/lib/eolian_cxx/grammar/c_type.hpp
new file mode 100644
index 0000000000..b963a77873
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/c_type.hpp
@@ -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{&param.c_type});
+ case parameter_direction::out:
+ case parameter_direction::inout:
+ return param.type.original_type.visit(c_type_visitor{&param.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
diff --git a/src/lib/eolian_cxx/grammar/case.hpp b/src/lib/eolian_cxx/grammar/case.hpp
new file mode 100644
index 0000000000..e6599910ec
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/case.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/class_declaration.hpp b/src/lib/eolian_cxx/grammar/class_declaration.hpp
new file mode 100644
index 0000000000..f117f1330d
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/class_declaration.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/class_definition.hpp b/src/lib/eolian_cxx/grammar/class_definition.hpp
new file mode 100644
index 0000000000..7473ae8ff0
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/class_definition.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/class_implementation.hpp b/src/lib/eolian_cxx/grammar/class_implementation.hpp
new file mode 100644
index 0000000000..a3c1d01f54
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/class_implementation.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/comment.hh b/src/lib/eolian_cxx/grammar/comment.hh
deleted file mode 100644
index 21fa3ea38d..0000000000
--- a/src/lib/eolian_cxx/grammar/comment.hh
+++ /dev/null
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/container.hpp b/src/lib/eolian_cxx/grammar/container.hpp
new file mode 100644
index 0000000000..4612612360
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/container.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/context.hpp b/src/lib/eolian_cxx/grammar/context.hpp
new file mode 100644
index 0000000000..9b5e164470
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/context.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/converting_argument.hpp b/src/lib/eolian_cxx/grammar/converting_argument.hpp
new file mode 100644
index 0000000000..0f512ca698
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/converting_argument.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh b/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh
deleted file mode 100644
index 03d6283b0a..0000000000
--- a/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh
+++ /dev/null
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/eo_class_events_generator.hh b/src/lib/eolian_cxx/grammar/eo_class_events_generator.hh
deleted file mode 100644
index 95e155ce58..0000000000
--- a/src/lib/eolian_cxx/grammar/eo_class_events_generator.hh
+++ /dev/null
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh b/src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh
deleted file mode 100644
index f99254c322..0000000000
--- a/src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh
+++ /dev/null
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/eo_class_generator.hh b/src/lib/eolian_cxx/grammar/eo_class_generator.hh
deleted file mode 100644
index e1545fc875..0000000000
--- a/src/lib/eolian_cxx/grammar/eo_class_generator.hh
+++ /dev/null
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/eo_class_scope_guard_generator.hh b/src/lib/eolian_cxx/grammar/eo_class_scope_guard_generator.hh
deleted file mode 100644
index 5915c38beb..0000000000
--- a/src/lib/eolian_cxx/grammar/eo_class_scope_guard_generator.hh
+++ /dev/null
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/eo_header_generator.hh b/src/lib/eolian_cxx/grammar/eo_header_generator.hh
deleted file mode 100644
index 0b0fc55a36..0000000000
--- a/src/lib/eolian_cxx/grammar/eo_header_generator.hh
+++ /dev/null
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/eps.hpp b/src/lib/eolian_cxx/grammar/eps.hpp
new file mode 100644
index 0000000000..e47d5f5499
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/eps.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/function_declaration.hpp b/src/lib/eolian_cxx/grammar/function_declaration.hpp
new file mode 100644
index 0000000000..aabf8a2dba
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/function_declaration.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/function_definition.hpp b/src/lib/eolian_cxx/grammar/function_definition.hpp
new file mode 100644
index 0000000000..8be8bba9e3
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/function_definition.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/generator.hpp b/src/lib/eolian_cxx/grammar/generator.hpp
new file mode 100644
index 0000000000..1100befddf
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/generator.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/header.hpp b/src/lib/eolian_cxx/grammar/header.hpp
new file mode 100644
index 0000000000..96e123593c
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/header.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/header_guards.hpp b/src/lib/eolian_cxx/grammar/header_guards.hpp
new file mode 100644
index 0000000000..6ab743afee
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/header_guards.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/header_include_directive.hpp b/src/lib/eolian_cxx/grammar/header_include_directive.hpp
new file mode 100644
index 0000000000..6049491397
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/header_include_directive.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/impl_header.hpp b/src/lib/eolian_cxx/grammar/impl_header.hpp
new file mode 100644
index 0000000000..0827eb3aab
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/impl_header.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/implementation_include_directive.hpp b/src/lib/eolian_cxx/grammar/implementation_include_directive.hpp
new file mode 100644
index 0000000000..01f89cf74d
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/implementation_include_directive.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/indentation.hpp b/src/lib/eolian_cxx/grammar/indentation.hpp
new file mode 100644
index 0000000000..7a64511511
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/indentation.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh b/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh
deleted file mode 100644
index 5cee5e297d..0000000000
--- a/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh
+++ /dev/null
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/keyword.hpp b/src/lib/eolian_cxx/grammar/keyword.hpp
new file mode 100644
index 0000000000..9359892f9c
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/keyword.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/klass_def.hpp b/src/lib/eolian_cxx/grammar/klass_def.hpp
new file mode 100644
index 0000000000..e9c988f795
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/klass_def.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/kleene.hpp b/src/lib/eolian_cxx/grammar/kleene.hpp
new file mode 100644
index 0000000000..8c3088fb03
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/kleene.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/list.hpp b/src/lib/eolian_cxx/grammar/list.hpp
new file mode 100644
index 0000000000..c8d96240d8
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/list.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/meta.hpp b/src/lib/eolian_cxx/grammar/meta.hpp
new file mode 100644
index 0000000000..1a06f94dfd
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/meta.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/namespace.hpp b/src/lib/eolian_cxx/grammar/namespace.hpp
new file mode 100644
index 0000000000..db5871c318
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/namespace.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/namespace_generator.hh b/src/lib/eolian_cxx/grammar/namespace_generator.hh
deleted file mode 100644
index 7f885ce6d4..0000000000
--- a/src/lib/eolian_cxx/grammar/namespace_generator.hh
+++ /dev/null
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/parameter.hpp b/src/lib/eolian_cxx/grammar/parameter.hpp
new file mode 100644
index 0000000000..cd30464e21
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/parameter.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/parameters_generator.hh b/src/lib/eolian_cxx/grammar/parameters_generator.hh
deleted file mode 100644
index dd692f3044..0000000000
--- a/src/lib/eolian_cxx/grammar/parameters_generator.hh
+++ /dev/null
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/qualifier_def.hpp b/src/lib/eolian_cxx/grammar/qualifier_def.hpp
new file mode 100644
index 0000000000..0f5de4a17d
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/qualifier_def.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/sequence.hpp b/src/lib/eolian_cxx/grammar/sequence.hpp
new file mode 100644
index 0000000000..96fb467af2
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/sequence.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/string.hpp b/src/lib/eolian_cxx/grammar/string.hpp
new file mode 100644
index 0000000000..a8a00a8da0
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/string.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/tab.hh b/src/lib/eolian_cxx/grammar/tab.hh
deleted file mode 100644
index e775bfffaf..0000000000
--- a/src/lib/eolian_cxx/grammar/tab.hh
+++ /dev/null
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/type.hpp b/src/lib/eolian_cxx/grammar/type.hpp
new file mode 100644
index 0000000000..2ba37442da
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/type.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/type_generator.hh b/src/lib/eolian_cxx/grammar/type_generator.hh
deleted file mode 100644
index 43cd1d2c34..0000000000
--- a/src/lib/eolian_cxx/grammar/type_generator.hh
+++ /dev/null
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/type_impl.hpp b/src/lib/eolian_cxx/grammar/type_impl.hpp
new file mode 100644
index 0000000000..5b8e7f2b7e
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/type_impl.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/type_traits.hpp b/src/lib/eolian_cxx/grammar/type_traits.hpp
new file mode 100644
index 0000000000..8e5e52e34b
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/type_traits.hpp
@@ -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
diff --git a/src/lib/eolian_cxx/grammar/variant.hpp b/src/lib/eolian_cxx/grammar/variant.hpp
new file mode 100644
index 0000000000..195c0a484b
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/variant.hpp
@@ -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
diff --git a/src/tests/eolian_cxx/callback.c b/src/tests/eolian_cxx/callback.c
deleted file mode 100644
index aee32370cb..0000000000
--- a/src/tests/eolian_cxx/callback.c
+++ /dev/null
@@ -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"
diff --git a/src/tests/eolian_cxx/callback.eo b/src/tests/eolian_cxx/callback.eo
index c05f64e293..9860281d6f 100644
--- a/src/tests/eolian_cxx/callback.eo
+++ b/src/tests/eolian_cxx/callback.eo
@@ -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;
}
}
diff --git a/src/tests/eolian_cxx/complex.c b/src/tests/eolian_cxx/complex.c
index a61072bdc1..2eb381c045 100644
--- a/src/tests/eolian_cxx/complex.c
+++ b/src/tests/eolian_cxx/complex.c
@@ -1,4 +1,9 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <Eina.h>
#include <Eo.h>
struct Complex_Data {};
diff --git a/src/tests/eolian_cxx/complex.eo b/src/tests/eolian_cxx/complex.eo
index b84cd09964..d7672e7182 100644
--- a/src/tests/eolian_cxx/complex.eo
+++ b/src/tests/eolian_cxx/complex.eo
@@ -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>;
+ }
+ }
}
}
diff --git a/src/tests/eolian_cxx/complex_cxx.cc b/src/tests/eolian_cxx/complex_cxx.cc
index b43e8be1ff..72f4608b7f 100644
--- a/src/tests/eolian_cxx/complex_cxx.cc
+++ b/src/tests/eolian_cxx/complex_cxx.cc
@@ -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;
diff --git a/src/tests/eolian_cxx/eolian_cxx_suite.cc b/src/tests/eolian_cxx/eolian_cxx_suite.cc
index f925b09edf..562eb82ebf 100644
--- a/src/tests/eolian_cxx/eolian_cxx_suite.cc
+++ b/src/tests/eolian_cxx/eolian_cxx_suite.cc
@@ -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 },
diff --git a/src/tests/eolian_cxx/eolian_cxx_suite.h b/src/tests/eolian_cxx/eolian_cxx_suite.h
index 73e6dc2169..451154a325 100644
--- a/src/tests/eolian_cxx/eolian_cxx_suite.h
+++ b/src/tests/eolian_cxx/eolian_cxx_suite.h
@@ -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);
diff --git a/src/tests/eolian_cxx/eolian_cxx_test_binding.cc b/src/tests/eolian_cxx/eolian_cxx_test_binding.cc
index b705e67732..83cb394658 100644
--- a/src/tests/eolian_cxx/eolian_cxx_test_binding.cc
+++ b/src/tests/eolian_cxx/eolian_cxx_test_binding.cc
@@ -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(std::bind([&called1] { called1 = true; }))
- );
+ nonamespace::Generic g
+ (
+ [&]
+ {
+ g.required_ctor_a(1);
+ g.required_ctor_b(2);
+ }
+ );
- 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(std::bind([&called1] { called1 = true; })),
- g.optional_ctor_a(3),
- g.optional_ctor_b(std::bind([&called2] { called2 = true; }))
- );
+ nonamespace::Generic g
+ (
+ [&]
+ {
+ g.required_ctor_a(2);
+ g.required_ctor_b(4);
+ g.optional_ctor_a(3);
+ g.optional_ctor_b(5);
+ }
+ );
- 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);
}
diff --git a/src/tests/eolian_cxx/eolian_cxx_test_callback.cc b/src/tests/eolian_cxx/eolian_cxx_test_callback.cc
deleted file mode 100644
index c22141307f..0000000000
--- a/src/tests/eolian_cxx/eolian_cxx_test_callback.cc
+++ /dev/null
@@ -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, &times_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);
-}
diff --git a/src/tests/eolian_cxx/eolian_cxx_test_generate.cc b/src/tests/eolian_cxx/eolian_cxx_test_generate.cc
index acb32dd8e2..a6f0f110d3 100644
--- a/src/tests/eolian_cxx/eolian_cxx_test_generate.cc
+++ b/src/tests/eolian_cxx/eolian_cxx_test_generate.cc
@@ -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
diff --git a/src/tests/eolian_cxx/eolian_cxx_test_inheritance.cc b/src/tests/eolian_cxx/eolian_cxx_test_inheritance.cc
index 8af557a2c5..5dc6b94773 100644
--- a/src/tests/eolian_cxx/eolian_cxx_test_inheritance.cc
+++ b/src/tests/eolian_cxx/eolian_cxx_test_inheritance.cc
@@ -9,35 +9,35 @@
#include "eolian_cxx_suite.h"
-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;
- }
-};
-
-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
+// 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;
+// }
+// };
+
+// 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
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);
}
diff --git a/src/tests/eolian_cxx/eolian_cxx_test_wrapper.cc b/src/tests/eolian_cxx/eolian_cxx_test_wrapper.cc
index 3441a8975b..971bb77886 100644
--- a/src/tests/eolian_cxx/eolian_cxx_test_wrapper.cc
+++ b/src/tests/eolian_cxx/eolian_cxx_test_wrapper.cc
@@ -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));
diff --git a/src/tests/eolian_cxx/generic.c b/src/tests/eolian_cxx/generic.c
index b0a32f6741..2ea56262c3 100644
--- a/src/tests/eolian_cxx/generic.c
+++ b/src/tests/eolian_cxx/generic.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)
+{
+ return pd->opt_ctor_b_val;
+}
+
+/* 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->req_ctor_b_cb)
- pd->req_ctor_b_cb(pd->req_ctor_b_data);
+ *value = pd->req_ctor_a_val;
}
-static void _generic_call_opt_ctor_b_callback(Eo *obj EINA_UNUSED, Generic_Data *pd)
+static void _generic_out_required_ctor_b(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_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"
diff --git a/src/tests/eolian_cxx/generic.eo b/src/tests/eolian_cxx/generic.eo
index cbff67aed5..20f471ba83 100644
--- a/src/tests/eolian_cxx/generic.eo
+++ b/src/tests/eolian_cxx/generic.eo
@@ -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;
+ }
+ }
+
+ @property req_ctor_b_value {
+ get {}
+ values {
+ value: int;
}
}
- call_req_ctor_b_callback {
+ @property opt_ctor_b_value {
+ get {}
+ values {
+ value: int;
+ }
}
- call_opt_ctor_b_callback {
+ 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;
+ }
}
diff --git a/src/tests/eolian_cxx/name1_name2_type_generation.c b/src/tests/eolian_cxx/name1_name2_type_generation.c
new file mode 100644
index 0000000000..28b8c853ad
--- /dev/null
+++ b/src/tests/eolian_cxx/name1_name2_type_generation.c
@@ -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"
diff --git a/src/tests/eolian_cxx/name1_name2_type_generation.eo b/src/tests/eolian_cxx/name1_name2_type_generation.eo
new file mode 100644
index 0000000000..66b6461a81
--- /dev/null
+++ b/src/tests/eolian_cxx/name1_name2_type_generation.eo
@@ -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;
+ }
+ }
+ }
+}
diff --git a/src/tests/eolian_cxx/name_name_cxx.cc b/src/tests/eolian_cxx/name_name_cxx.cc
index d5669bc5f6..003b526529 100644
--- a/src/tests/eolian_cxx/name_name_cxx.cc
+++ b/src/tests/eolian_cxx/name_name_cxx.cc
@@ -1,4 +1,8 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <Eo.h>
#include "name_name.eo.h"