eolian-cxx: Rewrite to accomodate new features of the C++ binding
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>
Mon, 6 Jun 2016 05:54:36 +0000 (02:54 -0300)
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>
Mon, 6 Jun 2016 05:54:36 +0000 (02:54 -0300)
98 files changed:
src/Makefile_Cxx.am
src/Makefile_Eolian_Cxx.am
src/bin/eolian_cxx/convert.cc [deleted file]
src/bin/eolian_cxx/convert.hh [deleted file]
src/bin/eolian_cxx/convert_comments.cc [deleted file]
src/bin/eolian_cxx/convert_comments.hh [deleted file]
src/bin/eolian_cxx/eolian_cxx.cc
src/bin/eolian_cxx/eolian_wrappers.hh [deleted file]
src/bin/eolian_cxx/safe_strings.hh [deleted file]
src/bin/eolian_cxx/type_lookup.hh [deleted file]
src/bin/eolian_cxx/type_lookup_table.cc [deleted file]
src/bindings/cxx/eo_cxx/Eo.hh
src/bindings/cxx/eo_cxx/eo_concrete.hh
src/bindings/cxx/eo_cxx/eo_cxx_interop.hh
src/bindings/cxx/eo_cxx/eo_event.hh
src/bindings/cxx/eo_cxx/eo_inherit.hh
src/examples/elementary/bg_cxx_example_01.cc
src/examples/elementary/button_cxx_example_00.cc
src/examples/eolian_cxx/Makefile.am
src/examples/eolian_cxx/colourable.c
src/examples/eolian_cxx/colourable_cxx.cc
src/examples/eolian_cxx/colourablesquare.c
src/examples/eolian_cxx/colourablesquare_cxx.cc
src/examples/eolian_cxx/eolian_cxx_simple_01.cc
src/examples/eolian_cxx/ns_colourable.eo
src/examples/eolian_cxx/ns_colourablesquare.eo
src/lib/eolian_cxx/Eolian_Cxx.hh
src/lib/eolian_cxx/eo_generate.hh [deleted file]
src/lib/eolian_cxx/eo_types.hh [deleted file]
src/lib/eolian_cxx/eo_validate.hh [deleted file]
src/lib/eolian_cxx/grammar/address_of.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/alternative.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/attribute_conditional.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/attribute_reorder.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/attribute_replace.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/attributes.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/base_class_definition.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/c_type.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/case.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/class_declaration.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/class_definition.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/class_implementation.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/comment.hh [deleted file]
src/lib/eolian_cxx/grammar/container.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/context.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/converting_argument.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh [deleted file]
src/lib/eolian_cxx/grammar/eo_class_events_generator.hh [deleted file]
src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh [deleted file]
src/lib/eolian_cxx/grammar/eo_class_generator.hh [deleted file]
src/lib/eolian_cxx/grammar/eo_class_scope_guard_generator.hh [deleted file]
src/lib/eolian_cxx/grammar/eo_header_generator.hh [deleted file]
src/lib/eolian_cxx/grammar/eps.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/function_declaration.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/function_definition.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/generator.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/header.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/header_guards.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/header_include_directive.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/impl_header.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/implementation_include_directive.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/indentation.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/inheritance_base_generator.hh [deleted file]
src/lib/eolian_cxx/grammar/keyword.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/klass_def.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/kleene.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/list.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/meta.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/namespace.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/namespace_generator.hh [deleted file]
src/lib/eolian_cxx/grammar/parameter.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/parameters_generator.hh [deleted file]
src/lib/eolian_cxx/grammar/qualifier_def.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/sequence.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/string.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/tab.hh [deleted file]
src/lib/eolian_cxx/grammar/type.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/type_generator.hh [deleted file]
src/lib/eolian_cxx/grammar/type_impl.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/type_traits.hpp [new file with mode: 0644]
src/lib/eolian_cxx/grammar/variant.hpp [new file with mode: 0644]
src/tests/eolian_cxx/callback.c [deleted file]
src/tests/eolian_cxx/callback.eo
src/tests/eolian_cxx/complex.c
src/tests/eolian_cxx/complex.eo
src/tests/eolian_cxx/complex_cxx.cc
src/tests/eolian_cxx/eolian_cxx_suite.cc
src/tests/eolian_cxx/eolian_cxx_suite.h
src/tests/eolian_cxx/eolian_cxx_test_binding.cc
src/tests/eolian_cxx/eolian_cxx_test_callback.cc [deleted file]
src/tests/eolian_cxx/eolian_cxx_test_generate.cc
src/tests/eolian_cxx/eolian_cxx_test_inheritance.cc
src/tests/eolian_cxx/eolian_cxx_test_wrapper.cc
src/tests/eolian_cxx/generic.c
src/tests/eolian_cxx/generic.eo
src/tests/eolian_cxx/name1_name2_type_generation.c [new file with mode: 0644]
src/tests/eolian_cxx/name1_name2_type_generation.eo [new file with mode: 0644]
src/tests/eolian_cxx/name_name_cxx.cc

