summaryrefslogtreecommitdiff
path: root/src/lib/eolian_cxx/grammar/type_function_declaration.hpp
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2017-11-22 16:54:57 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-12-05 10:14:03 +0900
commit5425baa9061753356d450a3c736669341e1b1570 (patch)
treea008cad3e6be4c7d5a2f5e79425ddf27cc6a6a68 /src/lib/eolian_cxx/grammar/type_function_declaration.hpp
parenta597084db7b3a8a4bc7320b68aee7cbb34c6da43 (diff)
cxx: Add support for function pointers
This was tested on the function pointer Efl.Ui.Format_Func_Cb
Diffstat (limited to '')
-rw-r--r--src/lib/eolian_cxx/grammar/type_function_declaration.hpp121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/lib/eolian_cxx/grammar/type_function_declaration.hpp b/src/lib/eolian_cxx/grammar/type_function_declaration.hpp
new file mode 100644
index 0000000000..eccedf8f4a
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/type_function_declaration.hpp
@@ -0,0 +1,121 @@
1#ifndef EOLIAN_CXX_TYPE_FUNCTION_DECLARATION_HH
2#define EOLIAN_CXX_TYPE_FUNCTION_DECLARATION_HH
3
4#include "grammar/generator.hpp"
5#include "grammar/klass_def.hpp"
6
7#include "grammar/string.hpp"
8#include "grammar/indentation.hpp"
9#include "grammar/list.hpp"
10#include "grammar/alternative.hpp"
11#include "grammar/type.hpp"
12#include "grammar/parameter.hpp"
13#include "grammar/keyword.hpp"
14#include "grammar/converting_argument.hpp"
15#include "grammar/eps.hpp"
16
17namespace efl { namespace eolian { namespace grammar {
18
19/** This generates the caller struct for function pointers. */
20struct type_function_declaration_generator {
21 type_function_declaration_generator() {}
22
23 template <typename OutputIterator, typename Context>
24 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& ctx) const
25 {
26 std::string guard = f.c_name + "_defined";
27
28 if (!as_generator("#ifndef " << string << "\n" <<
29 "#define " << string << "\n")
30 .generate(sink, std::make_tuple(guard, guard), add_upper_case_context(ctx)))
31 return false;
32
33 // efl::eolian::function_wrapper<T, F>
34 if (!as_generator("namespace efl { namespace eolian {\n")
35 .generate(sink, attributes::unused, add_lower_case_context(ctx)))
36 return false;
37
38 if (!as_generator(
39 "template <typename F>\n"
40 "struct function_wrapper<" << string << ", F> {\n"
41 << scope_tab << "function_wrapper(F cxx_func) : _cxx_func(cxx_func) {}\n"
42 ).generate(sink, f.c_name, ctx))
43 return false;
44
45 if (!as_generator(
46 scope_tab << "void *data_to_c() { return static_cast<void *>(this); }\n"
47 << scope_tab << string << " func_to_c() const { return &caller; }\n"
48 << scope_tab << "Eina_Free_Cb free_to_c() const { return &deleter; }\n"
49 << "private:\n"
50 << scope_tab << "F _cxx_func;\n"
51 << scope_tab << "static void deleter(void *data) {\n"
52 << scope_tab << scope_tab << "delete static_cast<function_wrapper<" << string << ", F>*>(data);\n"
53 << scope_tab << "}\n"
54 ).generate(sink, std::make_tuple(f.c_name, f.c_name), ctx))
55 return false;
56
57 std::vector<std::string> c_args;
58 for (auto itr : f.parameters)
59 c_args.push_back(", " + itr.c_type + " " + itr.param_name);
60 if (!as_generator(
61 scope_tab << "static " << string << " caller(void *cxx_call_data"
62 << *(string) << ") {\n"
63 << scope_tab << scope_tab << "auto fw = static_cast<function_wrapper<"
64 << string << ", F>*>(cxx_call_data);\n"
65 ).generate(sink, std::make_tuple(f.return_type.c_type, c_args, f.c_name), ctx))
66 return false;
67
68 if (f.return_type != attributes::void_
69 && !as_generator(scope_tab << scope_tab << "auto __return_value =\n")
70 .generate(sink, attributes::unused, ctx))
71 return false;
72
73 if (!f.parameters.empty())
74 {
75 std::vector<attributes::parameter_def> params;
76 for (auto itr = f.parameters.begin() + 1; itr != f.parameters.end(); itr++)
77 params.push_back(*itr);
78 if (!as_generator(
79 scope_tab << scope_tab << "fw->_cxx_func(" << parameter_as_argument << *(", " << parameter_as_argument) << ");\n"
80 ).generate(sink, std::make_tuple(*f.parameters.begin(), params), ctx))
81 return false;
82 }
83
84 if (f.return_type != attributes::void_
85 && !as_generator(scope_tab << scope_tab << "return ::efl::eolian::convert_to_c<"
86 << type << ">(__return_value);\n")
87 .generate(sink, f.return_type, ctx))
88 return false;
89
90 if (!as_generator(scope_tab << "}\n").generate(sink, attributes::unused, ctx))
91 return false;
92
93 if (!as_generator("};\n"
94 "} }\n"
95 "#endif\n\n")
96 .generate(sink, attributes::unused, ctx))
97 return false;
98
99 return true;
100 }
101};
102
103template <>
104struct is_eager_generator<type_function_declaration_generator> : std::true_type {};
105
106namespace type_traits {
107template <>
108struct attributes_needed<type_function_declaration_generator> : std::integral_constant<int, 1> {};
109}
110
111struct type_function_declaration_terminal
112{
113 type_function_declaration_generator operator()() const
114 {
115 return type_function_declaration_generator{};
116 }
117} const type_function_declaration = {};
118
119} } }
120
121#endif