aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2018-01-13 19:24:17 -0200
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2018-01-13 19:24:17 -0200
commitf8e36dce771c6ff0b44e4714437dc143b9354c9a (patch)
tree815281cd0f8f361503b6efc1380a6fff486c80a1
parentefl-js: Lots of changes (diff)
downloadefl-f8e36dce771c6ff0b44e4714437dc143b9354c9a.tar.gz
eolian-js: Add lazy grouping feature
-rw-r--r--src/Makefile_Efl_Js.am40
-rw-r--r--src/bin/eolian_js/main.cc382
-rw-r--r--src/bindings/cxx/eina_cxx/eina_aligned_union.hh10
-rw-r--r--src/bindings/cxx/eina_cxx/eina_tpl_char_switch.hh1005
-rw-r--r--src/bindings/cxx/eina_cxx/eina_tuple.hh166
-rw-r--r--src/bindings/js/efl_js/efl_js.cc156
-rw-r--r--src/bindings/js/eo_js/eo_js_list.hh160
-rw-r--r--src/bindings/js/eo_js/eo_js_namespace_tree.hh291
8 files changed, 2084 insertions, 126 deletions
diff --git a/src/Makefile_Efl_Js.am b/src/Makefile_Efl_Js.am
index addf072949..e253fa70e4 100644
--- a/src/Makefile_Efl_Js.am
+++ b/src/Makefile_Efl_Js.am
@@ -56,33 +56,16 @@ bin_efl_js_eflv8js_LDADD = \
endif
-# @echo @ECHO_E@ "#ifdef HAVE_CONFIG_H" > $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "#include \"config.h\"" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "#include \"elementary_config.h\"" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "#endif\n" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "#include <Efl.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "#include <Efl_Config.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "#include <Ecore.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "#include <Eo.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "#include <Ecore_Con.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "#include <Ecore_Audio.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "#include <Evas.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "#include <Edje.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "#include <Ecore_Con_Eet.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "#include <Emotion.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "#define ELM_INTERNAL_API_ARGESFSDFEFC" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "#include <Elementary.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "extern \"C\" {" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "#include <elm_widget.h>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "}\n" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "#include <Eina_Js.hh>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-# @echo @ECHO_E@ "#include <Eo_Js.hh>" >> $(top_builddir)/src/bindings/js/efl_js/eolian_js_bindings.cc
-
-bindings/js/efl_js/eolian_js_bindings.hh: $(GENERATED_JS_BINDINGS)
- @echo @ECHO_E@ "" > $@
- @for i in $(GENERATED_JS_BINDINGS); do echo "#include <$$i>" >> $@; done
-
-CLEANFILES += bindings/js/efl_js/eolian_js_bindings.hh
+ordered_generated_js_bindings = $(sort $(GENERATED_JS_BINDINGS))
+
+AM_V_EOLJS_LINK = $(am__v_EOLJS_LINK_@AM_V@)
+am__v_EOLJS_LINK_ = $(am__v_EOLJS_LINK_@AM_DEFAULT_V@)
+am__v_EOLJS__LINK_0 = @echo " EOLJS_LINK " $@;
+
+bindings/js/efl_js/eolian_js_bindings.js.hh: $(GENERATED_JS_BINDINGS:%.eo.js.cc=%.eo) $(_EOLIAN_JS_DEP)
+ $(AM_V_EOLJS_LINK)$(EOLIAN_JS) -l $(EOLIAN_FLAGS) -o $@ $(filter %.eo, $(^))
+
+CLEANFILES += bindings/js/efl_js/eolian_js_bindings.js.hh
## Install Ecore-JS headers
installed_ecorejsheadersdir = $(includedir)/ecore-js-@VMAJ@
@@ -164,12 +147,13 @@ bindings/js/eio_js/eio_js.cc \
bindings/js/efl_js/efl_js.cc \
bindings/js/ethumb_js/ethumb_js_client.cc
-bindings/js/efl_js/bindings_js_efl_js_libefl_js_la-efl_js.l$(OBJEXT): bindings/js/efl_js/eolian_js_bindings.hh
+bindings/js/efl_js/bindings_js_efl_js_libefl_js_la-efl_js.l$(OBJEXT): bindings/js/efl_js/eolian_js_bindings.js.hh
bindings/js/efl_js/efl_js.cc $(bindings_js_efl_js_libefl_js_la_SOURCES): $(ecore_eolian_cxx_public_hh) $(ecore_eolian_cxx_public_impl_hh) $(eo_eolian_cxx_public_hh) $(eo_eolian_cxx_public_impl_hh) $(efl_eolian_cxx_public_hh) $(efl_eolian_cxx_public_impl_hh) lib/ecore/Ecore.eo.hh
bindings_js_efl_js_libefl_js_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
-I$(top_srcdir)/src/lib/efl \
+-I$(top_builddir)/src/bindings/js/efl_js \
-I$(top_builddir)/src/lib/efl/interfaces/ \
-I$(top_builddir)/src/lib/evas/canvas/ \
-I$(top_builddir)/src/lib/evas/gesture/ \
diff --git a/src/bin/eolian_js/main.cc b/src/bin/eolian_js/main.cc
index 4921a58525..a68e7cbb16 100644
--- a/src/bin/eolian_js/main.cc
+++ b/src/bin/eolian_js/main.cc
@@ -24,6 +24,7 @@
#include <cstdlib>
#include <vector>
#include <set>
+#include <map>
namespace eolian { namespace js {
@@ -438,6 +439,8 @@ int main(int argc, char** argv)
std::vector<std::string> include_paths;
std::string out_file, in_file;
+ std::vector<std::string> in_files;
+ bool linking = false;
efl::eina::eina_init eina_init;
struct eolian_init
@@ -452,9 +455,10 @@ int main(int argc, char** argv)
{ "out-file", required_argument, 0, 'o' },
{ "version", no_argument, 0, 'v' },
{ "help", no_argument, 0, 'h' },
+ { "link", no_argument, 0, 'l' },
{ 0, 0, 0, 0 }
};
- const char* options = "I:D:o:c:arvh";
+ const char* options = "I:D:o:c:arvhl";
// get command line options
int c, idx;
@@ -463,6 +467,7 @@ int main(int argc, char** argv)
if (c == 'I')
{
include_paths.push_back(optarg);
+ std::cout << "-I" << optarg << std::endl;
}
else if (c == 'o')
{
@@ -483,114 +488,327 @@ int main(int argc, char** argv)
// _print_version();
// if (argc == 2) exit(EXIT_SUCCESS);
}
+ else if(c == 'l')
+ {
+ linking = true;
+ }
}
- if (optind == argc-1)
+ std::cout << "optind " << optind << " argc " << argc << std::endl;
+
+ std::ofstream os (out_file.c_str());
+ if(!os.is_open())
{
- in_file = argv[optind];
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "Couldn't open output file " << out_file;
+ return -1;
}
- Eolian* eolian = eolian_new();
- Eolian_Unit* eolian_unit = static_cast<Eolian_Unit*>(static_cast<void*>(eolian));
-
- // Add include paths to eolian library
- for(auto src : include_paths)
- if (!::eolian_directory_scan(eolian, src.c_str()))
+ EINA_CXX_DOM_LOG_DBG(eolian::js::domain) << "output was opened";
+
+ if(!linking)
+ {
+ Eolian* eolian = eolian_new();
+ Eolian_Unit* eolian_unit = static_cast<Eolian_Unit*>(static_cast<void*>(eolian));
+
+ if (optind == argc-1)
+ {
+ in_file = argv[optind];
+ }
+
+ // Add include paths to eolian library
+ for(auto src : include_paths)
+ if (!::eolian_directory_scan(eolian, src.c_str()))
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain)
+ << "Couldn't load eolian from '" << src << "'.";
+ }
+ if (!::eolian_all_eot_files_parse(eolian))
{
EINA_CXX_DOM_LOG_WARN(eolian::js::domain)
- << "Couldn't load eolian from '" << src << "'.";
+ << "Eolian failed parsing eot files";
+ assert(false && "Error parsing eot files");
+ }
+ if (!::eolian_file_parse(eolian, in_file.c_str()))
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain)
+ << "Failed parsing: " << in_file << ".";
+ assert(false && "Error parsing input file");
}
- if (!::eolian_all_eot_files_parse(eolian))
- {
- EINA_CXX_DOM_LOG_WARN(eolian::js::domain)
- << "Eolian failed parsing eot files";
- assert(false && "Error parsing eot files");
- }
- if (!::eolian_file_parse(eolian, in_file.c_str()))
- {
- EINA_CXX_DOM_LOG_WARN(eolian::js::domain)
- << "Failed parsing: " << in_file << ".";
- assert(false && "Error parsing input file");
- }
- // Create filename path for output
- std::string file_basename;
- const Eolian_Class *klass = NULL;
- {
- char* dup = strdup(in_file.c_str());
- char *bn = basename(dup);
- klass = ::eolian_class_get_by_file(eolian_unit, bn);
- file_basename = bn;
- free(dup);
- }
- if(!klass)
+ // Create filename path for output
+ std::string file_basename;
+ const Eolian_Class *klass = NULL;
{
- EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "could not find any class defined in this eo file";
- return -1;
+ char* dup = strdup(in_file.c_str());
+ char *bn = basename(dup);
+ klass = ::eolian_class_get_by_file(eolian_unit, bn);
+ file_basename = bn;
+ free(dup);
}
+ if(!klass)
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "could not find any class defined in this eo file";
+ return -1;
+ }
- std::ofstream os (out_file.c_str());
- if(!os.is_open())
- {
- EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "Couldn't open output file " << out_file;
- return -1;
+
+ std::ostream_iterator<char> iterator = std::ostream_iterator<char>(os);
+
+ // probably not eot file
+ if(klass)
+ {
+ os << "#if !defined(EFL_JAVASCRIPT_EOLIAN_GENERATE_REGISTER_STRUCT)\n";
+ // function to iterate through all inheritance class
+ std::function<void(Eolian_Class const*, std::function<void(Eolian_Class const*)>)>
+ recurse_inherits
+ = [&] (Eolian_Class const* klass, std::function<void(Eolian_Class const*)> function)
+ {
+ for(efl::eina::iterator<const char> first ( ::eolian_class_inherits_get(klass))
+ , last; first != last; ++first)
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << &*first << std::endl;
+ Eolian_Class const* base = ::eolian_class_get_by_name(eolian_unit, &*first);
+ if(base)
+ {
+ function(base);
+ recurse_inherits(base, function);
+ }
+ }
+ };
+
+ os << "extern \"C\" {\n\n";
+
+ auto includes_fun = [&os] (Eolian_Class const* klass)
+ {
+ os << "#include <" << eolian_class_file_get(klass) << ".h>\n\n";
+ };
+ // generate include for all inheritance
+ recurse_inherits(klass, includes_fun);
+ os << "#include <" << eolian_class_file_get(klass) << ".h>\n\n";
+
+ os << "}\n\n";
+
+ using efl::eolian::grammar::attributes::unused;
+ using efl::eolian::grammar::context_null;
+ efl::eolian::grammar::attributes::klass_def klass_def(klass, eolian_unit);
+ if (!eolian::js::grammar::class_registration.generate(iterator, klass_def, context_null{}))
+ {
+ throw std::runtime_error("Failed to generate class");
+ }
+
+ os << "#else\n";
+ // if (!eolian::js::grammar::call_registration.generate(iterator, klass_def, context_null{}))
+ // {
+ // throw std::runtime_error("Failed to generate class");
+ // }
+ os << "#endif\n";
+ }
}
+ else
+ {
+ Eolian* eolian = eolian_new();
+ Eolian_Unit* eolian_unit = static_cast<Eolian_Unit*>(static_cast<void*>(eolian));
+
+ for(auto src : include_paths)
+ if (!::eolian_directory_scan(eolian, src.c_str()))
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain)
+ << "Couldn't load eolian from '" << src << "'.";
+ }
+
+ int optional_index = optind;
+ while (optional_index != argc)
+ {
+ std::cout << "opening " << argv[optional_index] << std::endl;
+ if (!::eolian_file_parse(eolian, argv[optional_index]))
+ {
+ std::cout
+ << "Failed parsing: " << argv[optional_index] << "." << std::endl;
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain)
+ << "Failed parsing: " << argv[optional_index] << ".";
+ assert(false && "Error parsing input file");
+ }
+ // in_files.push_back(argv[optind]);
+ optional_index++;
+ }
- EINA_CXX_DOM_LOG_DBG(eolian::js::domain) << "output was opened";
+ // if(!::eolian_all_eo_files_parse(eolian))
+ // {
+ // EINA_CXX_DOM_LOG_WARN(eolian::js::domain)
+ // << "Eolian failed parsing eo files";
+ // assert(false && "Error parsing eot files");
+ // }
+ if (!::eolian_all_eot_files_parse(eolian))
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian::js::domain)
+ << "Eolian failed parsing eot files";
+ assert(false && "Error parsing eot files");
+ }
-
- std::ostream_iterator<char> iterator = std::ostream_iterator<char>(os);
+ // ns -> items
+ std::map<std::string, std::set<std::string>> all_names;
- // probably not eot file
- if(klass)
- {
- os << "#ifndef EFL_JAVASCRIPT_EOLIAN_GENERATE_REGISTER_CALL\n";
- // function to iterate through all inheritance class
- std::function<void(Eolian_Class const*, std::function<void(Eolian_Class const*)>)>
- recurse_inherits
- = [&] (Eolian_Class const* klass, std::function<void(Eolian_Class const*)> function)
+ efl::eina::iterator<Eolian_Class const> klasses (eolian_all_classes_get(eolian_unit));
+ for(;klasses != efl::eina::iterator<Eolian_Class const>{}
+ ;++klasses)
{
- for(efl::eina::iterator<const char> first ( ::eolian_class_inherits_get(klass))
- , last; first != last; ++first)
+ std::string outer_namespace; // starts with global
+ std::string name = ::eolian_class_full_name_get(&*klasses);
+
+ auto iterator_old = name.begin();
+ auto iterator = std::find(iterator_old, name.end(), '.');
+ while(iterator != name.end())
{
- EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << &*first << std::endl;
- Eolian_Class const* base = ::eolian_class_get_by_name(eolian_unit, &*first);
- if(base)
+ std::string namespace_name(iterator_old, iterator);
+
+ // std::cout << "outer namespace " << outer_namespace << " name " << namespace_name << std::endl;
+
+ all_names[outer_namespace].insert(namespace_name);
+ iterator_old = std::next(iterator);
+ if(outer_namespace.empty())
+ outer_namespace = namespace_name;
+ else
{
- function(base);
- recurse_inherits(base, function);
+ outer_namespace += '.';
+ outer_namespace += namespace_name;
}
+ // std::cout << "before loop outer namespace " << outer_namespace << " name " << namespace_name << std::endl;
+ iterator = std::find(iterator_old, name.end(), '.');
}
- };
+ all_names[outer_namespace].insert({iterator_old, iterator});
+ }
- os << "extern \"C\" {\n\n";
-
- auto includes_fun = [&os] (Eolian_Class const* klass)
+ // os << "typedef efl::eo::js::namespace_object"
+ for(auto&& item : all_names)
{
- os << "#include <" << eolian_class_file_get(klass) << ".h>\n\n";
- };
- // generate include for all inheritance
- recurse_inherits(klass, includes_fun);
- os << "#include <" << eolian_class_file_get(klass) << ".h>\n\n";
+ std::vector<std::string> classes;
+
+ std::cout << "namespace " << item.first << std::endl;
+
+ for(auto&& object : item.second)
+ {
+ std::string ns = item.first;
+ if(!ns.empty())
+ ns += '.';
+ if(all_names.find(ns + object) == all_names.end()) // class name
+ classes.push_back(object);
+ }
+
+ std::cout << "generating classes structs" << std::endl;
+ //if(!classes.empty())
+ {
+ std::string classes_struct_name = item.first;
+ std::transform(classes_struct_name.begin()
+ , classes_struct_name.end()
+ , classes_struct_name.begin()
+ , [] (char c)
+ {
+ c = ::tolower(c);
+ if(c == '.')
+ c = '_';
+ return c;
+ });
+ os << "struct " << classes_struct_name << "_classes\n"
+ << "{\n"
+ << " typedef efl::eo::js::list\n"
+ " <\n";
+
+ auto cls_iterator = classes.begin();
+ while(cls_iterator != classes.end())
+ {
+ auto&& cls = *cls_iterator;
+ os << "::efl::eo::js::class_object<efl::eo::js::name<";
+ auto char_iterator = cls.begin();
+ while(char_iterator != cls.end())
+ {
+ os << "'" << *char_iterator << "'";
+ if(std::next(char_iterator) != cls.end())
+ os << ", ";
+ ++char_iterator;
+ }
+ os << ">, std::false_type>";
+ cls_iterator++;
+ if(cls_iterator != classes.end())
+ os << ", ";
+ }
+ os << "> type;\n};\n";
+
+ ///
+ }
+ }
- os << "}\n\n";
+ for(auto item_iterator = all_names.rbegin()
+ , last_item_iterator = all_names.rend()
+ ;item_iterator != last_item_iterator
+ ;++item_iterator)
+ {
+ auto&& item = *item_iterator;
+
+ std::vector<std::string> namespaces;
+ //bool is_there_classes = false;
- using efl::eolian::grammar::attributes::unused;
- using efl::eolian::grammar::context_null;
- efl::eolian::grammar::attributes::klass_def klass_def(klass, eolian_unit);
- if (!eolian::js::grammar::class_registration.generate(iterator, klass_def, context_null{}))
- {
- throw std::runtime_error("Failed to generate class");
- }
+ std::cout << "namespace " << item.first << std::endl;
- os << "#else\n";
- // if (!eolian::js::grammar::call_registration.generate(iterator, klass_def, context_null{}))
- // {
- // throw std::runtime_error("Failed to generate class");
- // }
- os << "#endif\n";
+ for(auto&& object : item.second)
+ {
+ std::cout << "searching if " << object << " is a namespace" << std::endl;
+ std::string ns = item.first;
+ if(!ns.empty())
+ ns += '.';
+ if(all_names.find(ns + object) != all_names.end()) // namespace name
+ namespaces.push_back(object);
+ }
+
+ //if(!namespaces.empty())
+ {
+ std::string classes_struct_name = item.first;
+ auto fix_name = [] (std::string& name)
+ {
+ std::transform(name.begin()
+ , name.end()
+ , name.begin()
+ , [] (char c)
+ {
+ c = ::tolower(c);
+ if(c == '.')
+ c = '_';
+ return c;
+ });
+ };
+ fix_name(classes_struct_name);
+
+ os << "struct " << classes_struct_name << "_namespaces\n"
+ << "{\n"
+ << " typedef efl::eo::js::list\n"
+ " <\n";
+
+ std::cout << "namespace " << classes_struct_name << " has " << namespaces.size()
+ << " namespaces" << std::endl;
+
+ auto namespace_iterator = namespaces.begin();
+ while(namespace_iterator != namespaces.end())
+ {
+ auto&& namesp = *namespace_iterator;
+ os << "::efl::eo::js::namespace_object<efl::eo::js::name<";
+ auto char_iterator = namesp.begin();
+ while(char_iterator != namesp.end())
+ {
+ os << "'" << *char_iterator << "'";
+ if(std::next(char_iterator) != namesp.end())
+ os << ", ";
+ ++char_iterator;
+ }
+ std::string full_name = (item.first == "" ? "" : item.first + '.') + namesp;
+ fix_name(full_name);
+ os << ">, " << full_name << "_classes, " << full_name << "_namespaces>";
+ namespace_iterator++;
+ if(namespace_iterator != namespaces.end())
+ os << ", ";
+ }
+ os << "> type;\n};\n";
+ }
+ }
}
-
// std::vector<Eolian_Function const*> constructor_functions;
// std::vector<Eolian_Function const*> normal_functions;
diff --git a/src/bindings/cxx/eina_cxx/eina_aligned_union.hh b/src/bindings/cxx/eina_cxx/eina_aligned_union.hh
index eabe878408..b61a70ad3c 100644
--- a/src/bindings/cxx/eina_cxx/eina_aligned_union.hh
+++ b/src/bindings/cxx/eina_cxx/eina_aligned_union.hh
@@ -4,13 +4,13 @@
namespace efl { namespace eina { namespace _mpl {
template <std::size_t...Numbers>
-struct max;
+struct max_c;
template <std::size_t A0>
-struct max<A0> : std::integral_constant<std::size_t, A0> {};
+struct max_c<A0> : std::integral_constant<std::size_t, A0> {};
template <std::size_t A0, std::size_t A1, std::size_t...Args>
-struct max<A0, A1, Args...> : max<(A0 > A1 ? A0 : A1), Args...> {};
+struct max_c<A0, A1, Args...> : max_c<(A0 > A1 ? A0 : A1), Args...> {};
}
@@ -18,10 +18,10 @@ struct max<A0, A1, Args...> : max<(A0 > A1 ? A0 : A1), Args...> {};
template <std::size_t Min, typename...Args>
struct aligned_union
{
- static constexpr std::size_t alignment_value = _mpl::max<alignof(Args)...>::value;
+ static constexpr std::size_t alignment_value = _mpl::max_c<alignof(Args)...>::value;
typedef typename std::aligned_storage
- < _mpl::max<Min, sizeof(Args)...>::value
+ < _mpl::max_c<Min, sizeof(Args)...>::value
, alignment_value >::type type;
};
diff --git a/src/bindings/cxx/eina_cxx/eina_tpl_char_switch.hh b/src/bindings/cxx/eina_cxx/eina_tpl_char_switch.hh
new file mode 100644
index 0000000000..cc76bc5f04
--- /dev/null
+++ b/src/bindings/cxx/eina_cxx/eina_tpl_char_switch.hh
@@ -0,0 +1,1005 @@
+#ifndef EINA_TPL_SWITCH_HH_
+#define EINA_TPL_SWITCH_HH_
+
+namespace efl { namespace eina { namespace _mpl {
+
+template <char...Chars>
+struct tpl_char_switch;
+
+template <>
+struct tpl_char_switch<>
+{
+ template <typename F, typename Fail>
+ constexpr void operator()(char c, Fail const fail) const
+ {
+ fail(c);
+ }
+};
+
+template <char C0>
+struct tpl_char_switch<C0>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ if(c == C0)
+ typename F::template apply<C0>::type{}(args...);
+ else
+ fail(c);
+ }
+};
+
+template <char C0, char C1>
+struct tpl_char_switch<C0, C1>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2>
+struct tpl_char_switch<C0, C1, C2>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2, char C3>
+struct tpl_char_switch<C0, C1, C2, C3>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ case C3:
+ typename F::template apply<C3>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2, char C3, char C4>
+struct tpl_char_switch<C0, C1, C2, C3, C4>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ case C3:
+ typename F::template apply<C3>::type{}(args...);
+ break;
+ case C4:
+ typename F::template apply<C4>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2, char C3, char C4, char C5>
+struct tpl_char_switch<C0, C1, C2, C3, C4, C5>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ case C3:
+ typename F::template apply<C3>::type{}(args...);
+ break;
+ case C4:
+ typename F::template apply<C4>::type{}(args...);
+ break;
+ case C5:
+ typename F::template apply<C5>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2, char C3, char C4, char C5, char C6>
+struct tpl_char_switch<C0, C1, C2, C3, C4, C5, C6>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ case C3:
+ typename F::template apply<C3>::type{}(args...);
+ break;
+ case C4:
+ typename F::template apply<C4>::type{}(args...);
+ break;
+ case C5:
+ typename F::template apply<C5>::type{}(args...);
+ break;
+ case C6:
+ typename F::template apply<C6>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2, char C3, char C4, char C5, char C6, char C7>
+struct tpl_char_switch<C0, C1, C2, C3, C4, C5, C6, C7>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ case C3:
+ typename F::template apply<C3>::type{}(args...);
+ break;
+ case C4:
+ typename F::template apply<C4>::type{}(args...);
+ break;
+ case C5:
+ typename F::template apply<C5>::type{}(args...);
+ break;
+ case C6:
+ typename F::template apply<C6>::type{}(args...);
+ break;
+ case C7:
+ typename F::template apply<C7>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2, char C3, char C4, char C5, char C6, char C7, char C8>
+struct tpl_char_switch<C0, C1, C2, C3, C4, C5, C6, C7, C8>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ case C3:
+ typename F::template apply<C3>::type{}(args...);
+ break;
+ case C4:
+ typename F::template apply<C4>::type{}(args...);
+ break;
+ case C5:
+ typename F::template apply<C5>::type{}(args...);
+ break;
+ case C6:
+ typename F::template apply<C6>::type{}(args...);
+ break;
+ case C7:
+ typename F::template apply<C7>::type{}(args...);
+ break;
+ case C8:
+ typename F::template apply<C8>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2, char C3, char C4, char C5, char C6, char C7, char C8, char C9>
+struct tpl_char_switch<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ case C3:
+ typename F::template apply<C3>::type{}(args...);
+ break;
+ case C4:
+ typename F::template apply<C4>::type{}(args...);
+ break;
+ case C5:
+ typename F::template apply<C5>::type{}(args...);
+ break;
+ case C6:
+ typename F::template apply<C6>::type{}(args...);
+ break;
+ case C7:
+ typename F::template apply<C7>::type{}(args...);
+ break;
+ case C8:
+ typename F::template apply<C8>::type{}(args...);
+ break;
+ case C9:
+ typename F::template apply<C9>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2, char C3, char C4, char C5, char C6, char C7, char C8, char C9, char C10>
+struct tpl_char_switch<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ case C3:
+ typename F::template apply<C3>::type{}(args...);
+ break;
+ case C4:
+ typename F::template apply<C4>::type{}(args...);
+ break;
+ case C5:
+ typename F::template apply<C5>::type{}(args...);
+ break;
+ case C6:
+ typename F::template apply<C6>::type{}(args...);
+ break;
+ case C7:
+ typename F::template apply<C7>::type{}(args...);
+ break;
+ case C8:
+ typename F::template apply<C8>::type{}(args...);
+ break;
+ case C9:
+ typename F::template apply<C9>::type{}(args...);
+ break;
+ case C10:
+ typename F::template apply<C10>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2, char C3, char C4, char C5, char C6, char C7, char C8, char C9, char C10, char C11>
+struct tpl_char_switch<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ case C3:
+ typename F::template apply<C3>::type{}(args...);
+ break;
+ case C4:
+ typename F::template apply<C4>::type{}(args...);
+ break;
+ case C5:
+ typename F::template apply<C5>::type{}(args...);
+ break;
+ case C6:
+ typename F::template apply<C6>::type{}(args...);
+ break;
+ case C7:
+ typename F::template apply<C7>::type{}(args...);
+ break;
+ case C8:
+ typename F::template apply<C8>::type{}(args...);
+ break;
+ case C9:
+ typename F::template apply<C9>::type{}(args...);
+ break;
+ case C10:
+ typename F::template apply<C10>::type{}(args...);
+ break;
+ case C11:
+ typename F::template apply<C11>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2, char C3, char C4, char C5, char C6, char C7, char C8, char C9, char C10, char C11, char C12>
+struct tpl_char_switch<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ case C3:
+ typename F::template apply<C3>::type{}(args...);
+ break;
+ case C4:
+ typename F::template apply<C4>::type{}(args...);
+ break;
+ case C5:
+ typename F::template apply<C5>::type{}(args...);
+ break;
+ case C6:
+ typename F::template apply<C6>::type{}(args...);
+ break;
+ case C7:
+ typename F::template apply<C7>::type{}(args...);
+ break;
+ case C8:
+ typename F::template apply<C8>::type{}(args...);
+ break;
+ case C9:
+ typename F::template apply<C9>::type{}(args...);
+ break;
+ case C10:
+ typename F::template apply<C10>::type{}(args...);
+ break;
+ case C11:
+ typename F::template apply<C11>::type{}(args...);
+ break;
+ case C12:
+ typename F::template apply<C12>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2, char C3, char C4, char C5, char C6, char C7, char C8, char C9, char C10, char C11, char C12, char C13>
+struct tpl_char_switch<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ case C3:
+ typename F::template apply<C3>::type{}(args...);
+ break;
+ case C4:
+ typename F::template apply<C4>::type{}(args...);
+ break;
+ case C5:
+ typename F::template apply<C5>::type{}(args...);
+ break;
+ case C6:
+ typename F::template apply<C6>::type{}(args...);
+ break;
+ case C7:
+ typename F::template apply<C7>::type{}(args...);
+ break;
+ case C8:
+ typename F::template apply<C8>::type{}(args...);
+ break;
+ case C9:
+ typename F::template apply<C9>::type{}(args...);
+ break;
+ case C10:
+ typename F::template apply<C10>::type{}(args...);
+ break;
+ case C11:
+ typename F::template apply<C11>::type{}(args...);
+ break;
+ case C12:
+ typename F::template apply<C12>::type{}(args...);
+ break;
+ case C13:
+ typename F::template apply<C13>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2, char C3, char C4, char C5, char C6, char C7, char C8, char C9, char C10, char C11, char C12, char C13, char C14>
+struct tpl_char_switch<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ case C3:
+ typename F::template apply<C3>::type{}(args...);
+ break;
+ case C4:
+ typename F::template apply<C4>::type{}(args...);
+ break;
+ case C5:
+ typename F::template apply<C5>::type{}(args...);
+ break;
+ case C6:
+ typename F::template apply<C6>::type{}(args...);
+ break;
+ case C7:
+ typename F::template apply<C7>::type{}(args...);
+ break;
+ case C8:
+ typename F::template apply<C8>::type{}(args...);
+ break;
+ case C9:
+ typename F::template apply<C9>::type{}(args...);
+ break;
+ case C10:
+ typename F::template apply<C10>::type{}(args...);
+ break;
+ case C11:
+ typename F::template apply<C11>::type{}(args...);
+ break;
+ case C12:
+ typename F::template apply<C12>::type{}(args...);
+ break;
+ case C13:
+ typename F::template apply<C13>::type{}(args...);
+ break;
+ case C14:
+ typename F::template apply<C14>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2, char C3, char C4, char C5, char C6, char C7, char C8, char C9, char C10, char C11, char C12, char C13, char C14, char C15>
+struct tpl_char_switch<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ case C3:
+ typename F::template apply<C3>::type{}(args...);
+ break;
+ case C4:
+ typename F::template apply<C4>::type{}(args...);
+ break;
+ case C5:
+ typename F::template apply<C5>::type{}(args...);
+ break;
+ case C6:
+ typename F::template apply<C6>::type{}(args...);
+ break;
+ case C7:
+ typename F::template apply<C7>::type{}(args...);
+ break;
+ case C8:
+ typename F::template apply<C8>::type{}(args...);
+ break;
+ case C9:
+ typename F::template apply<C9>::type{}(args...);
+ break;
+ case C10:
+ typename F::template apply<C10>::type{}(args...);
+ break;
+ case C11:
+ typename F::template apply<C11>::type{}(args...);
+ break;
+ case C12:
+ typename F::template apply<C12>::type{}(args...);
+ break;
+ case C13:
+ typename F::template apply<C13>::type{}(args...);
+ break;
+ case C14:
+ typename F::template apply<C14>::type{}(args...);
+ break;
+ case C15:
+ typename F::template apply<C15>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2, char C3, char C4, char C5, char C6, char C7, char C8, char C9, char C10, char C11, char C12, char C13, char C14, char C15, char C16>
+struct tpl_char_switch<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ case C3:
+ typename F::template apply<C3>::type{}(args...);
+ break;
+ case C4:
+ typename F::template apply<C4>::type{}(args...);
+ break;
+ case C5:
+ typename F::template apply<C5>::type{}(args...);
+ break;
+ case C6:
+ typename F::template apply<C6>::type{}(args...);
+ break;
+ case C7:
+ typename F::template apply<C7>::type{}(args...);
+ break;
+ case C8:
+ typename F::template apply<C8>::type{}(args...);
+ break;
+ case C9:
+ typename F::template apply<C9>::type{}(args...);
+ break;
+ case C10:
+ typename F::template apply<C10>::type{}(args...);
+ break;
+ case C11:
+ typename F::template apply<C11>::type{}(args...);
+ break;
+ case C12:
+ typename F::template apply<C12>::type{}(args...);
+ break;
+ case C13:
+ typename F::template apply<C13>::type{}(args...);
+ break;
+ case C14:
+ typename F::template apply<C14>::type{}(args...);
+ break;
+ case C15:
+ typename F::template apply<C15>::type{}(args...);
+ break;
+ case C16:
+ typename F::template apply<C16>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2, char C3, char C4, char C5, char C6, char C7, char C8, char C9, char C10, char C11, char C12, char C13, char C14, char C15, char C16, char C17>
+struct tpl_char_switch<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ case C3:
+ typename F::template apply<C3>::type{}(args...);
+ break;
+ case C4:
+ typename F::template apply<C4>::type{}(args...);
+ break;
+ case C5:
+ typename F::template apply<C5>::type{}(args...);
+ break;
+ case C6:
+ typename F::template apply<C6>::type{}(args...);
+ break;
+ case C7:
+ typename F::template apply<C7>::type{}(args...);
+ break;
+ case C8:
+ typename F::template apply<C8>::type{}(args...);
+ break;
+ case C9:
+ typename F::template apply<C9>::type{}(args...);
+ break;
+ case C10:
+ typename F::template apply<C10>::type{}(args...);
+ break;
+ case C11:
+ typename F::template apply<C11>::type{}(args...);
+ break;
+ case C12:
+ typename F::template apply<C12>::type{}(args...);
+ break;
+ case C13:
+ typename F::template apply<C13>::type{}(args...);
+ break;
+ case C14:
+ typename F::template apply<C14>::type{}(args...);
+ break;
+ case C15:
+ typename F::template apply<C15>::type{}(args...);
+ break;
+ case C16:
+ typename F::template apply<C16>::type{}(args...);
+ break;
+ case C17:
+ typename F::template apply<C17>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2, char C3, char C4, char C5, char C6, char C7, char C8, char C9, char C10, char C11, char C12, char C13, char C14, char C15, char C16, char C17, char C18>
+struct tpl_char_switch<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ case C3:
+ typename F::template apply<C3>::type{}(args...);
+ break;
+ case C4:
+ typename F::template apply<C4>::type{}(args...);
+ break;
+ case C5:
+ typename F::template apply<C5>::type{}(args...);
+ break;
+ case C6:
+ typename F::template apply<C6>::type{}(args...);
+ break;
+ case C7:
+ typename F::template apply<C7>::type{}(args...);
+ break;
+ case C8:
+ typename F::template apply<C8>::type{}(args...);
+ break;
+ case C9:
+ typename F::template apply<C9>::type{}(args...);
+ break;
+ case C10:
+ typename F::template apply<C10>::type{}(args...);
+ break;
+ case C11:
+ typename F::template apply<C11>::type{}(args...);
+ break;
+ case C12:
+ typename F::template apply<C12>::type{}(args...);
+ break;
+ case C13:
+ typename F::template apply<C13>::type{}(args...);
+ break;
+ case C14:
+ typename F::template apply<C14>::type{}(args...);
+ break;
+ case C15:
+ typename F::template apply<C15>::type{}(args...);
+ break;
+ case C16:
+ typename F::template apply<C16>::type{}(args...);
+ break;
+ case C17:
+ typename F::template apply<C17>::type{}(args...);
+ break;
+ case C18:
+ typename F::template apply<C18>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2, char C3, char C4, char C5, char C6, char C7, char C8, char C9, char C10, char C11, char C12, char C13, char C14, char C15, char C16, char C17, char C18, char C19>
+struct tpl_char_switch<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ case C3:
+ typename F::template apply<C3>::type{}(args...);
+ break;
+ case C4:
+ typename F::template apply<C4>::type{}(args...);
+ break;
+ case C5:
+ typename F::template apply<C5>::type{}(args...);
+ break;
+ case C6:
+ typename F::template apply<C6>::type{}(args...);
+ break;
+ case C7:
+ typename F::template apply<C7>::type{}(args...);
+ break;
+ case C8:
+ typename F::template apply<C8>::type{}(args...);
+ break;
+ case C9:
+ typename F::template apply<C9>::type{}(args...);
+ break;
+ case C10:
+ typename F::template apply<C10>::type{}(args...);
+ break;
+ case C11:
+ typename F::template apply<C11>::type{}(args...);
+ break;
+ case C12:
+ typename F::template apply<C12>::type{}(args...);
+ break;
+ case C13:
+ typename F::template apply<C13>::type{}(args...);
+ break;
+ case C14:
+ typename F::template apply<C14>::type{}(args...);
+ break;
+ case C15:
+ typename F::template apply<C15>::type{}(args...);
+ break;
+ case C16:
+ typename F::template apply<C16>::type{}(args...);
+ break;
+ case C17:
+ typename F::template apply<C17>::type{}(args...);
+ break;
+ case C18:
+ typename F::template apply<C18>::type{}(args...);
+ break;
+ case C19:
+ typename F::template apply<C19>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+template <char C0, char C1, char C2, char C3, char C4, char C5, char C6, char C7, char C8, char C9, char C10, char C11, char C12, char C13, char C14, char C15, char C16, char C17, char C18, char C19, char C20>
+struct tpl_char_switch<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19, C20>
+{
+ template <typename F, typename Fail, typename...Args>
+ constexpr void operator()(char c, Fail const fail, Args&&...args) const
+ {
+ switch(c)
+ {
+ case C0:
+ typename F::template apply<C0>::type{}(args...);
+ break;
+ case C1:
+ typename F::template apply<C1>::type{}(args...);
+ break;
+ case C2:
+ typename F::template apply<C2>::type{}(args...);
+ break;
+ case C3:
+ typename F::template apply<C3>::type{}(args...);
+ break;
+ case C4:
+ typename F::template apply<C4>::type{}(args...);
+ break;
+ case C5:
+ typename F::template apply<C5>::type{}(args...);
+ break;
+ case C6:
+ typename F::template apply<C6>::type{}(args...);
+ break;
+ case C7:
+ typename F::template apply<C7>::type{}(args...);
+ break;
+ case C8:
+ typename F::template apply<C8>::type{}(args...);
+ break;
+ case C9:
+ typename F::template apply<C9>::type{}(args...);
+ break;
+ case C10:
+ typename F::template apply<C10>::type{}(args...);
+ break;
+ case C11:
+ typename F::template apply<C11>::type{}(args...);
+ break;
+ case C12:
+ typename F::template apply<C12>::type{}(args...);
+ break;
+ case C13:
+ typename F::template apply<C13>::type{}(args...);
+ break;
+ case C14:
+ typename F::template apply<C14>::type{}(args...);
+ break;
+ case C15:
+ typename F::template apply<C15>::type{}(args...);
+ break;
+ case C16:
+ typename F::template apply<C16>::type{}(args...);
+ break;
+ case C17:
+ typename F::template apply<C17>::type{}(args...);
+ break;
+ case C18:
+ typename F::template apply<C18>::type{}(args...);
+ break;
+ case C19:
+ typename F::template apply<C19>::type{}(args...);
+ break;
+ case C20:
+ typename F::template apply<C20>::type{}(args...);
+ break;
+ default:
+ fail(c);
+ };
+ }
+};
+
+
+} } }
+
+#endif
diff --git a/src/bindings/cxx/eina_cxx/eina_tuple.hh b/src/bindings/cxx/eina_cxx/eina_tuple.hh
index 45545c3702..155742f234 100644
--- a/src/bindings/cxx/eina_cxx/eina_tuple.hh
+++ b/src/bindings/cxx/eina_cxx/eina_tuple.hh
@@ -83,6 +83,172 @@ struct tuple_find<T, std::tuple<T, Ts...> > : std::integral_constant<std::size_t
template <typename T, typename T1, typename... Ts>
struct tuple_find<T, std::tuple<T1, Ts...> > : std::integral_constant
<std::size_t, 1 + tuple_find<T, std::tuple<Ts...> >::value> {};
+
+
+template <typename T, typename I, typename Fold>
+struct tuple_fold;
+
+template <typename I, typename Fold, typename...T>
+struct tuple_fold_aux;
+
+
+template <typename I, typename Fold, typename T>
+struct tuple_fold_aux<I, Fold, T> : Fold::template apply<I, T>
+{
+};
+
+template <typename I, typename Fold, typename T, typename...Ts>
+struct tuple_fold_aux<I, Fold, T, Ts...> : tuple_fold_aux
+ <typename Fold::template apply<I, T>::type
+ , Fold, Ts...>
+{
+
+};
+
+template <typename...T, typename I, typename Fold>
+struct tuple_fold<std::tuple<T...>, I, Fold> : tuple_fold_aux<I, Fold, T...>
+{};
+
+template <typename Pred, typename...Args>
+struct min;
+
+template <typename Pred, typename A0>
+struct min<Pred, A0>
+{
+ typedef A0 type;
+};
+
+template <typename Pred, typename A0, typename A1, typename...Args>
+struct min<Pred, A0, A1, Args...>
+{
+ typedef typename min<Pred, A1, Args...>::type rest_result;
+ typedef typename std::conditional
+ <Pred::template apply<A0, rest_result>::value
+ , A0, rest_result>::type type;
+};
+
+template <typename Pred, typename...Args>
+struct max;
+
+template <typename Pred, typename A0>
+struct max<Pred, A0>
+{
+ typedef A0 type;
+};
+
+template <typename Pred, typename A0, typename A1, typename...Args>
+struct max<Pred, A0, A1, Args...>
+{
+ typedef typename max<Pred, A1, Args...>::type rest_result;
+ typedef typename std::conditional
+ <Pred::template apply<rest_result, A0>::value
+ , A0, rest_result>::type type;
+};
+
+template <typename T, typename Removed>
+struct tuple_remove;
+
+template <typename Removed, typename Partial, typename...T>
+struct tuple_remove_aux;
+
+template <typename Removed, typename Partial>
+struct tuple_remove_aux<Removed, Partial>
+{
+ typedef Partial type;
+};
+
+template <typename Removed, typename...Partials, typename...T>
+struct tuple_remove_aux<Removed, std::tuple<Partials...>, Removed, T...>
+{
+ typedef std::tuple<Partials..., T...> type;
+};
+
+template <typename Removed, typename...Partials, typename A0, typename...T>
+struct tuple_remove_aux<Removed, std::tuple<Partials...>, A0, T...>
+ : tuple_remove_aux<Removed, std::tuple<Partials..., A0>, T...>
+{
+};
+
+template <typename...T, typename Removed>
+struct tuple_remove<std::tuple<T...>, Removed>
+ : tuple_remove_aux<Removed, std::tuple<>, T...>
+{
+};
+ ///
+
+template <typename T, typename Removed>
+struct tuple_remove_all;
+
+template <typename Removed, typename Partial, typename...T>
+struct tuple_remove_all_aux;
+
+template <typename Removed, typename Partial>
+struct tuple_remove_all_aux<Removed, Partial>
+{
+ typedef Partial type;
+};
+
+template <typename Removed, typename...Partials, typename...T>
+struct tuple_remove_all_aux<Removed, std::tuple<Partials...>, Removed, T...>
+ : tuple_remove_all_aux<Removed, std::tuple<Partials...>, T...>
+{
+};
+
+template <typename Removed, typename...Partials, typename A0, typename...T>
+struct tuple_remove_all_aux<Removed, std::tuple<Partials...>, A0, T...>
+ : tuple_remove_all_aux<Removed, std::tuple<Partials..., A0>, T...>
+{
+};
+
+template <typename...T, typename Removed>
+struct tuple_remove_all<std::tuple<T...>, Removed>
+ : tuple_remove_all_aux<Removed, std::tuple<>, T...>
+{
+};
+
+template <typename Tuple, typename Pred, typename Partial>
+struct tuple_sort_unique_aux;
+
+template <typename T0, typename...T, typename Pred, typename...Partials>
+struct tuple_sort_unique_aux<std::tuple<T0, T...>, Pred, std::tuple<Partials...>>
+{
+ typedef typename min<Pred, T0, T...>::type min_type;
+ typedef typename tuple_remove_all<std::tuple<T0, T...>, min_type>::type new_tuple_type;
+ typedef typename tuple_sort_unique_aux<new_tuple_type, Pred, std::tuple<Partials..., min_type>>::type type;
+};
+
+template <typename Pred, typename Partial>
+struct tuple_sort_unique_aux<std::tuple<>, Pred, Partial>
+{
+ typedef Partial type;
+};
+
+template <typename T, typename Pred>
+struct tuple_sort_unique
+ : tuple_sort_unique_aux<T, Pred, std::tuple<>>
+{};
+
+template <typename Tuple, typename Pred, typename Partial>
+struct tuple_sort_aux;
+
+template <typename T0, typename...T, typename Pred, typename...Partials>
+struct tuple_sort_aux<std::tuple<T0, T...>, Pred, std::tuple<Partials...>>
+{
+ typedef typename min<Pred, T0, T...>::type min_type;
+ typedef typename tuple_remove<std::tuple<T0, T...>, min_type>::type new_tuple_type;
+ typedef typename tuple_sort_aux<new_tuple_type, Pred, std::tuple<Partials..., min_type>>::type type;
+};
+
+template <typename Pred, typename Partial>
+struct tuple_sort_aux<std::tuple<>, Pred, Partial>
+{
+ typedef Partial type;
+};
+
+template <typename T, typename Pred>
+struct tuple_sort
+ : tuple_sort_aux<T, Pred, std::tuple<>>
+{};
} } }
diff --git a/src/bindings/js/efl_js/efl_js.cc b/src/bindings/js/efl_js/efl_js.cc
index b85574ae6c..a6cd5313f5 100644
--- a/src/bindings/js/efl_js/efl_js.cc
+++ b/src/bindings/js/efl_js/efl_js.cc
@@ -7,14 +7,26 @@
#include <Efl.h>
#include <Efl_Config.h>
#include <Ecore.h>
-#include <Ecore_Evas.h>
-#include <Eina.hh>
+#include <Eo.h>
+#include <Ecore_Con.h>
+#include <Ecore_Audio.h>
+#include <Evas.h>
+#include <Edje.h>
+#include <Ecore_Con_Eet.h>
+#include <Emotion.h>
+#define ELM_INTERNAL_API_ARGESFSDFEFC
+#include <Elementary.h>
+extern "C" {
+#include <elm_widget.h>
+}
+
#include <Eina_Js.hh>
#include <Ecore_Js.hh>
#include <Eio_Js.hh>
#include <Eldbus_Js.hh>
#include <Ethumb_Js.hh>
-#include <Elementary.h>
+
+#include <eo_js_list.hh>
#include <iostream>
@@ -36,22 +48,142 @@
# endif
#endif /* ! _WIN32 */
+// include registrations
+#include <eo_js_namespace_tree.hh>
+
+struct object_registration_win
+{
+ void operator()(v8::Handle<v8::Object>, v8::Isolate*) const
+ {
+ std::cout << "called " << __func__ << std::endl;
+ }
+};
+
+
+struct object_registration_abc
+{
+ void operator()(v8::Handle<v8::Object>, v8::Isolate*) const
+ {
+ std::cout << "called " << __func__ << std::endl;
+ }
+};
+
namespace {
+namespace _mpl {
+
+#include <eolian_js_bindings.js.hh>
+
+// struct efl_elementary_classes
+// {
+// typedef efl::eo::js::list
+// <efl::eo::js::class_object<efl::eo::js::name<'W', 'i', 'n'>, std::false_type>> type;
+// };
+
+// struct afl_elementary_classes
+// {
+// typedef efl::eo::js::list
+// <efl::eo::js::class_object<efl::eo::js::name<'W', 'i', 'n'>, std::false_type>> type;
+// };
+
+// struct efl_namespaces
+// {
+// typedef efl::eo::js::list
+// <efl::eo::js::namespace_object<efl::eo::js::name<'E', 'l', 'e', 'm', 'e', 'n', 't', 'a', 'r', 'y'>, std::false_type, efl_elementary_classes, efl::eo::js::empty>> type;
+// };
+
+// struct afl_namespaces
+// {
+// typedef efl::eo::js::list
+// <efl::eo::js::namespace_object<efl::eo::js::name<'E', 'l', 'e', 'm', 'e', 'n', 't', 'a', 'r', 'y'>, std::false_type, afl_elementary_classes, efl::eo::js::empty>> type;
+// };
+
+// struct global_namespaces
+// {
+// typedef efl::eo::js::list
+// <efl::eo::js::namespace_object<efl::eo::js::name<'E', 'f', 'l'>, std::false_type
+// , efl::eo::js::empty, efl_namespaces>
+// , efl::eo::js::namespace_object<efl::eo::js::name<'A', 'f', 'l'>, std::false_type
+// , efl::eo::js::empty, afl_namespaces>
+// > type;
+// };
+
+typedef efl::eo::js::namespace_object<efl::eo::js::name<>
+ , _classes, _namespaces
+ > global_namespace;
+
+}
+
+template <typename T>
+struct is_registered
+{
+ static bool yes;
+
+};
+
+template <typename T> bool is_registered<T>::yes = false;
+
+template <typename T>
+void namespace_accessor_get(v8::Local<v8::Name> name, v8::PropertyCallbackInfo<v8::Value> const& info);
+
+struct found_item
+{
+ efl::eina::string_view name;
+ v8::PropertyCallbackInfo<v8::Value> const& info;
+
+ template <typename Name, typename Classes, typename InnerNamespaces>
+ void operator()(efl::eo::js::namespace_object<Name, Classes, InnerNamespaces> const) const
+ {
+ typedef efl::eo::js::namespace_object<Name, Classes, InnerNamespaces> type;
+ std::cout << "returned namespace item" << std::endl;
+ if(is_registered<type>::yes)
+ {
+ std::cout << "Already registered" << std::endl;
+ }
+ else
+ {
+ std::cout << "Not registered yet" << std::endl;
+ is_registered<type>::yes = true;
+
+ v8::Isolate* isolate = info.GetIsolate();
+ v8::Local<v8::ObjectTemplate> ns_object = ::efl::eina::js::compatibility_new<v8::ObjectTemplate>(isolate);
+ ns_object->SetHandler({&namespace_accessor_get<type>});
+ auto obj = ns_object->NewInstance();
+ info.This()->Set(::efl::eina::js::compatibility_new<v8::String>(isolate, name.data())
+ , obj);
+
+ info.GetReturnValue().Set(obj);
+ }
+ }
+
+ template <typename Name, typename Registration>
+ void operator()(efl::eo::js::class_object<Name, Registration> const) const
+ {
+ //std::cout << "returned class item" << std::endl;
+ // must register
+ }
+};
+
+template <typename T>
void namespace_accessor_get(v8::Local<v8::Name> name, v8::PropertyCallbackInfo<v8::Value> const& info)
{
std::cout << "was it here?" << std::endl;
v8::Local<v8::String> name_str = name->ToString();
assert(!!*name_str);
v8::String::Utf8Value value(info.GetIsolate(), name_str);
- std::cout << *value << std::endl;
+ std::cout << "searching for " << *value << std::endl;
- if(info.Data()->IsNullOrUndefined())
- {
- std::cout << "no value already assigned" << std::endl;
- }
- else
- std::cout << "value already assigned" << std::endl;
+ // if(info.Data()->IsNullOrUndefined())
+ // {
+ // std::cout << "no value already assigned" << std::endl;
+ // }
+ // else
+ // std::cout << "value already assigned" << std::endl;
+
+ efl::eina::string_view string = *value;
+
+ efl::eo::js::search_separate(string, T{}
+ , found_item{string, info});
}
}
@@ -87,11 +219,13 @@ EAPI void init(v8::Local<v8::Object> exports, v8::Local<v8::Object> module)
{
auto evas = ::efl::eina::js::compatibility_new<v8::Object>(isolate);
ns_obj = ::efl::eina::js::compatibility_new<v8::ObjectTemplate>(isolate);
- ns_obj->SetHandler({&namespace_accessor_get});
+ ns_obj->SetHandler({&namespace_accessor_get<_mpl::global_namespace>});
auto obj = ns_obj->NewInstance();
obj->Set(::efl::eina::js::compatibility_new<v8::String>(isolate, "evas"), evas);
module->Set(::efl::eina::js::compatibility_new<v8::String>(isolate, "exports"), obj);
}
+
+ // _mpl::foo();
}
catch(...)
{
diff --git a/src/bindings/js/eo_js/eo_js_list.hh b/src/bindings/js/eo_js/eo_js_list.hh
new file mode 100644
index 0000000000..0f8c4d6a45
--- /dev/null
+++ b/src/bindings/js/eo_js/eo_js_list.hh
@@ -0,0 +1,160 @@
+#ifndef EFL_EO_JS_LIST_HH
+#define EFL_EO_JS_LIST_HH
+
+namespace efl { namespace eo { namespace js {
+
+template <typename...Items>
+struct list
+{
+};
+
+template <typename List1, typename...Lists>
+struct list_concat;
+
+template <typename...List1>
+struct list_concat<list<List1...>>
+{
+ typedef list<List1...> type;
+};
+
+template <typename...List1, typename...List2>
+struct list_concat<list<List1...>, list<List2...>>
+{
+ typedef list<List1..., List2...> type;
+};
+
+template <typename...List1, typename...List2, typename...List3, typename...Lists>
+struct list_concat<list<List1...>, list<List2...>, list<List3...>, Lists...>
+ : list_concat<list<List1..., List2..., List3...>, Lists...>
+{};
+
+template <typename T, typename PartialList, typename...Items>
+struct list_remove_first_impl;
+
+template <typename T, typename...Partials, typename...Items>
+struct list_remove_first_impl<T, list<Partials...>, T, Items...>
+{
+ typedef list<Partials..., Items...> type;
+};
+
+template <typename T, typename PartialList>
+struct list_remove_first_impl<T, PartialList>
+{
+ typedef PartialList type;
+};
+
+template <typename T, typename...Partials, typename T0, typename...Items>
+struct list_remove_first_impl<T, list<Partials...>, T0, Items...>
+ : list_remove_first_impl<T, list<Partials..., T0>, Items...>
+{
+};
+
+template <typename T, typename List>
+struct list_remove_first;
+
+template <typename T, typename...Items>
+struct list_remove_first<T, list<Items...>>
+ : list_remove_first_impl<T, list<>, Items...>
+{
+};
+
+template <typename Pred, typename Partial, typename List>
+struct list_sort_impl;
+
+template <typename T>
+struct message_fail
+{
+ struct type {};
+ static_assert(std::is_same<T, type>::value);
+};
+
+template <typename Pred, typename...Partials, typename T0, typename...T>
+struct list_sort_impl<Pred, list<Partials...>, list<T0, T...>>
+{
+ typedef typename eina::_mpl::min<Pred, T0, T...>::type min_type;
+ typedef typename list_remove_first<min_type, list<T0, T...>>::type new_list_type;
+ typedef typename list_sort_impl<Pred, list<Partials..., min_type>, new_list_type>::type type;
+ //typedef typename message_fail<min_type>::type fail;
+};
+
+template <typename Pred, typename Partial>
+struct list_sort_impl<Pred, Partial, list<>>
+{
+ typedef Partial type;
+};
+
+template <typename Pred, typename List1, typename...Lists>
+struct list_sort
+ : list_sort_impl<Pred, list<>, typename list_concat<List1, Lists...>::type>
+{};
+
+template <typename T, typename I, typename Fold>
+struct list_fold;
+
+template <typename I, typename Fold, typename...T>
+struct list_fold_aux;
+
+
+template <typename I, typename Fold, typename T>
+struct list_fold_aux<I, Fold, T> : Fold::template apply<I, T>
+{
+};
+
+template <typename I, typename Fold, typename T, typename...Ts>
+struct list_fold_aux<I, Fold, T, Ts...> : list_fold_aux
+ <typename Fold::template apply<I, T>::type
+ , Fold, Ts...>
+{
+
+};
+
+template <typename...T, typename I, typename Fold>
+struct list_fold<list<T...>, I, Fold> : list_fold_aux<I, Fold, T...>
+{};
+
+/// find_if
+
+template <typename List, typename Pred, typename Enable = void>
+struct list_find_if_impl;
+
+template <typename I, typename...List, typename Pred>
+struct list_find_if_impl<list<I, List...>, Pred
+ , typename std::enable_if<(Pred::template apply<I>::type::value)>::type>
+{
+ typedef I type;
+};
+
+template <typename I, typename...List, typename Pred>
+struct list_find_if_impl<list<I, List...>, Pred
+ , typename std::enable_if<!(Pred::template apply<I>::type::value)>::type>
+ : list_find_if_impl<list<List...>, Pred>
+{
+};
+
+template <typename Pred>
+struct list_find_if_impl<list<>, Pred>
+{
+};
+
+template <typename List, typename Pred>
+struct list_find_if : list_find_if_impl<List, Pred>
+{
+};
+
+template <typename Pred, typename T>
+struct list_min;
+
+template <typename Pred, typename T>
+struct list_max;
+
+template <typename...T, typename Pred>
+struct list_min<Pred, list<T...>>
+ : eina::_mpl::min<Pred, T...> {};
+
+template <typename...T, typename Pred>
+struct list_max<Pred, list<T...>>
+ : eina::_mpl::max<Pred, T...> {};
+
+} } }
+
+#endif
diff --git a/src/bindings/js/eo_js/eo_js_namespace_tree.hh b/src/bindings/js/eo_js/eo_js_namespace_tree.hh
new file mode 100644
index 0000000000..ca0aec1988
--- /dev/null
+++ b/src/bindings/js/eo_js/eo_js_namespace_tree.hh
@@ -0,0 +1,291 @@
+#ifndef EFL_EO_JS_NAMESPACE_TREE_HH
+#define EFL_EO_JS_NAMESPACE_TREE_HH
+
+#include <eina_string_view.hh>
+
+#include <eina_tpl_char_switch.hh>
+
+#include <eo_js_list.hh>
+
+namespace efl { namespace eo { namespace js {
+
+struct empty
+{
+ typedef list<> type;
+};
+
+template <char...Chars>
+struct name
+{
+ static constexpr const int size = sizeof...(Chars);
+};
+
+template <typename T>
+struct name_size;
+
+template <char...Chars>
+struct name_size<name<Chars...>>
+ : std::integral_constant<std::size_t, sizeof...(Chars)>
+{};
+
+template <std::size_t, typename Name>
+struct name_at_c;
+
+template <char Char, char...Chars>
+struct name_at_c<0ul, name<Char, Chars...>>
+ : std::integral_constant<char, Char>
+{
+};
+
+template <std::size_t Index, char Char, char...Chars>
+struct name_at_c<Index, name<Char, Chars...>>
+ : name_at_c<Index-1, name<Chars...>>
+{
+};
+
+// template <std::size_t Index, char...Chars>
+// struct name_at_c<Index, name<Chars...>
+// {
+
+// };
+
+// template <std::size_t Index, char...CharsBefore, char Char, char...CharsAfter>
+// struct name_at_c_impl<Index, name<Chars...>>
+// {
+
+// };
+
+typedef void(*object_registration_type)(v8::Handle<v8::Object>, v8::Isolate*);
+
+template <typename Name
+ , typename Classes
+ , typename InnerNamespaces>
+struct namespace_object
+{
+ typedef Name name;
+ typedef Classes classes;
+ typedef InnerNamespaces inner_namespaces;
+};
+
+template <typename Name, typename Registration>
+struct class_object
+{
+ typedef Name name;
+ typedef Registration registration;
+};
+
+template <typename NameLhs, typename NameRhs>
+struct name_less;
+
+template <>
+struct name_less<name<>, name<>>
+{
+ static constexpr const bool value = false;
+};
+
+template <char...Chars>
+struct name_less<name<Chars...>, name<>>
+{
+ static constexpr const bool value = false;
+};
+
+template <char...Chars>
+struct name_less<name<>, name<Chars...>>
+{
+ static constexpr const bool value = true;
+};
+
+template <char CharacterLhs, char...NameLhs, char CharacterRhs, char...NameRhs>
+struct name_less<name<CharacterLhs, NameLhs...>, name<CharacterRhs, NameRhs...>>
+{
+ static constexpr const bool value =
+ CharacterLhs < CharacterRhs
+ || (CharacterLhs == CharacterRhs && name_less<name<NameLhs...>, name<NameRhs...>>::value);
+};
+
+template <typename T>
+struct identity { typedef T type; };
+
+struct name_less_predicate
+{
+ template <typename A0, typename A1>
+ struct apply;
+
+ template <typename Name1, typename Name2, typename...Others1, typename...Others2>
+ struct apply<namespace_object<Name1, Others1...>, namespace_object<Name2, Others2...>>
+ : name_less<Name1, Name2>
+ {};
+ template <typename Name1, typename Name2, typename...Others1, typename...Others2>
+ struct apply<class_object<Name1, Others1...>, class_object<Name2, Others2...>>
+ : name_less<Name1, Name2>
+ {};
+ template <typename Name1, typename Name2, typename...Others1, typename...Others2>
+ struct apply<namespace_object<Name1, Others1...>, class_object<Name2, Others2...>>
+ : name_less<Name1, Name2>
+ {};
+ template <typename Name1, typename Name2, typename...Others1, typename...Others2>
+ struct apply<class_object<Name1, Others1...>, namespace_object<Name2, Others2...>>
+ : name_less<Name1, Name2>
+ {};
+};
+
+template <typename A0, typename A1>
+struct pair
+{
+ typedef A0 first;
+ typedef A1 second;
+};
+
+template <std::size_t Index>
+struct map_op
+{
+ template <typename I, typename A0, typename Enable = void>
+ struct apply;
+
+ template <typename A0>
+ struct apply<list<>, A0>
+ {
+ typedef list<pair<name_at_c<Index, typename A0::name>
+ , list<A0>>> type;
+ };
+
+ template <typename C, typename...Items, typename...Pairs, typename A0>
+ struct apply<list<pair<C, list<Items...>>, Pairs...>, A0
+ , typename std::enable_if<(name_at_c<Index, typename A0::name>::value == C::value)>::type>
+ {
+ typedef list<pair<C, list<A0, Items...>>, Pairs...> type;
+ };
+
+ template <typename C, typename List, typename...Pairs, typename A0>
+ struct apply<list<pair<C, List>, Pairs...>, A0
+ , typename std::enable_if<!(name_at_c<Index, typename A0::name>::value == C::value)>::type>
+ {
+ typedef list<pair<name_at_c<Index, typename A0::name>, list<A0>>, pair<C, List>, Pairs...> type;
+ };
+};
+
+template <std::size_t Index, typename List>
+struct map_chars
+{
+ typedef typename list_fold<List, list<>, map_op<Index>>::type type;
+};
+
+struct create_switch_fold
+{
+ template <typename I, typename A0>
+ struct apply;
+
+ template <char...Chars, typename A0, typename A1>
+ struct apply<eina::_mpl::tpl_char_switch<Chars...>, pair<A0, A1>>
+ {
+ typedef eina::_mpl::tpl_char_switch<Chars..., A0::value> type;
+ };
+};
+
+template <typename Map>
+struct create_switch
+{
+ typedef typename list_fold<Map, eina::_mpl::tpl_char_switch<>, create_switch_fold>::type type;
+};
+
+template <std::size_t Index, typename...Objects>
+void search_separate_switch_case(eina::string_view string, list<Objects...>
+ , std::false_type);
+template <std::size_t Index, typename...Objects>
+void search_separate_switch_case(eina::string_view string, list<Objects...>
+ , std::true_type);
+
+template <int Index, typename Map>
+struct switch_case_call
+{
+ template <char C>
+ struct apply
+ {
+ struct find_char_pair
+ {
+ template <typename T>
+ struct apply;
+ template <typename P1, typename P2>
+ struct apply<pair<P1, P2>>
+ : std::integral_constant<bool, (P1::value == C)>
+ {
+ };
+ };
+
+ struct type
+ {
+ template <typename F>
+ constexpr void operator()(eina::string_view string, F const f) const
+ {
+ std::cout << "Found character " << C << std::endl;
+ typedef typename list_find_if<Map, find_char_pair>::type type;
+ typedef typename type::second objects;
+ typedef typename list_max<name_less_predicate, objects>::type max_type;
+
+ search_separate_switch_case<Index+1>(string, objects{}
+ , f
+ , std::integral_constant<bool, (name_size<typename max_type::name>::value == Index+1)>{});
+ }
+ };
+ };
+};
+
+template <std::size_t Index, typename F, typename Object>
+void search_separate_switch_case(eina::string_view string, list<Object>
+ , F const f
+ , std::true_type)
+{
+ if(string.size() == Index)
+ {
+ std::cout << "Found " << typeid(Object).name() << std::endl;
+ f(Object{});
+ }
+ else
+ {
+ std::cout << "Not found" << std::endl;
+ }
+}
+
+template <std::size_t Index, typename F, typename...Objects>
+void search_separate_switch_case(eina::string_view string, list<Objects...>
+ , F const f
+ , std::false_type)
+{
+ typedef typename map_chars<Index, list<Objects...>>::type map;
+ typedef typename create_switch<map>::type switch_type;
+
+ switch_type{}
+ .template operator()<switch_case_call<Index, map>>
+ (string[Index]
+ , [] (char c)
+ {
+ std::cout << "Not found character " << c << " in Index " << Index << " possible characters should be " << typeid(switch_type).name() << std::endl;
+ }, string, f);
+}
+
+template <typename F, /*typename Registration, */typename Name, typename NamespaceList, typename ClassList>
+void search_separate(eina::string_view string, namespace_object<Name
+ , ClassList, NamespaceList>
+ , F const f)
+{
+ // typedef typename eina::_mpl::tuple_sort<std::tuple<Items...>, item_less_pred>::type ordered_by_tuple_sizes;
+ typedef typename list_sort<name_less_predicate, typename ClassList::type, typename NamespaceList::type
+ >::type objects;
+ typedef typename list_max<name_less_predicate, objects>::type max_type;
+
+ search_separate_switch_case<0ul>(string, objects{}
+ , f
+ , std::integral_constant<bool, (name_size<typename max_type::name>::value == 0)>{});
+ // search_separate_by_length_case(string, identity<ordered_by_tuple_sizes>{});
+}
+
+
+// template <typename...Items>
+// void search(identity<std::tuple<Items...>> x)
+// {
+
+// }
+
+} } }
+
+#endif