index 9a199bd..4343b5d 100644 (file)
@@ -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     \
index 57dc265..981cca5 100644 (file)
@@ -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 (file)
index 97e88c9..0000000
+++ /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 (file)
index df829f4..0000000
+++ /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 (file)
index 94fed90..0000000
+++ /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 (file)
index 788362e..0000000
+++ /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
index d7f3d93..12cd5f4 100644 (file)
 #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 (file)
index c2b8f66..0000000
+++ /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 (file)
index 4601af6..0000000
+++ /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 (file)
index 9410bdf..0000000
+++ /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 (file)
index 046b8b8..0000000
+++ /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"}},
-};
-
-}
index a6f0423..b7d1e85 100644 (file)
@@ -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
index c975bbc..11d2c5b 100644 (file)
@@ -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 {
index a588b5b..a19bb24 100644 (file)
@@ -7,6 +7,7 @@
 #include <utility>
 #include <type_traits>
 #include <initializer_list>
+#include <future>
 
 #include <Eina.hh>
 #include <Eo.hh>
 
 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
index 320bfc9..2120121 100644 (file)
@@ -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());
 }
 
 } }
index a05d11f..96ee1dc 100644 (file)
 
-///
-/// @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
index 9fe20f4..a1db40a 100644 (file)
@@ -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();
index a18d652..c12f504 100644 (file)
@@ -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();
index 8b6b68f..f0b82d1 100644 (file)
@@ -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
 
index dd2cc11..04c233a 100644 (file)
@@ -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
index 513e3dc..30f1bb3 100644 (file)
@@ -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
index f367c59..f67d3e2 100644 (file)
@@ -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
index b4c92b8..ecaf757 100644 (file)
@@ -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
index 0bf9642..eb093d9 100644 (file)
@@ -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());
index 90abc65..21af926 100644 (file)
@@ -1,7 +1,6 @@
 class Ns.Colourable (Eo.Base)
 {
     [[Colourable class.]]
-    legacy_prefix: legacy;
     data: Colourable_Data;
     methods {
         rgb_24bits_constructor {
index 70fb471..66fe8ae 100644 (file)
@@ -1,6 +1,5 @@
 class Ns.ColourableSquare (Ns.Colourable)
 {
-    legacy_prefix: legacy;
     data: ColourableSquare_Data;
     methods {
         @property size {
index dfa7482..5a8ea81 100644 (file)
@@ -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 (file)
index 97e53bb..0000000
+++ /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 (file)
index 4431d3b..0000000
+++ /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 (file)
index 8ffa7dc..0000000
+++ /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 (file)
index 0000000..41a0276
--- /dev/null
@@ -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 (file)
index 0000000..2d70052
--- /dev/null
@@ -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 (file)
index 0000000..1fab57d
--- /dev/null
@@ -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 (file)
index 0000000..b3f8b31
--- /dev/null
@@ -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 (file)
index 0000000..448abc2
--- /dev/null
@@ -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 (file)
index 0000000..4e63676
--- /dev/null
@@ -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 (file)
index 0000000..29b6813
--- /dev/null
@@ -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 (file)
index 0000000..b963a77
--- /dev/null
@@ -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 (file)
index 0000000..e659991
--- /dev/null
@@ -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 (file)
index 0000000..f117f13
--- /dev/null
@@ -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 (file)
index 0000000..7473ae8
--- /dev/null
@@ -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 (file)
index 0000000..a3c1d01
--- /dev/null
@@ -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 (file)
index 21fa3ea..0000000
+++ /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 (file)
index 0000000..4612612
--- /dev/null
@@ -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 (file)
index 0000000..9b5e164
--- /dev/null
@@ -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 (file)
index 0000000..0f512ca
--- /dev/null
@@ -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 (file)
index 03d6283..0000000
+++ /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 (file)
index 95e155c..0000000
+++ /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 (file)
index f99254c..0000000
+++ /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 (file)
index e1545fc..0000000
+++ /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 (file)
index 5915c38..0000000
+++ /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 (file)
index 0b0fc55..0000000
+++ /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 (file)
index 0000000..e47d5f5
--- /dev/null
@@ -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 (file)
index 0000000..aabf8a2
--- /dev/null
@@ -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 (file)
index 0000000..8be8bba
--- /dev/null
@@ -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 (file)
index 0000000..1100bef
--- /dev/null
@@ -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 (file)
index 0000000..96e1235
--- /dev/null
@@ -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 (file)
index 0000000..6ab743a
--- /dev/null
@@ -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 (file)
index 0000000..6049491
--- /dev/null
@@ -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 (file)
index 0000000..0827eb3
--- /dev/null
@@ -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 (file)
index 0000000..01f89cf
--- /dev/null
@@ -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 (file)
index 0000000..7a64511
--- /dev/null
@@ -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 (file)
index 5cee5e2..0000000
+++ /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 (file)
index 0000000..9359892
--- /dev/null
@@ -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 (file)
index 0000000..e9c988f
--- /dev/null
@@ -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 (file)
index 0000000..8c3088f
--- /dev/null
@@ -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 (file)
index 0000000..c8d9624
--- /dev/null
@@ -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 (file)
index 0000000..1a06f94
--- /dev/null
@@ -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 (file)
index 0000000..db5871c
--- /dev/null
@@ -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 (file)
index 7f885ce..0000000
+++ /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 (file)
index 0000000..cd30464
--- /dev/null
@@ -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 (file)
index dd692f3..0000000
+++ /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 (file)
index 0000000..0f5de4a
--- /dev/null
@@ -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 (file)
index 0000000..96fb467
--- /dev/null
@@ -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 (file)
index 0000000..a8a00a8
--- /dev/null
@@ -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 (file)
index e775bff..0000000
+++ /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 (file)
index 0000000..2ba3744
--- /dev/null
@@ -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 (file)
index 43cd1d2..0000000
+++ /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 (file)
index 0000000..5b8e7f2
--- /dev/null
@@ -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 (file)
index 0000000..8e5e52e
--- /dev/null
@@ -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 (file)
index 0000000..195c0a4
--- /dev/null
@@ -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 (file)
index aee3237..0000000
+++ /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"
index c05f64e..9860281 100644 (file)
@@ -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;
    }
 }
index a61072b..2eb381c 100644 (file)
@@ -1,4 +1,9 @@
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <Eina.h>
 #include <Eo.h>
 
 struct Complex_Data {};
index b84cd09..d7672e7 100644 (file)
@@ -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>;
+         }
+      }
    }
 }
 
index b43e8be..72f4608 100644 (file)
@@ -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;
index f925b09..562eb82 100644 (file)
@@ -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 },
index 73e6dc2..451154a 100644 (file)
@@ -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);
index b705e67..83cb394 100644 (file)
@@ -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 (file)
index c221413..0000000
+++ /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);
-}
index acb32dd..a6f0f11 100644 (file)
@@ -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
 
index 8af557a..5dc6b94 100644 (file)
@@ -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);
 }
index 3441a89..971bb77 100644 (file)
@@ -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));
index b0a32f6..2ea5626 100644 (file)
@@ -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"
index cbff67a..20f471b 100644 (file)
@@ -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 (file)
index 0000000..28b8c85
--- /dev/null
@@ -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 (file)
index 0000000..66b6461
--- /dev/null
@@ -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;
+       }
+     }
+  }
+}
index d5669bc..003b526 100644 (file)
@@ -1,4 +1,8 @@
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <Eo.h>
 
 #include "name_name.eo.h"